Return to Library: 라이브러리 함수로 NX를 우회하고 셸을 획득하는 공격 기법
- rtl.c
// Name: rtl.c
// Compile: gcc -o rtl rtl.c -fno-PIE -no-pie
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
const char* binsh = "/bin/sh";
int main() {
char buf[0x30];
setvbuf(stdin, 0, _IONBF, 0);
setvbuf(stdout, 0, _IONBF, 0);
// Add system function to plt's entry
system("echo '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;
}
- checksec; 보호 기법 확인
- NX로 인해 buf에 셸 코드를 주입하고 실행할 수 없음
- "/bin/sh"의 주소, system 함수의 PLT 주소를 알고 있음
- x86-64의 함수 호출 규약(6개의 인자를 rdi, rsi, rdx, rcx, r8, r9에 순서대로 저장)에 따라 rdi=<"/bin/sh"의 주소> 인 상태에서 system 함수를 호출해야 함
리턴 가젯(Return gadget): ret 명령어로 끝나는 어셈블리 코드 조각
- 리턴 가젯은 반환 주소를 덮는 공격의 유연성을 높여서 익스플로잇에 필요한 조건을 만족할 수 있도록 함
1. ("pop rdi; ret") 주소
2. "/bin/sh" 주소 - 전역 상수가 저장되는 text 영역의 주소는 바뀌지 않음
3. system plt 주소
익스플로잇
- pop rdi: rsp가 가리키는 값을 rdi에 넣고, rsp값 8 증가
- ret; pop rip, jmp rip = 스택 최상단 값을 rip 값에 넣고, 그 값이 가리키는 곳으로 jmp
- main 함수의 ret 실행 시 rip는 return addr(pop rdi; ret 가젯의 주소를 넣어줄 거임)를 가리키고, rsp 값은 8 증가
- 그럼 현재 프로그램의 실행 흐름은 pop rdi; ret 가젯임
- pop rdi; rsp 값을 rdi에 넣고, rsp값 8 증가시키므로 rdi에 "/bin/sh"의 주소 저장
- ret; rsp 값인 system함수의 주소를 rip에 넣고, jmp
- 현재 프로그램의 실행 흐름은 system 함수가 되었고, 첫 번째 인자가 저장되는 rdi에 "/bin/sh"의 주소가 저장되어 있으므로 쉘 획득
드림핵 워게임
'보안' 카테고리의 다른 글
[시스템해킹] Return Oriented Programming(ROP); ret2main (0) | 2024.04.26 |
---|---|
[시스템해킹] Return Oriented Programming(ROP); GOT Overwrite (0) | 2024.04.24 |
[시스템해킹] Background: Library (0) | 2024.04.23 |
[시스템해킹] NX & ASLR (0) | 2024.04.23 |
[시스템해킹] Background: Calling Convention(함수 호출 규약) (0) | 2024.04.23 |