{
	"id": "36e80383-d609-4eb2-8e8d-34c79b7092f0",
	"created_at": "2026-04-06T00:17:18.469352Z",
	"updated_at": "2026-04-10T03:36:13.672556Z",
	"deleted_at": null,
	"sha1_hash": "2e99d3f12eb1d20fd2aa3f73becc877214de514f",
	"title": "Adjusting the Anchor",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 364305,
	"plain_text": "Adjusting the Anchor\r\nPublished: 2021-07-15 · Archived: 2026-04-05 16:58:10 UTC\r\nOverview\r\nAnchorDNS is a backdoor used by the TrickBot actors to target selected high value victims. It has been seen\r\ndelivered by both TrickBot and Bazar1 malware campaigns2. AnchorDNS is particularly difficult to track given\r\nthat it is deployed only post-infection and that too only after a period of reconnaissance, once the malware\r\noperators have established that the target is of special interest.\r\nFollowing analysis of AnchorDNS samples published in recent reporting23, we have observed that the C2\r\ncommunications protocol of AnchorDNS has changed. We also see the use of another Anchor component called\r\nAnchorAdjuster. The newer variants contain a modification to the structure of the messages sent to the C2, and\r\nhave added additional encryption routines when creating the DNS queries. Data received from the C2 is now\r\nencoded, thereby making the traffic less obvious.\r\nIn this post we analyze the role that AnchorAdjuster plays and outline the changes made to the communication\r\nprotocol by the recent AnchorDNS samples.\r\nAnchorAdjuster\r\nAnchorAdjuster is a tool that is used to modify an AnchorDNS sample with an updated config and the victim’s\r\nUUID. The tool is executed by an external command and has been seen being run by CobaltStrike2.\r\nA valid series of arguments need to be passed to the AnchorAdjuster for it to execute succesfully. If arguments are\r\nnot passed, the tool outputs a message onto the console detailing the arguments required:\r\nusing:\r\nanchorAdjuster* --source=\u003csource file\u003e --target=\u003ctarget file\u003e --domain=\u003cdomain name\u003e\r\n --period=\u003crecurrence interval, minutes, default value 15\u003e-guid\r\nBelow is a description of the arguments:\r\nArgument Description Requirements\r\n--source AnchorDNS sample with a blank config Required\r\n--target Name to save the modified AnchorDNS sample Required\r\n--domain Domain C2s to save as config Required\r\n--period Interval between each cycle of DNS queries; default is 15 minutes Optional\r\nhttps://www.kryptoslogic.com/blog/2021/07/adjusting-the-anchor/\r\nPage 1 of 8\n\nArgument Description Requirements\r\n--lasthope Number of communication attempts; default is 100 Optional\r\n-guid Flag for initializing the Victim’s UUID in the sample Required\r\nThe AnchorAdjuster tool works as follows:\r\nFirstly, if it finds a 16 byte string of AAAAAAAAAAAAAAAA in the AnchorDNS bot, it rewrites it with a UUID that it\r\ngenerates by calling CoCreateGuid . This creates a UUID unique to the victim machine. The string\r\nAAAAAAAAAAAAAAAA acts as a placeholder for the UUID and is typically stored in the .rand section.\r\nSecondly, if it finds a 66 byte string of all B s, it overwrites this string with XOR encoded C2s. The C2s are the\r\nvalues that were passed to the AnchorAdjuster’s --domain argument. The XOR key used is a hardcoded hex\r\nvalue 0x23 .\r\nFinally, using the name passed to the --target argument, the tool creates a new AnchorDNS bot with these\r\nmodifications.\r\nBelow is an example standard output log from the tool after successful execution:\r\nsource file size 347648\r\nguid: 743E900F5861EF468E120559E9D23EF8, shift 0x00053C00(343040)\r\ndomain: shift 0x00053A04(342532)\r\nOK\r\nThis technique reuses an AnchorDNS sample to be able to communicate to new C2s that it provides, without\r\nhaving to re-compile an entirely new AnchorDNS binary. This also helps the threat actors to hide any new C2s\r\ncreated, especially if the AnchorDNS sample were to be discovered by a threat researcher.\r\nAnchorDNS\r\nAnchorDNS communicates to its C2 servers using DNS Tunnelling. Using the DNS protocol for command \u0026\r\ncontrol benefits AnchorDNS because such requests are often allowed to pass through firewalls. Using this method,\r\nAnchorDNS is able to exfiltrate data to its C2s in the form of DNS queries. The data is encoded and made to\r\nappear as subdomains. In addition, the C2 can communicate back to the bot by sending information in the form of\r\nDNS A records whereby the data is reconstructed by the bot based on AnchorDNS’s specific format.\r\nReview on how AnchorDNS works\r\nTo get a better grasp on what new changes have been implemented to this DNS communication, this section will\r\ndo a quick high-level review on how AnchorDNS works.\r\n1. Upon initial execution, AnchorDNS gains persistence on the machine by creating a scheduled task that is\r\nset to run every 15 minutes.\r\nhttps://www.kryptoslogic.com/blog/2021/07/adjusting-the-anchor/\r\nPage 2 of 8\n\nThe frequency of the scheduled task can be modified again by the bot if the C2 sends a command\r\nwith instructions to do so.\r\n2. Each run cycle involves a series of commands transmitted as DNS queries between the bot and the C2.\r\nInitial beacon message.\r\nRequest from the bot for command to be executed.\r\nRequest from the bot for a payload (if the command requires one).\r\nSend report on the command’s execution.\r\nPreparing the messages for the C2\r\nThe name of the bot at the start of the message has changed from anchor_dns to stickseed . This new name is\r\nvery different from that of the name used in the past variants4. One possible explanation is that tick in\r\nstickseed represents the Windows API GetTickCount and seed for a pseudorandom number generator, the\r\ntwo functions that we see being frequently used in the new variant.\r\nThe GUID created by the Bot is recorded by the C2 to keep track of the different infected machines. The format\r\nof the GUID is as follows:\r\n\u003cComputer_Name\u003e_W\u003cmajor version\u003e\u003cminor version\u003e\u003cversion build number\u003e.\u003c16 bytes UUID\u003e\r\nThe 16 byte UUID is hardcoded in the .rand section of the AnchorDNS PE file. If there are no 16 bytes in the\r\n.rand section or if there is a string AAAAAAAAAAAAAAAA in that section, the bot skips making any DNS queries.\r\nExample GUID :\r\nADMINWIN10_W629200.1BDD88D8278746A68CE4BCF8DCF27B7E\r\nBelow is a summary of the messages and the command sent to the C2:\r\nC2\r\nCommand\r\nDescription Info sent by New Variant Info sent by Previous Variant\r\n0 Register Bot\r\n/stickseed/\u003cGUID\u003e/0/\u003cWindows OS\r\nType\u003e/1001/\u003cBot IP\u003e/\u003c32 random\r\nhex bytes\u003e/\u003c32 random\r\nalphanumeric characters\u003e/\r\n/anchor_dns/\u003cGUID\u003e/0/\u003cWindows OS\r\nType\u003e/1001/\u003cBot IP\u003e/\u003c32 random hex\r\nbytes\u003e/\u003c32 random alphanumeric\r\ncharacters\u003e/\r\n1\r\nRequest Bot\r\ncommand\r\n/stickseed/\u003cGUID\u003e/1/\u003c32 random\r\nalphanumeric characters\u003e/\r\n/anchor_dns/\u003cGUID\u003e/1/\u003c32 random\r\nalphanumeric characters\u003e/\r\n5 Request File /stickseed/\u003cGUID\u003e/5/\u003cfilename\u003e /anchor_dns/\u003cGUID\u003e/5/\u003cfilename\u003e\r\n10\r\nSend result\r\nof Bot\r\ncommand\r\nexecution\r\n/stickseed/\u003cGUID\u003e/10/\u003cBot\r\nCommand\u003e/\u003cBot Command ID\u003e/\u003cResult\r\nof Command execution\u003e/\r\n/anchor_dns/\u003cGUID\u003e/10/\u003cBot\r\nCommand\u003e/\u003cBot Command ID\u003e/\u003cResult\r\nof Command execution\u003e/\r\nhttps://www.kryptoslogic.com/blog/2021/07/adjusting-the-anchor/\r\nPage 3 of 8\n\nThe DNS Queries\r\nEach message above, made by the AnchorDNS bot, to send to the C2 involves a sequence of 3 types of DNS\r\nqueries5. This order is still maintained in the new variants. The table below shows a summary of the sequence of\r\nDNS queries made:\r\nQuery\r\nOrder\r\nInfo Sent Info Received\r\n0 Send info including command Receive IP record from C2\r\n1 Convert IP to identifier and send to C2 Receive IP record from C2\r\n2\r\nConvert IP to size; send identifier and size to\r\nC2\r\nReceive data in the form of multiple IP\r\nrecords\r\nCrafting the Queries\r\nThe new variants make changes to the way in which the queries are crafted.\r\nOld Variant:\r\nTo better understand the changes made, this section will briefly review how the queries were crafted in the\r\nprevious variants. Each query would contain information about the query type and a 16 byte UUID. The query\r\ntype would inform the C2 on what type of message it is receiving and the UUID helps it keep track of the queries.\r\nIf the crafted query is type 0, the message gets divided into parts. This is to ensure that the length of the query\r\nremains under 255 characters. Finally, the queries are XOR’ed with the key 0xb9 . This is the only encoding we\r\nsee in the previous variants.\r\nThe table below summarizes the queries crafted in the old variants6:\r\nQuery\r\nOrder\r\nQuery\r\nType\r\nOld Variant Format Encoding\r\n0 0\r\n0\u003cUUID\u003e\u003c(BYTE)Current Part\u003e\u003c(BYTE)Total Parts\u003e\r\n\u003cDivided Message\u003e\r\nxor with\r\n0xb9\r\n1 1 1\u003cUUID\u003e\u003c(DWORD)Identifier\u003e\r\nxor with\r\n0xb9\r\n2 2 2\u003cUUID\u003e\u003c(DWORD)Identifier\u003e\u003c(DWORD)Size\u003e\r\nxor with\r\n0xb9\r\nNew Variant:\r\nhttps://www.kryptoslogic.com/blog/2021/07/adjusting-the-anchor/\r\nPage 4 of 8\n\nIn the new variant, before a query is crafted, the message in each DNS query type is XOR’ed with the key United\r\nStates of America (USA) . After encoding the message, a 16 byte UUID is generated for each query type (like the\r\nprevious variant, the UUID is for the C2 to keep track of the query) and is further encoded with a custom Base32\r\nalgorithm using the custom dictionary dghbcijklmnfqrwxyz23stuopaev4569 .\r\nThe bot then calculates if the message needs to be divided into parts for all 3 DNS query types (in the previous\r\nvariant we see this for only the query type 0).\r\nBelow is a python function that calculate the number of parts a message would get divided into and the size of\r\neach part:\r\nimport random\r\ndef get_parts(msg_len: int, c2_len: int) -\u003e list():\r\n blocks = list()\r\n foo = 5 * (0xba - 0x1a - c2_len - 8)\r\n fee = ((foo \u0026 7) + foo) \u003e\u003e 3\r\n faa = fee * 0.85\r\n if faa \u003e (fee - 5):\r\n faa = (fee - 5) * 0.85\r\n i, count = 0, 0\r\n while i \u003c msg_len:\r\n block_sz = msg_len - i\r\n if (msg_len - i) \u003e fee:\r\n rand = random.randint(0,0x7fff)\r\n fii = fee - 5\r\n if count:\r\n fii = fee\r\n block_sz = int(((rand * (fii - faa)) / 32767.0) + faa)\r\n i += block_sz\r\n count += 1\r\n blocks.append(block_sz)\r\n return blocks\r\nIn the new variant, the DNS query types are labeled differently (but still follow the same order as the previous):\r\nQuery Order Query Type Message\r\n0 0x0001 /stickseed/\u003cGUID\u003e/\u003cC2 Command\u003e/\u003cInfo if any\u003e/\r\n1 0xfffe \u003cIdentifier DWORD\u003e\r\n2 0xffff \u003cIdentifier DWORD\u003e\u003cSize in DWORD of data received\u003e\r\nFor each divided message part, additional information is appended. The image below gives an example of a\r\nmessage for DNS query type 0x0001 and how each divided part is crafted:\r\nhttps://www.kryptoslogic.com/blog/2021/07/adjusting-the-anchor/\r\nPage 5 of 8\n\nMessage being built for the queries\r\nThe resulting data is encoded with a custom Base32 algorithm and the encoded Base32 UUID is appended at the\r\nend. So for example, the message parts above would result in the following types of DNS queries being made:\r\nefkezwpdxpsq3lsdv2mp3u5kl.mppdslkiaohiqmhplaekp.rrzynhijic42cljjandescbf4nim\r\n .anoopcsmswhzpqeyphgvzre3oqsz.ygndzp3glhsnojidcddddjddddddabb.ygacsziqpmpqcvdkb2zhu2gjzg\r\n .domain.com\r\npnuctkdw5ntjcbrnxhcqy2txz3gjzo.cftgod2flrzglesnzlcbfqildx9ntdbqgns\r\n .nisgziha3eljwgntmtnhnqrdnuwb2cjgfoch.ldddlddddqddddhdpby.ygacsziqpmpqcvdkb2zhu2gjzg\r\n .domain.com\r\ns2sw3tcn3nc6guihblvwuudfc22wytzdhz.cjyipjnvlqihggnyhn26chizt4jdcksya\r\n .dzbyb6gxnyvgdgdddygdddydjlqd.ygacsziqpmpqcvdkb2zhu2gjzg.domain.com\r\nQuery Responses\r\nhttps://www.kryptoslogic.com/blog/2021/07/adjusting-the-anchor/\r\nPage 6 of 8\n\nThe query responses for each DNS query type have been slightly modified. Before the start of making the 3 types\r\nof DNS queries, the bot tries to resolve the C2 domain to an IP address. This IP address is used as a check by the\r\nbot to confirm if the C2 has received the message. Below is a table on what each response means.\r\nC2 IP Record Response Description\r\n255.255.255.255 Retry, cannot reach\r\n\u003cC2_IP\u003e Message received by C2, send next message part of the query type\r\n239.255.255.255 Sleep and retry\r\nSingle IP For query type 0xfffe , the IP is the identifier\r\nMultiple IPs For query type 0xffff , the IPs form as a structure for the Bot to parse to data\r\nAs with the previous version, the DNS query type 0xffff responds with multiple IP records. These records form\r\na particular structure (that has been reverse engineered before56), whereby the final message is constructed. The\r\nchange seen is that the resulting data built from the IP records is xor encoded. The key to decode the message is\r\nMiguel de Cervantes Saavedra .\r\nConclusion\r\nDespite their simplicity, the changes seen in AnchorDNS are still effective in evading detection. The use of\r\nAnchorAdjuster allows the threat actors to modify the AnchorDNS backdoor in-place, providing a stealthy way to\r\nadd fresh C2s that have been created for new targets. The actors behind AnchorDNS continue to actively develop\r\ntheir toolset, increasing flexibility and raising the barrier for detection.\r\nIOCs\r\nSHA256 Description\r\ncbff159d0b178734248209ae70565d09dddf397ea4e897bf99206ddd74673e6f AnchorDNS 64-bit DLL\r\na8a8c66b155fcf9bfdf34ba0aca98991440c3d34b8a597c3fdebc8da251c9634 AnchorDNS 64-bit DLL\r\n9fdbd76141ec43b6867f091a2dca503edb2a85e4b98a4500611f5fe484109513 AnchorDNS 64-bit DLL\r\nba801f1c2e2c5f5cd961e887cb0776f2d5cee8d17164f29b138a8952dd162165 AnchorDNS 64-bit DLL\r\n0d6a10df6eeb1dbb88b4d625873ed13daa367e165374a72daa16170af3ee31a0 AnchorDNS 64-bit DLL\r\nf93b838dc89e7d3d47b1225c5d4a7b706062fd8a0f380b173c099d0570814348 AnchorAdjuster 64-bit EXE\r\n3ab8a1ee10bd1b720e1c8a8795e78cdc09fec73a6bb91526c0ccd2dc2cfbc28d AnchorAdjuster 64-bit EXE\r\nhttps://www.kryptoslogic.com/blog/2021/07/adjusting-the-anchor/\r\nPage 7 of 8\n\nSHA256 Description\r\nc1ae70683da042792a504847b426a55cdcbca80dca12517f581a4e089a1f8932 AnchorAdjuster 64-bit EXE\r\nC2s\r\nfarfaris[.]com\r\nkalarada[.]com\r\nxyskencevli[.]com\r\nsluaknhbsoe[.]com\r\njetbiokleas[.]com\r\nnyhgloksa[.]com\r\nReferences\r\nSource: https://www.kryptoslogic.com/blog/2021/07/adjusting-the-anchor/\r\nhttps://www.kryptoslogic.com/blog/2021/07/adjusting-the-anchor/\r\nPage 8 of 8",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"references": [
		"https://www.kryptoslogic.com/blog/2021/07/adjusting-the-anchor/"
	],
	"report_names": [
		"adjusting-the-anchor"
	],
	"threat_actors": [
		{
			"id": "f8dddd06-da24-4184-9e24-4c22bdd1cbbf",
			"created_at": "2023-01-06T13:46:38.626906Z",
			"updated_at": "2026-04-10T02:00:03.043681Z",
			"deleted_at": null,
			"main_name": "Tick",
			"aliases": [
				"G0060",
				"Stalker Taurus",
				"PLA Unit 61419",
				"Swirl Typhoon",
				"Nian",
				"BRONZE BUTLER",
				"REDBALDKNIGHT",
				"STALKER PANDA"
			],
			"source_name": "MISPGALAXY:Tick",
			"tools": [],
			"source_id": "MISPGALAXY",
			"reports": null
		},
		{
			"id": "54e55585-1025-49d2-9de8-90fc7a631f45",
			"created_at": "2025-08-07T02:03:24.563488Z",
			"updated_at": "2026-04-10T02:00:03.715427Z",
			"deleted_at": null,
			"main_name": "BRONZE BUTLER",
			"aliases": [
				"CTG-2006 ",
				"Daserf",
				"Stalker Panda ",
				"Swirl Typhoon ",
				"Tick "
			],
			"source_name": "Secureworks:BRONZE BUTLER",
			"tools": [
				"ABK",
				"BBK",
				"Casper",
				"DGet",
				"Daserf",
				"Datper",
				"Ghostdown",
				"Gofarer",
				"MSGet",
				"Mimikatz",
				"Netboy",
				"RarStar",
				"Screen Capture Tool",
				"ShadowPad",
				"ShadowPy",
				"T-SMB",
				"down_new",
				"gsecdump"
			],
			"source_id": "Secureworks",
			"reports": null
		},
		{
			"id": "d4e7cd9a-2290-4f89-a645-85b9a46d004b",
			"created_at": "2022-10-25T16:07:23.419513Z",
			"updated_at": "2026-04-10T02:00:04.591062Z",
			"deleted_at": null,
			"main_name": "Bronze Butler",
			"aliases": [
				"Bronze Butler",
				"CTG-2006",
				"G0060",
				"Operation ENDTRADE",
				"RedBaldNight",
				"Stalker Panda",
				"Stalker Taurus",
				"Swirl Typhoon",
				"TEMP.Tick",
				"Tick"
			],
			"source_name": "ETDA:Bronze Butler",
			"tools": [
				"8.t Dropper",
				"8.t RTF exploit builder",
				"8t_dropper",
				"9002 RAT",
				"AngryRebel",
				"Blogspot",
				"Daserf",
				"Datper",
				"Elirks",
				"Farfli",
				"Gh0st RAT",
				"Ghost RAT",
				"HOMEUNIX",
				"HidraQ",
				"HomamDownloader",
				"Homux",
				"Hydraq",
				"Lilith",
				"Lilith RAT",
				"McRAT",
				"MdmBot",
				"Mimikatz",
				"Minzen",
				"Moudour",
				"Muirim",
				"Mydoor",
				"Nioupale",
				"PCRat",
				"POISONPLUG.SHADOW",
				"Roarur",
				"RoyalRoad",
				"ShadowPad Winnti",
				"ShadowWali",
				"ShadowWalker",
				"SymonLoader",
				"WCE",
				"Wali",
				"Windows Credential Editor",
				"Windows Credentials Editor",
				"XShellGhost",
				"XXMM",
				"gsecdump",
				"rarstar"
			],
			"source_id": "ETDA",
			"reports": null
		}
	],
	"ts_created_at": 1775434638,
	"ts_updated_at": 1775792173,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/2e99d3f12eb1d20fd2aa3f73becc877214de514f.pdf",
		"text": "https://archive.orkl.eu/2e99d3f12eb1d20fd2aa3f73becc877214de514f.txt",
		"img": "https://archive.orkl.eu/2e99d3f12eb1d20fd2aa3f73becc877214de514f.jpg"
	}
}