├── README.md └── reports ├── dark_pink_kamikakabot ├── readme.md └── scripts │ └── XML-Task-Extractor.py ├── katz_stealer └── readme.md ├── lynx_ransomware ├── idadb │ └── lynx.idb └── readme.md └── peach_sandstorm_false_font ├── readme.md └── scripts ├── falsefont-cleaner.py └── requirements.txt /README.md: -------------------------------------------------------------------------------- 1 | # Indicators of Compromise 2 | 3 | The following repository contains indicators of compromise related to analysis and research by Nextron Threat Research team 4 | 5 | - [Peach-Sandstorm - False Font Malware](./reports/peach_sandstorm_false_font/readme.md) 6 | - [DarkPink- KamiKakaBot Malware](./reports/dark_pink_kamikakabot/readme.md) 7 | - [In-Depth Analysis of Lynx Ransomware](./reports/lynx_ransomware/readme.md) 8 | 9 | -------------------------------------------------------------------------------- /reports/dark_pink_kamikakabot/readme.md: -------------------------------------------------------------------------------- 1 | # DarkPink - KamiKakaBot Malware 2 | 3 | The following IOCs are based on the analysis and research described in the following blog post 4 | 5 | - [Unveiling KamiKakaBot - Malware Analysis](https://www.nextron-systems.com/2024/03/22/unveiling-kamikakabot-malware-analysis/) 6 | 7 | ## IOCs 8 | 9 | #### New Variant 10 | 11 | | Type | Indicator | 12 | | ---- | ---- | 13 | | Commandline | `SCHTASKS /CREATE /f /TN "OneDriver Reporting Task" /TR "shutdown /l /f" /SC WEEKLY /d TUE,FRI /ST 12:35` | 14 | | Path | `%localappdata%\Temp\wctA91F.tmp` | 15 | | Path | `%localappdata%\Temp\3f88dd57-6ce606be-54c358fb-c566587a.tmp` | 16 | | C2 | `hxxps[://]api[.]telegram[.]org/bot6860236203:AAFrlFzcLuyXU4HxKisFUhvhwKucyL4rDS0` | 17 | 18 | #### Old Variant 19 | 20 | | Type | Indicator | 21 | | ---- | ---- | 22 | | Commandline | `SCHTASKS /CREATE /f /TN "Health Check" /TR "shutdown /l /f" /SC WEEKLY /d WED,FRI /ST 13:15` | 23 | | Commandline | `SCHTASKS /CREATE /f /TN "Microsoft Idle" /TR "shutdown /l /f" /SC WEEKLY /d WED,FRI /ST 23:00` | 24 | | Path | `%localappdata%\Temp\wctF3AB.tmp` | 25 | | Path | `%localappdata%\Temp\207ee439-2ebd-ba42-2f6f-ea02adb4a830.tmp` | 26 | | Path | `%localappdata%\desktop.ini.dat` | 27 | | C2 | `hxxps[://]api[.]telegram[.]org/bot6236700491:AAEcSXSg2mYbr8ydVVlOaJXJloWVRzoMwdM` | 28 | 29 | ### Hashes 30 | 31 | You can grab the list of all the samples we currently track related to DarkPink / KamiKakaBot from our Valhalla website 32 | 33 | - [APT_MAL_DarkPink_KamiKakaBot_Mar24](https://valhalla.nextron-systems.com/info/rule/APT_MAL_DarkPink_KamiKakaBot_Mar24) 34 | - [APT_MAL_DarkPink_KamiKakaBot_Stealer_Module_Mar24](https://valhalla.nextron-systems.com/info/rule/APT_MAL_DarkPink_KamiKakaBot_Stealer_Module_Mar24) 35 | - [MAL_APT_DarkPink_DLL_Jan24](https://valhalla.nextron-systems.com/info/rule/MAL_APT_DarkPink_DLL_Jan24) 36 | 37 | ### Registry 38 | 39 | #### New Variant 40 | 41 | - `HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\` 42 | 43 | - Value: `Shell` Data: `explorer.exe, explorer.exe /e,/root,%Pyps% -nop -w h "Start-Process -N -F $env:Msbd -A $env:Temprd"` 44 | 45 | #### Old Variant 46 | 47 | - `HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\` 48 | 49 | - Value: `Shell` Data: `"explorer.exe, %SYSPS% -nop -w h \"Start-Process -N -F $env:OSBuild -A $env:STMP\""` 50 | - Value: `Shell` Data: `"explorer.exe, %WINSYSPS% -nop -w h \"Start-Process -WindowStyle Hidden -FilePath $env:SYSS -ArgumentList $env:STMP\""` 51 | - Value: `Shell` Data: `"explorer.exe, explorer.exe /e,/root,%PSH% -nop -w h \"Start-Process -N -F $env:SYSB -A $env:TPM\""` 52 | - Value: `Shell` Data: `explorer.exe, %PSS% -nop -w h \"Start-Process -N -F $env:MS -A $env:TMPT\""` 53 | 54 | ## Additional Resources 55 | 56 | ### Sigma 57 | 58 | - [Suspicious Environment Variable Has Been Registered](https://github.com/SigmaHQ/sigma/blob/961932ee3fa9751c8f91599b70ede33bc72d90eb/rules/windows/registry/registry_set/registry_set_suspicious_env_variables.yml) 59 | - [Suspicious Msbuild Execution By Uncommon Parent Process](https://github.com/SigmaHQ/sigma/blob/961932ee3fa9751c8f91599b70ede33bc72d90eb/rules/windows/process_creation/proc_creation_win_msbuild_susp_parent_process.yml) 60 | - [Scheduled Task Creation Via Schtasks.EXE](https://github.com/SigmaHQ/sigma/blob/961932ee3fa9751c8f91599b70ede33bc72d90eb/rules/windows/process_creation/proc_creation_win_schtasks_creation.yml) 61 | - [CurrentVersion NT Autorun Keys Modification](https://github.com/SigmaHQ/sigma/blob/961932ee3fa9751c8f91599b70ede33bc72d90eb/rules/windows/registry/registry_set/registry_set_asep_reg_keys_modification_currentversion_nt.yml) 62 | - [Potential WWlib.DLL Sideloading](https://github.com/SigmaHQ/sigma/blob/961932ee3fa9751c8f91599b70ede33bc72d90eb/rules/windows/image_load/image_load_side_load_wwlib.yml) 63 | - [Explorer Process Tree Break](https://github.com/SigmaHQ/sigma/blob/961932ee3fa9751c8f91599b70ede33bc72d90eb/rules/windows/process_creation/proc_creation_win_explorer_break_process_tree.yml) 64 | - [Potential KamiKakaBot Activity - Lure Document Execution](https://github.com/SigmaHQ/sigma/blob/c0f77338374eb0ef33830182f423f8a79fca6420/rules-emerging-threats/2024/Malware/KamiKakaBot/proc_creation_win_malware_kamikakabot_lnk_lure_execution.yml) 65 | - [Potential KamiKakaBot Activity - Shutdown Schedule Task Creation](https://github.com/SigmaHQ/sigma/blob/c0f77338374eb0ef33830182f423f8a79fca6420/rules-emerging-threats/2024/Malware/KamiKakaBot/proc_creation_win_malware_kamikakabot_schtasks_persistence.yml) 66 | - [Potential KamiKakaBot Activity - Winlogon Shell Persistence](https://github.com/SigmaHQ/sigma/blob/c0f77338374eb0ef33830182f423f8a79fca6420/rules-emerging-threats/2024/Malware/KamiKakaBot/registry_set_malware_kamikakabot_winlogon_persistence.yml) 67 | 68 | ### Scripts 69 | 70 | - [XML Task Extractor](./scripts/XML-Task-Extractor.py) 71 | -------------------------------------------------------------------------------- /reports/dark_pink_kamikakabot/scripts/XML-Task-Extractor.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | def read_file_until_null_byte(file_path): 4 | 5 | chunk_size = 1024 # Adjust this based on your needs 6 | with open(file_path, 'rb') as file: 7 | file.seek(0, 2) # Move to the end of the file 8 | file_size = file.tell() 9 | data = [] 10 | 11 | while file.tell() > 0: 12 | current_position = max(file.tell() - chunk_size, 0) # Calculate position to start reading 13 | file.seek(current_position) 14 | chunk = file.read(min(chunk_size, file_size - current_position)) 15 | null_byte_position = chunk.rfind(b'\x00') # Find null byte in the current chunk 16 | 17 | if null_byte_position != -1: 18 | # Found the null byte, read until this point and break 19 | data.append(chunk[null_byte_position+1:]) 20 | break 21 | else: 22 | # No null byte, keep this chunk and continue 23 | data.append(chunk) 24 | file.seek(current_position) # Move back to read the next chunk 25 | 26 | if file.tell() == 0: 27 | # If we're at the start of the file, ensure we break the loop 28 | break 29 | 30 | data.reverse() # Reverse the order of chunks (we read the file backwards) 31 | result = b''.join(data) 32 | return result 33 | 34 | def main(): 35 | # Check if the correct number of arguments are provided 36 | if len(sys.argv) != 3: 37 | # python3 XML-Task-Extractor.py "~CN AOIP-based Comprehensive Regional Architecture.doc" afc4b8a1d3f2e1b3 38 | print("Usage: python XML-Task-Extractor.py [Malicious_DOC] [XOR_KEY]") 39 | exit() 40 | 41 | # file_path = '~CN AOIP-based Comprehensive Regional Architecture.doc' 42 | # xor_key = bytes.fromhex("afc4b8a1d3f2e1b3") 43 | 44 | file_path = read_file_until_null_byte(sys.argv[1]) 45 | xor_key = bytes.fromhex(sys.argv[2]) 46 | 47 | xml_content = "" 48 | for i in range(len(file_path)): 49 | xml_content += chr(file_path[i] ^ xor_key[i%len(xor_key)]) 50 | 51 | with open("build.xml", "w") as f: 52 | print(xml_content[0:10000]) 53 | f.write(xml_content) 54 | 55 | if __name__ == "__main__": 56 | main() 57 | -------------------------------------------------------------------------------- /reports/katz_stealer/readme.md: -------------------------------------------------------------------------------- 1 | # Katz Stealer Threat Analysis 2 | 3 | The following IOCs are based on the analysis and research described in the following blog post 4 | 5 | - [Katz Stealer Threat Analysis](link- we want to add it) 6 | ## IOCs 7 | 8 | 9 | **C2 Addresses:** 10 | ``` 11 | 185.107.74.40 12 | 31.177.109.39 13 | twist2katz[.]com 14 | pub-ce02802067934e0eb072f69bf6427bf6.r2.dev 15 | ``` 16 | 17 | **Related Domains:** 18 | ``` 19 | katz-stealer[.]com 20 | katzstealer[.]com 21 | ``` 22 | 23 | **User-Agent:** 24 | ``` 25 | Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36 katz-ontop 26 | ``` 27 | 28 | **Filenames:** 29 | ``` 30 | \AppData\Local\Temp\katz_ontop.dll 31 | \AppData\Local\Temp\received_dll.dll 32 | \AppData\Roaming\decrypted_chrome_key.txt 33 | \AppData\Roaming\decrypted_brave_key.txt 34 | \AppData\Roaming\decrypted_edge_key.txt 35 | ``` 36 | 37 | **Payloads:** 38 | | File | SHA256 | 39 | | --- | --- | 40 | | Gzip Archive | 22af84327cb8ecafa44b51e9499238ca2798cec38c2076b702c60c72505329cb | 41 | | JS Script | e4249cf9557799e8123e0b21b6a4be5ab8b67d56dc5bfad34a1d4e76f7fd2b19 | 42 | | PowerShell script | fb2b9163e8edf104b603030cff2dc62fe23d8f158dd90ea483642fce2ceda027 | 43 | | .NET Payload | 0df13fd42fb4a4374981474ea87895a3830eddcc7f3bd494e76acd604c4004f7 | 44 | | .NET UAC Bypass | 4f12c5dca2099492d0c0cd22edef841cbe8360af9be2d8e9b57c2f83d401c1a7 | 45 | | katz_ontop.dll | 6dc8e99da68b703e86fa90a8794add87614f254f804a8d5d65927e0676107a9d | 46 | | katz_ontop.dll | e73f6e1f6c28469e14a88a633aef1bc502d2dbb1d4d2dfcaaef7409b8ce6dc99 | 47 | | received_dll.dll | 15953e0191edaa246045dda0d7489b3832f27fdc3fcc5027f26b89692aefd6e1 | 48 | | Stealer Payload | 2798bf4fd8e2bc591f656fa107bd871451574d543882ddec3020417964d2faa9 | 49 | | Stealer Payload | e345d793477abbecc2c455c8c76a925c0dfe99ec4c65b7c353e8a8c8b14da2b6 | 50 | | Stealer Payload | c601721933d11254ae329b05882337db1069f81e4d04cd4550c4b4b4fe35f9cd | 51 | | Stealer Payload | fdc86a5b3d7df37a72c3272836f743747c47bfbc538f05af9ecf78547fa2e789 | 52 | | Stealer Payload | 25b1ec4d62c67bd51b43de181e0f7d1bda389345b8c290e35f93ccb444a2cf7a | 53 | | Stealer Payload | 964ec70fc2fdf23f928f78c8af63ce50aff058b05787e43c034e04ea6cbe30ef | 54 | | Stealer Payload | d92bb6e47cb0a0bdbb51403528ccfe643a9329476af53b5a729f04a4d2139647 | 55 | | Stealer Payload | b249814a74dff9316dc29b670e1d8ed80eb941b507e206ca0dfdc4ff033b1c1f | 56 | | Stealer Payload | 925e6375deaa38d978e00a73f9353a9d0df81f023ab85cf9a1dc046e403830a8 | 57 | | Stealer Payload | 96ada593d54949707437fa39628960b1c5d142a5b1cb371339acc8f86dbc7678 | 58 | | Stealer Payload | b912f06cf65233b9767953ccf4e60a1a7c262ae54506b311c65f411db6f70128 | 59 | | Stealer Payload | 2852770f459c0c6a0ecfc450b29201bd348a55fb3a7a5ecdcc9986127fdb786b | 60 | | Stealer Payload | 5dd629b610aee4ed7777e81fc5135d20f59e43b5d9cc55cdad291fcf4b9d20eb | 61 | 62 | ## Additional Resources 63 | 64 | ### Sigma Rules 65 | 66 | | Description| Rule | 67 | |---|---| 68 | | Detects the use of cmstp.exe to bypass UAC | [proc_creation_win_uac_bypass_cmstp](https:////github.com/SigmaHQ/sigma/blob/master/rules/windows/process_creation/proc_creation_win_uac_bypass_cmstp.yml) | 69 | | Detects suspicious execution of 'Msbuild.exe' by a uncommon parent process | [proc_creation_win_msbuild_susp_parent_process](https://github.com/SigmaHQ/sigma/blob/master/rules/windows/process_creation/proc_creation_win_msbuild_susp_parent_process.yml) | 70 | | Detects processes that query known 3rd party registry keys that hold credentials via commandline | [proc_creation_win_registry_enumeration_for_credentials_cli](https://github.com/SigmaHQ/sigma/blob/master/rules/windows/process_creation/proc_creation_win_registry_enumeration_for_credentials_cli.yml) | 71 | | Detects execution of Chromium based browser in headless mode | [proc_creation_win_browsers_chromium_headless_exec](https://github.com/SigmaHQ/sigma/blob/master/rules/windows/process_creation/proc_creation_win_browsers_chromium_headless_exec.yml)| 72 | -------------------------------------------------------------------------------- /reports/lynx_ransomware/idadb/lynx.idb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NextronSystems/iocs/2b14c1ded34d3704b4a27db95eb544d273afe2ae/reports/lynx_ransomware/idadb/lynx.idb -------------------------------------------------------------------------------- /reports/lynx_ransomware/readme.md: -------------------------------------------------------------------------------- 1 | # In-Depth Analysis of Lynx Ransomware 2 | 3 | The following IOCs are based on the analysis and research described in the following blog post: 4 | 5 | - [In-Depth Analysis of Lynx Ransomware](https://www.nextron-systems.com/2024/10/11/in-depth-analysis-of-lynx-ransomware/) 6 | 7 | ## IOCs 8 | | Type | Indicator | Family| 9 | | ---- | ---- | ---- | 10 | | SHA-256 | eaa0e773eb593b0046452f420b6db8a47178c09e6db0fa68f6a2d42c3f48e3bc | LYNX Ransomware | 11 | | SHA-256 | 571f5de9dd0d509ed7e5242b9b7473c2b2cbb36ba64d38b32122a0a337d6cf8b | LYNX Ransomware | 12 | | SHA-256 | b378b7ef0f906358eec595777a50f9bb5cc7bb6635e0f031d65b818a26bdc4ee | LYNX Ransomware | 13 | | SHA-256 | ecbfea3e7869166dd418f15387bc33ce46f2c72168f571071916b5054d7f6e49 | LYNX Ransomware | 14 | | SHA-256 | 85699c7180ad77f2ede0b15862bb7b51ad9df0478ed394866ac7fa9362bf5683 | LYNX Ransomware | 15 | | SHA-256 | 64b249eb3ab5993e7bcf5c0130e5f31cbd79dabdcad97268042780726e68533f | INC Ransomware | 16 | | SHA-256 | 508a644d552f237615d1504aa1628566fe0e752a5bc0c882fa72b3155c322cef | INC Ransomware | 17 | | SHA-256 | 7f104a3dfda3a7fbdd9b910d00b0169328c5d2facc10dc17b4378612ffa82d51 | INC Ransomware | 18 | | SHA-256 | 1754c9973bac8260412e5ec34bf5156f5bb157aa797f95ff4fc905439b74357a | INC Ransomware | 19 | | SHA-256 | d147b202e98ce73802d7501366a036ea8993c4c06cdfc6921899efdd22d159c6 | INC Ransomware | 20 | | SHA-256 | 05e4f234a0f177949f375a56b1a875c9ca3d2bee97a2cb73fc2708914416c5a9 | INC Ransomware | 21 | | SHA-256 | fef674fce37d5de43a4d36e86b2c0851d738f110a0d48bae4b2dab4c6a2c373e | INC Ransomware | 22 | | SHA-256 | 36e3c83e50a19ad1048dab7814f3922631990578aab0790401bc67dbcc90a72e | INC Ransomware | 23 | | SHA-256 | 869d6ae8c0568e40086fd817766a503bfe130c805748e7880704985890aca947 | INC Ransomware | 24 | | SHA-256 | ee1d8ac9fef147f0751000c38ca5d72feceeaae803049a2cd49dcce15223b720 | INC Ransomware | 25 | | SHA-256 | f96ecd567d9a05a6adb33f07880eebf1d6a8709512302e363377065ca8f98f56 | INC Ransomware | 26 | | SHA-256 | 3156ee399296d55e56788b487701eb07fd5c49db04f80f5ab3dc5c4e3c071be0 | INC Ransomware | 27 | | SHA-256 | fcefe50ed02c8d315272a94f860451bfd3d86fa6ffac215e69dfa26a7a5deced | INC Ransomware | 28 | | SHA-256 | 11cfd8e84704194ff9c56780858e9bbb9e82ff1b958149d74c43969d06ea10bd | INC Ransomware | 29 | | SHA-256 | 02472036db9ec498ae565b344f099263f3218ecb785282150e8565d5cac92461 | INC Ransomware | 30 | | SHA-256 | e17c601551dfded76ab99a233957c5c4acf0229b46cd7fc2175ead7fe1e3d261 | INC Ransomware | 31 | | SHA-256 | 9ac550187c7c27a52c80e1c61def1d3d5e6dbae0e4eaeacf1a493908ffd3ec7d | INC Ransomware | 32 | | SHA-256 | ca9d2440850b730ba03b3a4f410760961d15eb87e55ec502908d2546cd6f598c | INC Ransomware | 33 | | SHA-256 | 1a7c754ae1933338c740c807ec3dcf5e18e438356990761fdc2e75a2685ebf4a | INC Ransomware | 34 | | SHA-256 | a5925db043e3142e31f21bc18549eb7df289d7c938d56dffe3f5905af11ab97a | INC Ransomware | 35 | | SHA-256 | 7ccea71dcec6042d83692ea9e1348f249b970af2d73c83af3f9d67c4434b2dd0 | INC Ransomware | 36 | | SHA-256 | 5a8883ad96a944593103f2f7f3a692ea3cde1ede71cf3de6750eb7a044a61486 | INC Ransomware | 37 | | SHA-256 | 463075274e328bd47d8092f4901e67f7fff6c5d972b5ffcf821d3c988797e8e3 | INC Ransomware | 38 | ## Additional Resources 39 | 40 | ### Yara 41 | 42 | - [MAL_RANSOM_INC_Aug24](https://github.com/Neo23x0/signature-base/blob/master/yara/mal_inc_ransomware.yar) 43 | 44 | ### Sigma 45 | 46 | - [Potentially Suspicious Desktop Background Change Via Registry](https://github.com/SigmaHQ/sigma/blob/master/rules/windows/registry/registry_set/registry_set_desktop_background_change.yml) 47 | 48 | ### IDA DB 49 | 50 | - [LYNX IDA Database](./idadb/lynx.idb) 51 | -------------------------------------------------------------------------------- /reports/peach_sandstorm_false_font/readme.md: -------------------------------------------------------------------------------- 1 | # Peach Sandstorm - False Font Malware 2 | 3 | The following IOCs are based on the analysis and research described in the following blog post: 4 | 5 | - [Analysis of FalseFont Backdoor used by Peach-Sandstorm Threat Actor](https://www.nextron-systems.com/2024/01/29/analysis-of-falsefont-backdoor-used-by-peach-sandstorm-threat-actor/) 6 | 7 | ## IOCs 8 | | Type | Indicator | 9 | | ---- | ---- | 10 | | SHA-256 | 364275326bbfc4a3b89233dabdaf3230a3d149ab774678342a40644ad9f8d614 | 11 | | SHA-1 | ddd18e208aff7b00a46e06f8d9485f81ff4221ea | 12 | | MD5 | 6fd5d31d607a212c6f7651c79e7655a3 | 13 | | Mutex | `864H!NKLNB*x_H?5` | 14 | | Commandline | `SQP's*(58vaP!tF4` argument used for Update and Restart | 15 | | Filename | Maxar.exe | 16 | | Path | `%localappdata%\Temp\Maxar.exe` | 17 | | Path | `%localappdata%\Microsoft\System.exe` | 18 | | Path | `%localappdata%\broker.exe` | 19 | | Path | `%appdata%\host.exe` | 20 | | IP | hxxp://64[.]52[.]80[.]30:8080 | 21 | | Domain | hxxp://digitalcodecrafters[.]com | 22 | 23 | ### Registry 24 | 25 | - `SOFTWARE\Microsoft\Windows\CurrentVersion\Run` 26 | 27 | - `Value: host.exe Data: %appdata%\host.exe` 28 | 29 | - `Value: broker.exe Data: %localappdata%\broker.exe` 30 | 31 | - `Value: System.exe Data: %localappdata%\Microsoft\System.exe` 32 | 33 | ## Additional Resources 34 | 35 | ### Yara 36 | 37 | - [APT_MAL_FalseFont_Backdoor_Jan24](https://github.com/Neo23x0/signature-base/blob/master/yara/apt_peach_sandstorm.yar) 38 | 39 | ### Sigma 40 | 41 | - [Potential Peach Sandstorm APT C2 Communication Activity](https://github.com/SigmaHQ/sigma/blob/master/rules-emerging-threats/2023/TA/Peach-Sandstorm/proxy_apt_peach_sandstorm_falsefont_backdoor_c2_coms.yml) 42 | - [Peach Sandstorm APT Process Activity Indicators](https://github.com/SigmaHQ/sigma/blob/master/rules-emerging-threats/2023/TA/Peach-Sandstorm/proc_creation_win_apt_peach_sandstorm_indicators.yml) 43 | 44 | ### Scripts 45 | 46 | - [String Decryption and Cleanup Script](./scripts/falsefont-cleaner.py) 47 | -------------------------------------------------------------------------------- /reports/peach_sandstorm_false_font/scripts/falsefont-cleaner.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import clr 4 | import base64 5 | from Crypto.Cipher import AES 6 | from Crypto.Util.Padding import unpad 7 | 8 | # https://github.com/0xd4d/dnlib 9 | dnlib_dll_path = os.path.join(os.path.dirname(__file__), "dnlib") 10 | clr.AddReference(dnlib_dll_path) 11 | 12 | import dnlib 13 | from dnlib.DotNet import ModuleDefMD, DummyLogger, MDToken 14 | from dnlib.DotNet.Emit import OpCodes, OperandType 15 | from dnlib.DotNet.Writer import ModuleWriterOptions 16 | 17 | 18 | class Cleaner: 19 | def __init__(self, file_path) -> None: 20 | self.file_path: str = file_path 21 | self.moduleDef: ModuleDefMD = ModuleDefMD.Load(file_path) 22 | 23 | # These might be binary specific so you will need to change them depending on the sample 24 | self.method_name: str = "Core.Agent.Utilities.Constants::D(System.String)" 25 | self.aes_key: str = "3EzuNZ0RN3h3oV7rzILktSHSaHk+5rtcWOr0mlA1CUA=" 26 | self.aes_iv: str = "viOIZ9cX59qDDjMHYsz1Yw==" 27 | 28 | self.strings_to_inline = [] 29 | 30 | # Get top level and nested types 31 | def get_all_types(self): 32 | top_level_types = [t for t in self.moduleDef.Types] 33 | nested_types = [ 34 | nested_type for t in self.moduleDef.Types for nested_type in t.NestedTypes 35 | ] 36 | return top_level_types + nested_types 37 | 38 | def get_operand(self, inst): 39 | if inst.OpCode == OpCodes.Ldstr: 40 | return inst.Operand 41 | else: 42 | return None 43 | 44 | def get_string(self, key): 45 | for item in self.strings_to_inline: 46 | if item[0] == key: 47 | return item[1] 48 | 49 | def aes_decrypt(self, encrypted_string, base64_key, base64_iv): 50 | key = base64.b64decode(base64_key) 51 | iv = base64.b64decode(base64_iv) 52 | encrypted_data = base64.b64decode(encrypted_string) 53 | cipher = AES.new(key, AES.MODE_CBC, iv) 54 | decrypted_data = unpad(cipher.decrypt(encrypted_data), AES.block_size) 55 | decrypted_text = decrypted_data.decode("utf-8") 56 | return decrypted_text 57 | 58 | def decrypt_strings(self): 59 | for typeDef in self.get_all_types(): 60 | if not typeDef.HasMethods: 61 | continue 62 | 63 | for method in typeDef.Methods: 64 | if not method.HasBody: 65 | continue 66 | 67 | for index, inst in enumerate(method.Body.Instructions): 68 | if inst.OpCode != OpCodes.Call: 69 | continue 70 | 71 | if self.method_name not in str(inst.Operand): 72 | continue 73 | 74 | if (method.Body.Instructions[index - 1].OpCode != OpCodes.Ldstr): 75 | continue 76 | 77 | 78 | operand = self.get_operand(method.Body.Instructions[index - 1]) 79 | if operand is not None: 80 | try: 81 | result = self.aes_decrypt( 82 | operand, self.aes_key, self.aes_iv) 83 | print(result) 84 | except Exception as e: 85 | continue 86 | 87 | if not result: 88 | continue 89 | 90 | if (len(method.Body.Instructions) == 3): 91 | self.strings_to_inline.append((method.FullName, result)) 92 | 93 | # Nop string argument 94 | method.Body.Instructions[index - 1].OpCode = OpCodes.Nop 95 | # Replace call with decrypted string 96 | method.Body.Instructions[index].OpCode = OpCodes.Ldstr 97 | method.Body.Instructions[index].Operand = result 98 | 99 | def inline_strings(self): 100 | method_names = [item[0] for item in self.strings_to_inline] 101 | for typeDef in self.get_all_types(): 102 | if not typeDef.HasMethods: 103 | continue 104 | 105 | for method in typeDef.Methods: 106 | if not method.HasBody: 107 | continue 108 | 109 | for index, inst in enumerate(method.Body.Instructions): 110 | if inst.OpCode != OpCodes.Call: 111 | continue 112 | 113 | if (str(inst.Operand) not in method_names): 114 | continue 115 | 116 | result = self.get_string(str(inst.Operand)) 117 | inst.OpCode = OpCodes.Ldstr 118 | inst.Operand = result 119 | 120 | 121 | def save_module(self): 122 | options = ModuleWriterOptions(self.moduleDef) 123 | options.Logger = DummyLogger.NoThrowInstance 124 | 125 | split_name = self.file_path.rsplit(".", 1) 126 | output_path = ( 127 | f"{split_name[0]}_cleaned.{split_name[1]}" 128 | if len(split_name) > 1 129 | else f"{split_name[0]}_cleaned" 130 | ) 131 | 132 | self.moduleDef.Write(output_path, options) 133 | 134 | 135 | def main(): 136 | if len(sys.argv) < 2: 137 | sys.exit("falsefont-cleaner.py ") 138 | 139 | file_path = sys.argv[1] 140 | 141 | if not os.path.exists(file_path): 142 | sys.exit(f"[ERROR]: Could not find file {file_path}") 143 | 144 | if not os.path.isabs(file_path): 145 | file_path = os.path.abspath(file_path) 146 | 147 | cleaner = Cleaner(file_path) 148 | 149 | cleaner.decrypt_strings() 150 | cleaner.inline_strings() 151 | cleaner.save_module() 152 | 153 | 154 | if __name__ == "__main__": 155 | main() -------------------------------------------------------------------------------- /reports/peach_sandstorm_false_font/scripts/requirements.txt: -------------------------------------------------------------------------------- 1 | pythonnet>=3.0.1 2 | pycryptodome>=3.20.0 3 | --------------------------------------------------------------------------------