An interesting feature of the backdoor program is its use as a distributed denial of service (DDoS) tool. When the backdoor receives a command from the attacker (containing the victim's ip address or hostname), it starts a DoS attack against it. The DoS packet engine is very flexible and allows for many different kinds of attacks: udp flood, tcp flood, ping flood, smurf attack, dns smurf attack. With enought machines under the attacker's control, she can successfully impact major Internet sites, as evidenced by the events in Februrary 2000.
Parameters: src, dst, hostname
Similar to udp_flood, but sends ICMP echo request packets.
A variation of this attack is the ICMP smurf attack. If the attacker sends spoofed ICMP echo requests to the broadcast address of a vulnerable network, all hosts on the network will send their responses to the victim. The entire network will act as a traffic amplifier for the attack. This kind of attack was first reported by Edward Henigin in 1997. It is possible to use the backdoor a tool for a ICMP smurf attack, but we'll have to use the IP address of the victim, because the author of the backdoor did not include support for resolving the source IP address of the packet.
Parameters: src, dst, hostname, d_port, sleep_after
Launches a SYN flood attack. A good description of the SYN flood atack is the Phrack 48 article by route. The victim is specified with the dst or the hostname parameters. The source ip address can be specified with src or left empty, in which case a random address is generated for each packet. The destination port for the SYN packets is given in d_port. It should be an open TCP port on the victim's system. The DoS process sleeps for 300 microseconds after it has sent sleep_after packets. If the parameter is not specified, the process sleeps after each packet.
Parameters: src, dst, hostname, s_port, sleep_after
Launches a DNS queries flood atack. Sends DNS queries for top-level domains (.com, .net, etc) to the victim. Useful for bringing DNS servers down. The victim is specified with the dst or hostname parameters. The source ip address of the queries can be given in src or a random address will be generated for each packet. The source port can be given in s_port or it will also be generated randomly. The DoS process sleeps for 300 microseconds after it has sent sleep_after packets. If the parameter is not specified, the process sleeps after each packet.
Parameters: victim_ip, victim_hostname, s_port, sleep_after
Launches a DNS smurf attack using publicly accessible nameservers as traffic amplifiers. The backdoor binary contains a hardcoded list of more than 10000 DNS servers. The backdoor forks a process which continuously sends DNS requests for top-level domains (.com, .net, etc) with a spoofed source address. The source address is taken from the victim_ip parameter or resolved from victim_hostname. The address is resolved again after 40000 packets are sent, in case the dns record of the victim has been changed. All 10000 DNS servers will send their replies to the victim's ip address, causing a denial of service. The DNS Smurf attack was first described in s0ftpr0ject Security Advisory SPJ-002-000, July 19, 1999. If the s_port is specified, it is used as a source port for the queries, otherwise the source port is random. The DoS process sleeps for 300 microseconds after it has sent sleep_after packets. If it is not specified, the process sleeps after each packet.
|--------|------|-------------| | offset | size | description | |--------|------|-------------| | 0 | 20 | ip header | | 20 | 1 | packet type | | 21 | 1 | unused | | 22 | >200 | packet data | |--------|------|-------------|The packet data at offset 22 is encoded with a simple obfuscation alogirthm. Disassembling the packet_encode and packet_decode functions is straightforward and gives us the following source:
/* Simple obfuscation of the packet data */ void packet_encode(int input_size, char* input, char* output) { int c; output[0] = input[0] + 0x17; for (c=1; c <= input_size; c++) { output[c] = output[c-1] + input[c] + 0x17; } } /* The reverse of packet_encode */ void packet_decode(int input_size, char* input, char* output) { int c; for (c=input_size-1; c > 0; c--) { output[c] = input[c] - input[c-1] - 0x17; } output[0] = input[0] - 0x17; }
|--------|------|-------------| | offset | size | description | |--------|------|-------------| | 22 | 1 | unused | | 23 | 1 | command id | | 24 | X | parameters | |--------|------|-------------|
|--------|------|-------------| | offset | size | description | |--------|------|-------------| | 22 | 1 | unused | | 23 | 1 | reply type | | 24 | X | reply data | |--------|------|-------------|
The replies to the status command have a reply type of 1. If the byte at offset 25 is 0 then the backdoor does not have a shell or DoS process running. Otherwise the byte at offset 26 contains the command id of the command that forked the child process.
The replies to the exec_output command contain the output captured from stdout and stderr. It is sent as a null terminated string, starting at offset 24. The reply type is 3 if this is the first reply packet from the exec_output command, and 4 otherwise.
A decoder for the backdoor communication protocol is available: decoder.c. It uses libpcap and can sniff traffic in realtime or read tcpdump files. Running it on snort.log provided by project honeynet:
$ ./decoder -h ./decoder: invalid option -- h the-binary Traffic Decoder Syntax: the-binary [options] -i <iface> Listens on a interface -r <dumpfile> Reads in a tcpdump file $ ./decoder -r snort.log init: type=1 control_ip=203.173.144.35 init: type=1 control_ip=203.173.144.35 init: type=1 control_ip=203.173.144.35 exec_output: "rpcinfo -p 127.0.0.1" reply: program vers proto port 100000 2 tcp 111 portmapper 100000 2 udp 111 portmapper 100021 1 udp 1024 nlockmgr 100021 3 udp 1024 nlockmgr 100021 1 tcp 1024 nlockmgr 100021 3 tcp 1024 nlockmgr 100024 1 udp 924 status 100024 1 tcp 926 status reply: program vers proto port 100000 2 tcp 111 portmapper 100000 2 udp 111 portmapper 100021 1 udp 1024 nlockmgr 100021 3 udp 1024 nlockmgr 100021 1 tcp 1024 nlockmgr 100021 3 tcp 1024 nlockmgr 100024 1 udp 924 status 100024 1 tcp 926 status reply: program vers proto port 100000 2 tcp 111 portmapper 100000 2 udp 111 portmapper 100021 1 udp 1024 nlockmgr 100021 3 udp 1024 nlockmgr 100021 1 tcp 1024 nlockmgr 100021 3 tcp 1024 nlockmgr 100024 1 udp 924 status 100024 1 tcp 926 status reply: program vers proto port 100000 2 tcp 111 portmapper 100000 2 udp 111 portmapper 100021 1 udp 1024 nlockmgr 100021 3 udp 1024 nlockmgr 100021 1 tcp 1024 nlockmgr 100021 3 tcp 1024 nlockmgr 100024 1 udp 924 status 100024 1 tcp 926 status reply: program vers proto port 100000 2 tcp 111 portmapper 100000 2 udp 111 portmapper 100021 1 udp 1024 nlockmgr 100021 3 udp 1024 nlockmgr 100021 1 tcp 1024 nlockmgr 100021 3 tcp 1024 nlockmgr 100024 1 udp 924 status 100024 1 tcp 926 status reply: program vers proto port 100000 2 tcp 111 portmapper 100000 2 udp 111 portmapper 100021 1 udp 1024 nlockmgr 100021 3 udp 1024 nlockmgr 100021 1 tcp 1024 nlockmgr 100021 3 tcp 1024 nlockmgr 100024 1 udp 924 status 100024 1 tcp 926 status reply: program vers proto port 100000 2 tcp 111 portmapper 100000 2 udp 111 portmapper 100021 1 udp 1024 nlockmgr 100021 3 udp 1024 nlockmgr 100021 1 tcp 1024 nlockmgr 100021 3 tcp 1024 nlockmgr 100024 1 udp 924 status 100024 1 tcp 926 status reply: program vers proto port 100000 2 tcp 111 portmapper 100000 2 udp 111 portmapper 100021 1 udp 1024 nlockmgr 100021 3 udp 1024 nlockmgr 100021 1 tcp 1024 nlockmgr 100021 3 tcp 1024 nlockmgr 100024 1 udp 924 status 100024 1 tcp 926 status reply: program vers proto port 100000 2 tcp 111 portmapper 100000 2 udp 111 portmapper 100021 1 udp 1024 nlockmgr 100021 3 udp 1024 nlockmgr 100021 1 tcp 1024 nlockmgr 100021 3 tcp 1024 nlockmgr 100024 1 udp 924 status 100024 1 tcp 926 status reply end reply end reply end reply end reply end reply end reply end reply end reply end
Snort rule to detect traffic with an unknown IP protocol:
alert ip !$HOME_NET any -> $HOME_NET any (msg: "Weird IP protocol"; ip_proto: !tcp; ip_proto !udp;)Netfilter rule to deny all IP protocols but TCP and UDP:
iptables -A INPUT -p !TCP -p !UDP -j DROP
Of course this doesn't help much, since there are lots of other ways to sneak traffic past a firewall or an IDS. For further information:
The author of the binary has tried to make it harder to analyze it by compiling it statically. This makes it impossible to tell which library functions are used with simple tools like objdump -t, but it doesn't stop more advanced tools like IDA and Fenris. For more information on using IDA see the analysis section.
Once the problem with the static binary was solved, the binary presented no further challenges. It used no advanced tricks to throw reversers off. No encrypted or self-modifying code, no ptrace() calls, no intentional buffer overflows.
This tool is very similar to other DDoS tools such as trinoo, Tribe Flood Network and stacheldraht. The program captured by the Honeynet Project is not based on the source of these widespread programs, but implements many of the same ideas and introduces some new ones. The communication channel is novel, and the multitude of available DoS attacks is also an improvement. The backdoor functionality of the honeynet binary is a simple, but useful addition.
Trinoo, TFN and stacheldraht use a three tier network of control: attacker(s) -> handler(s) -> agent(s). The advantage of this kind of network is that the identity of the attacker is protected by one additional layer and the whole system can be triggered by sending only one packet to each handler. The disadvantage is that if a running handler is captured, it will reveal the IP addresses of all agents under its control. The existance of a backdoor functionality in the Honeynet binary hints that it is used directly by the attacker, but it is also possible that there is a handler between them. The communication protocol in the captured binary uses packets of types 2,3 and 4. Maybe packets of types 0 and 1 are used for comunication between the attacker and the handler. Further information is required to confirm or deny this.
More decentralized networks for communication between the agents in the system. I expect to see blackhats building trully distributed control and attack networks, like the one described in the Distributed Metastasis paper by Andrew J. Stewart. Distributed networks have a lot more to offer to blackhats than a DoS tool.
DDoS tools that can actively exploit other hosts and join them to the attack cluster. Think CodeRed with a control channel.
Strong encryption and public key cryptography for authentication