Python for Ethical Hackers - A Practical Approach

Cyber Security

Python remains the dominant language in the world of information security, even if the debate over your preferred language can sometimes resemble a religious war.

Python-based tools include fuzzers, proxy servers, and even the occasional exploit. Python is used to write exploit frameworks such as CANVAS, as well as more obscure tools such as Sulley and PyEmu.

In this article, we are going to review the vast uses of python in hacking and cyber security. One significant difference between a script kiddie and a professional is that one uses other peoples' tools while the other writes out their own tools.

some of the python2 syntax in this article is used conservatively and has no problem running on python3 releases.

There will not be too much definitions this time, just a deep dive into action.

Prerequisites

  • Intermediary skills in Python programming.

  • Integrated Development Environment (IDE eg Pycharm) - VS Code works as well

  • Internet connection

  • Computer - Linux Distribution

The Network

An attacker arguably can do the most with a simple network access. They can inject packets, sniff data, scan for hosts, remotely exploit hosts and a lot more making it a haven for someone determined to gain access.

We are going to use a python module called socket to work for us. This module exposes all of the necessary pieces to quickly write TCP and UDP clients and servers and use raw sockets.

A simple TCP client

import socket 
host = "www.google.com"
port = 80  
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
# connect our client 
client.connect((host, port)) 
# send data 
client.send(b"GET / HTTP/1.1\r\nHost: google.com\r\n\r\n") 
# receive data in formatted response
response = client.recv(4096)
print(response)

Having our values for the host and port target, we're going to create a socket object using the AF_INET and SOCK_STREAM. The AF_INET says the we are going to use the standard IPv4 address or host while the SOCK_STREAM says that the connection is going to be a TCP connection. There are some assumptions about the sockets we're handling here in this example that you need to know and prepare for while writing more complex socket exploits;

  • The connection will always succeed.
  • The server will always grant a response set of data in a timely manner.

A Simple UDP Client

For a UDP client we'll only need to make two changes to be able to send packets in UDP form.

import socket 
host = "127.0.0.1"
port = 80 
# create a socket object 
client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
# send some data 
client.sendto(b"AAABBBCCC",(host, port)) 
# receive some data 
data, addr = client.recvfrom(4096)

The difference here is that the socket type is changed to SOCK_DGRAM. Next is to pass the data we're going to send into the function sendto() and receive the UDP data block using the recvfrom() . Other than creating a TCP or UDP client, you may also need to create a server using said protocolos. That may run outside the scope of this article. You may request for that in the comments.

Acquiring Credentials Through a Network

logo.png

Scapy

Notice the soft terms. Acquiring may as well be stealing. Let us get into Scapy's interface for sniffing packets and dissecting their contents. You may also forge network packets using this module. First we're going to create a sniffer the captures packets and dumps its contents to us. Later you will find that you can filter through the data received.

from scapy.all import *
# the packet callback 
def packet_callback(packet): 
    print packet.show() 
# initialize the sniffer 
sniff(prn=packet_callback,count=1)

The packet callback here receives all the packets then we've just told scapy to sniff through with no filtering. Output:

$ python scapy_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

When the first packet is received on the network, the callback function in the code above uses the function packet.show() to display the packet contents and to separate some of the protocol information. Using the show() method is a useful way to debug the script we're creating as we go to ensure we are capturing the output you intended.

This is just a basic sniffer using Scapy. Read the docs to discover the various filters that you can add to your packets to get useful data.

Windows Processes

Process Monitoring using WMI

Using WMI API, a programmer has the ability to monitor certain events and receive callbacks when these events happen. We will prompt this interface to receive callbacks each time a process is created. When a process gets created;

  • we’re going to trap some valuable information:
  • The time the process was created
  • The user that spawned the process
  • The executable that was launched and its command-line arguments
  • The process ID
  • The parent process ID.

This should show us any processes started by higher-privilege accounts, as well as any processes that call external files like batch scripts. We'll also assess what permissions are allowed on the process tokens once we have all of this information.

Sometimes we might be lucky or unlucky depending on the recipient of the whip and find processes that were give higher privileges on Windows making it possible to gain more control. We must also take note of the privileges enabled on the process tokens.

Let's start by writing a simple monitoring script.

import win32con
import win32api
import win32security
import wmi
import sys
import os


def log_to_file(message): 
    fd = open("process_monitor_log.csv", "ab") 
    fd.write(b"%s\r\n" % message) 
    fd.close() 
    return 
# create a log file header 
log_to_file(b"Time,User,Executable,CommandLine,PID,Parent PID,Privileges") 
# instantiate the WMI interface
c = wmi.WMI() 
# create our process monitor 
process_watcher = c.Win32_Process.watch_for("creation") 
while True: 
    try:
        new_process = process_watcher() 
        proc_owner = new_process.GetOwner() 
        proc_owner = "%s\\%s" % (proc_owner[0],proc_owner[2]) 
        create_date = new_process.CreationDate 
        executable = new_process.ExecutablePath
        cmdline = new_process.CommandLine 
        pid = new_process.ProcessId 
        parent_pid = new_process.ParentProcessId 
        privileges = "N/A" 
        process_log_message = "%s,%s,%s,%s,%s,%s,%s\r\n" % (create_date,
             proc_owner, executable, cmdline, pid, parent_pid, privileges) 
        print(process_log_message)
        log_to_file(process_log_message) 
    except: 
        pass

To get information about privileged users' processes, you'll need to run the script as an Administator unlike the example below.

Output:

Screenshot (41).png

To begin, we instantiate the WMI class and tell it to monitor for the process creation event. We can monitor process creation and deletion events by using the methods described in the Python WMI documentation, which I will demonstrate in a moment.

If you decide that you want to closely monitor process events, you can use the operation, which will alert you of every single event that occurs during the process. We then enter a loop, which will continue until process_watcher returns a new process event.

The new process event is a WMI class called Win32_Process that contains all of the relevant information that we are after.

One of the class functions is "'GetOwner," which we use to find out who spawned the process, and from there we collect all of the process information we need, output it to the screen, and log it to a file.

You may wonder - why do I need to monitor processes?

If we use the process ID to obtain a handle to a target process. We could crack open the process token, and then request the token information for that process. We can instruct the API call to hand back all of the privilege information for that process.

That's jackpot if you ask me.

Conclusion

Oh well, I am not really creative with the catchy conclusions so I usually dread this part. I just end up having something awkward and making you uncomfortable is an honor, lol. Umm I'm pretty easy to find online so just drop me a text and we may have a good chat. This content is purely for ethical use.

Credit to Justin Seitz