Page personnelle de Nicolas Favre-Félix

The NetSend Protocol


Simple description

The server

The server listens on UDP port 135. When it receives a well-formed UDP packet, the server checks if the service is started. If it is, the packet is decoded and its content showed in a pop-up. A confirmation or reject message can be sent.

The client

The client sends a UDP packet to the server, with 3 fields : FROM, TO, and MESSAGE. These fields will be decoded by the server and shown. No matter where the packet comes from, the FROM field will be presented to the user instead of the real sender address.


Packet description

The packet has two main parts : the DCE RPC Header (Distributed Computing Environment Remote Procedure Call), and the message itself.
The examples below come from real packets. If some fields are different, it migth also work in some cases. We will describe little-endian encodings, because I have no big-endian computer to test the code.

The DCE-RPC Header

Its size is always equal to 0x50=80 bytes (offset 0x00 to 0x4f)

OFFSET NAME SIZE EXAMPLE DESCRIPTION
0x00 RPC Version 0x01 0x04 Must be 0x04
0x01 Packet Type 0x01 0x00 Must be 0x00 (request)
0x02 Flags 1 0x01 0x78 Packet options
0x03 Flags 2 0x01 0x00 Reserved (must be 0)
0x04 Data Format 0x100000 Little-endian
0x07 Serial High 0x00 Must be 0
0x08 Obj UUID 0x10 0x00 (*16) Must be 0
0x18 Interface 0x10 See source
0x28 Activity 0x10 See source
0x38 Server boot 0x04 0x00000000 Server boot time (0 ok)
0x3C Interface v 0x04 0x01000000 Interface version(1 ok)
0x40 Sequence # 0x00 0x00000000 Sequence number (0 ok)
0x44 Opnum 0x02 0x0000 Operation number (0 ok)
0x46 If Hint 0x02 0xffff Interface Hint (0xffff)
0x48 Activity Ht 0x02 0xffff Activity Hint (0xffff)
0x4a Lenght 0x02 0x1000 Second part lenght
0x4c Fragment # 0x01 0x00 For very long messages
0x4d Auth proto 0x01 0x00 None -> 0x00
0x4e Serial low 0x01 0x00 Must be 0

The message

There are three parts in the message (FROM, TO, MESSAGE). Between FROM and TO and between TO and MESSAGE, there is a padding. You can set it to anything, but MS put zeros in. Its size is quite weird :

padding-after = 3- ((x-1) % 4)

where x is the size of the null-terminated string.
For example, if you want to send a message from "SantaClaus\x00", to "LittleKid\x00", the padding after FROM will be : 3-((11-1) % 4) = 3-2 = 1 byte. And the padding after TO will be 3-((10-1) % 4) = 3-1 = 2 bytes.
Each part is composed of four fields :

  • Max count : 4 bytes, little endian (the total part size, in all packets).
  • Offset : 4 bytes, little endian (the offset in the packet, 0x00 if only one packet).
  • Actual count : 4 bytes, little endian (the number of bytes in all packets for this part).
  • Value : null-terminated string, data for this packet.

There may be more than one packet if the message is really long. So, the offset is the global position in data, actual count is the number of bytes for this packet, and max count the number of bytes in all packets.