Early on in our InfoSec careers we learn that Netcat is “Almighty” from its ability to quickly check if a port is open, bind a shell to a port, or wrap it around a bash for loop to create a quick port scanner. This is all because Netcat is a very easy tool that offers a lot of functionality. In my book one tool that has taken Netcat’s title as “Almighty” is Python. Python is an extremely flexible language that can accomplish complex tasks in a few lines of code. I know before I started to use Python and learn the syntax I assumed it was very complex because I wasn’t a developer. This was because I didn’t spend the time to get over the initial learning curve. My goal is to create a series of posts that will inspire others to get over the initial learning curve by introducing the basics and showing practical application in a security context.
Prior to getting into the code I wanted to point readers to some resources they can use to learn this powerful language: Violent Python by T.J. O’Connor, and the Python Scripting Expert Course by securitytube.net. These two resources will really get you up and running with great ideas to sharpen your Python Kung Fu.
One thing to note prior to diving into too much code is that Python does force the use of indentation, which makes it more readable but will drive Perl guys through the roof :). We will demonstrate code in the Python interpreter first because its a great way to develop your code on the fly. Once we have hammered down the syntax and logic we will move it into a formal script. Below some basic syntax and data types will be demonstrated using the Python interpreter. You can invoke a Python interpreter by typing ‘python’ at the CLI. First you see we create a variable ‘ip’ which is a string and variable ‘port’ which is an integer.
It’s important to understand the types of data types you’re working with because different functions are available. There are many instances where you’ll need to concatenate a string and an integer. In Python this will error out like you see below, but you can very easily cast an integer as a string using the ‘str()’ function:
Now that we have some variables defined in the interpreter we can begin to figure out what type of functions are available. Whenever dealing with a particular data type, or Python module I like to use the ‘dir()’ function to figure out what functions are available:
So let’s investigate one of the functions that is available to use for the string data type. One of the functions I find myself using a lot is the ‘split()’ function, it’s very similar to the Linux ‘awk’ utility with its ability to break a string up:
Above we take the string pointed to by the ‘s’ variable and split it based on a delineator of a ‘:’. Without specifying a value within the split function it will just strip off the new line character for a given string. Now this actually takes the string and breaks it up by the ‘:’ and returns a list data type. As you can see above the list data type can be used to store multiple string values, and you can leverage the index of the list to print the given element. So we are actually printing the ip address with ‘a
Python modules allow you to harness the functions in that given library which makes coding a lot easier. Python has various built-in modules (os, sys, socket, re, subprocess, urllib, httplib, optparse, etc.) and many third party modules (cymruwhois, scapy, dpkt, spider, etc.). You can import a module by typing “import <moduleName>”. Below is an example of importing the ‘os’ module and taking a look at the functions it provides:
As you might notice some pretty cool functionality available in the ‘os’ module. One of my favorites is the ‘os.system’ module because it lets you run OS commands within your Python script. Here is an example of leverage the ‘os.system’ function to execute ‘uname -a’ and the ‘id’ command:
Here we are actually just running the Linux ‘uname’ and ‘id’ utility within ‘os.system()’ the same way we would on the Linux CLI. Begin to play around with some of the os modules, as you advance your coding skills you’ll see they offer some great functionality.
Creating a File Object:
Now we will show some basic examples of how to read data from a file and create a file in Python. The screen shot below demonstrates how you can create a file object, and list the available functions for that object. As you can see when we create a file, we needed to close it prior to reading it. Often you’ll find yourself reading in input from a file, doing some logic and then writing the output to a file:
Now since a common use case for Python is to do some over and over so we don’t have to we will demonstrate some easy ways to automate. The most simplest example is leveraging a for loop within Python. The for loop syntax is pretty simple and I wont cover it start to finish, but I will show you a very common way you’ll find yourself leveraging it by interating over a file.
What is shown below is the basic syntax for a Python for loop to iterate through the contents of a file and print each line. One thing to note is the use of the string function ‘strip()’ to remove the new line character because ‘print’ already adds a new line by default. Now building on what was shown with the ‘os.system’ function you can see how you can very easily execute a command for a list of targets in a file. Let’s just use the ping command to quickly illustrate this point, but it could be replaced with any command or tool you could invoke from he command line:
As you can see from the output above it’s fairly trivial to execute system commands over a list. Now os.system is a very quick example, but if you want to leverage something a bit more powerful for scripting you’ll want to check out the ‘subprocess’ module. The big benefit here is you can pipe STDOUT to a variable and use it to write to a file for your report. The syntax is a little more complex:
So far we have put down the ground work leading up to this practical use case. You have a tool that accepts a website as a parameter and you need to run the tool against several websites in a list. We will use Nikto as an example:
Now to increase the complexity slightly by iterating through a list of targets and have Nikto output a CSV file report:
Now that we have some decent bit of syntax/logic down lets throw this into a file to finalize the script. Below is a basic shell that can be used to start a Python script. We start out telling the OS which interpreter to use with the file by “#!/usr/bin/env python”. Then we declare a main function with “def main():” and the last 2 lines of code are to have main() run first. You can define other functions within your script to make the code easier to understand and modify:
Now lets take the coding logic we worked up for running Nikto and put it into a file:
We could further advance our tool by adding in CLI switches by leveraging the ‘optparse’ module, but we will save that for another post. I hope you enjoyed this quick look at Python and how you can leverage some common modules to do some cool stuff. Future blog posts will build on concepts shown in this post to demonstrate more advanced Python scripting concepts.