It is time again for an extensive tutorial. This time, a tiny test application for passive and active information gathering. After the instruction you are welcome to improve the application with more features! Okay let’s start…
What should it do?
The security tester selects a information gathering method first. As second step the testers insert the URL or IP in a testfield and press a button. The result should printed out in a text area. The GUI should look like this:
How it is implemented?
The prefered language is Python 2.7. So it is portable to different OS and for the most of methods are already packages available. The GUI is done with Tkinter. Tkinter provides all objects which are needed as widgets and ranges for this scope out completely. The file and folder structure look like:
├── essential │ ├── __init__.py │ └── timestop.py ├── gathering │ ├── __init__.py │ ├── geolocation.py │ ├── icmpping.py │ ├── information.py │ ├── wappalyzer.py │ └── whoisgathering.py ├── requirements.txt └── sensei.py
File content
Files in root directory:
requests python-Wappalyzer python-whois
#!/usr/bin/env python # -*- coding: utf-8 -*- from urlparse import urlparse from gathering import IcmpPing, WhoisGathering, GeoLocation, WappAlyzer from Tkinter import (Tk, Frame, StringVar, OptionMenu, Entry, Button, Text, W, E, END, FALSE) class Sensei(object): def __init__(self): self.root = Tk() self.root.title('Sensei') self.root.resizable(width=FALSE, height=FALSE) self.select = [ 'ICMP Ping', 'Whois', 'GeoLocation', 'Wappalyzer' ] self.option = StringVar(self.root) self.option.set(self.select[0]) self.method = None self.url = None self.result = None def create_gui(self): self._top_frame() self._output_frame() self.root.mainloop() def quite_app(self): self.root.quit() def _start_request(self): self.result.delete(1.0, END) action = None target = self.url.get() method = self.option.get() if method == 'ICMP Ping': action = IcmpPing() elif method == 'Whois': action = WhoisGathering() elif method == 'GeoLocation': action = GeoLocation() elif method == 'Wappalyzer': action = WappAlyzer() if target: action.set_target(target) action.do_request() value = action.get_result() else: value = 'Internal Error' self.result.insert(END, value) def check_protocol(self, value): target = self.url.get() if value == 'Wappalyzer': if 'http' not in target: self.url.insert(0, 'http://') else: if 'http' in target: new_target = urlparse(target) self.url.delete(0, END) self.url.insert(0, new_target[1]) def _top_frame(self): top_frame = Frame(self.root) top_frame.grid(column=0, row=0, sticky=W+E) self.method = OptionMenu( top_frame, self.option, *self.select, command=self.check_protocol ) self.method.config(width=15) self.method.grid(column=0, row=0) self.url = Entry(top_frame, width=50) self.url.grid(column=1, row=0) Button(top_frame, text='Request', command=self._start_request).grid( column=2, row=0) Button(top_frame, text='Close', command=self.quite_app).grid( column=3, row=0) def _output_frame(self): output_frame = Frame(self.root) output_frame.grid(column=0, row=2, sticky=W+E) self.result = Text(output_frame, height=15) self.result.grid(column=0, row=0) if __name__ == '__main__': RUN = Sensei() RUN.create_gui()
Files in essential:
#!/usr/bin/env python # -*- coding: utf-8 -*- from essential.timestop import TimeStop
#!/usr/bin/env python # -*- coding: utf-8 -*- from datetime import datetime class TimeStop(object): """missing docstring""" __start = None @classmethod def start_measure(cls): cls.__start = datetime.now() @classmethod def stop_measure(cls): stop = datetime.now() total = stop - cls.__start return ">>>> request complete in " + str(total)
Files in gathering:
#!/usr/bin/env python # -*- coding: utf-8 -*- from gathering.information import InformationGathering from gathering.icmpping import IcmpPing from gathering.whoisgathering import WhoisGathering from gathering.geolocation import GeoLocation from gathering.wappalyzer import WappAlyzer
#!/usr/bin/env python # -*- coding: utf-8 -*- class InformationGathering(object): def __init__(self): self.errors = 0 self.target = '' self.result = '' def set_target(self, target): victim = target.strip(' \t\n\r') if not victim: self.errors += 1 self.result = 'No target given!' else: self.target = target def get_result(self): return self.result
#!/usr/bin/env python # -*- coding: utf-8 -*- from gathering.information import InformationGathering from essential.timestop import TimeStop import os import platform class IcmpPing(InformationGathering): COMMAND = '' def __create_command(self): operation_system = platform.system() if operation_system == "Windows": self.COMMAND = "ping -n 1 " elif operation_system == "Linux": self.COMMAND = "ping -c 1 " else: self.COMMAND = "ping -c 1 " def do_request(self): if self.errors == 0: self.__create_command() command = self.COMMAND + self.target TimeStop.start_measure() response = os.popen(command) for line in response.readlines(): self.result += line self.result += TimeStop.stop_measure()
#!/usr/bin/env python # -*- coding: utf-8 -*- from gathering.information import InformationGathering from essential.timestop import TimeStop import whois class WhoisGathering(InformationGathering): def do_request(self): if self.errors == 0: TimeStop.start_measure() result = whois.whois(self.target) self.result += result.text self.result += TimeStop.stop_measure()
#!/usr/bin/env python # -*- coding: utf-8 -*- from gathering.information import InformationGathering from essential.timestop import TimeStop import requests class GeoLocation(InformationGathering): API = 'http://ip-api.com/json/' def do_request(self): if self.errors == 0: target = self.API + self.target TimeStop.start_measure() response = requests.get(target) output = response.json() for key, val in output.items(): if val: self.result += str(key) + " => " + str(val) + "\n" self.result += TimeStop.stop_measure()
#!/usr/bin/env python # -*- coding: utf-8 -*- from gathering.information import InformationGathering from essential.timestop import TimeStop from Wappalyzer import Wappalyzer, WebPage class WappAlyzer(InformationGathering): def do_request(self): if self.errors == 0: TimeStop.start_measure() wappalyzer = Wappalyzer.latest() website = WebPage.new_from_url(self.target) output = wappalyzer.analyze(website) for val in output: self.result += " => " + str(val) + "\n" self.result += TimeStop.stop_measure()
That was it. The result looks like this:
Improve it with your ideas!