Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Preventing java agents from attaching at runtime

Reposting this here as advised by security.stackexchange

How can I prevent Java Agents from attaching to my running java application at runtime?

I am able to prevent users from launching my application with a javaagent at startup by scanning the command line arguments:

List<String> args = ManagementFactory.getRuntimeMXBean().getInputArguments();
for(String arg : args)
{
    if(arg.contains("-javaagent"))
    {
        System.out.println("Detected Java Agent: " + arg);
        logIncident(0x01);
        Runtime.getRuntime().exit(0);
    }
}

However this does not prevent people from attaching at runtime visualvm style.

I heard that you can use the -XX:+DisableAttachMechanism flag to disable this, however when I tried to use jinfo -flag +DisableAttachMechanism <PID> I got an exception telling me that it is not possible to modify this argument at runtime.

Another possibility I considered was modifying the system security manager to disallow all AttachPermission's (I believe that this needs to be allowed for java agents to attach), but I'm not sure where to start.

Would really appreciate any guidance on how to implement the ideas Ive already come up with, as well as suggestions for any new ideas.

Edit: I created a custom security manager to deny all AttachPermissions however it appears to not be triggered in the jar being attached to but rather the agent itself. Now I am looking to enable DisableAttachMechanism at runtime, but I cant seem to find any references to this in OpenJDK source?

like image 577
1hdsaifz1789h1hfdsofh Avatar asked Dec 12 '19 13:12

1hdsaifz1789h1hfdsofh


People also ask

Can you have multiple Java agents?

The -javaagent option may be used multiple times on the same command-line, thus starting multiple agents. The premain methods will be called in the order that the agents are specified on the command line. More than one agent may use the same <jarpath> .

How does a Java agent work?

In general, a java agent is just a specially crafted jar file. It utilizes the Instrumentation API that the JVM provides to alter existing byte-code that is loaded in a JVM. For an agent to work, we need to define two methods: premain – will statically load the agent using -javaagent parameter at JVM startup.

Where do I put Javaagent?

To pass the -javaagent argument on WebSphere: From the admin console, select Servers > Application servers > (select a server) > Configuration > Service Infrastructure > Java and Process Management. Select Process Definition > Additional Properties, then select Java Virtual Machine. Select Apply, then select Save.


1 Answers

Exit if this returns true:

  private static boolean acceptsJavaAgentsAttachingToThisJvm() {
    HotSpotDiagnosticMXBean vm = ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class);
    VMOption opt = vm.getVMOption("DisableAttachMechanism");
    return "false".equals(opt.getValue()) || opt.isWriteable();
  }

which should defend against casual usecases.

like image 141
drekbour Avatar answered Oct 17 '22 22:10

drekbour