[Home]

Summary:ASTERISK-24301: Security: Out of call MESSAGE requests processed via Message channel driver can crash Asterisk
Reporter:Matt Jordan (mjordan)Labels:Security
Date Opened:2014-09-05 15:30:00Date Closed:2014-09-18 11:35:58
Priority:MajorRegression?
Status:Closed/CompleteComponents:Channels/chan_sip/Messaging Resources/res_fax
Versions:11.12.0 12.5.0 13.0.0-beta1 Frequency of
Occurrence
Constant
Related
Issues:
Environment:Attachments:( 0) ASTERISK-24301-fax.diff
( 1) ASTERISK-24301-formats13.diff
Description:*NOTE*: This is being treated as a security vulnerability for the following reasons:
# It affects FreePBX fairly readily, which represents a very large percentage of Asterisk deployments
# It's very easy to construct a dialplan that gets hit by this
# It's good to fix crashes.

From Philippe:

The following scenario will crash Asterisk, confirmed on versions 11 and 12:

Don't set the following {{sip.conf}} variables set:
* {{accept_outofcall_messages}} (or set to no the default)
* {{outofcall_message_context}} (not set in general or for a specific context)

If you then receive an out of call SIP Message (SMS Message in this case) and the message is directed to {{ReceiveFAX()}} where, in my case we had spandsp installed, Asterisk will crash.

Here is a trace of the CLI with SIP debug on:

{code}
<--- SIP read from UDP:192.159.66.3:5060 --->

MESSAGE sip:2066514965@50.46.116.72:5060 SIP/2.0

Via: SIP/2.0/UDP 192.159.66.3;rport;branch=z9hG4bK3yyvKHUN2mQFD

Max-Forwards: 70

From: <sip:14257365924@192.159.66.3>;tag=7UZZZ6jSe2H0a

To: <sip:2066514965@50.46.116.72:5060>;did=2066514965

Call-ID: 5f88785c-27e0-11e4-a024-9b0328f6df6f

CSeq: 63335591 MESSAGE

Contact: <sip:192.159.66.3>

User-Agent: SIPStation 2.11.3

Allow: INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, INFO, UPDATE, REGISTER, REFER, NOTIFY, PUBLISH, SUBSCRIBE

Supported: timer, precondition, path, replaces

Content-Type: text/plain

Content-Length: 5

X-FS-Sending-Message: ace24dea-1d2b-11e4-8238-9b0328f6df6f


Again

<------------->

--- (14 headers 1 lines) ---

Receiving message!

Looking for 2066514965 in from-sip-external (domain 50.46.116.72)


<--- Transmitting (NAT) to 192.159.66.3:5060 --->

SIP/2.0 202 Accepted

Via: SIP/2.0/UDP 192.159.66.3;branch=z9hG4bK3yyvKHUN2mQFD;received=192.159.66.3;rport=5060

From: <sip:14257365924@192.159.66.3>;tag=7UZZZ6jSe2H0a

To: <sip:2066514965@50.46.116.72:5060>;did=2066514965;tag=as14ddad00

Call-ID: 5f88785c-27e0-11e4-a024-9b0328f6df6f

CSeq: 63335591 MESSAGE

Server: FPBX-2.11.0(11.3.0)

Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH

Supported: replaces, timer

Content-Length: 0



<------------>

Scheduling destruction of SIP dialog '5f88785c-27e0-11e4-a024-9b0328f6df6f' in 32000 ms (Method: MESSAGE)

   -- Executing [2066514965@from-sip-external:1] NoOp("Message/ast_msg_queue", "Received incoming SIP connection from unknown peer to 2066514965") in new stack

   -- Executing [2066514965@from-sip-external:2] Set("Message/ast_msg_queue", "DID=2066514965") in new stack

   -- Executing [2066514965@from-sip-external:3] Goto("Message/ast_msg_queue", "s,1") in new stack

   -- Goto (from-sip-external,s,1)

   -- Executing [s@from-sip-external:1] GotoIf("Message/ast_msg_queue", "1?checklang:noanonymous") in new stack

   -- Goto (from-sip-external,s,2)

   -- Executing [s@from-sip-external:2] GotoIf("Message/ast_msg_queue", "0?setlanguage:from-trunk,2066514965,1") in new stack

   -- Goto (from-trunk,2066514965,1)

   -- Executing [2066514965@from-trunk:1] Set("Message/ast_msg_queue", "FAX_FOR=Philippe Office (222)") in new stack

   -- Executing [2066514965@from-trunk:2] NoOp("Message/ast_msg_queue", "Receiving Fax for: Philippe Office (222), From: "" <>") in new stack

   -- Executing [2066514965@from-trunk:3] Set("Message/ast_msg_queue", "FAX_RX_EMAIL=philippe@espressofountain.com") in new stack

   -- Executing [2066514965@from-trunk:4] StopPlayTones("Message/ast_msg_queue", "") in new stack

   -- Executing [2066514965@from-trunk:5] ReceiveFAX("Message/ast_msg_queue", "/var/spool/asterisk/fax/1408464436.0.tif,f") in new stack

localhost*CLI>

Disconnected from Asterisk server

Asterisk cleanly ending (0).

Executing last minute cleanups
{code}

Here are the modules:

{code}
localhost*CLI> module show like fax

Module                         Description                              Use Count

res_fax.so                     Generic FAX Applications                 1        

res_fax_spandsp.so             Spandsp G.711 and T.38 FAX Technologies  0        

2 modules loaded
{code}

Here is the actual snip it of dialplan I used to regenerate this:

{code}
exten => 2066514965,1,Set(FAX_FOR=Philippe Office (222))

exten => 2066514965,n,Noop(Receiving Fax for: ${FAX_FOR}, From: ${CALLERID(all)})

