一个度过菜鸟期的后台程序员都会小心的避开SQL注入常见低级错误。
除了白盒和代码评审,作为第三方的渗透测试,使用sqlmap这样的常用工具进行SQL注入扫描可以降低上述问题发生概率。
工具环境准备
0.先检查一下是否安装过sqlmap工具,显示下版本
sqlmap --version
如果运行成功说明已经安装此工具,比如返回
1.1.6#pip
如果没有安装过sqlmap,请参考后面两个步骤
1.安装pip工具
多数新的发行版linux都带有python和pip,检查pip版本
[jim@host]$ pip --version
pip 9.0.1 from /usr/lib/python2.6/site-packages (python 2.6)
对于centos 6.5 或者以下,没有安装pip的话,请用root用户安装
[root@host]# wget https://bootstrap.pypa.io/get-pip.py
[root@host]# python get-pip.py
注:如果需要升级到 python2.7,可以参考 centos_6.5安装python2.7
2. 安装sqlmap工具,建议使用国内的源,比如阿里云,速度快很多
[root@host]# pip install sqlmap -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com
...
Successfully built sqlmap
Installing collected packages: sqlmap
Successfully installed sqlmap-1.1.6
很多步骤和依赖包安装完毕后可回到 步骤0 检查工具安装结果
常规注入扫描
最简单的注入原理就是在请求参数中增加“;sql statment”, 如果响应告诉扫描工具请求成功,那么这个请求就是有严重注入攻击漏洞的。
0. 了解常用的参数
sqlmap -h
常用到的必选项
-u URL, --url=URL Target URL (e.g. "http://www.site.com/vuln.php?id=1")
--data=DATA Data string to be sent through POST
--cookie=COOKIE HTTP Cookie header value
-H HEADER, --hea.. Extra header (e.g. "X-Forwarded-For: 127.0.0.1")
暴力的扫描选项
-a, --all Retrieve everything
如果已经知道目标数据库,比如mysql,请指定数据库参数,否则sqlmap会遍历尝试各种数据库注入
--dbms mysql
- 匿名访问和使用cookie来授权用户 如果要检测的应用属于匿名用户公开访问,不用考虑cookie
如果要检测的应用属于用户登录授权的,则需要使用cookie来保持授权用户会话,参考如何模拟http_https请求头和cookie
- 准备被扫描对象 找到api的列表,作为被扫描对象,但是构造参数可能是琐碎的事情,此外还要注意几点:
尽量从本机 127.0.0.1 来访问目标请求api
目的是降低网络要求和防火墙等安全产品的误报
不要在生产环境运行,可能是有破坏性的
获得访问请求api和参数,对于上线的系统,可从生产日志里面找到扫描请求
- 运行和查看扫描结果 我们看一个简单的扫描例子,只有一个参数的GET方法
sqlmap -u'http://127.0.0.1:8118/app/dealreport/query/user-info?user_name=%E4%B8%81%E4%BF%8A&_=1498102883406' -a --dbms mysql
___
__H__
___ ___[)]_____ ___ ___ {1.1.6#pip}
|_ -| . [.] | .'| . |
|___|_ ["]_|_|_|__,| _|
|_|V |_| http://sqlmap.org
[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illeg\
al. It is the end user's responsibility to obey all applicable local, state and federal laws. Dev\
elopers assume no liability and are not responsible for any misuse or damage caused by this progr\
am
[*] starting at 14:49:49
[14:49:49] [INFO] testing connection to the target URL
[14:49:49] [INFO] testing if the target URL is stable
[14:49:50] [INFO] target URL is stable
[14:49:50] [INFO] testing if GET parameter 'user_id_assistant' is dynamic
[14:49:50] [WARNING] GET parameter 'user_id_assistant' does not appear to be dynamic
[14:49:50] [WARNING] heuristic (basic) test shows that GET parameter 'user_id_assistant' might no\
t be injectable
[14:49:50] [INFO] testing for SQL injection on GET parameter 'user_id_assistant'
[14:49:50] [INFO] testing 'AND boolean-based blind - WHERE or HAVING clause'
[14:49:51] [INFO] testing 'MySQL >= 5.0 boolean-based blind - Parameter replace'
[14:49:52] [INFO] testing 'MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)'
...
...
[14:50:01] [INFO] testing 'MySQL >= 5.0 error-based - Parameter replace (FLOOR)'
[14:50:01] [INFO] testing 'MySQL inline queries'
[14:50:01] [INFO] testing 'MySQL >= 5.0.12 AND time-based blind'
[14:50:02] [INFO] testing 'Generic UNION query (NULL) - 1 to 10 columns'
[14:50:08] [WARNING] GET parameter '_' does not seem to be injectable
[14:50:08] [CRITICAL] all tested parameters appear to be not injectable. Try to increase '--level'/'--risk' values to perform more tests. Also, you can try to rerun by providing either a valid value for option '--string' (or '--regexp'). If you suspect that there is some kind of protection mechanism involved (e.g. WAF) maybe you could retry with an option '--tamper' (e.g. '--tamper=space2comment')
[*] shutting down at 14:50:08
注意到 [14:50:08] [CRITICAL] all tested parameters appear to be not injectable. , 那么这个api通过了常规注入套路的检测,未见可疑。
进阶注入扫描
- 我们需要用到更详细和高级的sqlmap运行选项
sqlmap -hh
- 更高效的api参数组合
使用代理来记录遍历所有的有效请求
- 快速评估
当不能对所有的api进行扫描,需要抽样评估,这是一个抽样数量计算的工具https://www.surveysystem.com/sscalc.htm,根据可接受误差和置信度来决定抽样数量