{
	"id": "1e461092-f9af-4a69-a29f-1768b4780fd5",
	"created_at": "2026-04-06T00:16:41.326129Z",
	"updated_at": "2026-04-10T03:20:16.829651Z",
	"deleted_at": null,
	"sha1_hash": "3baaa06b08083a7d0ce9fe16483d6c508e42faa6",
	"title": "Automating Pikabot’s String Deobfuscation | ThreatLabz",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 308142,
	"plain_text": "Automating Pikabot’s String Deobfuscation | ThreatLabz\r\nBy Nikolaos Pantazopoulos\r\nPublished: 2024-04-08 · Archived: 2026-04-02 10:47:52 UTC\r\nTechnical Analysis\r\nStrings obfuscation\r\nThe steps for decrypting a Pikabot string are relatively simple. Each string is decrypted only when required (in\r\nother words, Pikabot does not decrypt all strings at once). Pikabot follows the steps below to decrypt a string:\r\n1. Pushes on the stack the encrypted string array.\r\n2. Initializes the RC4 encryption algorithm. The RC4 key is different for each string (with very few\r\nexceptions).\r\n3. Pikabot takes the decrypted RC4 output, decodes it using Base64 after replacing all instances of the\r\ncharacter ‘ _ ’ (underscore) with ‘ = ’ (equal) and decrypts it using the AES-CBC algorithm. The AES key\r\nand initialization vector (IV) are the same for all strings.\r\nANALYST NOTE: There are encrypted strings, which are encrypted only with the RC4 algorithm.\r\nFigure 1 shows the code used to decrypt the string, Kernel32.dll . \r\nhttps://www.zscaler.com/blogs/security-research/automating-pikabot-s-string-deobfuscation\r\nPage 1 of 5\n\nFigure 1: Example Pikabot string decryption for Kernel32.dll .\r\nFigure 2 shows the function that first decrypts the AES key and IV. The RC4 decrypted string passed to the\r\nfunction is then Base64 decoded, and is finally decrypted using AES.\r\nhttps://www.zscaler.com/blogs/security-research/automating-pikabot-s-string-deobfuscation\r\nPage 2 of 5\n\nFigure 2: Pikabot Base64 decoding and AES decryption function.\r\nDecrypting Pikabot strings\r\nThe following information is required to decrypt a Pikabot string:\r\nThe AES key and IV of a binary sample.\r\nhttps://www.zscaler.com/blogs/security-research/automating-pikabot-s-string-deobfuscation\r\nPage 3 of 5\n\nThe RC4 encrypted array of each string.\r\nThe RC4 key of each encrypted string.\r\nThe string’s size.\r\nOur approach relies on IDA’s microcode. This decision helped us with several problems such as:\r\nIDA’s microcode converts the assignment/copy of the RC4 key into a strcpy function. In the assembly\r\nlevel, this could either be multiple mov or rep instructions. As a result, it would make the detection and\r\nextraction harder and more challenging.\r\nExtracting the RC4 encrypted array. Since IDA reconstructs the stack, it makes it much easier to search and\r\nextract the encrypted array.\r\nIDA’s microcode brings other limitations (for example, decompilation failure for a function) but no such issues\r\nwere encountered for the parts of the code we wanted to analyze.\r\nIn the sections below, we describe how each component was extracted.\r\nExtracting the AES key/IV\r\nFor the extraction of the AES key and IV, we iterate all analyzed functions and discard any function, whose size is\r\nnot in the range of 600 and 1,600 bytes.\r\nNext, we scan the functions for the following patterns:\r\nExistence of RC4 encryption. This is the same heuristic we use for detecting encrypted RC4 strings.\r\nExistence of values 0x3D and 0x5F (used before Base64 decoding the string) that are used with microcode\r\nopcodes m_stx and m_jnz respectively.\r\nLastly, if all of the patterns above match, then the handler for decrypting a Pikabot string is invoked. For the\r\nclassification of the key and the IV, we apply the following checks:\r\nThe number of decrypted strings from the identified function must be two. Otherwise, the identified\r\nfunction is incorrect.\r\nThe longest string is marked as the AES key (by taking the first 32-bytes) and the remaining decrypted\r\nstring as the IV (by taking the first 16-bytes).\r\nExtracting the RC4 encrypted array\r\nPikabot constructs the RC4 encrypted array by pushing it onto the stack and then decrypting it. Our approach\r\ninvolves the following steps for detecting each part of the array:\r\nUse the detected RC4 encryption block address as a starting point.\r\nSearch for the microcode opcode m_add in the decryption instruction. The detected microcode holds the\r\nstarting stack offset of the encrypted array.\r\nStart iterating backwards and search for the microcode opcodes m_mov/m_call , the second opcode is used\r\nin case the data is copied via a strcpy or memcpy instruction. If the stack offset matches, then we save\r\nhttps://www.zscaler.com/blogs/security-research/automating-pikabot-s-string-deobfuscation\r\nPage 4 of 5\n\nthe data and update the stack offset. This process is repeated until the reconstructed encrypted array has the\r\nexpected size.\r\nExtracting the RC4 encrypted array size\r\nThe length of the encrypted array is extracted in a similar way as the encrypted array. The detection pattern is:\r\nUse the detected RC4 encryption block address as a starting point.\r\nSearch for the microcode opcodes m_jb , m_jae , and m_setb , and use the immediate constant number\r\nin the instruction as a size.\r\nExtracting the RC4 key\r\nExtracting the RC4 key of each string proved to be the most challenging part while creating the plugin. In our first\r\nattempt, we were extracting the RC4 key after detecting the initialization of the RC4 algorithm. However, this\r\napproach had the following issues:\r\nIncorrect extraction of the RC4 key: In many cases, an invalid/junk string was placed in-between the\r\ncorrect RC4 key and the RC4 algorithm initialization.\r\nIncorrect detection of RC4 initialization code block: For example, if the size of the encrypted array was\r\n256 bytes then an incorrect RC4 key would be detected.\r\nInstead of trying to detect the RC4 key by detecting the initialization of the RC4 algorithm, we decided to extract\r\nall strings from each targeted function. Then, we decrypted the RC4 encrypted array with each extracted RC4 key\r\nand validated the decrypted output by applying the following checks:\r\nIf it matches the expected string size.\r\nIf all characters of the string are readable.\r\nANALYST NOTE: After successful decryption, the RC4 key is marked and not reused in order to limit any false-positives. For example, if the decrypted string does not have any junk characters.\r\n \r\nExplore more Zscaler blogs\r\nSource: https://www.zscaler.com/blogs/security-research/automating-pikabot-s-string-deobfuscation\r\nhttps://www.zscaler.com/blogs/security-research/automating-pikabot-s-string-deobfuscation\r\nPage 5 of 5",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"references": [
		"https://www.zscaler.com/blogs/security-research/automating-pikabot-s-string-deobfuscation"
	],
	"report_names": [
		"automating-pikabot-s-string-deobfuscation"
	],
	"threat_actors": [],
	"ts_created_at": 1775434601,
	"ts_updated_at": 1775791216,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/3baaa06b08083a7d0ce9fe16483d6c508e42faa6.pdf",
		"text": "https://archive.orkl.eu/3baaa06b08083a7d0ce9fe16483d6c508e42faa6.txt",
		"img": "https://archive.orkl.eu/3baaa06b08083a7d0ce9fe16483d6c508e42faa6.jpg"
	}
}