【Web 笔记】Md5 绕过总结
source link: https://binlep.github.io/2020/02/28/%E3%80%90Web%20%E7%AC%94%E8%AE%B0%E3%80%91md5%20%E7%BB%95%E8%BF%87%E6%80%BB%E7%BB%93/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
md5 太难咯
md5 弱类型比较
参考源码:
<?php
highlight_file(__FILE__);
error_reporting(0);
$val1 = @$_GET['val1'];
$val2 = @$_GET['val2'];
if( $val1 == $val2 ){
die('val1 OR val2 no no no');
}
if( md5($val1) != md5($val2) ){
die('step 1 fail');
}
?>
数组绕过适用于源码中没有判断变量类型或内容,如果加上了过滤函数就不能使用了
常见过滤函数如下:
ctype_alnum ( string $text ) : bool
// 如果text中所有的字符全部是字母和(或者)数字,返回 TRUE 否则返回FALSE
is_numeric ( mixed $var ) : bool
// 如果 var 是数字和数字字符串则返回 TRUE,否则返回 FALSE。
科学计数法绕过
参考源码:
<?php
highlight_file(__FILE__);
error_reporting(0);
$val1 = @$_GET['val1'];
$val2 = @$_GET['val2'];
if( $val1 == $val2 ){
die('val1 OR val2 no no no');
}
if( md5($val1) != md5($val2) ){
die('step 1 fail');
}
?>
它的原理在于:为 0e 开头,后面都是数字的字符串
会被识别为科学记数法
常见的明文与密文如下:
byGcY
0e591948146966052067035298880982
QNKCDZO
0e830400451993494058024219903391
s878926199a
0e545993274517709034328855841020
s155964671a
0e342768416822451524974117254469
s214587387a
0e848240448830537924465865611904
s214587387a
0e848240448830537924465865611904
s878926199a
0e545993274517709034328855841020
s1091221200a
0e940624217856561557816327384675
s1885207154a
0e509367213418206700842008763514
若有要求 md5 值的明文长度很小,其中只能出现一种字母,那么可以写脚本获取明文
通常有该要求的题目如下:
$a = $_POST['a'];
$b = $_POST['b'];
$m = $_GET['m'];
$n = $_GET['n'];
if (!(ctype_alnum($a)) || (strlen($a) > 5) || !(ctype_alnum($b)) || (strlen($b) > 6))
{
echo "a OR b fail!";
die();
}
if ((strlen($m) > 1) || (strlen($n) > 1))
{
echo "m OR n fail";
die();
}
$val8 = md5($a);
$val9 = strtr(md5($b), $m, $n);
echo PHP_EOL;
echo "<p>val8 : $val8</p>";
echo PHP_EOL;
echo "<p>val9 : $val9</p>";
echo PHP_EOL;
if (($val8 == $val9) && !($a === $b) && (strlen($b) === 5))
{
echo "nice,good job,give you flag:";
echo file_get_contents('/var/www/html/flag.php');
}
代码的意思就是需要一个长度小于等于 5 的字符串的 md5 值是科学计数法样式
还需要一个长度等于 5 的字符串的 md5 值在替换一个字符后能变成科学计数法样式的 md5,这也是我们要求的
这里采用 FireCC 师傅的脚本:
import hashlib
import string
str_list = list(string.letters + string.digits)
for i in range(0, len(str_list)):
for j in range(0, len(str_list)):
for k in range(0, len(str_list)):
for l in range(0, len(str_list)):
for m in range(0, len(str_list)):
tmp = str_list[i] + str_list[j] + str_list[k] + str_list[l] + str_list[m]
str_hash = hashlib.md5(tmp).hexdigest()
check = str_hash[0:2]
str_hash = str_hash[2:32]
a = str_hash.replace('a', '1')
b = str_hash.replace('b', '1')
c = str_hash.replace('c', '1')
d = str_hash.replace('d', '1')
e = str_hash.replace('e', '1')
f = str_hash.replace('f', '1')
g = str_hash.replace('g', '1')
h = str_hash.replace('h', '1')
i1 = str_hash.replace('i', '1')
j1 = str_hash.replace('j', '1')
k1 = str_hash.replace('k', '1')
l1 = str_hash.replace('l', '1')
m1 = str_hash.replace('m', '1')
n = str_hash.replace('n', '1')
o = str_hash.replace('o', '1')
p = str_hash.replace('p', '1')
q = str_hash.replace('q', '1')
r = str_hash.replace('r', '1')
s = str_hash.replace('s', '1')
t = str_hash.replace('t', '1')
u = str_hash.replace('u', '1')
v = str_hash.replace('v', '1')
w = str_hash.replace('w', '1')
x = str_hash.replace('x', '1')
y = str_hash.replace('y', '1')
z = str_hash.replace('z', '1')
if check == '0e' and (
a.isdigit() or b.isdigit() or c.isdigit() or d.isdigit() or e.isdigit() or f.isdigit() or g.isdigit() or h.isdigit() or i1.isdigit() or j1.isdigit() or k1.isdigit() or l1.isdigit() or m1.isdigit() or n.isdigit() or o.isdigit() or p.isdigit() or q.isdigit() or r.isdigit() or s.isdigit() or t.isdigit() or u.isdigit() or v.isdigit() or w.isdigit() or x.isdigit() or y.isdigit() or z.isdigit()):
print tmp
print str_hash
md5 强类型碰撞
两个 md5 碰撞
这里使用 fastcoll 工具来进行哈希碰撞获得两个相同的 md5
工具用法:.\fastcoll.exe init -o file1 file1
用一个源文件 init 制造两个 md5 相同的不同文件,之后将文件内的内容进行 url 编码即可作为变量传递,脚本如下:
import binascii
file1 = open('file1', 'rb').read()
file2 = open('file2', 'rb').read()
def urlencode(bstr):
encoded = ''
for i in bstr:
encoded = encoded + '%' + binascii.b2a_hex(i)
return encoded
print urlencode(file1)
print urlencode(file2)
三个及以上 md5 强碰撞
这个又是一个新知识点了,原理不懂,只会操作,大致原理如下:
MD5(file + col1_a + col2_a) === MD5(file + col1_a + col2_b) === MD5(file + col1_b + col2_a) === MD5(file + col1_b + col2_b)
那么操作流程如下:
.\fastcoll.exe a -o b c
.\fastcoll.exe b -o e f
.\fastcoll.exe e -o g h
这样执行完后会得到 5 个文件,接下来要用脚本来得到 5 个 md5 值相同的文件,脚本如下:
with open('a', 'rb') as a:
base = a.read()
with open('b', 'rb') as b:
file_1 = b.read()
coll_1 = file_1[len(base):]
with open('c', 'rb') as c:
file_2 = c.read()
coll_2 = file_2[len(base):]
with open('e', 'rb') as e:
file_1_1 = e.read()
coll_1_1 = file_1_1[len(file_1):]
with open('f', 'rb') as f:
file_1_2 = f.read()
coll_1_2 = file_1_2[len(file_2):]
with open('g', 'rb') as g:
file_1_1_1 = g.read()
coll_1_1_1 = file_1_1_1[len(file_1_1):]
with open('h', 'rb') as h:
file_1_1_2 = h.read()
coll_1_1_2 = file_1_1_2[len(file_1_2):]
def w(fn, data):
with open("out/" + fn, 'wb') as fp:
fp.write(data)
w("file1", base + coll_1 + coll_1_1 + coll_1_1_1)
w("file2", base + coll_1 + coll_1_1 + coll_1_1_2)
w("file3", base + coll_1 + coll_1_2 + coll_1_1_1)
w("file4", base + coll_1 + coll_1_2 + coll_1_1_2)
w("file5", base + coll_2 + coll_1_1 + coll_1_1_1)
可以在 linux 下用 md5sum 命令来查看文件的 md5 值,之后用脚本将文件内容转化成网页能识别的 url 编码:
import binascii
file1 = open('file1', 'rb').read()
file2 = open('file2', 'rb').read()
file3 = open('file3', 'rb').read()
file3 = open('file4', 'rb').read()
file3 = open('file5', 'rb').read()
def urlencode(bstr):
encoded = ''
for i in bstr:
encoded = encoded + '%' + binascii.b2a_hex(i)
return encoded
print urlencode(file1)
print urlencode(file2)
print urlencode(file3)
print urlencode(file4)
print urlencode(file5)
哈希长度扩展攻击
先留着,懒得写,遇到的时候再整理写上哈哈哈哈
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK