0x00 关于php弱类型—MD5

写这篇东西的原因,因为kiwiCTF遇到了两道关于php&==&MD5的WEB,至于为什么我还不学习PWN,无可奉告

0x01 kiwiCTF-MD5Games1

Source Code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
if (isset($_GET['src']))
highlight_file(__FILE__) and die();
if (isset($_GET['md5']))
{
$md5=$_GET['md5'];
if ($md5==md5($md5))
echo "Wonderbubulous! Flag is [here goes a flag]"; //.require __DIR__."/flag.php";
else
echo "Nah... '",htmlspecialchars($md5),"' not the same as ",md5($md5);
}


?>
<p>Find a string that has a MD5 digest equal to itself!</p>
<form>
<label>Answer: </label>
<input type='text' name='md5' />
<input type='submit' />
</form>

<a href='?src'>Source Code</a>

关键就是:

1
$md5==md5($md5)

这里就直接想到php里的'0e1111'=='0e1234'
因为这样会直接转换成科学记数法
所以就相等了
所以就网上找了个代码改了一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# -*- coding: utf8 -*-    
import hashlib
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):
#print '.',
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,'0e',13)

原始代码来源:http://blog.csdn.net/kalbertlee/article/details/70213392

顺带附上几条跑出来的结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$md5          md5($md5)
0e00275209979 0e551387587965716321018342879905
0e00506035745 0e224441551631909369101555335043
0e00540451811 0e057099852684304412663796608095
0e00678205148 0e934049274119262631743072394111
0e00741250258 0e899567782965109269932883593603
0e00928251504 0e148856674729228041723861799600
0e01350016114 0e769018222125751782256460324867
0e01352028862 0e388419153010508575572061606161
0e01392313004 0e793314107039222217518920037885
0e01875552079 0e780449305367629893512581736357
0e01975903983 0e317084484960342086618161584202
0e02042356163 0e335912055437180460060141819624
0e02218562930 0e151492820470888772364059321579
0e02451355147 0e866503534356013079241759641492
0e02739970294 0e894318228115677783240047043017
0e02760920150 0e413159393756646578537635311046
0e02784726287 0e433955189140949269100965859496
0e03298616350 0e851613188370453906408258609284
0e03393034171 0e077847024281996293485700020358

0x02 kiwiCTF-MD5Games2

大体上和MD5Games1没太大区别
唯一的区别是判断改成了

1
2
3
$md5=md5($md5);
if($md5==md5($md5))
~~~~~~

相当于

1
md5($md5)==md5(md5($md5));

我的想法是

1
2
md5('0e\d+')=='0e\d{30}';
md5('0d\d{30}')=='0e\d{30}'

就这个意思。。。把上面的代码改一下跑,理论上能搞出来,但是概率堪比单抽出奇迹
我以为我想法有问题,然后和前会长交流了一下,前会长当成了md5(Array)==NULL
直到今天我看到了官方writeup,真的是爆破,还讲了一下怎么爆破比较方便实惠。。。

0x03 其他一些关于md5的弱类型

0x031

1
2
3
#上略
if(md5($a)=='0e11111');
#下略

相当经典和基础。。通常情况这类就是用md5($a)='0e\d+'来过
有些时候会对$a进行过滤,比如全由数字组成,或者全由字母组成
具体实例不放了,网上一大堆

0x032

1
2
3
#上略
if(md5($a)===md5($b));
#下略

这个就不是弱类型比较了,===的要求比==要严格
这里咱们就用md5(数组)的特性:

1
2
$a=[1,2,3]
md5($a)==NULL

针对数组,我见过的参数写法

1
127.0.0.1/test.php?a[]=1&a[]=2

这样就生成了一个数组$a=[1,2]
当时前会长告诉我的另外一个骚操作我不记得了,到时候搞明白了再补上来

0x04 后记

我他娘的不是说以后搞PWN的吗。。。。。。
凉了凉了