The Back Orifice Protocol

# The Back Orifice (BO) Protocol

## Introductory Notes

- This specification was obtained by looking at the sources of the BO client for Unix and in the development stage of NOBO. It probably doesn't cover all aspects of the protocol and may contain incorrect information; such items are tagged with "(???)". If you find something missing or wrong in this document, please, let me know.
- All numeric values are represented in decimal notation or, if prefixed with a "`0x`" (e.g. "`0x0f`"), in hexadecimal, unless noted otherwise.

## The Protocol

The exchange of data between the BO client and server is done using encrypted UDP packets. The format of these packer's is simple, as is the cryptographic scheme used. The server normally binds to UDP port 31337, but it may be configured to use another port. All BO packets -- from the server to the client and vice-versa -- have the same basic format. Notice that even if no password is set up on the server and client, BO packets are always encrypted.

## Packet Format

BO packets are composed of a 17 bytes header which contains the characteristics of the packet, plus payload data (at least 1 byte). The packets ends with a one byte CRC (???).

### Packets fields:

Mnemonic | Size in bytes
--- | ---
MAGIC | 8
LEN | 4
ID | 4
T | 1
DATA | variable
CRC | 1

#### Header Fields

MAGIC - An eight byte string which identifies the BO packet. The sequence of characters is fixed and must be the string "`*!*QWTY?`" (star, bang, star, "Q", "W", "T", "Y", question).

LEN - A 32 bit integer which contains the length of the entire packet, including the header. The value of this field cannot be less than 19 (the header length plus, at least, 1 byte data and 1 byte CRC).

ID - A 32 bit integer which contains the identification of the UDP packet. This field is used to keep track of the fragment sequence number of fragmented packets (???). It's also used by the BO client to match a received packet with previously packets sent.

> The "32 bit integers" used in the header of BO packets aren't transmitted in network order, but with its least significant byte sent first. For example, the "integer" `0x11bb55ee` is transmitted is this order: `0xee`, `0x55`, `0xbb` and `0x11`.

T - This field contains the operation type that the packet carries. In this field, the 2 most significant bits are used to flag some conditions about the packet, such as the fragmentation of a large packet. The remaining 6 bits are used to specify the actual BO operation.

### BO Operations

