Playing With Named Pipe and NotPetya

A long time ago, in a galaxy far far away, I was having fun reversing NotPetya.

Files dropped by NotPetya

During the dynamical analysis, I identified some files dropped on the disk by the sample.

Files dropped in the disk

Files dropped in the disk

An executed file using named pipe

One of them caught my eye: it is executed by the sample with a named pipe argument.

A binary executed with named pipe argument

A binary executed with named pipe argument

Finding named pipe in NotPetya

I’ve never played with named pipe before and I was curious about the data that will potentially be exchanged through it. I searched for references of an API using named pipe in the sample.

API related to named pipe in the sample import table

API related to named pipe in the sample import table

And I found some: CreateNamedPipeW, ConnectNamedPipe and so on. I searched through the code calls to these functions and found a section calling:

  1. CreateNamedPipeW
  2. ConnectNamedPipe
  3. PeekNamedPipe
Calls to API related named pipes

Calls to API related named pipes

Stealing the data exchanged through the named pipe!

During the analysis, I noticed that the binary using named pipe was always dropped in the same directory: C:\Users\%USERNAME%\AppData\Local\Temp. The file name followed a pattern: 4 alpha-numeric characters and a .tmp extension.

I managed to retrieve the target binary dropped by the sample to perform some tests.

To access the data exchange between the sample and this binary, I needed to emulate the “named pipe server” set up by the sample. I gathered from the assembly code:

  1. The sample is creating a named pipe set up as a server on its side
  2. Waits for a connection on it
  3. One connection is made, gets all the data in the named pipe.

I coded something reproducing this part of the sample code:

// Emulation of the NotPetya named pipe server 
// By Alice Climent-Pommeret 

// To compile on linux
// sudo apt install g++-mingw-w64
// i686-w64-mingw32-g++ -static NamedPipeServerNotPetya.cpp -o NamedPipeServerNotPetya.exe

#include <iostream>
#include <windows.h>
using namespace std;
int main(int argc, const char **argv)

    wcout << "" << endl;
    wcout << "Creation of a named pipe called \\\\.\\pipe\\my_pipe" << endl;
    //pipe creation
    HANDLE pipe = CreateNamedPipe(
        "\\\\.\\pipe\\my_pipe", // name of the pipe
        3, // PIPE_ACCESS_DUPLEX
        1, // only one instance of the named pipe
        0, // no outbound buffer
        0, // no inbound buffer
        0, // use default wait time
        NULL // use default security attributes

    if (pipe == NULL || pipe == INVALID_HANDLE_VALUE) {
        wcout << "The named pipe creation failed";
        return 1;
    wcout << "Waiting for a client connection" << endl;
    if (ConnectNamedPipe(pipe, NULL)){// This call blocks the process here until a client connection to the pipe
        wcout << "Reading data from the named pipe" << endl;
        wchar_t buffer[2048];
        DWORD numBytesRead = 0;
        // Read data from the pipe
        while (ReadFile(pipe, buffer, 2048 * sizeof(wchar_t), &numBytesRead, NULL)){
       	    wcout << "Credentials sent by the NotPetya dropped binary: " << buffer << endl;
    //Close the pipe
    wcout << "Done !" << endl;
    return 0;

To test it, I ran the “named pipe server” in a terminal. At first, the server waits for incoming connections. Then I ran, in an administrator terminal, the dropped binary.

Since the “named pipe server” creates a named pipe called \\.\pipe\my_pipe, give this as a parameter to the dropped binary.


Calls to API related named pipes

Calls to API related named pipes

User creds are sent by the mysterious dropped binary… It may be some kind of Mimikatz like…

But this is another topic :)

You can find the C++ source code in this article in my GitHub repository