jigsaw@jigsaw
  • About Me
  • 👾Forensics CTF Methodology
    • Hard Disk Analysis Methodology
  • 📝ICTF 2024 Writeups
    • REDACTED
    • UnDelete
    • UnRename
  • 📝OSCTF 2024 Writeups
    • Leaky Pipes [Pwn]
    • Buffer Buffet [Pwn]
    • Another Python Game [Rev]
    • Phantom Script Intrusion [Forensics]
    • FOR101 [Forensics]
  • 📝UTAR Amazing Cyber Hunt CTF Writeups
    • OLE - Dirty Laundry [Forensics]
  • 📝PWC Hackaday CTF 2024
    • Taking On PWC's Active Directory Challenges Again
  • 📝SherpaCTF 2024 Writeups
    • Oren [Boot2Root]
Powered by GitBook
On this page
  • Enumeration
  • Initial Access
  • Privilege Escalation
  • User Flag
  • Root Flag
  • Intended Solution
  • Conclusion
  1. SherpaCTF 2024 Writeups

Oren [Boot2Root]

PreviousTaking On PWC's Active Directory Challenges Again

Last updated 6 months ago

For the first time, SherpaSec had its own physical CTF! But wait, what is SherpaSec? Well according to ChatGPT, SherpaSec is a Malaysian volunteer-based cybersecurity community dedicated to creating a sustainable ecosystem for cybersecurity. It brings together students, professionals, and enthusiasts to share knowledge, build skills, and foster collaboration. The organisation regularly hosts events like sharing sessions, workshops, and for the very first time, a Capture The Flag (CTF) competition, SherpaCTF!

Now, like PwC Hackaday CTF 2024, what is my goal? Dominate Boot2Roots. However, Red Teamers were shocked to know that the Boot2Roots weren’t normal Linux or Windows boxes, it was Active Directory, my playground. By the way, what made the Boot2Roots scary was that we knew who was the challenge creator beforehand. It was the legendary !

Enumeration


In context, a virtual machine was provided to us for the challenge. So, with that, a host scan denoted by the -sn switch was needed to find out what was the IP address of the virtual machine. As shown in the results, it’s 192.168.138.143 as our attacker machine has the IP Address of 192.168.138.129.