Mnemonic | Value | Meaning
--- | --- | ---
TYPE_ERROR | 0x00 | Error (???)
TYPE_PING | 0x01 | "Ping" packet
TYPE_SYSREBOOT | 0x02 | System reboot
TYPE_SYSLOCKUP | 0x03 | System lock up
TYPE_SYSLISTPASSWORDS | 0x04 | List system passwords
TYPE_SYSVIEWCONSOLE | 0x05 | View console (???)
TYPE_SYSINFO | 0x06 | Get system information
TYPE_SYSLOGKEYS | 0x07 | Log pressed keys
TYPE_SYSENDKEYLOG | 0x08 | Send keypress log
TYPE_SYSDIALOGBOX | 0x09 | Show a dialog box (message box)
TYPE_REGISTRYDELETEVALUE | 0x0a | Delete an value from the registry
TYPE_REDIRADD | 0x0b | Create TCP redirection (proxy)
TYPE_REDIRDEL | 0x0c | Delete TCP redirection
TYPE_REDIRLIST | 0x0d | List TCP redirections
TYPE_APPADD | 0x0e | Start application
TYPE_APPDEL | 0x0f | End application
TYPE_NETEXPORTADD | 0x10 | Export a share resource
TYPE_NETEXPORTDELETE | 0x11 | Cancel share export
TYPE_NETEXPORTLIST | 0x12 | Show export list
TYPE_PACKETRESEND | 0x13 | Resend packet (???)
TYPE_HTTPENABLE | 0x14 | Enable HTTP server
TYPE_HTTPDISABLE | 0x15 | Disable HTTP server
TYPE_RESOLVEHOST | 0x16 | Resolve host name
TYPE_FILEFREEZE | 0x17 | Compress a file
TYPE_FILEMELT | 0x18 | Uncompress a file
TYPE_PLUGINEXECUTE | 0x19 | Plug-in execute
TYPE_PROCESSLIST | 0x20 | Show active processes
TYPE_PROCESSKILL | 0x21 | Kill a process
TYPE_PROCESSSPAWN | 0x22 | Start a process
TYPE_REGISTRYCREATEKEY | 0x23 | Create a key in the registry
TYPE_REGISTRYSETVALUE | 0x24 | Set the value of a key in the registry
TYPE_REGISTRYDELETEKEY | 0x25 | Delete a key in the registry
TYPE_REGISTRYENUMKEYS | 0x26 | Enumerate registry keys
TYPE_REGISTRYENUMVALS | 0x27 | Enumerate registry values
TYPE_MMCAPFRAME | 0x28 | Capture a static image (.BMP) from the video capture device
TYPE_MMCAPAVI | 0x29 | Capture a video stream (.AVI) from the video capture device
TYPE_MMPLAYSOUND | 0x2a | Play a sound file (.WAV)
TYPE_MMLISTCAPS | 0x2b | Show available image/video capture devices
TYPE_MMCAPSCREEN | 0x2c | Capture the screen to a file (.BMP)
TYPE_TCPFILESEND | 0x2d | Start sending a file using TCP
TYPE_TCPFILERECEIVE | 0x2e | Start receiving a file using TCP
TYPE_PLUGINLIST | 0x2f | List (running) plug-ins
TYPE_PLUGINKILL | 0x30 | Kill plug-in
TYPE_DIRECTORYLIST | 0x31 | List directory
TYPE_FILEFIND | 0x34 | Find a file
TYPE_FILEDELETE | 0x35 | Delete a file
TYPE_FILEVIEW | 0x36 | View file contents
TYPE_FILERENAME | 0x37 | Rename a file
TYPE_FILECOPY | 0x38 | Copy a file
TYPE_NETVIEW | 0x39 | List all network devices, domain names and shares
TYPE_NETUSE | 0x3a | Connect a network resource
TYPE_NETDELETE | 0x3b | End connection of a network resource
TYPE_NETCONNECTIONS | 0x3c | Show network connections
TYPE_DIRECTORYMAKE | 0x3d | Create directory (folder)
TYPE_DIRECTORYDELETE | 0x3e | Remove directory
TYPE_APPLIST | 0x3f | Show running applications

### Two most Significant Bits from the Packet Type Byte

Mnemonic | Mask | Meaning
--- | --- | ---
PARTIAL_PACKET | 0x80 | This is a partial packet, i.e. expect more to come
CONTINUED_PACKET | 0x40 | This is a fragment of a fragmented packet

> These two flags are usually combined in intermediate packets containing fragments of a bigger "packet". For example, a big packet fragmented in 4 smaller ones would be send with the following flags:

> >     1. PARTIAL_PACKET
> >     2. PARTIAL_PACKET | CONTINUED_PACKET
> >     3. PARTIAL_PACKET | CONTINUED_PACKET
> >     4. CONTINUED_PACKET

## Data

The data field of a BO packet comes right after the header. It's composed of a simple sequence of characters, ended by a character with ASCII code 0 (zero) -- NUL. This terminator character is mandatory -- this mean that the data field must be at least 1 byte long (???).

The contents of the data field should be interpreted differently if the packet goes from the server to the client, or if it goes in the opposite way (???). In packets going from the client to the server, up to two string sequences can be sent in the data field, as they're separated by a NUL character. In packets going from the server to the client, there is only one string (???) with the command response.

### Data "Fields"