exten => 2066514965,n,Set(FAX_RX_EMAIL=philippe@espressofountain.com)

exten => 2066514965,n(receivefax),StopPlaytones

exten => 2066514965,n,ReceiveFAX(${ASTSPOOLDIR}/fax/${UNIQUEID}.tif,f)

exten => 2066514965,n,ExecIf($["${FAXSTATUS:0:6}"="FAILED" && "${FAXERROR}"!="INIT_ERROR"]?Set(FAXSTATUS="FAILED: error: ${FAXERROR} statusstr: ${FAXOPT(statusstr)}"))

exten => 2066514965,n,Hangup
{code}

In FreePBX it can be easily reproduced by sending an inbound DID directly to a 'FAX Recipient' destination which is setup in the Extension Page first.

From an earlier test of this (I think verbosity was set higher or I had better logging), the following ERROR messages are included:

{code}
[2014-08-19 08:43:37] VERBOSE[24146][C-00000001] res_fax.c:     -- Channel 'Message/ast_msg_queue' receiving FAX '/var/spool/asterisk/fax/1408463017.1.tif'

[2014-08-19 08:43:37] WARNING[24146][C-00000001] channel.c: Unable to find a codec translation path from (nothing) to (slin)

[2014-08-19 08:43:37] ERROR[24146][C-00000001] res_fax.c: channel 'Message/ast_msg_queue' failed to set write format to signed linear'.
{code}

I believe this should be pretty easy to reproduce. The severity of this is not super high since you have to be pointing the message at a DID that routes to ReceiveFAX, but if anonymous SIP is allowed on an Asterisk installation and there is a route to ReceiveFAX then the system could be subject to a DoS attack that will crash Asterisk. And of course, users could easily configure a box with bad routing to have the same result...
Comments:By: Mark Michelson (mmichelson) 2014-09-09 17:06:21.662-0500

Hi Philiippe. I've been having a gander at this issue and trying to determine the extent of it. The crash that you're seeing with regards to {{ReceiveFax()}} is one that appears to be triggerable without the use of messages, actually. There's a bit of faulty logic that passes a NULL pointer to a spandsp cleanup function, resulting in a crash. This appears to be possible on any failure of {{ReceiveFax()}} that occurs early enough in the FAXing process. I will attach a patch on this issue that will apply to res_fax_spandsp.c in Asterisk 11, 12, and 13 that fixes the crash for me.

When running the provided dialplan in Asterisk 13, the rework of media formats has caused an assertion to get triggered before the observed crash occurs. This is because the format code makes assumptions regarding the existence of media formats on a channel. I have a separate patch for Asterisk 13 that addresses some of the media-specific assertions that I observed.

There are some more...interesting errors you can trigger with messages. For instance, if you send a message into the {{Echo()}} application, it will be stuck there forever, and it will prevent any further messages from being able to be processed until Asterisk is restarted. A similar thing occurs if you run the {{Bridge()}} application on a message. These problems aren't so easily patchable, not without more fundamental, breaking changes of how messages in Asterisk work.

The plan for now is to release a security advisory that warns of the dangers of accepting text messages in Asterisk without being sure to confine them into message-specific contexts.

By: Mark Michelson (mmichelson) 2014-09-09 17:10:17.415-0500

I am attaching two files:

ASTERISK-24301-fax.diff fixes the crash in res_fax_spandsp.c and applies to Asterisk 11, 12, and 13.

ASTERISK-24301-formats13.diff is an additional patch for Asterisk 13 that causes assertions not to be triggered when sending messages to applications that expect media to be present on a channel.

By: Philippe Lindheimer (p_lindheimer) 2014-09-12 11:19:09.952-0500

We will have build asterisk against these patches to test and confirm. Will have someone work on that and then get back to you on it.

By: Philippe Lindheimer (p_lindheimer) 2014-09-16 14:02:00.012-0500

OK tested on 11.12.0 and it seems to fix the problem:
{noformat}
   -- Executing [2066514965@from-trunk:1] Set("Message/ast_msg_queue", "FAX_FOR=Philippe Office (222)") in new stack
   -- Executing [2066514965@from-trunk:2] NoOp("Message/ast_msg_queue", "Receiving Fax for: Philippe Office (222), From: "" <>") in new stack
   -- Executing [2066514965@from-trunk:3] Set("Message/ast_msg_queue", "FAX_RX_EMAIL=philippe@myemail.com") in new stack
   -- Executing [2066514965@from-trunk:4] StopPlayTones("Message/ast_msg_queue", "") in new stack
   -- Executing [2066514965@from-trunk:5] ReceiveFAX("Message/ast_msg_queue", "/var/spool/asterisk/fax/1410892649.0.tif,f") in new stack
   -- Channel 'Message/ast_msg_queue' receiving FAX '/var/spool/asterisk/fax/1410892649.0.tif'
[2014-09-16 14:44:18] WARNING[1937][C-00000000]: channel.c:5353 set_format: Unable to find a codec translation path from (nothing) to (slin)
[2014-09-16 14:44:18] ERROR[1937][C-00000000]: res_fax.c:1367 generic_fax_exec: channel 'Message/ast_msg_queue' failed to set write format to signed linear'.
   -- Executing [2066514965@from-trunk:6] ExecIf("Message/ast_msg_queue", "1?Set(FAXSTATUS="FAILED: error: Channel Problems statusstr: error starting fax session")") in new stack
   -- Executing [2066514965@from-trunk:7] Hangup("Message/ast_msg_queue", "") in new stack
 == Spawn extension (from-trunk, 2066514965, 7) exited non-zero on 'Message/ast_msg_queue'
{noformat}

backing off to a an un-patched version of 11.11.0 the same test crashes Asterisk so it would appear the patch fixes things, at least in 11.