写在前面:最近练习了一些CTF中关于md5绕过的题目,总结了几种思路,本质没有太大变化,就是各种组合绕过,也是比较考察基础的,前段时间太摆烂了,好久没有更新了,革命尚未成功,同志仍需努力!!!

关于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 字符十六进制数

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

松散比较类型

题目一

  • 题目如下:
 md5校验失败...
  • 题目分析:

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

payload:?md5=0e215962017

  • 此题可解:

题目二

  • 题目如下:
 用户名密码不能相等
  • 题目分析:

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

240610708 0e462097431906509019562988736854 314282422 0e990995504821699494520356953734 571579406 0e972379832854295224118025748221QLTHNDT 0e405967825401955372549139051580 QNKCDZO 0e830400451993494058024219903391 EEIZDOI 0e782601363539291779881938479162 TUFEPMC 0e839407194569345277863905212547 UTIPEZQ 0e382098788231234954670291303879
  • 此题可解:

严格比较类型

题目一

  • 题目如下:
 用户名密码不能相等!
  • 题目分析:

全等运算符“===”,既比较值又比较类型,题目中“!=”意思为“不等于”,具体可查看菜鸟教程关于“!=”说明,值不相等时返回“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 即 'or'66�]��!r,��b

利用方法:

select * from admin where password=”or’6′

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

select * from admin where password=''or 1

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

查看网页源代码。

这里通过代码审计:

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

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

  • 题目得解:

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

题目练习平台

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

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