天天看點

struts2 ajax上傳檔案 file空_檔案操作類基礎代碼審計0x00 檔案包含0x01 任意檔案删除0x02 任意檔案下載下傳0x03 檔案上傳0x04 文末

0x00 檔案包含

本地包含

本地檔案包含(Local File Include)簡稱 LFI,檔案包含在php中,一般涉及到的危險函數有

include()

include_once()

require()

require_once()

,在包含檔案名中存在可控變量的話就可能存在包含漏洞,由于這幾個函數的特性也可能産生其他漏洞,後面一一講到。

示例:

php

$file = $_GET['name'];

include($file);

?>

payload:

http://127.0.0.1/test.php?name=D:\phpstudy\PHPTutorial\MySQL\my.ini

這是個最簡單的檔案包含,沒有任何過濾。但是一般程式不會這麼寫,他一般會指定字尾,這樣我們就需要截斷來繞過了。

php

$file = $_GET['name'];

include($file . "html");

?>

在PHP5.2.x中我們可以通過使用%00來截斷後面的内容、也可以使用路徑長度截斷不過都在php5.3中被修複了。

payload:

http://127.0.0.1/test.php?name=D:\phpstudy\PHPTutorial\MySQL\my.ini%00

struts2 ajax上傳檔案 file空_檔案操作類基礎代碼審計0x00 檔案包含0x01 任意檔案删除0x02 任意檔案下載下傳0x03 檔案上傳0x04 文末

利用字元.或者/.或者./來截斷,系統檔案路徑長度限制:windows 259個byteslinux 4096個bytes。

遠端包含

遠端檔案包含漏洞(Remote File Inclusion)簡稱RFI,他需要我們的php.ini中配置

allow_url_include

allow_url_fopen

1.包含遠端檔案

需要打開

allow_url_include=On

allow_url_fopen=On

struts2 ajax上傳檔案 file空_檔案操作類基礎代碼審計0x00 檔案包含0x01 任意檔案删除0x02 任意檔案下載下傳0x03 檔案上傳0x04 文末

他可以利用?号截斷,不受版本限制

payload:

http://127.0.0.1/test.php?name=http://127.0.0.1/1.txt?

2.僞協定

file:// — 通路本地檔案系統

http:// — 通路 HTTP(s) 網址

ftp:// — 通路 FTP(s) URLs

php:// — 通路各個輸入/輸出流(I/O streams)

zlib:// — 壓縮流

data:// — 資料(RFC 2397)

glob:// — 查找比對的檔案路徑模式

phar:// — PHP 歸檔

ssh2:// — Secure Shell 2

rar:// — RAR

ogg:// — 音頻流

expect:// — 處理互動式的流

各種僞協定的使用方法網上很多,大家搜尋一下吧。

實戰審計

直接看首頁index.php

php

//單一入口模式

error_reporting(0); //關閉錯誤顯示

$file=addslashes($_GET['r']); //接收檔案名

$action=$file==''?'index':$file; //判斷為空或者等于index

include('files/'.$action.'.php'); //載入相應檔案

?>

他會包含files目錄下的檔案,因為他沒有過濾../是以可以包含任意目錄下的檔案,由于加了字尾是以漏洞存在于低版本。

struts2 ajax上傳檔案 file空_檔案操作類基礎代碼審計0x00 檔案包含0x01 任意檔案删除0x02 任意檔案下載下傳0x03 檔案上傳0x04 文末

0x01 任意檔案删除

任意檔案删除審計一般來說我們都是搜尋函數

unlink

然後回溯去看。

inc\zzz_file.php

struts2 ajax上傳檔案 file空_檔案操作類基礎代碼審計0x00 檔案包含0x01 任意檔案删除0x02 任意檔案下載下傳0x03 檔案上傳0x04 文末

首先判斷傳入的參數是否為空,然後拼接路徑,第516行中出現了一個函數

ifstrin

,我們跟進看看

struts2 ajax上傳檔案 file空_檔案操作類基礎代碼審計0x00 檔案包含0x01 任意檔案删除0x02 任意檔案下載下傳0x03 檔案上傳0x04 文末

隻是個簡單的判斷沒啥特殊情況,我們再來看看拿來調用了這個檔案。

struts2 ajax上傳檔案 file空_檔案操作類基礎代碼審計0x00 檔案包含0x01 任意檔案删除0x02 任意檔案下載下傳0x03 檔案上傳0x04 文末

function file_path( $path ) {

$list=array();

$path= substr( $path, 0, strrpos( $path, '/' ));

$list=splits($path,'/');

return $list;

}

function arr_search($arr1, $arr2 ) {

$result=false;

foreach ( $arr1 as $v ) {

if(in_array( $v,$arr2 )) return true;

}

return $result;

}

擷取參數,然後看看我們傳入的路徑是否存在這個數組裡面的值,也就是基本上是沒有過濾的,因為我們完全可以通過../ 跳回去。

payload:

POST /zzzp6p/admin/save.php?act=delfile

path=/zzzp6p/upload/../install/1install.lock

這裡我們走的下面的分支不能删除

array('php','db','mdb','tpl')

這個數組的檔案。

