Creating QR Code with Google

So today I thought I would be neat to show how to quickly create QR codes using Google’s Chart Tools.

Google gives us a extremely easy way to create QR code by sending GET data request via URL:

https://chart.googleapis.com/chart?cht=qr&chs=300×300&chl=nessy

That is nice and easy, but I figured I would wrap this up in a small Python script just because:

#!/usr/bin/env python
from urllib2 import quote, urlopen, Request
from poster.encode import multipart_encode
from poster.streaminghttp import register_openers
import sys

def create(width, heigth, data):
    '''Builds a URL for Google to create us a QR code'''
    # build and make URL request
    google_chart = 'https://chart.googleapis.com'
    url = '%s/chart?cht=qr&chs=%sx%s&chl=%s' % (google_chart, width, heigth, quote(data))
    request = urlopen(url)
    response = request.read()

    # write QR code to file
    f = open('qr.png', 'w')
    f.write(response)
    f.close
    return 'Wrote qr.png..'

def read(qr_file):
    '''Reads a QR code by URL'''
    # post image to decode page
    register_openers()
    datagen, headers = multipart_encode({'f': open(qr_file)})
    request = Request('http://zxing.org/w/decode', datagen, headers)
    response = urlopen(request).read()
    return response

if sys.argv[1] == 'create':
    print create(300, 300, sys.argv[2])

if sys.argv[1] == 'read':
    print read(sys.argv[2])

Basic usage works like so:

$ ./qr.py create "My name is Nessy, Hello"
Wrote qr.png..

Running the create option will write a file named qr.png to your current directory:

$ file qr.png
qr.png: PNG image, 300 x 300, 8-bit/color RGB, non-interlaced

qr

And reading this QR code works just like this:

$ ./qr.py read qr.png
My name is Nessy, Hello

Brute Forcing Salted Password

Since my last post showed how to check a salted password, I figured this time we can look over some example code for brute forcing a salted password. Of course this is just proof of concept and should not be used on any password you do not have access to.

The code I tossed together is using a bit of some examples I found online, and is no where near optimized for speed, but as I will show it will work.

First lets check out the code:

#!/usr/bin/env python
import sys
from md5 import md5
from crypt import crypt

def nextChar():
    '''create a generator for spitting out our chars'''
    chars = range(97,124) # Lower case range
    chars = map(chr, chars)
    for char in chars:
        yield char

def passRecurse(width, position, baseString):
    '''Loop over all characters using width'''
    for c in nextChar():
        if (position < width - 1):
            thisPassword = baseString + c
            passRecurse(width, position + 1, baseString + c)
        thisPassword = baseString + c

        # link in to external function here
        newhash = SHA512Salt(thisPassword, salt)
        if newhash == hash:
            print 'Password hash matached: %s' % thisPassword
            sys.exit()

def SHA512Salt(password, salt):
    output = crypt(password, '$6$%s$' % salt)
    return output.split('$')[-1]

# Set up some variables and start the Brute
width = 3
salt = sys.argv[1]
hash = sys.argv[2]
passRecurse(width, 0, '')

I was not able to find or think of a better way to create passwords using a character map other than calling the function within the function (eww….), if you have any examples or suggestion please let me know.

This time I set the password for the dummy user to bat (save some time and CPU cycles I suppose):

# cat /etc/shadow| grep dummy
dummy:$6$cIYtIxDs$XzsdCG1TD3hO3qpEtUardUbVPQRsEOgq.1yqWl8iFp0DCF4ZSbppuj63sXHwzEj7Faz5MRoVf2LxtD9kUwpG5.:15313:0:99999:7:::

Using the Python script above works as so (and ran in 3.690s):

$ ./brute.py cIYtIxDs "XzsdCG1TD3hO3qpEtUardUbVPQRsEOgq.1yqWl8iFp0DCF4ZSbppuj63sXHwzEj7Faz5MRoVf2LxtD9kUwpG5."
Password hash matached: bat

UNIX SHA-512 Passwords & Python

Well today I spent a bit of time looking up how /etc/shadow created their shadow passwords.

I found a good source for the method at http://www.akkadia.org/drepper/SHA-crypt.txt , and if you take some time to review it you will notice the steps are a bit involved

Lucky for us Python has a Crypt module that works nicely.

First off I started by creating a dummy user with the password of test on one of my Linux computers:

# cat /etc/shadow | grep dummy
dummy:$6$JJ1sbaL/$2P4ZcZ10VjIa9f5.8N/GJukYCg.RJVBTP2h30v2mnh0Q5izqc2rtKZ6qtI0Ewiyji
      0hX9zIVfftOVuJTIsBSKQ/:15310:0:99999:7:::

And like that we have a password we can attempt to validate.

Next I will need to define our salt in Python. A good article explaining the format of /etc/shadow can be found on cyberciti.biz. Like the article says the salt is found between the $ after the username and before the password hash. For comparison I will also extract the hash:

>>> salt = 'JJ1sbaL/'
>>> hash = '2P4ZcZ10VjIa9f5.8N/GJukYCg.RJVBTP2h30v2mnh0Q5izqc2rtKZ6qtI0Ewiyj0hX9zIVfftOVuJTIsBSKQ/'

Now that we have our salt we can create a hash of our password using that salt and verify it matches the hash shown in /etc/shadow:

>>> import crypt
>>> output = crypt.crypt('test', '$6$%s$' % salt)
>>> print output
$6$JJ1sbaL/$2P4ZcZ10VjIa9f5.8N/GJukYCg.RJVBTP2h30v2mnh0Q5izqc2rtKZ6qtI0Ewiyj0hX9zIVfftOVuJTIsBSKQ/

And lastly lets compare the new hash with the one found in /etc/shadow:

>>> newhash = output.split('$')[-1]
>>> print newhash
'2P4ZcZ10VjIa9f5.8N/GJukYCg.RJVBTP2h30v2mnh0Q5izqc2rtKZ6qtI0Ewiyj0hX9zIVfftOVuJTIsBSKQ/'
>>>
>>> newhash == hash
True

Wordlist with all Possible ASCII Elements

After a bit of thinking I believe I have a better way to create all possible ASCII pass phrases, rather than create a recursive function that calls itself as I did in the previous post.

This method takes a slightly different approach, but I believe it to return the same results.

First off let’s create a list of all lower case ASCII character numbers:

>>> chars = range(97, 123)
>>> chars
[97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
113, 114, 115, 116, 117, 118, 119, 120, 121, 122]
>>> map(chr, chars)
['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']

Next we can set our max word width and current word width variables:

import itertools
maxwidth = 3
currentwidth = 1

At this point we are ready to run with a while loop:

while int(currentwidth) <= int(maxwidth):
    for i in itertools.product(chars, repeat=currentwidth):
        print ''.join(['%c' % c for c in list(i)])
    currentwidth += 1

The loop above will run until currentwidth is greater than maxwidth (makes sense right), at that point we use itertools’s product method to create all possible orderings for our characters.

Then using list comprehension I print out the %c which returns the alphabetical character.

And lastly we increase the currentwidth by 1

What itertools.product does is creates all possible combinations (including repeated chars):

