{
	"id": "6ab82f74-95e1-4142-876f-2e1d2d8580e8",
	"created_at": "2026-04-06T03:36:58.50166Z",
	"updated_at": "2026-04-10T13:11:35.065984Z",
	"deleted_at": null,
	"sha1_hash": "7c71282be619062934d6849371f9c4a0b6ae1cd2",
	"title": "The DGA of Sisron",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 87107,
	"plain_text": "The DGA of Sisron\r\nArchived: 2026-04-06 03:26:32 UTC\r\nSisron was part of a financial fraud and identity theft botnet. It was taken down by Microsoft in the anti-botnet\r\noperation B106. The malware uses a very simple domain generation algorithm (DGA) that produces sets of\r\nsimilar looking domains.\r\nFor example, these are some of the domains listed in a Sophos report:\r\nmjawmjiwmtia.com\r\nmjawmjiwmtia.org\r\nmjewmjiwmtia.com\r\nmjewmjiwmtia.org\r\nmjiwmjiwmtia.com\r\nmjiwmjiwmtia.org\r\nmjmwmjiwmtia.com\r\nmjmwmjiwmtia.org\r\nmjqwmjiwmtia.com\r\nmjqwmjiwmtia.org\r\nmtcwmjiwmtia.com\r\nmtcwmjiwmtia.org\r\nmtgwmjiwmtia.com\r\nmtgwmjiwmtia.org\r\nmtkwmjiwmtia.com\r\nmtkwmjiwmtia.org\r\nmtuwmjiwmtia.com\r\nmtywmjiwmtia.com\r\nmtywmjiwmtia.org\r\nIn this write-up I show:\r\nwhen the DGA was most active and what names the AV vendors have given the malware;\r\ndisassembly of the DGA routine and its caller;\r\na reimplementation of the DGA in Python as well as a script to determine when a given domain was\r\ngenerated;\r\nproperties of the DGA, including a convoluted yet precise regex to match Sisron domains.\r\nPrevalence and Names\r\nAfter I reversed the DGA, I went through VirusTotal and collected the reports of 514 scans that contacted one of\r\nthe generated domains. Each square in the following graphic represents one scan on Virustotal.\r\nhttps://johannesbader.ch/blog/the-dga-of-sisron/\r\nPage 1 of 10\n\nThe first sample with the DGA was uploaded on April 2013. Summer and fall of 2013 saw the most Sisron\r\nsamples. Fewer samples were observed throughout 2014. After that, Sisron died off due to the takedown events —\r\nalmost no samples on Virustotal can be found that use the DGA domains anymore.\r\nSisron has been detected well by most anti virus software. Many products detected all samples, albeit in some\r\ncases only with generic rules. Here is a list of major products with their most common denominations:\r\nproduct\r\nnames\r\nTrendMicro\r\n92% of the samples are detected as TOMB\r\nMcAfee\r\nonly generic detections (Generic PWS; Generic PUP; Generic.dx*; GenericATG; Artemis; …)\r\nClamAV\r\nuses the ids Trojan.Agent-1360 and Trojan.Agent-267491\r\nESET\r\nall except three samples are labelled Win32/Agent.WRQ\r\nAgnitum\r\nDetects over 300 samples as Trojan.Scar. The same name is also used by Malwarebytes, VBA32, ViRobot,\r\nJiangmin, TheHacker and AhnLab-V3\r\nMicrosoft\r\nMicrosoft detects 411 samples as Trojan:Win32/Sisron and 89 as Trojan:Win32/Sisron!gmb\r\nKaspersky\r\nCalls the samples either HEUR:Trojan.Win32.Generic or Trojan-Spy.Win32.Zbot.njah\r\nSophos\r\nUses the designations Troj/Agent-UYB and Troj/Agent-OWJ\r\nReverse Engineering\r\nhttps://johannesbader.ch/blog/the-dga-of-sisron/\r\nPage 2 of 10\n\nI reversed the following sample from VirusShare.com. The sample was discovered by Daniel Plohmann with the\r\nhelp of Shadowserver:\r\nmd5\r\ne0a9b99f6b05a0cd66cdb5e4f5037980\r\nsha256\r\nc80b5846fe82d218f496db519d6cfe7b9d7625dd2e00b044850208d28a7eee94\r\nsha1\r\nc71df833c529b33f10b865ae922ab8c3cb45afb4\r\nsource\r\nVirusShare\r\nVirustotal report\r\nlink\r\nsize\r\n89'242 bytes\r\nExIF time stamp\r\n2010:09:22 06:56:08-04:00\r\nDGA\r\nThe DGA has three parts:\r\n1. Generating a time-based string.\r\n2. Encoding the string with a slightly modified base64 to obtain the second level domain.\r\n3. Appending one of four top level domains.\r\nTime-Based String\r\nThe DGA is seeded with the current date — determined by calling __time64 . Sisron uses a sliding window so\r\nthat domains are valid for more than one day. The malware achieves this sliding window by backdating the current\r\ndate a variable number of seconds given in the first function argument. The resulting time value is finally\r\nconverted into a string of format \u003cday\u003e\u003cmonth\u003e\u003cyear\u003e , e.g., 31052016 .\r\nhttps://johannesbader.ch/blog/the-dga-of-sisron/\r\nPage 3 of 10\n\nBase64\r\nThe date string is transformed using base64 with three modifications:\r\n1. The characters for index 62 and 63 are both a , not the commonly used + and / , which of course\r\nwould not be valid domain letters. This modification is not necessary and has no effect. The binary\r\nrepresentation of 62 and 63 is 111110 and 111111 respectively. The encoding, however, operates on\r\nASCII digits which at most have 3 consecutive 1 s in their binary representation and start with 00 . So\r\nregardless of which sequence of digits is encoded, there is no way to have more than three consecutive\r\n1 s. For the same reason there are no digits in the base64 encoding.\r\n2. Padding uses the letter a instead of = . Note that the date string always has 8 letters which requires one\r\npadding byte. All second level domains therefore end with a (see Regex).\r\n3. The resulting string is converted to lowercase, as domains are case insensitive.\r\nInterestingly, even though the encoded string is converted to lowercase, it still can be reversed back to the original\r\ndate, see Section Reversal.\r\nhttps://johannesbader.ch/blog/the-dga-of-sisron/\r\nPage 4 of 10\n\nTop Level Domain\r\nhttps://johannesbader.ch/blog/the-dga-of-sisron/\r\nPage 5 of 10\n\nThe top level domain is selected from an array of four top level domains .com, .org, .net, and .info. The index into\r\nthe tld array is passed as the second argument of the DGA routine.\r\nDGA Caller\r\nThe following routine excerpt calls the DGA:\r\nhttps://johannesbader.ch/blog/the-dga-of-sisron/\r\nPage 6 of 10\n\nhttps://johannesbader.ch/blog/the-dga-of-sisron/\r\nPage 7 of 10\n\nRegister eax holds the argument to the function, which is mapped as follows to the parameters of the DGA:\r\nnumber of seconds to backdate the date: 86400*(eax % 10) . 86400 is the number of seconds in a day, so\r\nthe date is backdated between 0 and 9 days.\r\ntop level domain index: (eax // 10) . The register eax is assigned the values 0 to 39, as can be seen in\r\nthe next graph view. This means that the tld index is 0 to 3, which corresponds with the four top level\r\ndomains.\r\nAs can also be seen from the above graph view, the DGA sleeps 3 seconds after each failed DNS request. Once the\r\nindex reaches 40, it is reset to 0, leading to an infinite loop as long as none of the 40 domains resolve.\r\nReimplementation and Reversal\r\nReimplementation\r\nThe following Python code generates all 40 domains for a given date (including the domains from the sliding\r\nwindow). You also find this code, as well as reimplementations for other DGAs, on my Github page.\r\nfrom datetime import datetime, timedelta\r\nimport base64\r\nimport argparse\r\nhttps://johannesbader.ch/blog/the-dga-of-sisron/\r\nPage 8 of 10\n\ndef dga(d, day_index, tld_index):\r\n tlds = [\".com\", \".org\", \".net\", \".info\"]\r\n d -= timedelta(days=day_index)\r\n ds = d.strftime(\"%d%m%Y\")\r\n return base64.b64encode(ds).lower().replace(\"=\",\"a\") + tlds[tld_index]\r\nif __name__==\"__main__\":\r\n parser = argparse.ArgumentParser()\r\n parser.add_argument(\"-d\", \"--date\", help=\"date for which to generate domains\")\r\n args = parser.parse_args()\r\n if args.date:\r\n d = datetime.strptime(args.date, \"%Y-%m-%d\")\r\n else:\r\n d = datetime.now()\r\n for i in range(40):\r\n print(dga(d, i%10, i//10))\r\nReversal\r\nAlthough the DGA is converting the base64 encoding to lowercase, e.g., not distinguishing between a and A ,\r\nthe domains can still be converted back to a unique date. The following code takes a domain and converts it back\r\nto the date:\r\nfrom datetime import datetime, timedelta\r\nimport base64\r\nimport argparse\r\ndef reverse(domain):\r\n domain = domain.split('.')[0][:-1] + \"=\"\r\n for c in ['A','E','D','I','M','O','N','Q','U','T','Y']:\r\n domain = domain.replace(c.lower(),c)\r\n return datetime.strptime(base64.b64decode(domain), \"%d%m%Y\")\r\nif __name__==\"__main__\":\r\n parser = argparse.ArgumentParser()\r\n parser.add_argument(\"domain\")\r\n args = parser.parse_args()\r\n print(\"The domain is from {}\".format(reverse(args.domain).strftime(\"%x\")))\r\nFor example:\r\n$ python reverse.py mjkwntiwmtya.info\r\nThe domain is from 05/29/16\r\nhttps://johannesbader.ch/blog/the-dga-of-sisron/\r\nPage 9 of 10\n\nBe aware of the sliding window: a given date can be revisited up to 9 days into the future. The domain in the\r\nexample above will be generated up to June 6th.\r\nProperties\r\nCharacteristics\r\nThe following tables summarizes the properties of the Sisron DGA.\r\nproperty value\r\ntype TDD (time-dependent-deterministic)\r\ngeneration scheme pseudo base64 encoding\r\nseed current date\r\ndomain change frequency daily, with a 10 day sliding window\r\ndomains per day 4 (plus 36 revisited)\r\nsequence sequential\r\nwait time between domains 3 seconds\r\ntop level domains .com, .org, .net, .info\r\nsecond level characters very limited set of lower case letters, see Regex\r\nsecond level domain length 12\r\nRegex\r\nSince the source of input of the base64 encoding are dates — and therefore a very small subset of all 8 byte\r\ncombinations — there exists a quite specific regular expression for the domains. The following regex holds for all\r\ndomains for the years 2000 to 2100:\r\n[m][djtz][acegikmquy][wx][mno][djtz][i][wx][mno][djtz][acegikmquy][a]\\.(com|org|net|info)\r\nAll second level domains begin with m and end with a . The remaining letters are also limited. Some letters\r\ndon’t appear at all, i.e., bfhlprsv .\r\nSource: https://johannesbader.ch/blog/the-dga-of-sisron/\r\nhttps://johannesbader.ch/blog/the-dga-of-sisron/\r\nPage 10 of 10",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"ETDA"
	],
	"origins": [
		"web"
	],
	"references": [
		"https://johannesbader.ch/blog/the-dga-of-sisron/"
	],
	"report_names": [
		"the-dga-of-sisron"
	],
	"threat_actors": [],
	"ts_created_at": 1775446618,
	"ts_updated_at": 1775826695,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/7c71282be619062934d6849371f9c4a0b6ae1cd2.pdf",
		"text": "https://archive.orkl.eu/7c71282be619062934d6849371f9c4a0b6ae1cd2.txt",
		"img": "https://archive.orkl.eu/7c71282be619062934d6849371f9c4a0b6ae1cd2.jpg"
	}
}