Violent Python: A Cookbook for Hackers, Forensic Analysts, Penetration Testers and Security Engineers (17 page)

Is Anonymous Really Anonymous? Analyzing LOIC Traffic

In December 2010, Dutch police arrested a teenager for participating in distributed denial-of-service attacks against Visa, MasterCard, and PayPal as part of an operation to target companies opposed to WikiLeaks. Less than a month later, the FBI issued forty search warrants and British police made five arrests as well. Loosely connected to the hacker group Anonymous, these alleged criminals downloaded and used the Low Orbit Ion Cannon (LOIC) distributed denial-of-service toolkit.

LOIC floods a target with large volumes of UDP and TCP traffic. A single instance of LOIC will do very little to exhaust the resources of a target; however, when hundreds of thousands of individuals use LOIC simultaneously, they quickly exhaust the target’s resources and ability to provide services.

LOIC offers two modes of operation. In the first mode, a user can enter a target address. In the second mode, dubbed HIVEMIND, the user connects LOIC to an IRC server where users can nominate targets that the IRC-connected users will automatically attack.

Using Dpkt to Find the LOIC Download

During Operation Payback, members of Anonymous posted a document containing answers to frequently asked questions about their toolkit, LOIC. The Frequently Asked Questions (FAQ) states: “
Will I get caught/arrested for using it? Chances are next to zero. Just blame you have a virus, or simply deny any knowledge of it.
” In this section, let’s debunk that reply by acquiring a good knowledge of packet analysis and write a toolkit to definitively prove that a member downloaded and used the toolkit.

Multiple sources on the Internet offer the LOIC toolkit for download; some are more credible than others. As sourceforge hosts a copy at
http://sourceforge.net/projects/loic/
, let’s download a copy from there. Before downloading, open up a tcpdump session, filter on port 80, and print the results in ASCII format. You should see that downloading the tool issues a HTTP GET request for the most recent version of the tool from /project/loic/loic/loic-1.0.7/LOIC_1.0.7.42binary.zip.

 analyst# tcpdump –i eth0 –A ‘port 80’

 17:36:06.442645 IP attack.61752 > downloads.sourceforge.net.http: Flags [P.], seq 1:828, ack 1, win 65535, options [nop,nop,TS val 488571053 ecr 3676471943], length 827E..o..@.@........”.;.8.P.KC.T.c.................”

 ..GET /project/loic/loic/loic-1.0.7/LOIC 1.0.7.42binary.zip ?r=http%3A%2F%2Fsourceforge.net%2Fprojects%2Floic%2F&ts=1330821290 HTTP/1.1

 Host: downloads.sourceforge.net

 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/534.53.11 (KHTML, like Gecko) Version/5.1.3 Safari/534.53.10

For the first part of our LOIC discovery toolkit, we will write a Python script to parse HTTP traffic and examine it for HTTP GETs for the zipped LOIC binary. To do this, we will again use Dug Song’s dpkt library. To examine the HTTP traffic, we must extract the Ethernet, IP, and TCP layers. Finally, the HTTP protocol rides on top of the TCP protocol layer. If the HTTP layer utilizes the GET method, we parse out the specific uniform resource identifier (URI) that the HTTP GET requested. If this URI contains .zip and LOIC in the name, we print a message to the screen with the IP that downloaded LOIC. This can help a clever administrator prove that a user downloaded LOIC as opposed to being infected by a virus. Combined with a forensic analysis of downloads (as shown in Chapter 3), we can definitively prove that a user downloaded LOIC.

 import dpkt

 import socket

 def findDownload(pcap):

  for (ts, buf) in pcap:

   try:

    eth = dpkt.ethernet.Ethernet(buf)

    ip = eth.data

    src = socket.inet_ntoa(ip.src)

    tcp = ip.data

    http = dpkt.http.Request(tcp.data)

    if http.method == ‘GET’:

     uri = http.uri.lower()

     if ‘.zip’ in uri and ‘loic’ in uri:

     print ‘[!] ‘ + src + ‘ Downloaded LOIC.’

   except:

    pass

 f = open()

 pcap = dpkt.pcap.Reader(f)

 findDownload(pcap)

