# Category Archives: Python

## Caesar ciphers in Python

One of the simplest ciphers is the Caesar cipher, also called the shift cipher. It works by shifting each letter in the alphabet n positions to the right, mapping it to a different letter. For example, using ‘rotation 13’, a is shifted 13 positions to the right, corresponding to the letter n.

What happens to the last letters in the alphabet? For example, shifting z 13 positions to the right maps it outside of the 26 letters of the English alphabet. In this case we have to use a bit of math, namely modular arithmetic. Whenever the result of the shift is bigger than the size of the alphabet (called the modulus), it wraps around and starts counting from the beginning. So z rotation 13 would become letter number 13 (26+13-26), or the letter m. Mathematically this is expressed as:

x ≡ (26 + 13) mod 26 ≡ 13

In Python, the modulus operator is designated as %

With these basics, how would we implement a Caesar cipher in Python? First, we need the letter number for each letter in the supplied string (let’s call it num), and then sum the rotation (rot) modulus the number of letters in the alphabet (26).

Mathematically, this would be written as:

x ≡ (num + rot) mod 26

For the first part, getting the letter number, we can either supply a table or, even simpler, get the ASCII value of the letter and subtract 97, since ASCII(‘a’) = 97. Remember, in computer science we almost always start counting at 0, which is why we subtract 97 and not 96 (97-97=0).
Getting the ASCII value is simple in Python, we just use ord() on the letter.

We can now shift the letter with the rotation value using modular arithmetic (to not get out of bounds of the alphabet), and finally change the resulting number back to ASCII using chr(). These 3 steps can be done in Python like this:

`num = ord(char)cypher = (num - 97 + rot) % 26cypher = chr(cypher + 97)`

Doing this for each letter gives us our encrypted string, the cipher text, which we can send to our friends and allies content in the knowledge that nobody can break our state-of-the-art cipher(!).

How then does the recipient decrypt the cipher? Apart from going to one of the countless online breaking tools or breaking it mathematically or using letter analysis, we can of course use Python again to do the decryption. Basically it’s the opposite of what we just did for encryption:

`num = ord(char)plain = (num - 97 - rot) % 26plain = chr(plain + 97)`

As you can see, we now subtract the rotation instead of adding it like in the encryption phase. We again use modulus to wrap around the alphabet, this time when we go lower than 0, or a.

Finally we can wrap the code in a loop so it works on the whole plainstring, import argparse so we can supply the string and rotation directly on the command line, and specify whether we want to encrypt or decrypt. The full script can be found on my GitHub repo or at the bottom of this post.

A few things to note: the script only encrypts letters, not symbols, and is hardcoded for the English alphabet (26 letters). Also, all letters will be changed to lowercase before encryption.

I hope you enjoyed this post. I intend to bring more crypto-related posts in the future since it is something I’m currently studying.

 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950 #!/usr/bin/python # Takes a string and shift encrypts or decrypts it using the # supplied rotation import argparse # Add arguments parser = argparse.ArgumentParser(description="Encrypt/decrypt     Caesar cyphers") parser.add_argument("mode", help="Encrypt or decrypt", nargs="?",     choices=("encrypt", "decrypt")) parser.add_argument("string", help="String to encrypt/decrypt") parser.add_argument("rot", help="Rotation to use") args = parser.parse_args() # Definitions mode = args.mode string = args.string.lower() rot = int(args.rot) def encrypt(string, rot):         """Caesar encryption function"""      cypherstr = ""      for char in string:          if not char.isalpha():              cypher = char          elif char.isalpha():              num = ord(char)              cypher = (num - 97 + rot) % 26              cypher = chr(cypher + 97)          cypherstr += cypher      return cypherstr def decrypt(string, rot):      """Caesar decryption function"""      plainstr = ""      for char in string:          if not char.isalpha():              plain = char          elif char.isalpha():              num = ord(char)              plain = (num - 97 - rot) % 26              plain = chr(plain + 97)          plainstr += plain      return plainstr # Either encrypt or decrypt if mode == "encrypt":      print(encrypt(string, rot)) elif mode == "decrypt":      print(decrypt(string, rot))

## DVWA login brute-forcer in Python

I recently started playing around with the Damn Vulnerable Web Application, a PHP/MySQL web app for security researchers and students. It is, as the name implies, damn vulnerable.

After installation of DVWA you’ll be presented with a login page. Unless you supply the user and password from the manual you’ll have to get access some other way. Fruitlessly trying some SQL injection I decided to simply brute force the login, and used Burp Suite to get some more information. Turns out that all you need to login is the username, password, user token and a session id. The session id is provided in a cookie, the user token by the login page, and the username and password is of course what we need to find.

 1

While manually supplying a few user names and passwords I found out that the login page responds with a 302 Found HTTP response, either forwarding back to the login page in case of a failed login, or to index.php in case of a successful login (I already knew the default user name and password from the manual). Going back to the index.php resulted in a new user token being generated, but ignoring the forward meant I could continue supplying the same user token again and again.

I wrote the brute forcer in python using BeautifulSoup, requests and re, all python modules. The program is pretty simple: request the login page, find and extract the user token from within the login page, get the session id from the cookie, and return these plus a random username and password with a HTTP POST method.

Running this script with a supplied list of user names and passwords meant I was able to find the login in just a few seconds. The script is tailored to DVWA but could easily be customised for other vulnerable sites.

## Decoding base64 in Python

This is a small tutorial for beginners on how to decode base64 text strings in Python3. While Python does have a function to directly encode and decode base64, it is always good practice to try and write one yourself if you are a new programmer.

Head over to Wikipedia to see how base64 is decoded. First, each character in the encoded string is assigned a number according to the base64 table. This number is then translated to 6 bit binary.

You can do this in Python by including the base64 table as a dictionary, and iterating through all characters in the encoded string, like this:

```for char in string:
if char in index.keys():
bin_string +=
"{0:06b}".format(index.get(char))```

The last line formats the decimal value to 6-bit binary ({0:06b}). As the highest value in the base64 table is 63 (for the / character), 6 bits are exactly enough to hold it and no information will be lost (0b111111 = 63).

The above loop creates one long binary string (bin_string) which should now be partitioned in bytes (8 bits) and converted to ASCII. This can be accomplished with the following loop:

```while len(bin_string) >= 8:
byte = bin_string[1:8]
char = chr(int(byte, 2))
output += char
bin_string = bin_string[8:]```

This code iterates through the binary string until it’s less than 8 bits long (which should be the end), takes the first byte and converts it to ASCII (actually, Unicode) using the chr function. This could also be done by including an ASCII table and using that to convert, just like we did in the beginning with the base64 table. I’ll leave that as an exercise.
Finally, it removes the first byte from the binary string which we just converted, and the loop continues to the next byte.

If you use print(output) now, it should display the decoded string.

To make the script a little more intuitive you can incorporate the argparse module which allows the coded string to be included as an argument while running the script, like this:

`python base64_decode.py --TWFu`

Where ‘TWFu’ is an encoded string.

The code for argparse is as follows:

```import argparse

parser = argparse.ArgumentParser(Description="")