ABOH 2023: MetalPipe
This is not a typical ReverseMe binary. You will need to write a malicious application to weaponize the bug.
Last updated
This is not a typical ReverseMe binary. You will need to write a malicious application to weaponize the bug.
Last updated
This writeup is written from the author's perspective to showcase the challenge design, and may or may not reflect the typical approach or methodology involved to solve the challenge.
Named Pipes are traditionally used for Inter-Process Communication (IPC) and store data on a First-In-First-Out (FIFO) basis. The main idea is that, named pipes are initialized as a shared memory space by the Windows Operating System, which allows any process to access it without any form of authentication, as long as the attacker knows the pipe name. The nature of this makes it vulnerable to Race Condition vulnerabilities.
This challenge is inspired by the CWE-421: Race Condition During Access to Alternate Channel flaw.
Running the executable shows that it is establishing some kind of connection at a constant interval.
NOTE: In named pipe nomenclature, the owner of a named pipe is known as the
Server
; whereas the entity accessing it is known as theClient
. Additionally, a named pipe is treated as a file object after it is created withCreateNamedPipeW
; whereasCreateFileW
here simply means theClient
is accessing the named pipe.
Looking at the decompiled code (symbols renamed for readability), we see signs of client-side code in the main function. On the other hand, server-side code is invoked in a separate thread.
Within the server thread, we see that a named pipe with the name \\.\pipe\battle-of-hackers
is created and awaits for incoming client connection with the ConnectNamedPipe
function.
To understand the properties of a named pipe, we'll have to cross-reference parameters used in Named Pipe creation with MSDN.
Cross-referencing the dwOpenMode
parameter, we know that the named pipe is initialized in Simplex mode, which allows data to flow from the Client
to the Server
, but not the other way around.
Mode
Meaning
PIPE_ACCESS_DUPLEX 0x00000003
The pipe is bi-directional; both server and client processes can read from and write to the pipe. This mode gives the server the equivalent of GENERIC_READ and GENERIC_WRITE access to the pipe. The client can specify GENERIC_READ or GENERIC_WRITE, or both, when it connects to the pipe using the CreateFile function.
PIPE_ACCESS_INBOUND 0x00000001
The flow of data in the pipe goes from client to server only. This mode gives the server the equivalent of GENERIC_READ access to the pipe. The client must specify GENERIC_WRITE access when connecting to the pipe. If the client must read pipe settings by calling the GetNamedPipeInfo or GetNamedPipeHandleState functions, the client must specify GENERIC_WRITE and FILE_READ_ATTRIBUTES access when connecting to the pipe.
PIPE_ACCESS_OUTBOUND 0x00000002
The flow of data in the pipe goes from server to client only. This mode gives the server the equivalent of GENERIC_WRITE access to the pipe. The client must specify GENERIC_READ access when connecting to the pipe. If the client must change pipe settings by calling the SetNamedPipeHandleState function, the client must specify GENERIC_READ and FILE_WRITE_ATTRIBUTES access when connecting to the pipe.
Additionally, this parameter may also include one or more extra flags such as:
Mode
Meaning
FILE_FLAG_FIRST_PIPE_INSTANCE 0x00080000
If you attempt to create multiple instances of a pipe with this flag, creation of the first instance succeeds, but creation of the next instance fails with ERROR_ACCESS_DENIED.
The core of this challenge depends on the fact that the named pipe was not not initialized with the FILE_FLAG_FIRST_PIPE_INSTANCE
flag, leading to an Instance Creation Race Condition. Without this flag, the Server
will not throw an error if multiple instances of named pipes with the same name are created at the same time.
You probably see where this is going... Data flowing from Client to Server in a Race Condition scenario means that we can spawn a Rogue Server
with the same pipe name and induce/coerce the Client
into sending data to us instead of the legitimate Server
!
To mount this attack, all we need to do is create a named pipe instance with the right name at the right time and hijack the data flow (flag is in reverse order):
Flag: ABOH{1nst4nc3_cr34710n_r4c3_c0nd1710n_CWE-421}