Running the script, we see that a couple of users have indeed downloaded LOIC.

 analyst# python findDownload.py

 [!] 192.168.1.3 Downloaded LOIC.

 [!] 192.168.1.5 Downloaded LOIC.

 [!] 192.168.1.7 Downloaded LOIC.

 [!] 192.168.1.9 Downloaded LOIC.

Parsing IRC Commands to the Hive

Simply downloading LOIC is not necessarily illegal (or the author of this book might be in some trouble); however, connecting to the Anonymous HIVE and launching a distributed denial-of-service attack with intent to disrupt a service does violate several state, federal, and national laws. Because Anonymous is a loose collective of similarly minded individuals rather than a hierarchically lead group of hackers, anybody can suggest a target for attack. To start an attack, a member of Anonymous logs onto a specific Internet Relay Chat (IRC) server, and issues an attack command, such as !
lazor targetip=66.211.169.66 message=test_test port=80 method=tcp wait=false random=true start
. Any member of Anonymous connected to the IRC with LOIC connected in HIVEMIND mode can immediately start an attack against the target. In this case, the IP address 66.211.169.66 refers to the address of paypal.com, targeted during Operation Payback.

Examining the specific attack message traffic in tcpdump, we see that a specific user—anonOps—issued a command to start an attack to the IRC server. Next, the IRC server issues a command to the connected LOIC clients to start the attack. While this proves easily looking at these two specific packets, imagine trying to find this in a lengthy PCAP file containing hours or days of network traffic.

 analyst# sudo tcpdump -i eth0 -A ‘port 6667’

 08:39:47.968991 IP anonOps.59092 > ircServer.ircd: Flags [P.], seq 3112239490:3112239600, ack 110628, win 65535, options [nop,nop,TS val 437994780 ecr 246181], length 110

 E...5<@[email protected].._..._............$....3......

 ..E.....TOPIC #LOIC:!lazor targetip=66.211.169.66 message=test_test port=80 method=tcp wait=false random=true start

 08:39:47.970719 IP ircServer.ircd > loic-client.59092: Flags [P.], seq 1:139, ack 110, win 453, options [nop,nop,TS val 260262 ecr 437994780], length 138

 E....&@[email protected].._..._........$.........k.....

 ......E.:kevin!kevin@anonOps TOPIC #loic:!lazor targetip=66.211.169.66 message=test_test port=80 method=tcp wait=false random=true start

In most cases, the IRC server uses TCP port 6667. Messages headed to the IRC server will have the destination TCP port 6667. Messages received from the IRC server will have a TCP source port 6667. Let’s use this knowledge when we write
our HIVEMIND parsing function, findHivemind(). This time, we will extract the Ethernet, IP, and TCP layers. After extracting the TCP layer, we examine it for the specific source and destination ports. If we see the command
!lazor
with a destination port 6667, we identify a member issuing an attack command. If we see the command
!lazor
with a source port 6667, we can identify the server issuing an attack to members of the hive.

 import dpkt

 import socket

 def findHivemind(pcap):

  for (ts, buf) in pcap:

   try:

    eth = dpkt.ethernet.Ethernet(buf)

    ip = eth.data

    src = socket.inet_ntoa(ip.src)

    dst = socket.inet_ntoa(ip.dst)

    tcp = ip.data

    dport = tcp.dport

    sport = tcp.sport

    if dport == 6667:

     if ‘!lazor’ in tcp.data.lower():

      print ‘[!] DDoS Hivemind issued by: ‘+src

      print ‘[+] Target CMD: ‘ + tcp.data

    if sport == 6667:

     if ‘!lazor’ in tcp.data.lower():

      print ‘[!] DDoS Hivemind issued to: ‘+src

      print ‘[+] Target CMD: ‘ + tcp.data

   except:

    pass

Identifying the DDoS Attack in Progress

