Inspecting iOS App AMQP Traffic

Ivan Nikanorov
@RosberryApps
Published in
6 min readMar 3, 2020

By Ivan Nikanorov, QA Engineer at Rosberry

In November 2019 we started a big project, which not being small at its initial stage, is supposed to have even greater scalability right after its implementation. The platform we are working on (web+mobile apps) is expected to have pretty serious data exchange, so securing reliable message delivery has been one of the implementation objectives. Whether the device is on or off, the messages should not be lost, whereas the delivery shall be made with a confirmation in place. To ensure message delivery between the system components, we’ve chosen to use AMQP protocol together with RabbitMQ. As a result we’ve taken care of the implementation simplicity and good compatibility with the existing solutions, but that’s another story.

I am sure you can find lots of articles and posts on the web describing different methods of traffic monitoring based on http/https protocols. But those methods are not workable for AMQP, as the exchange is made via a separate ‘channel’ and the most we can see is the authorisation of a client on the server.

In this article I would like to tell you how to check the packet content of the AMQP protocol messages. This information might turn interesting to both those who want to know how the protocol behaves in real life and those who take interest in mobile app traffic sniffing. To make everything work we will need:

  • Mac running macOS 10.13.6 or later;
  • iPhone/iPad;
  • Lighting сable;
  • Wireshark 3.2.1;
  • Xсode 10 or later;
  • UDID of the device.

1. Getting the UDID

You can get the UDID of a device in different ways, but we will go with two of them.

1.1 Through the terminal

Connect your iOS device to your Mac using a data-cable (lightning). Launch the terminal. Get the UDID of the device connected running the following command:

$ instruments -s devices

Copy the UDID to the clipboard.

1.2 Through the Finder

Launch the Finder with your iOS device on. Click on the required device in the Locations. You’ll see the UDID of the device which can be copied to the clipboard.

2. Creating the virtual interface

In the terminal enter the following command to create a virtual interface:

$ rvictl -s [UDID]

rvictl is the name of the command that manipulates RVIs (Remote Virtual Interface).

-s tells rvictl to set up a new RVI.

To make it work we’ll need Xсode 10 or later.

Starting device [UDID] [SUCCEEDED] with interface rvi0

where rvi0 — the number of virtual interface created for this very device.

If the version of your Xcode is 11, the above command will be inaccessible in the terminal. To make it work, open the following directory:

/Applications/Xcode.app/Contents/Resources/Packages

and install MobileDeviceDevelopment.pkg and MobileDevice.pkg.

If an error pops up, then:

command not found: rvictl

Let’s address rvictl directly running the following command:

$ sudo /Library/Apple/usr/bin/rvictl -s [UDID]

3. Monitoring the packages in Wireshark

To monitor AMQP protocol packets we will use Wireshark — a free and open-source packet analyser distributed under GNU GPLv2 license.

Launch Wireshark, choose the virtual interface created rvi0 and click on Start.

All the traffic of the connected device is displayed in the Wireshark window. To make it display only the traffic you need, you should type amqp into the filtration string and click on Apply display filter.

Now, only the AMQP traffic will be displayed in the main Wireshark window being divided into several subtypes:

  • Connection.Start, Connection.Tune — connection setup and tuning between the app and the server (message broker);
  • Channel.Open — opening of channel to exchange messages;
  • Queue.Declare — declaring the queue with a client specified;
  • Queue.Bind — message queue distribution between the clients;
  • Basic.Consume — request for opening the receipt of messages from the queue;
  • Heartbeat — checking the channel status (some kind of pinging);
  • Channel.Close — closing of channel;
  • Connection.Close — completing connection.

More details here.

All the stages of the AMQP RabbitMQ are accompanied with the confirmation on the client side and the server.

In our case we are interested in the packets which contain Basic.Publish and Basic.Deliver in the Info section.

  • Basic.Publish — traffic from the app to the server;
  • Basic.Deliver — from the server to the app.

You can copy the packet easily. To do that you should right-click on the details and then choose …as Printable Text from the pop-up menu:

Then paste the text into the json editor for it to be properly displayed.

4. Writing the packets in the pcap file

If you need to send the traffic log to someone or compare how the app operates with different builds used, you can save the traffic into a file and then open it in Wireshark. This can be done in two different ways.

4.1 Saving the trapped packets in Wireshark

  1. Stop trapping the traffic (cmd+E).
  2. In a File menu choose Export Specified Packets.

3. Specify the name as well as the file location, the packet saving range parameters.

4. Press Save.

4.2 Saving the trapped packets using tcpdump

Tcpdump — UNIX utility letting you trap and analyze the net traffic going through your computer which this software is launched on.

To launch it run the following command:

$ sudo tcpdump -i rvi0 -vvv -w packet_trace.pcap

where, rvi0 — the name and number of the created interface as described in paragraph 2 of this article, rvi2 as shown on the screen shot;

-vvv — displaying information with as much detail as possible;

-w — saving the tcpdump data in a binary format;

Packet_trace.pcap — the name of the file which the traffic will be saved into.

To stop running the command press Ctrl+C. The file will be saved in the current directory.

Open Wireshark using: File — Open, choose the file saved.

Additional notes

Traffic saving and monitoring is possible using several devices simultaneously, the only difference will be the number of the virtual interface.

When you stop working with the virtual interfaces it’s recommended that you delete them using the following command:

$ rvictl -x [UDID]

To run over active virtual interfaces you should enter the following command:

$ rvictl -l

Conclusion

Oftentimes to solve an app testing task we have to face such issues which we have never dealt with before, in our case that was AMQP, a rather new protocol for us. There are not so many tools to debug the apps using this protocol, so we’ve decided to share our experience and workarounds found. Hopefully, all this will be interesting and helpful.

--

--