{
	"id": "b897fee5-e94c-4aeb-afe9-3b221e1e08ca",
	"created_at": "2026-04-06T00:18:45.085608Z",
	"updated_at": "2026-04-10T03:21:36.067407Z",
	"deleted_at": null,
	"sha1_hash": "517fe9a301b2dc7c82b81fdebfa81c46cb23c810",
	"title": "NetWalker: il ransomware che ha beffato l’intera community",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 5621298,
	"plain_text": "NetWalker: il ransomware che ha beffato l’intera community\r\nArchived: 2026-04-05 15:49:37 UTC\r\nOur encryption algorithms are very strong and your files are very well protected, the only way to get your files\r\nback is to cooperate with us and get the decrypter program.\r\n[…]\r\nAdditionally, you must know that your sensitive data has been stolen by our analyst experts and if you choose to\r\nno cooperate with us, you are exposing yourself.\r\nMa è davvero così?\r\nCe lo siamo chiesti dopo che è emersa la tendenza da parte dei ransomware ad entrare in scena nei casi più\r\neclatanti di data leak.\r\nGiusto per citare gli ultimi, ne sono un esempio i casi di Luxottica ed Enel.\r\nGià dall’analisi di Maze, coinvolto anche’esso in un data leak, avevamo constatato come il ransomware fosse stato\r\nsolo l’ultimo stadio di un attacco più articolato.\r\nMaze, infatti, non è in grado di esfiltrare dati, così come non lo è neanche NetWalker. I ransomware sono da\r\nsempre focalizzati solo sulla cifratura dei file, lavoro di per sè già abbastanza complesso anche senza dover\r\naggiungere l’onere di trasferire GiB, se non TiB, di dati verso un host esterno.\r\nCome Maze quindi, neanche il ransomware NetWalker può esfiltrare dati (non importa nessuna API in grado di\r\ntrasferire dei dati all’esterno), per quanto si senta dire spesso il contrario.\r\nAd essere corretti, NetWalker non comunica affatto con l’esterno. La vittima deve inserire un misterioso JSON\r\nnel sito (un hidden service, ovviamente) dei criminali, per ottenere un decryptor.\r\nVedremo in questo articolo come funzioni NetWalker, un malware che, sebbene articolato, risulta di facile analisi\r\n(premesse le necessarie competenze sulle implementazioni delle primitive crittografiche usate).\r\nVedremo inoltre cosa sia il misterioso JSON da fornire ai criminali e soprattutto determineremo se esiste o meno\r\nla possibilità di un decryptor.\r\nQuasi tutto quello che si sà di NetWalker è il frutto di analisi che si limitano a dedurre il comportamento del\r\nmalware dalla sua configurazione e dalle istruzioni lasciate sulla macchina compromessa.\r\nIl loader\r\nIl campione che abbiamo analizzato era contenuto in un loader PowerShell che non era particolarmente offuscato\r\n(le stringhe lo erano ma fortunatamente erano facilmente decifrabili tramite conversione da base64 e XOR con una\r\ncostante).\r\nIl compito del loader è quello di trovare sul sistema il processo explorer.exe ed iniettarvi una DLL (disponibile\r\nin entrambe le versioni a 32 e 64 bit): se non vi riesce, mappa la DLL nel proprio processo (ovvero nell’interprete\r\npowershell) e la esegue.\r\nLa DLL è il ransomware NetWalker vero e proprio.\r\nhttps://cert-agid.gov.it/news/netwalker-il-ransomware-che-ha-beffato-lintera-community/\r\nPage 1 of 43\n\nIl loader di NetWalker, deoffuscato e con parti di codice omesse per brevità\r\nIl loader è piuttosto scontato; unica parte degna di nota sono le ultime due righe che cancellano le copie per il\r\nripristino dei dati.\r\nLa cancellazione delle copie per il ripristino dei dati\r\nQuesto è un indicatore preciso che si ritrova tipicamente nei ransomware, in quanto è una operazione che i\r\ncriminali devono necessariamente effettuare per il buon esito della loro operazione.\r\nNetWalker\r\nNel suo complesso, NetWalker è un malware piuttosto semplice da analizzare poichè non presenta offuscamento o\r\ntecniche anti-analisi.\r\nhttps://cert-agid.gov.it/news/netwalker-il-ransomware-che-ha-beffato-lintera-community/\r\nPage 2 of 43\n\nL’esecuzione inizia dell’entrypoint PE (il convenzionale DllMain ) ed è divisa in quattro passi, mostrati qui sotto.\r\nLe quattro fasi di NetWalker: importazione delle API; parsing della configurazione; generazione\r\ndelle chiavi di cifratura; cifratura vera e propria\r\nI più importanti sono gli ultimi due, dove il malware genera le chiavi per la cifratura ed effettua il suo lavoro sui\r\nfile.\r\nLe API e la configurazione\r\nAccorpiamo qui queste due fasi in quanto la prima risulta semplice.\r\nLe API sono recuperate tramite la classica enumerazione dei moduli dal campo Ldr del PEB .\r\nSempre tradizionalmente, le funzioni da importare e la relativa DLL sono ricercate comparando l’hash del loro\r\nnome, per evitare di usare costanti che potrebbero far scattare qualche strumento AV.\r\nLe API sono tutte salvate in un buffer, rinominato bufferAPI , ed è quindi facile verificare che tra queste non\r\nsono presenti API per la comunicazione di rete.\r\nhttps://cert-agid.gov.it/news/netwalker-il-ransomware-che-ha-beffato-lintera-community/\r\nPage 3 of 43\n\nL’importazione delle API di NetWalker. Gli interi evidenziati sono due esempi di hash usati durante\r\nl’enumerazione dei moduli e delle funzioni. In basso il buffer in cui sono salvati i puntatori alle API.\r\nGli autori di NetWalker non hanno prestato attenzione ad offuscare il nome delle DLL che devono essere\r\nesplicitamente caricate (perchè non facenti parte del set comune di explorer), come si vede chiaramente\r\ndall’immagine sotto.\r\nhttps://cert-agid.gov.it/news/netwalker-il-ransomware-che-ha-beffato-lintera-community/\r\nPage 4 of 43\n\nhttps://cert-agid.gov.it/news/netwalker-il-ransomware-che-ha-beffato-lintera-community/\r\nPage 5 of 43\n\nSe mpr.dll non è già presente (primo blocco), viene caricata, usando il nome in chiaro (secondo\r\nblocco).\r\nTutto il buffer di 0x284 byte è riempito, per un totale di 161 API.\r\nPer completezza riportiamo l’elenco completo:\r\n005A6980 7772E046 ntdll.RtlAllocateHeap\r\n005A6984 7772DFA5 ntdll.RtlFreeHeap\r\n005A6988 77742561 ntdll.RtlReAllocateHeap\r\n005A698C 7772DF40 ntdll.memset\r\n005A6990 77722340 ntdll.memcpy\r\n005A6994 777322A5 ntdll.memcmp\r\n005A6998 777D5555 ntdll.sprintf\r\n005A699C 77739D10 ntdll.strchr\r\n005A69A0 777619DA ntdll.strtol\r\n005A69A4 7777C340 ntdll.strcpy\r\n005A69A8 7777C350 ntdll.strcat\r\n005A69AC 777D57CD ntdll.wcscpy\r\n005A69B0 777D579A ntdll.wcscat\r\n005A69B4 7777C800 ntdll.strstr\r\n005A69B8 77730CC7 ntdll.wcsstr\r\n005A69BC 77732504 ntdll.wcscmp\r\n005A69C0 77737FA5 ntdll.wcsncmp\r\n005A69C4 77740299 ntdll.RtlRandomEx\r\n005A69C8 777C99C2 ntdll.RtlRandom\r\n005A69CC 7772E1F0 ntdll.RtlInitAnsiString\r\n005A69D0 7772E228 ntdll.RtlInitUnicodeString\r\n005A69D4 7772E6D5 ntdll.RtlAnsiStringToUnicodeString\r\n005A69D8 77736AF8 ntdll.RtlUnicodeStringToAnsiString\r\n005A69DC 7772E146 ntdll.RtlFreeAnsiString\r\n005A69E0 7772E146 ntdll.RtlFreeAnsiString\r\n005A69E4 7773C4DD ntdll.LdrLoadDll\r\n005A69E8 777B2040 ntdll.RtlAdjustPrivilege\r\n005A69EC 7771FDB0 ntdll.ZwQuerySystemInformation\r\n005A69F0 7771FC20 ntdll.NtOpenProcess\r\n005A69F4 777210C0 ntdll.NtOpenProcessToken\r\n005A69F8 7771FCB0 ntdll.ZwTerminateProcess\r\n005A69FC 7772012C ntdll.NtQuerySystemTime\r\n005A6A00 7771FAC0 ntdll.ZwAllocateVirtualMemory\r\n005A6A04 7771FB58 ntdll.ZwFreeVirtualMemory\r\n005A6A08 77720038 ntdll.NtProtectVirtualMemory\r\n005A6A0C 7771FE14 ntdll.ZwWriteVirtualMemory\r\n005A6A10 7771FE90 ntdll.ZwReadVirtualMemory\r\n005A6A14 7771FBD8 ntdll.NtQueryVirtualMemory\r\n005A6A18 7771FFA4 ntdll.NtCreateSection\r\n005A6A1C 7771FC50 ntdll.ZwMapViewOfSection\r\n005A6A20 7771FC80 ntdll.ZwUnmapViewOfSection\r\nhttps://cert-agid.gov.it/news/netwalker-il-ransomware-che-ha-beffato-lintera-community/\r\nPage 6 of 43\n\n005A6A24 77720C30 ntdll.ZwGetContextThread\r\n005A6A28 77721920 ntdll.ZwSetContextThread\r\n005A6A2C 77720068 ntdll.ZwResumeThread\r\n005A6A30 77721D70 ntdll.ZwSuspendThread\r\n005A6A34 7771FF24 ntdll.NtQueueApcThread\r\n005A6A38 7771F9E0 ntdll.ZwClose\r\n005A6A3C 7771FC38 ntdll.ZwSetInformationFile\r\n005A6A40 7771FA10 ntdll.ZwQueryInformationFile\r\n005A6A44 7771FE44 ntdll.NtDuplicateObject\r\n005A6A48 7771F9F8 ntdll.ZwQueryObject\r\n005A6A4C 7771FD64 ntdll.NtOpenFile\r\n005A6A50 77757CD9 ntdll.RtlDosPathNameToNtPathName_U\r\n005A6A54 777C00C1 ntdll.RtlComputeCrc32\r\n005A6A58 7773876A ntdll.RtlGetVersion\r\n005A6A5C 75943F1C kernel32.CreateFileW\r\n005A6A60 75941282 kernel32.WriteFile\r\n005A6A64 75943E93 kernel32.ReadFile\r\n005A6A68 7594193A kernel32.GetFileSize\r\n005A6A6C 759459AA kernel32.GetFileSizeEx\r\n005A6A70 7595C7DF kernel32.SetFilePointerEx\r\n005A6A74 7595CE06 kernel32.SetEndOfFile\r\n005A6A78 759C48AF kernel32.GetLogicalDriveStringsW\r\n005A6A7C 75944153 kernel32.GetDriveTypeW\r\n005A6A80 759413E0 kernel32.CloseHandle\r\n005A6A84 7594110C kernel32.GetTickCount\r\n005A6A88 7595D4AC kernel32.GetTempPathW\r\n005A6A8C 7596D1A6 kernel32.GetTempFileNameW\r\n005A6A90 759682D5 kernel32.CopyFileW\r\n005A6A94 75959AC8 kernel32.MoveFileW\r\n005A6A98 7594897B kernel32.DeleteFileW\r\n005A6A9C 7594103D kernel32.CreateProcessW\r\n005A6AA0 759479D8 kernel32.ExitProcess\r\n005A6AA4 75944221 kernel32.CreateDirectoryW\r\n005A6AA8 759C4A0F kernel32.RemoveDirectoryW\r\n005A6AAC 759443AA kernel32.GetWindowsDirectoryW\r\n005A6AB0 7594502B kernel32.GetSystemDirectoryW\r\n005A6AB4 7596BB86 kernel32.GetComputerNameExW\r\n005A6AB8 7594442F kernel32.GetVersion\r\n005A6ABC 75944918 kernel32.GetModuleFileNameW\r\n005A6AC0 7595E98B kernel32.FindResourceA\r\n005A6AC4 75945914 kernel32.LoadResource\r\n005A6AC8 75945921 kernel32.LockResource\r\n005A6ACC 75945A91 kernel32.SizeofResource\r\n005A6AD0 759443FD kernel32.FindFirstFileW\r\n005A6AD4 759454B6 kernel32.FindNextFileW\r\n005A6AD8 7594440A kernel32.FindClose\r\n005A6ADC 759441E8 kernel32.WaitForMultipleObjects\r\nhttps://cert-agid.gov.it/news/netwalker-il-ransomware-che-ha-beffato-lintera-community/\r\nPage 7 of 43\n\n005A6AE0 75943495 kernel32.CreateThread\r\n005A6AE4 7594192A kernel32.IsWow64Process\r\n005A6AE8 7595D620 kernel32.Wow64DisableWow64FsRedirection\r\n005A6AEC 7595D638 kernel32.Wow64RevertWow64FsRedirection\r\n005A6AF0 759410FF kernel32.Sleep\r\n005A6AF4 75941AE4 kernel32.GetFileAttributesW\r\n005A6AF8 7595D4C7 kernel32.SetFileAttributesW\r\n005A6AFC 759B87B9 kernel32.WaitForDebugEvent\r\n005A6B00 759B889F kernel32.ContinueDebugEvent\r\n005A6B04 759B88E3 kernel32.DebugActiveProcessStop\r\n005A6B08 759411C0 kernel32.GetLastError\r\n005A6B0C 759411F8 kernel32.GetCurrentProcessId\r\n005A6B10 75941ACC kernel32.SetErrorMode\r\n005A6B14 75942CFC kernel32.LocalFree\r\n005A6B18 77732C8A ntdll.RtlInitializeCriticalSection\r\n005A6B1C 777222C0 ntdll.RtlEnterCriticalSection\r\n005A6B20 77722280 ntdll.RtlLeaveCriticalSection\r\n005A6B24 75941136 kernel32.WaitForSingleObject\r\n005A6B28 75944663 kernel32.FlushFileBuffers\r\n005A6B2C 75941420 kernel32.GetCurrentThreadId\r\n005A6B30 7596CEDC kernel32.QueryDosDeviceW\r\n005A6B34 759515BF kernel32.QueryFullProcessImageNameW\r\n005A6B38 75943470 kernel32.GetModuleHandleW\r\n005A6B3C 7594180A kernel32.CreateEventW\r\n005A6B40 759415A6 kernel32.OpenEventW\r\n005A6B44 75941691 kernel32.SetEvent\r\n005A6B48 75944214 kernel32.CreateMutexW\r\n005A6B4C 75945119 kernel32.OpenMutexW\r\n005A6B50 7594111E kernel32.ReleaseMutex\r\n005A6B54 7596B297 kernel32.OutputDebugStringA\r\n005A6B58 77071A03 advapi32.GetCurrentHwProfileW\r\n005A6B5C 7707CA04 advapi32.OpenSCManagerW\r\n005A6B60 770D2401 advapi32.EnumServicesStatusW\r\n005A6B64 7707C9EC advapi32.OpenServiceW\r\n005A6B68 77071E3A advapi32.EnumDependentServicesW\r\n005A6B6C 770970DC advapi32.ControlService\r\n005A6B70 7708361C advapi32.CloseServiceHandle\r\n005A6B74 7707792C advapi32.QueryServiceStatusEx\r\n005A6B78 7708460D advapi32.RegOpenKeyExW\r\n005A6B7C 7708407E advapi32.RegCreateKeyExW\r\n005A6B80 77081456 advapi32.RegSetValueExW\r\n005A6B84 7708462D advapi32.RegQueryValueExW\r\n005A6B88 7707A965 advapi32.RegDeleteKeyExW\r\n005A6B8C 770811F2 advapi32.RegDeleteKeyW\r\n005A6B90 7707CED1 advapi32.RegDeleteValueW\r\n005A6B94 770976D7 advapi32.RegFlushKey\r\n005A6B98 7708461D advapi32.RegCloseKey\r\nhttps://cert-agid.gov.it/news/netwalker-il-ransomware-che-ha-beffato-lintera-community/\r\nPage 8 of 43\n\n005A6B9C 77084133 advapi32.LookupPrivilegeValueW\r\n005A6BA0 7708410E advapi32.AdjustTokenPrivileges\r\n005A6BA4 7707C9C4 advapi32.DuplicateTokenEx\r\n005A6BA8 7707C532 advapi32.CreateProcessAsUserW\r\n005A6BAC 770814E2 advapi32.RevertToSelf\r\n005A6BB0 7707C51A advapi32.ImpersonateLoggedOnUser\r\n005A6BB4 7708429C advapi32.GetTokenInformation\r\n005A6BB8 770842C4 advapi32.ConvertSidToStringSidW\r\n005A6BBC 7707CAA6 advapi32.IsWellKnownSid\r\n005A6BC0 68BC2F06 mpr.WNetOpenEnumW\r\n005A6BC4 68BC3058 mpr.WNetEnumResourceW\r\n005A6BC8 68BC4769 mpr.WNetUseConnectionW\r\n005A6BCC 68BC4744 mpr.WNetAddConnection2W\r\n005A6BD0 68BCD34E mpr.WNetGetUniversalNameW\r\n005A6BD4 68BC2DD6 mpr.WNetCloseEnum\r\n005A6BD8 75F25650 shell32.SHGetFolderPathW\r\n005A6BDC 75EB3C39 shell32.ShellExecuteW\r\n005A6BE0 69C63F33 srvcli.NetShareEnum\r\n005A6BE4 688713D2 netutils.NetApiBufferFree\r\n005A6BE8 75D109AD ole32.CoInitializeEx\r\n005A6BEC 75D186D3 ole32.CoUninitialize\r\n005A6BF0 75D19D0B ole32.CoCreateInstance\r\n005A6BF4 75CF7259 ole32.CoInitializeSecurity\r\n005A6BF8 771A4642 oleaut32.SysAllocString\r\n005A6BFC 771A3E59 oleaut32.SysFreeString\r\n005A6C00 751813F0 psapi.GetModuleFileNameExW\r\nLa configurazione di NetWalker è in formato JSON e si trova cifrata nell’unica sua risorsa.\r\nQuesta risorsa è così strutturata:\r\nRicostruire la struttura della risorsa non è stato complicato, sotto i frammenti di codice rilevanti.\r\nhttps://cert-agid.gov.it/news/netwalker-il-ransomware-che-ha-beffato-lintera-community/\r\nPage 9 of 43\n\nIl caricamento della risorsa, le usuali chiamate a LoadResource, LockResource e SizeOfResouce\r\nsono inoltre presenti.\r\nLe decifratura della configurazione. E’ stato possibile identificare RC4 grazie ai blocchi evidenziati\r\na destra. Quale altro cifrario usa tabelle da 256 byte?\r\nLa configurazione decifrata è un JSON che contiene, tra le altre, una chiave che si rileverà essere una chiave\r\npubblica X25519.\r\n{\r\n \"mpk\":\"MfPiGc7EOHCyHMHGB05GafqzEAvw8xhjuAB7MlNf53I=\",\r\n \"mode\":0,\r\n \"spsz\":15360,\r\n \"thr\":1500,\r\n \"idsz\":6,\r\n \"encname\":false,\r\nhttps://cert-agid.gov.it/news/netwalker-il-ransomware-che-ha-beffato-lintera-community/\r\nPage 10 of 43\n\n\"onion1\":\"pb36hu4spl6cyjdfhing7h3pw6dhpk32ifemawkujj4gp33ejzdq3did.onion\",\r\n \"onion2\":\"rnfdsgm6wb6j6su5txkekw4u4y47kp2eatvu7d6xhyn5cs4lt4pdrqqd.onion\",\r\n \"lfile\":\"{id}-Readme.txt\",\r\n \"lend\":\"SGkhDQpZb3VyIGZpbGVzIGFyZSBlbmNyeXB0ZWQuDQpBbGwgZW5jcnlwdGVkIGZpbGVzIGZvciB0aGlzIGNvbXB1dG\r\n \"white\":{\r\n \"path\":[\r\n \"*system volume information\",\r\n \"*windows.old\",\r\n \"*:\\\\users\\\\*\\\\*temp\",\r\n \"*msocache\",\r\n \"*:\\\\winnt\",\r\n \"*$windows.~ws\",\r\n \"*perflogs\",\r\n \"*boot\",\r\n \"*:\\\\windows\",\r\n \"*:\\\\program file*\\\\vmware\",\r\n \"\\\\\\\\*\\\\users\\\\*\\\\*temp\",\r\n \"\\\\\\\\*\\\\winnt\",\r\n \"\\\\\\\\*\\\\windows\",\r\n \"*\\\\program file*\\\\vmware\",\r\n \"*appdata*microsoft\",\r\n \"*appdata*packages\",\r\n \"*microsoft\\\\provisioning\",\r\n \"*dvd maker\",\r\n \"*Internet Explorer\",\r\n \"*Mozilla\",\r\n \"*Mozilla*\",\r\n \"*Old Firefox data\",\r\n \"*\\\\program file*\\\\windows media*\",\r\n \"*\\\\program file*\\\\windows portable*\",\r\n \"*windows defender\",\r\n \"*\\\\program file*\\\\windows nt\",\r\n \"*\\\\program file*\\\\windows photo*\",\r\n \"*\\\\program file*\\\\windows side*\",\r\n \"*\\\\program file*\\\\windowspowershell\",\r\n \"*\\\\program file*\\\\cuass*\",\r\n \"*\\\\program file*\\\\microsoft games\",\r\n \"*\\\\program file*\\\\common files\\\\system\",\r\n \"*\\\\program file*\\\\common files\\\\*shared\",\r\n \"*\\\\program file*\\\\common files\\\\reference ass*\",\r\n \"*\\\\windows\\\\cache*\",\r\n \"*temporary internet*\",\r\n \"*media player\",\r\n \"*:\\\\users\\\\*\\\\appdata\\\\*\\\\microsoft\",\r\n \"\\\\\\\\*\\\\users\\\\*\\\\appdata\\\\*\\\\microsoft\",\r\n \"*\\\\Program File*\\\\Cisco\"\r\n ],\r\nhttps://cert-agid.gov.it/news/netwalker-il-ransomware-che-ha-beffato-lintera-community/\r\nPage 11 of 43\n\n\"file\":[\r\n \"ntuser.dat*\",\r\n \"iconcache.db\",\r\n \"gdipfont*.dat\",\r\n \"ntuser.ini\",\r\n \"usrclass.dat\",\r\n \"usrclass.dat*\",\r\n \"boot.ini\",\r\n \"bootmgr\",\r\n \"bootnxt\",\r\n \"desktop.ini\",\r\n \"ntuser.dat\",\r\n \"autorun.inf\",\r\n \"ntldr\",\r\n \"thumbs.db\",\r\n \"bootsect.bak\",\r\n \"bootfont.bin\"\r\n ],\r\n \"ext\":[\r\n \"msp\",\r\n \"exe\",\r\n \"sys\",\r\n \"msc\",\r\n \"mod\",\r\n \"clb\",\r\n \"mui\",\r\n \"regtrans-ms\",\r\n \"theme\",\r\n \"hta\",\r\n \"shs\",\r\n \"nomedia\",\r\n \"diagpkg\",\r\n \"cab\",\r\n \"ics\",\r\n \"msstyles\",\r\n \"cur\",\r\n \"drv\",\r\n \"icns\",\r\n \"diagcfg\",\r\n \"dll\",\r\n \"ocx\",\r\n \"lnk\",\r\n \"ico\",\r\n \"idx\",\r\n \"ps1\",\r\n \"mpa\",\r\n \"cpl\",\r\nhttps://cert-agid.gov.it/news/netwalker-il-ransomware-che-ha-beffato-lintera-community/\r\nPage 12 of 43\n\n\"icl\",\r\n \"msu\",\r\n \"msi\",\r\n \"nls\",\r\n \"scr\",\r\n \"adv\",\r\n \"386\",\r\n \"com\",\r\n \"hlp\",\r\n \"rom\",\r\n \"lock\",\r\n \"386\",\r\n \"wpx\",\r\n \"ani\",\r\n \"prf\",\r\n \"rtp\",\r\n \"ldf\",\r\n \"key\",\r\n \"diagcab\",\r\n \"cmd\",\r\n \"spl\",\r\n \"deskthemepack\",\r\n \"bat\",\r\n \"themepack\"\r\n ],\r\n \"extfree\":null\r\n },\r\n \"kill\":{\r\n \"use\":true,\r\n \"prc\":[\r\n \"nslsvice.exe\",\r\n \"pg*\",\r\n \"nservice.exe\",\r\n \"cbvscserv*\",\r\n \"ntrtscan.exe\",\r\n \"cbservi*\",\r\n \"hMailServer*\",\r\n \"IBM*\",\r\n \"bes10*\",\r\n \"black*\",\r\n \"apach*\",\r\n \"bd2*\",\r\n \"db*\",\r\n \"ba*\",\r\n \"be*\",\r\n \"QB*\",\r\n \"oracle*\",\r\nhttps://cert-agid.gov.it/news/netwalker-il-ransomware-che-ha-beffato-lintera-community/\r\nPage 13 of 43\n\n\"wbengine*\",\r\n \"vee*\",\r\n \"postg*\",\r\n \"sage*\",\r\n \"sap*\",\r\n \"b1*\",\r\n \"fdlaunch*\",\r\n \"msmdsrv*\",\r\n \"report*\",\r\n \"msdtssr*\",\r\n \"coldfus*\",\r\n \"cfdot*\",\r\n \"swag*\",\r\n \"swstrtr*\",\r\n \"jetty.exe\",\r\n \"wrsa.exe\",\r\n \"team*\",\r\n \"agent*\",\r\n \"store.exe\",\r\n \"sql*\",\r\n \"sqbcoreservice.exe\",\r\n \"thunderbird.exe\",\r\n \"ocssd.exe\",\r\n \"encsvc.exe\",\r\n \"excel.exe\",\r\n \"synctime.exe\",\r\n \"mspub.exe\",\r\n \"ocautoupds.exe\",\r\n \"thebat.exe\",\r\n \"dbeng50.exe\",\r\n \"*sql*\",\r\n \"mydesktopservice.exe\",\r\n \"onenote.exe\",\r\n \"outlook.exe\",\r\n \"powerpnt.exe\",\r\n \"msaccess.exe\",\r\n \"tbirdconfig.exe\",\r\n \"wordpad.exe\",\r\n \"ocomm.exe\",\r\n \"dbsnmp.exe\",\r\n \"thebat64.exe\",\r\n \"winword.exe\",\r\n \"oracle.exe\",\r\n \"xfssvccon.exe\",\r\n \"firefoxconfig.exe\",\r\n \"visio.exe\",\r\n \"mydesktopqos.exe\",\r\nhttps://cert-agid.gov.it/news/netwalker-il-ransomware-che-ha-beffato-lintera-community/\r\nPage 14 of 43\n\n\"infopath.exe\",\r\n \"agntsvc.exe\"\r\n ],\r\n \"svc\":[\r\n \"Lotus*\",\r\n \"veeam*\",\r\n \"cbvscserv*\",\r\n \"hMailServer\",\r\n \"backup*\",\r\n \"*backup*\",\r\n \"apach*\",\r\n \"firebird*\",\r\n \"ibmiasrw\",\r\n \"IBM Domino*\",\r\n \"Simply Accounting Database Connection Manager\",\r\n \"IASJet\",\r\n \"QB*\",\r\n \"*sql*\",\r\n \"sql*\",\r\n \"QuickBooksDB*\",\r\n \"IISADMIN\",\r\n \"omsad\",\r\n \"dc*32\",\r\n \"server Administrator\",\r\n \"wbengine\",\r\n \"mr2kserv\",\r\n \"MSExchange*\",\r\n \"ShadowProtectSvc\",\r\n \"SP*4\",\r\n \"teamviewer\",\r\n \"MMS\",\r\n \"AcronisAgent\",\r\n \"ARSM\",\r\n \"AcrSch2Svc\",\r\n \"vsnapvss\",\r\n \"SPXService\",\r\n \"StorageCraft ImageManager\",\r\n \"wrsvc\",\r\n \"stc_endpt_svc\",\r\n \"acrsch2svc*\"\r\n ],\r\n \"svcwait\":0,\r\n \"task\":[\r\n \"reboot\",\r\n \"restart\",\r\n \"shutdown\",\r\n \"logoff\",\r\nhttps://cert-agid.gov.it/news/netwalker-il-ransomware-che-ha-beffato-lintera-community/\r\nPage 15 of 43\n\n\"back\"\r\n ]\r\n },\r\n \"net\":{\r\n \"use\":true,\r\n \"ignore\":{\r\n \"use\":true,\r\n \"disk\":true,\r\n \"share\":[\r\n \"ipc$\",\r\n \"admin$\"\r\n ]\r\n }\r\n },\r\n \"unlocker\":{\r\n \"use\":true,\r\n \"ignore\":{\r\n \"use\":true,\r\n \"pspath\":[\r\n \"*:\\\\windows*\",\r\n \"*:\\\\winnt*\",\r\n \"*:\\\\program file*\\\\vmwar*\",\r\n \"*\\\\Program File*\\\\Fortinet\",\r\n \"*\\\\Program File*\\\\Cisco\"\r\n ],\r\n \"prc\":[\r\n \"psexec.exe\",\r\n \"system\",\r\n \"forti*.exe\",\r\n \"fmon.exe\",\r\n \"fcaptmon.exe\",\r\n \"FCHelper64.exe\"\r\n ]\r\n }\r\n }\r\n}\r\nRiportiamo brevemente il significato di ogni campo. Per la comprensione di questi è necessario procedere con la\r\ncompleta analisi del ransomware: noi li riportiamo qui per riferimento senza indicare il codice dove sono usati.\r\nmpk. Chiave pubblica X25519 con la quale è ottenuto un segreto condiviso (vedi sotto, per il funzionamento di\r\nX25519) usato per cifrare la chiave segreta ed ottenere la chiave di cifratura (univoca) di ogni file.\r\nmode. Modalità di cifratura. Sono disponibili tre modi:\r\n1. Modo 0. Se il file ha dimensione minore di spsz, passa al modo 2, se ha dimensione inferiore a 5 * spsz\r\npassa al modo 1, altrimenti rimani in modo 0.\r\nhttps://cert-agid.gov.it/news/netwalker-il-ransomware-che-ha-beffato-lintera-community/\r\nPage 16 of 43\n\nIn questo modo, tre blocchi del file sono cifrati, tutti di dimensione spsz e posizionati rispettivamente:\r\nall’inizio, a metà e alla fine.\r\n2. Modo 1. Un blocco di dimensione spsz è cifrato ad inizio file.\r\n3. Modo 2. Tutto il file è cifrato.\r\nspsz. Dimensione da cifrare. Non più di una quantità di dati pari a tre volte questa dimensione è cifrata, per ogni\r\nfile.\r\nthr. Numero di thread worker da creare. NetWalker usa una sistema di task per cifrare i file. Dei thread\r\nenumerano i file e altri thread li cifrano. Questo è il numero massimo di thread in totale (esclusi i thread fissi che\r\nfanno altro).\r\nidsz. Lunghezza dell’identificativo di ogni vittima. L’identificativo è usato per calcolare l’estensione dei file\r\ncifrati e per la decifratura dei file in automatico nell’infrastruttura dei criminali.\r\nL’identificativo è, la prima parte del CRC32, convertito in hex, della chiave pubblica X25519 associata alla chiave\r\nsegreta del punto mpk. Questo campo indica quanti caratteri della stringa esadecimale prendere.\r\nencname. Se settato a vero, i nomi dei file sono a loro volta cifrati. NetWalker appende ad ogni file un payload,\r\ncifrato (vedi sotto), che contiene, tra l’altro, il nome originale del file.\r\nonion1, onion2. I due siti, hidden service, per il pagamento del riscatto.\r\nlfile. Template per il nome del file del riscatto. Le entità tra parentesi graffe sono sostituite con appositi valori. In\r\nquesto caso {id} è l’id indicato nel punto idsz.\r\nlend. Template, in base64, per il contenuto del file di riscatto. Un estratto è contenuto ad inizio news. Questo file\r\ncontiene l’entità {code} che verrà sostituita con un JSON necessario per il download del decryptor (una volta\r\npagato).\r\nwhite. Un oggetto che indica quale cartelle (path), file (file ed extfree) o estensioni (ext) non cifrare. L’obiettivo\r\nè evitare la compromissione della macchina vittima, in modo da permettergli il pagamento.\r\nkill. Se abilitato (use), indica quali processi (prc), servizi (svc) e task di Windows (task) terminare. Questi\r\ncontrolli sono fatti in thread appositi, fatti partire dopo un’attesa di svcwait secondi.\r\nnet. Se abilitato (use) indica di enumerare le risorse di rete eventualmente (ignore.use) ignorando determinate\r\ncondivisioni (ignore.share) o i dischi di rete (ingore.disk).\r\nunlocker. Se abilitato (use) indica di tentare di sbloccare un file in uso enumerando tutti gli handle ed i relativi\r\nprocessi, eventualmente (ignore.use) tranne quelli il cui file (ignore.pspath) o nome (ignore.prc), e chiudendo i\r\nprimi.\r\nLa configurazione JSON non è di immediato utilizzo per un programma scritto in C o affini. Questa viene\r\nconvertita in un formato nativo e salvata in un buffer, rinominato configBuffer.\r\nNetWalker utilizza spesso buffer allocati dinamicamente per contenere le sue strutture. Avere la “mappa\r\ngeografica” di questi buffer è di fondamentale importanza per l’analisi del ransomware.\r\nhttps://cert-agid.gov.it/news/netwalker-il-ransomware-che-ha-beffato-lintera-community/\r\nPage 17 of 43\n\nÈ importante in questo caso l’intuito e l’esperienza dell’analista per individuare le funzioni chiave del parsing. Ad\r\nesempio la funzione seguente è facilmente identificata come quella responsabile di fare il parsing della stringa\r\nJSON e ritornare una struttura dati apposita.\r\nAnalizzando la funzione che abbiamo chiamato parseJSON (mostrata in miniatura) è possibile\r\nrendersi conto, per via delle costanti usate, che si tratta di codice per il parsing di JSON.\r\nIn linguaggi in cui l’allocazione di memoria è lasciata al programmatore ed i tipi sono statici, un oggetto JSON,\r\nuna volta parsato, si manipola tramite una serie di funzioni accessor.\r\nCi aspettiamo quindi delle funzioni che, dato l’oggetto del tipo ritornato dalla funzione di prima, possano accedere\r\nalle sue proprietà oppure che consentano di ottenerne il valore nativo (nel caso sia una stringa, intero, booleano o\r\narray).\r\nCi aspettiamo inoltre che per ogni tipo JSON ci sia una corrispondente funzione accessor e che il risultato sia in\r\nformato nativo (quindi stringhe C o array ed interi nativi).\r\nLe nostre aspettative non si dimostrano sbagliate e possiamo identificare e rinominare facilmente le funzioni usate.\r\nhttps://cert-agid.gov.it/news/netwalker-il-ransomware-che-ha-beffato-lintera-community/\r\nPage 18 of 43\n\nLa creazione ed il primo popolamento del buffer di configurazione configBuffer. Inoltre una delle\r\nfunzioni accessor usate per manipolare JSON.\r\nhttps://cert-agid.gov.it/news/netwalker-il-ransomware-che-ha-beffato-lintera-community/\r\nPage 19 of 43\n\nUn esempio di accesso al valore di un campo JSON, come ci aspettavamo esiste l’apposita\r\nfunzione. Una analoga esiste per gli altri tipi JSON.\r\nRinominate le funzioni, risulta facile creare una mappa del configBuffer.\r\nhttps://cert-agid.gov.it/news/netwalker-il-ransomware-che-ha-beffato-lintera-community/\r\nPage 20 of 43\n\nFormat is XX: YYYY where XX is the offset of the field (in hex) and YYYY its description.\r\nAll values are native. The arrays hold native data too.\r\n00: JSON object\r\n04: ptr to mpk (decoded from base64)\r\n08: CRC32(mpk)\r\n0c: mode\r\n10: spsz\r\n14: spsz * 5\r\n18: thr\r\n1c: idsz\r\n20: encname\r\n24: ptr to lfile\r\n28: ptr to onion1\r\n2c: ptr to onion2\r\n30: ptr to lend (decoded from base64)\r\n34: ptr to array white.path\r\n38: # array white.path\r\n3c: ptr to array white.file\r\n40: # array white.file\r\n44: ptr to array white.ext\r\n48: # array white.ext\r\n4c: ptr to array white.extfree\r\n50: # array white.extfree\r\n54: kill.use\r\n58: kill.svcwait\r\n5c: ptr to array kill.prc\r\n60: # array kill.prc\r\n64: ptr to array kill.svc\r\n68: # array kill.svc\r\n6c: ptr to array kill.task\r\n70: # array kill.task\r\n74: net.use\r\n78: net.ignore.use\r\n7c: net.ignore.disk\r\n80: ptr array net.ignore.share\r\n84: # array net.ignore.share\r\n88: unlocker.use\r\n8c: unlocker.ignore.use\r\n90: ptr array unlocker.ignore.pspath\r\n94: # array unlocker.ignore.pspath\r\n98: ptr array unlocker.ignore.prc\r\n9c: # array unlocker.ignore.prc\r\nGenerazione delle chiavi e preparazione alla cifratura\r\nhttps://cert-agid.gov.it/news/netwalker-il-ransomware-che-ha-beffato-lintera-community/\r\nPage 21 of 43\n\nQuesta è la parte più complessa da analizzare, poichè l’implementazione delle primitive crittografiche è molto\r\nottimizzata ed il loro riconoscimento richiede un’ottima conoscenza dei loro principi di implementazione non solo\r\nteorici ma anche pratici (tipo le implementazioni branchless usate per evitare attacchi side-channel).\r\nNetWalker utilizza il classico doppio schema a crittografia simmetrica (autenticata) ed asimmetrica.\r\nLa cifratura simmetrica impiega ChaCha8 per la confidenzialità (ovvero per cifrare) ed HMAC-SHA256 per\r\nl’integrità (ovvero per evitare la manipolazione del payload).\r\nLa chiave segreta usata nella cifratura simmetrica è generata tramite Diffie-Hellman, in particolare tramite una\r\nforma di IES che impiega X25519 (conosciuto anche come Curve25519).\r\nLa chiave è generata come segreto condiviso a partire dalla chiave pubblica dei criminali (mpk) e da una seconda\r\nchiave segreta effimera (vedi dettagli sotto).\r\nLe primitive e la loro identificazione nel codice.\r\n🤖 Questa parte è particolarmente densa e rivolta a chi è interessato alle evidenze per la verifica delle\r\nprimitive usate.\r\nLa primitiva più semplice da identificare è SHA256, per via delle costanti usate per l’inizializzazione.\r\nL’inizializzazione dello stato SHA256\r\nSHA256 è usata in due contesti: il primo è nell’HMAC-SHA256 (a cui da il nome) e l’altro per la generazione\r\ndell’IV per chacha.\r\nIn quest’ultimo contesto il valore ottenuto è leggermente modificato, come vedremo.\r\nhttps://cert-agid.gov.it/news/netwalker-il-ransomware-che-ha-beffato-lintera-community/\r\nPage 22 of 43\n\nDato che molto probabilmente NetWalker è scritto in C o affini, ci aspettiamo di trovare le usuali funzioni di init,\r\nupdate e finalize di un hash.\r\nIdentificarle aiuterà ad etichettare la prossima primitiva: HMAC-SHA256.\r\nLe tre funzioni di generazione di un hash, una volta identificate\r\nHMAC si può riconoscere dalle costanti di padding interno ( 0x36 ripetuto) ed esterno ( 0x5c ripetuto).\r\nLe due constanti di padding.\r\nHMAC-SHA256 è usato nella stessa funzione che effettua la cifratura simmetrica, rinominata\r\nHMAC_and_encrypt , e si basa sull’utilizzo di una funzione hmac_internal che inizia (ma non termina) il calcolo\r\ndell’hash interno e di una funzione hmac_outer che calcola l’hash esterno.\r\nhttps://cert-agid.gov.it/news/netwalker-il-ransomware-che-ha-beffato-lintera-community/\r\nPage 23 of 43\n\nUn frammento del codice per la cifratura autenticata simmetrica. Si vedono le funzioni per il calcolo\r\ndell’HMAC e per la cifratura.\r\nNel codice sopra si possono indentificare le funzioni ChaCha, che inizialmente avevamo incorrettamente\r\nidentificato come salsa20.\r\nQueste si riconoscono per via di come è inizializzato lo stato.\r\nhttps://cert-agid.gov.it/news/netwalker-il-ransomware-che-ha-beffato-lintera-community/\r\nPage 24 of 43\n\nLa stringa evidenziata sono in realtà 4 DWORD scelte da D.J. Bernstein\r\nLa stringa mostrata sopra indica che siamo in presenza di Salsa20 o ChaCha. Il layout in memoria dello stato ha\r\npermesso di identificare le funzioni come implementazioni di ChaCha e non di Salsa20 (confermato poi\r\nsperimentalmente).\r\nChaCha infatti salva la stringa in modo continuo nel suo stato, il popolamento dello stato ha permesso di\r\nidentificare la funzione per il setup della chiave e dell’IV e, per esclusione, quella di cifratura.\r\nL’ultima primitiva usata da NetWalker è X25519. Ci sono due elementi chiave per la sua identificazione.\r\nIl primo è che le viene passato un buffer, di 32 byte, riempito di zeri tranne per il primo byte, che ha valore 9.\r\nUn buffer di 32 byte composto da un 9 seguito da zeri è molto probabilmente il punto iniziale in una\r\ncurva ellittica\r\nhttps://cert-agid.gov.it/news/netwalker-il-ransomware-che-ha-beffato-lintera-community/\r\nPage 25 of 43\n\nL’altro elemento, forse più decisivo, è l’operazione di clamping fatta sul secondo buffer passato alla funzione.\r\nI valori 248, 63 e 64 sono decisivi per identificare la primitiva.\r\nIl clamping è tipico di X25519 (ed Ed25519) ed insieme al punto iniziale di valore 9, permettono di identificare la\r\nprimitiva come X25519.\r\nX25519 e le altre primitive\r\nRispolverando le proprietà di X25519, almeno quelle usate da NetWalker, possiamo dire che:\r\nLa primitiva X25519(SK, Base) prende in input un intero (SK) ed un punto sulla curva (Base) e ritorna il loro\r\nprodotto.\r\nQuesta viene usata per generare un segreto in comune tra due comunicanti remoti senza che esso sia trasmesso o\r\nche sia calcolabile dalle informazioni trasmesse.\r\nIl classico uso del problema del logaritmo discreto ma applicato a questa specifica curva ellittica.\r\nPer generare una coppia di chiavi si usa:\r\nSKA = 32 byte random\r\nPKA = X25519(SKA, B9)\r\ndove B9 è il punto di valore 9.\r\nSupposto che Alice e Bob abbiamo una coppia di chiavi chiascuno:\r\nSKA = 32 byte random\r\nPKA = X25519(SKA, B9)\r\nSKB = 32 byte random\r\nPKB = X25519(SKB, B9)\r\nquesti possono generare un valore segreto comune (da usare come chiave simmetrica) solo scambiandoli le chiavi\r\npubbliche:\r\nshared = X25519(SKA, PKB) Alice\r\nshared = X25519(SKB, PKA) Bob\r\nNetWalker combina le primitive in due funzioni di alto livello:\r\nhash = SHA256p1(m). E’ lo SHA256 di m ma il primo byte dell’hash è incrementato di uno. Solo il primo byte è\r\nincrementato, con un’addizione modulo 28 (in pratica è usata l’istruzione inc BYTE [...] ).\r\nSHA256p1(m):\r\n hash[32] = SHA256(m)\r\nhttps://cert-agid.gov.it/news/netwalker-il-ransomware-che-ha-beffato-lintera-community/\r\nPage 26 of 43\n\nhash[0] += 1\r\n return hash\r\npk, h, shared = computeShared_Hash_Pk(pk_in). Ha il compito di generare una nuova coppia di chiavi (pk,\r\nsk), di ottenere un valore condiviso shared da (sk e pk_in) e di calcolare lo SHA256p1 di shared.\r\nmake_sk():\r\n rnd = RtlRandomEx if os_version \u003e 0x51 else RtlRandom\r\n seed = GetSystemTimeAsFileTime()\r\n return [rnd(seed) for _ in range(32)]\r\ncomputeShared_Hash_Pk(pk_in):\r\n sk[32] \u003c- make_sk()\r\n pk = X25519(sk, B9)\r\n shared = X25519(sk, pk_in)\r\n h = SHA256p1(shared)\r\n return pk, h, shared\r\n \r\nAbbiamo introdotto la funzione make_sk() per facilità di notazione futura, in quanto NetWalker usa sempre questo\r\nmetodo per la generazione di chiavi segrete. Usiamo inoltre la notazione \u003c- e non = per l’assegnazione, a\r\nrimarcare la natura casuale della funzione make_sk() .\r\nLa chiave segreta è generata salvando l’ora di sistema come ritornata da GetSystemTimeAsFileTime ed usando\r\nRtlRandomEx (o RtlRandom , in versioni di Windows più vecchie).\r\nhmac, c = HMAC_and_encrypt(key, iv, data, len). Cifra data usando ChaCha e la chiave e l’IV passati (solo i\r\nprimi 8 byte, gli altri non servono). Inoltre calcola l’HMAC di data usando la chiave passata.\r\nHMAC_and_encrypt(key, iv, data, len):\r\n c = chacha8(key = key, iv = iv[0..8], data, len)\r\n hmac = hmac_sha256(key = key, data, len)\r\n return hmac, c\r\nLa chiave segreta e gli altri buffer\r\nCome visto nel punto precedente X25519 non permette di cifrare, è una primitiva usata per lo scambio di chiavi.\r\nIn preparazione per la fase di cifratura, NetWalker genera una chiave segreta e la relativa chiave pubblica.\r\nsecret1 \u003c- make_sk()\r\npk1 = X25519(secret1, B9)\r\ncrc_pk1 = CRC32(pk1)\r\nhttps://cert-agid.gov.it/news/netwalker-il-ransomware-che-ha-beffato-lintera-community/\r\nPage 27 of 43\n\nPK1 sarà la chiave pubblica usata per generare la chiave di cifratura di ogni file. Vedremo che al momento di\r\ncifrare un file, una coppia di chiavi (PKF, SKF) è generata per quel file ed un segreto sharedF = X25519(SKF,\r\nPK1) è ottenuto per essere usato come chiave ChaCha.\r\nIl CRC32 (calcolato usando RtlComputeCrc32 ) è usato per il check, lato attaccanti, dei dati ricevuti.\r\nRisulta quindi necessario conoscere secret1 per riottenere lo stesso segreto a partire da PKF. (SKF non è mai\r\nsalvata, e risulta essere, di fatto, una chiave effimera).\r\nsecret1 è l’unica chiave segreta non effimera, cioè effettivamente necessaria e recuperabile dai criminali.\r\nPer trasmetterla a loro viene quindi cifrata a sua volta. Questo è fatto generando un’altra coppia di chiavi ed\r\nusando mpk per generare un segreto comune con i criminali.\r\nL’uso delle funzioni di alto livello viste sopra è uniforme in tutto NetWalker ed ha sempre la forma mostrata qui\r\nsotto.\r\npk2, h_shared1, shared1 = computeShared_Hash_Pk(mpk)\r\nshared1 è l’altro segreto di vitale importanza, esso è usato per cifrare secret1:\r\nhmac_secret1, e_secret1 = hmac_and_encrypt(shared1, h_shared1, secret1, 0x20)\r\nhttps://cert-agid.gov.it/news/netwalker-il-ransomware-che-ha-beffato-lintera-community/\r\nPage 28 of 43\n\nLa generazione di secret1, di shared1 per la cifratura del primo, del CRC32 di PK1 e la cifratura\r\nstessa di secret1.\r\nIl ransomware procede adesso con la creazione di quattro buffer, che abbiamo rinominato: buffer5C, buffer6C,\r\nbufferVar e bufferP50.\r\nIl primo è un buffer di lavoro usato estensivamente da NetWalker, gli altri tre sono buffer temporanei usati per la\r\ncreazione del JSON misterioso (che risulterà essere proprio il base64 di bufferP50).\r\nIniziamo con il buffer6C poichè è quello più immediato ed è linkato a buffer5C . Il codice che lo genera è\r\ndentro la stessa funzione che genera le chiavi sopra.\r\nhttps://cert-agid.gov.it/news/netwalker-il-ransomware-che-ha-beffato-lintera-community/\r\nPage 29 of 43\n\nCreazione e popolamento del buffer6C\r\nIl buffer ha il seguente layout.\r\nFormat is XX: YYYY where XX is the offset of the field (in hex) and YYYY its description.\r\nAll values are native. The arrays hold native data too.\r\n00-04: CRC32(pk1)\r\n04-24: pk2\r\n24-2c: h_shared1\r\n2c-4c: hmac_secret1\r\n4c-6c: e_secret1\r\nbuffer6C è quindi fondamentale per il recupero di secret1.\r\nInfatti tramite shared1 = X25519(SKcrim, PK2) è possibile ottenere shared1, decifrare secret1 con secret1 =\r\nhttps://cert-agid.gov.it/news/netwalker-il-ransomware-che-ha-beffato-lintera-community/\r\nPage 30 of 43\n\nchacha8(key = shared1, iv = h_shared1, data = e_secret1, len = 0x20), verificarne la correttezza con HMAC-SHA256(secret1) == hmac_secret1 e tramite il controllo aggiuntivo CRC32(X25519(secret1, B9)) ==\r\nCRC32(pk1).\r\nPermette quindi ai criminali di riottenere tutte le chiavi necessarie alla decifratura dei file.\r\nIl buffer6C è salvato nel buffer5C, quest’ultimo è usato frequentemente e contiene valori utili al malware.\r\nNe riportiamo una mappa, il suo popolamento avviene dentro la funzione prepareForEncryption e non presenta\r\ngrosse difficoltà per l’analista.\r\nFormat is XX: YYYY where XX is the offset of the field (in hex) and YYYY its description.\r\nAll values are native. The arrays hold native data too.\r\n00: OS major\r\n04: OS minor\r\n08: is WOW64 process\r\n0c: -\r\n10: current process id\r\n14: idsz\r\n18: hex(crc32(pk1))[0..idsz]\r\n1c: same as 0x18 but in unicode\r\n20: will be pupulated with net names\r\n24: len of the buffer at 0x20\r\n28: CRC32(mpk)\r\n2c: mpk\r\n30: CRC32(pk1)\r\n34: pk1\r\n38: size of buffer6C (which is 0x6c)\r\n3c: ptr buffer6C\r\n40: len of str at 0x44\r\n44: unicode str for ., where is str at 0x1c\r\n48: lfile string, interpolated, len\r\n4c: lfile string, interpolated\r\n50: lfile string, interpolated with * as {id}\r\n54: lend string, interpolated, len\r\n58: lend string, interpolated\r\nI valori nel buffer5C sono tutti di immediata comprensione, eccetto forse per quelli descritti come\r\n“interpolated”.\r\nCon questo nome si intende il valore ottenuto da una stringa con placeholder del tipo {id} o simili, una volta\r\nsostituito a questi un valore.\r\nAd esempio {id}-Readme.txt , una volta interpolato, può divenire 24138-ReadMe.txt .\r\nIl nome si rifà alla funzionalità di string interpolation di molti linguaggi moderni.\r\nLa stringa all’offset 0x50 , ovvero *-Readme.txt (secondo la configurazione mostrata all’inizio), è usata per\r\nhttps://cert-agid.gov.it/news/netwalker-il-ransomware-che-ha-beffato-lintera-community/\r\nPage 31 of 43\n\ncontrollare se nella directory di un file appena cifrato è già presente il manifesto per il riscatto (ed eventualmente\r\ncrearlo).\r\nAltro valore importante è la stringa a 0x18 , ovvero il CRC32(pk1) convertito in hex e troncato ai primi idsz\r\ncaratteri.\r\nQuesto è l’id della vittima, lo chiameremo, appunto, id nel seguito.\r\nUna volta preparato il buffer5C , NetWalker scrive il contenuto del manifesto per il riscatto. In particolare ci\r\ninteressa il campo {code} che viene riempito con un JSON.\r\nViene prima creato il bufferVar , di dimensione idsz + 0x74 + strlen(lfile), così fatto:\r\nFormat is XX: YYYY where XX is the offset of the field (in hex) and YYYY its description.\r\nAll values are native. The arrays hold native data too.\r\n00: copy of buffer6C\r\n6C: idsz (i.e. len of victim's id)\r\n70: victim's id\r\n74: len of lfile\r\n78: lfile\r\nQuesto buffer contiene il buffer6C e qualche informazione in più, necessarie ai criminali per sapere quale\r\nestensione hanno i file cifrati (in modo da poterli enumerare) e come si chiamano i file di manifesto (in modo da\r\npoterli rimuovere).\r\nQuesto buffer è essenzialmente il contenuto del JSON contenuto nel manifesto ma non così come mostrato.\r\nPer qualche motivo infatti bufferVar è cifrato ancora una volta:\r\npk3, h_shared2, shared2 = computeShared_Hash_Pk(mpk)\r\nhmac_buffer_var, e_buffer_var = hmac_and_encrypt(key = shared2, iv = h_shared2, data = bufferVar, len = len(buff\r\nViene, infine creato l’ultimo buffer, bufferP50 , che contiene le informazioni per decifrare bufferVar (il quale\r\ncontiene le informazioni per cifrare secret1, che serve per decifrare i file):\r\nFormat is XX: YYYY where XX is the offset of the field (in hex) and YYYY its description.\r\nAll values are native. The arrays hold native data too.\r\n00: h_shared2\r\n08: hmac_buffer_var\r\n28: pk3\r\n48: CRC32(mpk)\r\nhttps://cert-agid.gov.it/news/netwalker-il-ransomware-che-ha-beffato-lintera-community/\r\nPage 32 of 43\n\n4c: CRC32(pk1)\r\n50: e_buffer_var\r\nGli attaccanti possono generare shared2 = X25519(SKcrim, pk3) e decifrare il bufferVar.\r\nIl bufferP50 è convertito in base64, diviso in linee di 50 caratteri e poi usato per generare il JSON dalla forma\r\n{code_\u003cid\u003e: base64(bufferP50)} .\r\nhttps://cert-agid.gov.it/news/netwalker-il-ransomware-che-ha-beffato-lintera-community/\r\nPage 33 of 43\n\nhttps://cert-agid.gov.it/news/netwalker-il-ransomware-che-ha-beffato-lintera-community/\r\nPage 34 of 43\n\nLa generazione del JSON misterioso. Con tutte le primitive identificate, la sua analisi è banale.\r\nDi seguito un riepilogo.\r\nLa struttura del JSON da inviare ai criminali affinchè possano decifrare i file\r\nIl flusso di lavoro del malware\r\nUna volta preparate le chiavi per la cifratura, il flusso di lavoro del malware è abbastanza immediato.\r\nhttps://cert-agid.gov.it/news/netwalker-il-ransomware-che-ha-beffato-lintera-community/\r\nPage 35 of 43\n\nIl flusso di lavoro. Nella parte finale, non mostrata, il malware prova a scrivere il manifesto nel\r\ndesktop e nelle root dei dischi impersonando explorer.exe (sebbene sia già eseguito nel contesto di\r\nquesto)\r\nLe operazioni del malware sono, in ordine:\r\nAcquisizione dei privilegi di Debug e impersonificazione di altri processi.\r\nAvvio dei thread per la terminazione dei processi (usando NtQuerySystemInformation), dei servizi (usando le\r\nAPI del service manager) e dei task (usando l’interfaccia come ITaskService) indicati nella configurazione.\r\nControllo della presenza di file in uso da altre applicazioni. Il controllo avviene usando\r\nNtQuerySystemInformation , con classe 0x10 per ottenere tutti gli handle aperti, duplicando ognuno di essi e\r\nverificando se è possibile mapparne un byte. Questo controllo serve a considerare solo gli handle di tipo file.\r\nRecupero del token di explorer.exe. per fare ciò il malware usa GetSystemInformation per enumerare tutti i\r\nprocessi. Prima impersona winlogon.exe e dopo recupera il token di explorer.\r\nAvvio dei thread di lavoro. Viene inizializzata una lista doppia concatenata che contiene, per ogni elemento, un\r\npuntatore alla procedura da eseguire ed un puntatore ai dati di questa.\r\nVengono poi creati due thread: uno consuma un elemento dalla lista (se presente) e crea un nuovo thread se il\r\nnumero totale di thread non supera quello indicato dalla configurazione. L’altro thread rimuove i thread finiti\r\nhttps://cert-agid.gov.it/news/netwalker-il-ransomware-che-ha-beffato-lintera-community/\r\nPage 36 of 43\n\n(scorrendo il buffer con i loro handle ed usando WaitForSingleObject ) e decrementa il conteggio, permettendo\r\nla creazione di nuovi thread.\r\nLa creazione dei due thread: uno per il dispatch ed uno per rimuovere i thread terminati\r\nAl momento non vi è ancora lavoro per i thread.\r\nViene creato un file di manifesto per il riscatto nel desktop ed aperto con notepad.\r\nEnumera i dischi locali e di rete e per ognuno di essi avvia un task di cifratura.\r\nhttps://cert-agid.gov.it/news/netwalker-il-ransomware-che-ha-beffato-lintera-community/\r\nPage 37 of 43\n\nL’enumerazione dei dischi e i relativi task di cifratura\r\nIl task per la cifratura dei dischi si aspetta come parametro un percorso (inizialmente le root dei dischi) ed usa\r\nFindFirstFileEx per enumerare tutte le cartelle ed i file in questo percorso.\r\nPer le cartelle, crea un nuovo task con il loro percorso mentre per i file chiama la procedura di cifratura.\r\nhttps://cert-agid.gov.it/news/netwalker-il-ransomware-che-ha-beffato-lintera-community/\r\nPage 38 of 43\n\nUna parte della funzione di cifratura di un percorso, si vedono il passo ricorsivo (al centro in basso)\r\ne quello terminale. Inoltre è presente il controllo della whitelist in configurazione\r\nLa cifratura di un file\r\nNel file IDA allegato, la funzione di cifratura è chiamata CryptFile , e poichè piuttosto verbosa e lunga non\r\nmostriamo qui lo screenshot, ma ci limitiamo a descriverne il comportamento:\r\n1. Gli attributi originali del file sono salvati e poi cambiati in FILE_ATTRIBUTE_ARCHIVE .\r\n2. Il file è aperto con CreateFileW e, se questa fallisce, viene usata la procedura di unlocking (Se\r\nconfigurata).\r\nQuesta enumera tutti gli handle, considera solo quelli di tipo file e che non appartengono ai processi come\r\nindicato in configurazione, trova l’handle interessato e lo duplica chiudendolo nel processo sorgente (con\r\nNtDuplicateHandle ) 0 chiudendolo poi definitivamente.\r\nLa cifratura è riprovata.\r\n3. Viene recuperata la dimensione del file.\r\n4. Viene letta l’ultima DWORD del file, se questa è CRC32(pk1), il file è saltato. Questo controllo è fatto per\r\nsaltare i file già cifrati.\r\n5. In base alla dimensione del file viene scelto un modo (a meno che la configurazione non forzi un modo\r\ndiverso da 0).\r\nIl modo 0 cifra tre parti del file di dimensione spsz: una all’inizio, una a metà (all’offset: [(spsz + size /\r\n2 - 1) / spsz] * spsz , che è una metà arrotondata per eccesso) ed una alla fine.\r\nhttps://cert-agid.gov.it/news/netwalker-il-ransomware-che-ha-beffato-lintera-community/\r\nPage 39 of 43\n\nIl modo 1 è come il modo 0 ma cifra solo la parte all’inizio del file.\r\nIl modo 2 cifra tutto il file.\r\n6. La cifratura è fatta di ogni singolo pezzo usando le chiavi:\r\npkF, h_sharedF, sharedF = computeShared_Hash_Pk(pk1)\r\nogni pezzo è cifrato usualmente e riscritto inplace nel file\r\nhmac_pezzo, pezzo_cifrato= hmac_and_encrypt(key = sharedF, iv = h_sharedF, data =\r\npezzo_in_chiaro, len = len(pezzo_in_chiaro))\r\nGli HMAC sono collezionati in un buffer apposito.\r\n7. Viene generato un buffer (detto bufferX) contenente\r\n00: len id\r\n04: id\r\nXX: len of file original basename\r\nXX: file original basename\r\nQuesto buffer è necessario per riottenere il nome originale del file, nel caso la cifratura dei nomi dei file sia\r\nattivata nella configurazione.\r\nQuesto buffer è cifrato con le stesse chiave, generate al punto 6, usate per cifrare i dati del file.\r\n8. Viene creato un buffer, poi scritto alla fine del file, che ha la struttura:\r\nXX: bufferX encrypted\r\nXX: len of buffer\r\nXX: hmac bufferX\r\n-b8: hmacs of the encrypted file parts\r\n-98: h_sharedF\r\n-94: mode used\r\n-90: spsz used\r\n-24: buffer6C\r\n-04: pkF\r\n-00: CRC32(mpk)\r\nIl buffer contiene pkF, necessaria per la decifratura del file (vedi sotto). Contiene inoltre tutte le\r\ninformazioni su quali parti sono state cifrate, i loro HMAC e il CRC32 di mpk, per indicare che il file è già\r\nstato cifrato.\r\nNotare che il buffer è strutturato per essere letto al contrario, dalla file del file verso l’inizio.\r\nInfine questo buffer contiene buffer6C , permettendo ai criminali di decifrare i file caricati, come prova\r\ndella loro “onestà”.\r\n9. Il file viene rinominato (eventualmente cifrando il suo nome, se attivato dalla configurazione) per includere\r\nl’estensione .\u003cid\u003e.\r\n10. Se nella cartella del file non è già presente un manifesto per il riscatto, questo viene creato.\r\n11. Gli attributi originali del file sono ripristinati.\r\nPer decifrare un file è necessario conoscere sharedF, siccome questa è generata con PK1, è possibile ottenerla\r\ncon:\r\nsharedF = X25519(secret1, pkF)\r\nhttps://cert-agid.gov.it/news/netwalker-il-ransomware-che-ha-beffato-lintera-community/\r\nPage 40 of 43\n\nper cui secret1 è la chiave necessaria per la decifratura dei file e questo spiega il motivo per cui è stata cifrata con\r\ntanta cura nella preparazione.\r\nhttps://cert-agid.gov.it/news/netwalker-il-ransomware-che-ha-beffato-lintera-community/\r\nPage 41 of 43\n\nhttps://cert-agid.gov.it/news/netwalker-il-ransomware-che-ha-beffato-lintera-community/\r\nPage 42 of 43\n\nLa struttura, semplificata, di un file cifrato da NetWalker\r\nEsiste la possibilità di un decryptor?\r\nLa risposta è: No!\r\nLa generazione di secret1 usa GetSystemTimeAsFileTime come seed, ci si può chiedere se sia possibile\r\npredisporre un attacco bruteforce.\r\nIn fin dei conti, poco dopo la generazione di secret1 viene creato il file di manifesto nel desktop, per cui la sua\r\ndata di creazione non sarà mai troppo lontana dal seed usato (probabilmente un secondo, pari a 10 milioni di\r\npossibili valori di seed, è sufficiente).\r\nUn analista può recuperare dalla vittima il valore CRC32(pk1), ed enumerare tutti i valori del seed fino a che\r\nCRC32(X25519(make_sk(candidate_seed), B9)) non è uguale al valore recuperato.\r\nNel caso lo sia, si può procedere alla conferma, generando sharedF = X25519(make_sk(candidate_seed), pkF) e\r\nverificando se i pezzi sono stati correttamente decifrati (grazie agli HMAC).\r\nTuttavia RtlRandomFunctionEx non usa solo il seed per generare il numero casuale.\r\nEssa ha un pool di entropia di 128*4 byte e quindi non è possibile solo dal seed riottenere la stessa sequenza di\r\nnumeri casuali usata da NetWalker.\r\nL’implementazione di RtlRandomEx\r\nI database IDA\r\nCondividiamo per comodità i DB IDA utilizzati, per facilitare il lettore nel seguire l’articolo.\r\nLink: Scarica i DB IDA\r\nSource: https://cert-agid.gov.it/news/netwalker-il-ransomware-che-ha-beffato-lintera-community/\r\nhttps://cert-agid.gov.it/news/netwalker-il-ransomware-che-ha-beffato-lintera-community/\r\nPage 43 of 43\n\n4c-6c: e_secret1 buffer6C è quindi fondamentale per il recupero di secret1.   \nInfatti tramite shared1 = X25519(SKcrim, PK2) è possibile ottenere shared1, decifrare secret1 con secret1 =\n   Page 30 of 43",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"references": [
		"https://cert-agid.gov.it/news/netwalker-il-ransomware-che-ha-beffato-lintera-community/"
	],
	"report_names": [
		"netwalker-il-ransomware-che-ha-beffato-lintera-community"
	],
	"threat_actors": [],
	"ts_created_at": 1775434725,
	"ts_updated_at": 1775791296,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/517fe9a301b2dc7c82b81fdebfa81c46cb23c810.pdf",
		"text": "https://archive.orkl.eu/517fe9a301b2dc7c82b81fdebfa81c46cb23c810.txt",
		"img": "https://archive.orkl.eu/517fe9a301b2dc7c82b81fdebfa81c46cb23c810.jpg"
	}
}