[Studying] Analyzing NotPetya

First Post:

Last Update:

Word Count:
1.8k

Read Time:
11 min

NotPetya: Beyond ransomware — worming and destruction

Introduction

This article presents an analysis of NotPetya.

This article is part of my series: Inside Different Generations of Ransomware.

If you are interested in the full series, please refer to the mentioned page.

Key Takeaways

  • Combines ransomware with worm capabilities (EternalBlue, EternalRomance, wmic and psexec)
  • Uses credential harvesting (Mimikatz, CredEnumerateW) for lateral movement
  • Propagates efficiently within internal networks instead of scanning all devices
  • Overwrites MBR early, ensuring system damage regardless of propagation success
  • Destroys encryption keys, making recovery impossible
  • Functions more as a wiper than traditional ransomware

NotPetya

In the previous article, I conducted an analysis of Petya. In this article, I am going to conduct a reverse engineering anlysis of NotPetya..

NotPetya is a variant of Petya family. It was discovered in 2017, a year after Petya was discovered. It mainly targets infrastructure in Ukraine. Therefore, many cybersecurity experts believe this cyberattack is politically intentional.

Unlike the original Petya, NotPetya contains worming module, which is implemented with EternalBlue, EternalRomance and other domain penetration methods such as psexec. Furthermore, a device cannot be recovered if it is infected by NotPetya. Therefore, this design is purely intended for destruction.

Note: Although not covered in this analysis, NotPetya was initially distributed through a compromised software update mechanism (MeDoc), demonstrating a supply-chain attack vector.

Experimental Environment

To safely conduct malware analysis, the environment should be isolated using virtual machines. Under no circumstances should malware be executed on a personal or production system.

Tool Description
ExeInfo PE Detect packers, compilers, and basic file metadata
Detect It Easy (DIE) Identify packers, protectors, and signatures
Wireshark Network traffic analysis
x32dbg Win32 application debugging tool
Ghidra Software reverse engineering framework

Device IP Address Description
Windows 7 x64 (VM) 192.168.85.5 Victim machine
Windows 10 x64 (VM) 192.168.85.3 Analysis machine

The two virtual machines were configured within an isolated internal network to prevent unintended external communication. If you want to know how to set up your experimental environment, please view:

Launch

Murmur: While launching NotPetya in my VM, my laptop battery died. That split second of a black screen honestly gave me a heart attack.

Fake CHKDSK

The extortion message is a bit different from Petya:

Extortion message

Protocol Analysis

Try to exploit 139 and 445

The exploitation will be analyzed in the next section.

Reverse Engineering

Example’s information:

  • Compile date:
  • SHA256 hash: 63545fa195488ff51955f09833332b9660d18f8afb16bdf579134661962e548a

Open the malware using ExeInfo PE and DIE (Detect It Easy):

ExeInfo PE

DIE

DIE — Entropy

Open the malware using Ghidra:

The malware releases an embedded payload to the disk and executes it via rundll32.exe

In this analysis, I learned how to develop a script for Ghidra.

First, open Script Manager and click Create New Script:

Script Manager

Murmur: You can also use other provided languages, but I wanted to review Java programming!

I wrote a simple script for dumping embedded payload.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
// Dump a payload from memory using a known start address.
// Supports manual size input or automatic size detection (0 = auto).
// Auto mode dumps until the end of the current memory block.
//
// Useful for extracting embedded payloads, unpacked code, or shellcode.
//
// Url: https://github.com/iss4cf0ng/issac-reverse-toolbox/blob/main/Ghidra/DumpPayload.java
//@author iss4cf0ng/ISSAC
//@category Memory
//@keybinding
//@menupath
//@toolbar
//@runtime Java

import ghidra.app.script.GhidraScript;
import ghidra.program.model.mem.*;
import ghidra.program.model.address.*;
import java.io.File;
import java.io.FileOutputStream;