Packet Type | Field 1 | Field 2
--- | --- | ---
TYPE_ERROR | (???) | (???)
TYPE_PING | N/A | N/A
TYPE_SYSREBOOT | N/A | N/A
TYPE_SYSLOCKUP | N/A | N/A
TYPE_SYSLISTPASSWORDS | N/A | N/A
TYPE_SYSVIEWCONSOLE | (???) | (???)
TYPE_SYSINFO | N/A | N/A
TYPE_SYSLOGKEYS | File name | N/A
TYPE_SYSENDKEYLOG | N/A | N/A
TYPE_SYSDIALOGBOX | Text | Title
TYPE_REGISTRYDELETEVALUE | Value name | N/A
TYPE_REDIRADD | Port to open | Address:port
TYPE_REDIRDEL | Identification | N/A
TYPE_REDIRLIST | N/A | N/A
TYPE_APPADD | Executable file name | TCP port
TYPE_APPDEL | Identification | N/A
TYPE_NETEXPORTADD | Share | Directory, password, note
TYPE_NETEXPORTDELETE | Share | N/A
TYPE_NETEXPORTLIST | N/A | N/A
TYPE_PACKETRESEND | (???) | (???)
TYPE_HTTPENABLE | Port | Server's root directory
TYPE_HTTPDISABLE | N/A | N/A
TYPE_RESOLVEHOST | Host name | N/A
TYPE_FILEFREEZE | Input file | Output file
TYPE_FILEMELT | Input file | Output file
TYPE_PLUGINEXECUTE | DLL:Function | Parameters
TYPE_PROCESSLIST | N/A | N/A
TYPE_PROCESSKILL | Identification | N/A
TYPE_PROCESSSPAWN | Executable file name and arguments | Visible1
TYPE_REGISTRYCREATEKEY | Key | N/A
TYPE_REGISTRYSETVALUE | Value name | Type,value2
TYPE_REGISTRYDELETEKEY | Key | N/A
TYPE_REGISTRYENUMKEYS | Key | N/A
TYPE_REGISTRYENUMVALS | Key | N/A
TYPE_MMCAPFRAME | .BMP file | Device,width,height,bits
TYPE_MMCAPAVI | .AVI file | Device,seconds,width,height,bits
TYPE_MMPLAYSOUND | .WAV file | N/A
TYPE_MMLISTCAPS | N/A | N/A
TYPE_MMCAPSCREEN | .BMP file | N/A
TYPE_TCPFILESEND | File name | Address:port
TYPE_TCPFILERECEIVE | File name | Address:port
TYPE_PLUGINLIST | N/A | N/A
TYPE_PLUGINKILL | Identification | N/A
TYPE_DIRECTORYLIST | Directory | N/A
TYPE_FILEFIND | Name (wildcards allowed) | Root
TYPE_FILEDELETE | File name | N/A
TYPE_FILEVIEW | File name | N/A
TYPE_FILERENAME | Old file (???) | New file (???)
TYPE_FILECOPY | Source file | Destination file
TYPE_NETVIEW | N/A | N/A
TYPE_NETUSE | Network resource | Password
TYPE_NETDELETE | Resource | N/A
TYPE_NETCONNECTIONS | N/A | N/A
TYPE_DIRECTORYMAKE | Name of the new directory | N/A
TYPE_DIRECTORYDELETE | Directory name | N/A
TYPE_APPLIST | N/A | N/A

> 1 If the second parameter is present, the application is made visible. Otherwise, it is run hidden.

> 2 The type can be "B" for binary, "D" for a double word (DWORD) and "S" for a string of character. In binary fields, the value is a string containing a sequence of two hexadecimal digits (e.g. "`ab 11 5f`"); in double word fields, the value should be specified as a string containing the decimal representation of the DWORD; in string fields, the value is the string.

## CRC

After the data field, there is a 1-byte field containing the CRC of the packet (???). The BO server seems to silently ignore the value of this byte.

## Cryptography

All BO packets are encrypted. The entire BO packet (including the header) is encrypted. The cryptographic scheme used is simple, and depends on a secret key (the password) which must be known by the two parties. The password is used only to encrypt packets; the password never travels over the network.

The encryption is done applying a XOR (exclusive or) operation between each byte of the packet and the sequential value returned by a random number generator. This generator is initialized with a value which depends on the secret password being used in the communication. This way, having the same password, both random number generator (the server's and the client's one) will be initialized with the same seed, and they will return the same sequence of "random" numbers which will be used to encrypt/decrypt the packet.

This cryptographic scheme isn't strong. As all of the packet contents is encrypted, and they always contain a fixed sequence of characters (MAGIC) in the header, from inspection of a single encrypted packet it may be possible to obtain the initial sequence of random numbers generated and use a brute force attack to discover the random number generator seed. This is very feasible because the range of possible values is somewhat small. The methods used to decrypt and encrypt a BO packet without knowing the password being used are out of the scope of this document, and are left as an exercise to the reader.

