1. 程式人生 > >SQL注入原理及程式碼分析(二)

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

#前言 上一篇文章中,對union注入、報錯注入、布林盲注等進行了分析,接下來這篇文章,會對堆疊注入、寬位元組注入、cookie注入等進行分析。第一篇文章地址:[SQL注入原理及程式碼分析(一)](https://www.cnblogs.com/lxfweb/p/13236372.html) 如果想要了解Access的詳細手工注入過程,可以看我的這篇文章:[https://www.cnblogs.com/lxfweb/p/12643011.html](https://www.cnblogs.com/lxfweb/p/12643011.html) 如果想要了解MySQL的詳細手工注入過程,可以看我的這篇文章:[https://www.cnblogs.com/lxfweb/p/12655316.html](https://www.cnblogs.com/lxfweb/p/12655316.html) 如果想要了解SQL server的詳細手工注入過程,可以看我的這篇文章:[https://www.cnblogs.com/lxfweb/p/12675023.html](https://www.cnblogs.com/lxfweb/p/12675023.html) #SQL注入原理 SQL注入漏洞的產生需要滿足兩個條件 1. 引數使用者可控:前端傳給後端的引數內容是使用者可以控制的。 2. 引數帶入資料庫查詢:傳入的引數拼接到SQL語句並帶入資料庫查詢。 所以在實際環境中開發者要秉持“外部引數皆不可信原則”進行開發。 #幾種常見的SQL注入攻擊 ##堆疊查詢注入 先說一下堆疊查詢,堆疊查詢可以執行多條語句,多語句之間以分號隔開。堆疊注入就是利用這個特點,在第二條SQL語句中構造自己要執行的句子。 然後看程式碼 ``` 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` ![](https://img2020.cnblogs.com/blog/1996712/202007/1996712-20200709165354278-5780233.png) ![](https://img2020.cnblogs.com/blog/1996712/202007/1996712-20200709165301358-1385446902.png) 我們發現構造的時間注入語句成功執行,之後可以通過這種方法猜解出,庫名,表名,欄位及內容。 ##寬位元組注入攻擊 先說一下寬位元組注入原理,如果我們注入的引數為字元型,我們構造自己的SQL語句的時候需要用單引號閉合前面的SQL語句,但是咱們輸入的單引號被轉義(反斜槓)了,導致引數無法逃逸單引號的包圍,一般情況是沒有SQL注入的,不過有一個特例,那就是當資料庫的編碼為GBK時,可能存在寬位元組注入,具體操作是先在url後新增%df,在新增單引號,因為反斜槓的編碼為%5c,而在GBK編碼中,%df%5c是繁體字"綅"。所以單引號逃逸,就可以執行咱們構造的SQL語句了。 然後看程式碼 ```
SQL : ".$sql."

"; ?> ``` 在寬位元組注入頁面中,程式獲取GET引數id,並對引數id使用addslashes()轉義,然後拼接到SQL語句中,進行查詢。現在進行嘗試。 構造語句:`%df' and 1=1%23` ![](https://img2020.cnblogs.com/blog/1996712/202007/1996712-20200709173023228-49514705.png) 我們發現單引號成功逃逸,之後的過程就是和union注入一樣了,猜表,猜欄位,獲得資料。 ##cookie注入攻擊 先看程式碼 ``` "; ?> ``` 在cookie注入頁面中,程式通過$_COOKIE獲取到引數id,並直接將id拼接到select語句中進行查詢,如果有結果,將解惑輸出到頁面。 我們開啟頁面,發現url中沒有GET引數。通過抓包發現引數id在cookie中。 ![](https://img2020.cnblogs.com/blog/1996712/202007/1996712-20200709184121862-337546353.png) 接著構造語句:`and 1=2 `拼接到cookie中,發現報錯了,可以注入,之後也是用union注入的一些語句。 ![](https://img2020.cnblogs.com/blog/1996712/202007/1996712-20200709184440819-1269476039.png) 包括用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控制。 ![](https://img2020.cnblogs.com/blog/1996712/202007/1996712-20200709190359189-1193703851.png) 抓包,新增XFF頭,改為1.1.1.1,發現也更改,說明存在XFF注入。 ![](https://img2020.cnblogs.com/blog/1996712/202007/1996712-20200709190950471-1529237135.png) 接著使用報錯注入的方法,用updataxml()等函式將我們需要的資料查詢出來,詳細查詢過程這裡就不寫了,查詢到的賬號密碼的語句為: ``` ' and updatexml(1,concat(0x7e,(select concat(username,0x7e,password) from user limit 0,1) ,0x7e),1) or '1'='1 ``` ![](https://img2020.cnblogs.com/blog/1996712/202007/1996712-20200709191629109-1111642287.png) #小結 兩篇文章將常見的幾種SQL注入都簡單分析了一遍,並構造了相關有缺陷的程式碼用來加深理解。希望對大家有所幫助。 參考文獻:《Web安全