Stealthy outbound IP discovery in C

04 Oct 2026

In some specific cases, when writing stealthy code, we may want to be able to get the outbound IP address without spawning child processes (think ip or ifconfig). As a Linux box may have multiple interfaces, it is our program’s job to parse the output of those commands to find the proper interface with the correct route, which can be really painful to do especially in languages such as C. It is also our job to make sure that our piece of code is cross-platform, which is even harder.

Hopefully, there’s a trick that allows us to get source IP address: using getsockname() on a UDP socket!

The goal is to create a UDP socket that “connects” to a remote server (without sending any data), and then call getsockname() to get the interface that will be used by the kernel to properly route our traffic to the specified IP address. This has various advantages, such as:

This technique is not new, and is being used in production.

Here’s the PoC:

#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>

int main()
{
  int fd;
  int port = 80;
  char* ip = "8.8.8.8";
  struct sockaddr_in server_addr;

  fd = socket(AF_INET, SOCK_DGRAM, 0);
  if (fd < 0)
  {
    perror("cannot open socket");
    exit(EXIT_FAILURE);
  }

  server_addr.sin_family = AF_INET;
  server_addr.sin_port = htons(port);

  if (inet_pton(AF_INET, ip, &server_addr.sin_addr) <= 0)
  {
    perror("invalid address");
    exit(EXIT_FAILURE);
  }

  if (connect(fd, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0)
  {
    perror("cannot connect to socket");
    exit(EXIT_FAILURE);
  }

  int len = sizeof(server_addr);
  if (getsockname(fd, (struct sockaddr *) &server_addr, &len)  == -1 )
  {
     perror("cannot getsockname");
     exit(EXIT_FAILURE);
  }

  printf("%s\n", inet_ntoa(server_addr.sin_addr));
  return 0;
}

Let’s compile it and run it:

$ gcc udp_ip.c -o udp_ip
$ ./udp_ip
192.168.100.77

We can validate the by running ip route show:

$ ip route show to match 8.8.8.8
default via 192.168.100.254 dev eth0 proto dhcp src 192.168.100.77 metric 100
Tags: security malware c maldev