代码审计之漏洞挖掘与防范(基础篇)

SQL注入

漏洞类型

普通注入

普通注入值得是最容易利用的注入方式,比如union注入,盲注(基于时间盲注和基于Boolean的忙住),基于报错的注入等。

//union注入
<?php
$uid = $_GET['id'];
$sql = "SELECT * FROM userinfo where id = $id";
$conn = mysql_connect('localhost','root','root');
mysql_select_db("test",$conn);
$result = mysql_query($sql,$conn);
echo mysql_fetch_row($result);
?>

普通注入还分为字符型注入和数字型注入,上述例子是数字型注入,下面代码是字符型注入:

//union字符型注入
<?php
$uid = $_GET['id'];
$sql = "SELECT * FROM userinfo where id = '$id'";
$conn = mysql_connect('localhost','root','root');
mysql_select_db("test",$conn);
$result = mysql_query($sql,$conn);
echo mysql_fetch_row($result);
?>

字符型注入在利用时首先需要对单引号进行闭合,通常针对上述代码只需要将id设置为**1’ or 1=1 – '**就可以了,构造出来的查询语句如下

SELECT * FROM userinfo where id = '1' or 1=1 -- '';

但通常服务器端会开启GPC等功能将单引号给转义掉,这时候如果仍然使用上述payload构造出来的查询语句如下所示:

SELECT * FROM userinfo where id = '1\' or 1=1 --\ '';

很明显上述语句不会成功的,为了仍然能够利用漏洞就需要想办法从单引号中逃逸出来。

编码注入

编码转换就为上述提到的从单引号中逃逸出来提供了途径。只要存在编码转换就有可能存在注入问题。

宽字节注入

1.原理:

  • 首先服务器对数据库进行了如下设置
set character_set_client = gbk
或
SET NAMES 'gbk'
/*
上条语句等价于:
SET
character_set_connection = 'gbk'
character_set_results = 'gbk'
character_set_client = 'gbk'
*/mysql_set_charaset('gbk');
/*
上述函数其实仅是调用了SET NAMES
*/
  • 接着攻击者将payload设置为id%df’ or 1=1 #, 经过转义后payload为id%df\’ or 1=1 #,其中’\'就是**%5c**,至此就结合为了id%df%5c’ or 1=1 #。由于设置了编码为gbk或者使用了addslashes()、mysql_escape_string()、mysql_real_escape_string(),payload就变成了
  1. 例子
    以下面代码为例:
<?php
$link = mysqli_connect("localhost", "root", "147258zhao") or die("Cannot contact server");
mysqli_select_db($link, "test") or die("Cannot use database");
$id = addslashes($_GET['id']);//当前没有开启GPC所以使用了addslashes,如果开启GPC去掉addslashes
$sql = "SELECT * FROM User where id = '$id'";
echo $sql."<br>";
$request = mysqli_query($link,"SET character_set_client='gbk'");
$request = mysqli_query($link,$sql);
while($field = mysqli_fetch_assoc($request)){
	echo var_dump($field);
}
mysqli_close($link);
?>

当设置payload为id=1’ or 1=1 – '时页面输出如下:
图片
接着将payload设置为id=1%df’ or 1=1 – %df’,页面输出为:
图
数据库执行语句如下:
图
3. 防范

  • 设置SET NAMES 'gbk’后接着设置SET character_set_client=binary
  • 使用mysql_set_charset(‘gbk’)后,使用mysql_real_escape_string() 对参数进行过滤。
    在这里插入图片描述
  • 使用pdo方式,在PHP5.3.6及以下版本中需要设置setAttribute(PDO::ATTR_MULTATE_PREPARES,false);
  1. 挖掘关键字
SET NAMES
character_set_client='gbk'
mysql_set_character('gbk')

二次urldecode注入

  1. 原理
    提交到服务器的数据会自动进行一次url解码,如果服务器段再调用urldecode()或者rawurldecode()函数来对参数进行解码则会造成二次解码。这样 %2527在第一次解码后变为 %27从而绕过过滤再次经过urldecode()、rawurldecode()解码后变为
  2. 例子
    以下面代码为例:
<?php
$link = mysqli_connect("localhost", "root", "147258zhao") or die("Cannot contact server");
mysqli_select_db($link, "test") or die("Cannot use database");
$id = urldecode(addslashes($_GET['id']));
$sql = "SELECT * FROM User where id = '$id'";
echo $sql."<br>";
$request = mysqli_query($link,$sql);
while($field = mysqli_fetch_assoc($request)){
	echo var_dump($field);
}
mysqli_close($link);
?>

result
3. 挖掘关键字

urldecode()
rawurldecode()

漏洞防范

  • GPC魔术引号
  • 过滤函数和类
addslashes()
mysql_real_escape_string()
mysql_escape_string()
intval()
自定义类及函数
  • PDO预编译

XSS

原理

后台对于用户输入的数据未经过滤便直接输出到页面中,倘若用户输入的数据中存在恶意指令浏览器则会将其执行。XSS造成的影响可以用一句话来概括:

前段页面能做的他都能做

例子

<?php
echo $_GET['id'];
?>

访问效果如下:
在这里插入图片描述

挖掘关键字

print()
print_r()
echo()
printf()
sprintf()
die()
var_dump()
var_export()

防范

  • 特殊HTML实体转码
  • 标签时间属性黑白名单

CSRF

原理

类似于XSS,但是它的目的不向XSS那样盗取COOKIE等,而是伪造请求做一些触发这个漏洞角色所能做的事情。

例子

WooYun-2014-64886

挖掘关键

观察后台是否验证token或者referer

防范

防范的关键就是验证请求是否真正来自用户,这就要一些攻击者不能确定的元素,比如在页面

  • 增加token/referer验证
<?php
session_start();
function set_token(){
    $_SESSION['token'] = md5(time()+rand(1,1000));
}
function check_token(){
    if(isset($_POST['token'])&&$_POST['token']===$_SESSION['token']){
        return true;
    }else{
        return false;
    }
}
if(isset($_SESSION['token'])&&check_token()){
    echo "success";
}else{
    echo "failed";
}
set_token();
?>
<form method="POST">
    <input type="hidden" name="token" value="<?= $_SESSION['token']?>">
    <input type="submit">
</form>

  • 增加验证码

猜你喜欢

转载自blog.csdn.net/Blood_Pupil/article/details/82873324