After gaining elevated privileges on the victim machine, the Incident Response team has been assigned the task of analyzing whether the attacker has carried out any lateral movement or collected confidential data within the network, as unusual activity has been detected related to one of the cloud storage accounts.
The actor profiled the domain controller with the native nltest tool, then pulled two reconnaissance tools onto the Windows host through a BITS job and unpacked them in a system directory. A credential viewer was renamed to look like a system utility and run to harvest stored credentials. Those credentials gave SSH access to an internal PostgreSQL server, where a permission error pushed the actor to abuse COPY ... TO PROGRAM to make their own account a superuser. The database was dumped with the PostgreSQL dump utility and uploaded to an S3 bucket with curl. Two persistence callbacks to public IPs were left behind, one in a shell profile and one in a scheduled task, and an RDP session to the domain controller closed out the activity.
SWS25/C/ → Windows prefetch, $MFT, $J, Amcache.hve, SOFTWARE hive, event logs. Open with PECmd, MFTECmd, AmcacheParser, EvtxECmdcatscale_sdb00-20241024-0743.tar.gz → Linux host sdb00. Holds /var/log (auth.log, PostgreSQL log), user shell and psql histories, .bashrc, cron and ssh folders. Extract with tarTimestamp note: The Windows artifacts and the Linux logs share one incident day, 2024-10-24, and the answers are UTC. The Zimmerman CSVs start with a BOM, so read them in Python with
utf-8-sig. The tarball extracts some directories with mode 000, sochmodthem before reading.
Parse the prefetch folder and sort executions by LastRun. NLTEST.EXE, the native domain trust and domain controller query tool, is the first attacker tool in the sequence, ahead of the BITS download in Q3. Its LastRun is the answer.
PECmd -d evidence/SWS25/C/Windows/prefetch --csv work/pf
Prefetch lists every native binary that ran in the window. BITSADMIN.EXE ran at 06:28:09, right after the nltest run from Q1. The $J journal confirms the download: a BITB4BB.tmp file, the BITS temp name, becomes netscan_portable.zip, the first staged tool.
PECmd -d evidence/SWS25/C/Windows/prefetch --csv work/pf
MFTECmd -f 'evidence/SWS25/C/$Extend/$J' --csv work/j
bitsadmin creating a transfer job is the BITS Jobs technique. This comes from MITRE ATT&CK reference knowledge, not from an artifact.
From Q3 the tools arrived as zips, so look for the folders they unpacked into. Listing MFT entries created between 06:20 and 07:15 on the incident day shows netscan\ and winsysview\ side by side under one parent in the Windows directory, a spot chosen to blend in with system files. Parse the MFT, then filter the CSV in Python on the creation time.
MFTECmd -f 'evidence/SWS25/C/$MFT' --csv work/mft
Tip: Filter MFT entries on creation time inside the incident window rather than browsing user profile folders. The tools never touched them.
The $J journal records a rename into WinSysView.exe (the Q7 timestamp), sitting in the tool folder from Q2. Amcache.hve stores PE metadata for executed files, and its OriginalFileName field for that entry gives the real name.
AmcacheParser -f Amcache.hve --csv work/amc
grep -i -E 'winsysview|credentialsfileview' work/amc/*.csv
Gotcha: The folder and executable names say “system view”. The real identity is only in the Amcache
OriginalFileName, not the path.
The same Amcache row holds the SHA1 of the renamed binary. Copy it as raw text from the CSV.
grep -i -E 'winsysview|credentialsfileview' work/amc/*.csv
Use the $J journal, not the MFT. The MFT shows creation, while $J logs each rename as its own record. Filter the export to the incident window for rename and create events and take the RenameNewName record for WinSysView.exe.
MFTECmd -f 'evidence/SWS25/C/$Extend/$J' --csv work/j
The catscale tarball carries /var/log from the Linux database host. Extract it and search auth.log for accepted logins. A password login for sdb-aroy at 06:42:28 lands minutes after the credential tool ran on the Windows host in Q5 and Q7, which points to the account the actor harvested and reused.
tar xzf catscale_sdb00-20241024-0743.tar.gz
grep Accepted auth.log
The same Accepted password line from Q8 names the source address. It is an internal address, so the connection came from inside the network.
grep Accepted auth.log
Read the PostgreSQL server log from the extracted /var/log. The first statement from sdb-aroy to fail is a permission denied on the accounts table, since this was an ordinary role. That failure motivates the escalation in Q11. The format mask (****** * **** ********;) fits a plain SELECT * against a table.
grep -i -B2 -A2 'permission denied' postgresql*.log
.psql_history in the sdb-aroy home keeps statements typed at the prompt. After the Q10 denial the actor used COPY ... TO PROGRAM to make the server spawn psql as the postgres superuser and promote their own account to SUPERUSER.
cat sdb-aroy/.psql_history
Gotcha: The doubled single quotes are part of the answer, and the line ends with
;''';. Copy it exactly as stored, quotes and all.
With superuser rights in place, the same .psql_history and the shell history show the export step. The PostgreSQL dump utility ran against the database and produced the atm.sql file that Q13 uploads.
cat sdb-aroy/.psql_history
.bash_history for sdb-aroy shows curl uploading the dump to an S3 bucket. The URL in that command is the full target, and it ties back to the cloud storage alert in the scenario.
cat sdb-aroy/.bash_history
Two mechanisms hold the callbacks. The tail of the sdb-aroy .bashrc ends with a netcat line pointing at a public IP, and the Windows scheduled task MicrosoftNetworkConnector carries a public IP in its arguments. The task name is borrowed from Microsoft to look routine. Read the task definition from the collected Tasks folder, and run strings on the SOFTWARE hive as a cross-check for the TaskCache entry. List both addresses, smaller first octet first.
tail sdb-aroy/.bashrc
cat Tasks/MicrosoftNetworkConnector
strings -el SOFTWARE | grep -B3 -A3 MicrosoftNetworkConnector
Run EvtxECmd over the collected event logs and look at the RDP client channel. Event 1025 records the connection to the DC at 10.10.0.21.
EvtxECmd -d winevt/logs --csv work/evtx
Gotcha: Event
1024is also logged around the same connection and leaves the timestamp ambiguous. The1025time is the connection time that counts.
The session closes with RDP client event 1026 (disconnect) at 07:34:40. Subtract the Q15 time 07:07:45 for the duration in seconds. No single field holds this value, so it is derived from the two events.
EvtxECmd -d winevt/logs --csv work/evtx
| Phase | Action |
|---|---|
| Discovery | nltest run to retrieve domain controller details |
| Command and Control | bitsadmin pulls netscan_portable.zip and a second tool |
| Defense Evasion | Tools unpacked into C:\Windows\INF |
| Credential Access | Credential viewer renamed to WinSysView.exe and run |
| Initial Access | sdb-aroy logs in over SSH from 10.10.2.55 |
| Execution | SELECT * FROM accounts; fails with permission denied |
| Privilege Escalation | COPY ... TO PROGRAM promotes sdb-aroy to SUPERUSER |
| Collection | Database exported with pg_dump |
| Exfiltration | Dump uploaded to an S3 bucket with curl |
| Persistence | Netcat callback in .bashrc and MicrosoftNetworkConnector task |
| Lateral Movement | RDP session from the Windows host to the domain controller |
| Timestamp (UTC) | Event |
|---|---|
| 2024-10-24 06:27:29 | nltest.exe last run |
| 2024-10-24 06:28:09 | bitsadmin.exe executed |
| 2024-10-24 06:35:24 | Credential viewer renamed to WinSysView.exe |
| 2024-10-24 06:42:28 | sdb-aroy accepted over SSH on the database host |
| 2024-10-24 07:07:45 | RDP client connection to the domain controller |
| 2024-10-24 07:34:40 | RDP client session to the domain controller ends |
| Type | Value |
|---|---|
| Directory | C:\Windows\INF (netscan\, winsysview\) |
| File | WinSysView.exe (original name CredentialsFileView.exe) |
| SHA1 | 5463f4140efd005a7bafa6fa0fa759bcfcf7da4a |
| Account | sdb-aroy |
| Internal IP (SSH source) | 10.10.2.55 |
| Internal IP (domain controller) | 10.10.0.21 |
| URL | hxxps[://]festival-of-files[.]s3[.]amazonaws[.]com/atm.sql |
| IP (persistence) | 3[.]224[.]124[.]130 |
| IP (persistence) | 34[.]234[.]202[.]16 |
| Scheduled task | MicrosoftNetworkConnector |
| Technique | ID | Description |
|---|---|---|
| Domain Trust Discovery | T1482 | nltest used to query the domain controller |
| BITS Jobs | T1197 | bitsadmin downloads of the recon tools |
| Masquerading | T1036 | Credential viewer renamed to WinSysView.exe |
| Credentials from Password Stores | T1555 | Credential viewer run on the victim host |
| Valid Accounts | T1078 | Reused sdb-aroy on the database server |
| Remote Services: SSH | T1021.004 | SSH login to the database host |
| Command and Scripting Interpreter | T1059 | COPY ... TO PROGRAM runs psql as postgres |
| Account Manipulation | T1098 | Own role altered to SUPERUSER |
| Data from Local System | T1005 | Database dumped with pg_dump |
| Exfiltration to Cloud Storage | T1567.002 | Dump uploaded to S3 |
| Event Triggered Execution: Unix Shell Configuration Modification | T1546.004 | Callback appended to .bashrc |
| Scheduled Task/Job: Scheduled Task | T1053.005 | MicrosoftNetworkConnector task |
| Remote Services: Remote Desktop Protocol | T1021.001 | RDP session to the domain controller |
Block and alert on bitsadmin downloads. A BITS transfer from a workstation that lands an archive outside user folders is rare in normal operations. Log the BITS-Client operational channel and alert on jobs created by interactive shells.
A tool folder under C:\Windows\INF stands out in the MFT. Legitimate content there is driver INF files. New directories or executables created in it are a strong hunt, and Amcache OriginalFileName exposes renamed NirSoft utilities even when the path is innocent.
Database accounts must not be able to run programs. COPY ... TO PROGRAM let an unprivileged role escalate to superuser. Limit membership of pg_execute_server_program and the superuser role, and alert on ALTER USER ... SUPERUSER in the server log.
Egress to cloud storage needs a control. A single curl upload to an S3 bucket carried the entire dump. Restrict outbound S3 to approved buckets and monitor shell history and proxy logs for uploads from database hosts.
Check shell profiles and tasks named after Microsoft services. The .bashrc netcat line and the MicrosoftNetworkConnector task both held public callbacks. Baseline scheduled tasks and review profile files on servers for outbound connections.
The actor moved from a Windows host to a PostgreSQL server on a reused credential, escalated inside the database engine itself, and walked the data out to a bucket they controlled while leaving two callbacks behind. Every step lives in routine artifacts (prefetch,
$J, shell history, the database log), so the gap was visibility, not evasion.