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.
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.
var/log/auth.log → read with grep. Syslog format, local time with no yearhome/administrator/.bash_history → read directly. The attacker’s hands-on commandsetc/systemd/system/, etc/cron.d/, root/.bashrc, root/.profile, root/.ssh/authorized_keys → read directlyhash_executables/hash_executables.sha1 and .md5 → grep by filenamelive_response/ (network, process, system, packages) and bodyfile/bodyfile.txt → context and timelineTimestamp note:
auth.logis in the host’s local time (+02:00). Both timestamp answers use the log’s own clock, unchanged.
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 asSSH brutedoes not fit the mask.
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.logprints it.
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
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'
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'
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'
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'
.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/'
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
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.
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.
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'
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'
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'
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.
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/passwdfits the same mask length as/etc/shadow. The password hashes live inshadow, which is the one that counts as “more sensitive”.
| Phase | Action |
|---|---|
| Initial Access | SSH password guessing against root from one internal host |
| Initial Access | Login accepted for the administrator account |
| Discovery | groups administrator to check privileges |
| Credential Access | Credential-recovery tool cloned from GitHub |
| Exfiltration | Two credential files copied to the attacker host with scp |
| Execution | Malicious script run, later installed as a service |
| Persistence | Root systemd service systemd-networkm.service disguised as network management |
| Persistence | ncat listeners added to root’s .bashrc and .profile |
| Persistence | Attacker SSH key added for root |
| Persistence | Local user created |
| Command and Control | Cron job pulls an encoded payload from Pastebin |
| Exfiltration | Payload POSTs the base64-encoded shadow file to the attacker |
| Type | Value |
|---|---|
| IP (attacker) | 192.168.161[.]198 |
| Attacker key identity | kali@kali |
| Account (compromised) | administrator |
| Account (created) | Regev |
| Script | sys_monitor.sh (SHA1 3ae5dea716a4f7bfb18046bfba0553ea01021c75) |
| Service | etc/systemd/system/systemd-networkm.service |
| Cron | etc/cron.d/syscheck |
| URL | hxxps[://]pastebin[.]com/raw/SAuEez0S |
| URL | hxxp[://]192[.]168[.]161[.]198/steal[.]php |
| Technique | ID | Description |
|---|---|---|
| Brute Force: Password Guessing | T1110.001 | SSH guessing burst from the attacker host |
| Valid Accounts: Local Accounts | T1078.003 | Login as administrator |
| System Owner/User Discovery | T1033 | groups administrator |
| Credentials from Password Stores | T1555 | Credential-recovery tool cloned |
| Exfiltration Over Alternative Protocol | T1048 | Credential files sent with scp |
| Unix Shell | T1059.004 | Malicious script and piped bash payload |
| Systemd Service | T1543.002 | Root service masquerading as network management |
| Unix Shell Configuration Modification | T1546.004 | ncat listeners in .bashrc and .profile |
| SSH Authorized Keys | T1098.004 | Attacker key in root’s authorized_keys |
| Create Account: Local Account | T1136.001 | Regev created |
| Scheduled Task/Job: Cron | T1053.003 | syscheck cron job |
| Web Service | T1102 | Payload hosted on Pastebin |
| OS Credential Dumping: /etc/passwd and /etc/shadow | T1003.008 | Shadow file base64-encoded and POSTed out |
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.
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.