{
	"id": "ba4e84a4-77b0-4292-9353-c58aa2e27a11",
	"created_at": "2026-04-06T00:21:21.986639Z",
	"updated_at": "2026-04-10T13:11:50.038586Z",
	"deleted_at": null,
	"sha1_hash": "a2f8f4687a06a3030054c4e828161333fcf5ccc2",
	"title": "The Domain Generation Algorithm of Orchard v3 - A DGA Seeded by the Bitcoin Genesis Block",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 99623,
	"plain_text": "The Domain Generation Algorithm of Orchard v3 - A DGA Seeded\r\nby the Bitcoin Genesis Block\r\nArchived: 2026-04-05 20:25:12 UTC\r\nEdit 2022-08-08: Two weeks after this blog post, 360 Netlab published a detailed report on the malware, whose\r\nDGA version 3 I have described below. Please read Netlab’s post for general informations about the malware and\r\ntwo older DGA’s that is uses. I have adopted the name “Orchard” that they have given to the malware.\r\nXMRig is an open-source software for mining cryptocurrencies like Monero or Bitcoin. It is also frequently used\r\nby cryptojacking malware to mine cryptocurrencies on victims’ computers. These malwares are a dime a dozen\r\nand are mostly unremarkable — to the point that they remain unnamed by AV vendors. Orchard is no exception.\r\nWhat sets the sample apart, however, is its Domain Generation Algorithm (DGA) which uses two different\r\nsources for seeding:\r\n1. the current date — which is deterministic of course\r\n2. balance of the Bitcoin genesis block (the first block on the Bitcoin blockchain) — which is not\r\ndeterministic\r\nFor both seeds the same algorithm is used to generate the domains. The first 16 domains are derived from the\r\ncurrent date, while the next 16 domains are based on the Bitcoin block:\r\nhttps://bin.re/blog/a-dga-seeded-by-the-bitcoin-genesis-block/\r\nPage 1 of 11\n\nFigure 1DNS traffic related to the DGA. The first 16 domains are seeded with the date, and the last\r\n16 domains with the genesis block, whose current balance is retrieved from blockchain.info (larger\r\nversion).\r\nI analyzed the following sample:\r\nFile type\r\nPE32 executable (GUI) Intel 80386, for MS Windows\r\nMD5\r\n077b6b101cccb3d77a98e2cc02003526\r\nSHA1\r\nhttps://bin.re/blog/a-dga-seeded-by-the-bitcoin-genesis-block/\r\nPage 2 of 11\n\n9e4f04d513ef119d7872c7ce0af6ffbdf4f42a7c\r\nSHA256\r\n2e63bbbbbb11c21445885f85fc8ef398737184c603f365c8e77a8cbf7523cac9\r\nSize\r\n507 KB (519680 Bytes)\r\nCompile Timestamp\r\n2022-06-19 16:47:27 UTC\r\nLinks\r\nMalwareBazaar, Cape, Dropping_sha256, Dropping_md5, VirusTotal\r\nFilenames\r\nuAAAACCCGGGJ.exe (VirusTotal )\r\nDetections[\r\nVirustotal: 53/73 as of 2022-07-22, nothing specific\r\nThe sample unpacks to this binary, which — like the original — can be downloaded from MalwareBazaar:\r\nFile type\r\nPE32 executable (GUI) Intel 80386, for MS Windows\r\nMD5\r\n5c13ee5dbe45d02ed74ef101b2e82ae6\r\nSHA1\r\nbdc36bc233675e7a96faa2c4917e9b756cc2a2a0\r\nSHA256\r\nad1e39076212d8d58ff45d1e24d681fe0c600304bd20388cddcf9182b1d28c2f\r\nSize\r\n400 KB (409600 Bytes)\r\nCompile Timestamp\r\n2022-06-19 19:59:36 UTC\r\nLinks\r\nMalwareBazaar, Dropped_by_md5, Dropping_sha256, Cape, Dropped_by_sha256, VirusTotal\r\nDetections\r\nVirustotal: 53/74 as of 2022-07-22, nothing specific.\r\nMany more samples that feature the DGA can be found on VirusTotal since June 22, 2022, with a clear cluster on\r\nJuly 6 and 7. The hashes are summarized in this VT Collection.\r\nSeeding\r\nThe first seed is calculated by taking the current date and formatting it as YYYY-mm-dd , e.g., 2022-07-23 . Then\r\na hardcoded domain name is appended. In the examined sample, the domain is “ ojena.duckdns.org ” so the\r\nresulting seed string would be “ 2022-07-23ojena.duckdns.org ”.\r\nThe second seed is obtained by making a GET request to the following URL:\r\nhttps://bin.re/blog/a-dga-seeded-by-the-bitcoin-genesis-block/\r\nPage 3 of 11\n\nhttps://blockchain.info/balance?active=1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa\r\nThis url returns the current balance of the Bitcoin genesis block. The response is the seed for the DGA, for\r\nexample:\r\n{\"1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa\":{\"final_balance\":6854870116,\"n_tx\":3389,\"total_received\":6854870116}}\r\nDue to the fame of the genesis account, it receives many transactions, which all result in a changed seed string and\r\ntherefore different domains. The time between transactions varies greatly, but there was only about a 20% chance\r\nlast year that a domain would have been valid for more than 2 days.\r\nFigure 2Lifespan of DGA domains seeded by the Bitcoin genesis block (larger version).\r\nDGAs that use undeterministic sources for seeding are rare: Bedep used the foreign exchange reference rates\r\npublished by the European Central Bank and Torpig Twitter trends. Unlike for these two examples, the seed in our\r\ncase can be changed by anyone with a predictable outcome. This allows domains to be registered before they are\r\nused by Orchard, something which is not possible for Bedep and Torpig whose seeds can’t be influenced.\r\nDomain Generation\r\nThe DGA itself is very simple: The seed string is MD5-hashed, then the hex representation of the hash is split into\r\n4 strings of 8 characters to form the second level domains (sld). These 4 slds are then combined with 4 hardcoded\r\ntop level domains to form 16 domains:\r\nhttps://bin.re/blog/a-dga-seeded-by-the-bitcoin-genesis-block/\r\nPage 4 of 11\n\nFigure 3Illustration of the DGA (larger version)\r\nReimplementation\r\nThe following script is a reimplementation of the DGA in Python. It can generate the first set of domains for\r\narbitrary dates, but if you like to generate the second set of domains seeded by the genesis block, you need to\r\nrequest it with the -b command line argument. This will check if the date is covered by a local database of\r\ntransactions of the Bitcoin genesis block. If necessary, this database will be updated by downloading transactions\r\nfrom blockchain.info. You find the DGA on my Github 1, along with a database of transactions until September\r\n2022.\r\nimport argparse\r\nimport hashlib\r\nimport itertools\r\nimport json\r\nimport os\r\nimport time\r\nfrom datetime import date, datetime\r\nfrom typing import Iterator, Union\r\nimport requests\r\nLIMIT = 100\r\nDB_PATH = \"db.json\"\r\nBLOCK = \"1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa\"\r\nPATTERN = '{\"1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa\":{\"final_balance\":FB,\"n_tx\":NTX,\"total_received\":FB}}'\r\nhttps://bin.re/blog/a-dga-seeded-by-the-bitcoin-genesis-block/\r\nPage 5 of 11\n\ndef refresh_blockchain_db():\r\n offset = 0\r\n if os.path.exists(DB_PATH):\r\n with open(DB_PATH) as r:\r\n db = json.load(r)\r\n else:\r\n db = {}\r\n while True:\r\n url = f\"https://blockchain.info/multiaddr?active={BLOCK}\u0026limit={LIMIT}\u0026offset={offset}\"\r\n r = requests.get(url)\r\n data = r.json()\r\n error = data.get('error')\r\n if error:\r\n print(f\"error updating blockchain balance: {data}\")\r\n quit()\r\n txs = data[\"txs\"]\r\n for tx in txs:\r\n h = tx['hash']\r\n if h in db:\r\n break\r\n db[h] = tx\r\n else:\r\n time.sleep(1)\r\n offset += LIMIT\r\n continue\r\n break\r\n with open(DB_PATH, \"w\") as w:\r\n json.dump(db, w, indent=2)\r\ndef get_blockchain_seed(when, updated: bool = False) -\u003e str:\r\n if when \u003e datetime.now():\r\n raise ValueError(\r\n \"you can't generate the blockchain domains for the future!\")\r\n with open(DB_PATH) as r:\r\n transactions = json.load(r)\r\n transactions = sorted(\r\n transactions.values(),\r\n key=lambda x: x['balance'],\r\n reverse=True\r\n )\r\n ntx = len(transactions) + 1\r\nhttps://bin.re/blog/a-dga-seeded-by-the-bitcoin-genesis-block/\r\nPage 6 of 11\n\nfor i, transaction in enumerate(transactions):\r\n tt = transaction[\"time\"]\r\n time = datetime.fromtimestamp(tt)\r\n if when \u003c time:\r\n continue\r\n if i == 0 and not updated:\r\n \"\"\" if the desired date is later than the latest transaction,\r\n then update the transaction database to make sure it is\r\n the current transaction you like to access \"\"\"\r\n refresh_blockchain_db()\r\n return get_blockchain_seed(when, updated=True)\r\n balance = transaction['balance']\r\n return PATTERN.replace(\"FB\", str(balance)).replace(\"NTX\", str(ntx-i-1))\r\n raise ValueError(\"the provided date is before the first transaction\")\r\ndef dga(when: Union[date, datetime], blockchain: bool = False) -\u003e Iterator[str]:\r\n for i in range(2):\r\n if i and not blockchain:\r\n return\r\n if i == 0:\r\n magic = when.strftime(\"%Y-%m-%d\")\r\n seed = f\"{magic}ojena.duckdns.org\"\r\n else:\r\n magic = get_blockchain_seed(when)\r\n seed = f\"{magic}\"\r\n md5 = hashlib.md5(seed.encode(\"ascii\")).hexdigest()\r\n slds = [md5[i:i+8] for i in range(0, len(md5), 8)]\r\n tlds = [\".com\", \".net\", \".org\", \".duckdns.org\"]\r\n for sld, tld in itertools.product(slds, tlds):\r\n yield f\"{sld}{tld}\"\r\ndef date_parser(s):\r\n return datetime.strptime(s, \"%Y-%m-%d\")\r\nif __name__ == \"__main__\":\r\n now = datetime.now().strftime(\"%Y-%m-%d\")\r\n parser = argparse.ArgumentParser(\r\n description=\"Orchard malware with DGA based on Bitcoin Genesis Block\"\r\nhttps://bin.re/blog/a-dga-seeded-by-the-bitcoin-genesis-block/\r\nPage 7 of 11\n\n)\r\n parser.add_argument(\r\n \"-d\", \"--date\",\r\n help=\"date for which to generate domains, e.g., 2022-05-09\",\r\n default=now,\r\n type=date_parser\r\n )\r\n parser.add_argument(\r\n \"-b\", \"--blockchain\",\r\n help=\"also generate blockchain domains, requires blockchain db\",\r\n action='store_true'\r\n )\r\n parser.add_argument(\r\n \"-u\", \"--update\",\r\n help=\"just update of blockchain db\",\r\n action='store_true'\r\n )\r\n args = parser.parse_args()\r\n if args.update:\r\n refresh_blockchain_db()\r\n exit()\r\n for domain in dga(args.date, args.blockchain):\r\n print(domain)\r\nCharacteristics of the DGA\r\nThe following table summarizes the properties of the DGA\r\nproperty value\r\ntype TDD-H and TDN-H\r\nseeding time-dependent deterministic and indeterministic\r\ngeneration scheme hash\r\nseed current date\r\ndomain change frequency every day / arbitrary\r\nunique domains per day 32\r\nsequence sequential\r\nwait time between domains none\r\nhttps://bin.re/blog/a-dga-seeded-by-the-bitcoin-genesis-block/\r\nPage 8 of 11\n\nproperty value\r\ntop level domain .com, .net, .org, .duckdns.org\r\nsecond level characters 0-9a-f\r\nregex ``[0-9a-f]{8}.(com\r\nsecond level domain length 8\r\nC2 Communication\r\nThe DGA domains — along with the hardcoded domain ( ojena.duckdns.org ) — are used to control XMRig.\r\nFirst, the client sends some fingerprinting information like the following to the C2. The data is sent unencrypted to\r\na hardcoded port, in my sample to port 25654:\r\n{\r\n \"Active_Window\": \"*internet\",\r\n \"Antivirus\": [\"Windows Defender\"],\r\n \"Authenticate_Type\": 0,\r\n \"CPU_Model\": \"12th Gen Intel(R) Core(TM) i9-12900K\",\r\n \"Camera\": false,\r\n \"Elevated\": false,\r\n \"GPU_Models\": [\r\n {\r\n \"Name\": \"-\",\r\n \"Type\": 2\r\n }\r\n ],\r\n \"Identity\": \"F12C8A2E\\Username\\DESKTOP-XYZ\",\r\n \"Operating_System\": \"{\\\"BuildNumber\\\":19044,\\\"MajorVersion\\\":10,\\\"MinorVersion\\\":0,\\\"ProductType\\\":false}\",\r\n \"Ram_Size\": 17179332608,\r\n \"System_Architecture\": 1,\r\n \"Threads\": 4,\r\n \"Version\": 2\r\n}\r\nAfter that, the XMRig JSON RPC communication is also sent — again unencrypted — to the C2. For example the\r\nlogin:\r\n{\r\n \"id\": 1,\r\n \"jsonrpc\": \"2.0\",\r\n \"method\": \"login\",\r\n \"params\": {\r\n \"login\": \"CPU\",\r\nhttps://bin.re/blog/a-dga-seeded-by-the-bitcoin-genesis-block/\r\nPage 9 of 11\n\n\"pass\": \"x\",\r\n \"agent\": \"XMRig/6.15.2 (Windows NT 10.0; Win64; x64) libuv/1.38.0 msvc/2019\",\r\n \"algo\": [\"cn/0\", \"cn/1\", \"cn/2\", \"cn/r\", \"cn/fast\", \"cn/half\", \"cn/xao\",\r\n \"cn/rto\", \"cn/rwz\", \"cn/zls\", \"cn/double\", \"cn/ccx\", \"cn-lite/0\",\r\n \"cn-lite/1\", \"cn-heavy/0\", \"cn-heavy/tube\", \"cn-heavy/xhv\", \"cn-pico\",\r\n \"cn-pico/tlo\", \"cn/upx2\", \"rx/0\", \"rx/wow\", \"rx/arq\", \"rx/graft\",\r\n \"rx/sfx\", \"rx/keva\", \"argon2/chukwa\", \"argon2/chukwav2\", \"argon2/ninja\",\r\n \"astrobwt\"]\r\n }\r\n}\r\nThese JSON RPC connections of XMRig will be detected by many Suricata rules.\r\nDetection\r\nSpeaking of detections: there are many YARA rule hits you will see both on VirusTotal and MalwareBazaar:\r\nUnfortunately, all these rules by The DFIR Report are non functional 2. I wrote the following YARA rule, but it\r\nonly matches on the unpacked sample, e.g., on memory dumps:\r\nrule win_bitcoin_genesis_b9 {\r\n meta:\r\n author = \"Johannes Bader @viql\"\r\n date = \"2022-07-22\"\r\n description = \"detects a downloader with a DGA based on the Bitcoin Genesis Block\"\r\n tlp = \"TLP:WHITE\"\r\n version = \"v1.0\"\r\n hash_md5 = \"5c13ee5dbe45d02ed74ef101b2e82ae6\"\r\n hash_sha1 = \"bdc36bc233675e7a96faa2c4917e9b756cc2a2a0\"\r\nhttps://bin.re/blog/a-dga-seeded-by-the-bitcoin-genesis-block/\r\nPage 10 of 11\n\nhash_sha256 = \"ad1e39076212d8d58ff45d1e24d681fe0c600304bd20388cddcf9182b1d28c2f\"\r\n strings:\r\n $str_json_1 = \"\\\"bytes\\\": [\"\r\n $str_json_2 = \"\\\"subtype\\\": \"\r\n $str_json_3 = \"{\\\"bytes\\\":[\"\r\n $str_json_4 = \"],\\\"subtype\\\":\"\r\n $str_json_5 = \"null}\"\r\n $str_json_6 = \"\u003cdiscarded\u003e\"\r\n $str_json_7 = \"[json.exception.\"\r\n /*\r\n mov dl, [ebp+var_14]\r\n mov [eax+ecx], dl\r\n mov byte ptr [eax+ecx+1], 0\r\n jmp short loc_3CBF9F\r\n */\r\n $split_hash_1 = {8A 55 ?? 88 14 08 C6 44 08 01 00 EB}\r\n /*\r\n inc ebx\r\n cmp ebx, 10h\r\n jl loc_3CBF10\r\n */\r\n $split_hash_2 = {43 83 FB 10 0F 8C}\r\n /*\r\n push 0\r\n push 0\r\n mov [ebp-14h], edx\r\n mov [ebp-18h], eax\r\n */\r\n $format_the_date = {6A 00 6A 00 89 55 EC 89 45 E8}\r\n condition:\r\n uint16(0) == 0x5A4D and\r\n all of ($str_json_*) and\r\n all of ($split_hash_*) and\r\n $format_the_date\r\n}\r\nSource: https://bin.re/blog/a-dga-seeded-by-the-bitcoin-genesis-block/\r\nhttps://bin.re/blog/a-dga-seeded-by-the-bitcoin-genesis-block/\r\nPage 11 of 11",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"origins": [
		"web"
	],
	"references": [
		"https://bin.re/blog/a-dga-seeded-by-the-bitcoin-genesis-block/"
	],
	"report_names": [
		"a-dga-seeded-by-the-bitcoin-genesis-block"
	],
	"threat_actors": [],
	"ts_created_at": 1775434881,
	"ts_updated_at": 1775826710,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/a2f8f4687a06a3030054c4e828161333fcf5ccc2.pdf",
		"text": "https://archive.orkl.eu/a2f8f4687a06a3030054c4e828161333fcf5ccc2.txt",
		"img": "https://archive.orkl.eu/a2f8f4687a06a3030054c4e828161333fcf5ccc2.jpg"
	}
}