[ Pwnable.kr ] - collision

DPOS·2021년 6월 26일
2

pwnable.kr

목록 보기
2/4
post-thumbnail

문제조건

  • 플래그 얻기

문제풀이

이번에도 항상 그래왔듯 ls -alF로 파일목록을 확인합니다.
접근 가능한 파일 중 col.c를 까보면 다음과 같은 코드가 나옵니다.

#include <stdio.h>
#include <string.h>
unsigned long hashcode = 0x21DD09EC;
unsigned long check_password(const char* p){
        int* ip = (int*)p;			// 매개변수를 정수형 포인터로 변환한 값을 ip변수에 저장
        int i;
        int res=0;
        for(i=0; i<5; i++){
                res += ip[i];			// int형이라 4byte씩 5번에 걸쳐 res에 값을 더해줌
        }
        return res;				// 4byte씩 넘겨받은 값을 반환
}

int main(int argc, char* argv[]){
        if(argc<2){						// 전달받은 매개변수가 없으면 다음을 출력
                printf("usage : %s [passcode]\n", argv[0]);
                return 0;
        }
        if(strlen(argv[1]) != 20){				// 매개변수가 20byte가 아니면 다음을 출력
                printf("passcode length should be 20 bytes\n"); 
                return 0;
        }

        if(hashcode == check_password( argv[1] )){		// hashcode와 check_password의 반환 값이 같은지 비교
                system("/bin/cat flag");
                return 0;
        }
        else
                printf("wrong passcode.\n");			// 반환값과 hashcode가 다를 경우 출력
        return 0;
}

  코드를 확인하면 매개변수로 받은 값을 check_password()에 넘겨나온 반환값을 passcode와 비교하여 플래그를 뱉어내는 코드입니다.

  check_password()를 분석해보면 20byte로 받은 매개변수를 4byte씩 쪼개서 res라는 반환값을 담을 변수에 더해주는 코드라는 것을 알 수 있습니다. 따라서 4byte 길이의 16진수 5개의 합이 0x21DD09EC되는 payload를 작성해주면 됩니다.

* Speed Crunch라는 계산기를 사용했습니다.


 먼저 5개의 값이 거의 같아야 계산하기 편함으로 5로 나눠줍니다.(여기서 결과값을 16진수로하면 "~.CCC…"가 되기 때문에 10진수로 결과를 뽑아주세요!)
그리고 소수점을 제거하면 0x6C5CEC8이 나오고 제거한 소수점을 여기에 더해주면 0x6C5CECC이 나옵니다. 따라서 페이로드를 구성하자면 0x6C5CEC8 4개와 0x6C5CECC 1개로 구성할 수 있겠죠?

./col $(python -c 'print "\xc8\xce\xc5\x06"*4+"\xcc\xce\xc5\x06"')

왜 이렇게 적는지 모르겠는 분들을 위해 설명을 드리자면 \x의 경우엔 16진수를 나타내는 이스케이프 문이고, 그 뒤에 각각 c8, ce, c5, 06은 06/C5/CE/C8를 리틀 엔디언 방식에 따라 뒤에서부터 2자리씩 넣어준겁니다.(이 부분에 대해서는 어셈블리어를 하다보면 이해하는데 도움이 될 것입니다.)

결과사진

profile
본인 전공빼고 다 하는 사람

0개의 댓글