public class DumpPayload extends GhidraScript {

@Override
public void run() throws Exception {

Address startAddr = askAddress(
"Payload Dumper",
"Start address (e.g. 0x00400000): "
);

int size = askInt(
"Payload Dumper",
"Size in bytes (0 = auto to end of block): "
);

File output = askFile("Save payload", "Save");

Memory mem = currentProgram.getMemory();

//Auto size
if (size == 0) {
MemoryBlock block = mem.getBlock(startAddr);

if (block == null) {
printerr("[-] Address is not inside any memory block.");
return;
}

size = (int)(block.getEnd().subtract(startAddr) + 1);

println("[*] Auto size detected: " + size + " bytes");
} else {
Address endAddr = startAddr.add(size - 1);
println("[*] Dump range: " + startAddr + " - " + endAddr);
}

//Read memory
byte[] payload;

try {
payload = getBytes(startAddr, size);
} catch (Exception e) {
printerr("[-] Failed to read memory: " + e.getMessage());
return;
}

//Write file
try (FileOutputStream fs = new FileOutputStream(output)) {
fs.write(payload);
println("[+] Saved payload: " + output.getAbsolutePath());
} catch (Exception e) {
printerr("[-] Failed to write file: " + e.getMessage());
}
}
}

Execute the script:

Enter address:

Then the stage 2 payload can be successfully dumped.

Open the malware using ExeInfo PE and DIE:

ExeInfo PE

DIE

DIE — Entropy

Open the malware using Ghidra:

NotPetya restarts itself after a long interval (13 ~ 63 minutes). This design is used for worming since it allows the malware to infect as many machines as possible.

hexadecimal 0x3C is 60 in decimal representation

This mechanism can be summarized below:

flowchart TD A[Program Start] --> B[GetTickCount saved as DAT_1001f118] B --> C[Parse command-line arguments FUN_10006a2b] C --> D{Is a minute value provided?} D -- Yes --> E[DAT_1001f760 = input value] D -- No --> F[DAT_1001f760 = 60 minutes default] E --> G F --> G G["Compute elapsed time\nelapsed = (now - start) / 60000"] --> H{remaining = DAT_1001f760 - elapsed > 0?} H -- Yes --> I[remaining = DAT_1001f760 - elapsed] H -- No --> J[remaining = 0] I --> K J --> K K{remaining < 10?} -- Yes --> L[delay = 10 minutes] K -- No --> M[delay = remaining minutes] L --> N M --> N N[final_delay = delay + 3 minutes] --> O[Compute reboot time = now + final_delay] O --> P{Windows version check} P -- Version > 5 --> Q[Use schtasks /Create /SC once /TR shutdown.exe /r /f] P -- Version <= 5 --> R[Use at command shutdown.exe /r /f] Q --> S[Schedule forced reboot] R --> S S --> T[End]

This malware also contains other embedded payloads. They can also be dumped by the above Ghidra script. However, I rewrote it into a new version with auto size functionality.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
//DumpAllPayloads.java
//@author iss4cf0ng/ISSAC
//@category Memory
//@keybinding
//@menupath
//@toolbar
//@runtime Java

import ghidra.app.script.GhidraScript;
import ghidra.program.model.mem.*;
import ghidra.program.model.address.*;

import java.io.*;
import java.util.zip.Inflater;

public class DumpAllPayloads extends GhidraScript {

@Override
public void run() throws Exception {

println("[*] Scanning .rsrc for zlib...");

MemoryBlock rsrc = null;

for (MemoryBlock b : currentProgram.getMemory().getBlocks()) {
if (b.getName().toLowerCase().contains("rsrc")) {
rsrc = b;
break;
}
}

if (rsrc == null) {
println("[-] .rsrc not found");
return;
}

byte[] data = new byte[(int) rsrc.getSize()];
rsrc.getBytes(rsrc.getStart(), data);

println("[+] .rsrc size = " + data.length);

int count = 0;

for (int i = 0; i < data.length - 2; i++) {

// 找 zlib header
if ((data[i] == 0x78) &&
(data[i+1] == (byte)0xDA || data[i+1] == (byte)0x9C)) {

println("[+] Found zlib at offset: " + i);

byte[] out = decompress(data, i);

if (out == null || out.length == 0) {
println("[-] Decompress failed");
continue;
}

boolean isPE = out.length > 2 &&
out[0] == 'M' &&
out[1] == 'Z';

String name = "dump_" + count + (isPE ? ".pe_file" : ".bin");

File f = askFile("Save " + name, "Save");

FileOutputStream fos = new FileOutputStream(f);
fos.write(out);
fos.close();

println("[+] Saved: " + name);

count++;
}
}

println("[*] Done. Found " + count + " zlib streams.");
}

private byte[] decompress(byte[] data, int offset) {
try {
Inflater inflater = new Inflater();
inflater.setInput(data, offset, data.length - offset);

ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] buf = new byte[4096];

while (!inflater.finished()) {
int n = inflater.inflate(buf);
if (n == 0) break;
bos.write(buf, 0, n);
}

inflater.end();
return bos.toByteArray();

} catch (Exception e) {
return null;
}
}
}

