{
	"id": "15623623-2081-406e-bb88-24e6e257de4f",
	"created_at": "2026-04-10T03:20:32.49603Z",
	"updated_at": "2026-04-10T03:22:17.511063Z",
	"deleted_at": null,
	"sha1_hash": "3024eb2138f1b9413a8c270fbb182c99e68f4248",
	"title": "DECAF Ransomware: A New Golang Threat Makes Its Appearance",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 383603,
	"plain_text": "DECAF Ransomware: A New Golang Threat Makes Its Appearance\r\nBy Hido Cohen \u0026 Michael Dereviashkin\r\nArchived: 2026-04-10 02:32:17 UTC\r\nOverview\r\nThe Go language is becoming increasingly popular among threat actors, with attacks starting to appear in 2019\r\nMorphisec Labs has tracked a new Golang-based (1.17) ransomware variant that appeared starting in late September\r\nand continued development through October \r\nMorphisec recommends organizations update their ransomware prevention strategies to include the risk of Golang-based ransomware \r\nIntroduction\r\nRansomware written in the Go language is quickly becoming more popular among threat actors. These include Babuk, Hive,\r\nand HelloKitty, as well as many other threats written in Golang. “Go” is a statically typed, object-oriented, cross-platform\r\nprogramming language introduced by Google. The abstraction and the support for multiple platforms is an advantage for\r\nmany developers and also a disadvantage for security vendors who attempt to create signatures for malicious executable\r\nmalware, which comes with all the dependent libraries built-in.\r\nMorphisec Labs has identified a new strain of ransomware, implemented in Go 1.17 and named DECAF. The first version,\r\nwhich includes symbols and test assertion, was identified in late September. The attackers very quickly stripped the original\r\nalpha version, added additional functionality, and uploaded this stub version to verify its detection score. Within a week they\r\nhad deployed a fully weaponized version on a customer site.\r\nGolang 1.17 introduces additional complexity to analyze the application flow due to a modification in how\r\nparameters are being passed to functions, this is a great example of how the attackers are becoming extremely agile\r\nin utilizing the latest technology.\r\nThe blog post that follows will cover in great detail the different debug and pre-release versions of the new ransomware\r\nstrain, as well as how the threat actor successfully encrypts their target. \r\nTechnical Introduction \r\nAs has been described in the introduction, we have identified the delivery of the DECAF ransomware on one of our\r\ncustomer’s sites. It is only following a detailed investigation that we successfully found a trail that leads us to a debug\r\nversion of the ransomware, which also included symbols. In the first technical part, we will go into great detail about the\r\nfunctionality of this debug version step by step. In the second part of the blog, we will identify the updates introduced to the\r\npre-release version. We are aware of more updated versions that have been deployed during the last two weeks.\r\nTechnical Analysis\r\nAttack Chain: DECAF Ransomware\r\nFigure 1: The attack chain of the Golang ransomware\r\nSetting Up \r\nThe initialization phase sets up the data required for the ransomware’s malicious activity.\r\nThe malware starts by parsing a command-line argument, –path, which represents the root directory where the ransomware\r\nwill start recursively encrypting files.\r\nimage1-2\r\nFigure 2: Parsing –path parameter\r\nNext, the malware creates an Encryptor object structure:\r\nhttps://blog.morphisec.com/decaf-ransomware-a-new-golang-threat-makes-its-appearance\r\nPage 1 of 7\n\nEncrypted file prefix – each encrypted file header starts with special “magic” prefix, 0xDADFEEDBABEDECAF \r\nDECAF file extension – .decaf \r\nFile extension length \r\nAttacker’s Public key – initialize and parse the embedded PKCS1 public key (see IOCs section)\r\nimage15\r\nFigure 3: Initializing the encrypter with relevant data\r\nMany ransomwares implement file filtering mechanisms for several purposes. Controls to avoid double encrypting the same\r\nfile and avoiding the wrecking of the victim’s operating system for payment.\r\nDECAF is no different and also uses a files filtering mechanism. It ignores: \r\n1. .decaf extension files\r\n2. README.txt files \r\n3. Embedded blacklists of files, folders, and extensions\r\nFor that task, the attacker created a FileUtils class which has a pointer to README.txt string (the name of the ransomware\r\nnotification file) and the relevant functions. One of the functions inside FileUtils is Init(). This function is responsible for\r\nbuilding blacklists for files, folders, and file extensions (the list’s content can be found in the Appendix section).\r\nDECAF Ransomware Building files filters and optional pathsFigure 4: Building files filters and optional paths\r\nThe next step is figuring out which directories the malware should encrypt. It checks if –path has value and if not calls to\r\nFileUtils.ListDriverRootPaths()as shown in the figure above. \r\nLooking inside ListDriverRootPaths, we can see that the malware iterates over the possible drives and searches for drives\r\nwith a type that is NOT a  DRIVE_CDROM.\r\nDECAF Drive bitmask iterationFigure 5: Drive bitmask iteration\r\nDECAF Adding drives excluding DRIVE_CDROM type to the slice\r\nFigure 6: Adding drives excluding DRIVE_CDROM type to the slice\r\nThe last thing that the malware does in this phase is to create a WMI object for future use. We’ll go over its functionality\r\nwhen we show the mechanism used to delete files. \r\nLet’s Encrypt Some Files \r\nThe encryption phase starts by adding the attacker’s email into the ransom note.\r\nDECAF: Creating the formatted ransom note string\r\nFigure 7: Creating the formatted ransom note string\r\nAs you may know, one of the biggest challenges ransomware authors face when developing ransomware is encryption\r\nperformance. The malware needs to encrypt as many files as possible, as fast as possible.\r\nThe author of DECAF chose the multi-goroutine (Go’s thread “equivalent”) method. It creates several encryption goroutines\r\nwhich wait for messages from the main routine. The message contains the file path that it has to encrypt.\r\nCreating communication channel and 4 Go Routines\r\nFigure 8: Creating a communication channel and 4 Go Routines\r\nEach EncWorker waits to receive a new file path to encrypt from the channel. The file paths come from the function\r\nFileUtils.ListFilesToEnc, which enumerates the files of the given directory and applies filtering according to the blacklists,\r\nREADME.txt, and .decaf extension. \r\ndecaf_1\r\nFigure 9: The main goroutine sends file paths after filtering and skipping symlinks\r\ndecaf2\r\nFigure 10: check arg_file_path for symlink\r\nEncryption Worker\r\nmain_EncWorker_func1 is the function responsible for the encryption task. It listens for new file paths, calls the file\r\nencryption function, deletes the original file after it is encrypted, and creates a README.txt file inside each directory.\r\nmain_EncWorker_func1 functionality\r\nFigure 11: main_EncWorker_func1 functionality\r\nOnce the file path has been received, the function calls Encryptor.E for encrypting the file. \r\nhttps://blog.morphisec.com/decaf-ransomware-a-new-golang-threat-makes-its-appearance\r\nPage 2 of 7\n\nThe encryption routine is as follows: \r\nChecks if the file size is smaller than 4GB \r\nDECAF File Size CheckFigure 12: File size check\r\nSets up the cryptographic algorithms\r\nDECAF uses AES-CBC-128  with a randomly generated encryption key and initial vector\r\nEach file is encrypted with a different symmetric encryption key\r\nThe file’s encryption key is encrypted using the attacker’s public key\r\nimage20Figure 13: Encryption key and IV\r\nciphertext, err := EncryptOAEP(sha256.New(), aes_key, public_key, G_Reader,0x10)\r\nThe next thing is to open the source (original file) and target (encrypted file) files. The malware opens the original file\r\nwith OF_READWRITE permission and creates a new target file with .decaf extension.\r\nDECAF Open original and target files\r\nFigure 14: Open original and target files\r\nThe attacker needs to be able to decrypt all files in case someone pays the demanded ransom to maintain its credibility. To\r\ndo that, the attacker creates a special header for each file that contains the relevant data for decryption. \r\nEncrypted file format: \r\n{\r\nFilePrefix// Encrypted files identifier\r\nFileSize// Reconstrcut the real file size after it has encryptedCBC_IV// Shared between encryption and\r\ndecryption\r\nEncrypyedKeyLength\r\nEncryptedKey// Required for decrypting the enc_key using the attacker's private key\r\nEncrypyedData\r\n}\r\n\u003ccode: go\u003e\r\nDECAF Encrypted file format\r\nFigure 15: Encrypted file format\r\nThe file content is divided into chunks, where each chunk is 0x10 bytes. We wrote simple pseudocode which represents the\r\ncontent encryption’s logic: \r\n1. Read 0x10 bytes from the original file \r\n2. If it’s EOF, end. \r\n3. If less than 0x10 bytes read, add random padding and create 0x10 bytes block \r\n4. Encrypt the data\r\n5. Write the encrypted data to the target file\r\nfuncEncryptFileContent()\r\n// ...\r\n// More initialization explained above\r\nsymmetricKey := rand.Reader.Read(0x10)\r\ninitialVector := rand.Reader.Read(0x10)\r\nhFile := os.OpenFile(\"\u003cfile_path\u003e\", O_RDWR,0)\r\nhTargetFile := os.OpenFile(\"\u003cfile_path\u003e.decaf\", o_RDWR | O_CREATE | O_TRUNC,0x1B6)\r\nfileReader := bufio.NewReader(hFile)\r\nfileWriter := bufio.NewWriter(hFile)\r\nplaintext :=make([]byte,0x10)\r\nciphertext :=make([]byte,0x10)\r\n// Read until there's nothing to read\r\n_, err := io.ReadAtLeast(fileReader, plaintext,0x10)\r\nwhile err != io.EOF {\r\niferr == io.ErrUnexpectedEOF {\r\n// Add random padding\r\nhttps://blog.morphisec.com/decaf-ransomware-a-new-golang-threat-makes-its-appearance\r\nPage 3 of 7\n\npadLen := aes.BlockSize -\r\nlen(inBytes)%aes.BlockSizepadding :=make([]byte, padLen)\r\n_, err = rand.Reader.Read(padding)\r\npadding[0] =byte(padLen)\r\nplaintext =append(padding, plaintext...)\r\nplaintextLen :=len(plaintext)\r\n}\r\nblock, err := aes.NewCipher(symmetricKey)\r\ncfb := cipher.NewCBCEncrypter(block, initialVector)\r\ncfb.CryptBlocks(ciphertext[aes.BlockSize:], plaintext) \r\nfileWriter.Write(ciphertext)\r\n}\r\n}\r\nWe can assume that the author chose to divide the data into such small chunks as a way to evade detection by Anti-Ransomware solutions that monitor for large data chunk encryptions.\r\nOriginal File Wiping\r\nOnce the ransomware has created the encrypted file it needs to delete the original file and eliminate the target’s ability to\r\nrecover the file. \r\nFirst, the malware deletes the file using the WMI object created in the initialization phase. We’ve reconstructed the\r\nmalware’s WMI usage in the following pseudocode: \r\n1. The malware connects to the local WMI’s ROOT\\\\CIMV2 namespace for executing commands \r\n2. Once the file is encrypted, the malware queries for the CIM_DataFile object according to the file’s path \r\n3. It counts the results and iterates over the items \r\n4. For each item, it invokes the Delete function\r\nfuncDeleteFileUsingWMI() {\r\nole.CoInitialize(0)\r\nunknown, _ := oleutil.CreateObject(\"WbemScripting.SWbemLocator\")wmi, _ :=\r\nunknown.QueryInterface(ole.IID_IDispatch)\r\nserviceRaw, _ := oleutil.CallMethod(wmi,\"ConnectServer\")service := serviceRaw.ToIDispatch()\r\n// ...\r\n// File encryption\r\n// ...\r\n// result is a SWBemObjectSet\r\nresultRaw, _ := oleutil.CallMethod(service,\"ExecQuery\", \"SELECT * FROM CIM_DataFile where name=\"\r\n\u003cfile_path\u003e\"\")\r\nresult := resultRaw.ToIDispatch()\r\ncountVar, _ := oleutil.GetProperty(result,\"Count\")\r\ncount :=int(countVar.Val)\r\nfori :=0; i \u003c count; i++ {\r\n// Each item is CIM_DataFile objectitemRaw, _ := oleutil.CallMethod(result,\"ItemIndex\", i)item :=\r\nitemRaw.ToIDispatch()\r\noleutil.CallMethod(item,\"Delete\")\r\n}\r\n}\r\nNow the last thing left is to remove the recovery ability on the infected system. For that, DECAF utilizes cipher.exe,\r\nsimilarly to other ransomware (e.g., LockerGoga and MegaCortex). \r\nDECAF iterates over the directories it needs to encrypt and calls cipher.exe with a /w:\u003cdirectory_path\u003e. This option\r\noverwrites (“wipes”) deleted data and, as a result, eliminates the ability to recover the file.\r\nDECAF Wiping delete data inside the directory\r\nFigure 16: Wiping delete data inside the directory\r\nDebug VS Pre-Release\r\nThe difference between the two versions of the same ransomware is that the pre-release variant is stripped of symbols,\r\nstrings and function names are obfuscated.\r\nhttps://blog.morphisec.com/decaf-ransomware-a-new-golang-threat-makes-its-appearance\r\nPage 4 of 7\n\nWe assumed that the second version is a Pre-Released version due to the Protonmail used in the ransom note, which is filled\r\nwith a placeholder instead of a real email address.\r\nimage19\r\nFigure 17: Email address in the ransom note of the Pre-Release version\r\nComparison\r\nGo Version\r\nLet’s take a look at the code from runtime.schedinit that contains the variable buildVersion. This variable points to the\r\nGolang version that has been used, at least in the case that the symbols are present and not stripped.\r\nDECAF Go version comparisonFigure 18: Go version comparison\r\nIt’s worth mentioning that Go 1.17 implements a new way of passing function arguments and results using registers instead\r\nof the stack. Because of this, reverse engineering Golang could become messy for newcomers. \r\nhttps://golang.org/doc/go1.17#compiler\r\nPublic Key\r\nDECAF Public key comparisonFigure 19: Public key comparison\r\nStrings Obfuscation\r\nThe ransomware uses string obfuscation in its Pre-Release version. Strings are being de-obfuscated on runtime while\r\nutilizing different custom de-obfuscation functions. \r\nFor example, the initialization of the `Encryptor` object’s decaf extension attribute:\r\nDECAF deobfuscation\r\nFigure 20: .decaf extension deobfuscation\r\nAnother example could be seen while deleting the original file. The WMI query used in the Debug version was embedded\r\ninto the binary while in the Pre-Release version it was stored encrypted. Before calling the delete function, the malware\r\nexecutes the decryption function and reveals the real WMI query, as we saw in the Debug version.\r\nDECAF WMI query resolving\r\nFigure 21: WMI query resolving\r\nConclusion\r\nThe development of DECAF continues to this day, showing that ransomware groups constantly innovate their attacks. That\r\nthe attack is written in Golang is further proof of this trend toward innovation among the adversary community; threat actors\r\nare forever making changes and adding new capabilities to evade the detection-centric solutions that predominate in the\r\nmarket. As such, ransomware protection remains a weak spot for many organizations, \r\nCompanies need to adopt prevention-first strategies, such as the ones Morphisec provides, to ensure that they stand a chance\r\nat protecting their critical systems from further attacks. Morphisec Labs will continue to track the development of the\r\nDECAF ransomware and report any further developments that we uncover. \r\nIOCs\r\nDebug Version Public Key\r\n-----BEGINRSA PUBLIC KEY-----\r\nMIIBCgKCAQEAv+D8WLstRCGExBNfcsd8iYvvBajk1wxLbHgteWQCtXWqr7VDaBD8\r\nSEVez9LQVDvUNdHmRK+8n/JtkJ2vuPwBfb8IxZJ7sXsk/Zt1eoE7tZYUtKTZwazl\r\n1zNbTR8Ocftkj3LW57atj+nTEUues7RkauWkXAlJckGXON4LXTI63QFleOmF0+C+\r\nxoRkw3MibdQhePLZFm9eczZAmYqU875iBAQ5krsmvG10FU+2VVKmwAXfD9EUiuQ0\r\nhttps://blog.morphisec.com/decaf-ransomware-a-new-golang-threat-makes-its-appearance\r\nPage 5 of 7\n\nZQPwayA0ubYuMmayj6SE7OlQzYuPQJzj6vYjMOnalCoe3yEu6Km35moYDcBN9p9f v36lPX2Mlq20tYiuGKcGSMeT7y/fmO9joQIDAQAB\r\n-----ENDRSA PUBLIC KEY-----\r\nPre-Release Version Public Key\r\n-----BEGINRSA PUBLIC KEY-----\r\nMIIBCgKCAQEAq4k1Hdb1THrzBBeO184knCbBKr03apfXqlOkSdtHSJgfyIqJPGxl/cFisJmVXR3/t4e9FbLsEIuTp9PJTciomHfr5CgCQzhnAZ0AvjGBaWP6KpCyfDnsybruyKqyg\r\n----ENDRSA PUBLIC KEY-----\r\nHashes\r\nPre-release\r\n5da2a2ebe9959e6ac21683a8950055309eb34544962c02ed564e0deaf83c9477 \r\nDebug\r\n98272cada9caf84c31d70fdc3705e95ef73cb4a5c507e2cf3caee1893a7a6f63\r\nAppendix\r\nFiles blacklist\r\nbootfont.bin\r\nboot.ini\r\nntuser.dat\r\ndesktop.ini\r\niconcache.db\r\nntldr\r\nntuser.dat.log\r\nthumbs.db\r\nbootsect.bak\r\nntuser.ini\r\nautorun.inf\r\nbootnxt\r\nbootmgr\r\nDirectories blacklist\r\nintel\r\nprogram files (x86)\r\nprogram files\r\nmsocache\r\n$recycle.bin\r\n$windows.~ws\r\ntor browser\r\nboot\r\nsystemvolume information\r\nperflogs\r\ngoogle\r\napplication data\r\nwindows\r\nprogramdata\r\nwindows.old\r\nappdata\r\nmozilla\r\nExtensions blacklist\r\n.themepack.shs     .prf\r\n.ldf  .drv     .dll\r\n.scr  .wpx     .nomedia\r\n.icl  .deskthemepack.idx\r\n.386  .bat     .tmp\r\n.cmd  .rom     .pdb\r\n.ani  .msc     .lib\r\n.adv  .lnk     .class\r\nhttps://blog.morphisec.com/decaf-ransomware-a-new-golang-threat-makes-its-appearance\r\nPage 6 of 7\n\n.theme\r\n.cab\r\n.msi.spl\r\n.rtp  .ps1\r\n.diagcfg.msu\r\n.msstyles.ics\r\n.bin  .key\r\n.hlp   .msp\r\nAbout the author\r\nHido Cohen\r\nMichael Dereviashkin\r\nSource: https://blog.morphisec.com/decaf-ransomware-a-new-golang-threat-makes-its-appearance\r\nhttps://blog.morphisec.com/decaf-ransomware-a-new-golang-threat-makes-its-appearance\r\nPage 7 of 7",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"references": [
		"https://blog.morphisec.com/decaf-ransomware-a-new-golang-threat-makes-its-appearance"
	],
	"report_names": [
		"decaf-ransomware-a-new-golang-threat-makes-its-appearance"
	],
	"threat_actors": [],
	"ts_created_at": 1775791232,
	"ts_updated_at": 1775791337,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/3024eb2138f1b9413a8c270fbb182c99e68f4248.pdf",
		"text": "https://archive.orkl.eu/3024eb2138f1b9413a8c270fbb182c99e68f4248.txt",
		"img": "https://archive.orkl.eu/3024eb2138f1b9413a8c270fbb182c99e68f4248.jpg"
	}
}