#!/usr/bin/python3

# Source: https://www.forcepoint.com/blog/x-labs/lockys-new-dga-seeding-new-domains-russia-update-26feb16

import argparse
import socket
from numpy import seterr, uint32
from datetime import datetime

import time

seterr(over="ignore")    

def processDate(dateStr): # Converts date string into usable format
    try:
        date = int(dateStr)
    except ValueError:
        return None
    except TypeError:
        return None
    month = int(date / 10000  % 100)
    day = int(date / 1000000)
    year = int(date % 10000)
    dateData = [ year, month, day ]
    return dateData

def genDate(): 
    time = datetime.now()
    year = time.year
    month = time.month
    day = time.day
    dateData = [ year, month, day ]
    return dateData

def ror(n, shift):
    n &= 0xFFFFFFFF
    return ((n >> shift) | (n << (32 - shift))) & 0xFFFFFFFF

def rol(n, shift):
    n &= 0xFFFFFFFF
    return ((n << shift) | (n >> (32 - shift))) & 0xFFFFFFFF

def gen(number, seed, date, prefix, suffix, tld):
    if date: # Date supplied in DDMMYYYY
        date = processDate(date)
        if date is None:
            print("Date format error. Date must be in DDMMYYYY format.")
            exit(-1)
    else:
        date = genDate()
    domains = []
    for i in range(number):
        url = prefix
        const1 = 0xB11924E1
        const2 = 0x27100001
        const3 = 0x2709A354
        tldchars = "rupweuinytpmusfrdeitbeuknltf"

        modYear = uint32(ror(const1 * (date[0] + 0x1BF5), 7))
        modYear = uint32(ror(const1 * (modYear + seed + const2), 7))
        modDay = uint32(ror(const1 * (modYear + (date[2] >> 1) + const2), 7))
        modMonth = uint32(ror(const1 * (modDay + date[1] + const3), 7))
        seed = uint32(rol(seed, 17))
        modBase = uint32(rol(i & 7, 21))
        modFinal = uint32(ror(const1 * (modMonth + modBase + seed + const2), 7) + const2)

        genLength = modFinal % 11 + 5

        if genLength:
            for i in range (genLength):
                x = uint32(rol(modFinal, i))
                y = uint32(ror(const1 * x, 7))
                z = uint32(y + const2)
                modFinal = z
                url += chr(z % 25 + 97)
        
            url += suffix
            if tld: # Appends user specified TLD instead of generated TLD
                url += tld
            else:
                url += "."
                x = uint32(ror(const1 * modFinal, 7))
                y = uint32((x + const2) % (len(tldchars) / 2))
                url += tldchars[2 * y]
                url += tldchars[2 * y + 1]
        domains.append(url)
    return domains
