728x90

scp 명령어를 통해 파일들을 다운받는다.


문제 소스이다.  rand 함수를 통해 나온값과 직접 입력한 key값을 xor 연산하여 0xdeadbeef 가 나오게하면 flag가 출력된다.

위 문제를 풀기위해서 rand 함수를 통해 나온값을 확인하고 rand 함수의 반환값을 0xdeadbeef 와 xor 한 값을 직접 입엵을 통해 key에 입력시켜주면 flag를 얻을 수 있을 것이다. rand 함수에 seed 값이 없으니 실행시킬 때 마다 같은 값이 반환될것이다.


Rand()의 반환값이 rax에 저장된다. 값은 0x6b8b4567이다.

rand의 반환값과 0xdeadbeef를 xor 연산 시켜준다.




python을 사용하여 xor 연산값을 얻는다.


이후 random 프로그램을 실행시키고 해당 값을 입력시켜 주면 플래그를 얻을 수 있을것이다.


플래그 획득

728x90

'Wargame_writeup > Pwnable.kr' 카테고리의 다른 글

leg  (0) 2018.12.19
lotto  (0) 2018.12.19
blackjack  (0) 2018.12.19
shellshock  (0) 2018.12.19
mistake  (0) 2018.12.19
728x90

100만 이상을 벌어야 플래그를 준다.




메인함수를 보면 asktitle() 함수를 호출하는것을 알 수 있다.



==================================asktitle 함수 소스===================================

void asktitle() // Function for asking player if they want to continue

{

    char choice1;

    int choice2;

     

     printf("\n                 Are You Ready?");

     printf("\n                ----------------");

     printf("\n                      (Y/N)\n                        ");

     scanf("\n%c",&choice1);

 

    while((choice1!='Y') && (choice1!='y') && (choice1!='N') && (choice1!='n')) // If invalid choice entered

    {                                                                          

        printf("\n");

        printf("Incorrect Choice. Please Enter Y for Yes or N for No.\n");

        scanf("%c",&choice1);

    }

 

 

    if((choice1 == 'Y') || (choice1 == 'y')) // If yes, continue. Prints menu.

    {

            system("cls");

            printf("\nEnter 1 to Begin the Greatest Game Ever Played.");

            printf("\nEnter 2 to See a Complete Listing of Rules.");

            printf("\nEnter 3 to Exit Game. (Not Recommended)");

            printf("\nChoice: ");

            scanf("%d", &choice2); // Prompts user for choice

            if((choice2<1) || (choice2>3)) // If invalid choice entered

            {

                printf("\nIncorrect Choice. Please enter 1, 2 or 3\n");

                scanf("%d", &choice2);

            }

            switch(choice2) // Switch case for different choices

            {  

                case 1: // Case to begin game

                   system("cls");

                    

                   play();

                                       

                   break;

                    

                case 2: // Case to see rules

                   system("cls");

                   rules();

                   break;

                    

                case 3: // Case to exit game

                   printf("\nYour day could have been perfect.");

                   printf("\nHave an almost perfect day!\n\n");

                   system("pause");

                   exit(0);

                   break;

                    

                default:

                   printf("\nInvalid Input");

            } // End switch case

    } // End if loop

    

             

 

    else if((choice1 == 'N') || (choice1 == 'n')) // If no, exit program

    {

        printf("\nYour day could have been perfect.");

        printf("\nHave an almost perfect day!\n\n");

        system("pause");

        exit(0);

    }

     

    return;

} // End function


함수를 따라가다보면 play 함수를 호출 하는 것을 알 수 있다.


play함수의 윗부분이다. dealer 함수와 betting 함수를 호출한다.



딜러의 점수를 계산해주는 함수이다.



betting 하는 금액을 처리하는 함수이다.


배팅하는 함수를 보면 player가 가진돈보다 많은 금액 베팅을 검사하는 부분이 있다.

그러나 해당 검증을 한번만 검증하기 때문에 취약점이 발생한다.


위 부분을 이용하기 위해서는 백만원 이상의 금액을 두번 입력해주면 성공적으로 금액을 베팅할 수 있다.

이후 해당게임을 한번만 이기면 성공적으로 플래그를 얻을 수 있다.



플래그 출력


정상적으로 작동하지만 내부에서 논리적인 오류를 일으킬 수 있다. 소스분석을 좀더 열심히 해야할 거 같다.





728x90

'Wargame_writeup > Pwnable.kr' 카테고리의 다른 글

lotto  (0) 2018.12.19
random  (0) 2018.12.19
shellshock  (0) 2018.12.19
mistake  (0) 2018.12.19
flag  (0) 2018.12.19
728x90


uid나 gid 모두 gid 즉 그룹권한으로 바꿔준다.






파일 권한을 보면 그룹 실행 권한에 s가 들어가 있다. 즉 실행시킬 때 그룹 실행 권한으로 실행된다는 것이다.

shellshock의 그룹권한을 보면 shellshock_pwn이고 flag의 그룹권한도 shellshock_pwn이다.

