# Bullseye: A Story of a Targeted Cyberattack

Targeted malware used a scheduled task to run chunked PowerShell that reflectively loaded a C# stub to patch AmsiScanBuffer, disabling AMSI before deploying an Empire beacon.

- Payout: Real-world hack
- Severity: high
- Program: Bullseye
- Analysis by: Huntress
- Disclosed: 2021-08-24
- Write-up quality: 7/10
- Original: https://www.huntress.com/blog/bullseye-a-story-of-a-targeted-cyberattack
- Library page: https://bugbountylibrary.com/r/blog%3Ahuntress-com-blog-bullseye-a-story-of-a-targeted-cyberattack
- Tags: area:os domain:desktop impact:internal-access impact:rce kind:incident platform:threat-intel sev:high tech:windows technique:reverse-engineering technique:source-review vuln:misconfiguration

**Target:** Windows endpoint PowerShell / amsi.dll AmsiScanBuffer
**Root cause:** PowerShell reflectively loads a .NET stub (ASBBAPI) that calls LoadLibrary/GetProcAddress/VirtualProtect on amsi.dll and overwrites the first bytes of AmsiScanBuffer with 0xB8 0x57 0x00 0x07 0x80 0xC3, making the scan function return clean.
**Steps:**
1. Scheduled task `C:\WINDOWS\system32\tasks\Microsoft\Windows\EnterpriseMgmt\LTSvc` launches PowerShell hidden with execution policy bypass and no profile.
2. Stage 1 repeatedly calls `(New-Object Net.WebClient).DownloadString()` on typosquatted look-alike domain endpoints, piping each chunk to `Invoke-Expression` to assemble the next stage.
3. Stage 2 Base64-decodes a blob beginning `TVqQ` into a .NET DLL and reflectively loads it via `[Reflection.Assembly]::Load([Convert]::FromBase64String($SAVNNBL))`.
4. Creates an object from the ASBBAPI class and calls LoadLibrary on `amsi.dll`, GetProcAddress on `AmsiScanBuffer`, and VirtualProtect to make its memory writable.
5. Writes patch bytes with `[System.Runtime.InteropServices.Marshal]::Copy($LHLCD, 0, $WUGAGU, 6)` where the bytes are 0xB8,0x57,0x00,0x07,0x80,0xC3, clobbering AmsiScanBuffer.
6. Final Base64/GZIP blob is decoded and passed to IEX, which builds RC4-encrypted C2 comms to `/login/product.php` and runs `Invoke-Empire`.
7. Final stage performs recon (OS, user account, IP) and prepares an Empire beacon.
**How found:** Huntress ThreatOps hunted for persistence footholds and found the LTSvc scheduled task invoking PowerShell; suspicious autorun-launched PowerShell prompted manual beautification of the one-liner, revealing repeated DownloadString/IEX staging and a Base64 blob starting with TVqQ that decoded to a .NET assembly.
**Exploitation:** Attacker planted a scheduled task masquerading as a legitimate vendor product (LTSvc) that launched hidden PowerShell. Chunked DownloadString/IEX staging pulled down a reflective .NET loader that patched AmsiScanBuffer to neutralize AMSI, then decoded a GZIP+Base64 blob to establish encrypted C2 to a typosquatted look-alike domain and deploy an Empire beacon for persistent remote control.
**Escalation:** AMSI bypass enabled subsequent malicious PowerShell stages to run undetected, culminating in an Empire C2 beacon for persistent access.
**Insight:** When a PowerShell one-liner is just minified rather than obfuscated, manually inserting newlines after semicolons and braces exposes the DownloadString/IEX staging chain; a Base64 blob starting with TVqQ signals a .NET PE that can be reflectively loaded and decompiled with ilspycmd to reveal Win32 API imports like LoadLibrary/GetProcAddress/VirtualProtect used for AMSI patching.

## Proof of concept (copied exactly from the original report)

**Scheduled task invoking hidden PowerShell download cradle**

```
C:\WINDOWS\system32\tasks\Microsoft\Windows\EnterpriseMgmt\LTSvc
The scheduled task looked to be invoking PowerShell. When we see PowerShell being started by an autorun, we take extra precaution because sometimes the code could be a benign script developed by a system administrator, or a tool an organization legitimately uses.
In this case, however, it was easy to see strange behavior that no sysadmin would put in their environment.

Full script can be found online in this gist.
An observant eye will immediately notice that this looks like PowerShell code. We can see that this invokes PowerShell with a hidden window style, bypassing the execution policy, running without a profile and passing a lengthy command as an argument.
```

**AMSI bypass via AmsiScanBuffer patch**

```
[System.Runtime.InteropServices.Marshal]::Copy($LHLCD, 0, $WUGAGU, 6)
Those new bytes are the machine code operations to “return out,” or just do nothing and successfully pass on the execution.
This process ultimately breaks AMSI.
```

**Reflective load of Base64 .NET DLL stub**

```
[Reflection.Assembly]::Load([Convert]::FromBase64String($SAVNNBL))
At this point, the code has staged the use of these three Win32 API functions.
```

