新闻资讯
咨询热线
020-08980898传真:020-08980898
CTF中MD5弱类型比较和强碰撞题目梳理及php相关知识
CTF赛场当中,MD5题目持续不断地大量涌现,看样子颇为基础实际却隐藏着危险的机关。不少人搜寻遍了网络上零零星星不成系统的writeup ,但真正碰到题目之时依旧没有办法着手处理。就在今天,我会把MD5弱类型比较以及强碰撞这两类题目,从初步入门一直到深入进阶为你整理得一清二楚,看完之后能够直接拿去进行实际操作。
弱类型比较的致命陷阱
PHP里存在两个比较符号,分别是==与===,它们之间的区别是诸多CTF题目的着手要点,==仅仅比较值是不是相等,然而===会先去比较类型是不是相同,在运用==进行比较时,要是一个数字跟一个字符串碰到一起,字符串会被强制转变为数值。
if (isset($_POST['a']) and isset($_POST['b']))
{
if ($_POST['a'] != $_POST['b'])
{
if (md5($_POST['a']) == md5($_POST['b']))
echo 'flag';
else
echo 'you are wrong';
}
else echo "请输入不同的a,b值";
}
好比字符串"123abc"碰到数字123 ,PHP会把abc忽略掉 ,只拿前面的数字。更为关键的是 ,当一个字符串以"0e"起始 ,后面全都是数字 ,在科学计数法之下 ,这个值便是0。这就表明"0e123456"与"0"用==进行比较是相等的。
数组绕过轻松破防
有个特性很多人不知的MD5函数,它根本没法处理数组,当你传进一个数组时,MD5会返回NULL,要是比较两个NULL,用==判断自然是相等的,这个漏洞在CTF里屡试不爽,直接传两个不一样的数组就能绕过检查。
for($a=1;$a<=1000000000;$a++){
$md5 = md5($a);
if(preg_match('/^0e\d+$/',$md5)){
echo $a;
echo "\n";
echo $md5;
echo "\n";
}
}
在诸多题目里,当存在限制不允许传递数组这种情况出现的时候,才会去思考考虑别的解法,然而,只要是允许传递数组的状况下,这里便属于是最简单的能够突破的口子。在实际的战斗中,见识过数量不少的题目,明明是能够通过数组来进行绕过的,可是选手们却依旧在那里费尽心力地去寻找0e字符串。
s1502113478a
0e861580163291561247404381396064
s1885207154a
0e509367213418206700842008763514
s1836677006a
0e481036490867661113260034900752
s155964671a
0e342768416822451524974117254469
s1184209335a
0e072485820392773389523109082030
0e开头的字符串对决
倘若要进行字符串的传递,那就需要去寻觅经MD5处理后以0e起始的值,留意务必是纯粹的数字紧跟在0e之后,绝不能有字母,不然PHP不会将其视作科学计数法,网络上存在诸多现成的字符串,像是QNKCDZO的MD5值是0e830400451993494058024219903391。
if (isset($_POST['a']) and isset($_POST['b']))
{
if ($_POST['a'] != $_POST['b'])
{
if (md5($_POST['a']) === md5($_POST['b']))
echo 'flag';
else
echo 'you are wrong';
}
else echo "请输入不同的a,b值";
}
?>
凭借自身去编写脚本然后运行其实也并不复杂,通过循环的方式来生成随机的字符串,接着计算其MD5值以判断开头部分是不是0e并且后面的内容全部都是数字。这样的一种方法适用于入门类型的题目,然而在面对强碰撞的情况时就显得不够有优势了。
强碰撞===的终极考验
当题目借助 === 来开展比较之时,先前那些花里胡哨的手段统统都失效了。一定要寻觅到两个截然不同的字符串,然而它们的 MD5 值却是完全相同的。这听起来简直是匪夷所思,不过借助 MD5 碰撞生成器便能够达成这一点。
将fastcoll工具进行下载,准备好一个源文件,运行相应命令,进而产生两个二进制内容不一样然而MD5相同的文件。这两个文件之中包含着不可见字符,在上传之际需要进行URL编码。在比赛的时候依靠这个去绕过===的严格检查。
HECTF实战案例解析
审视一道HECTF的ezphp题目,其源码之中strtr函数会将字符串里的cxhp替换成0123,这也就表明c将会变为0。要是寻觅到MD5以ce起始的字符串,经过替换之后就会成为0e开头。
fastcoll_v1.0.0.5.exe -p ywj.txt -o 1.txt 2.txt
开始的时候所撰写的脚本运行速度迟缓,经过优化之后效率大幅度提高了。这道题目还规定a是纯粹的数字,而且$a.$r运用==等于$b。只要确保a以0e起始,随后拼接上随机生成的数字,在PHP当中依旧被当作0。b传入MD5是0e开头的字符串,两边都是0便实现相等了。
代码生成器自己动手
function readmyfile($path){
$fh = fopen($path, "rb");
$data = fread($fh, filesize($path));
fclose($fh);
return $data;
}
echo '二进制md5加密 '. md5( (readmyfile("1.txt")));
echo "";
echo 'url编码 '. urlencode(readmyfile("1.txt"));
echo "";
echo '二进制md5加密 '.md5( (readmyfile("2.txt")));
echo "";
echo 'url编码 '. urlencode(readmyfile("2.txt"));
echo "";
想要去批量地找寻以ce开头的MD5字符串,进而去写一个循环让其运行起来,每一次都生成随机的字符串并计算MD5。再者去检查生成的MD5字符串的前两位是不是ce,经过优化形成的脚本能够控制步长,以此来避免出现重复计算的情况。
二进制md5加密 8e4ef6c69a337c0de0208455ee69a416
url编码 1%A3njn%FD%1A%CB%3A%29WrEn%CE%89%9A%E3%8EF%F1%BE%E9%EE3%0E%82%2A%95%23%0D%FA%CE%1C%F2%C•4P%C2%B7s%0F%C8t%F28%FAU%AD%2C%EB%1D%D8%D2%8C%3B%FCN%C9b4%DB%AC%A8%BF%3Fh%84i%F4%1E%B5Q%7B%FC%B9RuJ%60%B4%0D7%F9%F9%1E%C1%1B%C9M%2A%7D%B2%BBoW%7D%8F%7F%C0qT%D0%CF%3A%9DFH%F1%25%AC%DF%FA%C4G%27uW%CFNB%E7%EF%B0
二进制md5加密 8e4ef6c69a337c0de0208455ee69a416
url编码 1%A3njn%FD%1A%CB%3A%29WrEn%CE%89%9A%E3%8E%C6%F1%BE%E9%EE3%0E%82%2A%95%23%0D%FA%CE%1C%F2%C4P%C2%B7s%0F%C8t%F28zV%AD%2C%EB%1D%D8%D2%8C%3B%FCN%C9%E24%DB%AC%A8%BF%3Fh%84i%F4%1E%B5Q%7B%FC%B9RuJ%60%B4%0D%B7%F9%F9%1E%C1%1B%C9M%2A%7D%B2%BBoW%7D%8F%7F%C0qT%D0%CF%3A%1DFH%F1%25%AC%DF%FA%C4G%27uW%CF%CEB%E7%EF%B0
留存生成出的字符串,往后比赛时能直接取出来用。另外,一些题含有其他过滤条件,譬如对字符类形作出限制,那时就得针对此去修改脚本。
你平常在参与CTF的时候,碰到MD5相关题目之际,是头一回就想到借助数组进行绕过呢,还是会咬着牙去尝试跑碰撞呀?在评论区域分享一下你的实战经历,为这篇干货点赞并且收藏起来,等下次比赛的时候直接把它拿出来对照着去解题。


