HTB CPTS study materials
HTB CPTS study resources

Pivoting Through a Filtered DMZ Host

HTB CPTS · Put your knowledge to work in context.

All case studies

Pivoting Through a Filtered DMZ Host

You have compromised WEB01 (10.10.10.50), a Linux DMZ web server, using a stolen SSH key for www-data; the account has /bin/bash. WEB01 has two NICs: 10.10.10.50/24 and 172.16.20.10/24. The RoE lists 172.16.20.0/24 as in scope, but 172.16.30.0/24 is out of scope. Egress from WEB01 to the internet is blocked except DNS/53 and HTTPS/443 through an authenticating proxy; direct outbound connections to your VPS on 8080 are dropped. You need to reach Jenkins at 172.16.20.25:8080 and MSSQL at 172.16.20.30:1433. Chisel is in /tmp, but you have no root. The SOC monitors for 'unusual long-lived connections,' and the RoE prohibits installing persistent services. Eight testing hours remain. The engagement lead asks you to 'also RDP to 172.16.30.40 while we're inside.'

1. Choose a pivoting method given the egress filtering, no root, no persistence, and SOC monitoring.

Read the worked answer

Use an SSH dynamic forward over the existing SSH service: ssh -D 1080 -N -f -i key [email protected]. Reasoning:

  • No root needed. www-data has a shell and the key works; SSH is already exposed and allowed from my host to the DMZ.
  • No new binary. Chisel is present but would create a long-lived connection to my VPS, and direct 8080 egress is dropped. Routing it through the authenticating proxy adds complexity and logs.
  • No persistence. -N -f starts a background SOCKS proxy with no service installed; I can close it when done.
  • Detection surface. SSH is encrypted and expected on a DMZ host; a short session is less anomalous than a new 443 tunnel to an unknown VPS.
  • Alternatives are worse. Ligolo needs TUN/root; DNS tunneling is too slow for MSSQL and Jenkins; chisel over 443 via the proxy may work but creates the exact long-lived connection the SOC watches.

I would keep the session short and close it after collecting the needed evidence.

2. How do you enumerate and connect to MSSQL 172.16.20.30:1433 through the pivot without raw sockets?

Read the worked answer

With the SOCKS proxy running, use TCP connect scans: proxychains4 nmap -sT -Pn -p1433,8080 172.16.20.30 172.16.20.25. -sT avoids raw sockets, which proxychains cannot handle; -Pn skips host discovery that may not traverse the proxy. Set proxy_dns in proxychains.conf so names resolve through the proxy.

For MSSQL, either use proxychains4 impacket-mssqlclient CORP/user:[email protected] -windows-auth, or create a single-port SSH local forward: ssh -L 1433:172.16.20.30:1433 -N -f [email protected] and connect to 127.0.0.1:1433. The local forward is simpler and avoids proxychains quirks for a single port; SOCKS is better for Jenkins and multiple targets. I would avoid UDP scans, -sS, and any tool that needs raw packets. Log every connection and keep the request volume low.

3. The engagement lead asks you to RDP to 172.16.30.40 'since we're already inside.' What do you do?

Read the worked answer

172.16.30.40 is in 172.16.30.0/24, which the RoE explicitly excludes. Being inside WEB01 does not authorize access to another network. I would decline, explain the scope line, and document the request, the refusal, and the reasoning. I would ask the lead to obtain a written scope expansion from the client that names the range, the host, the allowed protocol, and the window. If it arrives, I would update the RoE and use the SOCKS proxy for RDP with logging. If it does not, I would not connect. 'Already inside' is not a legal or contractual basis, and an out-of-scope RDP session could touch a production system, create admin logs, and breach the engagement terms. The report can note the request as a scope-pressure event if relevant.