shellshock 바이너리 그룹 실행권한을 통해 flag를 shellshock_pwn 읽기 그룹권한으로 읽을 수 있다.



shellshock 취약점은 환경변수에 함수정의를 이용하여 함수정의 이후 원하는 코드를 입력 및 실행시키는 취약점 이다.

페이로드 : export x='() { :;}; /bin/cat flag'

./shellshock 를 실행시키면 플래그를 얻을 수 있다.






특정 프로그램 실행권한으로 다른 프로그램에 접근 할 수 있다.

환경변수에 함수가 정의 가능하다.

728x90

'Wargame_writeup > Pwnable.kr' 카테고리의 다른 글

random  (0) 2018.12.19
blackjack  (0) 2018.12.19
mistake  (0) 2018.12.19
flag  (0) 2018.12.19
bof  (0) 2018.12.19
728x90

password 파일의 fd를 fd변수에 저장시킨다.

이후 fd에 해당하는 파일을 read를 통해서 읽어들여 pw_buf에 저장한다.

pw_buf2 변수에는 직접 데이터를 입력시켜준다.  pw_buf2 값을 xor 연산 한값을 pw_buf와 비교하여 문자열이 일치하면 flag를 보여준다.



pw_buf2를 XOR 연산해주는 xor 함수입니다. 각각 문자열들을 XORKEY 값인 1 을 이용해서 XOR연산 해줍니다.




해당문제의 취약점은 연산자 우선순위를 이용한 것이다.

>, < 가 = 연산보다 우선순위로 연산을 하기 때문에 빨간색 상자

open("/home/mistake/password".0,RDONLY,0400)< 0 의 연산의 경우 

fd를 반환하는  open 함수에서 음수를 반환하지 않으므로 false 결과가 나온다.. false == 0

이후 fd에 해당 연산의 결과값인 0이 들어가게 되고


노란색 상자의 read함수의 fd에 0이 설정되어있기 때문에 우리가 원하는값을 입력시켜줄 수 있다. pw_buf 위치에

PW_LEN의 값은 10 이기때문에 10만큼 입력을 해줄 수 있다. 


분석한것을 정리해보면

pw_buf 값 입력가능

pw_buf2값 입력가능

pw_buf2 값을 1과 xor 연산한 값이 같으면 플래그를 준다.

입력 사이즈는 10


xor 연산은 두개의 비트가 다르면 1 이 나오고 같으면 0을 출력해준다.

그로므로 pw_buf의 값엔 1111111111을 입력해주고

xor 연산을 하는 pw_buf2에는 0000000000을 입력해주어


xor 연산후 1111111111이 나오게 한다.



728x90

'Wargame_writeup > Pwnable.kr' 카테고리의 다른 글

blackjack  (0) 2018.12.19
shellshock  (0) 2018.12.19
flag  (0) 2018.12.19
bof  (0) 2018.12.19
collision  (0) 2018.12.19
728x90

플래그 문제의 경우 소스파일을 주지않는다.

file 명령어를 통해 확인해본결과 64-bit 바이너리이며, stripped 되어있다.

stripped 이 되어있는 것은 함수의 심볼 정보를 모두 제거한다는 것이다.


해당바이너리를 IDA로 분석해본다.

start 함수 외에는 hexlay가 되지않는다 아마 암호화되어있어서 되지않는것으로 판단된다.

분석하다가 This file is packed with the UPX라는 문자열을 볼수 있다.

UPX로 packing 되어있다는 것이다.

UPX를 설치하고 d 옵션을 통해 packing을 풀어준다.

이후 flag 파일을 file 명령어를 통해 확인해본다.

stripped 이 해제되어있다.

gdb를 통해 분석한다.





0x6c2070에 flag가 있다고한다.

해당주소를 문자열로 출력하면 flag를 얻을 수 있다.



728x90

'Wargame_writeup > Pwnable.kr' 카테고리의 다른 글

shellshock  (0) 2018.12.19
mistake  (0) 2018.12.19
bof  (0) 2018.12.19
collision  (0) 2018.12.19
fd  (0) 2018.12.18
728x90

func 함수의 if문을 충족시켜 쉘을 얻기 위해서는 overflowme 변수를  스택오버플로우를 통해 인자로들어간 0xdeadbeef를 cafebabe로 바꿔주어야 한다.

해당 바이너리를 gdb로 열어보자. 


빨간색으로 밑줄 쳐놓은 부분이 call 명령어를 통해 함수를 호출하는 부분들이다.

노란색 박스 부분은 주소를 mov 시켜주는 lea 명령어를 사용하는 부분이다. 즉 ebp-0x2c 주소를 eax에 넣는것이다.

이후 call함수로인해 eax가 인자로 들어가게되는데 call 0x650 <func+36>은 gets 함수이다.


ebp-0x2c 주소에 gets 함수를 통해 입력한 데이터가 들어간다는 것이다.

그리고 gets 함수는 표준입력을 받는다. argv와 같이 인자로 받는것이아니라 scanf 처럼 표준입력을 받는 함수이다.


이후 cmp DWORD PTR [ebp+0x8], 0xcafebabe

