当前位置:   article > 正文

md5绕过

md5绕过

一、什么是md5

一种运用与密码的函数

二、类型

1.弱比较(==)
(1)例如
  1. <?php
  2. highlight_file(__FILE__);
  3. error_reporting(0);
  4. $flag = "flag{H3rmesk1t_is_a_loser}";
  5. $val1 = $_GET['val1'];
  6. $val2 = $_GET['val2'];
  7. if (isset($_GET['val1']) and isset($_GET['val2']))
  8. {
  9. if ($_GET['val1'] != $_GET['val2'])
  10. {
  11. if ((md5($_GET['val1']) == md5($_GET['val2'])))
  12. echo $flag;
  13. else
  14. echo "you can't get flag";
  15. }
  16. }
  17. ?>
(2)绕过方法
1>数组绕过

md5不能加密数组,会返回null

例如

  1. $a=$_GET['a'];
  2. $b=$_GET['b'];
  3. md5($a)==md5($b)

?a[]=1&b[]=2

2>科学计数法(0E)绕过

在php中,0e开头的数字会当作科学计数法解析

QNKCDZO
0e830400451993494058024219903391
 
s878926199a
0e545993274517709034328855841020
 
s155964671a
0e342768416822451524974117254469
 
s214587387a
0e848240448830537924465865611904
 
s214587387a
0e848240448830537924465865611904
 
s878926199a
0e545993274517709034328855841020

例如

  1. $a=$_GET['a'];
  2. $b=$_GET['b'];
  3. md5($a)==md5($b)

?a=QNKCDZO&b=240610708

  1. $a=$_GET['a'];
  2. $a==md5($a);

?a=0e215962017

2.强比较(===)
(1)md5值完全相同的字符绕过
  1. $a=$_GET['a'];
  2. $b=$_GET['b'];
  3. md5($a)===md5($b)

?a=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2&b=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2

(2)数组绕过

与弱比较相同

(3)md5($pass,true)的注入

1>当数字和字符串比较时,若字符串的数字部分(需要从头开始)和数字是相同的,那么则返回的是true。

select if(1="1abcd","等于","不等于") as test;

20201014141938298265.png

if(exp1,stat1,stat2)类似于高级语言中三元运算符。当exp1为true的是否返回stat1,为false返回stat2。

2>以数字开头的字符串,若开头的字符不是0,那么在做逻辑运算的时候返回的是1,也就是true。

select * from user where password =‘‘or‘1234a‘;

php md5($pass,true) 的漏洞:

select * from user where password = md5($pass,true);

20201014141938351973.png

可以看到raw参数是True,为返回原始16字符二进制格式。

也就是说当md5函数的第二个参数为true时,该函数的输出是原始二进制格式,会被作为字符串处理。

如果构造一个‘or‘xxx‘的密码,只要后面的字符串为真即可。那么可以根据32位16进制的字符串来查找,‘or‘对应的16进制是276f7227,所以目标就是要找一个字符串,取32位16进制的md5值里带有276f7227这个字段的,在276f7227这个字段后面紧跟一个数字(除了0)1-9,对应的asc码值是49-57,转化为16进制就是31-39,也就是含有276f7227+(31-39)这个字段,就可以满足要求。

则拼接后构成的SQL语句为:

select * from user where password=‘‘or‘1asodijfoi‘;

select * from user where password=‘‘or‘1abcdefg‘ ---> True

select * from user where password=‘‘or‘0abcdefg‘ ---> False

select * from user where password=‘‘or‘1‘ ---> True

select * from user where password=‘‘or‘2‘ ---> True

select * from user where password=‘‘or‘0‘ ---> False

只要‘or‘后面的字符串为一个非零的数字开头都会返回True,这就是突破点。

http://t.csdnimg.cn/P1hoS

练习

[BJDCTF 2020]easy_md5

搜索发现这里需要对其进行注入,也就是属于md5($pass,true)的注入类型,传入?password=ffifdyop得到这样一个界面

查看源代码,发现还有一组md5的弱比较

数组绕过后,出现新的界面,是强类型,而且是POST传参

得到flag

[NSSCTF 2022 Spring Recruit]babyphp

可以看到是POST传参,a有一个正则表达;b1,b2是md5强比较;检查c1,c2是否为字符串并进行md5弱比较

go on说明已经绕过,可以继续

出现yee说明上面都已经绕过,还差c,要求是字符串而且还是弱比较,说明只能0e绕过

得到flag

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/619284
推荐阅读
相关标签
  

闽ICP备14008679号