GCS, short for Ground Control Station, is software designed for various operations such as drone control and mission. (QGroundControl is recommended in PX4)
- Autonomous flight and real-time flight path control.
- Map data processing, flight route analysis,
- Geofence (If necessary, create a no-fly zone)
ardupilot | px4 | dji |
---|---|---|
mission planner | qground control | ground station |
Prior to analyzing vulnerabilities in QGC, we identified the Release file QGroundControl.AppImage using checksec.sh to check memory protection techniques.
All protection techniques except NX can be seen to be turned off, due to the nature of AppImage extensions.
As shown in the following figure, AppImage is stored together in the form of squashfs with the execution binaries and libraries to meet dependencies. So we're going to... sudo mount ./qgroundcontrol.AppImage mountpoint -o offset=188392
I checked the binaries that were actually built through the command, and again the memory protection techniques.
Since QGC uses the QT library as a Cross-Platform library, it downloads QT and compiles it through QT Creator.
-
Download and run the Qt installer
-
Install additional packages
sudo apt-get install speech-dispatcher libudev-dev libsdl2-dev patchelf
-
Clone the repository, including the submodule
git clone --recursive -j8 https://github.com/mavlink/qgroundcontrol.git
-
Submodule Update
git submodule update --recursive
- Create makefile
cd qgroundcontrol mkdir build cd build ~/Qt/5.15.2/gcc_64/bin/qmake ../
- Build
make
-
Create makefile
cd qgroundcontrol mkdir build cd build ~/Qt/5.15.2/gcc_64/bin/qmake ../
-
Add sanitizer on makefile's CC, CXX, LINK
From the QGC source directory src/Vehicle/Vehicle.cc
If you look at the 593line of , it handles the mavlink packet in a function called Vehicle:::_mavlinkMessageRecovered(). Therefore, we audited according to the flow of the function.
In the QGC program, the functions implemented with GUI were analyzed to find vulnerabilities.
Since QGC also uses the same mavlink protocol as PX4, it was able to find vulnerabilities in the three functions using the fuzzer that was previously made.
We used AFL++ for code coverage-based fuzzing. First, since AFL++ basically performs fuzzing using file I/O, we changed afl-forkserver.c
to use UDP as follows.
int client_socket;
struct sockaddr_in serverAddress;
memset(&serverAddress, 0, sizeof(serverAddress));
serverAddress.sin_family = AF_INET;
inet_aton("127.0.0.1", (struct in_addr*) &serverAddress.sin_addr.s_addr);
serverAddress.sin_port = htons(14540);
serverAddresss.sin_family = AF_INET;
// socket create
if ((client_socket = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
{
printf("socket create fail\n");
exit(0);
}
sendto(client_socket, buf, len, 0, (struct sockaddr*)&serverAddress, sizeof(serverAddress));
// socket close
close(client_socket);
Afterwards, he modified Makefile and changed compiler to apl-g++ to conduct fuzzing. However, three problems arise if we proceed this way.
- AFL sends packets first before QGC is turned on.
- If you do not receive Heartbeat, you do not receive other packets.
- AFL can be measured only when the program is terminated.
We used the following methods to solve problems.
For the first troubleshooting, the following UDP Server broadcasts were required to load the socket of QGC before sending heartbeat packets and generated packets.
if (heatbeatFlag){exit(0);}
heatbeatFlag = 1
Next, to solve the second and third problems, _uas->receiveMessage(message)
at src/Vehicle/Vehicle.cc; the code was added below to terminate the QGC when receiving the heartbeat and the generated packet.
As a result of fuzzing in the above two ways, 120 uniq hands were found as follows, but no crash came out. Because the method mutates the full packet, it cannot pass through the crc verification routine of mavlink.
Therefore, we modified the code of the UDP relay server and proceeded with fuzzing again with the following structure.
The structure mutates only the 'payload' part of Mavlink in AFL++ and transmits a full packet containing CRC values from the UDP server.
As a result, many crashes could be obtained as follows. All of these crashes were vulnerabilities found in the 4dfuzzer above, but it seems that they can be useful as future work by applying them.