Unhackable Cloud Storage
Description
There is no way you can read the flag at /app/flag.txt
Lab
package.json wasnt provided, but it can be easily generated.
npm init(hit Enter for most part for defaults)npm install express(Install needed library)Add
"type": "module"inpackage.jsonso node can run it.Add script:
"start": "node index.js"
Final package.json:
{
"name": "unhackablecloudstorage",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "node index.js"
},
"author": "",
"license": "ISC",
"type": "module",
"dependencies": {
"express": "^4.18.2"
}
}Change
process.env.ADMIN_PASSWORDto fixed string if you dont want to configure dotenv.
Analysis
Application is simple, it allows to read files if certain checks are met.
First vulnaribility spotted, directory traversal. If we supply /tmp/../app/flag.txt we are able to read file with user priviledges.
Second vulnaribility (not needed): adminOnly
While the code seems safe parseInt doesnt work as intended (JavaScript 💦)
So if userID is 0{anything} and because of no sanitization of parameters we are essentially admin user.
Now let's address the main function of the application: getFileContent
If you notice something weird happens. First the file is opened, then it's checked for filtered word, if the blacklisted word is not inside filename we get back file contents. But what happens if blacklisted word is inside? First file gets opened, filtered and exits. Ok..? So what? The File Descriptors
A file descriptor is an integer that identifies an open file. File descriptors are used to access files in the operating system. Each file descriptor has a unique number that is assigned to it when the file is opened. This number is used to refer to the file in subsequent operations, such as reading from or writing to the file. File descriptors are also used to keep track of the state of a file. For example, a file descriptor can be used to indicate whether a file is open, closed, or in use.
So somewhere in the system there's open file descriptor for the flag.txt always in read mode and waiting to be closed. From docker image we know that application runs on Unix and file descriptors in Unix systems can be found in /proc/{PID}/fd/ directory.
First lets find descriptor inside the lab.
And there we go, file descriptor with ID of 22 is the flag file.
Solution
Because in the Analysis section we did manual read on file descriptor we had to find process id, but since application does this for us we can utilize /proc/self/ (self being the current process id).
/proc/self/ directory is a link to our current running processes. Remember that in Linux everything is a file.
Flag: d4rk{d0nt_leav3_0pen_fDs}c0de
Note
PwnFunction goes into more details with practical live example: https://youtu.be/6SA6S9Ca5-U
Last updated