- Query Chronicles
- Posts
- Arbitrary Configuration Injection
Arbitrary Configuration Injection
You are reading Sim4n6's newsletter, a publication designed for ethical hackers. Each issue features a selected vulnerability-related topic for the best of our learning experience.
This edition is about Arbitrary Configuration Injection.
What is an arbitrary configuration injection?
Setting values in a user configuration file without adequately sanitizing user input may permit an attacker to inject new keys and values.
Example
Suppose a user input reaches the configuration file as in INJECTION.
# A configuration file
[section1]
key1 = INJECTION
If the user input was written unsanitized to the configuration file, it may contain a carriage return \r
. It may permit the breaking of a line in the configuration file. Thus, the injection of a new key/value association.
The payload would be:
key = INJECTION\rNEW__KEY = NEW__VALUE
The injection location is not always a value in the configuration file. It could be a section name or a key.
Vulnerable web application
The following Python code represents a vulnerable web application with two endpoints: One for updating the configuration file and the other for reading the same configuration file.
from flask import Flask, request, jsonify
import configparser
app = Flask(__name__)
@app.route("/update-config", methods=["POST"])
def update_config():
try:
# Create a sample configuration file
config = configparser.ConfigParser()
config.read("config.ini")
# Get the value from the request JSON data
data = request.get_json()
new_value = data.get("new_value")
# Update the configuration file
config["section_name"]["key_name"] = new_value
with open("config.ini", "w") as configfile:
config.write(configfile)
return jsonify({"message": "Configuration updated successfully"})
except Exception as e:
return jsonify({"error": str(e)})
@app.route("/read-config", methods=["GET"])
def read_config():
try:
# Read a configuration file
config = configparser.ConfigParser()
config.read("config.ini")
# Read the configuration file and convert it to a dictionary
config_dict = {section: dict(config[section]) for section in config.sections()}
return jsonify(config_dict)
except Exception as e:
return jsonify({"error": str(e)})
if __name__ == "__main__":
app.run(debug=True)
The screenshot displays the config.ini file before and after using the previous payload. You can notice the injection of a new key and a new value.
An Arbitrary Configuration Injection
Level up the impact
Under some circumstances, this may result in an arbitrary command execution.
Consider a web application that retrieves a user input from an HTTP POST request and writes the unsanitized value directly to a user's configuration file. Arbitrary configuration injection is possible.
Consider a case where the configuration values permit the mention of executables, like in a key for
core.pager
, orsshCommand
.It would be possible to trick the application into remote command execution by injecting a payload as such
old_value\rcore.pager=less;whoami
into the configuration file.
References:
Thank you for reading this issue.
@Sim4n6