{
	"id": "5bbd6bfc-581e-4626-baf7-0c2fa398bbac",
	"created_at": "2026-04-06T00:11:27.213057Z",
	"updated_at": "2026-04-10T13:11:34.407754Z",
	"deleted_at": null,
	"sha1_hash": "6757fecbaa765511ca8a869f654ef23504c649ae",
	"title": "Emansrepo Infostealer - PyInstaller, Deobfuscation and LLM",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 1691964,
	"plain_text": "Emansrepo Infostealer - PyInstaller, Deobfuscation and LLM\r\nArchived: 2026-04-05 18:49:28 UTC\r\nSHA256: ae2a5a02d0ef173b1d38a26c5a88b796f4ee2e8f36ee00931c468cd496fb2b5a\r\nTable of Contents\r\nIntroduction\r\nExtracting the Python Code\r\nPyInstaller Detection\r\nExtracting the Compiled Python Script\r\nDecompile into Python Script\r\nDeobfuscating the Python Code\r\nDeobfuscating the First Stage\r\nDeobfuscating the Second Stage\r\nThe Third and Final Stage\r\nEmansrepo and LLM\r\nSummary\r\nIntroduction\r\nEmansrepo is a Python-based information stealer reported by Fortinet last month. The variant we will examine in\r\nthis blog is packaged with PyInstaller, enabling it to run on a computer without requiring Python to be installed.\r\nThe primary focus of this blog is to extract the Python script from the PyInstaller-based sample and then\r\ndeobfuscate it to reveal the actual malware code. Finally, I will offer some hypotheses linking Emansrepo to\r\nLLMs.\r\nPyInstaller Detection\r\nThe introduction to PyInstaller is best given from their documentation:\r\nPyInstaller bundles a Python application and all its dependencies into a single package. The user can\r\nrun the packaged app without installing a Python interpreter or any modules. It is not a cross-compiler;\r\nto make a Windows app you run PyInstaller on Windows, and to make a Linux app you run it on Linux,\r\netc.\r\nhttps://nikhilh-20.github.io/blog/emansrepo_deobfuscation/\r\nPage 1 of 9\n\nSince PyInstaller-based packages are self-contained, the file size is expected to be larger than that of typical\r\nC/C++-based malware. This is evident in the VirusTotal detections snapshot at the beginning of this blog, with the\r\nsample size being ~22 MB.\r\nDetect It Easy can identify a PyInstaller-based package. Additionally, by examining the printable strings (such as\r\n_MEIPASS ), you can determine not only that the package is PyInstaller-based but also the Python version used, as\r\nshown in Fig. 1. The sample uses Python 3.11.\r\nFig. 1: PyInstaller and Python Version Detection\r\nPyInstaller bundles compiled Python scripts instead of source code. In the following sections, we will examine\r\nhow to go from a PyInstaller executable to Python source code.\r\npyinstxtractor-ng can be used to extract the compiled Python scripts from the PyInstaller-based sample.\r\n.\\pyinstxtractor-ng.exe.lnk C:\\Users\\Ashura\\Desktop\\ae2a5a02d0ef173b1d38a26c5a88b796f4ee2e8f36ee00931c468cd496f\r\n[+] Processing C:\\Users\\Ashura\\Desktop\\ae2a5a02d0ef173b1d38a26c5a88b796f4ee2e8f36ee00931c468cd496fb2b5a\\ae2a5a02\r\n[+] Pyinstaller version: 2.1+\r\n[+] Python version: 3.11\r\n[+] Length of package: 22339020 bytes\r\n[+] Found 163 files in CArchive\r\n[+] Beginning extraction...please standby\r\nhttps://nikhilh-20.github.io/blog/emansrepo_deobfuscation/\r\nPage 2 of 9\n\n[+] Possible entry point: pyiboot01_bootstrap.pyc\r\n[+] Possible entry point: pyi_rth_inspect.pyc\r\n[+] Possible entry point: pyi_rth_pkgutil.pyc\r\n[+] Possible entry point: pyi_rth_multiprocessing.pyc\r\n[+] Possible entry point: pyi_rth_setuptools.pyc\r\n[+] Possible entry point: pyi_rth_pkgres.pyc\r\n[+] Possible entry point: pyi_rth_win32comgenpy.pyc\r\n[+] Possible entry point: pyi_rth_pywintypes.pyc\r\n[+] Possible entry point: pyi_rth_pythoncom.pyc\r\n[+] Possible entry point: one.pyc\r\n[+] Found 782 files in PYZ archive\r\n[+] Successfully extracted pyinstaller archive: C:\\Users\\Ashura\\Desktop\\ae2a5a02d0ef173b1d38a26c5a88b796f4ee2e8f\r\nYou can now use a python decompiler on the pyc files within the extracted directory\r\nAs expected, pyinstxtractor-ng also reported the Python version as 3.11. Multiple potential entry points were\r\nidentified, but one.pyc appears to be the most relevant. We will decompile it next.\r\nDecompile into Python Script\r\nMy first choice for a Python decompiler is pycdc. However, it wasn’t able to decompile one.pyc due to an\r\nassertion error, as shown in Fig. 2. Multiple other issues (see #230, #262, #298, #405) also reference this error.\r\nPerhaps some Python bytecode implementations have not yet been covered.\r\nFig. 2: Error with pycdc\r\nIn situations like these, I turn to PyLingual, having had a good experience with the tool. However, note that any\r\nsubmissions to PyLingual will be used by their team for R\u0026D purposes. If you have a sample that you cannot\r\nshare, avoid using PyLingual.\r\nFig. 3 shows a snippet of the decompiled code, revealing a significant amount of junk code. Out of the 1282 lines\r\nof decompiled code, most are junk, with the relevant code interspersed between them.\r\nhttps://nikhilh-20.github.io/blog/emansrepo_deobfuscation/\r\nPage 3 of 9\n\nFig. 3: Decompilation with PyLingual\r\nDeobfuscating the Python Code\r\nhttps://nikhilh-20.github.io/blog/emansrepo_deobfuscation/\r\nPage 4 of 9\n\nDeobfuscating the First Stage\r\nFig. 3 showed the decompiled Python code of the sample, marking the first stage of its infection flow. The\r\nobfuscation technique is simple - insert junk code that follows specific patterns. Notepad++ is sufficient for\r\ndeobfuscating the code. Fig. 4 demonstrates that using just three patterns to remove the junk code reduces the\r\nscript from 1282 lines to only 45.\r\nFig. 4: Deobfuscated First Stage\r\nThe code base64-decodes a string and then executes it using exec .\r\nCyberChef can be used to base64-decode the string, as shown in Fig. 5. This reveals the obfuscated second stage.\r\nYou may notice that the obfuscation technique is identical to the one used in the first stage.\r\nhttps://nikhilh-20.github.io/blog/emansrepo_deobfuscation/\r\nPage 5 of 9\n\nFig. 5: Obfuscated Second Stage\r\nDeobfuscating the Second Stage\r\nThe deobfuscation in the second stage can be removed in the same way as in the first stage. Fig. 6 shows the\r\ndeobfuscated code.\r\nFig. 6: Deobfuscated Second Stage\r\nThe code base64-decodes a string and then decrypts it using the Fernet cipher with the key\r\ncNXzShHJ02wQEYspi_fi817tN-a16yUZUYFeDCO88x0= . The decrypted code is then executed using exec .\r\nhttps://nikhilh-20.github.io/blog/emansrepo_deobfuscation/\r\nPage 6 of 9\n\nThe Third and Final Stage\r\nThe second stage Python code can be slightly modified to write the decrypted third stage to disk instead of\r\nexecuting it, as shown in Fig. 7. Upon execution, we obtain the final stage: Emansrepo.\r\nFig. 7: Deobfuscated Third Stage\r\nEmansrepo and LLM\r\nhttps://nikhilh-20.github.io/blog/emansrepo_deobfuscation/\r\nPage 7 of 9\n\nI have chosen not to dive into the infostealer aspect of the code, as its scope is limited to stealing data stored in\r\nbrowsers. Additionally, it is a simple Python script, so interested analysts can easily analyze it themselves.\r\nHowever, upon reviewing the code, I have some observations to make:\r\n1. When I first looked at the code, I noticed unnecessary line breaks. In my experience, I sometimes\r\nencounter these when I copy and paste text from one location to another, such as when copying text from\r\nthe Ubuntu terminal into a GitHub PR description. Perhaps this malware code was copy-pasted from\r\nsomewhere.\r\n2. The code is extremely readable, with great variable names, function names, and comments. The control\r\nflow is easy to follow as well. I’ve encountered such readable code generated by LLMs like ChatGPT or\r\nClaude. Perhaps this malware code was generated with the help of an LLM, which could also explain the\r\ncopy-pasting.\r\nFig. 8: Well-Written Emansrepo Code\r\nSummary\r\nhttps://nikhilh-20.github.io/blog/emansrepo_deobfuscation/\r\nPage 8 of 9\n\nIn this blog, we examined the Emansrepo information stealer, focusing on a variant with capabilities limited to\r\nstealing data from browsers. Our primary emphasis was on extracting the Python code from the PyInstaller-based\r\nsample and deobfuscating it by removing junk code. Additionally, we hypothesized that Emansrepo may have\r\nbeen developed with the assistance of an LLM, highlighting their potential to lower the barrier to entry into the\r\ncybercrime world.\r\nSource: https://nikhilh-20.github.io/blog/emansrepo_deobfuscation/\r\nhttps://nikhilh-20.github.io/blog/emansrepo_deobfuscation/\r\nPage 9 of 9",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"origins": [
		"web"
	],
	"references": [
		"https://nikhilh-20.github.io/blog/emansrepo_deobfuscation/"
	],
	"report_names": [
		"emansrepo_deobfuscation"
	],
	"threat_actors": [],
	"ts_created_at": 1775434287,
	"ts_updated_at": 1775826694,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/6757fecbaa765511ca8a869f654ef23504c649ae.pdf",
		"text": "https://archive.orkl.eu/6757fecbaa765511ca8a869f654ef23504c649ae.txt",
		"img": "https://archive.orkl.eu/6757fecbaa765511ca8a869f654ef23504c649ae.jpg"
	}
}