漏洞挖掘與防範(基礎篇)
阿新 • • 發佈:2018-12-13
文章目錄
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就變成了
- 例子 以下面程式碼為例:
<?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);
- 挖掘關鍵字
SET NAMES
character_set_client='gbk'
mysql_set_character('gbk')
二次urldecode注入
- 原理 提交到伺服器的資料會自動進行一次url解碼,如果伺服器段再呼叫urldecode()或者rawurldecode()函式來對引數進行解碼則會造成二次解碼。這樣 %2527在第一次解碼後變為 %27從而繞過過濾再次經過urldecode()、rawurldecode()解碼後變為 ’ 。
- 例子 以下面程式碼為例:
<?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);
?>
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>
- 增加驗證碼