1. 程式人生 > >漏洞挖掘與防範(基礎篇)

漏洞挖掘與防範(基礎篇)

文章目錄

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等,而是偽造請求做一些觸發這個漏洞角色所能做的事情。

例子

挖掘關鍵

觀察後臺是否驗證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>

  • 增加驗證碼