Difficulty: Meadium
Focus Areas: Web Enumeration, File Upload Abuse, AV Evasion, Uac bypass
Description: #
Welcome, brave cyber warriors, to the Avenger Training Cyber Security Capture the Flag! Prepare yourselves for a wild and wacky adventure through the treacherous realm of cyberspace.
Your mission, should you choose to accept it (and trust us, you want to), is to outsmart the devious cyber villains, snatch their flags, and assert your dominance as the reigning champions of cyber security. But be warned, the villains won’t make it easy for you!
You’ll need more than just technical expertise to triumph in this whimsical battle. Think outside the box, unleash your inner prankster, and find unconventional solutions to outwit your opponents. Remember, even the most formidable challenges can be conquered with a healthy dose of laughter and an ingenious trick up your sleeve.
Just a final reminder that AV is enabled, and everything should be patched!
Initial Recon #
I started off with a port scan, lately Ive been testing out Rustscan.
rustscan -a 10.82.178.57 -- -A -oN scan.txt
┌──(parallels㉿Kali)-[~/targets/AVenger]
└─$ cat scan.txt
# Nmap 7.98 scan initiated Wed Jan 28 20:36:14 2026 as: /usr/lib/nmap/nmap --privileged -vvv -p 80,139,135,443,445,3306,3389,5985,7680,47001,49670,49666,49668,49667,49673,49665,49664,49674 -4 -sC -sV -A -oN scan.txt 10.82.178.57
Nmap scan report for 10.82.178.57
Host is up, received echo-reply ttl 126 (0.12s latency).
Scanned at 2026-01-28 20:36:15 EST for 80s
PORT STATE SERVICE REASON VERSION
80/tcp open http syn-ack ttl 126 Apache httpd 2.4.56 (OpenSSL/1.1.1t PHP/8.0.28)
| http-ls: Volume /
| SIZE TIME FILENAME
| 3.5K 2022-06-15 16:07 applications.html
| 177 2022-06-15 16:07 bitnami.css
| - 2023-04-06 09:24 dashboard/
| 30K 2015-07-16 15:32 favicon.ico
| - 2023-06-27 09:26 gift/
| - 2023-06-27 09:04 img/
| 751 2022-06-15 16:07 img/module_table_bottom.png
| 337 2022-06-15 16:07 img/module_table_top.png
| - 2023-06-28 14:39 xampp/
|_
|_http-title: Index of /
| http-methods:
| Supported Methods: GET POST OPTIONS HEAD TRACE
|_ Potentially risky methods: TRACE
|_http-favicon: Unknown favicon MD5: 6EB4A43CB64C97F76562AF703893C8FD
|_http-server-header: Apache/2.4.56 (Win64) OpenSSL/1.1.1t PHP/8.0.28
135/tcp open msrpc syn-ack ttl 126 Microsoft Windows RPC
139/tcp open netbios-ssn syn-ack ttl 126 Microsoft Windows netbios-ssn
443/tcp open ssl/http syn-ack ttl 126 Apache httpd 2.4.56 (OpenSS
L/1.1.1t PHP/8.0.28)
|_http-server-header: Apache/2.4.56 (Win64) OpenSSL/1.1.1t PHP/8.0.28
| tls-alpn:
|_ http/1.1
|_http-title: Index of /
|_http-favicon: Unknown favicon MD5: 6EB4A43CB64C97F76562AF703893C8FD
| http-ls: Volume /
| SIZE TIME FILENAME
| 3.5K 2022-06-15 16:07 applications.html
| 177 2022-06-15 16:07 bitnami.css
| - 2023-04-06 09:24 dashboard/
| 30K 2015-07-16 15:32 favicon.ico
| - 2023-06-27 09:26 gift/
| - 2023-06-27 09:04 img/
| 751 2022-06-15 16:07 img/module_table_bottom.png
| 337 2022-06-15 16:07 img/module_table_top.png
| - 2023-06-28 14:39 xampp/
|_
| http-methods:
| Supported Methods: GET POST OPTIONS HEAD TRACE
|_ Potentially risky methods: TRACE
445/tcp open microsoft-ds? syn-ack ttl 126
3306/tcp open mysql syn-ack ttl 126 MariaDB 5.5.5-10.4.28
| mysql-info:
| Protocol: 10
| Version: 5.5.5-10.4.28-MariaDB
| Thread ID: 10
| Capabilities flags: 63486
| Some Capabilities: Speaks41ProtocolOld, SupportsCompression, Support41Auth, SupportsTransactions, DontAllowDatabaseTableColumn, ODBCClient, IgnoreSigpipes, ConnectWithDatabase, InteractiveClient, Speaks41ProtocolNew, IgnoreSpaceBeforeParenthesis, SupportsLoadDataLocal, LongColumnFlag, FoundRows, SupportsAuthPlugins, SupportsMultipleResults, SupportsMultipleStatments
| Status: Autocommit
| Salt: \Q^fgP=|}{uW26V1/8j/
|_ Auth Plugin Name: mysql_native_password
3389/tcp open ms-wbt-server syn-ack ttl 126 Microsoft Terminal Services
|_ssl-date: 2026-01-29T01:37:33+00:00; -1s from scanner time.
| rdp-ntlm-info:
| Target_Name: GIFT
| NetBIOS_Domain_Name: GIFT
| NetBIOS_Computer_Name: GIFT
| DNS_Domain_Name: gift
| DNS_Computer_Name: gift
| Product_Version: 10.0.17763
=
|
5985/tcp open http syn-ack ttl 126 Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
7680/tcp open pando-pub? syn-ack ttl 126
47001/tcp open http syn-ack ttl 126 Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
49664/tcp open msrpc syn-ack ttl 126 Microsoft Windows RPC
49665/tcp open msrpc syn-ack ttl 126 Microsoft Windows RPC
49666/tcp open msrpc syn-ack ttl 126 Microsoft Windows RPC
49667/tcp open msrpc syn-ack ttl 126 Microsoft Windows RPC
49668/tcp open msrpc syn-ack ttl 126 Microsoft Windows RPC
49670/tcp open msrpc syn-ack ttl 126 Microsoft Windows RPC
49673/tcp open msrpc syn-ack ttl 126 Microsoft Windows RPC
49674/tcp open msrpc syn-ack ttl 126 Microsoft Windows RPCKey Observations
- Web Services
- Apache 2.4.56 on ports 80 and 443
- PHP 8.0.28
- Directory listing enabled
- Windows Services
- SMB (445)
- RDP (3389)
- WinRM (5985)
- Database
- MariaDB 10.4.28 (3306)
- Host Details
- Windows Server (Build 17763)
- Hostname:
GIFT
Lets check out the web server.
Web Enumeration (Port 80 / 443) #
XAMPP Application Discovery #
Browsing the root directory revealed an XAMPP deployment with several notable directories:
/dashboard/gift/xampp

Navigating to /dashboard page we are met with the default installation page.

Navigating to /dashboard/phpinfo.php confirmed the PHP version previously identified via Nmap.

Virtual Host & Hostname Resolution #
Attempting to access /gift caused the request to hang before redirecting to a hostname (avenger.tryhackme). Looks like we found a vhost, lets add it to our /etc/hosts file.

After adding the hostname to /etc/hosts, the application loaded correctly.

Application Behavior & WordPress Discovery #
pressing the “our services” button takes us to localhost/wordpress … interesting. Is gift a wordpress site?

looking at the certificate its also to localhost

The site is just filled with filler data and is poorly configured.

We found an upload feature on the gift page in a contact form. lets keep looking around and come back to test it soon.

Dirsearch #
Before further interaction, a directory brute-force was performed.
┌──(parallels㉿Kali)-[~/targets/AVenger]
└─$ dirsearch -u http://avenger.tryhackme
_|. _ _ _ _ _ _|_ v0.4.3
(_||| _) (/_(_|| (_| )
Extensions: php, aspx, jsp, html, js | HTTP method: GET | Threads: 25 | Wordlist size: 11460
Output File: /home/parallels/targets/AVenger/reports/http_avenger.tryhackme/_26-01-28_21-18-08.txt
Target: http://avenger.tryhackme/
[21:18:08] Starting:
[21:18:10] 403 - 302B - /%3f/
[21:18:10] 403 - 302B - /%C0%AE%C0%AE%C0%AF
[21:18:10] 403 - 302B - /%ff
[21:18:13] 403 - 302B - /.ht_wsr.txt
[21:18:13] 403 - 302B - /.htaccess.orig
[21:18:13] 403 - 302B - /.htaccess.bak1
[21:18:13] 403 - 302B - /.htaccess_orig
[21:18:13] 403 - 302B - /.htaccess.save
[21:18:13] 403 - 302B - /.htaccess.sample
[21:18:13] 403 - 302B - /.htaccessOLD
[21:18:13] 403 - 302B - /.htaccess_sc
[21:18:13] 403 - 302B - /.htaccessOLD2
[21:18:13] 403 - 302B - /.htaccess_extra
[21:18:13] 403 - 302B - /.htm
[21:18:13] 403 - 302B - /.htaccessBAK
[21:18:13] 403 - 302B - /.html
[21:18:13] 403 - 302B - /.htpasswd_test
[21:18:13] 403 - 302B - /.htpasswds
[21:18:13] 403 - 302B - /.httr-oauth
[21:18:35] 403 - 302B - /cgi-bin/
[21:18:37] 200 - 2KB - /cgi-bin/printenv.pl
[21:18:39] 301 - 341B - /dashboard -> http://avenger.tryhackme/dashboard/
[21:18:39] 200 - 5KB - /dashboard/
[21:18:39] 200 - 6KB - /dashboard/howto.html
[21:18:39] 200 - 31KB - /dashboard/faq.html
[21:18:40] 200 - 77KB - /dashboard/phpinfo.php
[21:18:43] 200 - 30KB - /favicon.ico
[21:18:43] 503 - 402B - /examples/
[21:18:43] 503 - 402B - /examples
[21:18:44] 503 - 402B - /examples/jsp/index.html
[21:18:44] 503 - 402B - /examples/jsp/snp/snoop.jsp
[21:18:44] 503 - 402B - /examples/jsp/%252e%252e/%252e%252e/manager/html/
[21:18:44] 503 - 402B - /examples/servlets/servlet/CookieExample
[21:18:44] 503 - 402B - /examples/servlets/index.html
[21:18:44] 503 - 402B - /examples/servlet/SnoopServlet
[21:18:44] 503 - 402B - /examples/websocket/index.xhtml
[21:18:44] 503 - 402B - /examples/servlets/servlet/RequestHeaderExample
[21:18:47] 301 - 335B - /img -> http://avenger.tryhackme/img/
[21:18:48] 403 - 302B - /index.php::$DATA
[21:18:57] 403 - 302B - /phpmyadmin
[21:18:58] 403 - 302B - /phpmyadmin/ChangeLog
[21:18:58] 403 - 302B - /phpmyadmin/
[21:18:58] 403 - 302B - /phpmyadmin/docs/html/index.html
[21:18:58] 403 - 302B - /phpmyadmin/doc/html/index.html
[21:18:58] 403 - 302B - /phpmyadmin/phpmyadmin/index.php
[21:18:58] 403 - 302B - /phpmyadmin/index.php
[21:18:58] 403 - 302B - /phpmyadmin/README
[21:18:58] 403 - 302B - /phpmyadmin/scripts/setup.php
[21:19:02] 403 - 421B - /server-info
[21:19:02] 403 - 421B - /server-status
[21:19:02] 403 - 421B - /server-status/
[21:19:08] 403 - 302B - /Trace.axd::$DATA
[21:19:12] 403 - 302B - /web.config::$DATA
[21:19:12] 403 - 421B - /webalizer
[21:19:12] 403 - 421B - /webalizer/
[21:19:12] 200 - 779B - /Webalizer/
[21:19:14] 200 - 771B - /xampp/
[21:19:14] 200 - 6KB - /wordpress/wp-login.php
[21:19:14] 404 - 105KB - /wordpress/
Task CompletedKey Findings #
- Confirmed WordPress installation:
/wordpress//wordpress/wp-login.php
- Accessible PHP info pages
- Upload directories exposed
- phpMyAdmin present but access-restricted
WordPress Enumeration #
We note the login page at /wordpress/wp-login.php

Wordpress version #
We check the wordpress version with wappalyzer

A google search for vulnerabilities in this version lead us to wpscan site disclosing multiple vulnerabilities.

We note that an admin php file upload could be useful to us in the future.
Wpscan #
ran wpscan with the —enumerate u flag to try to enumerate any users.
┌──(parallels㉿Kali)-[~/targets/AVenger]
└─$ wpscan --url http://avenger.tryhackme/wordpress --enumerate u
_______________________________________________________________
__ _______ _____
\ \ / / __ \ / ____|
\ \ /\ / /| |__) | (___ ___ __ _ _ __ ®
\ \/ \/ / | ___/ \___ \ / __|/ _` | '_ \
\ /\ / | | ____) | (__| (_| | | | |
\/ \/ |_| |_____/ \___|\__,_|_| |_|
WordPress Security Scanner by the WPScan Team
Version 3.8.28
Sponsored by Automattic - https://automattic.com/
@_WPScan_, @ethicalhack3r, @erwan_lr, @firefart
_______________________________________________________________
[+] URL: http://avenger.tryhackme/wordpress/ [10.81.175.222]
[+] Started: Thu Jan 29 11:45:07 2026
Interesting Finding(s):
[+] Headers
| Interesting Entries:
| - Server: Apache/2.4.56 (Win64) OpenSSL/1.1.1t PHP/8.0.28
| - X-Powered-By: PHP/8.0.28
| Found By: Headers (Passive Detection)
| Confidence: 100%
[+] XML-RPC seems to be enabled: http://avenger.tryhackme/wordpress/xmlrpc.php
| Found By: Direct Access (Aggressive Detection)
| Confidence: 100%
| References:
| - http://codex.wordpress.org/XML-RPC_Pingback_API
| - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_ghost_scanner/
| - https://www.rapid7.com/db/modules/auxiliary/dos/http/wordpress_xmlrpc_dos/
| - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_xmlrpc_login/
| - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_pingback_access/
[+] WordPress readme found: http://avenger.tryhackme/wordpress/readme.html
| Found By: Direct Access (Aggressive Detection)
| Confidence: 100%
[+] Upload directory has listing enabled: http://avenger.tryhackme/wordpress/wp-content/uploads/
| Found By: Direct Access (Aggressive Detection)
| Confidence: 100%
[+] The external WP-Cron seems to be enabled: http://avenger.tryhackme/wordpress/wp-cron.php
| Found By: Direct Access (Aggressive Detection)
| Confidence: 60%
| References:
| - https://www.iplocation.net/defend-wordpress-from-ddos
| - https://github.com/wpscanteam/wpscan/issues/1299
[+] WordPress version 6.2.2 identified (Insecure, released on 2023-05-20).
| Found By: Rss Generator (Passive Detection)
| - http://avenger.tryhackme/gift/feed/, <generator>https://wordpress.org/?v=6.2.2</generator>
| - http://avenger.tryhackme/gift/comments/feed/, <generator>https://wordpress.org/?v=6.2.2</generator>
[+] WordPress theme in use: astra
| Location: http://avenger.tryhackme/wordpress/wp-content/themes/astra/
| Last Updated: 2026-01-21T00:00:00.000Z
| Readme: http://avenger.tryhackme/wordpress/wp-content/themes/astra/readme.txt
| [!] The version is out of date, the latest version is 4.12.1
| Style URL: http://avenger.tryhackme/wordpress/wp-content/themes/astra/style.css
| Style Name: Astra
| Style URI: https://wpastra.com/
| Description: Astra is fast, fully customizable & beautiful WordPress theme suitable for blog, personal portfolio,...
| Author: Brainstorm Force
| Author URI: https://wpastra.com/about/?utm_source=theme_preview&utm_medium=author_link&utm_campaign=astra_theme
|
| Found By: Urls In Homepage (Passive Detection)
| Confirmed By: Urls In 404 Page (Passive Detection)
|
| Version: 4.1.5 (80% confidence)
| Found By: Style (Passive Detection)
| - http://avenger.tryhackme/wordpress/wp-content/themes/astra/style.css, Match: 'Version: 4.1.5'
[+] Enumerating Users (via Passive and Aggressive Methods)
Brute Forcing Author IDs - Time: 00:00:04 <======================================================================================================================================> (10 / 10) 100.00% Time: 00:00:04
[i] User(s) Identified:
[+] admin
| Found By: Rss Generator (Passive Detection)
| Confirmed By:
| Wp Json Api (Aggressive Detection)
| - http://avenger.tryhackme/gift/wp-json/wp/v2/users/?per_page=100&page=1
| Login Error Messages (Aggressive Detection)
[!] No WPScan API Token given, as a result vulnerability data has not been output.
[!] You can get a free API token with 25 daily requests by registering at https://wpscan.com/register
[+] Finished: Thu Jan 29 11:45:47 2026
[+] Requests Done: 51
[+] Cached Requests: 7
[+] Data Sent: 13.062 KB
[+] Data Received: 700.438 KB
[+] Memory used: 189.363 MB
[+] Elapsed time: 00:00:40wpscan returned the user admin.
so I tried brute forcing the admin user with the top1050.txt wordlist in the background in hopes for a quick hit but wasn’t successful.

from wpscan we also see the uploads directory is exposed, this immediately made me think back to the upload feature we found initially. Now I want to test to see if i can upload any files to the uploads folder to potentially get a php web shell.

I uploaded a test.php file and test.txt with random data inside, this was mainly to test if there were any security features blocking dangerous file extensions.

reading the response we see that when we press “send message” a post request is made to /gift/wp-admin/admin-adjax.php with our file contents. We also see the php file was accepted.

navigating to the uploads directory, after fully searching each directory I couldn’t find the file I uploaded.
this made me think there could be some sort of filtering that we cant see blocking the php upload. so I uploaded a txt file to check.

The server seemed to like the txt file too, but after another manual search of the upload directory there was no sign of our uploaded txt file.

Here I took a closer look at the message returned after uploading a file.
Thank you for your submission. Our team is delighted to review every message carefully. You will hear from us shortly!this might be a hint that anything uploaded is auto executed. lets try uploading a ps1 or exe, but before we do this, we remember back to the description of the box.
Just a final reminder that AV is enabled, and everything should be patched!Weaponization #
Anyways I already had a bit of an idea that it could be something like a ps1 upload or exe upload that we can somehow execute or that gets executed. I know this because this specific room is part of an av evasion series ive been completing in preparation for the pt1 exam and practicing av evasion.
since were doing av evasion im going to do some shellcode packing to see if we can get a shell.
I already have a small loader that I created for a project a while back so I normally just use that as it currently bypasses defender.
I generated the Implant shellcode.

then I used my python tool to xor obfuscate the shellcode, then compile it with my loader as an executable. At a high level, the loader is just: virtualalloc a block of memory → decode the xor shellcode → execute.

**note: had to use an amd64 based machine to generate the shellcode and compile because I was on an arm64 machine and sliver wouldn’t let me cross compile.
back on my attacker vm I transferred the executable over.

I noticed the tryhackme connection dropped while I was compiling the exe, so I got connected back with the new ip 10.82.133.255
then I started the sliver listener and uploaded the exe
And… received no connection. Im not sure why, I know defender isn’t catching this because I just tested it on a fully patched environment. I figured it could be an issue with something mtls related. Maybe I just jumped the gun by wanting to get a heavy payload onto the system as sliver payloads are quite large. Maybe the script on the machine is expecting a ps1 or bat file instead.
Lets try something else.
Delivery & Execution #
So I tried using a simple base64 encoded powershell reverse shell instead which should be enough to get past AMSI.
I took the generated payload and placed it in a bat file.

I then started a listener and uploaded the file.
After uploading the bat file we got a connection back to our listener. So there was indeed a script of some sort simulating a user clicking on whatever gets uploaded.
In our shell, we land as the user hugo. lets navigate to his desktop to get the user flag.

now lets check our privileges and groups to see if we have anything interesting.
WARNING: To get more info, run this script with the option '-Extended'.
PS > PS > whoami /all
USER INFORMATION
----------------
User Name SID
========= ============================================
gift\hugo S-1-5-21-1966530601-3185510712-10604624-1008
GROUP INFORMATION
-----------------
Group Name Type SID Attributes
============================================================= ================ ============ ==================================================
Everyone Well-known group S-1-1-0 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\Local account and member of Administrators group Well-known group S-1-5-114 Group used for deny only
BUILTIN\Administrators Alias S-1-5-32-544 Group used for deny only
BUILTIN\Remote Desktop Users Alias S-1-5-32-555 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
NT AUTHORITY\INTERACTIVE Well-known group S-1-5-4 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
NT AUTHORITY\Local account Well-known group S-1-5-113 Mandatory group, Enabled by default, Enabled group
LOCAL Well-known group S-1-2-0 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\NTLM Authentication Well-known group S-1-5-64-10 Mandatory group, Enabled by default, Enabled group
Mandatory Label\Medium Mandatory Level Label S-1-16-8192
PRIVILEGES INFORMATION
----------------------
Privilege Name Description State
============================= ============================== ========
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Disabledwe see we are in the administrators group but we see “group used for deny only”. This is an indication that UAC is present.
NT AUTHORITY\Local account and member of Administrators group Well-known group S-1-5-114 Group used for deny only
BUILTIN\Administrators Alias S-1-5-32-544 Group used for deny onlybefore we mess with this. I decided to run PrivescCheck.ps1 to see if we have any obvious paths first.
we serve PrivescCheck.ps1 and download it onto the target machine

Then executed privescheck.ps1 with this command
powershell -ep bypass -c ". .\PrivescCheck.ps1; Invoke-PrivescCheck"After running PrivescCheck.ps1 the only notable thing we see is that the user hugo has cleartext winlogon creds in the registry.

Since we are in the rdp group lets rdp as hugo with our new found password. This will let us interact with the UAC gui if we need to.
rdp as hugo exposes the automation that was simulating a user.

while ($true){ Start-Sleep -Second 30;Get-ChildItem -Path "C:\\xampp\\htdocs\\gift\\wp-content\\uploads\\forminator\\1176_bfb25fcc9ab03b0c3d853234c0a45028\\uploads" | ForEach-Object {Start-Process $_.FullName};}this makes sense why we couldn’t find the uploads directory. Its completely randomized.
Lets verify UAC is running

Just as expected UAC is enabled and running on its default settings
The first thing i thought of doing was opening powershell as administrator and see if we were blocked or not.

To my surprise… we are not blocked. We get an easy root flag this time.
Key Takeaways & Lessons learned #
- AV evasion ≠ execution success
- in this specific case bypassing Defender did not guarantee payload execution
- Understand automation context
- Script execution succeeded where binaries failed
- Observe application responses closely
- Generic upload messages hinted at backend processing early
- Don’t over-engineer early
- Lightweight payloads are often more effective in constrained environments
Final Thoughts #
This challenge reinforced the importance of adapting your exploitation strategy based on environmental behaviour, not just vulnerability presence, and also highlighted the value of having multiple payload options available.