Scan Wifi from Terminal

There is a command line tool that allows you to work with the wireless connection on your Mac. The tool is very useful but by default hidden and not well documented.

airport

# show airport help
$ /System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport --help

networksetup

# find device names
$ networksetup -listallhardwareports

Turn on/off and join

# turn it off
$ networksetup -setairportpower en0 off

# turn it on
$ networksetup -setairportpower en0 on

# join a network
$ networksetup -setairportnetwork en0 <SSID> <Password>

Let`s start a wifi scan and get some information

# scan with interface en0
$ /System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport en0 --scan

# show information of en0
$ /System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport en0 --getinfo

Note: If do not specify the interface, airport will use the first wifi interface on the system.

Easy way

# create a symbolic link to the command
$ sudo ln -s /System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport /usr/sbin/airport

# after link created start the scan
$ airport en0 --scan

Sniff

# find WEP
$ airport en0 scan | grep WEP

# start sniff on channel
$ airport en0 sniff 6

The captured packets you will find as “/tmp/airportSniffXXXXXX.cap”.

Publish continuous integration status on Desktop

In one of my last tutorials, i show how to develop test tools for software tester with Python. Now i will show you, how to publish continuous integration status information for other team members like Scrum master, Product owner or Test manager.

Preconditions

Note

If you don`t have Jenkins or Hudson running, search some public services with Google!

Example: inurl:8080 intitle:”Dashboard [Jenkins]”

Steps

Create a python script like this:

#!/usr/bin/env python
#  -*- coding: utf-8 -*-

import ast
import urllib


class JenkinsAPI(object):

    api = "/api/python?depth=1&tree=jobs[displayName,lastBuild[result]]"

    def __init__(self):
        self.url = 'http://masi.vuse.vanderbilt.edu:8080/jenkins/'

    def _get_status(self):
        xml_input_no_filter = ast.literal_eval(
            urllib.urlopen(self.url + self.api).read()
        )
        all_jobs = xml_input_no_filter['jobs']
        return all_jobs

    def show_results(self):
        job = self._get_status()
        fail = [row for row in job if 'SUCCESS' != row['lastBuild']['result']]
        passed = len(job) - len(fail)
        print "Jenkins: %s" % self.url
        print "Jobs: %s - Successful: %s - Failed: %s" % (
            len(job), passed, len(fail)
        )
        if len(fail) > 0:
            for (i, item) in enumerate(fail):
                print " > Job: %s - %s" % (
                    item['displayName'], item['lastBuild']['result']
                )
            del i


if __name__ == '__main__':
    RUN = JenkinsAPI()
    RUN.show_results()

Now start GeekTool and create a new Geeklet. Drag a Shell Geeklet on you Desktop. Now insert values for name, size, set colors and so on and add the python script on “Command”.

Create Geeklet

… the script.

Geeklet Command

Thats it! Now you can export the Geeklet and share it with you team members. My current screen looks like:

Geeklet result

Simple ssh brute-force attack with Hydra

With Hydra you can recover your SSH credentials. Here a tiny tutorial how it works.

Installation

I do install via ports but also different other possibilities are available.

# update macports (optional)
$ sudo port selfupdate

# search port (optional)
$ port search hydra

# check dependencies (optional)
$ port rdeps hydra

# install port
$ sudo port install hydra

Test preparation

Now create two files (or download anywhere)

# create password file
$ vim passwords.txt

# create users file
$ vim users.txt

Create some content (by line) and start the ssh brute-force with Hydra.

Run SSH password recover

# use password.txt only
$ hydra -l root -P passwords.txt <target> ssh

# use user.txt only
$ hydra -L users.txt -p 12345 <target> ssh

# use user and password files
$ hydra -L users.txt -P passwords.txt <target> ssh

If Hydra found something, the message looks like:

[22][ssh] host: <target> login: <user> password: <password>

Note: for legal purposes only!

Create your own test application