After executing the script, 3 files were saved:

  • dump_0.pe_file: mimikatz
  • dump_1.pe_file: Petya DLL (does not relate to this analysis)
  • dump_2.pe_file: psexec tool

VirusTotal — dump_0.pe_file

VirusTotal — dump_1.pe_file

VirusTotal — dump_2.pe_file

So, how does the malware work? At the beginning, the malware overwrites PhysicalDrive0:

Overwrite PhysicalDrive0

Note: Therefore, if the malware started to scan other devices, the physical drive of the infected devices had already overwritten.

Next, it extracts available devices on the network via different APIs. Unlike WannaCry — scanning all potential devices — this design significantly enhances efficiency.

GetComputerNameExW(), NetBIOS

GetAdaptersInfo()

GetIpNetTable()

GetExtendedTcpTable()

Then, the malware scans ports 139 and 445 to check alive:

Note: Hexadecimal 0x8b and 0x1bd are 139 and 445 in decimal representation respectively.

After extracting available devices on the network. It enters the penetration phase.

File dump_0.pe_file is a mimikatz file, which is used for dumping credentials of Windows operating systems. In addition, the credentials can also be extracted via CredEnumerateW() API.

CredEnumerateW()

Mimikatz and CredEnumerateW() credential extraction:

Next, the malware enters propagation phase.

The dumped credentials will then be used for exploiting via psexec and wmic. psexec and wmic are powerful remote Windows systems administration tool, which are also widely used in domain penetration.

Propagation via psexec and wmic

Subsequently, the malware propagates other devices via EternalBlue and EternalRomance, both of them exploit SMB protocol.

Note: As mentioned in previous articles, both vulnerabilities are very complex. Therefore, I will study them in the future articles.

EternalBlue

Construct exploit packet

Send exploit packet

EternalRomance


Last, NotPetya enters file encryption phase. It randomly generates a AES key for all file encryption:

Then, it encrypts all files with the following extensions:

Note that NotPetya skips C:\Windows\ for maintaining system stability.

File encryption

Leaving extortion message in README.md

The AES key will then be destroyed after encryption:

The MBR of the file system can theoretically be decrypted if the key is correct. However, the key used for decryption MBR cannot be used for decrypting all encrypted files.

Therefore, systems which infected NotPetya are practically unrecoverable.

Conclusion

This article presents an analysis of NotPetya, focusing on its propagation strategy, credential harvesting, and destructive behavior.

Unlike the original Petya, NotPetya integrates multiple propagation techniques, including SMB exploits (EternalBlue, EternalRomance) and credential-based lateral movement using Mimikatz, PsExec, and WMIC. This combination allows the malware to spread rapidly within internal networks, making it significantly more dangerous in enterprise environments.

From a design perspective, NotPetya demonstrates a clear shift from ransomware to destructive malware.

The encryption key is irreversibly destroyed. This characteristic indicates that financial gain is not the primary objective. Instead, the malware is designed to maximize disruption and damage.

Compared to WannaCry and Petya, NotPetya represents a different evolutionary path:

  • WannaCry: automated, large-scale worming
  • Petya: low-level disk manipulation (MBR/MFT)
  • NotPetya: targeted, enterprise-level destruction with efficient lateral movement

NotPetya is not just ransomware, it is a weaponized cyberattack disguised as one.

If you have any comments or suggestions, please feel free to leave them below!

References

1. https://en.wikipedia.org/wiki/Petya_(malware_family)

THANKS FOR READING