With functions to locate a user downloading LOIC and to find the hive commands, one last mission remains: identifying the attack in progress. When a user starts a LOIC attack, it fires a massive amount of TCP packets towards a target. These packets, combined with the collective packets from the hive, essentially exhaust the resources of the target. We start a tcpdump session and see several small (length 12) TCP packets sent every 0.00005 seconds. This behavior repeats until the attack terminates. Notice that the target has difficulty responding and only acknowledges about one out of every five packets.

 analyst# tcpdump –i eth0 ‘port 80’

 06:39:26.090870 IP loic-attacker.1182 >loic-target.www: Flags [P.], seq 336:348, ack 1, win

 64240, length 12

 06:39:26.090976 IP loic-attacker.1186 >loic-target.www: Flags [P.], seq 336:348, ack 1, win

 64240, length 12

 06:39:26.090981 IP loic-attacker.1185 >loic-target.www: Flags [P.], seq 301:313, ack 1, win

 64240, length 12

 06:39:26.091036 IP loic-target.www > loic-attacker.1185: Flags [.], ack 313, win 14600, lengt

 h 0

 06:39:26.091134 IP loic-attacker.1189 >loic-target.www: Flags [P.], seq 336:348, ack 1, win

 64240, length 12

 06:39:26.091140 IP loic-attacker.1181 >loic-target.www: Flags [P.], seq 336:348, ack 1, win

 64240, length 12

 06:39:26.091142 IP loic-attacker.1180 >loic-target.www: Flags [P.], seq 336:348, ack 1, win

 64240, length 12

 06:39:26.091225 IP loic-attacker.1184 >loic-target.www: Flags [P.], seq 336:348, ack 1, win

 <.. REPEATS 1000x TIMES..>

Let’s quickly write a function that finds a DDoS attack in progress. To detect an attack, we will set a threshold of packets of packets. If the number of packets from a user to a specific address exceeds this threshold, it indicates something we might want to investigate further as an attack. Arguably, this does not definitively prove a user has initiated an attack; however, correlating this to a user downloading LOIC, followed by acceptance of a HIVE command, followed by the actual attack, does provide overwhelming evidence to prove a user participated in an Anonymous-sponsored DDoS attack.

 import dpkt

 import socket

 THRESH = 10000

 def findAttack(pcap):

  pktCount = {}

  for (ts, buf) in pcap:

   try:

    eth = dpkt.ethernet.Ethernet(buf)

    ip = eth.data

    src = socket.inet_ntoa(ip.src)

    dst = socket.inet_ntoa(ip.dst)

    tcp = ip.data

    dport = tcp.dport

    if dport == 80:

     stream = src + ‘:’ + dst

     if pktCount.has_key(stream):

      pktCount[stream] = pktCount[stream] + 1

     else:

      pktCount[stream] = 1

   except:

    pass

  for stream in pktCount:

   pktsSent = pktCount[stream]

   if pktsSent > THRESH:

    src = stream.split(‘:’)[0]

    dst = stream.split(‘:’)[1]

    print ‘[+] ‘+src+’ attacked ‘+dst+’ with ‘ \

      + str(pktsSent) + ‘ pkts.’

