Sql Sort Guess--基於排序的SQL猜解問題

問題的發現

最近在對公司後臺代碼安全審計的過程當中,發現了一種有意思的漏洞類型,一種基於排序的SQL猜解攻擊問題,咱們且抽一段片斷代碼來看一下mysql

 

<select id="queryUsers" resultType="com.kool.open.mis.dao.Users">
        select u.user_id, u.username, u.email, u.mobile, u.status,u.password_status from crm_user
        <where>
            <if test="username != null and username.trim() != ''">
                and u.`username` like concat('%',#{username},'%')
            </if>
            <if test="userId != null and userId != ''">
                and u.`user_id` != #{userId}
            </if>
        </where>
        <choose>
            <when test="sidx != null and sidx.trim() != ''">
                order by u.${sidx} ${order}
            </when>
            <otherwise>
                order by u.user_id desc
            </otherwise>
        </choose>
        <if test="offset != null and limit != null">
            limit #{offset}, #{limit}
        </if>
    </select>

 

若是直接觀測這段代碼,彷佛有SQL注入的問題,在Spring的,SPEL表達式 # 至關於佔位符,這有效的防止SQL注入的發生,因此通常對於mapper的審計,咱們就觀測是否有使用 $ 的地方,在根據對應的id去追溯使用到它的代碼,查看是否有SQL注入git

 

@Pattern(regexp = "^(?i)DESC|(?i)ASC$",name="排序",message = "order非法")

 

繼續追蹤代碼,因而發現程序對 sidx 和 order 作了安全校驗,這彷佛沒有什麼問題了, 因而這一處就經過了SDL團隊的安全測試。但是再繼續追溯起來我發現這段代碼依然存在安全問題,由於它雖然防止了SQL注入攻擊,可是它沒有對排序字段作限制,這就存在了一個問題github

 

 

 當我企圖使用password進行排序的時候,服務器成功返回了數據,那麼這意味着我可以使用order by進行排序攻擊,舉個例子,咱們查詢一張常規的用戶表sql

 

mysql> select * from crm_user;
+-----+----------+--------------+
| uid | username | password     |
+-----+----------+--------------+
|   1 | 111      | 111          |
|   2 | enoch    | apple        |
|   3 | sam      | boomsakalaka |
|   4 | belln    | zipzip       |
|   5 | mosuan   | 123456       |
|   6 | xsseng   | 123456       |
+-----+----------+--------------+
6 rows in set (0.00 sec)

 

咱們根據password對數據進行升序排序,就會發現數據由密碼的首字符1-9a-z如此升序排序數據庫

 

mysql> select * from crm_user order by password asc;
+-----+----------+--------------+
| uid | username | password     |
+-----+----------+--------------+
|   1 | 111      | 111          |
|   5 | mosuan   | 123456       |
|   6 | xsseng   | 123456       |
|   2 | enoch    | apple        |
|   3 | sam      | boomsakalaka |
|   4 | belln    | zipzip       |
+-----+----------+--------------+
6 rows in set (0.00 sec)

 

固然即使這樣也能夠後端

 

mysql> select uid from crm_user order by password asc;
+-----+
| uid |
+-----+
|   1 |
|   5 |
|   6 |
|   2 |
|   3 |
|   4 |
+-----+
6 rows in set (0.00 sec)

 

 這就有了咱們的上一處漏洞的場景,即使沒有查詢password,可是對用戶表查詢過程當中能夠由用戶自定義排序形成了安全隱患,排列出三種攻擊手法安全

 

1.基於明文儲存狀況下的密碼猜解攻擊:

假設belln的密碼是zipzip,咱們能夠經過設置一個密碼爲yzzzzzzz的用戶猜解出belln的密碼以z打頭,再經過如此反覆猜解出後面的密碼服務器

mysql> select * from crm_user order by password asc;
+-----+----------+--------------+
| uid | username | password     |
+-----+----------+--------------+
|   1 | 111      | 111          |
|   5 | mosuan   | 123456       |
|   6 | xsseng   | 123456       |
|   2 | enoch    | apple        |
|   3 | sam      | boomsakalaka |
|   7 | attack0  | yzzzzzzzzz   |
|   8 | attack1  | zhzzzzzzzz   |
|   4 | belln    | zipzip       |
|   9 | attack2  | zizzzzzzzz   |
+-----+----------+--------------+
9 rows in set (0.00 sec)

 

咱們經過attack0用戶猜解出它的密碼爲z打頭;又經過attack一、attack2猜解出其密碼前兩位爲zi;如此反覆咱們能夠獲得後臺每一位用戶的密碼,這隻須要你寫一個腳本,而且每次更改之後查詢/admin/user/list的數據進行比對,你就能夠猜解出全部用戶的口令app

 

2.弱口令形成的安全問題

 這個問題原理就比較簡單,若是用戶xsseng經過這種手法必定能夠了解到mosuan的密碼可能與他相同,由於他們的正反排序都粘合在一塊兒,以下表:xss

mysql> select uid,username,md5(password) from crm_user order by password asc;
+-----+----------+----------------------------------+
| uid | username | md5(password)                    |
+-----+----------+----------------------------------+
|   1 | 111      | 698d51a19d8a121ce581499d7b701668 |
|   5 | mosuan   | e10adc3949ba59abbe56e057f20f883e |
|   6 | xsseng   | e10adc3949ba59abbe56e057f20f883e |
|   2 | enoch    | 1f3870be274f6c49b3e31a0c6728957f |
|   3 | sam      | 8f1e77c1e064d9b3e20ada1e5ee85175 |
|   7 | attack0  | 54a6d46b0356cec2a7190898ff609af6 |
|   8 | attack1  | fa891568c546c8beec0d7aceeafe3133 |
|   4 | belln    | adc472b32512cf2f1b89641b7933af52 |
|   9 | attack2  | 3c9c1f77627d03b225bb67b538cbc352 |
+-----+----------+----------------------------------+
9 rows in set (0.00 sec)

 

這種攻擊適用於密碼hash後儲存在數據庫中,中大型互聯網公司後臺成員人數比較多,這種攻擊手法能夠在不被前臺鎖定的狀況下對用戶帳戶進行暴力破解。固然也能夠對hash值進行猜解,只要後端直接接受加密以後的新密碼,這種狀況也比較常見,由於這麼作能夠防止劫持而且給後端減輕工做量,可是若是後端接受的是明文,這種猜解將不復存在

 

3.大樣本安全問題

在思考過如上兩種問題後,我將目標放到了前臺用戶表中,這但是幾百上千萬的樣本數據。結合以上咱們會發現若是存在該漏洞,而且樣本空間足夠大, 即使後臺管理員只能查詢到前臺的用戶名,可是利用該漏洞它能夠大規模的對前臺弱口令用戶批量盜號、猜解前臺用戶支付密碼、猜解前臺用戶手機號,只要這些信息都儲存在一張表中而且沒有對排序字段進行安全限制

 

問題的嚴峻性

在我發現問題後,我搜索發現目前相關資料較少,一個是這種問題大多數存在於後臺,一個是問題的危害有待挖掘,因此我簡單的整理了一下分享給你們。爲此我還搜尋了github的代碼,以$_GET['sort']爲例,第一頁就是一段可能存在問題的代碼,我十分確信的是這個漏洞和我測試中的漏洞一摸同樣,是一個後臺用戶排序的SSG(Sql Sort Guess)問題,固然還有更多的關鍵字包括 sort、sidx、order、field等等

 

 

問題的防護

在開發過程當中,後臺對排序的需求比較大,開發人員的安全意識薄弱,就會形成這種安全問題,缺少經驗、精力的安全團隊在這方面也相對薄弱。可能不少後臺還會存在類似的問題,這就要求安全測試人員在安全測試中注意order by可能帶來的問題,以及對數據安全的治理。

 

投稿至安全客,本文轉自安全客,原文地址:https://www.anquanke.com/post/id/177572

相關文章
相關標籤/搜索