1.题目
搞了好久,这道题,就一个简简单单的输入框。
2、利用md5($password,true)实现SQL注入
打开题目,看上去像sql注入,也有可能是命令执行,或者SSRF,但是注入半天也没什么反应。于是我们去看网页源码,在响应头的地方看到了提示。
select * from 'admin' where password=md5($pass,true)
果然是sql注入,这里面password就是我们用户框中输入得东西。
突破点在md5($pass,true)这里,先来看看md5函数的用法:
可以看到这里的raw参数是True,意为返回原始16字符二进制格式。
也就是说如果md5值经过hex转成字符串后为 'or'+balabala这样的字符串,则拼接后构成的SQL语句为:
select * from 'admin' where password=''or'balabala'
当'or'后面的值为True时,即可构成万能密码实现SQL注入,这里我们需要知道的是MySQL的一个特性:
在mysql里面,在用作布尔型判断时,以1开头的字符串会被当做整型数。
要注意的是这种情况是必须要有单引号括起来的,比如password=‘xxx’ or ‘1xxxxxxxxx’,那么就相当于password=‘xxx’ or 1 ,也就相当于password=‘xxx’ or true,所以返回值就是true。
当然在我后来测试中发现,不只是1开头,只要是数字开头都是可以的。
当然如果只有数字的话,就不需要单引号,比如password=‘xxx’ or 1,那么返回值也是true。(xxx指代任意字符)
select * from 'admin' where password=''or'1abcdefg' ---> True select * from 'admin' where password=''or'0abcdefg' ---> False select * from 'admin' where password=''or'1' ---> True select * from 'admin' where password=''or'2' ---> True select * from 'admin' where password=''or'0' ---> False
只要'or'后面的字符串为一个非零的数字开头都会返回True,这就是我们的突破点。
我们可以通过这个脚本来获得满足我们要求的明文:
<?php for ($i = 0;;) { for ($c = 0; $c < 1000000; $c++, $i++) if (stripos(md5($i, true), '\'or\'') !== false) echo "\nmd5($i) = " . md5($i, true) . "\n"; echo "."; } ?>//引用于 http://mslc.ctf.su/wp/leet-more-2010-oh-those-admins-writeup/
这里提供一个最常用的:ffifdyop,该字符串md5加密后若raw参数为True时会返回 'or'6
所以如果这里我们输入ffifdyop,后端的SQL语句会变成:
select * from 'admin' where password=''or'6<trash>' ---> True
成功构成SQL注入,我们在本题直接输入ffifdyop即可进入下一关
2、PHP md5弱类型比较
进入第二关后右键查看源代码可以从注释中得到后端PHP的一部分源码:
`$a = $GET['a'];
$b = $_GET['b'];
if($a != $b && md5($a) == md5($b)){
// wow, glzjin wants a girl friend.`
这里要求a和b明文值不同,但md5值相同,注意这里是两个等于号,是弱相等,所以我们可以利用PHP的弱类型比较突破,寻找两个明文不同但md5值为"0exxxxx"的字符串,可以参考文章https://www.cnblogs.com/yesec/p/12232075.html
这里直接提供两个QNKCDZO和s214587387a,用GET传值直接过。
3、数组绕过
进入第三关给出了源码:
`<?php
error_reporting(0);
include "flag.php";
highlight_file(FILE);
if($_POST['param1']!$_POST['param2']&&md5($_POST['param1'])=md5($_POST['param2'])){
echo $flag;
}`
可以看到依旧是md5比较,但是不同于第二关,这一关是“===“强相等,很明显2中的方法没办法通过
刚才推荐的那一片文章里文末也提到了这种方法,这里需要知道的是PHP的一些特性:
md5(array()) = null
sha1(array()) = null
ereg(pattern,array()) = null vs preg_match(pattern,array) = false
strcmp(array(), "abc") = null
strpos(array(),"abc") = null
引用自 https://blog.csdn.net/q1352483315/article/details/89469928
md5()函数无法处理数组,如果传入的为数组,会返回NULL,所以两个数组经过加密后得到的都是NULL,也就是相等的。
所以直接POST传入param1[]=1¶m2[]=2即可得到Flag:
标签:password,admin,where,BUUCTF,Easy,BJDCTF2020,True,select,md5 From: https://www.cnblogs.com/djkl/p/16661130.html