只是隐隐约约记得MD5是一种加密算法
SQL Injection?
输入:
-
数字
-
字母
-
数字+符号
-
简单SQL语句
-
简单XSS语句
都没什么效果,所以抓包。
|
|
查看Response
|
|
那个Hint
(从 admin 表中选择密码字段等于 $pass 变量的 MD5 值的记录),比较显眼。所以启用sqlmap
。
同时也启用dirsearch
和dirmap
(结果是什么也没得到)。
结果:
-
sqlmap
——GET parameter 'password' does not seem to be injectable
-
dirmap
——没有可用信息 -
dirsearch
——几个200 URL都是跳转leveldo4.php
MD5?
再回看Hint
:
PHP中md5函数如果第二个参数设为true,返回的是二进制内容,如果能恰好凑出类似’or的字符串,就可以构成SQL注入
所以就是要构造一个经过MD5
再经过二进制
后得到的值有‘or
的payload。
上网找了找,说是有
ffifdyop
将password的值修改为ffidyop
就会跳转界面levels91.php
。
好大一个Do You Like MD5?
查看页面代码:
|
|
-
- 从 GET 请求参数中获取
a
和b
的值,并将它们分别赋给变量$a
和$b
。
- 从 GET 请求参数中获取
-
- 接下来,使用条件判断语句进行逻辑判断。如果
$a
不等于$b
并且$a
的 MD5 值等于$b
的 MD5 值,即md5($a) == md5($b)
,则进入条件判断的代码块内部。
- 接下来,使用条件判断语句进行逻辑判断。如果
所以接下来又是寻找符合条件的a与b。
有两种解决方式:
1.PHP弱类型比较绕过
参考PHP hash漏洞之MD5可以得到:
- PHP在处理哈希字符串时,会利用”!=”或”==”来对哈希值进行比较,它把每一个以”0E”开头的哈希值都解释为0,所以如果两个不同的密码经过哈希以后,其哈希值都是以”0E”开头的,那么PHP将会认为他们相同,都是0
(为什么说是hash值?)
另一个简洁版本:PHP MD5相等绕过
构造payload:
|
|
2.数组绕过
在上面那个简洁版本里也提到了这个数组绕过,不过说PHP8就行不通了。不过靶场的PHP依旧适用。
参考PHP弱类型绕过:
md5()/sha()
这类函数无法处理数组,如果传入的是数组,md5()
返回NULL
,加密后得到的也是NULL
,满足两个md5值相等
构造payloa:
|
|
a[]=1&b[]=2
,其中 a[]
和 b[]
是数组参数。当 PHP 解析这个查询字符串时,它会将这些参数解析为数组。
|
|
- 由于md5()函数存在缺陷,加密数组的时候返回值是NULL,即在MD5加密之后,
a[]=NULL、b[]=NULL
,符合要求。
然后我们又跳转页面…
param?
|
|
其实可以看出就是call back,只不过要以POST
方式传参,所以打开我的firefox渗透版:
|
|
最后得到flag。
ファンワイ
比较详细的解释了PHP比较和绕过的原理:PHP 黑魔法