• Skip to primary navigation
  • Skip to main content
  • Skip to footer

The Dark Tech

The Dark Tech

  • Home
  • Blogs
  • HTB
  • My account
  • Terms and Conditions
  • Privacy Policy
  • Home
  • Blogs
  • HTB
  • My account
  • Terms and Conditions
  • Privacy Policy

For Beginners

How To Map Open Source Web App Installations Using Python

February 19, 2022 by BlackHammer 1 Comment

Content management systems and blogging platforms such as Joomla, WordPress, and Drupal make starting a new blog or website simple, and they’re relatively common in a shared hosting environment or even an enterprise network. All systems have their own challenges in terms of installation, configuration, and patch management, and these CMS suites are no exception. When an overworked sysadmin or a hapless web developer doesn’t follow all security and installation procedures, it can be easy pickings for an attacker to gain access to the web server.

Because we can download any open source web application and locally determine its file and directory structure, we can create a purpose-built scanner that can hunt for all files that are reachable on the remote target. This can root out leftover installation files, directories that should be protected by .htaccess files, and other goodies that can assist an attacker in getting a toehold on the web server. This project also introduces you to using Python Queue objects, which allow us to build a large, thread-safe stack of items and have multiple threads pick items for processing. This will allow our scanner to run very rapidly. Let’s open web_app_mapper.py and enter the following code:

import Queue
import threading
import os
import urllib2
threads = 10 
 target = "http://www.blackhatpython.com" 
directory = "/Users/justin/Downloads/joomla-3.1.1"
filters = [".jpg",".gif","png",".css"]
os.chdir(directory)

We begin by defining the remote target website and the local directory into which we have downloaded and extracted the web application. We also create a simple list of file extensions that we are not interested in fingerprinting.

web_paths = Queue.Queue()

This list can be different depending on the target application. The web_paths variable is our Queue object where we will store the files that we’ll attempt to locate on the remote server.

for r,d,f in os.walk("."): 
 for files in f:
 remote_path = "%s/%s" % (r,files)
 if remote_path.startswith("."):
 remote_path = remote_path[1:]
 if os.path.splitext(files)[1] not in filters:
 web_paths.put(remote_path)

We then use the os.walk function to walk through all of the files and directories in the local web application directory. As we walk through the files and directories, we’re building the full path to the target files and testing them against our filter list to make sure we are only looking for the file types we want. For each valid file we find locally, we add it to our web_paths Queue.

def test_remote():
x while not web_paths.empty(): 
 path = web_paths.get()
 url = "%s%s" % (target, path)
 request = urllib2.Request(url)
 try:
 response = urllib2.urlopen(request)
 content = response.read()

On each iteration of the loop, we grab a path from the Queue, add it to the target website’s base path, and then attempt to retrieve it.

print "[%d] => %s" % (response.code,path) 
 response.close()

If we’re successful in retrieving the file, we output the HTTP status code and the full path to the file.

except urllib2.HTTPError as error: 
 #print "Failed %s" % error.code
 pass

If the file is not found or is protected by an .htaccess file, this will cause urllib2 to throw an error, which we handle so the loop can continue executing.

for i in range(threads): 
 print "Spawning thread: %d" % i
 t = threading.Thread(target=test_remote)
 t.start()

Looking at the bottom of the script, we are creating a number of threads (as set at the top of the file) that will each be called the test_remote function. The test_remote function operates in a loop that will keep execut- ing until the web_paths Queue is empty.

Let’s Check Our Code

For testing purposes, I installed Joomla 3.1.1 into my Kali VM, but you can use any open source web application that you can quickly deploy or that you have running already. When you run web_app_mapper.py, you should see output like the following:

Spawning thread: 0
Spawning thread: 1
Spawning thread: 2
Spawning thread: 3
Spawning thread: 4
Spawning thread: 5
Spawning thread: 6
Spawning thread: 7
Spawning thread: 8
Spawning thread: 9
[200] => /htaccess.txt
[200] => /web.config.txt
[200] => /LICENSE.txt
[200] => /README.txt
[200] => /administrator/cache/index.html
[200] => /administrator/components/index.html
[200] => /administrator/components/com_admin/controller.php
[200] => /administrator/components/com_admin/script.php
[200] => /administrator/components/com_admin/admin.xml
[200] => /administrator/components/com_admin/admin.php
[200] => /administrator/components/com_admin/helpers/index.html
[200] => /administrator/components/com_admin/controllers/index.html
[200] => /administrator/components/com_admin/index.html
[200] => /administrator/components/com_admin/helpers/html/index.html
[200] => /administrator/components/com_admin/models/index.html
[200] => /administrator/components/com_admin/models/profile.php
[200] => /administrator/components/com_admin/controllers/profile.php

You can see that we are picking up some valid results including some .txt files and XML files. Of course, you can build additional intelligence into the script to only return files you’re interested in—such as those with the word install in them.

Filed Under: For Beginners, Hacking, Learn Hacking, Python For Hacking Tagged With: Black hat python, Enumeration, File search, Mapping, Python, Python for hacking

How To Hack Email By Packet Sniffing With Python

February 19, 2022 by BlackHammer 1 Comment

Let’s learn About Scapy

Scapy is a packet manipulation tool for computer networks, originally written in Python by Philippe Biondi. It can forge or decode packets, send them on the wire, capture them, and match requests and replies. It can also handle tasks like scanning, tracerouting, probing, unit tests, attacks, and network discovery.

Scapy Interface

Stealing Email Credentials

You have already spent some time getting into the nuts and bolts of sniff- ing in Python. So let’s get to know Scapy’s interface for sniffing packets and dissecting their contents. We are going to build a very simple sniffer to cap- ture SMTP, POP3, and IMAP credentials. Later, by coupling our sniffer with our Address Resolution Protocol (ARP) poisoning man-in-the-middle (MITM) attack, we can easily steal credentials from other machines on the network. This technique can of course be applied to any protocol or to sim- ply suck in all traffic and store it in a PCAP file for analysis, which we will also demonstrate.

To get a feel for Scapy, let’s start by building a skeleton sniffer that sim- ply dissects and dumps the packets out. The aptly named sniff function looks like the following:

sniff(filter="",iface="any",prn=function,count=N)

The filter parameter allows us to specify a BPF (Wireshark-style) filter to the packets that Scapy sniffs, which can be left blank to sniff all packets. For example, to sniff all HTTP packets you would use a BPF filter of tcp port 80. The iface parameter tells the sniffer which network interface to sniff on; if left blank, Scapy will sniff on all interfaces. The prn parameter specifies a callback function to be called for every packet that matches the filter, and the callback function receives the packet object as its single parameter. The count parameter specifies how many packets you want to sniff; if left blank, Scapy will sniff indefinitely.

Let’s start by creating a simple sniffer that sniffs a packet and dumps its contents. We’ll then expand it to only sniff email-related commands. Crack open mail_sniffer.py and jam out the following code:

from scapy.all import *
# our packet callback
 def packet_callback(packet): 
 print packet.show()

We start by defining our callback function that will receive each sniffed packet.

# fire up our sniffer
 sniff(prn=packet_callback,count=1)

Now we will simply tell Scapy to start sniffing on all interfaces with no filtering.

Now let’s run the script and you should see output similar to what you see below.

$ python2.7 mail_sniffer.py
WARNING: No route found for IPv6 destination :: (no default route?)
###[ Ethernet ]###
 dst = 10:40:f3:ab:71:02 
 src = 00:18:e7:ff:5c:f8
 type = 0x800
###[ IP ]###
 version = 4L 
 ihl = 5L
 tos = 0x0
 len = 52
 id = 35232
 flags = DF
 frag = 0L
 ttl = 51
 proto = tcp
 chksum = 0x4a51
 src = 195.91.239.8 
 dst = 192.168.0.198
 \options \
###[ TCP ]###
 sport = etlservicemgr 
 dport = 54000
 seq = 4154787032
 ack = 2619128538
 dataofs = 8L
 reserved = 0L
 flags = A 
 window = 330
 chksum = 0x80a2
 urgptr = 0
 options = [('NOP', None), ('NOP', None), ('Timestamp', (1960913461,¬ 
 764897985))]
 None

How incredibly easy was that! We can see that when the first packet was received on the network, our callback function used the built-in function packet.show() to display the packet contents and to dissect some of the proto- col information. Using show() is a great way to debug scripts as you are going along to make sure you are capturing the output you want.

Now that we have our basic sniffer running, let’s apply a filter and add some logic to our callback function to peel out email-related authentication strings.

from scapy.all import *
# our packet callback
def packet_callback(packet):
 
 if packet[TCP].payload: 
 
 mail_packet = str(packet[TCP].payload)
 if "user" in mail_packet.lower() or "pass" in mail_packet.lower():

When our callback function is called, we check to make sure it has a data payload and whether the payload contains the typical USER or PASS mail commands.

 print "[*] Server: %s" % packet[IP].dst
 print "[*] %s" % packet[TCP].payload

If we detect an authentication string, we print out the server we are sending it to and the actual data bytes of the packet.

# fire up our sniffer
sniff(filter="tcp port 110 or tcp port 25 or tcp port 143",prn=packet_callback,store=0)

Pretty straightforward stuff here. We changed our sniff function to add a filter that only includes traffic destined for the common mail ports 110 (POP3), 143 (IMAP), and SMTP (25). We also used a new parameter called store, which when set to 0 ensures that Scapy isn’t keep- ing the packets in memory. It’s a good idea to use this parameter if you intend to leave a long-term sniffer running because then you won’t be consuming vast amounts of RAM.

Lets Test Our Code

Here is some example output from a dummy email account I attempted to connect my mail client to:

[*] Server: 25.57.168.12
[*] USER thedarktech
[*] Server: 25.57.168.12
[*] PASS sudopsxc
[*] Server: 25.57.168.12
[*] USER thedarktech
[*] Server: 25.57.168.12
[*] PASS test

You can see that my mail client is attempting to log in to the server at 25.57.168.12 and sending the plain text credentials over the wire. This is a really simple example of how you can take a Scapy sniffing script and turn it into a useful tool during penetration tests.

Sniffing your own traffic might be fun, but it’s always better to sniff with a friend, so in next article we will take a look at how you can perform an ARP poisoning attack to sniff the traffic of a target machine on the same network.

Also Check Decoding The ICMP Packets With Python | For Hackers.

Filed Under: For Beginners, Hacking, Learn Hacking, Python For Hacking Tagged With: Email Hacking, hackers, Learn python, Packet Sniffer, Python, Python for hacking, Scapy

Decoding The ICMP Packets With Python

February 19, 2022 by BlackHammer 1 Comment

What Is ICMP

The Internet Control Message Protocol (ICMP) is a supporting protocol in the Internet protocol suite. It is used by network devices, including routers, to send error messages and operational information indicating success or failure when communicating with another IP address, for example, an error is indicated when a requested service is not available or that a host or router could not be reached.ICMP differs from transport protocols such as TCP and UDP in that it is not typically used to exchange data between systems, nor is it regularly employed by end-user network applications (with the exception of some diagnostic tools like ping and traceroute).

Decoding The ICMP Packets

Now that we can fully decode the IP layer of any sniffed packets, we have to be able to decode the ICMP responses that our scanner will elicit from sending UDP datagrams to closed ports. ICMP messages can vary greatly in their contents, but each message contains three elements that stay consis- tent: the type, code, and checksum fields. The type and code fields tell the receiving host what type of ICMP message is arriving, which then dictates how to decode it properly.

For the purpose of our scanner, we are looking for a type value of 3 and a code value of 3. This corresponds to the Destination Unreachable class of ICMP messages, and the code value of 3 indicates that the Port Unreachable error has been caused. Refer to Figure for a diagram of a Destination Unreachable ICMP message.

Destination Unreachable ICMP message

As you can see, the first 8 bits are the type and the second 8 bits con- tain our ICMP code. One interesting thing to note is that when a host sends one of these ICMP messages, it actually includes the IP header of the originating message that generated the response. We can also see that we will double-check against 8 bytes of the original datagram that was sent in order to make sure our scanner generated the ICMP response. To do so, we simply slice off the last 8 bytes of the received buffer to pull out the magic string that our scanner sends.

Let’s add some more code to our previous sniffer to include the ability to decode ICMP packets. Let’s save our previous file as sniffer_with_icmp.py and add the following code:

--snip--
class IP(Structure):
--snip--
 class ICMP(Structure): 
 _fields_ = [
 ("type", c_ubyte),
 ("code", c_ubyte),
 ("checksum", c_ushort),
 ("unused", c_ushort),
 ("next_hop_mtu", c_ushort)
 ]
 def __new__(self, socket_buffer):
 return self.from_buffer_copy(socket_buffer) 
 def __init__(self, socket_buffer):
 pass
--snip--
 print "Protocol: %s %s -> %s" % (ip_header.protocol, ip_header.src_address, ip_header.dst_address)

This simple piece of code creates an ICMP structure u underneath our existing IP structure.

# if it's ICMP, we want it
 if ip_header.protocol == "ICMP":

When the main packet-receiving loop determines that we have received an ICMP packet.

# calculate where our ICMP packet starts
 offset = ip_header.ihl * 4

We calculate the offset in the raw packet where the ICMP body lives.

buf = raw_buffer[offset:offset + sizeof(ICMP)]
 # create our ICMP structure
 icmp_header = ICMP(buf) 
 print "ICMP -> Type: %d Code: %d" % (icmp_header.type, icmp_header.
code)

Then create our buffer and print out the type and code fields. The length calculation is based on the IP header ihl field, which indicates the number of 32-bit words (4-byte chunks) contained in the IP header. So by multiplying this field by 4, we know the size of the IP header and thus when the next network layer— ICMP in this case—begins.

If we quickly run this code with our typical ping test, our output should now be slightly different, as shown below:

Protocol: ICMP 74.125.226.78 -> 192.168.0.190
ICMP -> Type: 0 Code: 0

This indicates that the ping (ICMP Echo) responses are being correctly received and decoded. We are now ready to implement the last bit of logic to send out the UDP datagrams, and to interpret their results.

Now let’s add the use of the netaddr module so that we can cover an entire subnet with our host discovery scan. Save your sniffer_with_icmp.py script as scanner.py and add the following code:

import threading
import time
from netaddr import IPNetwork,IPAddress
--snip--
# host to listen on
host = "192.168.0.187"
# subnet to target
subnet = "192.168.0.0/24"
# magic string we'll check ICMP responses for
 magic_message = "PYTHONRULES!"

This last bit of code should be fairly straightforward to understand. We define a simple string signature so that we can test that the responses are coming from UDP packets that we sent originally.

# this sprays out the UDP datagrams
 def udp_sender(subnet,magic_message): 
 time.sleep(5)
 sender = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
 for ip in IPNetwork(subnet):
try:
 sender.sendto(magic_message,("%s" % ip,65212))
 except:
 pass
--snip--

Our udp_sender function simply takes in a subnet that we specify at the top of our script, iterates through all IP addresses in that subnet, and fires UDP datagrams at them.

# start sending packets
 t = threading.Thread(target=udp_sender,args=(subnet,magic_message)) 
t.start()
--snip--
try:
 while True:
 --snip--
 #print "ICMP -> Type: %d Code: %d" % (icmp_header.type, icmp_header.code)
 # now check for the TYPE 3 and CODE
 if icmp_header.code == 3 and icmp_header.type == 3:

In the main body of our script, just before the main packet decoding loop, we spawn udp_sender in a separate thread to ensure that we aren’t interfering with our ability to sniff responses.

# make sure host is in our target subnet 
 if IPAddress(ip_header.src_address) in IPNetwork(subnet):

If we detect the anticipated ICMP message, we first check to make sure that the ICMP response is com- ing from within our target subnet.

# make sure it has our magic message
 if raw_buffer[len(raw_buffer)-len(magic_message):] == magic_message: 
 print "Host Up: %s" % ip_header.src_address

We then perform our final check of making sure that the ICMP response has our magic string in it. If all of these checks pass, we print out the source IP address of where the ICMP message originated.

Now Let’s Check Our Code

Now let’s take our scanner and run it against the local network. You can use Linux or Windows for this as the results will be the same. In my case, the IP address of the local machine I was on was 192.168.0.187, so I set my scanner to hit 192.168.0.0/24. If the output is too noisy when you run your scanner, simply comment out all print statements except for the last one that tells you what hosts are responding.

c:\Python27\python.exe scanner.py
Host Up: 192.168.0.1
Host Up: 192.168.0.190
Host Up: 192.168.0.192
Host Up: 192.168.0.195

For a quick scan like the one I performed, it only took a few seconds to get the results back. By cross-referencing these IP addresses with the DHCP table in my home router, I was able to verify that the results were accurate. You can easily expand what you’ve learned in this chapter to decode TCP and UDP packets, and build additional tooling around it. This scanner is also useful for the trojan framework we will begin building in Chapter 7. This would allow a deployed trojan to scan the local network looking for additional targets. Now that we have the basics down of how networks work on a high and low level. In next article we will explore a very mature Python library called Scapy.

Note

The NETADDR Module

Our scanner is going to use a third-party library called netaddr, which will allow us to feed in a subnet mask such as 192.168.0.0/24 and have our scan- ner handle it appropriately. Download the library from here: .com/p/netaddr/downloads/list

Or, if you installed the Python setup tools package, you can simply execute the following from a command prompt:

easy_install netaddr

The netaddr module makes it very easy to work with subnets and addressing. For example, you can run simple tests like the following using the IPNetwork object:

ip_address = "192.168.112.3"
if ip_address in IPNetwork("192.168.112.0/24"):
 print True

Or you can create simple iterators if you want to send packets to an entire network:

for ip in IPNetwork("192.168.112.1/24"):
 s = socket.socket()
 s.connect((ip, 25))
 # send mail packets

This will greatly simplify your programming life when dealing with entire networks at a time, and it is ideally suited for our host discovery tool. After it’s installed, you are ready to proceed.

Also Check Decoding The IP Layer With Python | For Hackers.

Filed Under: For Beginners, Hacking, Learn Hacking, Python For Hacking Tagged With: Black hat python, Hacking, ICMP, Learn python, Python, Python for hacking

Decoding The IP Layer With Python

February 19, 2022 by BlackHammer 1 Comment

What Is IP Layer

The internet layer is a group of internetworking methods, protocols, and specifications in the Internet protocol suite that are used to transport network packets from the originating host across network boundaries; if necessary, to the destination host specified by an IP address. The internet layer derives its name from its function facilitating internetworking, which is the concept of connecting multiple networks with each other through gateways.

Decoding The IP Layer

In its current form, our sniffer receives all of the IP headers along with any higher protocols such as TCP, UDP, or ICMP. The information is packed into binary form, and as shown above, is quite difficult to under- stand. We are now going to work on decoding the IP portion of a packet so that we can pull useful information out such as the protocol type (TCP, UDP, ICMP), and the source and destination IP addresses. This will be the foundation for you to start creating further protocol parsing later on.

If we examine what an actual packet looks like on the network, you will have an understanding of how we need to decode the incoming packets. Refer to Figure 3-1 for the makeup of an IP header.

We will decode the entire IP header (except the Options field) and extract the protocol type, source, and destination IP address. Using the Python ctypes module to create a C-like structure will allow us to have a friendly format for handling the IP header and its member fields. First, let’s take a look at the C definition of what an IP header looks like.

struct ip {
 u_char ip_hl:4;
 u_char ip_v:4;
 u_char ip_tos;
 u_short ip_len;
 u_short ip_id;
 u_short ip_off;
 u_char ip_ttl;
 u_char ip_p;
 u_short ip_sum;
 u_long ip_src;
 u_long ip_dst;
}

You now have an idea of how to map the C data types to the IP header values. Using C code as a reference when translating to Python objects can be useful because it makes it seamless to convert them to pure Python. Of note, the ip_hl and ip_v fields have a bit notation added to them (the :4 part). This indicates that these are bit fields, and they are 4 bits wide. We will use a pure Python solution to make sure these fields map correctly so we can avoid having to do any bit manipulation. Let’s implement our IP decoding routine into sniffer_ip_header_decode.py as shown below.

import socket
import os
import struct
from ctypes import *
# host to listen on
host = "192.168.0.187"
# our IP header
 class IP(Structure): 
 _fields_ = [
 ("ihl", c_ubyte, 4),
 ("version", c_ubyte, 4),
 ("tos", c_ubyte),
 ("len", c_ushort),
 ("id", c_ushort),
 ("offset", c_ushort),
 ("ttl", c_ubyte),
 ("protocol_num", c_ubyte),
 ("sum", c_ushort),
 ("src", c_ulong),
 ("dst", c_ulong)
 ]
 def __new__(self, socket_buffer=None):
 return self.from_buffer_copy(socket_buffer) 
 def __init__(self, socket_buffer=None):
 # map protocol constants to their names
 self.protocol_map = {1:"ICMP", 6:"TCP", 17:"UDP"}

The first step is defining a Python ctypes structure u that will map the first 20 bytes of the received buffer into a friendly IP header. As you can see, all of the fields that we identified and the preceding C structure match up nicely. The __new__ method of the IP class simply takes in a raw buffer (in this case, what we receive on the network) and forms the structure from it.

# human readable IP addresses 
 self.src_address = socket.inet_ntoa(struct.pack("<L",self.src)) 
 self.dst_address = socket.inet_ntoa(struct.pack("<L",self.dst))
 # human readable protocol
 try:
 self.protocol = self.protocol_map[self.protocol_num]
 except:
 self.protocol = str(self.protocol_num)
# this should look familiar from the previous example
if os.name == "nt":
 socket_protocol = socket.IPPROTO_IP 
else:
 socket_protocol = socket.IPPROTO_ICMP
sniffer = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket_protocol)
sniffer.bind((host, 0))
sniffer.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
if os.name == "nt":
 sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)
try:
 
 while True:

When the __init__ method is called, __new__ is already finished process- ing the buffer. Inside __init__, we are simply doing some housekeeping to give some human readable output for the protocol in use and the IP addresses.

# read in a packet
 raw_buffer = sniffer.recvfrom(65565)[0]

With our freshly minted IP structure, we now put in the logic to continually read in packets and parse their information. The first step is to read in the packet.

# create an IP header from the first 20 bytes of the buffer
 ip_header = IP(raw_buffer[0:20])

Now, We will pass the first 20 bytes to initialize our IP structure.

# print out the protocol that was detected and the hosts
 print "Protocol: %s %s -> %s" % (ip_header.protocol, ip_header.src_¬ 
address, ip_header.dst_address) 
# handle CTRL-C
except KeyboardInterrupt:
 # if we're using Windows, turn off promiscuous mode
 if os.name == "nt":
 sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF)

Next, we simply print out the information that we have captured.

Now Let’s Check Our Code

Let’s test out our previous code to see what kind of information we are extracting from the raw packets being sent. I definitely recommend that you do this test from your Windows machine, as you will be able to see TCP, UDP, and ICMP, which allows you to do some pretty neat testing (open up a browser, for example). If you are confined to Linux, then perform the previous ping test to see it in action. Open a terminal and type:

python sniffer_ip_header_decode.py

Now, because Windows is pretty chatty, you’re likely to see output immediately. I tested this script by opening Internet Explorer and going to www .google.com, and here is the output from our script:

Protocol: UDP 192.168.0.190 -> 192.168.0.1
Protocol: UDP 192.168.0.1 -> 192.168.0.190
Protocol: UDP 192.168.0.190 -> 192.168.0.187
Protocol: TCP 192.168.0.187 -> 74.125.225.183
Protocol: TCP 192.168.0.187 -> 74.125.225.183
Protocol: TCP 74.125.225.183 -> 192.168.0.187
Protocol: TCP 192.168.0.187 -> 74.125.225.183

Because we aren’t doing any deep inspection on these packets, we can only guess what this stream is indicating. My guess is that the first couple of UDP packets are the DNS queries to determine where google.com lives, and the subsequent TCP sessions are my machine actually connecting and downloading content from their web server.

To perform the same test on Linux, we can ping google.com, and the results will look something like this:

Protocol: ICMP 74.125.226.78 -> 192.168.0.190
Protocol: ICMP 74.125.226.78 -> 192.168.0.190
Protocol: ICMP 74.125.226.78 -> 192.168.0.190

You can already see the limitation: we are only seeing the response and only for the ICMP protocol. But because we are purposefully building a host discovery scanner, this is completely acceptable. We will now apply the same techniques we used to decode the IP header to decode the ICMP messages in the next article.

Also Check Packet Sniffer On Windows And Linux Using Python | For Hackers.

Filed Under: For Beginners, Hacking, Learn Hacking, Python For Hacking Tagged With: Black hat python, Decoding ip, Hacking, Internet protocol, Learn python, Python, Python for hacking

Packet Sniffer On Windows And Linux Using Python

February 1, 2022 by BlackHammer 2 Comments

What Is Packet Sniffing

A Packet Analyzer (also known as a packet sniffer) is a computer program or piece of computer hardware (such as a packet capture appliance) that can intercept and log traffic that passes over a digital network or part of a network.Packet capture is the process of intercepting and logging traffic. 

Packet Sniffing On Windows And Linux

Accessing raw sockets in Windows is slightly different than on its Linux brethren, but we want to have the flexibility to deploy the same sniffer to multiple platforms. We will create our socket object and then determine which platform we are running on. Windows requires us to set some additional flags through a socket input/output control (IOCTL),1 which enables promiscuous mode on the network interface. In our first example, we simply set up our raw socket sniffer, read in a single packet, and then quit.

import socket
import os
# host to listen on
host = "192.168.0.196"
# create a raw socket and bind it to the public interface
if os.name == "nt":
 socket_protocol = socket.IPPROTO_IP 
else:
 socket_protocol = socket.IPPROTO_ICMP
sniffer = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket_protocol) 
sniffer.bind((host, 0))

We start by constructing our socket object with the parameters necessary for sniffing packets on our network interface u. The difference between Windows and Linux is that Windows will allow us to sniff all incoming packets regardless of protocol, whereas Linux forces us to specify that we are sniffing ICMP. Note that we are using promiscuous mode, which requires administrative privileges on Windows or root on Linux. Promiscuous mode allows us to sniff all packets that the network card sees, even those not destined for your specific host.

# we want the IP headers included in the capture
 sniffer.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)

Next we set a socket option that includes the IP headers in our captured packets.

# if we're using Windows, we need to send an IOCTL
# to set up promiscuous mode
w if os.name == "nt": 
 sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)

The next step w is to determine if we are using Windows, and if so, we perform the additional step of sending an IOCTL to the network card driver to enable promiscu- ous mode. If you’re running Windows in a virtual machine, you will likely get a notification that the guest operating system is enabling promiscuous mode; you, of course, will allow it.

# read in a single packet
 print sniffer.recvfrom(65565)

Now we are ready to actually perform some sniffing, and in this case we are simply printing out the entire raw packet with no packet decoding. This is just to test to make sure we have the core of our sniffing code working.

# if we're using Windows, turn off promiscuous mode
 if os.name == "nt": 
 sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF)

After a single packet is sniffed, we again test for Windows, and disable promiscuous mode before exiting the script.

Now Let’s Test Our Packet Sniffer

Open up a fresh terminal or cmd.exe shell under Windows and run the following:

python sniffer.py

In another terminal or shell window, you can simply pick a host to ping. Here, we’ll ping thedarktech.com:

ping thedarktech.com

In your first window where you executed your sniffer, you should see some garbled output that closely resembles the following:

('E\x00\x00:\x0f\x98\x00\x00\x80\x11\xa9\x0e\xc0\xa8\x00\xbb\xc0\xa8\x0
0\x01\x04\x01\x005\x00&\xd6d\n\xde\x01\x00\x00\x01\x00\x00\x00\x00\x00\
x00\x08thedarktech\x03com\x00\x00\x01\x00\x01', ('192.168.0.187', 0))

You can see that we have captured the initial ICMP ping request des- tined for nostarch.com (based on the appearance of the string nostarch.com). If you are running this example on Linux, then you would receive the response from nostarch.com. Sniffing one packet is not overly useful, so let’s add some functionality to process more packets and decode their contents in next article.

Also Check SSH Tunneling Using Python |For Hackers

Filed Under: For Beginners, Hacking, Learn Hacking, Python For Hacking Tagged With: Black hat python, hacker, Hacking, learn hacking, Learn python, Packet Sniffer, Python, Python for hacking, Sniffing

  • « Go to Previous Page
  • Go to page 1
  • Go to page 2
  • Go to page 3
  • Go to page 4
  • Interim pages omitted …
  • Go to page 8
  • Go to Next Page »

Footer

Contact Us

If you’d like to find out more about our services and explore the possibility of us working together, get in touch. Our initial consultation is free. So you’ve nothing to lose!

Contact Us
  • Privacy Policy
  • Disclaimer
  • Terms and Conditions

Copyright © 2022 · Parallax Pro on Genesis Framework · WordPress · Log in