一、首先是MD5()函数的作用?
MD5()函数的作用是计算字符串的MD5散列。
返回值:如果成功则返回已计算的 MD5 散列,如果失败则返回 FALSE。
二、PHP == 弱类型比较绕过?
代码:
<?phphighlight_file(__FILE__);error_reporting(0);$flag="flag{H3rmesk1t_is_a_loser}";$val1=$_GET['val1'];$val2=$_GET['val2'];if(isset($_GET['val1'])andisset($_GET['val2'])){if($_GET['val1']!=$_GET['val2']){if((md5($_GET['val1'])==md5($_GET['val2'])))echo$flag;elseecho"you can't get flag";}}?>//此时如果输入 ver1[]=1&ver2[]=2,返回flag
这里比较的是PHP弱类型,需要绕过MD5()。
方法一:数组绕过
由于MD5不能加密数组,在加密数组的时候会返回NULL,所以我们可以传入两个数组绕过。适用于源码中没有判断变量类型或内容,如果加上了过滤函数就不能使用了。
常见的过滤函数:
ctype_alnum(string$text):bool类型
//如果text中所有的字符都是字母或者数字,则返回true,否则falseis_numeric(mixed$ver):bool类型
//如果ver是数字或者数字字符串,则返回true,否则返回false
例如:
<?phphighlight_file(_FILE_);error_reporting(0);$flag="flag{123456789}";$ver1=$_GET['ver1'];$ver2=$_GET['ver2'];if(isset($_GET['ver1'])andisset($_GET['ver2'])){if($GET['ver1']!=$_GET['ver2']){if((md5($_GET['ver1'])==md5($_GET['ver2']))andis_numeric($_GET['ver1'])andis_numeric($_GET['ver2']))echo$flag;//如果加密和ver1和ver2相等且ver1和ver2都是数字或者数字字符串,则..elseecho"you can't get flag";}}?>//此时如果输入 ver1[]=1&ver2[]=2,返回you can't get flag
方法二:科学计数法绕过
原理:可以传入两个md5加密后是0e开头的字符串,但这个以0e开头的字符串只能是纯数字,这样php在进行科学计算法的时候会将它转化为0。
<?phpfor($a=1;$a<=1000000000;$a++){$md5=md5($a);if(preg_match('/^0e\d+$/',$md5)){//preg_match函数是进行正则表达式的匹配,成功返回1,否则返回0,前面的参数是要搜索的模式、字符串形式,后面的参数指输入的字符串。echo$a;echo"\n";echo$md5;echo"\n";}}?>//加密后是0e开头的数字字符串:QNKCDZO240610708314282422
s878926199a
s155964671a
s214587387a
s214587387a
例如:
<?phphighlight_file(_FILE_);error_reporting(0);$flag="flag{123456789}";$ver1=$_GET['ver1'];$ver2=$_GET['ver2'];if(isset($_GET['ver1'])andisset($_GET['ver2'])){if($GET['ver1']!=$_GET['ver2']){if((md5($_GET['ver1'])==md5($_GET['ver2']))andctype_alnum($_GET['ver1'])andctype_alnum($_GET['ver2']))echo$flag;//如果加密和ver1和ver2相等且ver1和ver2都是数字或者数字字符串,则..elseecho"you can't get flag";}}?>//此时如果输入 ver1=240610708&ver2=314282422,返回$flag,此时ver1和ver2加密后都是0e开头
双MD碰撞绕过
md和md5后都是以0e开头的字符串:
CbDLytmyGm2xQyaLNhWn
770hQgrBOjrcqftrlaZk
7r4lGXCH2Ksu2JNT3BYM
三、PHP===强类型比较绕过?
代码:
<?phphighlight_file(_FILE_);error_reporting(0);$flag="flag{122365944454}";$ver1=$_GET['ver1'];$ver2=$_GET['ver2'];if(isset($_GET['ver1'])andisset($_GET['ver2'])){if($_GET['ver1']!=$_GET['ver2']){if(md5($_GET['ver1'])===md5($_GET['ver2']))echo$flag;elseecho"you can't get flag";}}?>
方法:数组绕过
原理同上、过程同上,可使用。
注:使用md5加密后完全相等的两个字符串绕过,不能用。
这是刚刚同上第二种方法,加密后’oe’开头的字符串,但因为强比较会比较类型和值,因此不能用这个方法来绕过。
当然可以试试加密后类型和值都完全相等的字符串。有篇博客说可以利用fastcoll_v1.0.0.5.exe来生成符合条件的字符串,还没试过,待考察。
链接:https://blog.csdn.net/LYJ20010728/article/details/116779357
四、sql注入类的MD5绕过?
起因:为了信息的安全,在数据库里存放密码的时候都是进行了加密处理的,大多数查询语句在没有进行处理的情况下应该是:
SELECT*FROM admin WHERE username ='admin'and password =".md5($password,true)."
原理:ffifdyop经过MD5加密后变为’or’6xxx阿巴阿巴,
而在mysql中,在用作布尔型判断时,以数字开头的字符串会被当成整型,不过由于是字符串,因此后面必须要有单引号括起来的,比如:‘xxx’or’6xxxxxx’,就相当于’xxx’or 6,就相当于 'xxx’or true,所以返回值是true。
因此查询时就变成了:
sql代码:select * from flag where user='amdin'and password=''or'6xxxx',等于 password=''ortrue== ture
从而实现了绕过。
开始做题:
题目叫easy md5,但是进去看见一个输入框,直觉跟sql有关,因此往输入框里面输入ffifdyop试试,
果然页面发生变化:
打开f12看源码,发现:
这里直接用科学计数法绕过a和b
这里我构造了一个payload,
http://03fa941a-e636-4c85-9c3d-57d574bbfee0.node4.buuoj.cn:81/levels91.php/?a=s1885207154a&b=s1836677006a
发现一直是404,
发现是自己多打了一个斜杠(博主纠结了一个小时)
于是修改payload,
http://03fa941a-e636-4c85-9c3d-57d574bbfee0.node4.buuoj.cn:81/levels91.php?a=s1885207154a&b=s1836677006a
得到页面:
终于看见希望了,flag近在咫尺!
这里看代码是php强类型比较,用数组绕过,构造payload如下图:
得到结果:
版权归原作者 今天小白努力学习了吗 所有, 如有侵权,请联系我们删除。