SQL注入原理及代碼分析(二)


前言

上一篇文章中,對union注入、報錯注入、布爾盲注等進行了分析,接下來這篇文章,會對堆疊注入、寬字節注入、cookie注入等進行分析。第一篇文章地址:SQL注入原理及代碼分析(一)
如果想要了解Access的詳細手工注入過程,可以看我的這篇文章:https://www.cnblogs.com/lxfweb/p/12643011.html
如果想要了解MySQL的詳細手工注入過程,可以看我的這篇文章:https://www.cnblogs.com/lxfweb/p/12655316.html
如果想要了解SQL server的詳細手工注入過程,可以看我的這篇文章:https://www.cnblogs.com/lxfweb/p/12675023.html

SQL注入原理

SQL注入漏洞的產生需要滿足兩個條件

  1. 參數用戶可控:前端傳給后端的參數內容是用戶可以控制的。
  2. 參數帶入數據庫查詢:傳入的參數拼接到SQL語句並帶入數據庫查詢。
    所以在實際環境中開發者要秉持“外部參數皆不可信原則”進行開發。

幾種常見的SQL注入攻擊

堆疊查詢注入

先說一下堆疊查詢,堆疊查詢可以執行多條語句,多語句之間以分號隔開。堆疊注入就是利用這個特點,在第二條SQL語句中構造自己要執行的句子。
然后看代碼

<?php
try {
    $conn = new PDO("mysql:host=localhost;dbname=dvwa", "root", "XFAICL1314");
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $stmt = $conn->query("SELECT * FROM users where `user_id`='" . $_GET['id']."'");
    $result = $stmt->setFetchMode(PDO::FETCH_ASSOC);
    foreach ($stmt->fetchAll() as $k => $v) {
        foreach ($v as $key => $value) {
            echo $value;
        }
    }
    $dsn = null;
}
catch (PDOException $e)
{
    echo "error";
}
$conn = null;
?>

在堆疊注入頁面中,程序獲取GET參數id,使用PDO的方式進行數據查詢,但是還是將id拼接到SQL語句中,導致POD沒起到預編譯的效果。程序仍然存在SQL注入。使用PDO執行SQL語句時,可以執行多條語句,但只返回第一條執行的結果。所以第二條語句中可以使用時間盲注等來會獲取數據。時間注入上一篇文章分析了。
所以咱們構造的語句為:
';select if(substr(user(),1,1)=0x72,sleep(5),1)%23


我們發現構造的時間注入語句成功執行,之后可以通過這種方法猜解出,庫名,表名,字段及內容。

寬字節注入攻擊

先說一下寬字節注入原理,如果我們注入的參數為字符型,我們構造自己的SQL語句的時候需要用單引號閉合前面的SQL語句,但是咱們輸入的單引號被轉義(反斜杠)了,導致參數無法逃逸單引號的包圍,一般情況是沒有SQL注入的,不過有一個特例,那就是當數據庫的編碼為GBK時,可能存在寬字節注入,具體操作是先在url后添加%df,在添加單引號,因為反斜杠的編碼為%5c,而在GBK編碼中,%df%5c是繁體字"綅"。所以單引號逃逸,就可以執行咱們構造的SQL語句了。
然后看代碼

<?php
$conn = mysql_connect('localhost','root','XFAICL1314') or die('abd!');
mysql_select_db('dvwa',$conn) OR emMsg("數據庫連接失敗");
mysql_query("SET NAMES 'gbk'",$conn);
$id = addslashes($_GET['id']);
$sql="select * from users where user_id='$id'limit 0,1";
$result = mysql_query($sql,$conn) or die(mysql_error());
$row = mysql_fetch_array($result);
if($row)
{
    echo $row['user'].":".$row['password'];
}
else
{
    print_r(mysql_error());
}
?>
</font>
<?php
echo "<br><br>SQL : ".$sql."<br><br>";
?>

在寬字節注入頁面中,程序獲取GET參數id,並對參數id使用addslashes()轉義,然后拼接到SQL語句中,進行查詢。現在進行嘗試。
構造語句:%df' and 1=1%23

我們發現單引號成功逃逸,之后的過程就是和union注入一樣了,猜表,猜字段,獲得數據。

cookie注入攻擊

先看代碼

<?php
$id=$_COOKIE['id'];
$value="1";
setcookie("id",$value);
$con=mysqli_connect("localhost","root","XFAICL1314","dvwa");
if(mysqli_connect_error())
{
    echo "連接失敗:". mysqli_connect_error();
}
$result = mysqli_query($con,"select * from users where `user_id`=".$id);
if (!$result){
    printf("Error:%s\n",mysqli_error($con));
    exit();
}
$row= mysqli_fetch_array($result);
echo $row['user'].":". $row['password'];
echo "<br>";
?>

在cookie注入頁面中,程序通過$_COOKIE獲取到參數id,並直接將id拼接到select語句中進行查詢,如果有結果,將解惑輸出到頁面。
我們打開頁面,發現url中沒有GET參數。通過抓包發現參數id在cookie中。

接着構造語句:and 1=2 拼接到cookie中,發現報錯了,可以注入,之后也是用union注入的一些語句。

包括用order by 判斷字段,接着使用聯合查詢。得到表名,字段名和數據。
cookie注入還有一種情況,那就是,程序用$_REQUEST[]來接收用戶的輸入,但是程序的防御程序只是對GET和POST接收的輸入做了防御。沒考慮cookie,這就導致了cookie注入。和上面的操作方式一樣,只需要抓包,將有注入點的參數移到cookie中就可以了。

XFF注入攻擊

XFF注入原理是通過修改X-Forwarded-For頭對帶入系統的dns進行sql注入,從而得到網站的數據庫內容。X-Forwarded-For:簡稱XFF頭,它代表客戶端,也就是HTTP的請求端真實的IP。
這里用墨者學院的XFF注入靶場來做演示。
打開靶場,發現是登陸頁面,隨便輸入賬號和密碼。發現返回客戶機ip,猜測是由XFF控制。

抓包,添加XFF頭,改為1.1.1.1,發現也更改,說明存在XFF注入。

接着使用報錯注入的方法,用updataxml()等函數將我們需要的數據查詢出來,詳細查詢過程這里就不寫了,查詢到的賬號密碼的語句為:

' and updatexml(1,concat(0x7e,(select concat(username,0x7e,password) from user limit 0,1) ,0x7e),1) or '1'='1

小結

兩篇文章將常見的幾種SQL注入都簡單分析了一遍,並構造了相關有缺陷的代碼用來加深理解。希望對大家有所幫助。
參考文獻:《Web安全攻防》


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM