WebShell绕过技巧

概述

在webshell上线木马,他的进程链是cmd,若双击木马,它的进程链是explorer.exe

核晶查杀机制

当我们在webshell终端执行cmd命令时,不要一上来就whoami,这样很容易会被杀软查杀,从而导致杀软的查杀力度越来越严格,毕竟360核晶是带机器学习引擎的

image-20230706100519333

最好先执行tasklist命令列出目标系统的所有进程,看看是否有杀毒软件

image-20230707210931111

有时候你执行calc.exe命令也会被核晶捕捉到,讲道理calc命令就是一个正常的命令,那么为什么会报毒呢?我觉得这可能是一开始你的一些操作被杀软捕捉到了,例如上述我说的执行whoami命令,一旦杀软的查杀力度上来了,你后面起的任何进程都会被查杀

image-20230706102328691

360核晶查杀还涉及到进程链问题,当我们在webshell终端执行notepad.exe命令时,它的cmd进程是起在w3wp.exe进程下

w3wp.exe 是 Windows Web 服务器 (IIS) 中的 Worker Process(工作进程)。在你的 web 应用程序接收到一个请求时,该请求实际上是由一个或多个这样的进程来处理的

image-20230706104523446

如果在虚拟机中直接打开cmd执行notepad.exe,可以发现cmd进程是起在explorer进程下,这种方式起的进程是不会被杀软查杀的

image-20230706104945850

我将白+黑程序上传至目标主机,随后在目标主机中点击白程序,CS能够成功上线

image-20230707212917711

但是在webshell的cmd终端执行白程序会被查杀,就连你劫持的哪个dll都会被杀软捕捉到

image-20230707213404445

0x1.aspx马加载shellcode

实战演示

以下是aspx文件的代码,主要使用C#编写,导入了SystemSystem.Runtime.InteropServices命名空间。

然后,它声明了两个P/Invoke方法,这些方法是.NET中用于调用Windows API或者其他非.NET DLL的方法。这两个方法是VirtualAllocCreateThread,它们来自kernel32.dll,一个是Windows系统的核心库

接下来是Page_Load方法,这是ASP.NET页面生命周期中的一个重要事件。在页面首次加载和后续的请求中,它都会被触发

在上述代码中,填写C#的shellcode要注意w3wp.exe的架构,w3wp.exe是IIS的工作进程,我们的aspx文件都是通过w3wp.exe来解析的,就如此处的w3wp.exe的架构是x64的,那就需要填写x64的shellcode

image-20230707120718329

360和火绒都不查杀此文件,但是WindowsDefender会查杀

image-20230707121418517

image-20230707221833150

网页访问aspx文件时,cobaltstrike上线成功,并且360核晶也没有拦截

image-20230707130455544

在beacon执行getuid命令也不会被拦截,简单总结下,此类技术之所以能躲避杀软的检测,是因为w3wp.exe进程本身是正常存在的,并且经常在正常操作中被使用,这也导致杀软不敢轻易就关掉此进程

image-20230707223429319

免杀处理

WindowsDefender会查杀aspx代码里的shellcode, 只需对shellcode进行异或加密就能绕过, 以下是修改后的aspx文件代码

以下是xor加密shellcode的C#代码

0x2.jsp马研究

查杀机制

当我在webshell终端执行tasklistwhoami命令时,核晶没有出现报毒

image-20230711120654971

当执行白+黑时被核晶查杀了,通过ProcessExplorer查看进程链可知,cmd进程是起在javaw.exe下的,javaw.exe 主要用于运行解析和执行 JSP 文件的 Servlet 容器,所以说这还是涉及到进程链的检测

image-20230711162006664

image-20230711161922059

冰蝎反弹shell

在核晶开启时,使用冰蝎的反弹shell功能可以直接使目标主机上线,并且后续的执行命令也不会出现报毒,这是因为shellcode注入的进程是javaw.exe,这是一个白进程,360也不敢随意终止此进程,毕竟这会影响到整个Web应用的运行状态

image-20240109215743980
image-20240109215748385

加载动态链接库

此处所讲的知识点和代码都是从倾旋师傅的文章中获取的,讲解得十分全面,尤其是其中的代码,很值得去学习和积累

JAVA加载动态链接库的三种方式

1.Runtime.getRuntime().load()

Runtime.getRuntime().load()是一个在运行时期加载库文件的方法。它是Runtime类的一个实例方法,可以加载系统路径或者其他指定路径下的动态链接库。使用这种方式时,需要提供库文件的绝对路径

2.System.load

System.load()是另一种加载动态链接库的方法。与Runtime.getRuntime().load()相似,它也需要库文件的绝对路径。这个方法是System类的静态方法

3.Native Load

这种方式尝试找到并调用一个名为NativeLibLoader的类中的loadLibrary方法,这是更复杂和灵活的加载方式,允许更细致地控制加载过程

Webshell代码

由于倾旋师傅给出的webshell代码无法在Tomcat9.0及以上版本运行,这是因为sun.misc.BASE64Decoder在Java8及以前的版本里是可用的,但是之后的版本就要使用java.util.Base64替代sun.misc.BASE64Decoder,以下是我稍微调整过后的代码

此Webshell的主要功能就是上传并加载DLL文件和执行shellcode

RandomAccessFile类的功能是对文件内容进行读写操作,此处我们用它来实现webshell与命名管道的通信。例如先创建一个RandomAccessFile 对象来访问一个名为pipeName的命名管道,随后可通过此对象读取管道中接收的数据或向管道写入数据

Webshell通过HTTP请求头中的WWW-Authenticate字段的值来接收来自攻击者的指令,随后通过命名管道传递给服务器上的恶意进程,以此实现数据交互

Dll的编写

此处DLL的编写值得学习的地方主要是对命名管道的灵活运用,命名管道是一个先进先出的结构,也就是说第一个写入的字节将是第一个被读取的,当使用ReadFile函数从命名管道读取数据时,被读取的数据就会从管道中消失

比如在webshell的一次请求中,将0x01(操作指令)和shellcode写入管道中,第一次读取的内容会是0x01,第二次读取的内容会是shellcode

除此之外,我建议编译时将VisualStudio的平台工具集修改为LLVM(clang-cl),这样能够减小静态查杀率

image-20240109215012299

实例演示

首先对生成的dll文件进行Base64编码

image-20240109214657398

抓取webshell的请求包,将WWW-Authenticate字段值修改为load表示加载dll,提交的内容填上dll base64编码后的内容

image-20240109211201955

在第二次发给webshell的请求中,将WWW-Authenticate的值修改为shellcode,提交的内容填上shellcode的base64编码,这样表示加载shellcode

image-20240109214750177

上线的进程是javaw,是一个普通权限,通常tomcat是以local service权限运行的,倾旋师傅的文章里提到,将土豆提权的功能写入dll中以此实现shellcode执行时是上线管理员的权限,不过我更倾向于在CobaltStrike的bof去实现吧

image-20240109214152797

0x3.php马

待定

参考文章

  • https://paper.seebug.org/1953/#0x06-java

最后更新于