>>> [i for i in itertools.product(chars, repeat=2)]
[(97, 97), (97, 98), (97, 99), (97, 100), (97, 101), (97, 102), (97,
 103), (97, 104), (97, 105), (97, 106), (97, 107), (97, 108), (97, 109),
 (97, 110), (97, 111), (97, 112), (97, 113), (97, 114), (97, 115), (97,
 116), (97, 117), (97, 118), (97, 119), (97, 120), (97, 121), (97, 122),
 (98, 97), (98, 98), (98, 99), (98, 100), (98, 101), (98, 102), (98,
103), (98, 104), (98, 105), (98, 106), (98, 107), (98, 108), (98, 109),
 (98, 110), (98, 111), (98, 112), (98, 113), (98, 114), (98, 115), (98,
 116), (98, 117), (98, 118), (98, 119), (98, 120), (98, 121), (98, 122),
 (99, 97), (99, 98), (99, 99), (99, 100), (99, 101), (99, 102), (99,
......
.....
...

Of course you probably want to see those tuples of characters as letters right:

>>> for i in itertools.product(chars, repeat=2):
...   ''.join(['%c' % c for c in i])
...
'aa'
'ab'
'ac'
'ad'
'ae'
'af'
'ag'
'ah'
'ai'
'aj'
'ak'
'al'
'am'
'an'
'ao'
'ap'
'aq'
'ar'
'as'
'at'
'au'
'av'
'aw'
'ax'
..
..
..

Python Libvirt Domain Configuration

So in my last article I talked a little bit about using libvirt to start and stop QEMU domains.

In this article I would like to go over how domains are created.

QEMU uses XML files for each domain configuration, and using libvirt we can access that data.

First off lets connect to our local running QEMU instance:

>>> import libvirt
>>> conn = libvirt.open('qemu:///system')

Next lets look for and link to a running domain:

>>> conn.listDomainsID()
[35, 36, 37, 41, 38, 39]

>>> domain = conn.lookupByID(35)

The libvirt domain object gives os a function called XMLDesc() which we can use to see our running configuration:

>>> raw_xml = domain.XMLDesc(0)
>>> print raw_xml

<domain type='kvm' id='35'>
  <name>build01-dev</name>
  <uuid>c5c698cc-95bb-188d-3b5a-625asdj128sd</uuid>
  <memory>1048576</memory>
  <currentMemory>1048576</currentMemory>
  <vcpu>2</vcpu>
  <os>
    <type arch='x86_64' machine='fedora-13'>hvm</type>
    <boot dev='hd'/>
  </os>
  <features>
    <acpi/>
    <apic/>
    <pae/>
  </features>
  <clock offset='utc'/>
  <on_poweroff>destroy</on_poweroff>
  <on_reboot>restart</on_reboot>
  <on_crash>restart</on_crash>
  <devices>
    <emulator>/usr/bin/qemu-kvm</emulator>
    <disk type='file' device='disk'>
      <driver name='qemu' type='qcow2'/>
      <source file='/mnt/data/libvirt/datastore01/data01-dev-clone-2.img'/>
      <target dev='vda' bus='virtio'/>
      <alias name='virtio-disk0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
    </disk>
    <disk type='file' device='cdrom'>
      <driver name='qemu' type='raw'/>
      <target dev='hdc' bus='ide'/>
      <readonly/>
      <alias name='ide0-1-0'/>
      <address type='drive' controller='0' bus='1' unit='0'/>
    </disk>
    <controller type='ide' index='0'>
      <alias name='ide0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
    </controller>
    <interface type='bridge'>
      <mac address='50:00:00:00:00:00'/>
      <source bridge='br1'/>
      <target dev='vnet0'/>
      <model type='e1000'/>
      <alias name='net0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
    </interface>
    <serial type='pty'>
      <source path='/dev/pts/0'/>
      <target port='0'/>
      <alias name='serial0'/>
    </serial>
    <console type='pty' tty='/dev/pts/0'>
      <source path='/dev/pts/0'/>
      <target type='serial' port='0'/>
      <alias name='serial0'/>
    </console>
    <input type='tablet' bus='usb'>
      <alias name='input0'/>
    </input>
    <input type='mouse' bus='ps2'/>
    <graphics type='vnc' port='5900' autoport='yes'/>
    <video>
      <model type='cirrus' vram='9216' heads='1'/>
      <alias name='video0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
    </video>
    <memballoon model='virtio'>
      <alias name='balloon0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </memballoon>
  </devices>
</domain>

Now say you are interested in working with this XML data, we can do just that using the xml module:

>>> from xml.dom import minidom
>>> xml = minidom.parseString(raw_xml)

And something that may be useful in the XML above is the type tag, so lets grab that data:

>>> domainTypes = xml.getElementsByTagName('type')
>>> for domainType in domainTypes:
...   print domainType.getAttribute('machine')
...   print domainType.getAttribute('arch')
...
fedora-13
x86_64

And there you have it, we can easily pull out data from this XML using the minidom function.

Using this data it should be pretty easy to deploy a new guest domain using the createXML function:

Help on method createXML in module libvirt:

createXML(self, xmlDesc, flags) method of libvirt.virConnect instance
    Launch a new guest domain, based on an XML description similar
    to the one returned by virDomainGetXMLDesc()
    This function may require privileged access to the hypervisor.
    The domain is not persistent, so its definition will disappear when it
    is destroyed, or if the host is restarted (see virDomainDefineXML() to
    define persistent domains).

    If the VIR_DOMAIN_START_PAUSED flag is set, the guest domain
    will be started, but its CPUs will remain paused. The CPUs
    can later be manually started using virDomainResume.

    If the VIR_DOMAIN_START_AUTODESTROY flag is set, the guest
    domain will be automatically destroyed when the virConnectPtr
    object is finally released. This will also happen if the
    client application crashes / loses its connection to the
    libvirtd daemon. Any domains marked for auto destroy will
    block attempts at migration, save-to-file, or snapshots.