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

前言

上一篇文章中,對union注入、報錯注入、布爾盲注等進行了分析,接下來這篇文章,會對堆疊注入、寬字節注入、cookie注入等進行分析。第一篇文章地址:SQL注入原理及代碼分析(一)
若是想要了解Access的詳細手工注入過程,能夠看個人這篇文章:http://www.javashuo.com/article/p-kgpywxsu-nb.html
若是想要了解MySQL的詳細手工注入過程,能夠看個人這篇文章:http://www.javashuo.com/article/p-nmtkbjqi-nb.html
若是想要了解SQL server的詳細手工注入過程,能夠看個人這篇文章:http://www.javashuo.com/article/p-uhllaflr-nb.htmlphp

SQL注入原理

SQL注入漏洞的產生須要知足兩個條件html

  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


咱們發現構造的時間注入語句成功執行,以後能夠經過這種方法猜解出,庫名,表名,字段及內容。mysql

寬字節注入攻擊

先說一下寬字節注入原理,若是咱們注入的參數爲字符型,咱們構造本身的SQL語句的時候須要用單引號閉合前面的SQL語句,可是我們輸入的單引號被轉義(反斜槓)了,致使參數沒法逃逸單引號的包圍,通常狀況是沒有SQL注入的,不過有一個特例,那就是當數據庫的編碼爲GBK時,可能存在寬字節注入,具體操做是先在url後添加%df,在添加單引號,由於反斜槓的編碼爲%5c,而在GBK編碼中,%df%5c是繁體字"綅"。因此單引號逃逸,就能夠執行我們構造的SQL語句了。
而後看代碼web

<?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注入同樣了,猜表,猜字段,得到數據。sql

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安全攻防》cookie

相關文章
相關標籤/搜索