Domain Registration Killswitch

As part of my Maldev Academy sub, there are challenges included. The first one I've tackled is easily the simplest, with the objective of writing a Killswitch to check if a domain is active, and return a statement depending on the domain registration state. Code similar to this was featured in the WannaCry code, and when the domain was not registered, the payload would fail to execute.

The code sample below, and also in this GitHub repo, does not perform a ransomware attack, and merely displays a message as to the status of the domain registration.

#include <stdio.h>
#include <Windows.h>
#include <windns.h>
#pragma comment(lib, "dnsapi.lib")

// Domain to check
PCSTR domainName = "lasagnesec.com";

int main() {

	// If the domain exists, a 0 is returned and evaluated as false
	if (DnsQuery_A(domainName, DNS_TYPE_A, DNS_OPCODE_QUERY, NULL, NULL, NULL)) {
		printf("[!] Domain '%s' is NOT registered, exiting!", domainName);
		return 1;
	}
	printf("[+] Domain '%s' is registered, continuing.", domainName);

	return 0;
}

Let's break down what limited code there is here

PCSTR domainName = "lasagnesec.com";

As explained in the comment above it, this is the domain being checked by the application, we merely need the label and TLD, or the fully qualified domain name.

Next, we have the core logic.

 // If the domain exists, a 0 is returned and evaluated as false
	if (DnsQuery_A(domainName, DNS_TYPE_A, DNS_OPCODE_QUERY, NULL, NULL, NULL)) {
		printf("[!] Domain '%s' is NOT registered, exiting!", domainName);
		return 1;
	}

The main function in use here is DnsQuery_A(), a Windows API funciton used to perform the DNS query, this takes six arguments and returns a value on successful completion. The first value passed, domainName is a pointer to a string representing the queried DNS name, the second value represents the Resource Record DNS Record type queried, in this case, an A record, the third value is the query type, the fourth and sixth values are reserved and must be set to NULL, and the optional fifth value set to NULL in this case would be a pointer to a pointer to the list of Resource Records that comprise the response. For more information on this function, it is described in the Microsoft documentation here.

The if condition will evaluate on the function returning an ERROR_SUCCESS represented as a value of 0 if the DNS record is found. Since 0 is treated as false, any non-zero value is represented as true. So, if DNSQuery_A returns 0, it will evaluate to false and the code inside the if block is skipped, while if it returns any other value it will be treated as true and the code inside the if block will execute.

Finally, return 1 will exit the main function and indicate that the program terminated with an error or abormal condition.

Note: On failure, specific error codes are returned, such as 9003 for DNS_ERROR_RCODE_NAME_ERROR.

Now, if the if condition was false (meaning the main was registered).

	printf("[+] Domain '%s' is registered, continuing.", domainName);

	return 0;

This printf statement is executed if a 0 is returned, indicating a success. Ideally, if this were used in malware, this would instead call other functions, and then the program would perform its malicious function. The return 0 statement indicates a successful program execution on exit.

So, in essence, this program queries DNS for an A record of 'lasagnesec.com', if an A record is found, it prints a registered message and exits successfully. If no A record is found, a NOT registered message is printed and the program exits with an error status, this is the "killswitch" behaviour: if the domain isn't there, the malware would stop its execution.