본문 바로가기

Hacking/DreamHack

Stupid GCC

1. 소스 분석

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

int main() {
    uint8_t v1 = 0;
    int v2 = 0;
    char v3[31];
    uint16_t v4[10]={0,};

    while (v4[v1] < UINT16_MAX && v1 < 10) {
        v1++;
        printf("v4[%d]: %p\n", v1, &v4[v1]);
        v2 += v1;

        if (v2 > 10000) {
            FILE *fp = fopen("/flag.txt", "r");
            fgets(v3, 31, fp);
            fclose(fp); 
            
            fp = fopen("/home/stupid_gcc/flag.txt", "w");
            fwrite(v3, 31, 1, fp);
            fclose(fp); 
            return 0;
        }
    }
    return 0;
}

=> v2 >10000 이상일 경우 /home/stupid_gcc/flag.txt 생성 하여 읽을 수 있음

 

ssh 접속 root 경로에 flag.txt 있으나, read 안됨

 

해결 방법들 소개

1) flag.txt 에 권한 부여

echo 로 소스 직접 c 코드 작성 및 컴파일 하여 권한 부여

echo -e '
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

int main()
{
	chmod("/flag.txt", 07777);
}' | gcc -o a.out -x c -

 

 - echo -e: 줄바꿈 및 백슬래시 해석을 포함하여 문자열을 출력

 - |: echo의 출력을 다음 명령어로 파이핑 

 - gcc -o a.out -x c -:

    > -o : 출력 파일 이름 설정 옵션
    > -x c: 입력이 C 코드임을 지정

    > - : 표준 입력에서 입력을 받음 (파이프 전 echo 문자열)

==> ./a.out 실행 시

 

2) gcc -D"if(x)=if(1)" a.c

if 문을 모두 참으로 컴파일

 

3) cat a.c | sed 's/10000/10/' | gcc -x c -

유닉스 함수 내장 함수인 sed (문자열 에디터) 를 사용하여, a.c 의 10000 문자열을 10으로 바꿔서 컴파일

 

4) 최적화 레벨로 컴파일 -03 옵션

gcc -03 a.c

불필요한 코드 제거, 루프 펼치기, 함수 인라이닝

컴파일러는 변수 v1v2의 값이 바뀌지 않는다고 가정하고 최적화할 수 있음

이렇때 volatile 로 선언 해주어야함

volatile uint8_t v1 = 0;
volatile int v2 = 0;

 

https://blog.naver.com/younjung1996/223440632224

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

md5 password  (0) 2024.07.31
Textbook-HMAC  (1) 2024.05.22
textbook-des__crypto  (1) 2024.05.07
arm traning v2  (0) 2024.05.07
arm training v1 (pwn)  (0) 2024.05.07