### The Random Number Generator

The BO protocol uses the following random number generator function:

> `BORAND(x) = (x * 214013) + 2531011`

Where "`A * B`" denotes the multiplication of A by B, and "`+`" the usual sum operation.

The value of the initial parameter (the seed) is derived from the communication password (see below). The next value is always the result of the value returned by the last run. For example, a sequence of "random" numbers `X1, X2, ..., Xn` can be obtained in the following way:

>     X1 = BORAND(IV)
>     X2 = BORAND(X1)
>     X3 = BORAND(X2)
>         ...
>     Xn = BORAND(Xn - 1)

Where `IV` is the seed and `Xn` is the nth random number.

### The Seed

The seed to be used on the BO random number generator is generated using the communication password. If no password is being used, the special value of 31337 is used as the seed. Otherwise, the following algorithm gives the seed from a password `S`:

>     X = 0
>     Y = length (number of characters) of S
>     Z = 0
>     WHILE X < Y
>     	Z = Z + S[X]
>     	X = X + 1
>     END

>     X = 0
>     WHILE X < Y
>     	IF X is odd
>     		Z = Z - (S[X] * (Y - X + 1))
>     	ELSE
>     		Z = Z + (S[X] * (Y - X + 1))
>     	END
>     	Z = Z % 0x7fffffff
>     	X = X + 1
>     END
>     Z = (Z * Y) % 0x7fffffff
>     IV = Z

Where "`S[n]`" is the nth character of the password, "`A % B`" the remainder of the division of A by B, and "`IV`" the seed we're looking for.

Note: the random number generator is reinitialized with the a new seed every time a packet is sent.

Note: the variables `X`, `Y` and `Z` are all 32 bit integer. This mean that the most significant bits above the 32nd one should be ignored when an overflow occurs.

## Encrypting/decrypting

The following algorithm is a demonstration of how a BO packet can be encrypted or decrypted:

>     L = length of the BO packet
>     X = 0
>     Z = IV
>     WHILE X < L
>     	Z = BORAND(Z)
>      	P[X] = P[X] ^ ((Z >> 16) & 0xff)
>     	X = X + 1
>     END

Where "`P[n]`" denotes the nth byte of the packet, "`A ^ B`" the bitwise XOR operation between A and B, "`A >> B`" the 32 bit shift of A by B bits to the right, and "`A & B`" the bitwise AND operation between A and B.

## TCP file transfer

The transfer of files using TCP (operations TYPE_TCPFILESEND and TYPE_TCPFILERECIVED) is done with the server opening the port specified in the parameter of the command.

When the client sends a TYPE_TCPFILESEND packet, the server opens the file specified and start listening for a TCP connection on the specified TCP port. Then the client connects to that port and start sending the file.

When the client wishes to receive a file, it sends a TYPE_TCPFILERECEIVE packet specifying the desired file name and the TCP port. The server will then open the specified port and start transferring the file as soon as someone (probably the client) connects to it.

The TCP stream is not encrypted.

> All this TCP file send/receive stuff is "(???)".

## References

- BO client for Unix
- ISS Security Alert Advisory (X-FORCE) -- "Cult of the Dead Cow Back Orifice Backdoor"

## Copyright/disclaimer

Copyright © 1998-2001 by Flávio Veloso. All rights reserved.

This document and its contents may be copied, used entirely or as basis for derived work, either entirely or in parts, freely without the need of the author authorization, provided that he must be credited for this work. Also, any copies of this document can be changed, translated, fixed, etc., without the need of author authorization provided that the changes are explicitly noted in the changed copy (which does not remove the need of author credits).

You do assume all risk and responsibility arising from the use of any information contained on this document. In no moment the author warrants that this document is entirely correct, and he cannot be made responsible if it isn't. If you find any mistake in this document, or have some information you think will contribute to make it more precise, please mail me at flaviovs@magnux.com. Any information which may help me to get rid of those "(???)" are welcome!

## Thanks

Thanks to the following people who helped me to fix or improve this document:

> Markus <markus@?????????.nl>
> J.M. Colàs <jmcolas@mx3.redestb.es>

-x-x-

Last updated on November 22, 2001