BadRabbit was a ransomware variant initially detected in the wild on October 24, 2017. On that day, Carbon Black and several other research organizations conducted triage analysis of the sample and provided write ups. Carbon Black also provided an internal post in the User Exchange documenting IOCs as well as content to detect and stop this variant. Many of the initial post made by different research organizations focused on a basic triage or the sample or did not contain analysis of important functions performed by the ransomware variant.
Carbon Black’s Threat Analysis Unit (TAU) completed a comprehensive analysis of the dropper and the ransomware to determine the best way to detect or stop the dropper as well as understand how this variant functioned.
The analysis showed that there are numerous similarities between this sample and the NotPetya sample that was documented in June. The similarities do not necessarily prove that the same author(s) was responsible for both families. However if this was not the case, then the author(s) of the BadRabbit variant either had access to the NotPetya source code, or spent a considerable amount of time reverse engineering NotPetya to reimplement the overall approach.
The most notable difference between the two samples, which was not highly reported on, is that if the process has SeShutdown privileges it will not reach the routines responsible for lateral movement. This could be a major contributing factor as to why the BadRabbit outbreak was not damaging as previous campaigns that used NSA leaked exploits (WannaCry and NotPetya). It’s not completely clear why the malware authors would write the code in this manner.
This analysis is being provided to customers, partners, and other community researchers in an effort to help security practitioners understand how this attack was carried out and to assist any ongoing investigations.
Along with this analysis there is a list of IOCs and a yara signature, it should be noted that the Yara signature was written to detect the BadRabbit dropper (which could be used to deliver different payloads).
Technical Analysis
Main Dropper
As part of our analysis, we initially began analyzing the main dropper, which was responsible for creating the ransomware on an infected system. The metadata for the initial dropper is listed in the table below.
File Size : 441,899 bytes
MD5 : fbbdc39af1139aebba4da004475e8839 SHA1 : de5c8d858e6e41da715dca1c019df0bfb92d32c0 SHA256 : 630325cac09ac3fab908f903e3b00d0dadd5fdaa0875ed8496fcbb97a558d0da Fuzzy : 12288:BHNTywFAvN86pLbqWRKHZKfErrZJyZ0yqsGO3XR63:vT56NbqWRwZaEr3yt2O3XR63 Compiled Time : Sun Oct 22 02:33:58 2017 UTC PE Sections (5) : Name Size MD5 .text 12,288 098c323b1a59bcf15c1feb8055e58931 .rdata 12,800 9cc3629beb9d1f37932d860de2e3a4f5 .data 512 4e5d61b2bd73632f0225e39a2e2c5144 .rsrc 29,184 256c5e23a9ad8a276128f84017b2d79d .reloc 1,024 26cd68101ade4e5f70ab3cd5f35e0ad5 + 0xde00 385,067 829c177d1421b4ba42e8e205abd93f10 Magic : PE32 executable for MS Windows (console) Intel 80386 32-bit |
Table 1: Dropper metadata
To help conceal its identity the initial dropper in the wild was named for Adobe related files (Flash Player.exe, FlashUtil.exe, and Adobe® Flash® Player Installer/Uninstaller 27.0) as well as having an embedded icon that is commonly used with legitimate Adobe Flash products, displayed below.
Figure 1: Dropper Icon
Second Stage Execution
The initial dropper has very few functions and only responsible for creating the embedded second stage payload onto the infected system, and then executing that file.
The image below shows the main function of the dropper which is responsible for locating the embedded file and inflating it using the Zlib library. The area highlighted in red is used to determine the Windows System directory, decompress (or inflate) the embedded payload, and then write that file to disk as infpub.dat, a file name hard coded into the binary. The data highlighted in green is used to construct the command line which will be used in conjunction with the CreateProcess call (highlighted in blue), which will execute the second stage payload.
Figure 2: Main Function
Second Stage File Deobfuscation
In order to locate the embedded second stage the dropper will load itself into memory and then walk the PE structure of itself to ultimately determine where the end of the file should be located (highlighted in red). The code will locate the different sections and get the offset for the last section and its size, combining those values and determining where the file should end. The second stage payload was then just appended to the end of the file. Once payload offset is determined, the code will copy that data to a new memory heap (highlighted in blue).
Figure 3: Locate Embed
Once the second stage payload is copied into a memory space, the dropper will take the first byte and XOR it with the value 0xE9, this value is then XOR’d again and again with the same value (0xE9) for n times (where n is the length of the payload itself), highlighted in blue. This is a peculiar set of commands as the resulting value will only be one of two possibilities regardless of the number of times XOR’d (the original value itself or that value XOR’d with 0xE9). The same result could be achieved by taking the length of the payload and performing a modulus (mod) of 2, and then performing the XOR instruction that number of times. It is assumed that this routine was added to obfuscate the outcome. The resulting value from this set of instructions is then written back to the original memory location. The end result is that the first dword of the payload data is the size of the data once inflated, which has least significant byte encoded with a simple XOR of 0xE9. This dword is passed to the zlib inflate function and would raise an error if the value was incorrect (which is highlighted in green).
Figure 4: Inflate Payload
Once the data is inflated it is written out to the disk as C:\Windows\infpub.dat, which is illustrated in the image below.
Figure 5: Write Second Stage
The newly created file will then be executed with a call to CreateProcess. The process is passed the command line rundll32.exe C:\Windows\infpub.dat #1 15 (highlighted in blue), which is using rundll32.exe to call the ordinal export number 1 of the infpub.dat Dll file.
Figure 6: Create infpub.dat Process
Main Payload
The metadata for the second stage payload which is executed is listed below. This binary is responsible for performing the ransomware and wormlike related activity.
File Name : infpub.dat
File Size : 410,760 bytes MD5 : 1d724f95c61f1055f0d02c2154bbccd3 SHA1 : 79116fe99f2b421c52ef64097f0f39b815b20907 SHA256 : 579fd8a0385482fb4c789561a30b09f25671e86422f40ef5cca2036b28f99648 Fuzzy : 12288:GtDjvhNTc/cq4RKZZKfArRuSA80m+/6sXRnfPGp:IjTc/cq4RUZaArbInfPGp Compiled Time : Sun Oct 22 02:33:41 2017 UTC PE Sections (5) : Name Size MD5 .text 49,152 f277e74393ce6a5225228d538d794067 .rdata 24,064 50eb2a2b07fa914ce2e9d3f470796e41 .data 2,560 14a2ecc6822bbedc01d209e8b3f541c4 .rsrc 316,928 49761becfc454de3506c3fa2b11cfbc9 .reloc 3,584 0b73b18ff226349be058ad09669b00b0 + 0x61000 13,448 cf7a57208e69c5992bdf0a8044d4a957 (Authenticode Signature) |
Table 2: infpub.dat metadata
It should be noted that this Dll has three export functions: the customary main entry, then two additionals listed as ordinal values 1 and 2. When the dropper creates this process initially it will call the export #1, which can be observed (highlighted in blue) from Figure 2 above. The analysis of this binary will begin with this exported function.
Checking Privileges
The first function that is called will enumerate the privileges of the process. This was also observed in the NotPetya sample that was observed in the wild in June of 2017. The two images below depict the functions from BadRabbit and NotPetya, which are identical in purpose and return values.
Figure 7: SE Privilege Check (BadRabbit left – NotPetya right)
The function uses a byte to track associated privileges, which has eight potential combinations (listed in the table below).
Value | Privileges |
0 | No privileges granted |
1 | SeShutdownPrivilege |
2 | SeDebugPrivilege |
3 | SeShutdownPrivilege and SeDebugPrivilege |
4 | SeTcbPrivilege |
5 | SeShutdownPrivilege and SeTcbPrivilege |
6 | SeDebugPrivilege and SeTcbPrivilege |
7 | All privileges |
Table 3: Privilege Value Combinations
Process Enumeration
The BadRabbit sample will then enumerate the running processes on the system, and create a hash of the process name, which are compared to hard coded values. This type of check was also present in the NotPetya samples, however the comparison values differed between to the two samples. If should also be noted that in the BadRabbit sample the XOR key 0x87654321 was used as a base to hash each process name and in the NotPetya sample the XOR key 0x12345678 was used as the base. The image below depicts the code responsible for conducting the compares and setting the potential return values, which are used for code flow later by the sample.
Figure 8: Process Hash Check
The table below highlights the running process names that the sample is specifically looking to identify on the infected system.
Name Hash | Process Name | Notes |
0x966D0415 | dwarkdaemon.exe | Related to Dr. Web Antivirus |
0xE2517A14 | dwengine.exe | |
0xAA331620 | dwservice.exe | |
0x4A241C3E | dwwatcher.exe | |
0xE5A05A00 | mcshield.exe | Related to McAfee Antivirus |
0x923CA517 | McTray.exe | |
0xC8F10976 | mfevtps.exe |
Table 4: Process Name Hashes
If the sample identifies running processes related to Dr. Web AV, it will return the value 0xFFFFFFEF and for McAfee related processes the value 0xFFFFFFBF. These values are used as checks for code execution paths. The table below shows the execution flow paths of both BadRabbit (on the left) and NotPetya (on the right). Both sample follow a similar code path based upon the type of privileges and detected processes. There are some notable differences, which are detailed later in this report.
Table 5: Execution Flow BadRabbit (left) NotPetya (right)
It should be noted that a subfunction is called is used to generate a 4 byte random value (highlighted in red below), which is used later when creating a service for dispci.exe. For clarity dispci.exe is the Diskcryptor client that can be used (along with the associated Diskcryptor driver) to encrypt the system from kernel mode.
Figure 9: Rand value creation
Generating Mutex
The sample will then gather the computer name and the fully qualified path (FQP) of the sample itself. Each of those string values will then be hashes using the same function that was used to hash the process names. The two hash name values will then be converted to ASCII hex and concatenated together. This value will be used as the Mutex name for the process. If the mutex already exist, then the process will terminate. The mutex name creation process is detailed in the image below.
Figure 10: Mutex Name Creation
It should be noted that while the first portion of the mutex name can vary, the last portion of the mutex (assuming the FQP is the same) should be consistent across different environments. The last 8 bytes of the mutex will be 3AD6FDE5, this could be used as an additional technique to detect and prevent this sample from running in an environment.
DiskCryptor and Token Impersonation
After creating a mutex, the sample will check that the process has SeDebug privileges. If it does it will attempt to create the C:\Windows\cscc.dat file on the system. The sample will initially check to see if this file is present and exit, if located on the system. A check is then performed to see if the process is running under Wow64, presumably (although not reliably) to determine if the system is x86 or x64. Depending on the check the sample will then either load resource 7 or resource 8 (x86 and x64 DiskCryptor driver respectively) into memory. The resource is then inflated using the Zlib library and written to disk as C:\Windows\cscc.dat (which is highlighted in the image below).
Figure 11: cscc.dat file creation
The sample will enumerate the processes and look for the process name rundll32.exe by hashing process names (using the same function that was previously detailed), and compare those results against the value 0xF4713B0E. If the rundll32.exe process name is located, the sample will attempt to impersonate the token for the rundll32 process. This image below depicts this activity.
Figure 12: Rundll32.exe Token Impersonation
The sample performs a check to ensure that the process has SeDebug privileges (highlighted in red below), as it prepares to create the dispci.exe file. Dispci.exe is the Diskcryptor program client that interacts (from userland) with the Diskcryptor driver. An additional check is performed (highlighted in blue below) and if McAfee related processes are not detected then the dispci.exe file will be created in the C:\Windows directory. If McAfee related processes are present dispci.exe will be created in the %ALLUSERSPROFILE% (highlighted in green). It should be noted that this location can be different depending on the version of Windows (XP and prior era systems would be C:\Documents and Settings\All Users, while Vista and later would be C:\ProgramData).
Figure 13: Check to determine dispci.exe directory location
After the destination directory has been determined that sample will load the resource 9 (highlighted in red below) into memory and inflate that resource using the Zlib library. The inflated data is then written to the appropriate directory as dispci.exe.
Figure 14: dispci.exe file creation
DiskCryptor Execution using Scheduled Task
The dispci.exe file will then be entrenched on the system as a scheduled task. The sample will first call a subfunction to delete any scheduled task with the name rhaegal (highlighted in red below). The sample will then build a new string which will be used as a command to create a new scheduled task (highlighted in green below) to execute dispci.exe once the system is rebooted.
Figure 15: dispci.exe scheduled task setup
The output of the wsprintf call results in a string that is used in conjunction with cmd.exe to create a new scheduled task. The table below contains an example of what the formatted string would look like. The scheduled task will run as system on start up, with a task name of rhaegal.
The id value (which is in red in the table below) is passed to and used by dispci.exe. This value is random generated dword value (depicted in Figure 9 above) formatted as an unsigned integer.
schtasks /Create /RU SYSTEM /SC ONSTART /TN rhaegal /TR “C:\Windows\system32\cmd.exe /C Start \”\” \”C:\Windows\dispci.exe\” -id 3634207313 && exit |
Table 6: example entrenchment command
DiskCryptor Driver Service Execution
The sample will then setup the Diskcryptor driver file (cscc.dat) as a service, with a display name of Windows Client Side Caching DDriver and scheduled to execute on startup. The figure below shows the service being created with the arguments that are used in conjunction with this service.
Figure 16: cscc.dat service arguments
If for whatever reason the sample can not create the above detailed service, it will attempt to alter the existing service cdfs (highlighted in red below). It will query for that service name in the registry and if located it will alter the Start Type, Load order Group, Dependencies, Image Path, and Error control (to match the values outlined in the image above.
Figure 17: cdfs service modified for cscc.dat
After the service is created (and it should be noted again that this could be named as cscc or the modified cdfs), the sample will attempt make modifications to existing registry entries to register the driver’s service. Initially the sample will attempt to alter the Storage Volume Class’ (highlighted in red below and listed by GUID) LowerFilters value to the previously generated service name. If that fails of the GUID is not present, the sample will attempt to alter the CD-Rom Drives Class’ (highlighted in blue below and list by GUID) UpperFilters value to the same previously generated service name. If both of those fail and the operating system version is 6 or above (Vista or later), then the sample will modify DumpFilters value for the CrashControl key, to the service name (highlighted in green below).
Figure 18: Registered Driver Class modification
Scheduled Shutdown and Time Calculation
The sample will start up WSA before it completes a check against provided command line arguments. One of the main purposes of this function is to set the scheduled task offset. In the example command below the value 15 (in red) will be converted to an integer and saved as a dword value to be used later. If no value is provided then the function will set this word value to 45.
C:\Windows\System32\rundll32.exe C:\ProgramData\infpub.dat, #1 15 |
Table 7: scheduled task offset value
The next function is responsible for creating a scheduled task to shutdown the system. The sample will construct the command to create the scheduled task shutting down the system based off a number of variables. The first variable that is determined is the amount of time in the future to schedule the task, which was provided in the command line argument described above.
In the example in Table 7 above (which is the same command initially used to execute the sample, the value 15 is provided. A subfunction is called which will calculate a minute value based off of a call to the GetTickCount API and subtracting the value stored from a previous call to the same API when the process first executed (displayed in the image below). If this minute value is less than the value in the command line argument (in this example 15), it is then subtracted from command line value and returned to the calling function (in this scenario the return value would most likely be 15 given a small difference in when the two Tick counts were taken). If the minute value is more or there was no value provided in the command line, then the value 0 is returned.
Figure 19: Tick count comparison
The returned value is then compared with the hard coded value 15 and if less than that value, a base value of 15 will be used (it should be noted in this example that the argument matches the base value). That derived value is then added with the hard coded value 3 (18 in this scenario) and that result is converted to a value after a Modulus of 60 (number of minutes in a hour), resulting in 18 in this example. This would be the number of minutes added to the current time’s minute value on which to schedule the task (highlighted in red below). Given the code in this function the minimum number of minutes that the scheduled task will be created is 18 minutes.
Figure 20: Scheduled task time calculation
The hour value is determined by taking the same base value (in this scenario 15) and adding that value with 3 before dividing the result by 60 (minutes in an hour) and adding that result to the current hour system time hour value. That resulting value is then converted to a value after a Modulus of 24, resulting in 0 in this scenario. In this example if the sample was run with the command line in Table 7 at 1400 hours, then the task would be scheduled to run at 1418 hours.
It should be noted that this is the same technique that the NotPetya sample used to calculate the time for a scheduled task that would also reboot the system. The only different is a base value of 10 was used (versus 15 in this sample).
The BadRabbit sample uses a string stacking and concatenation method (highlighted in red below), which was not present in the NotPetya sample. This was mostly likely done to avoid certain signatures or AV detection.
Figure 21: String Stacking
Ultimately the string in the following table is created from the wsprintf call highlighted in green above. The scheduled task is named drogon and the previously determined hour and minute values are formatted and an example is highlighted in red below. This string is then passed to a sub function is executed with cmd.exe.
schtasks /Create /SC once /TN drogon /RU SYSTEM /TR “C:\Windows\System32\shutdown.exe /r /t 0 /f” /ST 14:18:00 |
Table 8: scheduled task string example
Reboot or Lateral Movement
The next function (0x10008A6F) that is called is will determine whether or not the sample will attempt to move laterally or shutdown the system initiating the Diskcryptor files (that were previously installed on the system). The image below shows where the sample will create a thread (with the start or the routine being (0x10008A6F), which is highlighted in red.
Figure 22: Shutdown routine CreateThread
The thread will do a quick check to ensure that the system session is not currently shutting down (highlighted in red), before calling a sub function at 0x10008A23 (highlighted in green).
Figure 23: Shutdown checks
This subfunction will (0x10008A23), will delete the Setup, System, Security, and Application event logs; as well as deleting the USN journal (highlighted in green). The function will then check to see if the process has SeDebug privileges and if so, will delete the scheduled task (named drogon) that was previously created. The function will then check to see if the process has SeShutdown privileges, if so it will then initiate a shutdown of Windows using one of the two API calls highlighted in blue. It should be noted that if this occurs the system will reboot and execute the previously installed Diskcryptor client and driver file (which will encrypt the system and display a ransom note. At this point the current sample (infpub.dat) will not run again as it was not entrenched on the system by the original dropper. Furthermore the sample will not return from this function and continue onto the functions responsible for lateral movement or worm like capabilities.
If the process does not have SeShutdown privileges then the ExitProcess call is made, which will kill this thread, but not the parent process allowing the code to return to the previous calling function.
Figure 24: Reboot vs. Lateral Movement routine
Lateral Movement
If the process does not have SeShutdown privileges then the ExitProcess call is made, which will kill this thread, but not the parent process allowing the code to return to the previous calling function.
If the function returns it will again check to see if the process has SeDebug privileges, and if so it will create a file on the system that is used to dump plaintext credentials. The function will initially check to see if the process is running under Wow64 (again this is presumably done to determine the architecture), which is highlighted in red. If the system is x86 then resource 1 is loaded and if x64 then resource 2 is loaded. The appropriate resource will then be passed to a function responsible for inflating the resource using the Zlib library (which is highlighted in green). It should be noted the initial dword value (the size) of the resource is then modified (by XORing the least significant byte with 0xE9), a similar routine was observed in the initial dropper and is documented in Figure 4 above. The function will then use the GetTempFileName (highlighted in blue) api to get a unique name, which with the arguments provided will result in a 4 character hex ascii string (ex. C1F0.tmp). The inflated executable will then be written to disk as that file name in the same directory as the infpub.dat file (C:\Windows in this variant).
Figure 25: Credential stealer creation
The sample will then created a named pipe to communicate with the credential stealer (which is highlighted in red below).
Figure 26: named pipe creation
After these threads are initiated the sample will begin the lateral movement process. If The sample has SeTcb privileges it will use standard API calls to duplicate and set thread tokens. The sample will then dump service credentials as well as connecting to different admin shares (highlighted in the image below).
Figure 27: Lateral movement main function
The sample will attempt to copy over the infpub.dat and cscc.dat files to the remote systems, where it is able to establish a connection to a share (displayed below). The sample will then attempt to execute the file on the newly infected system by using rundll32.exe and calling export #2 (versus when the initial dropper called #1).
Figure 28: Start infpub.dat with service
The sample will then attempt to spread by traversing different SMB shares, if McAfee and Dr. Web are not installed on the system (highlighted in the image below).
Figure 29: AV check
Eternal Romance
As previously stated if McAfee and Dr. Web are not present on the system, the sample will begin to target SMB shares. This routine will attempt to make SMB connections and if successful, will attempt to authenticate with a set of hard coded usernames and credentials (highlighted in red below). This is done prior to the routine attempting to leverage the External Romance exploit that was released earlier this year.
Figure 30: SMB lateral movement
The following two tables list the usernames and passwords that are used to attempt to authenticate with the above referenced SMB shares. If successful the infpub.dat and cscc.dat files are copied over to the remote systems and executed in the same manner as detailed above.
Usernames | |||
Administrator | buh | support | ftpadmin |
Admin | boss | work | nas |
Guest | ftp | other user | nasuser |
User | rdp | operator | nasadmin |
User1 | rdpuser | backup | superuser |
user-1 | rdpadmin | asus | netguest |
Test | manager | ftpuser | alex |
root |
Table 9: User names
Passwords | ||||
Administrator | 123 | Guest123 | 77777 | zxc123 |
administrator | 1234 | guest123 | 777 | zxc321 |
Guest | 12345 | User123 | qwe | zxcv |
guest | 123456 | user123 | qwe123 | uiop |
User | 1234567 | Admin123 | qwe321 | 123321 |
user | 12345678 | admin123Test123 | qwer | 321 |
Admin | 123456789 | test123 | qwert | love |
adminTest | 1234567890 | password | qwerty | secret |
test | Administrator123 | 111111 | qwerty123 | sex |
root | administrator123 | 55555 | zxc | god |
Table 10: Passwords
User Mode Encryption
The sample will then initiate the user mode encryption routine. The routine will create a thread pointing to the entry point for the main encryption function. The function will use an embedded public key to generate the appropriate encryption routines. The function then walks the file system and compare the file extensions with a set of extensions that is typically observed in ransomware families (displayed in the image below).
Figure 31: File extension compare
If a file meets the above checks it the file’s contents will be mapped and then encrypted, before the data is then flushed and unmapped. The file’s extension is then changed to .encrypted.
Figure 32: File mapping and Encryption
After the user mode encryption routine, the process will then again attempt to shutdown the system using the same routine that was documented Figure 24. It should be noted that in this call to that function, the ExitProcess call will shutdown the infpub.dat process itself, as it was not called as a separate thread.
IOCs
Hashes
BadRabbit Dropper | |
MD5 | 1d724f95c61f1055f0d02c2154bbccd3 |
SHA256 | 630325cac09ac3fab908f903e3b00d0dadd5fdaa0875ed8496fcbb97a558d0da |
infpub.dat – BadRabbit | |
MD5 | fbbdc39af1139aebba4da004475e8839 |
SHA256 | 579fd8a0385482fb4c789561a30b09f25671e86422f40ef5cca2036b28f99648 |
Infpub.dat Resources | |
Resource 1 | x86 Credential dumper |
MD5 | 37945c44a897aa42a66adcab68f560e0 |
SHA256 | 2f8c54f9fa8e47596a3beff0031f85360e56840c77f71c6a573ace6f46412035 |
Resource 2 | x64 Credential dumper |
MD5 | 347ac3b6b791054de3e5720a7144a977 |
SHA256 | 301b905eb98d8d6bb559c04bbda26628a942b2c4107c07a02e8f753bdcfe347c |
Resource 7 | x86 DiskCryptor Driver |
MD5 | b4e6d97dafd9224ed9a547d52c26ce02 |
SHA256 | 682adcb55fe4649f7b22505a54a9dbc454b4090fc2bb84af7db5b0908f3b7806 |
Resource 8 | x64 DiskCryptor Driver |
MD5 | edb72f4a46c39452d1a5414f7d26454a |
SHA256 | 0b2f863f4119dc88a22cc97c0a136c88a0127cb026751303b045f7322a8972f6 |
Resource 9 | DiskCryptor Client |
MD5 | b14d8faf7f0cbcfad051cefe5f39645f |
SHA256 | 8ebc97e05c8e1073bda2efb6f4d00ad7e789260afa2c276f0c72740b838a0a93 |
Yara Signature
rule bad_rabbit_dropper : TAU ransom rabbit
{ meta: author = “Carbon Black TAU” //jmyers date = “2017-Oct-24” confidence = 10 serverity = 10 description = “Designed to catch BadRabbit Dropper File” link = “” rule_version = 1 yara_version = “3.5.0” exemplar_hashes = “630325cac09ac3fab908f903e3b00d0dadd5fdaa0875ed8496fcbb97a558d0da,”
strings: $b1 = /\x00{40}[^\x00]{3}\x00\x78\xDA/ //Zlib header (max compression) with dword size value $b2 = {80 F1 ?? 48} //Instructions for altering dword size value $s1 = “inflate 1.2.8” $s2 = “CreateFile” $s3 = “WriteFile” $s4 = “HeapFree” $s5 = “rundll32” wide $s6 = “CreateProcess” $s7 = “ExitProcess” $s8 = “C:\\Windows” wide condition: uint16(0) == 0x5A4D and all of ($b*) and 6 of ($s*) } |