<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    PHP文件包含漏洞(利用phpinfo)

    Path php/inclusion

    PHP文件包含漏洞中,如果找不到可以包含的文件,我們可以通過包含臨時文件的方法來getshell。因為臨時文件名是隨機的,如果目標網站上存在phpinfo,則可以通過phpinfo來獲取臨時文件名,進而進行包含。

    參考鏈接:

    漏洞環境

    執行如下命令啟動環境:

    docker-compose up -d
    

    目標環境是官方最新版PHP7.2,說明該漏洞與PHP版本無關。

    環境啟動后,訪問http://your-ip:8080/phpinfo.php即可看到一個PHPINFO頁面,訪問http://your-ip:8080/lfi.php?file=/etc/passwd,可見的確存在文件包含漏洞。

    利用方法簡述

    在給PHP發送POST數據包時,如果數據包里包含文件區塊,無論你訪問的代碼中有沒有處理文件上傳的邏輯,PHP都會將這個文件保存成一個臨時文件(通常是/tmp/php[6個隨機字符]),文件名可以在$_FILES變量中找到。這個臨時文件,在請求結束后就會被刪除。

    同時,因為phpinfo頁面會將當前請求上下文中所有變量都打印出來,所以我們如果向phpinfo頁面發送包含文件區塊的數據包,則即可在返回包里找到$_FILES變量的內容,自然也包含臨時文件名。

    在文件包含漏洞找不到可利用的文件時,即可利用這個方法,找到臨時文件名,然后包含之。

    但文件包含漏洞和phpinfo頁面通常是兩個頁面,理論上我們需要先發送數據包給phpinfo頁面,然后從返回頁面中匹配出臨時文件名,再將這個文件名發送給文件包含漏洞頁面,進行getshell。在第一個請求結束時,臨時文件就被刪除了,第二個請求自然也就無法進行包含。

    這個時候就需要用到條件競爭,具體流程如下:

    1. 發送包含了webshell的上傳數據包給phpinfo頁面,這個數據包的header、get等位置需要塞滿垃圾數據
    2. 因為phpinfo頁面會將所有數據都打印出來,1中的垃圾數據會將整個phpinfo頁面撐得非常大
    3. php默認的輸出緩沖區大小為4096,可以理解為php每次返回4096個字節給socket連接
    4. 所以,我們直接操作原生socket,每次讀取4096個字節。只要讀取到的字符里包含臨時文件名,就立即發送第二個數據包
    5. 此時,第一個數據包的socket連接實際上還沒結束,因為php還在繼續每次輸出4096個字節,所以臨時文件此時還沒有刪除
    6. 利用這個時間差,第二個數據包,也就是文件包含漏洞的利用,即可成功包含臨時文件,最終getshell

    漏洞復現

    利用腳本exp.py實現了上述過程,成功包含臨時文件后,會執行<?php file_put_contents('/tmp/g', '<?=eval($_REQUEST[1])?>')?>,寫入一個新的文件/tmp/g,這個文件就會永久留在目標機器上。

    用python2執行:python exp.py your-ip 8080 100

    可見,執行到第289個數據包的時候就寫入成功。然后,利用lfi.php,即可執行任意命令:

    本文章首發在 網安wangan.com 網站上。

    上一篇 下一篇
    討論數量: 0
    只看當前版本


    暫無話題~
    亚洲 欧美 自拍 唯美 另类