From 533e7dfd15c61d67a742820db8175caddc860119 Mon Sep 17 00:00:00 2001 From: 87owo <85057800+87owo@users.noreply.github.com> Date: Fri, 23 Jan 2026 13:49:06 +0800 Subject: [PATCH] Add files via upload --- Engine/Heuristic/Rules_General_A1.yar | 1439 +++++++++++++++++++++++++ Engine/Pattern/convert.py | 55 + Engine/Pattern/deduplicate.py | 34 + Engine/Pattern/train.py | 163 +++ Engine/Properties/convert.py | 513 +++++++++ Engine/Properties/train.py | 195 ++++ 6 files changed, 2399 insertions(+) create mode 100644 Engine/Heuristic/Rules_General_A1.yar create mode 100644 Engine/Pattern/convert.py create mode 100644 Engine/Pattern/deduplicate.py create mode 100644 Engine/Pattern/train.py create mode 100644 Engine/Properties/convert.py create mode 100644 Engine/Properties/train.py diff --git a/Engine/Heuristic/Rules_General_A1.yar b/Engine/Heuristic/Rules_General_A1.yar new file mode 100644 index 0000000..bc7a446 --- /dev/null +++ b/Engine/Heuristic/Rules_General_A1.yar @@ -0,0 +1,1439 @@ +import "pe" + +rule General_1 { + meta: + description = "1" + author = "PYAS Security" + date = "2024-06-12" + strings: + $x1 = "System.Object, mscorlib, Version=" ascii + $x2 = ".pdb" ascii + $x3 = "System.Drawing" ascii + $s1 = "a2VybmVsMzIuZGxs" fullword wide + $s2 = "RnJlZUNvbnNvbGU=" fullword wide + $s3 = "Paleozoologist Timpanist Troubling" ascii + $s4 = "Paleozoologist Timpanist Troubling" wide + $s5 = "Levitating" fullword ascii + $s6 = ".Properties" ascii + $s7 = "PublicKeyToken" ascii + $s8 = "helpToolStripButton.Image" fullword wide + $s9 = "newToolStripButton.Image" fullword wide + $s10 = "openToolStripButton.Image" fullword wide + $s11 = "printToolStripButton.Image" fullword wide + $s12 = "printPreviewToolStripButton.Image" fullword wide + $s13 = "Extractor" ascii + $s14 = "Congratulations" fullword ascii + $s15 = "Byrnies" fullword wide + $s16 = "showString" fullword ascii + $s17 = "AScsrhgtr" fullword ascii + $s18 = "ZknciocoiAw" fullword ascii + $s19 = "Volute Transitions" fullword wide + $s20 = "IOasuoihciujo" fullword ascii + $s21 = "labelComp" wide + $s22 = "ErrorImage" wide + $s23 = "get_QuestCompletionItems" fullword ascii + $s24 = "get_DropPercentage" fullword ascii + $s25 = "PlayerData.xml" fullword wide + $s26 = "get_LootTable" fullword ascii + $s27 = "get_Potions" ascii + $s28 = "get_CurrentMonster" fullword ascii + $s29 = "MONSTER_ID_RAT" fullword ascii + $s30 = "get_AddExtraNewLine" fullword ascii + $s31 = "get_LootItems" fullword ascii + $s32 = "get_HasAMonster" fullword ascii + $s33 = "get_MinimumDamage" fullword ascii + $s34 = "get_RewardGold" fullword ascii + $s35 = "get_VendorWorkingHere" fullword ascii + $s36 = "get_RewardItem" fullword ascii + $s37 = "get_MaximumDamage" fullword ascii + $s38 = "get_RewardExperiencePoints" fullword ascii + $s39 = "imgur.com" wide + $s40 = "CURD_ALUNOS.md" wide + $s41 = "Parametros.xml" fullword wide + $s42 = "dgEditar_CellContentClick" fullword ascii + $s43 = "dgDados_CellContentClick" fullword ascii + condition: + uint16(0) == 0x5a4d and filesize < 5000KB and + 1 of ($x*) and 8 of them +} + +rule General_2 { + meta: + description = "2" + author = "PYAS Security" + date = "2024-06-12" + strings: + $s1 = "You walk into the" wide + $s2 = "_unprocessedInterAgentMessages" fullword ascii + $s3 = "ProcessAllInterAgentMessages" fullword ascii + $s4 = "AgentsComunnicationExecution" fullword ascii + $s5 = "SendExecuteMessage" fullword ascii + $s6 = "TemporarySetAgentModel" fullword ascii + $s7 = "immediatelyProcess" fullword ascii + $s8 = "ProcessTheMessage" fullword ascii + $s9 = "HoldTarget" ascii nocase + $s10 = "SimulationEngine." ascii + $s11 = "FindAddresseeAgent" ascii + $s12 = "AgentIsAlreadyRegistredException" fullword ascii + $s13 = "MessageTimestampComparer" fullword ascii + $s14 = "startcombat" fullword ascii + condition: + uint16(0) == 0x5a4d and filesize < 5000KB and + 8 of them +} + +rule General_3 { + meta: + description = "3" + author = "PYAS Security" + date = "2024-06-12" + strings: + $x1 = "GrapeCity.ActiveReports.Chart.Win" ascii + $s1 = "ComponentlessCollectionEditor" ascii + $s2 = "LabelsCollectionEditorGrapeCity" ascii + $s3 = "AxesEditor" ascii + $s4 = "AnnotationEditor" ascii + $s5 = "GradientEditor" ascii + $s6 = "DoubleArrayEditor" ascii + $s7 = "LegendsEditor" ascii + $s8 = "DataPointsEditor" ascii + $s9 = "ChartAreasEditor" ascii + $s10 = "AxesSelectEditor" ascii + $s11 = "StyleEditor" ascii + $s12 = "PatternEditor" ascii + condition: + uint16(0) == 0x5a4d and filesize < 30000KB and + $x1 and 8 of them +} + +rule General_4 { + meta: + description = "PYAS_Rules_A4" + author = "PYAS Security" + date = "2024-06-12" + strings: + $x1 = ".Properties" ascii nocase + $x2 = ".Resources" ascii nocase + $s1 = "ListenToAll" fullword ascii + $s2 = "Abberant" fullword ascii + $s3 = "Shlyber" fullword ascii + $s4 = ".exe" wide + $s5 = ".pdb" wide + condition: + uint16(0) == 0x5a4d and filesize < 4000KB and + ($x1 and $x2) and 5 of them +} + +rule General_5 { + meta: + description = "5" + author = "PYAS Security" + date = "2024-06-12" + strings: + $x1 = "Microsoft.VSDesigner.DataSource.Design" ascii + $s1 = "columnPostcode" fullword ascii + $s2 = "GetRealUpdatedRows" fullword ascii + $s3 = "set_Postcode" fullword ascii + $s4 = "System.Drawing.Design.UITypeEditor" fullword ascii + $s5 = "postcodeDataGridViewTextBoxColumn" fullword wide + $s6 = "get_AlexandraDBConnectionString" fullword ascii + $s7 = "SELECT [Number]" wide + $s8 = "Original_Postcode" fullword wide + $s9 = "get_CellPhone" fullword ascii + $s10 = "get_CellPhoneColumn" fullword ascii + $s11 = "postcodeTextBox" fullword wide + condition: + uint16(0) == 0x5a4d and filesize < 5000KB and + $x1 and 3 of them +} + +rule General_6 { + meta: + description = "6" + author = "PYAS Security" + date = "2024-06-12" + strings: + $x1 = "System.Drawing" ascii + $x2 = "PublicKeyToken" ascii + $x3 = "System.Security.Permissions.SecurityPermission" wide + $x4 = "urn:schemas-microsoft-com:asm" ascii + $s1 = "feffeeffeef" ascii + $s2 = "fefefeffefe" ascii + $s3 = "feffefeeffe" ascii + $s4 = "ffeefeffeefa" ascii + $s5 = "ffeeffefeef" ascii + $s6 = "ffeeffeeffe" ascii + $s7 = "ffefeeffefe" ascii + $s8 = "feffefefe" ascii + $s9 = "fefefeffea" ascii + $s10 = "supercommerce@example.com" fullword wide + $s11 = "btnLogin" fullword ascii + $s12 = "loginToolStripMenuItem" fullword wide + $s13 = "loginToolStripMenuItem_Click" fullword ascii + $s14 = "LoginController" fullword ascii + $s15 = "Erro: login Mal Sucedido" fullword wide + $s16 = "Erro de Login" fullword wide + $s17 = "supermercado.Login.resources" fullword ascii + $s18 = "get_Cordinations" fullword ascii + $s19 = "get_Utgivnings" fullword ascii + $s20 = "The Dark Knight" fullword wide + $s21 = "get_Both_Shiled_and_Sword_Hero" fullword ascii + $s22 = "get_Empty_handed_Hero" fullword ascii + $s23 = "LogicValues1" fullword ascii + $s24 = "by adguard" fullword wide + $s25 = "ErrorImage" wide + $s26 = "thedarkknight.jpg" fullword wide + $s27 = "terkomst.jpg" fullword wide + $s28 = "rymdimperiet.jpg" fullword wide + $s29 = "get_Hero_with_shield" fullword ascii + $s30 = "get_PowerOfDistraction" fullword ascii + $s31 = "operationPressed" fullword ascii + $s32 = "get_RadiusOfAttack" fullword ascii + $s33 = "get_FilmNamn" fullword ascii + $s34 = "operatorClick" fullword ascii + $s35 = "get_Hero_with_sword" fullword ascii + $s36 = "CustomImageFormat.txt" wide + $s37 = "get_BeatsPerSecond" fullword ascii + $s38 = "get_BeatPerSecond" fullword ascii + $s39 = "DJ Control" fullword wide + $s40 = "add_BeatChanged" fullword ascii + $s41 = "_presenterModel" fullword ascii + $s42 = "set_BeatsPerSecond" fullword ascii + $s43 = "HandleBeat" fullword ascii + $s44 = "BeatEventArgs" fullword ascii + $s45 = ".NET Framework 4.6l" fullword ascii + $s46 = ".?AV?$IListEnum@PAVECChildEvent@@@bd@@" fullword ascii + $s47 = ".?AV?$_Func_impl_no_alloc@V@@_NABUDllProtectEvent@@@std@@" fullword ascii + $s48 = ".?AV?$_Func_base@_NABUDllProtectEvent@@@std@@" fullword ascii + $s49 = ".?AV?$ListEnum@PAVECChildEvent@@@bd@@" fullword ascii + $s50 = ".?AV?$IConstListEnum@PAVECChildEvent@@@bd@@" fullword ascii + $s51 = ".?AV?$ConstListEnum@PAVECChildEvent@@@bd@@" fullword ascii + $s52 = "labelComp" wide + condition: + uint16(0) == 0x5a4d and filesize < 10000KB and + 1 of ($x*) and 5 of them +} + +rule General_7 { + meta: + description = "7" + author = "PYAS Security" + date = "2024-06-12" + strings: + $s1 = "python3" ascii nocase + $s2 = "_:@:P:H:X:D:T:L:\\:B:R:J:Z:F:V:N:^:A:Q:I:Y:E:U:M:]:C:S:K:[:G:W:O:_" fullword ascii + $s3 = "KkdgJiVj1" fullword ascii + $s4 = "2V1V5V3V7" fullword ascii + $s5 = "Cxz.Yfc" fullword ascii + $s6 = "'7 7$7\"7&7!7%7#7'" fullword ascii + $s7 = "* %\\5?" fullword ascii + $s8 = "xezygjy" fullword ascii + $s9 = "tgkvdjv" fullword ascii + $s10 = "bfDs /nU," fullword ascii + $s11 = "zktmxjuxjeh" fullword ascii + $s12 = "indljaj" fullword ascii + $s13 = "Z t:\"-" fullword ascii + $s14 = "o^EX:\"" fullword ascii + $s15 = "rjF.tNb" fullword ascii + $s16 = "pynput.keyboard._dummy)" fullword ascii + $s17 = "pynput.keyboard._darwin)" fullword ascii + $s18 = "pynput.keyboard)" fullword ascii + $s19 = "pynput.keyboard._uinput)" fullword ascii + $s20 = "pynput.keyboard._win32)" fullword ascii + $s21 = "pynput.keyboard._xorg)" fullword ascii + $s22 = "pynput.keyboard._base)" fullword ascii + condition: + uint16(0) == 0x5a4d and filesize < 50000KB and + 10 of them +} + +rule General_8 { + meta: + description = "8" + author = "PYAS Security" + date = "2024-06-12" + strings: + $x1 = "TASKKILL /F /IM" wide nocase + $x2 = "processhacker" wide nocase + $x3 = "cmd.exe /" wide nocase + $s1 = "SHELL32.dll" wide nocase + $s2 = "mmc.exe" wide nocase + $s3 = "Execute ERROR" fullword wide + $s4 = "WindowsServiceMode.exe" fullword wide + $s5 = "ping 0" wide nocase + $s6 = "Microsoft" wide nocase + $s7 = "shutdown" wide nocase + $s8 = "Download ERROR" fullword wide + $s9 = "Executed As " fullword wide + $s10 = "winmgmts:\\\\.\\root\\SecurityCenter2" fullword wide + $s11 = "ScanProcess" fullword ascii + $s12 = "HKEY_CURRENT_USER\\Software\\" wide nocase + $s13 = "HKEY_LOCAL_MACHINE\\SOFTWARE\\" wide nocase + $s14 = "TerminateProcessPath" ascii nocase + $s15 = "svchost.exe" wide nocase + $s16 = "wscript.exe" wide nocase + $s17 = "Application.exe" fullword ascii + condition: + uint16(0) == 0x5a4d and filesize < 15000KB and + 2 of ($x*) and 6 of them +} + +rule General_9 { + meta: + description = "9" + author = "PYAS Security" + date = "2024-06-12" + strings: + $s1 = "SignalEventHandler" fullword ascii + $s2 = "get_CrossTraffic" fullword ascii + $s3 = "get_BeforeIntersection" fullword ascii + $s4 = "get_InIntersection" fullword ascii + $s5 = "get_CloseToIntersection" fullword ascii + $s6 = "TrafficSignal.Settings" fullword ascii + $s7 = "TrafficSignal.Strategy" fullword ascii + $s8 = "TrafficSignal.Serializers" fullword ascii + $s9 = "lblComputerName" fullword wide + $s10 = "TrafficSignal.Properties.Resources.resources" fullword ascii + $s11 = "TrafficSignal.TrafficSignalForm.resources" fullword ascii + $s12 = "TrafficSignal.Properties" fullword ascii + $s13 = "TrafficSignal.Properties.Resources" fullword wide + $s14 = "get_pmYK" fullword ascii + condition: + uint16(0) == 0x5a4d and filesize < 5000KB and + 6 of them +} + +rule General_10 { + meta: + description = "10" + author = "PYAS Security" + date = "2024-06-12" + strings: + $x1 = "DQuasar.Common" ascii + $x2 = "PublicKeyToken" ascii + $s1 = "GetKeyShareHelloRetryRequest" ascii + $s2 = "GetKeyShareServerHello" ascii + $s3 = "Process already elevated." fullword wide + $s4 = "get_PotentiallyVulnerablePasswords" ascii + $s5 = "GetKeyloggerLogsDirectory" ascii + $s6 = "Gma.System.MouseKeyHook.KeyPressEventArgsExt" ascii + $s7 = "GetKeyloggerLogsDirectoryResponse" ascii + $s8 = "Quasar.Common.Models.FileChunk" ascii + $s12 = "set_PotentiallyVulnerablePasswords" ascii + $s13 = "potentiallyVulnerablePasswords" ascii + $s16 = "getBytesProcessed" ascii + $s17 = "GetPreSharedKeyClientHello" ascii + $s18 = "GetKeyShareClientHello" ascii + condition: + uint16(0) == 0x5a4d and filesize < 20000KB and + ($x1 and $x2) and 6 of them +} + +rule General_11 { + meta: + description = "11" + author = "PYAS Security" + date = "2024-06-12" + strings: + $s1 = "/c schtasks /create /f /sc onlogon /rl highest /tn \"" fullword wide + $s2 = "get_SendSync" fullword ascii + $s3 = "get_SslClient" fullword ascii + $s4 = "kpTBNFtPhayeH" fullword ascii + $s5 = "get_ActivatePong" fullword ascii + $s6 = "Pastebin" fullword wide + $s7 = "GetUtf8Bytes" fullword ascii + $s8 = "Plugin.Plugin" fullword wide + $s9 = "RunAntiAnalysis" fullword ascii + condition: + uint16(0) == 0x5a4d and filesize < 1000KB and + 6 of them +} + +rule General_12 { + meta: + description = "12" + author = "PYAS Security" + date = "2024-06-12" + strings: + $x1 = "-ExecutionPolicy Bypass" wide + $s1 = "shutdown" wide nocase + $s2 = "OfflineKeylogger Not Enabled" fullword wide + $s3 = "Win32_Processor.deviceid" wide + $s4 = "CloseMutex" fullword ascii + $s5 = "AES_Encryptor" fullword ascii + $s6 = "POST / HTTP/1.1" fullword wide + $s7 = "GetHashT" fullword ascii + $s8 = "AES_Decryptor" fullword ascii + $s9 = "PCLogoff" fullword wide + $s10 = "RunShell" fullword wide + $s11 = "HostsMSG" fullword wide + $s12 = "HostsErr" fullword wide + $s13 = "OfflineGet" fullword wide + $s14 = "Content-length:" wide + $s15 = "Mozilla/5.0" wide + condition: + uint16(0) == 0x5a4d and filesize < 30000KB and + 1 of ($x*) and 5 of them +} + +rule General_13 { + meta: + description = "13" + author = "PYAS Security" + date = "2024-06-12" + strings: + $s1 = "xehook.exe" fullword wide + $s2 = "System.Collections.Generic" ascii + $s3 = "" ascii + $s7 = "Confuser.Core 1.6.0+447341964f" fullword ascii + $s8 = "rsqypuz" fullword ascii + $s9 = "scyt6m$!k-}qbwu|ud6m#!k-sctbqs6m\"!k-u}q~s`6 -cbud|yv6m!!k-dhu6m !k-~u{" fullword ascii + $s10 = "s6m%k-u}q~buce6m$k-cuy{" fullword ascii + $s11 = "ETALUME" fullword ascii + $s12 = "EYKLLGJCYEHBODMAHOGOCDNCJABEGNCG" fullword ascii + $s13 = "JGVIWIWIPUVG" fullword ascii + $s14 = "BAAD10E40DF6B5D52A22FCCE498BBD641EBB2377BB7DA4FE04EE26F084647F69" ascii + $s15 = "(&'(/- /.,$ $, & */! .('% ,#$+(" fullword ascii + $s16 = "xehook" fullword ascii + $s17 = "#+- +e,:'?;;)8" fullword ascii + $s18 = "\\DVzVCRz " fullword ascii + $s19 = "gv8) -" fullword ascii + $s20 = "[oBxxnhdy[" fullword ascii + condition: + uint16(0) == 0x5a4d and filesize < 2000KB and + 6 of them +} + +rule General_14 { + meta: + description = "14" + author = "PYAS Security" + date = "2024-06-12" + strings: + $s1 = "jdownloader" wide nocase + $s2 = "cmdvrt32.dll" fullword wide + $s3 = "accounts.dat" fullword wide + $s4 = "SxIn.dll" fullword wide + $s5 = "Paltalk NG" wide + $s6 = "encrypted" fullword wide + $s7 = "ip-api.com" wide + $s8 = "mRzIs.exe" fullword wide + $s9 = "SmtpPassword" fullword wide + $s10 = "FTP Commander" wide + $s14 = "privateinternetaccess.com" fullword wide + $s15 = "paltalk.com" fullword wide + $s16 = "discord.com" fullword wide + $s17 = "Sf2.dll" fullword wide + $s18 = "account.dyn.com" fullword wide + condition: + uint16(0) == 0x5a4d and filesize < 2000KB and + 8 of them +} + +rule General_15 { + meta: + description = "15" + author = "PYAS Security" + date = "2024-06-12" + strings: + $s1 = "aGVpbWdsaWduZGRramdvZmtjYmdla2hlbmJofE94eWdlbgptZ2Zma2ZiaWRpaGpwb2FvbWFqbGJnY2hkZGxpY2dwbnxQYWxpV2FsbGV0CmFvZGtrYWduYWRjYm9iZnBn" wide + $s2 = "Could not list processes locking resource." wide + $s3 = "Failed to get size of result." wide + $s4 = "DownloadAndExecuteUpdate" fullword ascii + $s5 = "loginusers.vdf" fullword wide + $s7 = "ProcessInfo" wide + $s8 = "get_encrypted_key" fullword ascii + $s9 = "Tokens.txt" fullword wide + $s10 = "DisplayDown" wide + $s11 = "VisualPlus-Debug.log" fullword wide + $s12 = "Total of RAMExecutablePath" fullword wide + $s13 = "loginPairs" fullword ascii + $s15 = "Software\\Valve\\SteamLogin Data" fullword wide + $s16 = "SELSystem" wide + $s17 = "FRSystem" wide + $s18 = "WinSystem" wide + $s19 = "%localappdata%\\" fullword wide + $s20 = "NoEngrdVpEngn.exe*" fullword wide + condition: + uint16(0) == 0x5a4d and filesize < 2000KB and + 8 of them +} + +rule General_16 { + meta: + description = "16" + author = "PYAS Security" + date = "2024-06-12" + strings: + $x1 = "LoginForm." ascii + $x2 = ".pdb" ascii + $s1 = "btnLogin" fullword ascii + $s2 = "Wrong ID or Password" fullword wide + $s3 = "Log In" wide + $s4 = "CodiNauts" wide + $s5 = "btnclear" fullword ascii + $s6 = "GridFactura.Factura.resources" fullword ascii + $s7 = "txtUserID_Validating" fullword ascii + $s8 = "TrabajoPractico.GridFactura.resources" fullword ascii + $s9 = "txtUserPass" fullword wide + $s10 = "txtUserID" fullword wide + $s11 = "Please Enter User ID" fullword wide + $s12 = "Properties.Resources" ascii + $s13 = "Log In Successfully" fullword wide + condition: + uint16(0) == 0x5a4d and filesize < 4000KB and + ($x1 and $x2) and 6 of them +} + +rule General_17 { + meta: + description = "17" + author = "PYAS Security" + date = "2024-06-12" + strings: + $x1 = "select * from user" wide nocase + $s1 = "ltromatic.ttf" wide + $s2 = "password mismatch issue" fullword wide + $s3 = "tada.wav" wide + $s4 = "GetAllIncome" fullword ascii + $s5 = "getIcomeData" fullword ascii + $s6 = "execQueryForStoredProcedure" fullword ascii + $s7 = "GetAllIncomeValues" fullword ascii + $s8 = "GetTotalIncomeSum" fullword ascii + $s9 = "getAllUser" fullword ascii + $s10 = "The password must include letters and numbers both" fullword wide + $s11 = "Passwords not mathced" fullword wide + condition: + uint16(0) == 0x5a4d and filesize < 4000KB and + $x1 and 8 of them +} + +rule General_18 { + meta: + description = "18" + author = "PYAS Security" + date = "2024-06-12" + strings: + $s1 = "WINDESCRIPTION" fullword wide + $s2 = "2#2?2a2{2" fullword ascii + $s3 = "CWM_GETCONTROLNAME" fullword wide + $s4 = ":%:=:C:L:R:\\:g:" fullword ascii + $s5 = ":-:I:T:\\:g:o:{:" fullword ascii + $s6 = "C@COM_EVENTOBJ" fullword wide + $s7 = "ISTABLE" fullword wide + $s8 = "Cstatic" fullword wide + $s9 = "HtZHtEHt2" fullword ascii + $s10 = "tgHuM95" fullword ascii + $s11 = "EEnvironment" fullword wide + $s12 = "Invalid characters behind Object assignment!" fullword wide + condition: + uint16(0) == 0x5a4d and filesize < 6000KB and + 6 of them +} + +rule General_19 { + meta: + description = "19" + author = "PYAS Security" + date = "2024-06-12" + strings: + $x1 = "step executed succcessfully" wide + $x2 = "NurseWorkstationDemo" wide + $s1 = "get_ObejctOperation" fullword ascii + $s2 = "man.png" wide + $s3 = "woman.png" fullword wide + $s4 = "get_AUTHORITY_ALL" fullword ascii + $s5 = "GetDataTableInfo_CommonGood" fullword ascii + $s6 = "from CommonGood where user_name=@user_Name" wide + $s7 = "PSYCHOLOGY" fullword ascii + $s8 = "GYNECOLOGY" fullword ascii + $s9 = "Workstation_Library.Common" fullword ascii + $s10 = "get_DataColumn1" fullword ascii + $s11 = "get_DataColumn1Column" fullword ascii + $s12 = "get_DataTable1" fullword ascii + $s13 = "get_Status_R" fullword ascii + $s14 = "GetAllBedNum" fullword ascii + $s15 = "GetDataTableInfo_PatientName" fullword ascii + $s16 = "get_Major_Doctor" fullword ascii + condition: + uint16(0) == 0x5a4d and filesize < 5000KB and + ($x1 and $x2) and 8 of them +} + +rule General_20 { + meta: + description = "20" + author = "PYAS Security" + date = "2024-06-12" + strings: + $s1 = "Log_Clientes.txt" wide + $s2 = "Log_Produtos.txt" wide + $s3 = "Log_Vendas.txt" wide + $s4 = "SCV - Sistema de Cadastro e Vendas" fullword wide + $s5 = "SCV - Novo Cliente" fullword wide + $s6 = "SCV - Lista de Clientes" fullword wide + $s7 = "SCV - Lista de Produtos" fullword wide + $s8 = "SCV - Listar Vendas" fullword wide + $s9 = "SCV - Novo Produto" fullword wide + $s10 = "SCV - Nova Venda" fullword wide + $s11 = "dgvListaClientes_CellContentClick" fullword ascii + $s12 = "Comprador" fullword wide + $s13 = "LogProdutos" fullword ascii + $s14 = "LogVendas" fullword ascii + $s15 = "dgvListaProdutos_CellContentClick" fullword ascii + $s16 = "LogClientes" fullword ascii + $s17 = "Compras" fullword ascii + $s18 = "dgvProdutos_CellContentClick" fullword ascii + condition: + uint16(0) == 0x5a4d and filesize < 5000KB and + 8 of them +} + +rule General_21 { + meta: + description = "21" + author = "PYAS Security" + date = "2024-06-12" + strings: + $s1 = "xeno rat client" wide + $s2 = "Windows Functionality" wide + $s3 = "mutex_string" fullword ascii + $s4 = "5__2" fullword ascii + $s5 = "xeno_rat_client" ascii + $s6 = "_EncryptionKey" fullword ascii + $s7 = "/query /v /fo csv" fullword wide + $s8 = "5__3" fullword ascii + $s9 = "5__2" fullword ascii + $s10 = "GetIdleTimeAsync" ascii + $s11 = "PT0S" wide + $s12 = "L0MgY2hvaWNlIC9DIFkgL04gL0QgWSAvVCAzICYgRGVsICI=" fullword wide + $s13 = "d__5" fullword ascii + $s14 = "5__7" fullword ascii + $s15 = "_dllhandler" fullword ascii + $s16 = "d__3" fullword ascii + condition: + uint16(0) == 0x5a4d and filesize < 500KB and + 8 of them +} + +rule General_22 { + meta: + description = "22" + author = "PYAS Security" + date = "2024-06-12" + strings: + $s1 = "Single.exe" fullword wide + $s2 = "Single.pdb" fullword ascii + $s3 = "Overchills" fullword wide + $s4 = "Single.g.resources" fullword ascii + $s5 = "dYuVXzkLLVWbcxpNkzwMQNycwFrMShzJDdw" fullword ascii + $s6 = "ZtrbobDfRVDVSYJDbiTjJYMtnApmznZIIGm" fullword ascii + $s7 = "OmmLUOYnOXYPbQacJiJgtIiOzIZqtuzkkZYgGzISElssPeGNll" fullword wide + $s8 = "RuJwfBUCLwnFkjrsmBeNtwwSyNBZKewfylZFqqPiXRqujAEskL" fullword wide + condition: + uint16(0) == 0x5a4d and filesize < 2000KB and + 6 of them +} + +rule General_23 { + meta: + description = "23" + author = "PYAS Security" + date = "2024-06-12" + strings: + $s1 = "HKCU:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run" wide + $s2 = "-ItemProperty -Path" wide + $s3 = "Kutc64InaW" fullword ascii + $s4 = "Cronos-Crypter" fullword wide + $s5 = "PrivateImplementationDetails" ascii + $s6 = "SetProcessSecurityDescriptor" ascii + $s7 = "Systemhost" fullword wide + $s8 = "decKey" fullword ascii + $s9 = "StartupInformation" fullword ascii + $s10 = "InstallRegistry" fullword ascii + $s11 = "EEC0C451-6B9A-45A0-A879-90E70D3033F5" ascii + condition: + uint16(0) == 0x5a4d and filesize < 500KB and + 7 of them +} + +rule General_24 { + meta: + description = "24" + author = "PYAS Security" + date = "2024-06-12" + strings: + $s1 = "LcD$`Mi" fullword ascii + $s2 = "yBZh11AY&SYS" fullword ascii + $s3 = "+HcD$DHcL$DH" fullword ascii + $s4 = "D$P9D$@}0" fullword ascii + $s5 = "tkHcD$8H" fullword ascii + $s6 = "BHcD$D" fullword ascii + $s7 = "|$(2t%" fullword ascii + $s8 = "D$ 9D$(}z" fullword ascii + $s9 = "D$ 9D$$}w" fullword ascii + $s10 = "|$02t\"" fullword ascii + $s11 = "L$P9H$s" fullword ascii + $s12 = "L$P9H$|uH" fullword ascii + $s13 = "D$89D$(}," fullword ascii + $s14 = " `l;Vig" fullword ascii + $s15 = "D$@HcL$\\H" fullword ascii + $s16 = "L$p9A 0] / len(arr) + return float(-np.sum(probs * np.log2(probs))) + + def _safe_div(n, d): + return n / d if d > 0 else 0.0 + + try: + fsize = os.path.getsize(file_path) + if fsize == 0 or fsize > MAX_FILE_SIZE: + return None + except: + return None + + fts = {k: 0 for k in Features.SCHEMA} + pe = None + try: + pe = pefile.PE(file_path, fast_load=True) + + fts['TrustSigned'] = verify_signature(file_path) + + fh = pe.FILE_HEADER + fts['Machine'] = fh.Machine + fts['NumberOfSections'] = fh.NumberOfSections + fts['TimeDateStamp'] = fh.TimeDateStamp + fts['PointerToSymbolTable'] = fh.PointerToSymbolTable + fts['NumberOfSymbols'] = fh.NumberOfSymbols + fts['SizeOfOptionalHeader'] = fh.SizeOfOptionalHeader + fts['Characteristics'] = fh.Characteristics + + curr_ts = datetime.datetime.utcnow().timestamp() + fts['HasInvalidTimestamp'] = 1 if (fh.TimeDateStamp < 631152000 or fh.TimeDateStamp > curr_ts + 2592000) else 0 + + if hasattr(pe, 'OPTIONAL_HEADER'): + op = pe.OPTIONAL_HEADER + fts['Magic'] = op.Magic + fts['MajorLinkerVersion'] = op.MajorLinkerVersion + fts['MinorLinkerVersion'] = op.MinorLinkerVersion + fts['SizeOfCode'] = op.SizeOfCode + fts['SizeOfInitializedData'] = op.SizeOfInitializedData + fts['SizeOfUninitializedData'] = op.SizeOfUninitializedData + fts['AddressOfEntryPoint'] = op.AddressOfEntryPoint + fts['BaseOfCode'] = op.BaseOfCode + fts['ImageBase'] = op.ImageBase + fts['SectionAlignment'] = op.SectionAlignment + fts['FileAlignment'] = op.FileAlignment + fts['MajorOperatingSystemVersion'] = op.MajorOperatingSystemVersion + fts['MinorOperatingSystemVersion'] = op.MinorOperatingSystemVersion + fts['MajorImageVersion'] = op.MajorImageVersion + fts['MinorImageVersion'] = op.MinorImageVersion + fts['MajorSubsystemVersion'] = op.MajorSubsystemVersion + fts['MinorSubsystemVersion'] = op.MinorSubsystemVersion + fts['SizeOfImage'] = op.SizeOfImage + fts['SizeOfHeaders'] = op.SizeOfHeaders + fts['CheckSum'] = op.CheckSum + fts['Subsystem'] = op.Subsystem + fts['DllCharacteristics'] = op.DllCharacteristics + fts['SizeOfStackReserve'] = op.SizeOfStackReserve + fts['SizeOfStackCommit'] = op.SizeOfStackCommit + fts['SizeOfHeapReserve'] = op.SizeOfHeapReserve + fts['SizeOfHeapCommit'] = op.SizeOfHeapCommit + fts['LoaderFlags'] = op.LoaderFlags + fts['NumberOfRvaAndSizes'] = op.NumberOfRvaAndSizes + + fts['Is64Bit'] = 1 if fh.Machine == 0x8664 else 0 + fts['IsExe'] = 1 if pe.is_exe() else 0 + fts['IsDll'] = 1 if pe.is_dll() else 0 + fts['IsDriver'] = 1 if pe.is_driver() else 0 + + if len(op.DATA_DIRECTORY) > 9 and op.DATA_DIRECTORY[9].VirtualAddress > 0: + fts['HasTlsCallbacks'] = 1 + if len(op.DATA_DIRECTORY) > 5 and op.DATA_DIRECTORY[5].Size > 0: + fts['HasRelocationDirectory'] = 1 + + pe.parse_sections(pe.FILE_HEADER.NumberOfSections) + + file_data = pe.get_memory_mapped_image() + fts['FileEntropy'] = _calc_entropy(file_data) + + fts['SectionCount'] = len(pe.sections) + for section in pe.sections: + try: + name = section.Name.decode('ascii', 'ignore').strip('\x00') + except: + name = "" + s_data = section.get_data() + s_entropy = _calc_entropy(s_data) + + if any(p in name.lower() for p in Features.PACKERS): + fts['HasPacked'] = 1 + if section.Characteristics & 0x20000000: + fts['ExecutableSections'] += 1 + if section.Characteristics & 0x80000000: + fts['WritableSections'] += 1 + if section.Characteristics & 0x40000000: + fts['ReadableSections'] += 1 + if section.SizeOfRawData + section.PointerToRawData > fsize: + fts['SectionException'] = 1 + + ratio = _safe_div(section.SizeOfRawData, fsize) + if name.startswith('.text'): + fts['TextSection'] = s_entropy + fts['TextSizeRatio'] = ratio + elif name.startswith('.data'): + fts['DataSection'] = s_entropy + fts['DataSizeRatio'] = ratio + elif name.startswith('.rsrc'): + fts['RsrcSection'] = s_entropy + fts['RsrcSizeRatio'] = ratio + if b"requireAdministrator" in s_data: + fts['IsAdmin'] = 1 + + for sig in Features.INSTALLER_SIGS: + if sig in s_data: + fts['IsInstall'] = 1 + break + + pe.parse_data_directories(directories=[ + pefile.DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_IMPORT'], + pefile.DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_EXPORT'], + pefile.DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_RESOURCE'], + pefile.DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_DEBUG'] + ]) + + if hasattr(pe, 'DIRECTORY_ENTRY_IMPORT'): + for entry in pe.DIRECTORY_ENTRY_IMPORT: + for imp in entry.imports: + fts['ApiCount'] += 1 + if not imp or not hasattr(imp, 'name') or not imp.name: + continue + try: + name = imp.name.decode('ascii', 'ignore') + if name in Features.SCHEMA_SET: + fts[name] = 1 + except: + pass + + if hasattr(pe, 'DIRECTORY_ENTRY_EXPORT'): + fts['ExportCount'] = len(pe.DIRECTORY_ENTRY_EXPORT.symbols) + + if hasattr(pe, 'DIRECTORY_ENTRY_RESOURCE'): + for entry in pe.DIRECTORY_ENTRY_RESOURCE.entries: + if entry.id == 3 and hasattr(entry, 'directory'): + fts['IconCount'] = len(entry.directory.entries) + break + + if hasattr(pe, 'DIRECTORY_ENTRY_DEBUG'): + fts['DebugCount'] = len(pe.DIRECTORY_ENTRY_DEBUG) + + for k in fts: + fts[k] = safe_float(fts[k]) + + return fts + + except Exception: + return None + finally: + if pe: + pe.close() + +#################################################################################################### + +def init_db(): + conn = sqlite3.connect(DB_PATH) + conn.execute("PRAGMA synchronous = OFF") + conn.execute("PRAGMA journal_mode = WAL") + conn.execute("PRAGMA cache_size = 10000") + cols = ", ".join([f"{c} REAL" for c in Features.SCHEMA]) + conn.execute(f"CREATE TABLE IF NOT EXISTS PeData ({cols}, Label INTEGER)") + conn.commit() + return conn + +def prune_db_duplicates(conn): + try: + print("\n[*] Post-processing: Checking for and removing duplicate entries...") + all_cols = ", ".join(Features.SCHEMA + ["Label"]) + + sql_count_before = "SELECT COUNT(*) FROM PeData" + before = conn.execute(sql_count_before).fetchone()[0] + + sql_dedup = f""" + DELETE FROM PeData + WHERE rowid NOT IN ( + SELECT MIN(rowid) + FROM PeData + GROUP BY {all_cols} + ) + """ + conn.execute(sql_dedup) + conn.commit() + + after = conn.execute(sql_count_before).fetchone()[0] + removed = before - after + + if removed > 0: + print(f"[+] Deduplication complete. Removed {removed} duplicate rows.") + print(" (Duplicates occur if the same file is scanned multiple times)") + else: + print("[+] Deduplication complete. No duplicates found.") + + except Exception as e: + print(f"[-] Deduplication Warning: {e}") + +#################################################################################################### + +def scan_and_save(conn, path, label): + print(f"\n[*] Scanning: {path} (Label={label})") + print(f"[*] Config: Max File Size = {MAX_FILE_SIZE/1024/1024:.0f} MB") + + files = [] + print("[*] Walking directory tree...") + if os.path.isfile(path): + files.append(path) + else: + for r, _, fs in os.walk(path): + for f in fs: + if os.path.splitext(f)[1].lower() in TARGET_EXTENSIONS: + files.append(os.path.join(r, f)) + + total = len(files) + if total == 0: + print("[-] No valid PE files found in this path.") + return + + print(f"[*] Found {total} files. Processing...") + + batch = [] + count = 0 + errors = 0 + start_time = time.time() + + placeholders = ",".join(["?"] * (len(Features.SCHEMA) + 1)) + sql = f"INSERT INTO PeData VALUES ({placeholders})" + + try: + for i, file_path in enumerate(files): + res = process_single_file(file_path) + + if res: + vals = [res.get(c, 0.0) for c in Features.SCHEMA] + vals.append(float(label)) + batch.append(tuple(vals)) + count += 1 + else: + errors += 1 + + if len(batch) >= BATCH_SIZE: + try: + conn.executemany(sql, batch) + conn.commit() + batch = [] + except Exception as batch_err: + print(f"\n[-] Batch Error: {batch_err}. Retrying strictly...") + for row in batch: + try: + conn.execute(sql, row) + except Exception: + errors += 1 + count -= 1 + conn.commit() + batch = [] + + elapsed = time.time() - start_time + rate = (i + 1) / elapsed if elapsed > 0 else 0 + sys.stdout.write(f"\r[{i+1}/{total}] OK: {count} | Skip/Err: {errors} | {rate:.1f} files/s") + sys.stdout.flush() + + except KeyboardInterrupt: + print("\n\n[-] Interrupted by user.") + except Exception as e: + print(f"\n[-] Unexpected Error: {e}") + finally: + if batch: + print(f"\n[*] Saving remaining {len(batch)} items...") + try: + conn.executemany(sql, batch) + conn.commit() + except Exception as final_err: + print(f"[-] Final Batch Error: {final_err}. Retrying strictly...") + for row in batch: + try: + conn.execute(sql, row) + except Exception: + pass + conn.commit() + + print(f"\n[+] Scan finished/stopped. Total added: {count}") + prune_db_duplicates(conn) + +#################################################################################################### + +if __name__ == "__main__": + print("\n---------------- PE Dataset Builder v2.6 ----------------\n") + print("Type 'exit' or 'q' at any prompt to quit.") + + if os.path.exists(DB_PATH): + print(f"[-] Note: If SCHEMA changed, please delete {DB_PATH} before running.") + + conn = init_db() + try: + while True: + print("\n---------------------------------------------------------\n") + raw_path = input("[*] Enter Path (File or Folder): ").strip() + target_path = raw_path.strip('"').strip("'") + + if target_path.lower() in ['exit', 'q']: + break + + if not target_path or not os.path.exists(target_path): + print("[-] Invalid path. Please try again.") + continue + + while True: + label_input = input("[*] Enter Label (0=Safe, 1=Malware): ").strip() + if label_input.lower() in ['exit', 'q']: + conn.close() + sys.exit() + + if label_input in ['0', '1']: + label = int(label_input) + break + else: + print("[-] Please enter 0 or 1.") + + scan_and_save(conn, target_path, label) + except KeyboardInterrupt: + print("\n\n[-] Interrupted.") + finally: + conn.close() + print(f"\n[+] Database saved to: {os.path.abspath(DB_PATH)}") diff --git a/Engine/Properties/train.py b/Engine/Properties/train.py new file mode 100644 index 0000000..5c24e93 --- /dev/null +++ b/Engine/Properties/train.py @@ -0,0 +1,195 @@ +import os, sys, time, sqlite3, re, json +import pandas as pd +import numpy as np +import lightgbm as lgb +import onnxmltools +from onnxmltools.convert.common.data_types import FloatTensorType +from sklearn.model_selection import train_test_split +from sklearn.metrics import classification_report, accuracy_score, roc_auc_score + +#################################################################################################### + +DB_PATH = "pe_features.db" +MODEL_FILE = "pe_malware_lgbm.txt" +ONNX_FILE = "pe_malware.onnx" +FEATURE_FILE = "features.json" +TEST_SIZE = 0.0001 +RANDOM_SEED = 42 + +LGBM_PARAMS = { + 'objective': 'binary', + 'metric': ['binary_logloss', 'auc'], + 'boosting_type': 'gbdt', + 'num_leaves': 63, + 'learning_rate': 0.05, + 'feature_fraction': 0.8, + 'bagging_fraction': 0.8, + 'bagging_freq': 5, + 'verbose': -1, + 'seed': RANDOM_SEED, + 'n_jobs': -1, + 'max_depth': -1, + 'min_data_in_leaf': 20, + 'lambda_l1': 0.1, + 'lambda_l2': 0.1 +} + +#################################################################################################### + +def get_raw_schema(db_path): + if not os.path.exists(db_path): + return None + conn = sqlite3.connect(db_path) + try: + cursor = conn.cursor() + cursor.execute("PRAGMA table_info(PeData)") + columns = [row[1] for row in cursor.fetchall()] + exclude_lower = {'label', 'id', 'filename', 'filelength', 'rowid', 'probability', 'predictedlabel', 'score'} + return [c for c in columns if c.lower().strip() not in exclude_lower] + except: + return None + finally: + conn.close() + +def load_and_clean_data(db_path, raw_cols): + print(f"[*] Connecting to database: {db_path}") + conn = sqlite3.connect(db_path) + req_cols = list(set(raw_cols + ['Label'])) + sql = f"SELECT {', '.join(req_cols)} FROM PeData" + + try: + df = pd.read_sql_query(sql, conn) + if df.empty: return None, None, None + + label_col = next((c for c in df.columns if c.lower().strip() == 'label'), None) + if not label_col: + print("[-] Critical Error: Label column not found.") + return None, None, None + + y = df[label_col].astype(int) + X = df.drop(columns=[label_col], errors='ignore') + + valid_features = [c for c in raw_cols if c in X.columns] + X = X[valid_features].copy() + + X = X.rename(columns=lambda x: re.sub('[^A-Za-z0-9_]+', '', x)) + + if X.isnull().values.any(): + X = X.fillna(X.median(numeric_only=True)) + + final_features = X.columns.tolist() + return X, y, final_features + finally: + conn.close() + +#################################################################################################### + +def train_process(X, y): + print(f"[*] Dataset shape: {X.shape}") + + X_train, X_test, y_train, y_test = train_test_split( + X, y, test_size=TEST_SIZE, random_state=RANDOM_SEED, stratify=y + ) + + n_pos = (y_train == 1).sum() + n_neg = (y_train == 0).sum() + + base_weight = n_neg / n_pos if n_pos > 0 else 1.0 + + weight_ratio_base = 1.0 + weight_ratio_target = 0.1 + final_pos_weight = base_weight * (weight_ratio_target / weight_ratio_base) + + print(f"[*] Balance Report: Safe={n_neg}, Malware={n_pos}") + print(f"[*] Weight Config: Base Balanced={base_weight:.4f}, Final Adjusted (Favor Safe)={final_pos_weight:.4f}") + + train_data = lgb.Dataset(X_train, label=y_train) + valid_data = lgb.Dataset(X_test, label=y_test, reference=train_data) + + params = LGBM_PARAMS.copy() + params['scale_pos_weight'] = final_pos_weight + + print("\n[*] Starting LightGBM training (Full Force, No Early Stopping)...") + start_time = time.time() + + model = lgb.train( + params, + train_data, + valid_sets=[valid_data], + num_boost_round=1000, + callbacks=[ + lgb.log_evaluation(period=100) + ] + ) + + elapsed = time.time() - start_time + print(f"\n[+] Training finished in {elapsed:.2f}s") + + return model, X_test, y_test + +def export_onnx_model(model, feature_names): + print(f"[*] Exporting ONNX model to {ONNX_FILE}...") + try: + initial_type = [('float_input', FloatTensorType([None, len(feature_names)]))] + onnx_model = onnxmltools.convert_lightgbm(model, initial_types=initial_type) + onnxmltools.utils.save_model(onnx_model, ONNX_FILE) + + with open(FEATURE_FILE, 'w') as f: + json.dump(feature_names, f) + + print(f"[+] ONNX export success. Features synced to {FEATURE_FILE}") + except Exception as e: + print(f"[-] ONNX export failed: {e}") + +def evaluate_and_save(model, X_test, y_test): + print("\n------------------- Evaluation Report -------------------\n") + y_prob = model.predict(X_test, num_iteration=model.best_iteration) + y_pred = (y_prob > 0.5).astype(int) + + acc = accuracy_score(y_test, y_pred) + auc = roc_auc_score(y_test, y_prob) + + print(f"Accuracy : {acc:.4f}") + print(f"ROC AUC : {auc:.4f}") + print("\n" + classification_report(y_test, y_pred, zero_division=0)) + + print("---------------------------------------------------------\n") + print("[*] Top 20 Features (Importance by Gain):") + + feature_names = model.feature_name() + importance = model.feature_importance(importance_type='gain') + feature_imp = pd.DataFrame(sorted(zip(importance, feature_names), reverse=True), columns=['Value', 'Feature']) + print(feature_imp.head(20).to_string(index=False)) + + print("\n---------------------------------------------------------\n") + + model.save_model(MODEL_FILE) + print(f"[+] Native model saved to: {os.path.abspath(MODEL_FILE)}") + + export_onnx_model(model, feature_names) + +#################################################################################################### + +if __name__ == "__main__": + print("\n---------------- PE Malware Trainer v3.0 ----------------\n") + + if not os.path.exists(DB_PATH): + print(f"[-] Error: Database {DB_PATH} not found.") + sys.exit(1) + + raw_schema = get_raw_schema(DB_PATH) + if not raw_schema: + print("[-] Error: Could not read schema.") + sys.exit(1) + + X, y, _ = load_and_clean_data(DB_PATH, raw_schema) + if X is None: + sys.exit(1) + + try: + model, X_test, y_test = train_process(X, y) + evaluate_and_save(model, X_test, y_test) + except KeyboardInterrupt: + print("\n\n[-] Training interrupted.") + except Exception as e: + print(f"\n[-] Critical Error: {e}")