[asterisk-dev] Another IAX2 problem with the latest security fix ...

Russell Bryant russell at digium.com
Thu May 29 10:47:58 CDT 2008


Greetings,

After the last IAX2 security fix was made to chan_iax2, we hit some unforeseen 
problems.  One of which was the impact on performance, which was quickly 
addressed.  Now, another one has come up.

I have been working with Nic Bellamy to figure out why his Asterisk 1.2 systems 
have been freaking out after the upgrade.  The conversation started here:

http://lists.digium.com/pipermail/asterisk-dev/2008-May/032843.html

I have determine what the problem is, and now must decide the most appropriate fix.

--- The security fix

The security fix was to make it more difficult to abuse IAX2 in Asterisk in a 
traffic amplification attack.

1) One problem in the code was that the destination call number was never 
checked on incoming frames.  This made it very easy for an arbitrary host to 
initiate an unauthenticated call in Asterisk, because it never had to see any 
packets coming back.  The code now enforces that the destination call number is 
correct.

2) Previously, Asterisk was very predictable in choosing call numbers.  This 
would make the change in #1 not very useful, since guessing the destination call 
number would be trivial.  So, the other change was to randomize the choice of 
destination call numbers.

#2 is what exposed the gross performance issue which has been resolved.

Now, we have an issue caused by change #1.

--- The problem

We changed the code to verify destination call numbers were correct.  The exact 
logic in the change is very simple.  If the packet is a full frame, it must 
carry an accurate destination call number.

This unfortunately has introduced a race condition.  If a host sends a 2nd frame 
in an IAX2 session before receiving the first frame from the other side, we have 
a problem.  The receiver expects that second frame to contain the destination 
call number.  Since it doesn't, the frame is rejected with an INVAL.  If a 3rd 
frame is received that does contain the destination call number, it is dropped, 
as the 2nd frame has not been received, and a VNAK is sent.  This process never 
ends, resulting in a "INVAL/VNAK storm".

--- The fix to the fix to the fix to the ....

My initial patch was a bit of a hack.  I simply added some code to ensure that 
the PING and LAGRQ frames did not get sent until the first frame is received 
from the other end, since these were the cases that were triggering the race 
condition.

However, the biggest downside is that this only helps new installations, and 
interoperability with previous Asterisk versions is still broken.

My proposed fix is to change the logic for enforcing accurate destination call 
numbers.  Since this was done to combat traffic amplification, I propose that 
this enforcement is only done on frames that are responsible for completing the 
handshake to start a call.  Essentially, that means _only_ doing this 
enforcement on an ACK, and no other full frames.

The benefit to this is that we prevent traffic amplification from hosts that 
have no way to figure out the destination call number, while doing so in such a 
way that doesn't introduce problems with older Asterisk versions.

--- Conclusion

I plan on implementing and committing the proposed fix.  However, I wanted to 
explain my logic and give everyone a chance to review all of the information and 
disagree, in case I am missing something.

Thanks for reading if you made it this far.  :)

-- 
Russell Bryant
Senior Software Engineer
Open Source Team Lead
Digium, Inc.



More information about the asterisk-dev mailing list