Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Domain Name Generation

DZone's Guide to

Domain Name Generation

A security expert demonstrates how to reproduce the same input on the server- and client-side of a malware installation.

· Security Zone ·
Free Resource

Protect your applications against today's increasingly sophisticated threat landscape.

Domain name generation (DGAs) sound sophisticated, but they don't need to be. All they need to do is reproduce the same input on the server- and client-side of a malware installation. I'm going to show you how to do this, and then talk about how we can make it a bit more sophisticated.

I'm going to show you two distinct models you can use to generate somewhat unique domain names on a regular basis. The first model I'm going to use has a rotating token exchanged between the client and the command and control (C&C) endpoint. This provides some level of resiliency and allows the command and control system to rotate the URLs used on a regular basis. The second will use a time seed, rounded to the nearest minute to provide for some slack on system time. Distributed time synchronization turns out to be remarkably difficult, so we need to do this kind of rounding to be safe. Both examples will use the same basic code but will preprocess information differently.

Tokens. So the token approach is pretty straightforward. We need to structure a protocol that exchanges tokens between the client and the server (and a top-level domain) at some point in each exchange. Once we have the token, we simply hash it and take the generated characters out of the hash:

from Crypto.Hash import SHA512 as hasher


def build_url(domain):
    return domain['sd'] + '.' + domain['sld'] + '.' + domain['tld']

def generate_domain(seed, tld):
    h = hasher.new()
    h.update(seed)
    dg = h.hexdigest()
    return {'sd': dg[:9], 'sld': dg[10:19], 'tld': tld}

print build_url(generate_domain('foo', 'edu'))
print build_url(generate_domain('bar', 'com'))
print build_url(generate_domain('fleek', 'nz'))

When we run this, we have this kind of output:

f7fbba6e0.36f890e56.edu
d82c4eb52.1cb9c8aa9.com
32a9af3a3.2585eca49.nz

Not fancy, but it does the job.

Time. Time is a little different - we need to preprocess the time settings to correctly tokenize for submission to our algorithm:

from datetime import datetime as dt

def extract_time():
    utc = dt.utcnow()
    return str(utc.year) + str(utc.month) + str(utc.day) + str(utc.hour) + str(utc.minute)

print build_url(generate_domain(extract_time(), 'edu'))
print build_url(generate_domain(extract_time(), 'com'))
print build_url(generate_domain(extract_time(), 'nz'))

Then, we just run it through our previous algorithms, giving us this:

6dae957d4.51acbebcb.edu
6dae957d4.51acbebcb.com
6dae957d4.51acbebcb.nz

(...and then, a couple minutes later...)

17ef6524e.714abfeaf.edu
17ef6524e.714abfeaf.com
17ef6524e.714abfeaf.nz

Nice, we had the same token, so all our domain information is the same, but it does rotate after a minute. Realistically, you'd rotate this no less than every five minutes, as that's just about the shortest TTL you can configure.

That's it! You've implemented a domain name generation algorithm. We used Python, but the same kind of thing can be done with C, Java, C#, Powershell; really whatever you have handy. Now the generated URLs are detectable, as the generated strings don't look like real words, but you could tweak the output using a few simple grammatical rules to fix that. At the end of the day, it can really be this simple.

Rapidly detect security vulnerabilities in your web, mobile and desktop applications with IBM Application Security on Cloud. Register Now

Topics:
domain name generation ,security ,malware

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}