登陆地址:http://ctf5.shiyanbar.com/web/houtai/ffifdyop.php
直接没有登陆,右键查看源代码发现问题:
<!-- $password=$_POST['password'];
$sql = "SELECT * FROM admin WHERE username = 'admin' and password = '".md5($password,true)."'";
$result=mysqli_query($link,$sql);
if(mysqli_num_rows($result)>0){
echo 'flag is :'.$flag;
}
else{
echo '密码错误!';
} -->
可以看到sql语句,由于$password在md5方法之内,所以不存在sql注入。
但是有一处不一样的地方:
md5($password,true)
这里给md5方法加了第二个参数,ture,查看php说明:
定义和用法
md5() 函数计算字符串的 MD5 散列。
md5() 函数使用 RSA 数据安全,包括 MD5 报文摘要算法。
来自 RFC 1321 的解释 - MD5 报文摘要算法:MD5 报文摘要算法将任意长度的信息作为输入值,并将其换算成一个 128 位长度的"指纹信息"或"报文摘要"值来代表这个输入值,并以换算后的值作为结果。MD5 算法主要是为数字签名应用程序而设计的;在这个数字签名应用程序中,较大的文件将在加密(这里的加密过程是通过在一个密码系统下[如:RSA]的公开**下设置私有**而完成的)之前以一种安全的方式进行压缩。
语法
md5(string,raw)
参数 | 描述 |
---|---|
string | 必需。规定要计算的字符串。 |
raw |
可选。规定十六进制或二进制输出格式:
|
技术细节
返回值: | 如果成功则返回已计算的 MD5 散列,如果失败则返回 FALSE。 |
PHP 版本: | 4+ |
更新日志: | 在 PHP 5.0 中,raw 参数变为可选的。 |
通过文档可以看到,md5方法有第二个可选参数,当第二个参数为ture时,返回原始16字符二进制格式
何为原始16字符二进制格式?
本地建立一个php文件,查看返回结果
<?php
echo md5("123456",true);
?>
输出结果:
好像是一堆乱码,去掉true参数
这里大胆预测,是不是md5参数为true时,返回二进制序列,然后通过转hex,得到ASCII码?
<?php
echo hex2bin(md5("123456"));
echo "<br>";
echo md5("123456",true);
?>
输出结果为:
验证猜测正确,我们接着来看,如何才能登陆后台
sql语句为:
$sql = "SELECT * FROM admin WHERE username = 'admin' and password = '".md5($password,true)."'";
要登陆成功,上面这个查询必须不能为空,突破点肯定在md5($password,true)
那么我们要让md5($password,true) 编码后 二进制转字符串为 'or 'xxx
这样sql 为 and password=''or'xx' ''or'xx'=true 这样查询结果为真
那怎么才能拿到md5('key',true)为真的呢?
需要生成md5('key',true)二进制序列化为'or'开头的即可
笔者网上搜集了3个,可做参考:
e58
ffifdyop
129581926211651571912466741651878684928
flag is :flag{ffifdyop_has_trash}
启示:
要利用md5注入,必须满足三个条件
1.sql使用select * from user where username='xx' and password='xx',类似使用可利用万能密码的变种sql
2.md5第二个参数为true
3.用户名在表中可查到