// HackTheBox  ·  writeup

Meerkat

HackTheBox Easy tsharkstringsPythonSuricata
SOC

Scenario

You are brought in as the new security provider for Forela, a fast-growing startup. The startup has been using a business management platform, but with insufficient documentation and potentially lax security practices. You are provided with PCAP and log data and are tasked with determining if a compromise has occurred. This scenario pushes the you to employ your analysis skills, effectively sifting through network data and logs to detect potential signs of intrusion, thereby offering a realistic taste of the pivotal role cybersecurity plays in the protection of burgeoning businesses.

Executive Summary

An external client replayed breached-style credential pairs against the login service of a Bonita business platform until one real user’s account opened. With that session the attacker abused a known path-handling authorization bypass to reach an API extension that runs OS commands. The commands pulled a script from a public paste site and ran it with bash. The script and everything it fetched next travel over TLS, so the persistence stage is not readable in the capture and has to be reasoned from the pattern.

Artifacts

Tooling note: tshark -e http.file_data and the urlencoded-form fields came back empty for the login POSTs because each body sits in its own short TCP segment. Pull tcp.payload from the small segments and decode the hex instead (see Q5).

Discovery

Q1 — We believe our Business Management Platform server has been compromised. Please can you confirm the name of the application running?

List the HTTP requests first to get the shape of the traffic. Nearly every path sits under /bonita/, with the login service, the portal and the REST API all visible, which identifies the platform.

tshark -r meerkat.pcap -Y http.request -T fields -e ip.src -e http.request.method -e http.request.uri
Click flag to reveal Bonitasoft

Credential Access

Q2 — We believe the attacker may have used a subset of the brute forcing attack category - what is the name of the attack carried out?

One client with a python-requests user agent posts to /bonita/loginservice over and over. The bodies alternate between a generic install/install pair and distinct user:pass combinations that look like breached credentials. Replaying known pairs, instead of guessing passwords for one account, is the credential stuffing subset of brute force.

tshark -r meerkat.pcap -Y 'http.request.method == "POST" && http.request.uri contains "loginservice"' -T fields -e frame.number -e ip.src -e http.user_agent
Click to reveal answer Credential Stuffing
Q5 — How many combinations of usernames and passwords were used in the credential stuffing attack?

The form fields are empty at the HTTP layer, so go to TCP. The POST bodies are short segments: filter on a small tcp.len, dump tcp.payload, decode the hex and keep the lines that look like credentials. Drop the repeated install pair and count the unique combinations that remain.

tshark -r meerkat.pcap -Y 'tcp.len < 80 && tcp.len > 0' -T fields -e frame.number -e tcp.payload

Gotcha: The install pair is interleaved with the real attempts and repeats, so counting raw POSTs overshoots. Count unique non-install pairs.

Click flag to reveal 56
Q6 — Which username and password combination was successful?

Failed attempts get an error response. The winning pair is the one answered with a 204 and session cookies, at frame 2903. Match that response back to its request body (frame 2900) from the Q5 dump.

tshark -r meerkat.pcap -Y 'frame.number >= 2895 && frame.number <= 2905' -T fields -e frame.number -e http.response.code -e http.set_cookie
Click to reveal answer [email protected]:g0vernm3nt

Initial Access

Q3 — Does the vulnerability exploited have a CVE assigned - and if so, which one?

meerkat-alerts.json carries a Suricata alert named “Bonitasoft Authorization Bypass” that points straight at the vulnerability. The capture agrees: after the valid login the client requests a /bonita/API/portal/page/ path with a ; suffix and then reaches /API/extension/rce. That bypass is what turns a low-privilege login into command execution.

tshark -r meerkat.pcap -Y 'http.request.uri contains ";"' -T fields -e frame.number -e http.request.method -e http.request.uri
Click flag to reveal CVE-2022-25237
Q4 — Which string was appended to the API URL path to bypass the authorization filter by the attacker's exploit?

The same request listing from Q3 shows the suffix after the semicolon in the portal page path.

Gotcha: The answer format says no special characters, so submit the bare string without the leading ;.

Click to reveal answer i18ntranslation

Command and Control

Q7 — If any, which text sharing site did the attacker utilise?

The RCE requests (rce?p=0) carry the command line in the capture, so pull them with strings. They run whoami and cat /etc/passwd, then a wget of a raw paste followed by bash on the downloaded file. The TLS handshake confirms the server name the host contacted (frames 3653 and 3661). The paste content itself is encrypted.