Putting our code back together and adding some option parsing, our script now detects the download, overhears the HIVE commands, and detects the attack.

 import dpkt

 import optparse

 import socket

 THRESH = 1000

 def findDownload(pcap):

  for (ts, buf) in pcap:

   try:

    eth = dpkt.ethernet.Ethernet(buf)

    ip = eth.data

    src = socket.inet_ntoa(ip.src)

    tcp = ip.data

    http = dpkt.http.Request(tcp.data)

    if http.method == ‘GET’:

     uri = http.uri.lower()

     if ‘.zip’ in uri and ‘loic’ in uri:

      print ‘[!] ‘ + src + ‘ Downloaded LOIC.’

   except:

    pass

 def findHivemind(pcap):

  for (ts, buf) in pcap:

   try:

    eth = dpkt.ethernet.Ethernet(buf)

    ip = eth.data

    src = socket.inet_ntoa(ip.src)

    dst = socket.inet_ntoa(ip.dst)

    tcp = ip.data

    dport = tcp.dport

    sport = tcp.sport

    if dport == 6667:

     if ‘!lazor’ in tcp.data.lower():

      print ‘[!] DDoS Hivemind issued by: ‘+src

      print ‘[+] Target CMD: ‘ + tcp.data

    if sport == 6667:

     if ‘!lazor’ in tcp.data.lower():

      print ‘[!] DDoS Hivemind issued to: ‘+src

      print ‘[+] Target CMD: ‘ + tcp.data

   except:

    pass

 def findAttack(pcap):

  pktCount = {}

  for (ts, buf) in pcap:

   try:

    eth = dpkt.ethernet.Ethernet(buf)

    ip = eth.data

    src = socket.inet_ntoa(ip.src)

    dst = socket.inet_ntoa(ip.dst)

    tcp = ip.data

    dport = tcp.dport

    if dport == 80:

     stream = src + ‘:’ + dst

     if pktCount.has_key(stream):

      pktCount[stream] = pktCount[stream] + 1

     else:

      pktCount[stream] = 1

   except:

    pass

  for stream in pktCount:

   pktsSent = pktCount[stream]

   if pktsSent > THRESH:

    src = stream.split(‘:’)[0]

    dst = stream.split(‘:’)[1]

    print ‘[+] ‘+src+’ attacked ‘+dst+’ with ‘ \

     + str(pktsSent) + ‘ pkts.’

 def main():

  parser = optparse.OptionParser(“usage%prog ‘+\

   ‘-p -t

 )

  parser.add_option(‘-p’, dest=’pcapFile’, type=’string’,\

   help=’specify pcap filename’)

  parser.add_option(‘-t’, dest=’thresh’, type=’int’,\

   help=’specify threshold count ‘)

  (options, args) = parser.parse_args()

  if options.pcapFile == None:

    print parser.usage

    exit(0)

  if options.thresh != None:

   THRESH = options.thresh

  pcapFile = options.pcapFile

  f = open(pcapFile)

  pcap = dpkt.pcap.Reader(f)

  findDownload(pcap)

  findHivemind(pcap)

  findAttack(pcap)

 if __name__ == ‘__main__’:

  main()

Running the code, we see the results. Four users downloaded the toolkit. Next, a different user issued the attack command to two other connected attackers. Finally, these two attackers actually participated in the attack. Thus, the script now identifies an entire DDoS in action. While an IDS can detect similar activity, writing a custom script such as this does a much better job of telling the
story of the attack. In the following section, we will look at a custom script that a seventeen-year-old wrote to defend the Pentagon.

 analyst# python findDDoS.py –p traffic.pcap

 [!] 192.168.1.3 Downloaded LOIC.

 [!] 192.168.1.5 Downloaded LOIC.

 [!] 192.168.1.7 Downloaded LOIC.

 [!] 192.168.1.9 Downloaded LOIC.

 [!] DDoS Hivemind issued by: 192.168.1.2

 [+] Target CMD: TOPIC #LOIC:!lazor targetip=192.168.95.141 message=test_test port=80 method=tcp wait=false random=true start

 [!] DDoS Hivemind issued to: 192.168.1.3

 [+] Target CMD: TOPIC #LOIC:!lazor targetip=192.168.95.141 message=test_test port=80 method=tcp wait=false random=true start

 [!] DDoS Hivemind issued to: 192.168.1.5

 [+] Target CMD: TOPIC #LOIC:!lazor targetip=192.168.95.141 message=test_test port=80 method=tcp wait=false random=true start

 [+] 192.168.1.3 attacked 192.168.95.141 with 1000337 pkts.

 [+] 192.168.1.5 attacked 192.168.95.141 with 4133000 pkts.

Other books

Eye of the Storm by Emmie Mears
The Howling Man by Beaumont, Charles
Seize the Fire by Laura Kinsale
Hex by Allen Steele
Heart and Soul by Maeve Binchy
To Wear His Ring Again by Chantelle Shaw
New Point by Olivia Luck
Members of the Tribe by Zev Chafets