jigsaw@jigsaw ~/H0j3n_AD> sudo nmap -sC -sV -p- 192.168.138.143 --open -oN 192.168.138.143.nmap_all_ports
Starting Nmap 7.94SVN ( <https://nmap.org> ) at 2024-11-24 12:56 +08
Nmap scan report for 192.168.138.143
Host is up (0.00090s latency).
Not shown: 65510 filtered tcp ports (no-response)
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
PORT      STATE SERVICE       VERSION
53/tcp    open  domain        Simple DNS Plus
80/tcp    open  http          Microsoft IIS httpd 10.0
|_http-title: Site doesn't have a title.
|_http-server-header: Microsoft-IIS/10.0
88/tcp    open  kerberos-sec  Microsoft Windows Kerberos (server time: 2024-11-24 04:58:20Z)
135/tcp   open  msrpc         Microsoft Windows RPC
139/tcp   open  netbios-ssn   Microsoft Windows netbios-ssn
389/tcp   open  ldap          Microsoft Windows Active Directory LDAP (Domain: oren.local0., Site: Default-First-Site-Name)
445/tcp   open  microsoft-ds?
464/tcp   open  kpasswd5?
593/tcp   open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
636/tcp   open  tcpwrapped
3268/tcp  open  ldap          Microsoft Windows Active Directory LDAP (Domain: oren.local0., Site: Default-First-Site-Name)
3269/tcp  open  tcpwrapped
5985/tcp  open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
8080/tcp  open  http          Apache httpd 2.4.58 ((Win64) OpenSSL/3.1.3)
|_http-server-header: Apache/2.4.58 (Win64) OpenSSL/3.1.3
|_http-title: Maintenance
|_http-open-proxy: Proxy might be redirecting requests
8530/tcp  open  http          Microsoft IIS httpd 10.0
|_http-title: Site doesn't have a title.
|_http-server-header: Microsoft-IIS/10.0
8531/tcp  open  unknown
9389/tcp  open  mc-nmf        .NET Message Framing
49666/tcp open  msrpc         Microsoft Windows RPC
49667/tcp open  msrpc         Microsoft Windows RPC
49679/tcp open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
49680/tcp open  msrpc         Microsoft Windows RPC
49682/tcp open  msrpc         Microsoft Windows RPC
49690/tcp open  msrpc         Microsoft Windows RPC
49695/tcp open  msrpc         Microsoft Windows RPC
53564/tcp open  msrpc         Microsoft Windows RPC
MAC Address: 00:0C:29:B1:43:DB (VMware)
Service Info: Host: DC01; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
|_nbstat: NetBIOS name: DC01, NetBIOS user: <unknown>, NetBIOS MAC: 00:0c:29:b1:43:db (VMware)
| smb2-security-mode: 
|   3:1:1: 
|_    Message signing enabled and required
| smb2-time: 
|   date: 2024-11-24T04:59:14
|_  start_date: N/A

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

Now that we know the IP address of the target, a full port scan was done on the target. What was noteworthy in the scan was the 3 web servers hosted on port 80, 8080 and 8530. Only the web server on port 8080 showed something of interest.

On the web server running on port 8080, a page indicating the site was under maintenance was displayed.

Performing directory bruteforcing on all 3 of the web servers, the web server on port 8080 was the only one that showed interesting directories.

Going into admin.php, a login page was displayed. However, after exhausting SQLmap and Hydra to bruteforce it, I turned my head to phpinfo.php.

Right here, a goldmine of information can be found such as the target’s operating system and the web application’s PHP version.

Quickly googling the PHP version along with the word “exploit” showed that there were proof of concepts (POCs) for exploiting this PHP version that will lead to remote code execution. However, using some of the POCs did not work.

With that, I googled for the CVE, which led to a Git repository from WatchTowr which had a Python exploit. (THANK GOD FOR PYTHON EXPLOITS)

Initial Access


So, after cloning the repository, I executed the script with the -h switch to see what arguments can be parsed in. The script takes in the URL of the web application with the --target switch followed by the command we want to run wrapped around PHP tags with the -c switch.

Using the example command from the help menu, replaced with the target’s IP address and port number followed by a PowerShell command to callback to my Python server reveals a callback!

So, repeating the steps before, I replaced the command that will be executed with a PowerShell reverse shell command encoded in Base64.

And as expected, we received a reverse shell!

To make my life easier, I will be using the Sliver C2. An implant was generated and a listener was started.

Then, on the PowerShell reverse shell, the implant was downloaded and executed.

As you can see here, I have a session!

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Admin Console</title>
    <style>
        body {
            font-family: Consolas, monospace;
            background-color: #000000;
            color: #00ff00;
            text-align: center;
        }
        .container {
            background-color: #1e1e1e;
            padding: 20px;
            margin-top: 50px;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0, 0, 0, 0.5);
            display: inline-block;
            width: 80%;
            text-align: left;
        }
        .console {
            background-color: #000000;
            padding: 15px;
            height: 300px;
            overflow-y: auto;
            white-space: pre-wrap;
            font-family: Consolas, "Courier New", monospace;
            color: #00ff00;
            border-radius: 8px;
            border: 1px solid #333;
        }
        input[type="text"] {
            background-color: #000000;
            border: 1px solid #333;
            color: #00ff00;
            padding: 10px;
            width: 90%;
            font-family: Consolas, monospace;
            font-size: 16px;
            border-radius: 8px;
        }
        .cmd {
            color: #00ff00;
            display: inline-block;
            margin-right: 10px;
        }
        button {
            background-color: #00ff00;
            color: #000;
            border: none;
            padding: 10px 20px;
            font-family: Consolas, monospace;
            font-size: 16px;
            cursor: pointer;
            border-radius: 8px;
        }
        button:hover {
            background-color: #00e600;
        }
        .cmd-prompt {
            text-align: left;
            white-space: nowrap;
            margin: 0;
            padding: 0;
        }
        .cmd-output {
            text-align: left;
            white-space: pre-wrap;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>Admin Console</h1>
        <div class="console">
            <?php if (!empty($command)): ?>
                <div class="cmd-output"><?php echo htmlspecialchars($output); ?></div>
            <?php endif; ?>
        </div>
        <form method="POST">
            <span class="cmd cmd-prompt">CMD></span>
            <input type="text" name="command" placeholder="Type a command..." autofocus required>
            <button type="submit">Run</button>
        </form>
        <br><br>
        <a href="admin.php?logout=true">Logout</a>
    </div>
</body>
</html>

Now, as shown before there was a admin.php file which we saw before on the web page. Analysing it, we found our first set of credentials! However, we will not be using it.

webadmin:N0ts0s3cr3t_123!!!

Privilege Escalation



sliver (NUCLEAR_HEALTH) > sa-whoami

[*] Successfully executed sa-whoami (coff-loader)
[*] Got output:

UserName		SID
====================== ====================================
OREN\\webadmin	S-1-5-21-2956732219-3055473855-868524036-1105

GROUP INFORMATION                                 Type                     SID                                          Attributes               
================================================= ===================== ============================================= ==================================================
OREN\\Domain Users                                 Group                    S-1-5-21-2956732219-3055473855-868524036-513  Mandatory group, Enabled by default, Enabled group, 
Everyone                                          Well-known group         S-1-1-0                                       Mandatory group, Enabled by default, Enabled group, 
BUILTIN\\Remote Management Users                   Alias                    S-1-5-32-580                                  Mandatory group, Enabled by default, Enabled group, 
BUILTIN\\Users                                     Alias                    S-1-5-32-545                                  Mandatory group, Enabled by default, Enabled group, 
BUILTIN\\Pre-Windows 2000 Compatible Access        Alias                    S-1-5-32-554                                  Mandatory group, Enabled by default, Enabled group, 
NT AUTHORITY\\SERVICE                              Well-known group         S-1-5-6                                       Mandatory group, Enabled by default, Enabled group, 
CONSOLE LOGON                                     Well-known group         S-1-2-1                                       Mandatory group, Enabled by default, Enabled group, 
NT AUTHORITY\\Authenticated Users                  Well-known group         S-1-5-11                                      Mandatory group, Enabled by default, Enabled group, 
NT AUTHORITY\\This Organization                    Well-known group         S-1-5-15                                      Mandatory group, Enabled by default, Enabled group, 
LOCAL                                             Well-known group         S-1-2-0                                       Mandatory group, Enabled by default, Enabled group, 
Authentication authority asserted identity        Well-known group         S-1-18-1                                      Mandatory group, Enabled by default, Enabled group, 
OREN\\Web_Administrator                            Alias                    S-1-5-21-2956732219-3055473855-868524036-1107 Mandatory group, Enabled by default, Enabled group, 
OREN\\GPO_Manager                                  Alias                    S-1-5-21-2956732219-3055473855-868524036-1108 Mandatory group, Enabled by default, Enabled group, 
Mandatory Label\\High Mandatory Level              Label                    S-1-16-12288                                  Mandatory group, Enabled by default, Enabled group, 

Privilege Name                Description                                       State                         
============================= ================================================= ===========================
SeMachineAccountPrivilege     Add workstations to domain                        Disabled                      
SeChangeNotifyPrivilege       Bypass traverse checking                          Enabled                       
SeImpersonatePrivilege        Impersonate a client after authentication         Enabled                       
SeCreateGlobalPrivilege       Create global objects                             Enabled                       
SeIncreaseWorkingSetPrivilege Increase a process working set                    Disabled                      

So, the first thing to do when you have user access, is to CHECK YOUR PRIVILEGES! As you can see here, we have SeImpersonatePrivilege which is exploitable with PrintSpoofer through named pipes. PrintSpoofer is vulnerable to Windows Server 2019 which we have identified in phpinfo.php.

So, PrintSpoofer is uploaded on the target, and executed with the parameter of the implant that was uploaded just now with the -c switch.

As shown here, we have gained machine access, which is higher than NT Authority System!

User Flag


Now I have the highest authority, let’s get the flag. As the user webadmin, I can view the files in my directory.

On the Desktop of the webadmin, there are 3 files. A user.zip which has the user flag, an encrypted password and a PowerShell script to decrypt the password.

# Load the necessary assembly
Add-Type -AssemblyName System.Security

# Read the encrypted password from the file
$encryptedPassword = [System.IO.File]::ReadAllBytes("C:\\Users\\webadmin\\Desktop\\encryptedPassword.bin")

# Decrypt the password using DPAPI
$decryptedPasswordBytes = [System.Security.Cryptography.ProtectedData]::Unprotect($encryptedPassword, $null, [System.Security.Cryptography.DataProtectionScope]::CurrentUser)

# Convert the decrypted password back to a string
$decryptedPassword = [System.Text.Encoding]::UTF8.GetString($decryptedPasswordBytes)

# Retrieve Password
Write-Host "Here your password = $decryptedPassword"
Write-Host "Use the password to unzip user.zip and submit your flag!"

However, user.zip is password protected. So, with the information that we gathered, it can be assumed that the PowerShell script is used to decrypt the encrypted password file which will reveal the password to user.zip. However, the PowerShell script only works if you are the current user as shown in the PowerShell script above. it uses the user’s DPAPI secret to decrypt the file. To elaborate on this, you can only decrypt the password if you are logged in as the user that encrypted the file.

Using that script we have the password for user.zip!

We got the user flag!

SHCTF24{CVE_0ren_G0tcha!}

Root Flag


Now continuing our red team assessment, I mean CTF challenge, time for post-exploitation. mimikatz.exe was uploaded and the SAM account passwords were dumped using that.

Looking at the Administrator’s Desktop, we had the same exact files as the user account except this time there is a root.zip file. At this point, I had every account. The Administrator account, the machine account and the user account. However, the PowerShell script did not work for some reason even though I am logged in as the user that encrypted the file. So, I raised a ticket and the issue was resolved.

The resolution for this error was to give us a password.zip file which was password protected by the Administrator’s hash.

So, using the results from mimikatz.exe, the zip file was decrypted and we got the password for root.zip.

From there, we got the root flag!

SHCTF24{H0pe_y0u_3njoyed_AD!}

Intended Solution


BUT WAIT, what if I told you the way I did the privilege escalation was an unintended way? Remember the credentials we got? The first thing to do when you get domain credentials is to run Bloodhound.

So, using the credentials, I ran bloodhound-python to query the LDAP server on the Active Directory for all Domain objects.

Note that in my opinion bloodhound-python is not recommended for red team assessments or basically any advanced red team certifications mainly because it does not pick up every Domain object such as Active Directory Certificate Services (ADCS). For this reason, Sharphound is recommended.

When we have the Domain objects, I loaded up neo4j, the database for Bloodhound and of course, the Bloodhound GUI. So, what do we do from here? As John Hammond would put it, CLICK EVERYTHING. However, my methodology is to check the outbound permissions of the compromised user first. As you can see the webadmin user is part of the WEB_ADMINISTRATOR group.

Looking at the WEB_ADMINISTRATOR group, it can add itself to the GPO_MANAGER group.

So, by using net group "GPO_MANAGER" webadmin /add /domain, the user webadmin is now in the GPO_Manager group!

Looking at the outbound permissions of the GPO_Manager group, it is shown that it has full read and write permissions on the ACCESS_FILES Group Policy!

From here, SharpGPOAbuse is used to add the webadmin user as a local administrator.

Finally, NetExec can be used to dump the SAM account passwords.

Conclusion


Overall, I think this box is a good Active Directory box, despite some hiccups and the unintended way. It constrains you to be a certain user to get the flag and also uses some access control lists or ACLs to get Domain Admin. If you wanna try one of H0j3n’s Active Directory boxes, is one which at the time of writing is still available and was created for Wargames 2022. I really enjoyed this CTF as we as a team did not intend to get 2nd place in the open category as well as the best presentation for the creative category. I hope SherpaSec can organise another physical CTF next for the open category as well! Till then, peace out!

📝
here
H0j3n