{
	"id": "67d4514a-4d0c-4646-85c8-6550365a8397",
	"created_at": "2026-05-07T02:42:54.86764Z",
	"updated_at": "2026-05-07T02:44:10.955508Z",
	"deleted_at": null,
	"sha1_hash": "923dee492c30d01fa3111a18ba7a1e6bc521ae79",
	"title": "ArechClient; Decoding IOCs and finding the onboard browser extension",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 232099,
	"plain_text": "ArechClient; Decoding IOCs and finding the onboard browser\r\nextension\r\nBy Jason Reaves\r\nPublished: 2025-03-13 · Archived: 2026-05-07 02:19:36 UTC\r\n4 min read\r\nMar 13, 2025\r\nBy: Jason Reaves\r\nFound myself analyzing ArechClient recently and needed a way to automatically decode out the C2 info from lots\r\nof samples. By the end of our work we also discovered that the browser extension being delivered by ArechClient\r\nis on board the client itself.\r\nThe sample I started with:\r\n96ba74cc27b44547d23fe1fa550fc59b4f340dbbca8472d9b4698576751bb189\r\nA very good technical writeup on ArechClient was done back in 2023 by dr4k0nia[1,2]. Using that information I\r\nwas able to quickly find the function responsible for decoding strings:\r\n internal static string c(int num, int num2, int num3)\r\n {\r\n num += 593;\r\n Assembly executingAssembly = Assembly.GetExecutingAssembly();\r\n num2 -= 331;\r\n Stream manifestResourceStream = executingAssembly.GetManifestResourceStream(\"resource\r\n int num4 = num ^ num2;\r\n num4 = num4 * 17 / 27;\r\n manifestResourceStream.Seek((long)(7 + num4), SeekOrigin.Begin);\r\n byte[] array = new byte[8];\r\n manifestResourceStream.Read(array, 0, 4);\r\n int num5 = (BitConverter.ToInt32(array, 0) ^ 2100157544) - 100;\r\n manifestResourceStream.Read(array, 0, 4);\r\n int num6 = BitConverter.ToInt32(array, 0) - 5 ^ 485648943;\r\n manifestResourceStream.Seek((long)num5, SeekOrigin.Begin);\r\n array = new byte[num6];\r\n manifestResourceStream.Read(array, 0, num6);\r\nhttps://medium.com/walmartglobaltech/arechclient-decoding-iocs-and-finding-the-onboard-browser-extension-477f8796568d\r\nPage 1 of 8\n\nfor (int i = 0; i \u003c array.Length; i++)\r\n {\r\n array[i] = (byte)((int)array[i] ^ num3);\r\n }\r\n return Encoding.UTF8.GetString(array);\r\n }\r\nA single byte XOR, and the offset and key are passed as parameters. Using different keys for various strings\r\nmakes it a bit annoying for automating but makes no difference in detection using YARA:\r\nrule archeclient\r\n{\r\n strings:\r\n $a1 = \"https://pastebin.com/raw/\" xor\r\n $a2 = \"CatalinaGroup\" xor\r\n $a3 = \"Cookies\" xor\r\n condition:\r\n all of them\r\n}\r\nWhile I let that run gathering up more samples, let’s look at writing a decoder.\r\nSo the decoding method means if we want to stay static then we’ll either need to delve into decompiling every\r\nbinary or look at bruting, decompiling them would require a bit much for my framework so I stick to the bruting\r\nrealm using a regex for the IP and a quick shortcut check for pastebin for the URL:\r\nimport re\r\nimport sys\r\ndata = open(sys.argv[1], 'rb').read()\r\nips = []\r\nfor i in range(255):\r\n temp = bytearray(data)\r\n for j in range(len(temp)):\r\n temp[j] ^= i\r\n t = re.findall(b'''[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}''', temp)\r\n ips += t\r\n if b'pastebin' in temp:\r\n \r\n tt = re.findall(b'''https?://[\\x20-\\x7e]+''', temp)\r\n ips += tt\r\nprint(ips)\r\nhttps://medium.com/walmartglobaltech/arechclient-decoding-iocs-and-finding-the-onboard-browser-extension-477f8796568d\r\nPage 2 of 8\n\nThis works but is very slow because we are bruting files that are just under 1mb in size, speeding this up for\r\nfinding pastebin atleast we can utilize YARA in python:\r\nrule_source = '''\r\nrule archeclient\r\n{\r\n strings:\r\n $a1 = \"https://pastebin.com/raw/\" xor\r\n $a2 = \"CatalinaGroup\" xor\r\n $a3 = \"Cookies\" xor\r\n condition:\r\n all of them\r\n}\r\n'''\r\ndef yara_scan(raw_data, rule_name):\r\n xor_keys = []\r\n yara_rules = yara.compile(source=rule_source)\r\n matches = yara_rules.match(data=raw_data)\r\n for match in matches:\r\n if match.rule == 'archeclient':\r\n for item in match.strings:\r\n if item.identifier == rule_name and len(item.instances) \u003e 0:\r\n xor_keys.append((item.instances[0].xor_key, item.instances[0].offset))\r\n return xor_keys\r\nThe code above will allow us to recover the the offset and xor key for the pastebin URL much easier, this doesn’t\r\nhelp with finding IP addresses though. Since most of the strings are all stored in a giant blob we can use the offset\r\nto narrow the scope for bruting the IPs:\r\ndata = open(sys.argv[1], 'rb').read()\r\ntet = yara_scan(data, '$a1')\r\nif len(tet) \u003e 0:\r\n ips = []\r\n rough_off = tet[0][1]\r\n newdata = data[rough_off-10000:rough_off+10000]\r\n pb_xor_key = tet[0][0]\r\n temp = bytearray(newdata)\r\n for i in range(len(temp)):\r\n temp[i] ^= pb_xor_key\r\n tt = re.findall(b'''https?://pastebin.com/raw/[\\x20-\\x7e]{8}''', temp)\r\n ips += tt\r\n \r\n for i in range(255):\r\n temp = bytearray(newdata)\r\n for j in range(len(temp)):\r\nhttps://medium.com/walmartglobaltech/arechclient-decoding-iocs-and-finding-the-onboard-browser-extension-477f8796568d\r\nPage 3 of 8\n\ntemp[j] ^= i\r\n t = re.findall(b'''[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}''', temp)\r\n ips += t\r\n print(ips)\r\nDecoded IOCs for ArechClient samples can be found at the bottom.\r\nGet Jason Reaves’s stories in your inbox\r\nJoin Medium for free to get updates from this writer.\r\nRemember me for faster sign in\r\nA previous blog detailed that ArechClient was being leveraged for delivering a browser extension[3], looking at\r\nthe sandbox report for our sample it appears the same thing is happening.\r\nPress enter or click to view image in full size\r\nSince the C2 resides in the content.js we can enumerate samples on VirusTotal:\r\ncontent:{7370796a735f726566726573684576656e747328636c69656e74496429}\r\nTaking the first 48 samples found and writing a quick one-liner to rip out the C2s:\r\ngrep \"server =\" * |awk -F'\"' '{print $2}' |awk -F'/' '{print $3}' |sort |uniq -c\r\nhttps://medium.com/walmartglobaltech/arechclient-decoding-iocs-and-finding-the-onboard-browser-extension-477f8796568d\r\nPage 4 of 8\n\nHowever while looking at the pcap for this sample I noticed something strange, for one there was not enough\r\ntraffic before the extension traffic started to justify downloading the extension from the C2. After checking in the\r\nsame section of the ArechClient binary we were able to see that it is actually onboard and decoded in the same\r\nway as the C2 info earlier but still needs to be base64 decoded:\r\nCmFzeW5jIGZ1bmN0aW9uIGh0dHBHZXQodGhlVXJsKQp7CiAgICBsZXQgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCh0aGVVcmwpOwogI\r\newoJIm1hbmlmZXN0X3ZlcnNpb24iOiAyLAoKCSJuYW1lIjogIkdvb2dsZSBEb2NzIiwKCSAgICJkZXNjcmlwdGlvbiI6ICJFZGl0L\r\ndmFyIHNlcnZlciA9ICJodHRwOi8vXl5eXl4mJiYmJioqKioqKiYmJl5eXiUlJV5eXiZeJV4mJV4mJiZeJiomXiZeJl4mXio6OTAwM\r\nSnippet from base64 decoded content.js:\r\nvar server = \"http://^^^^^\u0026\u0026\u0026\u0026\u0026******\u0026\u0026\u0026^^^%%%^^^\u0026^%^\u0026%^\u0026\u0026\u0026^\u0026*\u0026^\u0026^\u0026^\u0026^*:9000/\";\r\nvar iddd = '$%^\u0026#^\u0026@#@\u0026#@\u0026#\u0026*\u0026*\u0026*^#*@\u0026#*\u0026@#*@\u0026#*#\u0026*@#';\r\nvar debug = 1;\r\nvar currLoc = \"\";\r\n(async function () {\r\n var clientId = iddd;\r\n urlChangeAllert();\r\n spyjs_refreshEvents(clientId);\r\n})()\r\nfunction urlChangeAllert(){\r\nIOCs\r\nPastebin URLs:\r\nhttps://pastebin.com/raw/DWCCqGB0\r\nhttps://pastebin.com/raw/ENEhYpTW\r\nhttps://pastebin.com/raw/Ld9GfkdJ\r\nhttps://pastebin.com/raw/NH3NwEpf\r\nhttps://pastebin.com/raw/UPxYyFp8\r\nhttps://pastebin.com/raw/cLika3dt\r\nhttps://pastebin.com/raw/eB8bmiVA\r\nhttps://pastebin.com/raw/eKZZkcvz\r\nhttps://pastebin.com/raw/gxDS2LkW\r\nhttps://pastebin.com/raw/hN7U6xHt\r\nhttps://pastebin.com/raw/nJqnXW3u\r\nhttps://pastebin.com/raw/ravLcZ9f\r\nhttps://medium.com/walmartglobaltech/arechclient-decoding-iocs-and-finding-the-onboard-browser-extension-477f8796568d\r\nPage 5 of 8\n\nhttps://pastebin.com/raw/ubFNTPjt\r\nhttps://pastebin.com/raw/wikwTRQc\r\nhttps://pastebin.com/raw/yZ0ektdh\r\nPastebin C2s:\r\n92.255.57.31\r\n92.255.57.32\r\n144.76.103.92\r\n92.255.85.23\r\n109.120.186.139\r\n45.141.84.208\r\n185.147.124.181\r\n92.255.57.75\r\n45.118.248.29\r\n85.209.11.243\r\n194.26.135.180\r\n91.202.233.18\r\n80.64.30.2\r\nIPs from binaries:\r\n109.120.186.139\r\n185.147.124.179\r\n185.147.124.181\r\n194.26.135.180\r\n213.109.202.229\r\n45.118.248.29\r\n45.141.84.168\r\n45.141.84.208\r\n45.141.87.124\r\n45.141.87.50\r\n62.84.98.67\r\n80.64.30.2\r\n81.19.135.11\r\n91.202.233.18\r\n92.255.57.31\r\n92.255.57.32\r\n92.255.57.75\r\n92.255.85.23\r\n92.255.85.36\r\nBrowser Extension package on VT:\r\nhttps://medium.com/walmartglobaltech/arechclient-decoding-iocs-and-finding-the-onboard-browser-extension-477f8796568d\r\nPage 6 of 8\n\n7b9cc025a1bc19552ec3a69872ddc9dbf1233ab779f081aaf75b902435f6477e\r\nBrowser Extension C2s:\r\n109.107.182.209:9000\r\n109.234.34.3:9000\r\n144.76.163.55:9000\r\n152.89.198.51:9000\r\n176.9.66.115:9000\r\n178.63.51.126:9000\r\n185.147.124.181:9000\r\n185.42.12.247:9000\r\n185.42.12.64:9000\r\n185.42.12.85:9000\r\n185.73.125.96:9000\r\n213.109.202.15:9000\r\n34.141.167.33:9000\r\n34.89.247.212:9000\r\n45.118.248.29:9000\r\n45.141.84.208:9000\r\n45.141.87.124:9000\r\n45.141.87.215:9000\r\n45.141.87.55:9000\r\n45.88.104.78:9000\r\n45.92.179.249:9000\r\n5.42.67.10:9000\r\n77.246.107.149:9000\r\n80.64.30.2:9000\r\n81.19.135.11:9000\r\n91.202.233.18:9000\r\n91.215.85.23:9000\r\n91.215.85.66:9000\r\n91.240.118.154:9000\r\n92.255.57.31:9000\r\n92.255.57.75:9000\r\n92.255.85.23:9000\r\n95.216.24.238:9000\r\nYARA:\r\nrule archeclient\r\n{\r\n strings:\r\n $a1 = \"https://pastebin.com/raw/\" xor\r\n $a2 = \"CatalinaGroup\" xor\r\nhttps://medium.com/walmartglobaltech/arechclient-decoding-iocs-and-finding-the-onboard-browser-extension-477f8796568d\r\nPage 7 of 8\n\n$a3 = \"Cookies\" xor\r\n condition:\r\n all of them\r\n}\r\nrule spyjs_extension\r\n{\r\nstrings:\r\n$a1 = \"spyjs_saveData\"\r\n$a2 = \"spyjs_refreshEvents\"\r\ncondition:\r\nall of them\r\n}\r\nReferences\r\n1: https://dr4k0nia.github.io/posts/Analysing-a-sample-of-ArechClient2/\r\n2: https://www.sentinelone.com/blog/reverse-engineering-walkthrough-analyzing-a-sample-of-arechclient2/\r\n3: https://malwr-analysis.com/2025/02/18/arechclient2-malware-analysis-sectoprat/\r\nSource: https://medium.com/walmartglobaltech/arechclient-decoding-iocs-and-finding-the-onboard-browser-extension-477f8796568d\r\nhttps://medium.com/walmartglobaltech/arechclient-decoding-iocs-and-finding-the-onboard-browser-extension-477f8796568d\r\nPage 8 of 8",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"origins": [
		"web"
	],
	"references": [
		"https://medium.com/walmartglobaltech/arechclient-decoding-iocs-and-finding-the-onboard-browser-extension-477f8796568d"
	],
	"report_names": [
		"arechclient-decoding-iocs-and-finding-the-onboard-browser-extension-477f8796568d"
	],
	"threat_actors": [],
	"ts_created_at": 1778121774,
	"ts_updated_at": 1778121850,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/923dee492c30d01fa3111a18ba7a1e6bc521ae79.pdf",
		"text": "https://archive.orkl.eu/923dee492c30d01fa3111a18ba7a1e6bc521ae79.txt",
		"img": "https://archive.orkl.eu/923dee492c30d01fa3111a18ba7a1e6bc521ae79.jpg"
	}
}