This post shows how easy you can build a fuzzer for the MQTT protocol by using the Polymorph framework.
I will start by assuming that the reader knows the MQTT protocol. For those who do not know it, you can find more information here.
The first thing we will do is prepare the environment where we will perform the fuzzing, in this case, it will be very simple, a Kali Linux machine in which we will install the following dependencies:
Polymorph framework
apt-get install build-essential python-dev libnetfilter-queue-dev tshark tcpdump python3-pip wireshark
pip3 install polymorph
Mosquitto
apt-get install mosquitto mosquitto-clients
Radamsa
sudo apt-get install gcc make git wget
git clone https://github.com/aoh/radamsa.git && cd radamsa && make && sudo make install
With all this installed, we are ready to start!
Before starting the construction of the fuzzer, we are going to test our mosquitto installation in localhost. To do this, we are going to open two terminals and execute a client that is going to publish to a certain topic and another in which we will run the mosquito broker. In the following image you can see the commands and the result.
Well, now that we have tested the communication between both clients, we are going to open Polymorph and begin with the capture and modification of MQTT packets in real time.
In our particular case, we are going to fuzz the topic field of the MQTTPublish packets, notice that the modification of any other field would be done in exactly the same way. Also, for simplicity, we are going to modify MQTT packets that implement the IPv4 protocol. Sometimes you will see that Polymorph captures the MQTT protocol over IPv6, to temporarily disable IPv6 you can use the following command over the loopback interface:
sudo sh -c 'echo 1 > /proc/sys/net/ipv6/conf/loopback/disable_ipv6'
Having said that, we are going to access the Polymorph main interface, to do that, we only have to introduce the polymorph command from a Linux terminal.
Once here, let's start with the construction of the fuzzer. As in this case we will not need to intercept the communication between two machines because the client and the broker will be in localhost, we do not need to use any spoofing technique. We can simply use the capture
command to start the packet sniffing process.
Our goal at this point is to capture one of the packets that we want to modify, so that the framework converts it into a template and we can work on it. Therefore, while the tool is sniffing packets, we place ourselves in our MQTT client and send an MQTTPublish message to the broker.
Once this is done, we use Ctr-C
to finish the sniffing process in Polymorph and use the show
command to show the captured packets on the screen.
As you can see, most of the packets include a last Raw layer, which means that, at first glance, they have not been interpreted/dissected correctly by the primary dissectors. With the dissect
command, we use more advanced dissectors that give us a representation of the part of the packets that have not been represented.
Now that we have a more concrete representation of all the bytes of the packets that we have captured, what we must do is choose the template that corresponds to the packet that we want to modify. We can use the wireshark
command to open this application and perform a more detailed filtering. Once the template is selected, we access it using the template
command.
Right now, we are in the context of the selected template. With the show
command we can see the different layers and fields that it has, as well as the type of them. The template concept is the most important abstraction of the framework, and it is what allows the user to access the captured packets in real time using simple syntax in the code he writes to perform complex processing on them. Furthermore, it is the container in which all the conditional functions and structures of the framework are stored when we save a session.
At this point, the conditional functions come into play (preconditions, postconditions and executions). When the user enters the intercept
command in the template interface, the machine that hosts Polymorph will stop forwarding the packets at the kernel level and start sending those packets to the tool to be processed before being forwarded. The conditional functions defined by the user will be executed in each of the intercepted packets.
Let's see a simple example of how these functions work, we are going to add the following precondition to our current template using the command:
precs -a test_condition
If you are using the default editor, pico, remember not to mix tabs and spaces, better use only spaces to indent the code. (You can specify another editor that is in your PATH using the option -e):
def test_precondition(packet):
print("The next packet arrive:")
print(packet.raw)
return packet
Enter "y" to keep the code on disk and enter precs -s
to visualize the added precondition.
Now, introduce the intercept
command with the next iptables rule (by default the framework will set a forward rule):
Look how all the packets that flow through the machine are processed in real time by the tool, and the precondition we have added is executed on each of them. We can test it just by sending a MQTTPublish message from one MQTT client to the other.
The conditional functions are another important abstraction of the framework and work as follows: when a packet is intercepted in real time, the conditional functions defined by the user are executed on it following a certain order, first the preconditions are executed in the order in which the user has added them to the template, then the executions and finally the postconditions. If at any point of the execution of any of the three types of conditional functions the value None is returned by one of them, the execution chain is broken and the packet is forwarded as it is at that moment. On the other hand, if the packet that is received as an argument is returned, the chain of execution of conditions continues. Remember that the packet that is received as argument is the packet that has been intercepted in real time at that moment.
Once this is understood, we are going to exit the intercept mode in Polymorph by entering Ctr-C
(in this way, the machine that hosts Polymorph only forwards the packets without passing them through the conditional functions). After that, we are going to add the following preconditions, executions and postconditions, which, I insist, when we start intercepting will be executed on each of the packets that are intercepted in real time. To eliminate the test precondition function that we added before, use:
precs -d test_condition
Preconditions¶
Two preconditions have been added using the commands:
precs -a global_vars -e editor
precs -a filter_mqttpublish -e editor
The first precondition, global_vars
, is creating a global variable that will remain constant for all intercepted packets. It will be used to store all the test cases that we will use to fuzz the MQTTPublish packets.
def global_vars(packet):
try:
packet.fuzz_cases
except:
setattr(packet, 'fuzz_cases', [])
return packet
On the other hand, the second precondition, filter_mqttpublish
, will filter the incoming packets so that they only continue executing the rest of the conditional functions those whose msgtype field is equals to 48. Notice that thanks to the template abstraction, Polymorph knows the position that the msgtype field occupies within the bytes of the intercepted packet, and therefore, the user can access it much more easily.
def filter_mqttpublish(packet):
try:
if packet['RAW.MQTT']['msgtype'] == 48:
return packet
except:
return None
Executions¶
We are going to add one execution function. The piece of code shown below performs the following tasks:
- Transforms the intercepted packet into a Scapy representation. We do this to be able to interact more easily with the fields of the MQTT layer, especially with the lengths, which are encoded. I wrote the MQTT specification for Scapy a while ago, you can find it here.
- We check if fuzzing values remain in our list of test cases. The list is stored in the global variable created above. If the list is empty, we invoke Radamsa to generate more test cases and we stored them in the global variable.
- Finally, we use Scapy to insert the fuzzing value in the topic field of the packet and we eliminate that value from our list, so that it is not inserted twice. In addition, we recalculate the control fields, such as lengths and chksums.
def insert_value(packet):
import subprocess
from os import listdir
from os.path import join
from scapy.all import IP
from scapy.contrib.mqtt import MQTT
# Building a Scapy packet
pkt = IP(packet.get_payload())
# Retrieving the fuzzing case
if not packet.fuzz_cases:
valid_cases = "valid_cases"
dpath = "fuzz_cases"
subprocess.check_call(["radamsa",
"-o",
join(dpath, "fuzz-%n.%s"),
"-n",
"58",
"-r",
valid_cases])
packet.fuzz_cases = [open(join(dpath, f), 'rb').read()
for f in listdir(dpath)]
# Inserting the value and recalculating some fields
del pkt['IP'].len
del pkt['IP'].chksum
del pkt['TCP'].chksum
del pkt['MQTT'].len
del pkt['MQTTPublish'].length
pkt['MQTTPublish'].topic = packet.fuzz_cases.pop()
pkt.show2()
packet.set_payload(bytes(pkt))
return packet
That's all we need to build a Proxy Fuzzer for the MQTT protocol using Polymorph!
To execute it, we will create two directories in the PATH from which we have run Polymorph, one called valid_cases
and another called fuzz_cases
. These directories will be used by Radamsa to read valid test cases and mutate them in new cases that may unravel in a possible vulnerability. We can add some simple valid cases like the following ones.
Once this is done we simply go to the template interface in Polymorph and enter the command:
intercept -ipt "iptables -A INPUT -j NFQUEUE --queue-num 1"
After that, we go to our MQTT client and publish a message, preferably with a long value so that there are no problems with the sequence numbers of the TCP/IP session.
We can observe how the packet is modified in real time and the value produced by Radamsa is introduced. What we could do now is making a simple loop in Bash and let it test a significant number of test values. Also, the most common thing would be that we run the application that we are testing under a debugger, so we can capture the exceptions that occur and analyze them.
Finally, we can use the save
command from the template interface to export the template and import it into Polymorph in another machine, so you can share it with your colleagues!
Thanks for the post. Did you find any bugs in MQTT implementations?
ReplyDeleteIt is used related to Real-Time Transport Control Protocol (RTCP) to guarantee that screen information conveyance for huge multicast networks is given and Quality of Service (QOS) can be kept up with. Checking is utilized to identify any parcel misfortune and to repay any defer jitter. https://onohosting.com/
ReplyDeleteReal time video is a succession of "moving pictures" that are sent in packed structure such that it can begin being continue before it is totally gotten like video cuts on a Web page.https://hostinglelo.in/
ReplyDelete
ReplyDeleteThanks for nice post . its realy help us . if any one looking for
cheap web hosting india , you can buy from webeyesoft at very low cost .
Thanks again
Interesting article thank you for sharing check article here Sec Lawyer
ReplyDeleteThis particular is typically plainly principal furthermore exceptional truth close by undoubtedly sensible and moreover as a matter of fact supportive My business is wanting to see as quite a bit early planned for this specific significant stuffs click for info
ReplyDeleteHey, Pleasant post. Directly following taking a gander at two or three the articles on your webpage, I really like your technique of composing for a blog. I bookmarked it to my bookmark site summary and will get back soon. Assuming no one cares either way, visit my site https://diigo.com/0puqjw
ReplyDeleteI might want to say that this blog truly persuaded me to make it happen! Much obliged, excellent post http://jaredcofp812.bravesites.com/entries/general/14-savvy-ways-to-spend-leftover-scott-d-gross-budget
ReplyDeleteGreat blog. Keep sharing. tree removal service raleigh nc
ReplyDeleteGreat blog. Keep sharing. concrete companies omaha
ReplyDeletePretty great post. Keep up the good work. pool fence miami
ReplyDeleteGreat blog. Keep up the good work. crawl space repair raleigh nc
ReplyDeleteThanks for sharing such a nice article. nc home inspection
ReplyDeletePretty impressive website. chain link fencing richmond va
ReplyDeleteInteresting blog. it-service-west-palm-beach
ReplyDeleteIt's really nice and manful. it's really cool blog. Linking is very useful thing. you have really helped lots of people who visit blog and provide them use full information
ReplyDeleteclick here now
Playtech - Playtech slot video games are typically well-known among the online on line casino community. The products of this developer are fascinating to the users with unique 바카라사이트 graphics, a number of} bonuses, and cash prizes. The company's huge recreation catalog includes Gladiator, Beach Life, Monty Python's Spamalot slots and different masterpieces. Random Wilds - randomly emerging wild symbols are part of of} the bonuses you get when taking part in} slot machines on the Internet. These symbols have the potential to multiply income as well as|in addition to} contribute to numerous additional advantages. All the money you made in the slot recreation you chose will improve if a random wild symbol appears on the display.
ReplyDeleteA security service can provide real-time monitoring and response to security threats through advanced technology. https://www.alphasecuritemontreal.com/
ReplyDeleteFortunately, there are various sorts of security frameworks which are accessible on the lookout.
ReplyDeleteAlphaSecuriteMontreal