Documentation ¶
Index ¶
Constants ¶
const ( SuccessDNSResponse = "1.1.1.1" FailureDNSResponse = "1.1.1.2" )
Response codes sent as DNS answers.
const ( FileProtocol = iota CmdProtocol UploadProtocol CobaltStrikeProtocol )
Protocols understood
const ( PollTypeUndefined = iota PollTypeCheckin PollTypeUpload )
PollTypes to expect from agents.
const ( StreamStart = 0xbe StreamData = 0xef StreamEnd = 0xca )
Request stream status
const MaxLabelSize = 63
MaxLabelSize is the maximum size a DNS hostname label may be.
Variables ¶
var ( NoCmdTxtResponse = "v=B2B3FE1C" ErrorTxtResponse = "v=D31CFAA4" CmdTxtResponse = "v=A9F466E8" UploadTxtResponse = "v=H34FERKL" )
TXT record default responses
Functions ¶
func ARequestify ¶
ARequestify generates hostnames for DNS lookups via A records. This is typically for data streams coming from the client to the server.
A full conversation with the server will involve multiple DNS lookups. Requestifying assumes that the client will be sending data to the server. Each request normally requires the server to respond with a specific IP address indicating success, failure or other scenarios. Checking these is up to the caller to verify, but something to keep in mind.
Generically speaking, hostnames for lookups will have multiple labels. ie:
Structure: ident.type.seq.crc32.proto.datalen.data.data.data ident: the identifier for this specific stream type: stream status indicator. ie: start, sending, stop seq: a sequence number to track request count crc32: checksum value proto: the protocol this transaction is for. eg: file transfer/cmd datalen: how much data does this packet have data: the labels containing data. max of 3 but can have only one too Size: 4 + 2 + 16 + 8 + 2 + 2 + 60 + 60 + 60 for a maximum size of 214 Sample: 0000.00.0000000000000000.00000000.00.00.60.60.60
Note: Where the label lenths may be something like 60, a byte takes two of those, meaning that each data label is only 30 bytes for a total of 90 bytes per request, excluding ident, seq and crc32.
func TXTRequestify ¶
TXTRequestify creates TXT record responses for data transfer. This is typically for data streams to an agent.
Unlike A record responses that have markers to indicate stream status, TXT record chunks are just a list of payloads in order to be appended together on the agent side. A TXT record response has the following format.
Structure: ident.seq.crc32.proto.datalen.data ident: the identifier for this specific stream seq: a sequence number to track request count crc32: checksum value proto: the protocol this transaction is for. eg: file transfer/cmd datalen: how much data does this packet have data: the labels containing data. max of 3 but can have only one too Size: 4 + 16 + 8 + 2 + 2 + 200 (max) for a maximum size of 233 Sample: 0000.0000000000000000.00000000.00.00.00000000000000...
Types ¶
type Command ¶
type Command struct { Exec string `json:"exec"` Data []byte `json:"data"` ExecTime int64 `json:"exectime"` Identifier string `json:"identifier"` }
Command represents a command to be send over DNS.
func (*Command) GetOutgoing ¶
GetOutgoing returns the hostnames to lookup as part of a file transfer operation.
func (*Command) GetRequests ¶
GetRequests returns the hostnames to lookup as part of a command output operation.
type File ¶
type File struct { Size int64 `json:"size"` Shasum string `json:"shasum"` Name string `json:"name"` Destination string `json:"destination"` Data *[]byte `json:"data"` Identifier string `json:"identifier"` }
File represents a file to be send over DNS.
func (*File) GetARequests ¶
GetARequests returns the hostnames to lookup as part of a file transfer operation via A records.
func (*File) GetTXTRequests ¶
GetTXTRequests returns the TXT record contents to return as part of a file transfer operation via TXT records
type FileTransport ¶
FileTransport defines properties, as well as the data for a file.