Hacking/Pwnable

Type Error

mitdog 2024. 7. 18. 22:17

타입을 반환하거나.. 변환하거나... 한 타입에서 다른 타입으로 값이 옮겨지는 과정의 논리적 취약점이다.

예를 들면)

  • int로 값을 입력받아 특정 함수에 넘겨준다.
  • 해당 함수에서 어떠한 검사 과정을 거쳐, int형으로 값을 반환한다.
  • 반환 받는 변수가 unsigned short형이다.

위 과정에서 int -> unsigned short로 바뀌면서 소실이 일어난다.

해당하는 CTF 문제 하나를 예시로 마무리하겠다.

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

#define MAX_ID_LEN 10
#define USERS_COUNT 5
char account_id[USERS_COUNT][MAX_ID_LEN] = { "james", "sarah", "gildong", "asdf1234", "admin" };

int get_lower_than(int idx) {
    int input;
    scanf("%d", &input);
    if(input >= idx) {
        puts("NO ACCOUNT FOUND");
        exit(1);
    }
    return input;
}

int main() {
    printf("HI, Logging in as?: ");
    fflush(stdout);
    unsigned short idx = get_lower_than(USERS_COUNT - 1);
    printf("Welcome, %s\n", account_id[idx]);
    fflush(stdout);
    if(strncmp(account_id[idx], "admin", 5) == 0) {
        printf("________SYSTEM SETTINGS________\n");
        fflush(stdout);
        system("/bin/sh");
    } else {
        system("/bin/date");
    }
}

목표는 main함수의 system("/bin/sh")를 실행시키는 것.
그러려면 해당하는 if문을 통과해야 한다.

account_id[idx]와 admin 이라는 문자열을 비교하는데, account_id[4]에 admin 문자열이 존재한다.
따라서 idx가 4가 되도록하면 풀리는 문제이다.

idx는

unsigned short idx = get_lower_than(USERS_COUNT - 1);

으로부터 온다. USERS_COUNT는 5로 전처리 되어있다. 여튼 저기서 주는 값이 idx를 4로 만들도록 하면 되겠다.

int get_lower_than(int idx) {
    int input;
    scanf("%d", &input);
    if(input >= idx) {
        puts("NO ACCOUNT FOUND");
        exit(1);
    }
    return input;
}

입력하는 값은 int형.. 반환하여 도착하는 변수인 idx의 타입은 unsigned short..
int가 더 크니까 언더플로우로 유도하면 되겠다.

위 함수의 idx는 4로 고정되어 있다. if문을 그냥 지나가야 return을 한다. 따라서 우리가 입력하는 값의 조건은 다음과 같다.

  • 4보다 작아야 한다.
  • int -> unsigned short가 되면서 결국 4가 되어야 한다.

-65532를 입력하면 쉘을 얻을 수 있다!

'Hacking > Pwnable' 카테고리의 다른 글

RTL and ROP  (0) 2024.07.14
원하는 주소로 return 시키기  (0) 2024.07.12