The objective of my career has been pretty simple up until recently. Bad guys want information X. Keep bad guys from taking information X. Simple enough. There’s also an Appendix to that objective. Bad guys always want to take information X. Build a program to stop bad guys from taking information X. Routinely check the infrastructure around information X to ensure that bad guys still have not taken information X.
Lately, my career has taken a different turn and I’m beginning to find out that sometimes the bad guys do not give a flying rip about stealing X. They would much rather just cripple you.
That brings us to last week’s Wireshark VoIP Challenge. If you haven’t yet taken the challenge for yourself, please click the previous link to give it a go.
Let’s start by laying out the participants in this rather small packet capture. There are four:
- 192.168.1.13 | Not Available | Extension: 1001 | Grandstream GXP2130
- 192.168.1.14 | 00:0b:82:6c:4e:2a | Extension: 1000 | Grandstream GXP2130
- 192.168.1.15 | 00:0b:82:72:92:57 | Extension: 1017 & 1049 | Grandstream GXP2130
- 192.168.1.250 | 08:00:27:fc:df:b9 | PBX | FreePBX
From here on out I’ll refer to each participant by the last octet in their IP range. Every characteristic in the list above was taken from the packets. It’s always good to start from what you absolutely know. There are a few points of interest here.
We do not know 13’s MAC address. It is on another network segment. We know this by looking at the reported MAC address in the capture. It is 30:b5:c2:8e:02:1f. That’s a TP-Link address. During the capture, this guy was sitting on the other side of my wireless bridge (a TP-Link). In the real world if you still had suspensions about 13, you could physically track down the bridge to ensure the MAC.
Every once in awhile the PBX (250) likes to reach out to a phone on the network to send an OPTIONS method. This is a packet that asks the phone, “Hey, what can you do?” (Packet 15) To which the phone usually replies, “I can do a lot. Look and see.” (Packet 16) If you click on Packet 16 and open the message header, you’ll see the “Allow:” label that lists every command to which this phone will respond. Incidentally, you don’t need to be a PBX or phone to issue these commands (foreshadowing) ;o).
Another piece that not everyone might understand is that SIP packets will carry the device’s make and model. For instance click on Packet 15 and open up the SIP Message Header. One of the fields is entitled User Agent. The will list the Make and Model of the device that originated the packet.
Anatomy of a Call
Next, we’ll take a look at what actually happened. The best way to get an overview is by going to the Telephony menu and selecting VoIP Calls. There appear to be two calls that both successfully completed. We’ll see if this is true. First, it helps to have a little knowledge about the SIP/RTP call process. When a call is being setup there are a series of steps that must be adhered to in a SIP environment.
- Phone A sends Phone B an INVITE.
- Phone B replies by saying that it is Trying to make the connection happen.
- Phone B replies by saying it has started Ringing.
- Once someone has answered, Phone B will confirm the answer by sending Phone A an OK.
- Phone A will then acknowledge Phone B by sending an ACK.
- After all this setup, RTP (voice) packets will begin to flow.
Visually represented, you get the following:
Click on the second conversation in the VoIP Calls list and click the Flow Sequence button. Behold, a model phone call. Everything matches the setup above. We can see each step of the above process and the initiator of each step. Finally at the end of the call, the terminating party hangs up. This action triggers the phone, in this case 14, to send a BYE method to which 15 replies with an OK. It should be noted that this is an IP to IP VoIP call that did not include the PBX. Such calls can be perfectly legit and it leaves out the middle man.
In summary, 15 called 14, they had a little chat, and 14 ended the conversation.
Close out the Flow Sequence chart, click the first conversation in the VoIP Calls window, and then click the Flow Sequence button for this call.
Did you notice how broken this is? 14 called 15, 15 went through its normal process, and then 14 absolutely would not would not acknowledge 15. 15 seems to be stuck sending OK packets to 14. Why? Everything seemed to be going great. To top it all off, 14 sends a final kick in the stomach by not even properly acknowledging the BYE method sent from 15. Unfortunately, the call flow is not revealing enough, so we need to go back to the main Wireshark screen.
There are some packets the flow sequence did not reveal because they are technically ICMP packets. The first ICMP packet is Packet 3 and the second is Packet 5. If you dig into these a little, you realize something very strange. These packets were sent from 14, the caller, to 15, the receiver. 14 is telling the 15, “I have no idea why you sent me a Trying packet and then followed it up with a Ringing packet.” Technically, 14 will not allow a connection to 15 because 14 is contending that it never opened its SIP port (5060) in the first place. 14 isn’t say, “I didn’t order steak, I ordered fish,” instead 14 is saying, “I didn’t place an order in the first place.” That’s why the final packet in the setup says Transaction Does Not Exist. Truly, even though 14 placed the call, by Packet 3, 14 is saying it didn’t place the call. Really!?!?!
So if 14 is denying any involvement with the call by the time Packet 3 comes around, let’s look closely at Packet 1, the INVITE.
First, look at the MAC address. Does it match the MAC address of 14 throughout the rest of the packet? Yes, it does. Second, it is using a common SIP port to make the call setup? Yes, 5060 is normally used for call setup with these devices. Next, look at the SIP Message Header.
Where did this invite come from. The From line says extension 1000 with the proper SIP URI address (firstname.lastname@example.org). Then things start to get strange. CSeq is a number to identify a single transaction during the setup. I’ve never really seen 1 preceded by a ton of zeros as a sequence number before, but it might seem plausible (compare to Packet 25, the other invite). It’s a small thing and barely noticeable.
Next, there sure are a lot of Allow fields. Usually there is just one Allow field and all the methods are listed out beside one label. At second glance, there are two Supported fields as well and they aren’t even listed in the same space.
The final and most important piece of the puzzle is found in the User-Agent field. It’s not a Grandstream phone. Every subsequent packet in which 14 is involved declares 14 to be a Grandstream, specifically a GXP2130, but this packet says something completely different.
What’s It All Mean?
Whatever sent out that first INVITE packet was not a Grandstream phone and it definitely wasn’t the phone on our network. This is where knowledge from the PCAP ends.
In reality there was another participant on the network. It was my virtual Linux box. The MAC address had been spoofed to match 14’s. The IP address was matched as well. The interface was brought up long enough to send a specially “crafted” invite packet to 15. I say “crafted” because even though the packet did the job, there were artifacts (multiple Allow fields, weird CSeq, and bogus User Agent) that a keen eye could pick up on.
Anyway, this false INVITE packet blew 15’s mind. When 14 did not respond to 15’s call setup attempt, it locked down 15 for 40 seconds. During that time, I could not get dialtone from the phone! One packet from an aggressor within the network had denied service for 40 seconds. This is not a multiple packet ICMP, denial of service take down. It was just one packet.
When the packet was sent, the phone did ring. When it was answered, the handset was completely dead, and as I said before, the phone was inoperable.
The scary part is that I can send this packet to the whole subnet with one keystroke. I can send thousands of packets to each phone. On several occasions, I’ve brought my entire system to it’s knees. Every extension, on every phone had to be manually reset.
Why Does It Matter
As a technical security professional, I’ve always had the mindset that a network that is denied service, is a secure network. If you can’t use the network, that means no one can get information out. I’ve very recently changed my mind regarding this thought. What happens when your company is about to launch a product to make millions and the sales department’s phones take a dive. The lack of information flow could destroy the launch. You haven’t protected your important asset.
Speaking of launch, what happens if mission control loses comms during the launch of a rocket. A halt of network traffic does not mean they are safe. In this case it means someone could die.
The wrong information flowing out, can be bad. We want to stop the wrong information from flowing out, but I’m starting to feel that my job should also entail insuring that the right information always flows internally and that certain information can flow out and in. The aggressor doesn’t always want to steal what you’ve got. Sometimes he wants to just choke you out. When the important asset relies on the continuous flow of information, then as technical security professionals we must find the vulnerabilities and penetrations that might impede that flow.
Break Out Other Tools
This PCAP will only take you so far to a solution. In the real world, you would want to find this aggressor on the network. I believe SNMP might be of use in this situation. You could query the switch ports and find out that the same MAC address was sitting on two different ports. You could then physically track each down to the end of the cable. TDRs or FDRs come to mind as well. I’m sure there are other ways to follow up and would love to hear your ideas.
Thanks for Your Participation
If you found any of this helpful, be sure to leave a comment here or on social media. Also, if you have any questions, please feel free to ask.