[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