strings -n 4 meerkat.pcap | grep 'rce?p=0'
tshark -r meerkat.pcap -Y 'tls.handshake.type == 1' -T fields -e ip.dst -e tls.handshake.extensions_server_name
Click flag to reveal pastes.io

Persistence

Q8 — Please provide the filename of the public key used by the attacker to gain persistence on our host.

The key comes back from the paste site entirely inside TLS, so its filename never appears in plaintext in the capture or the alerts. The live paste is long gone, but the Wayback Machine archived the script’s raw URL. That snapshot shows the script doing a curl of a second paste and appending it to /home/ubuntu/.ssh/authorized_keys, then restarting SSH. The second paste’s ID is the key file’s name. Reading an archived copy is passive OSINT and never touches the attacker’s live infrastructure.

curl -s "https://archive.org/wayback/available?url=pastes.io/raw/bx5gcr0et8"

Gotcha: The paste ID in the wget and bash commands is the script’s ID, not the key file’s, so it isn’t the answer here.

Click flag to reveal hffgra4unv
Q9 — Can you confirm the file modified by the attacker to gain persistence?

A public key dropped on a Linux host points at an SSH authorized_keys file under the compromised service user’s ~/.ssh. This one was reasoned, not read from an artifact: the script content is encrypted and the home directory is not visible in the capture, so the ubuntu user path rests on the standard default account for this kind of server.

Tip: When the payload is hidden, fall back on the standard persistence location for the artifact type you can see (a public key means SSH).

Click to reveal answer /home/ubuntu/.ssh/authorized_keys
Q10 — Can you confirm the MITRE technique ID of this type of persistence mechanism?

An SSH key added to authorized_keys is the SSH Authorized Keys sub-technique of Account Manipulation, per MITRE ATT&CK. It depends on the Q9 inference, so it carries the same caveat.

Click flag to reveal T1098.004

Attack Summary

PhaseAction
Credential AccessOne python-requests client replays dozens of breached-style credential pairs against /bonita/loginservice
Initial AccessOne pair succeeds (204 with session cookies) for a real user
Initial Access;i18ntranslation appended to an API path bypasses authorization (CVE-2022-25237)
Execution/API/extension/rce runs commands on the host
Command and Controlwget fetches a raw paste from pastes.io and bash runs it
PersistencePublic key fetched over TLS; likely an SSH authorized_keys entry (inferred, not seen in plaintext)

IOCs

TypeValue
Domainpastes[.]io
IP (SNI host)66.29.132[.]145
URLhxxps[://]pastes[.]io/raw/bx5gcr0et8
Account (compromised)[email protected]
User agentpython-requests
URI marker/bonita/API/portal/page/;i18ntranslation
File (likely persistence)/home/ubuntu/.ssh/authorized_keys

MITRE ATT&CK

TechniqueIDDescription
Brute Force: Credential StuffingT1110.004Replayed breached-style pairs against /bonita/loginservice
Valid AccountsT1078Successful login as a real Forela user
Exploit Public-Facing ApplicationT1190CVE-2022-25237 bypass, then RCE through /API/extension/rce
Command and Scripting Interpreter: Unix ShellT1059.004Downloaded script run with bash
Ingress Tool TransferT1105wget of a script from pastes.io
Account Manipulation: SSH Authorized KeysT1098.004Likely persistence mechanism (inferred, not seen in plaintext)

Defender Takeaways

Patch Bonita and keep its API off the internet. The authorization bypass turns any valid login into command execution. Upgrade the platform, and restrict the portal and /API/ paths to the networks that need them.

A single client posting many credential pairs to one login endpoint is easy to flag. The python-requests user agent and the steady POST rate to /bonita/loginservice stand out against normal portal use. A rate limit or lockout would have slowed it, and MFA would have made the reused password worthless.

A ; segment in an API path is a signature for this exploit. Alert on ;i18ntranslation and similar suffixes at the reverse proxy or WAF, where the request is still visible. The Suricata rule already fired here; the gap was that nobody acted on it.

Block server-side egress to paste sites. An application server running wget against a text sharing host is not normal. Egress filtering would have cut the payload fetch.

Encrypted staging hides the persistence stage from the network. The script and key travel over TLS, so the capture cannot say what was installed. File integrity monitoring on authorized_keys, plus endpoint process logging, has to cover what the wire cannot.

Conclusion

The attacker went from a reused password to command execution on the Bonita server using one known authorization bypass, then staged a payload from a paste site. The network side shows the intrusion clearly up to the TLS boundary, and what the attacker left behind can only be confirmed on the host.