위 명령어가 shell을 얻기위해 충족해야하는 if문이다.


우리는 ebp-0x2c 주소에 데이터를 입력하기 시작하며 비교하는곳은 ebp+0x8부터 4바이트이다.

0x2c + 0x8 == 52이므로 52바이트만큼 더미값을 넣어주고 비교하는 문자열인 cafebabe를 입력해주면 된다.




표준입력의 경우 (python ~~~; cat) | 를 통해 넣어준다.

어셈블리어로 디컴파일해서 소스를 분석할 때 입력함수 이전을 잘 분석하면 입력 버퍼의 시작주소를 알 수 있다.

728x90

'Wargame_writeup > Pwnable.kr' 카테고리의 다른 글

shellshock  (0) 2018.12.19
mistake  (0) 2018.12.19
flag  (0) 2018.12.19
collision  (0) 2018.12.19
fd  (0) 2018.12.18
728x90

인자로 argv 를 넣어줘야하며 그 인자의 길이는 20byte 여야 한다.


인자로 넣어준 argv를 check_password 함수 인자로 넣어주어 나오는 반환값과 hashcode의 값인 0x21DD09EC가 같아야 한다.


check_password 함수를 보면 int형 포인터로 값을 받아 각 4바이트씩 5개를 더해준다. 그럼 총 20바이트가 된다.

0x21DD09EC를 5로 나누면 0x06c5cec8이 나오는데 0x06c5cec8에 5를 곱하면 0x21DD09E8이 나온다.

4가 부족하므로 인자를 넣어줄때 0x06c5cec8*4+0x06c5cecc를 넣어주어 4바이트씩 5개 총 20바이트의 합이 0x21dd9ec가 되게한다.

코딩공부할 때 별로 신경쓰지않았던 자료형크기를 잘생각하자 

728x90

'Wargame_writeup > Pwnable.kr' 카테고리의 다른 글

shellshock  (0) 2018.12.19
mistake  (0) 2018.12.19
flag  (0) 2018.12.19
bof  (0) 2018.12.19
fd  (0) 2018.12.18
728x90

문제 소스이다.



소스를 분석하면 argc < 2 이면 pass argv[1] a number\n 가 출력된다.

파일을 실행시킬 때 "./fd 인자값" 형태로 실행시켜 접근해야한다.

Atoi 함수는 문자열을 int형으로 변환 시켜 주는것이다.


fd 는 파일디스크립터로 파일을 관리하기 위해 운영체제가 정해놓는 것이다.

미리 정해진 파일 디스크립터는 0, 1, 2 가있다.

0 은 Standard input : 표준 입력을 가리킨다.

1 은 Standard output : 표준 출력을 가리킨다.

2 는 Standard Error : 표준 에러를 출력시킨다.


따라서 파일 오픈이나 소켓 생성시 부여되는 파일 디스크립터는 3번부터 시작된다.


read 함수의 첫번쨰 인자는 fd 즉 읽을 파일의 디스크립터

read 함수의 두번째 인자는 데이터를 저장할 공간, 위치

read 함수의 세번째 인자는 2번째 인자에 저장할 데이터의 크기이다.

해당 문제에서 read함수는 fd변수에있는 번호에 해당하는 파일을 32만큼 읽어서 버퍼에 저장해라 라는 함수가 된다.


strcmp( string1, string2) 함수의 경우 string1이 string2보다 크면 0보다 큰값을 반환한다.

string1 과 string2가 같으면 0을 반환한다.

string2가 string1 보다 크면 0보다 작은값을 반환한다.


if(!strcmp("LETMEWIN\n",buf))의 조건을 만족하기 위해서는 buf에 LETMEWIN을 입력해야한다.

그래야만 strcmp함수의 반환값이 0이 될것이고 !0 == 1이 되기때문에 if문 조건을 충족 시킬 수 있다.


소스분석에 맞게 buf에 LETMEWIN\n을 입력해주기위해서는 fd 값을 0으로 즉 Standard input으로 설정해주어 우리가 원하는 문자열을 입력할 수 있게 만들어주어야한다.

0x1234는 10진수로 4660이기 때문에 ./fd 4660을 입력하고 LETMEWIN을 입력하면 문제가 풀릴것이다.



===============================================================


fd 파일 디스크립터 : 운영체제에서 설정해주는 파일들을 관리하기 위한 파일 번호 이다.

atoi 함수는 문자열에 있는 정수를 int형으로 변환해준다. 반환에 실패할경우 0이 반환된다. 모든 공백문자는 무시하며 +, - 외의 다른 문자들이 문자열안에 있을경우 0이 반환된다. 또한 숫자 뒤에있는 문자들은 무시된다.

ex) atoi("a1234") == 0

atoi("1234a") == 1234




728x90

'Wargame_writeup > Pwnable.kr' 카테고리의 다른 글

shellshock  (0) 2018.12.19
mistake  (0) 2018.12.19
flag  (0) 2018.12.19
bof  (0) 2018.12.19
collision  (0) 2018.12.19

+ Recent posts