要删除任意檔案隻需要使用

path=/zzzp6p/runtime/../install/1.db

ifstrin()

為true走上面的分支即可。

一般來說我們任意檔案删除 是配合删除install.lock來達到網站重裝漏洞。

0x02 任意檔案下載下傳

任意檔案下載下傳常見于檔案的顯示和下載下傳的地方,一般關注的檔案是和下載下傳有關的,比如download。當然你還可以搭建源碼,來尋找能夠下載下傳的地方。

常見的下載下傳或讀取函數:

file_get_contents()

readfile()

fopen()

在網上找到個别人審計的執行個體,結合起來審計一下,用到的源碼是EarMusic20180820_UTF8

搜尋down相關的詞語,找到檔案\template\default\source\down.php

struts2 ajax上傳檔案 file空_檔案操作類基礎代碼審計0x00 檔案包含0x01 任意檔案删除0x02 任意檔案下載下傳0x03 檔案上傳0x04 文末

我們看看

$file

參數怎麼來的,先是調用函數

getfield()

,轉到函數去看看

struts2 ajax上傳檔案 file空_檔案操作類基礎代碼審計0x00 檔案包含0x01 任意檔案删除0x02 任意檔案下載下傳0x03 檔案上傳0x04 文末

不出意外應該是從資料庫中讀取路徑,再來看看

geturl()

函數

struts2 ajax上傳檔案 file空_檔案操作類基礎代碼審計0x00 檔案包含0x01 任意檔案删除0x02 任意檔案下載下傳0x03 檔案上傳0x04 文末

構造下載下傳位址,這些地方沒什麼問題,我們來看看什麼地方對儲存位址的表中插入了資料,搜尋表名

lyric

\source\user\music\ajax.php

struts2 ajax上傳檔案 file空_檔案操作類基礎代碼審計0x00 檔案包含0x01 任意檔案删除0x02 任意檔案下載下傳0x03 檔案上傳0x04 文末

我們看到

$lyric

經過

checkrename

SafeRequest

這兩個函數的清洗,先來轉到函數

SafeRequest

struts2 ajax上傳檔案 file空_檔案操作類基礎代碼審計0x00 檔案包含0x01 任意檔案删除0x02 任意檔案下載下傳0x03 檔案上傳0x04 文末

我們傳入的mode是get,然後經過

addslashes()

的轉義,下面在替換為空,也就是我們基本上是不能使用

\\

了,我們在看看

checkrename

struts2 ajax上傳檔案 file空_檔案操作類基礎代碼審計0x00 檔案包含0x01 任意檔案删除0x02 任意檔案下載下傳0x03 檔案上傳0x04 文末

這裡正則比對了我們的

.\

?iframe=

.php?

這裡完全看不懂他比對字尾為php?這個的意義何在,直接php就繞過了。

是以綜合起來就是不要帶有

\和./

這裡我們隻要傳入絕對路徑就可以了

登陸前台找到上傳歌曲的頁面在歌詞位址中插入payload

payload:

D:/phpstudy/PHPTutorial/WWW/Ear_Music/template/default/source/down.php

struts2 ajax上傳檔案 file空_檔案操作類基礎代碼審計0x00 檔案包含0x01 任意檔案删除0x02 任意檔案下載下傳0x03 檔案上傳0x04 文末

0x03 檔案上傳

檔案上傳隻有一個函數

move_uploaded_file()

一般來說,我們就可以搜尋這個函數來回溯,看他的驗證方式,是黑名單還是白名單,是否是前端限制,是否隻是簡單的驗證了檔案頭,是否是能繞過的正則比對,是否渲染了圖檔。

結合zzzphp來審計一下檔案上傳,全局搜尋

move_uploaded_file

\zzzcms\inc\zzz_file.php

struts2 ajax上傳檔案 file空_檔案操作類基礎代碼審計0x00 檔案包含0x01 任意檔案删除0x02 任意檔案下載下傳0x03 檔案上傳0x04 文末

回溯看看那裡調用了這個函數

struts2 ajax上傳檔案 file空_檔案操作類基礎代碼審計0x00 檔案包含0x01 任意檔案删除0x02 任意檔案下載下傳0x03 檔案上傳0x04 文末

典型的黑名單驗證,可以使用asa繞過,隻需要在背景添加這個擴充名

struts2 ajax上傳檔案 file空_檔案操作類基礎代碼審計0x00 檔案包含0x01 任意檔案删除0x02 任意檔案下載下傳0x03 檔案上傳0x04 文末

上傳即可,當然也可以通過上圖中的 switch分支,隻要傳入的 type不是他的類型就可以跳過背景添加這個步驟。

struts2 ajax上傳檔案 file空_檔案操作類基礎代碼審計0x00 檔案包含0x01 任意檔案删除0x02 任意檔案下載下傳0x03 檔案上傳0x04 文末

0x04 文末

對檔案的操作還見于寫入其他配置檔案,典型的有thinkphp緩存檔案寫入。

由于幾天沒更新公衆号了,一直在寫關于代碼審計wiki相關的文章,文章基本都是從0開始沒啥門檻。

文章轉載自404師傅的公衆号