Pwnable.kr - Toddler Bottle

This is a writeup with some hints to help you out with basic concepts and doesn't give direct answers or direct flags so that you enjoy the wargame like I did and not spoil it for anyone. You can't simply read this writeup and understand, you need to spend some time on the question before referring to this writeup.

Passcode:

In the code there is scanf function being called with argument as integer and scanf takes integer pointer and then writes to the address specified for variable which has to be written with value. In function main first,welcome() is called and just after it login() is called. With scanf() function in welcome() we can write a string of 100 bytes and then this can be seen in disassembly that name value is stored at [ebp-0x70](0x70 =112) and passcode1 address(where passcode1 value will be written by scanf in login) is stored at [ebp-0x10](0x10=16) in stack.As we can write 100 bytes string in name, with a padding of 96(112-16)bytes, we can write the address where value of passcode1 will be written . And then we can give a value in passcode (which will be an integer) that we want to execute. So what we can do is write a got table entry with system call entry and in this way redirect the code execution so . So we'll first overwrite the passcode1 address with got table entry and then write to it the address of system("/bin/sh") call and when ffush or printf will be called we get the shell instead .So disassemble fflush or printf in login and copy the address in our exploit and for the integer value to be wriiten at that address we take (0x080485e3 =134514147) in our exploit so this is how our exploit looks like

python -c "print 'A' * 96 + '\x00\xa0\x04\x08' + '134514147\n'" | ./passcode

Random:

This was pretty easy. From gdb we get the value of random integer and that remains same so we take its XOR with 0xdeadbeef and convert it in int and pass it as key and gets the flag.

Input:

Stage1

Make an array of 99 characters (100 arguments) and change value of index (ord('A')-1)and (ord('B')-1) to specified strings and then execute the input file in same directory with subprocess.Popen func in python with first argument as array with two entries (file to be executed and arguments array ) and other two arguments as stdin and stderr.

Stage2

Use os.pipe to create a pipe and return a pair of file descriptors(r,w ) usable for reading and writing and specify stdinr and stdinw (similarly for stderr).And then with os.write, write into stdinw and stderrw as specified in problem and then we pass in subprocess.Popen stdin and stderr as stdinr an dstderrr respectively as arguments.

Stage3

Create variable environ as required in challenge and pass it as argument in subprocess.Popen.

Stage4

Open file "\x0a" file and open it and write into it "\x00\x00\x00\x00"

Stage5

Just send the string over a socket connection in exploit.

Now, copy this exploit to /tmp and we need to create a symlink to file flag in order to open it with our script.

Leg:

In ARM architecture, r1, r2, r3 and r4 are registers similar to eax, ebx, ecx and edx and pc stands for program counter. for the func key1(),

mov r3, pc; mov r0, r3;
this will set r0 to pc = 0x00008cdc ( In ARM mode pc = current place +8) For func key2(),
add r6, pc, #1;bx r6;
(bx stands for branch and exchange instruction which means that according to lsb (least significant bit) of the address to branch to , the process will treat the next instruction as ARM or as thumb mode.In thumb mode,16 bits registers are there and for less memory targets thumb allows code to be smaller and faster.So bx changes the ARM to thumb) and then
mov r3, pc;adds r3, #4; mov r0, r3;
so key2 = pc + 4 and pc in thumb mode = current address +4 so key2 = (0x00008d08 + 4) Key3 is equal to final value of link register which is equal to next instruction n disassembly after func key3 is called. So key3 = 0x00008d80. Add values of key1, key2 and key3 and give that as ouput to get the flag.

Mistake:

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

Here there is no bracket for fd value assignment so due to operator priority of '<' is more than "=" if the file opens correctly then open will be definitely greter than 0 and hence fd will be set to 0(false condition). So in the line "read(fd,pw_buf,PW_LEN)" , instead of reading from password file it will read from stdin and that's why we see on running file that after printing "Do not bruteforce" it waits for a input.So then with scanf another input is taken pw_buffer and whose xor is taken and compared with input passed .XOR key is 1.So Xor of 111111111 with key 1 will give 0000000000 so we give 000000000 as first input and 111111111 as second output and gets the flag

This is my first blog post and written quite improperly. So, feel free to correct me and suggestions are more than welcome. XD

Harsha Sharma

A junior year student pursuing Bachelor in Technology in Engineering Physics in Indian Institute of Technology

Roorkee, Uttarakhand