{
	"id": "93b964e9-6ea5-48ca-84dc-cd26923be039",
	"created_at": "2026-04-06T00:19:20.376346Z",
	"updated_at": "2026-04-10T03:21:14.03784Z",
	"deleted_at": null,
	"sha1_hash": "6fdd8a394fdfc0eb56432bd4d56d629ea5714660",
	"title": "The DGA of Ramnit",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 74708,
	"plain_text": "The DGA of Ramnit\r\nArchived: 2026-04-05 23:43:48 UTC\r\nRamnit is a Zeus-like malware from 2010 used to spy on infected users. Although the malware isn’t as prevalent\r\nas it used to be, there are many recent submissions still. Ramnit uses a Domain Generation Algorithm (DGA) to\r\ncontact its C2-server. Upon infection, the sample starts to make DNS queries for many different domains in rapid\r\nsuccession:\r\nI reverse engineered the underlying DGA as a sunday afternoon RCE exercise. I used a fairly recent Ramnit\r\nsample from Malware-Traffic-Analysis.\r\nDGA Disassembly\r\nThe DGA is very simple. Here is the disassembly of the routine that generates the domains:\r\nseg074:2001A91C create_next_domain proc near ; CODE XREF: thread_start+36p\r\nseg074:2001A91C\r\nseg074:2001A91C seed = dword ptr -4\r\nseg074:2001A91C initial_seed = dword ptr 8\r\nseg074:2001A91C hostname = dword ptr 0Ch\r\nseg074:2001A91C\r\nseg074:2001A91C push ebp\r\nseg074:2001A91D mov ebp, esp\r\nseg074:2001A91F add esp, 0FFFFFFFCh\r\nseg074:2001A922 push ebx\r\nseg074:2001A923 push ecx\r\nseg074:2001A924 push edx\r\nseg074:2001A925 push esi\r\nseg074:2001A926 push edi\r\nseg074:2001A927 push 12 ; modulus\r\nseg074:2001A929 push [ebp+initial_seed] ; seed\r\nseg074:2001A92C call rand_int_modulus\r\nseg074:2001A931 mov [ebp+seed], edx\r\nseg074:2001A934 add eax, 8\r\nseg074:2001A937 mov ecx, eax ; ecx = = length of 2nd level domain\r\nseg074:2001A939 mov esi, [ebp+hostname]\r\nseg074:2001A93C\r\nseg074:2001A93C loc_2001A93C: ; CODE XREF: create_next_domain+2Dj\r\nhttps://bin.re/blog/the-dga-of-ramnit/\r\nPage 1 of 9\n\nseg074:2001A93C push 25 ; modulus\r\nseg074:2001A93E push edx ; seed\r\nseg074:2001A93F call rand_int_modulus\r\nseg074:2001A944 add al, 'a' ; -\u003e random letter (one of 25)\r\nseg074:2001A946 mov [esi], al\r\nseg074:2001A948 inc esi\r\nseg074:2001A949 loop loc_2001A93C ; modulus\r\nseg074:2001A94B mov byte ptr [esi], 0 ; null terminate\r\nseg074:2001A94E push offset tld_com ; \".com\"\r\nseg074:2001A953 push [ebp+hostname] ; lpString1\r\nseg074:2001A956 call j_lstrcatA\r\nseg074:2001A95B xor edx, edx\r\nseg074:2001A95D mov eax, [ebp+initial_seed]\r\nseg074:2001A960 mov ebx, [ebp+seed]\r\nseg074:2001A963 mul ebx ; multiply seeds\r\nseg074:2001A965 add eax, edx ; add higher dword\r\nseg074:2001A967 pop edi\r\nseg074:2001A968 pop esi\r\nseg074:2001A969 pop edx\r\nseg074:2001A96A pop ecx\r\nseg074:2001A96B pop ebx\r\nseg074:2001A96C leave\r\nseg074:2001A96D retn 8\r\nseg074:2001A96D create_next_domain end\r\nThe subroutine rand_int_modulus is:\r\nseg074:2001331C ; =============== S U B R O U T I N E =======================================\r\nseg074:2001331C\r\nseg074:2001331C ; Attributes: bp-based frame\r\nseg074:2001331C\r\nseg074:2001331C rand_int_modulus proc near ; CODE XREF: seg074:2001303Fp\r\nseg074:2001331C ; seg074:20013089p ...\r\nseg074:2001331C\r\nseg074:2001331C rnd_seed = dword ptr 8\r\nseg074:2001331C modulus = dword ptr 0Ch\r\nseg074:2001331C\r\nseg074:2001331C push ebp\r\nseg074:2001331D mov ebp, esp\r\nseg074:2001331F push ebx\r\nseg074:20013320 push ecx\r\nseg074:20013321 mov eax, [ebp+rnd_seed]\r\nseg074:20013324 xor edx, edx\r\nseg074:20013326 mov ecx, 127773\r\nseg074:2001332B div ecx ; eax = k1\r\nseg074:2001332D mov ecx, eax ; ecx = k1\r\nhttps://bin.re/blog/the-dga-of-ramnit/\r\nPage 2 of 9\n\nseg074:2001332F mov eax, 16807\r\nseg074:20013334 mul edx\r\nseg074:20013336 mov edx, ecx\r\nseg074:20013338 mov ecx, eax\r\nseg074:2001333A mov eax, 2836\r\nseg074:2001333F mul edx\r\nseg074:20013341 sub ecx, eax ; ix\r\nseg074:20013343 xor edx, edx\r\nseg074:20013345 mov eax, ecx ; eax =ebx = ix\r\nseg074:20013347 mov ebx, ecx\r\nseg074:20013349 div [ebp+modulus]\r\nseg074:2001334C mov eax, edx ; eax = rand_int(seed) % modulus\r\nseg074:2001334E mov edx, ebx ; edx = seed\r\nseg074:20013350 pop ecx\r\nseg074:20013351 pop ebx\r\nseg074:20013352 leave\r\nseg074:20013353 retn 8\r\nseg074:20013353 rand_int_modulus endp\r\nThis is a Linear Congurential Generator (LCG) that produces random numbers. The parameters and\r\nimplementation match this article. The subroutine gets the seed as the first argument, and the modulus as the\r\nsecond parameter.\r\nThe DGA uses this random number generator to first determine the length of the second level domain by\r\nuniformly picking a length between 8 and 19 characters. Next, the DGA determine the second level domain by\r\nuniformly picking letters from “a” to “x” (note: letter “z” can’t be picked, this also helps to spot Ramnit domains).\r\nThe DGA then appends the static top level domain “.com”. Finally, the seed for the next domain is determined.\r\nThe first seed is hardcoded:\r\nseg076:20029004 initial_seed dd 79159C10h\r\nDGA in Python\r\nThe following Python script generates Ramnit domains for a provided seed (Edit January 18, 2015: fixed a bug\r\nin rand_int_modulus , some of the generated domains were wrong before).:\r\nimport argparse\r\nclass RandInt:\r\n def __init__(self, seed):\r\n self.seed = seed\r\n def rand_int_modulus(self, modulus):\r\nhttps://bin.re/blog/the-dga-of-ramnit/\r\nPage 3 of 9\n\nix = self.seed\r\n ix = 16807*(ix % 127773) - 2836*(ix / 127773) \u0026 0xFFFFFFFF\r\n self.seed = ix\r\n return ix % modulus\r\ndef get_domains(seed, nr):\r\n r = RandInt(seed)\r\n for i in range(nr):\r\n seed_a = r.seed\r\n domain_len = r.rand_int_modulus(12) + 8\r\n seed_b = r.seed\r\n domain = \"\"\r\n for i in range(domain_len):\r\n char = chr(ord('a') + r.rand_int_modulus(25))\r\n domain += char\r\n domain += \".com\"\r\n m = seed_a*seed_b\r\n r.seed = (m + m//(2**32)) % 2**32\r\n yield domain\r\nif __name__==\"__main__\":\r\n parser = argparse.ArgumentParser(description=\"generate Ramnit domains\")\r\n parser.add_argument(\"seed\", help=\"seed as hex\")\r\n parser.add_argument(\"nr\", help=\"nr of domains\", type=int)\r\n args = parser.parse_args()\r\n for domain in get_domains(int(args.seed, 16), args.nr):\r\n print(domain)\r\nFor example\r\n$ python dga.py 79159C10 10\r\nknpqxlxcwtlvgrdyhd.com\r\nnvlyffua.com\r\nhgyudheedieibxy.com\r\nanrylixwcbnjopdd.com\r\nvrndmdrdrjoff.com\r\njhghrlufoh.com\r\ntqjhvylf.com\r\nhufqifjq.com\r\nitktxexjghvvxa.com\r\nppyblaohb.com\r\nDGA Characteristics\r\nhttps://bin.re/blog/the-dga-of-ramnit/\r\nPage 4 of 9\n\n\u003ctd\u003e\r\n static\r\n\u003c/td\u003e\r\n\u003ctd\u003e\r\n unlimited\r\n\u003c/td\u003e\r\n\u003ctd\u003e\r\n unlimited\r\n\u003c/td\u003e\r\n\u003ctd\u003e\r\n none\r\n\u003c/td\u003e\r\n\u003ctd\u003e\r\n .com\r\n\u003c/td\u003e\r\n\u003ctd\u003e\r\n all letters except \u0026#8220;z\u0026#8221;\u003c/br\u003e(picked uniformly at random)\r\n\u003c/td\u003e\r\n\u003ctd\u003e\r\n between 8 and 19 characters\u003c/br\u003e(picked uniformly at random)\r\n\u003c/td\u003e\r\nseed\r\ndomains per seed\r\ntested domains\r\nwait time between domains\r\ntop level domain\r\nsecond level characters\r\nsecond level domain length\r\nhttps://bin.re/blog/the-dga-of-ramnit/\r\nPage 5 of 9\n\nObserved Seeds in the Wild\r\nEven without access to the binary one can determine the seed that lead to a given domain: The seed is only 32 bit\r\nwhich makes it possible to enumerate all possible domains and match them with known network traffic. Using this\r\nscript I analysed three different sets of DGA domains to find the underlying seeds. (Edit January 18, 2015: some\r\ndomains were wrong before). (Edit September 14, 2015: found a fourth seed).\r\nSeed: 0xEF214BBF\r\nI found this seed by analysing a malware from malware-traffic-analysis.net. The sample can be downloaded from\r\nmalwr.com. The first 30 domains for this seed are:\r\n1. mtsoexdphaqliva.com\r\n2. uulwwmawqjujuuprpp.com\r\n3. twuybywnrlqcf.com\r\n4. wcqqjiixqutt.com\r\n5. ubgjsqkad.com\r\n6. iihsmkek.com\r\n7. tlmmcvqvearpxq.com\r\n8. flkheyxtcedehipox.com\r\n9. edirhtuawurxlobk.com\r\n10. tfjcwlxcjoviuvtr.com\r\n11. bfmbrrihwsfkqy.com\r\n12. fyodimwialsoobu.com\r\n13. crudcqgf.com\r\n14. toixqdmkicnrdhseduj.com\r\n15. ssofasuafn.com\r\n16. edaqpyrppopwldv.com\r\n17. qbuyqrogyglljk.com\r\n18. hpmnvvbhnoomnkj.com\r\n19. rgggwpfcwueytjoxfb.com\r\n20. cslbnrypemnx.com\r\n21. hycrotqqubvplffbk.com\r\n22. ytxtdhjlme.com\r\n23. pxgmtqfoluw.com\r\n24. lqenouffubcjpvtmf.com\r\n25. eqhpcqjxpeqhjravy.com\r\n26. iqlibdbawapeb.com\r\n27. opfgjnhe.com\r\n28. xlrcqwuyehrsqu.com\r\n29. arnsjlbjaqsswum.com\r\n30. neqkjkopo.com\r\nhttps://bin.re/blog/the-dga-of-ramnit/\r\nPage 6 of 9\n\nSeed: 0x28488EEA\r\nThis seed was used first in March 2012. Some of the samples are Malwr, Sonicwall, Sophos, another Sophos,\r\nLavasoft. The first 30 domains for this seed are:\r\n1. htmthgurhtchwlhwklf.com\r\n2. jiwucjyxjibyd.com\r\n3. khddwukkbwhfdiufhaj.com\r\n4. snoknwlgcwgaafbtqkt.com\r\n5. tfgyaoingy.com\r\n6. ukiixagdbdkd.com\r\n7. swbadolov.com\r\n8. ouljuvkvn.com\r\n9. tiqfgpaxvmhsxtk.com\r\n10. cxatodxefolgkokdqy.com\r\n11. ubkfgwqslhqyy.com\r\n12. caytmlnlrou.com\r\n13. qbsqnpyyooh.com\r\n14. vrguyjjxorlyen.com\r\n15. nvepdnpx.com\r\n16. vwaeloyyutodtr.com\r\n17. gokbwlivwvgqlretxd.com\r\n18. mukevipvxvrq.com\r\n19. empsqyowjuvvsvrwj.com\r\n20. duomyvwabkuappgqxhp.com\r\n21. voohnyqdinl.com\r\n22. ncxphtrpiawmchfylsy.com\r\n23. xwrmquiqjdsxk.com\r\n24. ldiogjdyyxacm.com\r\n25. kuetvxnntsk.com\r\n26. lsawmyxqxvmogvxifm.com\r\n27. ppdbeidwufrb.com\r\n28. tfipmwkcgigiey.com\r\n29. pgahbyurf.com\r\n30. yaesbfejdxs.com\r\nSeed: 0x4BFCBC6A\r\nThis seed probably first appeared early 2013. There are a couple of Sophos reports that correspond to this seed:\r\nRamnit-B, Ramnit-FS, Ramnit-DD, Ramnit-DA, Ramnit-DB.\r\nThe first 30 generated domains are:\r\n1. rkjtwjwmesvwhpc.com\r\nhttps://bin.re/blog/the-dga-of-ramnit/\r\nPage 7 of 9\n\n2. axigleyldgeq.com\r\n3. wxsssfvmqi.com\r\n4. nhedwmmg.com\r\n5. axswdqnjgrnryt.com\r\n6. roiornfvclppad.com\r\n7. sqhofbxqksckbfrs.com\r\n8. rwtxpiehuiiucxkfckw.com\r\n9. pmyadxuvmfmcajv.com\r\n10. uejgdopjiyxnnvws.com\r\n11. nbfplqkemrpedccrcyp.com\r\n12. ywyqjdqktqxsxkt.com\r\n13. gveejaqxpyrb.com\r\n14. vuxrkjrewjwl.com\r\n15. mgnodqfisg.com\r\n16. dhlpcscshdrvpcpp.com\r\n17. xygkltvhkvbje.com\r\n18. ijxahlsdiw.com\r\n19. jhchibrcyo.com\r\n20. sdcepuelyqary.com\r\n21. nqbvanrafsi.com\r\n22. txnhnwwxfam.com\r\n23. jpdvnajhhv.com\r\n24. kkiykxbsc.com\r\n25. hxlsxpmmtdqqvo.com\r\n26. cnlbabnssw.com\r\n27. dthjrnnicjkdetclt.com\r\n28. eewbwvjommryy.com\r\n29. vjckfodjtbobafxmc.com\r\n30. yswkdrulyic.com\r\nSeed: 0x79159C10\r\nThis seed was used first in April 2014. Here are some of the samples that use this seed: Malwr, Sophos Ramnit-BZ, many samples on Virustotal. The first 30 domains for this seed are:\r\n1. knpqxlxcwtlvgrdyhd.com\r\n2. nvlyffua.com\r\n3. hgyudheedieibxy.com\r\n4. anrylixwcbnjopdd.com\r\n5. vrndmdrdrjoff.com\r\n6. jhghrlufoh.com\r\n7. tqjhvylf.com\r\n8. hufqifjq.com\r\nhttps://bin.re/blog/the-dga-of-ramnit/\r\nPage 8 of 9\n\n9. itktxexjghvvxa.com\r\n10. ppyblaohb.com\r\n11. ectdsitvvoydawmfni.com\r\n12. vbvqbnwyurqem.com\r\n13. jetuergatod.com\r\n14. anxsmqyfy.com\r\n15. ckyioylutybvcxv.com\r\n16. khllpmpmare.com\r\n17. riaaiysk.com\r\n18. vfrpojablskkqrx.com\r\n19. egopuefrdsefc.com\r\n20. fycecyuksgjfxy.com\r\n21. qyuylvjwh.com\r\n22. wldlrwlygck.com\r\n23. lcqavndroo.com\r\n24. acuhjbadvnmhthwnlxv.com\r\n25. qvberjspofqsxdnr.com\r\n26. euvyalbkwahxxjn.com\r\n27. typmyloijdcxtdxd.com\r\n28. hjahmduyebf.com\r\n29. ebrfoyrs.com\r\n30. uvenqtbfbeyvebqeb.com\r\nSource: https://bin.re/blog/the-dga-of-ramnit/\r\nhttps://bin.re/blog/the-dga-of-ramnit/\r\nPage 9 of 9",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"references": [
		"https://bin.re/blog/the-dga-of-ramnit/"
	],
	"report_names": [
		"the-dga-of-ramnit"
	],
	"threat_actors": [],
	"ts_created_at": 1775434760,
	"ts_updated_at": 1775791274,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/6fdd8a394fdfc0eb56432bd4d56d629ea5714660.pdf",
		"text": "https://archive.orkl.eu/6fdd8a394fdfc0eb56432bd4d56d629ea5714660.txt",
		"img": "https://archive.orkl.eu/6fdd8a394fdfc0eb56432bd4d56d629ea5714660.jpg"
	}
}