x86-64호출 규약 SYSV는 6개의 인자를 RDI, RSI, RDX, RCX, R8, R9에 순서대로 저장하여 전달한다.
더 많은 인자를 사용할 때는 스택을 추가로 이용한다.
함수의 반환 값은 RAX로 전달한다.
x86 호출 규약 cdecl은 스택을 통해 인자를 전달한다.
스택 버퍼 오버플로우는 스택에 있는 버퍼의 크기보다 큰 값을 담으려고 할 때 오버플로우가 발생하는 취약점이다.
오버플로우로 인해 버퍼 뒤에 있는 스택 값을 조작해 해킹에 이용할 수 있다.
스택 구조를 파악하면 오버플로우로 반환 주소를 바꾸거나 뒤에 있는 값을 읽어오는 등 많은 작업을 할 수 있다.
개념 자체는 간단한 기법이라 더 설명할게 없는데 너무 짧으니 드림핵 함께실습에 있는
<Return Address Overwrite>문제의 풀이까지 같이 작성해보겠다.
#include <stdio.h>
#include <unistd.h>
void init() {
setvbuf(stdin, 0, 2, 0);
setvbuf(stdout, 0, 2, 0);
}
void get_shell() {
char *cmd = "/bin/sh";
char *args[] = {cmd, NULL};
execve(cmd, args, NULL);
}
int main() {
char buf[0x28];
init();
printf("Input: ");
scanf("%s", buf);
return 0;
}
문제 코드이다.
gdb로 분석해보면 scanf 함수가 호출되는 부분에서 버퍼가 rbp-0x30에 위치한다.
그리고 rbp에 스택 프레임 포인터가 저장되고 rbp+0x8에 반환 주소가 저장된다.
0x38만큼의 거리가 있으니 그만큼 더미를 채우고 실행하고자 하는 주소를 입력하면 된다.
get_shell 함수의 주소를 확인해보면 0x4006aa이다.
x86-64아키텍처는 리틀 엔디언을 사용하기 때문에 get_shell함수의 주소는
\xaa\x06 \x40 \x00 \x00 \x00 \x00 \x00으로 전달해야 한다.
'포너블' 카테고리의 다른 글
드림핵 basic_exploitation_001 롸업 (1) | 2024.03.06 |
---|---|
드림핵 basic_exploitation_000 롸업 (0) | 2024.03.04 |
드림핵 shell_basic 롸업 (0) | 2024.02.02 |
범용 레지스터 & gdb(pwndbg) & pwntools (1) | 2024.01.23 |
Shellcode (0) | 2024.01.17 |