手工SQL注入寻找技巧

Track-聂风   ·   发表于 2018-05-29 11:01:18   ·   漏洞文章
本文为大家介绍手工SQL注入的技巧,以及利用的方法。

根据bugbountyforum.com的AMA版面,最常见的问题之一就是:如何测试服务器端漏洞,例如SQL注入?直到最近我还在努力解决这个问题(特别是关于SQL注入)。我发现,SQL注入经常被发现并被sqlmap利用的,之后我发现这个服务器对单引号的反应很奇怪。然而在过去的两个月,我被迫深入到手工SQL注入发现,因为我的目标有一个很强的防火墙可以使sqlmap失效。在这两个月里我能够找到超过10个SQL注入,从这些中我学到了很多。这个博客也会专注于分享我的过程和知识以及展示现实中的例子。我将会把这个博客分成两个部分:发现和利用,因为这两部分都需要很好的报告。最后,这个博客假设用的是MySQL,因为它拥有半数以上的市场份额。

发现

找到有效SQL注入的第一部分是发现漏洞。而其中最重要的部分是知道在你的输入会在哪一SQL语境中结束。这里有一些基本的例子:

· SELECT user_input FROM tournament ORDER BY region;

· INSERT INTO tbl_name (col1,col2) VALUES (15,user_input);

· DELETE FROM somelog WHERE texts ='user_input'

现在我们可以看到我们的user_input在不同语境中结束:在()之间,在之间或者没有任何分隔符。这些命令的共同之处是,一旦’作为输入进行注入,它们就会失效。如果使用了不存在的系统变量,前两个即使没有分隔符也会给出一个错误。像:@@versionz'(取代@@version)。

一旦你能够让这个服务返回错误(主要是HTTP 500),你需要确认是SQL命令引起这个错误而不是一些类似数据解析器的东西。要做到这一点,你可以使用一系列技巧:

| 如果一个导致错误,试着查看\’能否成功(因为反斜杠在MySQL中取消了单引号)

l 你也可以尝试注释掉’就会返回成功消息,就像:%23’或者--’。这是因为你告诉MYSQL忽略注释之后的所有东西,包括额外的

l 如果是不允许,你可以在有效和无效的系统变量之间比较,类似@@versionzvs @@version',或在无效函数和有效函数之间的比较:SLEP(5) vsSLEEP(5)

l 有些时候你的输入会在()之间结束,以确保你可以测试input)%23,也会查看你是否可以突破这些,例如利用UnionSQL注入( input)order by 5%23)。

l 如果正常的输入只是一个整数,你可以尝试减去一些量,然后查看减法是否有效( id=460-5 )。

l 试着看偶数的引号是否会返回成功(例如460''460-'')并且奇数的引号会导致错误(460' 或460-''')。

例子

想要把这些弄清楚,你需要下面这个URL:

https://www.example.com/php/sales_dash_poc_handle.php?action=month-breakdown&type_of_report=billing&city=all&month=8&year=2017&poc=35141008

这个基本的URL返回一个状态码200。输入poc=35141008'以及poc=35141008'%23返回错误500,但是poc=35141008''返回状态200。这就提示,这个参数可能没有使用任何分隔符,因此我尝试了poc=35141008%23',它会返回状态码200。现在我们知道了我们可以在35141008%23之间注入。在这之后我尝试了一个简单的35141008OR 2 LIKE 2%23,它起作用了,但是35141008 OR 2 LIKE 1%23返回错误500,在这里证明布尔类型的SQL注入是可行的。然而,这并不总是如此简单,而且这个例子并没有显示出太大的影响,这是下一章节的内容,证明数据检索。

利用

在你找到SQL注入之后,你总是要尝试证明输出或者输出中的敏感数据有差异。不幸的是这并不总是直截了当的,特别是防火墙和黑名单会妨碍你。这部分是帮助你绕过那些问题。

防火墙