A lot of software testers do have no or less development skills. They also have less skills to use commandline tools and need GUI applications. In addition, the test applications for the respective claims should be easy to use. This guide will show you how to easily deploy software testers the needed test tools. This is just an example, please feel free to expand it!

Precondition

Let`s go

After create a new PyCharm project (with virtualenv), create 2 new empty files (requirements.txt, ShowHeaders.py) and import a icon. You can found icons (*.icns) on iconarchive for free.

application project files

Open the “requirements.txt” file and add Requests library.

requests==2.6.0

Open the “ShowHeader.py” and add the following content.

#!/usr/bin/env python
#  -*- coding: utf-8 -*-
"""
This is a main script

Usage:
    python ShowHeaders.py
"""
import requests
from Tkinter import (Tk, Frame, StringVar, OptionMenu, Button, Entry, Text,
                     END, DISABLED, NORMAL, SUNKEN, E, W)


class ShowHeaders(object):
    """
    ShowHeaders class
    """

    OPTIONS = ["GET", "POST", "PUT", "DELETE"]

    def __init__(self):
        """
        Constructor for Tk GUI
        """
        self.root = Tk()
        self.root.title('Show Headers')
        self.root.configure(bg="light blue")
        self.option = StringVar(self.root)
        self.option.set(self.OPTIONS[0])
        self.methods = None
        self.url = None
        self.response = None
        self.copy = None

    def create_gui(self):
        """
        Create Tk GUI
        """
        self._create_top_frame()
        self._create_middle_frame()
        self._create_bottom_frame()
        self.root.mainloop()

    def close_app(self):
        """
        Close & Quit Application
        """
        self.root.quit()

    def _print_response(self, response_txt):
        """
        Print response
        """
        self.response.config(state=NORMAL)
        self.response.delete(1.0, END)
        self.response.insert(END, response_txt)
        self.response.config(state=DISABLED)

    def _copy_to_clipboard(self):
        """
        Copy to text clipboard
        """
        text = self.response.get("1.0", END)
        self.root.clipboard_clear()
        self.root.clipboard_append(text)

    def _make_request(self):
        """
        Run http request and print
        """
        self.copy.config(state="normal")
        methods = self.option.get()
        url = self.url.get()
        if methods == 'GET':
            req = requests.get(url)
        elif methods == 'POST':
            req = requests.post(url)
        elif methods == 'PUT':
            req = requests.put(url)
        elif methods == 'DELETE':
            req = requests.delete(url)
        else:
            req = dict()
        header = req.headers
        self._print_response(header)

    def _create_top_frame(self):
        """
        Create top frame
        """
        top_frame = Frame(self.root)
        top_frame.grid(row=0, column=0, padx=5, pady=5, sticky=W+E)

        self.methods = OptionMenu(top_frame, self.option, *self.OPTIONS)
        self.methods.config(width=15)
        self.methods.grid(row=0, column=0)

        self.url = Entry(top_frame, width=50)
        self.url.insert(0, "http://")
        self.url.grid(row=0, column=1)

        Button(top_frame, text='Request', command=self._make_request).grid(
            row=0, column=2)

    def _create_middle_frame(self):
        """
        Create middle frame
        """
        middle_frame = Frame(self.root, height=75, bd=1, relief=SUNKEN)
        middle_frame.grid(row=1, column=0, padx=5, pady=5)

        self.response = Text(middle_frame, height=10)
        self.response.config(state=DISABLED)
        self.response.grid(row=1)

    def _create_bottom_frame(self):
        """
        Create bottom frame
        """
        bottom_frame = Frame(self.root)
        bottom_frame.grid(row=2, column=0, padx=5, pady=5, sticky=W+E)

        self.copy = Button(bottom_frame, text="Copy", state=DISABLED,
                           command=self._copy_to_clipboard)
        self.copy.grid(row=0, column=0)

        Button(bottom_frame, text='Quit', command=self.close_app).grid(
            row=0, column=1)


if __name__ == '__main__':
    APP = ShowHeaders()
    APP.create_gui()

For first test, run the application. If there are no issues – open the PyCharm terminal and run the following command.

$ py2applet --make-setup ShowHeaders.py

# or if you use virtualenv
$ /Users/<username>/ShowHeaderEnv/bin/py2applet --make-setup ShowHeaders.py

Now you should see the generated file “setup.py” in the Project. Open the file and add the icon. The content should look like this:

"""
This is a setup.py script generated by py2applet

Usage:
    python setup.py py2app
"""

from setuptools import setup

APP = ['ShowHeaders.py']
DATA_FILES = []
OPTIONS = {'argv_emulation': True, 'iconfile':'header.icns'}

setup(
    app=APP,
    data_files=DATA_FILES,
    options={'py2app': OPTIONS},
    setup_requires=['py2app'],
)

Now execute the following command to build, for first test.

$ python setup.py py2app -A

After some messages in terminal, your Project should show 2 new folders (build, dist). The alias mode (-A / –alias) instructs py2app to build an application, but it is not portable to other machines! You can open the Application in Finder or from terminal for your tests. If there are changes, just run the build-command again.

$ open dist/ShowHeaders.app

If everything is fine and your Application is ready for ship, run the following command.

# remove build and dist folder
$ rm -fr build/ dist/

# build application
$ python setup.py py2app

Again the Application can be found on folder “dist”. The result should look like this:

example application

Have fun and be creative! Too ship the test application for Windows users, look at py2exe.

PyCharm with Virtualenv on Mac OS X

This guide shows you how to use PyCharm with virtualenv on Mac OS X.

Preconditions

PyCharm installed

Steps

First install we install Virtualenv and Virtualenvwrapper.

# if pip not installed
$ sudo easy_install pip

# install virtualenv
$ sudo pip install virtualenv

# install virtualenvwrapper
$ sudo pip install virtualenvwrapper

Now we start PyCharm to create new project.

PyCharm Virtualenv

After given the new name for the project on Location, select for Interpreter “Create VirtualEnv”.

PyCharm Create Virtualenv

Create Virtual Environment dialog box opens. Here type the name of the new virtual environment and specify the target directory for he new virtual environment on Location. Select one “Base interpreter” and if needed, select the check box “Inherit global site-packages”.

PyCharm Virtualenv Setup

Press “OK” button to apply changes and close the dialog box. After press the  “Create” button – PyCharm create the new project.

Speed up with VBoxManage

If you use Virtualbox, you can speed up your daily workflow with VBoxManage. This guide show some basic commands.

Precondition

VirtualBox installed

Commands

# show version
$ VBoxManage --version

# show help
$ VBoxManage --help

# list all VM's
$ VBoxManage list vms

# list only running VM's
$ VBoxManage list runningvms

# show VM information
$ VBoxManage showvminfo <uuid|vmname>

# start VM (GUI)
$ VBoxManage startvm <uuid|vmname>

# start VM (Headless)
$ VBoxManage startvm <uuid|vmname> --type headless

# pause VM
$ VBoxManage controlvm <uuid|vmname> pause

# resume VM
$ VBoxManage controlvm <uuid|vmname> resume

# shutdown VM
$ VBoxManage controlvm <uuid|vmname> poweroff

There ‘s more! If you are familiar with basic commands, read the help or user manual!

Install Jenkins with Puppet

As a software tester you need a test environment! The test environment should be soon as possible and without outside resources deployable. This guide shows you how to install Jenkins on Debian/Ubuntu with Puppet (Version 2.7.x).

Preparation

# get puppet version
$ puppet --version

# get puppet-lint version
$ puppet-lint --version

If Puppet and Puppet-Lint are not installed:

# update and upgrade
$ apt-get update && apt-get upgrade

# install puppet and puppet-lint
$ apt-get install puppet && apt-get install puppet-lint

The project looks like the following:

testenvironment
├── manifests
│   ├── nodes.pp
│   └── site.pp
└── modules
    └── jenkins
        └── manifests
            └── init.pp

Steps

# create folders
$ mkdir -p testenvironment/manifests
$ mkdir -p testenvironment/modules/jenkins/manifests

# create files
$ touch testenvironment/manifests/site.pp
$ touch testenvironment/manifests/nodes.pp
$ touch testenvironment/modules/jenkins/manifests/init.pp

The first content we add is for “site.pp”. Here we include the “nodes.pp” and setup basic paths.

import 'nodes.pp'

Exec {
    path => ['/bin', '/usr/bin'],
}

The next content is for second file “nodes.pp”. Here we create the case statement with the include for Jenkins class and a message (if OS is not supported).

node default {
    case $::operatingsystem {
        'Debian', 'Ubuntu' : { include jenkins }
        default  : { notify {"$::operatingsystem is not supported yet":} }
    }
}

As last step we create the content for “init.pp”.

class jenkins {
    # get key
    exec { 'install_jenkins_key':
        command => 'wget -q -O - http://pkg.jenkins-ci.org/debian/jenkins-ci.org.key | apt-key add - ',
    }

    # update
    exec { 'apt-get update':
        command => 'apt-get update',
        require => File['/etc /apt/sources.list.d/jenkins.list'],
    }

    # source file
    file { '/etc /apt/sources.list.d/jenkins.list':
        content => "deb http://pkg.jenkins-ci.org/debian binary/\n",
        mode    => '0644',
        owner   => root,
        group   => root,
        require => Exec['install_jenkins_key'],
    }

    # jenkins package
    package { 'jenkins':
        ensure  => latest,
        require => Exec['apt-get update'],
    }

    # jenkins service
    service { 'jenkins':
        ensure  => running,
        require => Package['jenkins'],
    }
}

Note: The space after “/etc /apt” on “update” and “source file” should removed! I made this just because of the security policies of my provider. They do not allow! 🙁

Continue

First we check the syntax with the puppet-lint. As software tester i think you always lint! 😉

# example project-wide
$ puppet-lint testenvironment/

# example specific files
$ puppet-lint testenvironment/manifests/site.pp
$ puppet-lint testenvironment/manifests/nodes.pp
$ puppet-lint testenvironment/modules/jenkins/manifests/init.pp

Now we make some different “Dry-runs”.

# simple Dry-run with noop
$ puppet apply testenvironment/manifests/site.pp --modulepath=/root/testenvironment/modules/ $* --noop

# Dry-run with noop and summarize
$ puppet apply testenvironment/manifests/site.pp --modulepath=/root/testenvironment/modules/ $* --noop --summarize

# Dry-run with noop, summarize and debug
$ puppet apply testenvironment/manifests/site.pp --modulepath=/root/testenvironment/modules/ $* --noop --summarize --debug

With “–noop” nothing is really executed. The “–modulepath”, “–summarize” and “–debug” speaks for themselves.

the Final

Now the final, after the Puppet is ready you should able to connect to Jenkins.

# run puppet
$ puppet apply testenvironment/manifests/site.pp --modulepath=/root/testenvironment/modules/ $*

 

Textmate with Puppet syntax highlighting

To enable syntax highlighting for puppet in textmate, follow this guide.

Preconditions

  • Textmate installed
  • Git installed (available with command line developer tools)

Steps

Create new folder somewhere on your directories. I do directly on Desktop.

# create new directory
$ mkdir ~/Desktop/Bundles

Go inside created folder and clone from Git repository.

# change directory
$ cd ~/Desktop/Bundles

# run git clone
$ git clone https://github.com/masterzen/puppet-textmate-bundle.git Puppet.tmbundle

Move the “Puppet.tmbundle” file into specific folder and delete created folder on desktop.

# move file
$ mv ~/Desktop/Bundles/Puppet.tmbundle ~/Library/Application\ Support/TextMate/Bundles/

# delete created directory
$ rm -fr ~/Desktop/Bundles

Now select a *.pp file and open with Textmate. In the Textmate dialog, select “Puppet” and “Install Bundle”.