Skip to content

WowSuchRicky/pwnable.kr

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 

Repository files navigation

pwnable.kr

pwnable.kr writeups as I go

fd

"Mommy! What is a file descriptor in Linux?"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char buf[32];
int main(int argc, char* argv[], char* envp[]){
        if(argc<2){
                printf("pass argv[1] a number\n");
                return 0;
        }
        int fd = atoi( argv[1] ) - 0x1234;
        int len = 0;
        len = read(fd, buf, 32);
        if(!strcmp("LETMEWIN\n", buf)){
                printf("good job :)\n");
                system("/bin/cat flag");
                exit(0);
        }
        printf("learn about Linux file IO\n");
        return 0;

}

This simple program takes an integer passed in, subtracts 0x1234 from it (4660 decimal), and then tries to read 32 bytes from the file descriptor associated with the arg-0x1234. The easiest way I could think to solve this is just to make fd-4663 == 0 (fd == argv[1] = 4660), which would result in the program reading from stdin. You can then clearly see it checking for LETMEWIN\n, so I entered this, and:

fd@ubuntu:~$ ./fd 4660
LETMEWIN
good job :)
mommy! I think I know what a file descriptor is!!

flag

Papa brought me a packed present! let's open it.

Download : http://pwnable.kr/bin/flag

This is reversing task. all you need is binary

I download the binary, and open it up in IDA Pro (free) since they mention reversing. This area is actually one that I'm not that strong in, but I figured I would give it a shot anyways.

I start skimming through the binary, realizing most of it is a bunch of unreadable hex and not much actual code. What's up with that? Then I notice an interesting line:

UPX? I remember that UPX is a packer for executables, so I install the upx-ucl package (found from searching Google) on my Linux machine. Then, I unpack the binary like so: upx -d flag. I now open the new flag binary in IDA Pro once again. I start at the main() function, and notice the following few lines:

cs:flag? particularly: cs:flag. I double click on that to see what the data actually is in the data section, and:

flag? and... voila! UPX...? sounds like a delivery service :) is indeed the flag!

random

"Daddy, teach me how to use random value in programming!"

#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;
}

This program, I can immediately tell (recalling from my noob C days) does not seed the RNG at all. Thus, random() returns the same result every single time.

To find out what that number is on this system, I copy random.c (the target) to /tmp, and edit it to dislpay the result of rand(): replacing:

        random = rand();        // random value!

with

        random = rand();        // random value!
        printf("rand: %d\n", random);

then compiled using gcc random.c, followed by running the program with: ./a.out. Receiving: rand: 1804289383. (hex: 0x6b8b4567)

I head back to ~ (cd ~), then run ./random. There's one more catch, though. The password has to match 1804289383 when XOR'd with 0xdeadbeef. To undo an XOR, you can simply XOR two of the other terms, like so:

Pass ^ 0xDEADBEEF == 0xDEADBEEF ^ 6b8b4567(our hex'd version of the rand() result) And thus,

Pass = 0xdeadbeef ^ 0x6b8b4567 = 0xb526fb88 (using wolframalpha)

Lastly, you'll need to convert that result back to decimal (3039230856) (as that's how integers are passed around as strings), and thus:

random@ubuntu:~$ ./random
3039230856
Good!
Mommy, I thought libc random is unpredictable...

mistake

The hint given is "hint: operator priority". Here's the exploitable .c file (mistake.c) from the target:

#include <stdio.h>
#include <fcntl.h>

#define PW_LEN 10
#define XORKEY 1

void xor(char* s, int len){
	int i;
	for(i=0; i<len; i++){
		s[i] ^= XORKEY;
	}
}

int main(int argc, char* argv[]){
	
	int fd;
	if(fd=open("/home/mistake/password",O_RDONLY,0400) < 0){
		printf("can't open password %d\n", fd);
		return 0;
	}

	printf("do not bruteforce...\n");
	sleep(time(0)%20);

	char pw_buf[PW_LEN+1];
	int len;
	if(!(len=read(fd,pw_buf,PW_LEN) > 0)){
		printf("read error\n");
		close(fd);
		return 0;		
	}

	char pw_buf2[PW_LEN+1];
	printf("input password : ");
	scanf("%10s", pw_buf2);

	// xor your input
	xor(pw_buf2, 10);

	if(!strncmp(pw_buf, pw_buf2, PW_LEN)){
		printf("Password OK\n");
		system("/bin/cat flag\n");
	}
	else{
		printf("Wrong Password\n");
	}

	close(fd);
	return 0;
}

The mistake(s), which may or may not be obvious, are:

if(fd=open("/home/mistake/password",O_RDONLY,0400) < 0)

and

if(!(len=read(fd,pw_buf,PW_LEN) > 0))

Because the first one will (if it can open the file) always assign 0 as the fd, and then the second line will open fd(0) for reading, rather than the actual file.

Therefore:

if(!strncmp(pw_buf, pw_buf2, PW_LEN))

is actually checking against stdin twice rather than stdin vs the password file. However, there's a catch. The second input (pw_buf) has each byte XOR'd by 1. So you can't just enter AAAAAAAAAA and AAAAAAAAAA as the passwords, as the second one will get XOR'd by 1 in each block.

I decided to use I (ASCII 73) for the "password", and H (ASCII 72) for the inputted password. Therefore my H string will get XOR'd by 1 at each character, essentially turning it into a string of Is. This will match, and thus:

mistake@ubuntu:~$ ./mistake
do not bruteforce...
IIIIIIIIII
input password : HHHHHHHHHH
Password OK
Mommy, the operator priority always confuses me :(

blackjack

Hey! check out this C implementation of blackjack game!
I found it online
* http://cboard.cprogramming.com/c-programming/114023-simple-blackjack-program.html

I like to give my flags to millionares.
how much money you got?


Running at : nc pwnable.kr 9009

When you connect via netcat, you get asked if you want to play. I said Y(es). Based on the hint of "I like to give my flags to millionaires", I tried entering $99999999999999999999999 as my bet. Surprisingly (or is it?), it let me bet that much. I won, and then my screen displayed:

YaY_I_AM_A_MILLIONARE_LOL


Cash: $1410065908
-------
|S    |
|  2  |
|    S|
-------

Was it really this easy? Yup. YaY_I_AM_A_MILLIONARE_LOL is, in fact, the flag.

About

pwnable.kr writeups as I go

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published