当你处理防火墙时,你要做的第一件事是看你是否可以在一个设置中找到错误配置。对于大多数防火墙和CDN,你可以通过访问真实IP并用真实域名作为主机值访问不受保护的网站(防火墙在IP前面)。这里第一步应该是找到网站的原始IP,使用追踪某个网站所使用的IP服务通常不会太难(http://viewdns.info/iphistory/)。通常用在防护墙ip前的那一个是他们仍在使用的那一个(基本上就是后面所说的cloudflare 或 akamai)。在寻找真实IP时Shodan 也非常有用。

在你找到真实IP地址之后,尝试访问带有真实主机HTTP头信息的网站。在cURL中这部分会这样工作的(添加头文件也适用于sqlmap):

$ curl –header ‘Host: www.example.com‘ ‘https://54.165.170.2/‘ -v -k

很不幸我的目标被禁止了。所以我必须具有创造力。在这我发现通过给主机域名后面添加一个点(http://www.example.com.)不会受限制而且仍然允许我浏览这个直接IP。在你的/etc/hosts文件中添加:

54.165.170.2       http:www.example.com

就会允许你在浏览器中浏览http://www.example.com,并且在这之间没有任何防火墙。从这开始,所有的限制都应该消失,而且SQL注入的利用应该相当容易

绕过黑名单

有时, 您无法绕过防火墙, 这将要求您绕过已就位的 (可能) 黑名单。这里我最大的提示是, 谷歌是你的朋友。找到具有强大功能的利基功能, 要求您以某种方式提取数据。但是这里有一些常见的提示

1. 在查询中使用注释作为空格以破坏防火墙中的正则表达式或词组。例如:2/dhab bc/OR/dahdshka/2/sd/LIKE/da/"2"/**/%23就是:2 OR 2=2%23

2.  如上例所示,用 LIKE 代替 =,用 2 代替 1,用 ” 代替 ’ 。很多人都很懒,防火墙也是如此,走小路会让许多防火墙措手不及。

3. 正如我上面说的用Google找niche函数。例如,我发现MID()SUBSTRING()的工作方式一样,然而,后一个是被禁止的,第一个不是。变量也是一样的CURRENT_USER()是被禁止的,而CURRENT_USER不是。

把它们放在一起

从SQL注入发现,这很可能是我最喜欢的。因为利用真的非常难。所以我将详细地描述它,并且希望你们可以从中学到一些东西。

我偶然发现这个URL:

https://www.example.com/php/analyticsExcel.php?action=res_unique_analytics&resid=2100935&start_date=2016-07-11 00:00:00&end_date=2017-08-11 23:59:59&action=res_unique_analytics&entity_type=restaurant

这里我有2100935的合法访问权,而且请求2100935将会导致未经验证的错误。奇怪的是,在2100935后面添加一个引号,就会导致错误500,添加两个引号就会使URL再次起作用。在这里,为了让利用更容易,我用www.example.com.绕过。在那里,我试图在输入中找到一个地方在输入中注入我自己的SQL命令,然而我没有设法在字符串中插入注释,因此我断定这个查询是非常复杂的。考虑到这一点我决定把侧重点烦躁一个更简单的OR语句上,这个语句几乎可以在任何地方注入。在这我注意到' OR 1='1会返回状态码200,' OR 1='2' AND1='1' AND 1='2也都是一样的。而且最终似乎没有哪个sleep()命令有效果。

非常奇怪的是,我可以确定我注入的语法是正确的,但是没有任何技巧可以提取数据。在这我尝试' OR@@version=5,它会导致状态码200,以及' OR@@versionz=5,它会导致错误500。这至少证实我正在使用MySQL并表明注入确实在这里。这里指向MySQL的IF函数。我的想法是如果我可以根据if语句是真是假来返回一个无效函数,我就可以证明数据提取。由于MySQL似乎在验证IF语句之前验证了命令,但是进展并没有如想象般顺利。但是IF语句最终成为解决方案的一部分。在一个具有正整数的IF语句中输入一个有效的SLEEP命令将会导致服务器超时,而从IF语句中返回一个简单的整数时,将会迅速返回一个状态码200。从这里我利用了下面的POC:

TRUE: if @@version starts with a 5:

2100935' OR IF(MID(@@version,1,1)='5',sleep(1),1)='2

Response:

HTTP/1.1 500 Internal Server Error

False: if @@version starts with a 4:

2100935' OR IF(MID(@@version,1,1)='4',sleep(1),1)='2

Response:

HTTP/1.1 200 OK

总结

如果注入一个单引号会在响应中导致不同的输出,请尝试使用这篇博客中列出的其他的技术,以查看你是否在处理SQL注入。在确定了你正在使用的SQL上下文之后,利用一个POC,它可以显示敏感信息(基于error或union),或者根据问题是真是假(基于布尔和时间)来显示输出中的差异。

*参考来源:Manual SQL injection discovery tips,文章内容以原文为准,本文由丁牛网安实验室小编EVA编辑整理


打赏我,让我更有动力~

0 条回复   |  直到 2018-5-29 | 2712 次浏览
登录后才可发表内容
返回顶部 投诉反馈

© 2016 - 2024 掌控者 All Rights Reserved.