[picoCTF] two-sum

Monitor In Secure☃️·2024년 4월 9일

wargame_pwn

목록 보기
6/11

처음엔 길이 59보다 길게 입력해서 하는 공격방법을 생각했지만, 아래 주어진 힌트인 integer overflow를 보고 값 크기가 지정된 것보다 더 크게 입력해야한다는 것을 유추할 수 있었다.

hint) Integer overflow
       Not necessarily a math problem

integer overflow(정수 오버플로우) : 정수형의 크기는 고정되어있지만, 정수형이 저장할 수 있는 값의 크기보다 큰 값을 저장하려 할 경우 발생하는 취약점


주어진 코드)

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

static int addIntOvf(int result, int a, int b) {
    result = a + b;
    if(a > 0 && b > 0 && result < 0)
        return -1;
    if(a < 0 && b < 0 && result > 0)
        return -1;
    return 0;
}

int main() {
    int num1, num2, sum;
    FILE *flag;
    char c;

    printf("n1 > n1 + n2 OR n2 > n1 + n2 \n");
    fflush(stdout);
    printf("What two positive numbers can make this possible: \n");
    fflush(stdout);
    
    if (scanf("%d", &num1) && scanf("%d", &num2)) {
        printf("You entered %d and %d\n", num1, num2);
        fflush(stdout);
        sum = num1 + num2;
        if (addIntOvf(sum, num1, num2) == 0) {
            printf("No overflow\n");
            fflush(stdout);
            exit(0);
        } else if (addIntOvf(sum, num1, num2) == -1) {
            printf("You have an integer overflow\n");
            fflush(stdout);
        }

        if (num1 > 0 || num2 > 0) {
            flag = fopen("flag.txt","r");
            if(flag == NULL){
                printf("flag not found: please run this on the server\n");
                fflush(stdout);
                exit(0);
            }
            char buf[60];
            fgets(buf, 59, flag);
            printf("YOUR FLAG IS: %s\n", buf);
            fflush(stdout);
            exit(0);
        }
    }
    return 0;
}

이 중 아래의 코드 부분이 핵심인 것 같다.

char buf[60];
            fgets(buf, 59, flag);
            printf("YOUR FLAG IS: %s\n", buf);
            fflush(stdout);

핵심부분에 쓰인 함수 분석)

fgets(str, sizeof(str), stdin); 

fgets : stdin으로부터 문자열을 입력받아서 배열 str에 저장하되, sizeof(str)의 길이만큼만 저장

fflush(stdout);

fflush : '출력 버퍼'를 비움

-> flag으로부터 문자열을 입력받아서 배열 buf에 59길이만큼만 저장하여 printf함수로 문자열이 출력되도록 하고, fflush함수로 출력 버퍼를 비운다.

int 데이터 최대값 : 2,147,483,647
이므로 두 수를 합쳤을 때 이보다 더 크면 된다.

플래그가 출력되었다.

[Reference]
https://m.blog.naver.com/wwwkasa/80180210172

0개의 댓글