- Joined
- Jan 24, 2006
- Location
- South Dakota
So I am using this thread mostly as my own way of tracking my progress.
The idea is that I am developing a python program that gets the input from Nmap and stores it in a mysql database.
Currently my table layout is as follows
Currently you have to edit the script to tell nmap where to scan. Eventually it will take user input. The script which puts the information into mysql is as follows
Here is a down and dirty UI:
I merged the IANA parsing and have 7zipped the xml file and attached it here
Below find an updated UI with gtk
Added a completely GTK interface. Functional but could use some design help. Scroll bars added and slight redesign substituting liststore for treestore Oct 1, 2011
The idea is that I am developing a python program that gets the input from Nmap and stores it in a mysql database.
Currently my table layout is as follows
Code:
-- phpMyAdmin SQL Dump
-- version 3.3.10deb1
-- http://www.phpmyadmin.net
--
-- Host: localhost
-- Generation Time: Sep 23, 2011 at 09:47 PM
-- Server version: 5.1.54
-- PHP Version: 5.3.5-1ubuntu7.2
SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
--
-- Database: `nmap`
--
-- --------------------------------------------------------
--
-- Table structure for table `Computer_Info`
--
CREATE TABLE IF NOT EXISTS `Computer_Info` (
`Computer_ID` int(11) NOT NULL AUTO_INCREMENT,
`DNS_Name` varchar(50) NOT NULL,
`Computer_IP_Address` varchar(15) NOT NULL,
`OS_ID` int(11) NOT NULL,
PRIMARY KEY (`Computer_ID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
--
-- Dumping data for table `Computer_Info`
--
-- --------------------------------------------------------
--
-- Table structure for table `Computer_Ports`
--
CREATE TABLE IF NOT EXISTS `Computer_Ports` (
`Computer_ID` int(11) NOT NULL,
`Port_ID` int(11) NOT NULL,
PRIMARY KEY (`Computer_ID`,`Port_ID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
--
-- Dumping data for table `Computer_Ports`
--
-- --------------------------------------------------------
--
-- Table structure for table `OS_Table`
--
CREATE TABLE IF NOT EXISTS `OS_Table` (
`OS_ID` int(11) NOT NULL AUTO_INCREMENT,
`OS_Name` varchar(100) NOT NULL,
PRIMARY KEY (`OS_ID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
--
-- Dumping data for table `OS_Table`
--
-- --------------------------------------------------------
--
-- Table structure for table `Ports_Table`
--
CREATE TABLE IF NOT EXISTS `Ports_Table` (
`Port_ID` int(11) NOT NULL AUTO_INCREMENT,
`Port_Number` int(11) NOT NULL,
PRIMARY KEY (`Port_Number`),
UNIQUE KEY `Port_ID` (`Port_ID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
--
-- Dumping data for table `Ports_Table`
--
-- --------------------------------------------------------
--
-- Table structure for table `Port_Description`
--
CREATE TABLE IF NOT EXISTS `Port_Description` (
`Port_Number` varchar(50) NOT NULL,
`Port_Description` varchar(100) NOT NULL,
`Port_Protocol` varchar(3) NOT NULL,
PRIMARY KEY (`Port_Number`),
UNIQUE KEY `Port_Number` (`Port_Number`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
--
-- Dumping data for table `Port_Description`
--
Currently you have to edit the script to tell nmap where to scan. Eventually it will take user input. The script which puts the information into mysql is as follows
Code:
#!/usr/bin/python
#This script is being designed to cleanup an NMAP produced text file and insert it into mysql
import sys, os
import re
import MySQLdb
from BeautifulSoup import BeautifulSoup, NavigableString
#####Global variables
last_line = '---' #if you reach this line, treat previous lines as a single block
scratch_file = "sit_new"
#nmap_output is the file which nmap will be piped to
nmap_output = "SIT_nmap"
#When the flag is set to 0 the script will begin to read
#When the flag is set to 1, the script knows that this is being designated as the last line
flag = 1
# Open the connection to the database
database_connection = MySQLdb.connect('192.168.89.22', 'root', '', 'nmap');
cursor = database_connection.cursor()
##########################################################################
def createNmap():
#Run the nmap command with the option to querry the host OS
#os.system("sudo nmap -O 192.168.88.0/24 > '%s'" % str(nmap_output))
nmap_unformatted = open(nmap_output, "r").readlines()
#Words to exclude
word1 = "up"
word3 = "Starting"
word4 = "done"
word5 = "Not"
word6 = "MAC"
word7 = "Device"
word8 = "Network"
word9 = "detection"
#Here I am redirecting standard out to the scratch file
#So that the info can be more easily managed
old_stdout = sys.stdout
sys.stdout = open(scratch_file, "w")
for line in nmap_unformatted:
if word1 not in line and word3 not in line and word5 not in line and word6 not in line and word7 not in line and word8 not in line and word9 not in line:
#replace the blank lines with dashes so that they are easier to parse
if line.isspace():
print "---"
else:
print line.strip()
#Put the stardard out back to normal
sys.stdout = old_stdout
##########################################################################
def parse_dns():
text = open(scratch_file, "r").readlines()
#filter out the hostname expecting user.company.com
hostname = re.compile(r'[\w\-][\w\-\.]+.com')
#filter out the IP, expecting a 192 address
ip = re.compile(r'192.\d+.\d+.\d+')
computer_id = 1
#go through the text line by line
ip_address_list = []
host_name_list = []
for word in text:
find_ip = ip.findall(word)
find_ip = " ".join(find_ip)
find_hostname = hostname.findall(word)
find_hostname = " ".join(find_hostname)
#if the hostname and the IP are blank pass
if str(find_hostname) == "" and find_ip == "":
pass
#If the hostname is not in dns but it has an ip, insert the information into the ip table
elif find_hostname == "" and find_ip != "":
computer_id +=1
print "inserting :", find_ip
ip_address_list.append(find_ip)
host_name_list.append("Not Available")
#This statement assumes that both the dns name and ip are parsed properly and it adds this information to the proper table
else:
print "inserting :", find_hostname
host_name_list.append(find_hostname)
ip_address_list.append(find_ip)
computer_id +=1
counter = 0
#Use the length of the ip_address_list to determine the number of loops to run to add to database
while counter < len(ip_address_list):
ID = counter + 1
print "Adding OS ID: ", ID, " IP Address: ", ip_address_list[counter], " and Host Name: ", host_name_list[counter]
cursor.execute("INSERT ignore INTO Computer_Info(Computer_ID, DNS_Name,Computer_IP_Address,OS_ID) values('%s','%s','%s', '%s')" % (ID, host_name_list[counter], ip_address_list[counter], ID))
cursor.execute("INSERT ignore INTO Computer_Ports(Computer_ID, Port_ID) values('%s', '%s')" % (ID, ID))
counter +=1
#########################################################################
def parse_ports():
###############Parse known ports from the IANA list ####################
#open the xml file for reading
ports_xml = open("port_numbers.xml", "r")
search_xml = BeautifulSoup(ports_xml)
#This tells beautiful soup to pull out only the name tag
search_unassigned_numbers = search_xml.findAll('record')
#The file contains stuff we dont want (unassined and reserved ports)
#This list contains the known ports that we want
filtered_entries = []
#append the appropriate ports to the filtered_entries list
for entries in search_unassigned_numbers:
entries = str(entries)
if "Unassigned" in entries or "Reserved" in entries:
pass
else:
filtered_entries.append(entries)
#Turn the list into text so that Beautiful soup can use it
filtered_entries = "".join([x for x in filtered_entries])
#Change the soup tags so that it is searching the filtered entries
search_xml = BeautifulSoup(filtered_entries)
search_port = search_xml.findAll('record')
#set the list for the port_descriptions
port_description = []
port_names = re.compile(r'<name>.*</name>')
counter = 0
#while counter < len(port_number):
for ports in search_port:
ports = str(ports)
find_ports = port_names.findall(ports)
find_ports = " ".join(find_ports)
if "name" in find_ports:
find_ports = find_ports.replace("<name>", "").replace("</name>", "")
print find_ports
port_description.append(find_ports)
else:
port_description.append("")
#set the list for the port numbers
port_number = []
port_names = re.compile(r'<number>.*</number>')
counter = 0
for ports in search_port:
ports = str(ports)
find_ports = port_names.findall(ports)
find_ports = " ".join(find_ports)
if "number" in find_ports:
#remove the tags and leave only the port numbers going into the list
find_ports = find_ports.replace("<number>", "").replace("</number>", "")
print find_ports
port_number.append(find_ports)
else:
port_number.append("")
protocol_name = []
protocol_names = re.compile(r'<protocol>.*</protocol>')
counter = 0
for protocol in search_port:
ports = str(ports)
find_ports = port_names.findall(ports)
find_ports = " ".join(find_ports)
if "protocol" in find_ports:
#remove the tags and leave only the protocol names going into the list
find_ports = find_ports.replace("<protocol>", "").replace("</protocol>", "")
protocol_name.append(find_ports)
else:
protocol_name.append("")
#############Begin parsing nmap###################
port_list = []
nmap_file = open(scratch_file)
for line in nmap_file:
if line.startswith('Nmap'):
flag = 0
if last_line in line:
flag = 1
if not flag and not last_line in line:
#append the line to the list and strip the dashes away
port_list.append(line.strip('---').rstrip())
#set the computer_id to 0. The computer_id represents the ID of the computer
#each port can have the same ID. In this way ports 80, 22, 443 etc all reference computer by ID
computer_id = 0
existing_ports = []
for ports_open in port_list:
starts_with_digit = re.match(r"[0-9]", ports_open) is not None
#For the ports section we dont want anything that starts with a letter
#If the line starts with a digit, parse out only the port number
if starts_with_digit == True:
ports_open = ports_open.split('/')[0]
print "Inserting: ", ports_open
existing_ports.append(ports_open)
cursor.execute("INSERT ignore INTO Ports_Table(Port_ID, Open_Port) values('%s','%s')" % (computer_id, ports_open))
continue
#If the line starts with Port, increase the computer_id. Nmap lists the PORT heading only once per computer
#Therefore it is a reliable way to indicate the ID of a new computer
elif starts_with_digit == False and "Nmap" in ports_open:
computer_id +=1
elif "All 1000" in ports_open:
print "no ports open at ID ", computer_id
ports_open = 0
cursor.execute("INSERT ignore INTO Ports_Table(Port_ID, Open_Port) values('%s','%s')" % (computer_id, ports_open))
#Loop through the open ports on your network and only add port descriptions of ports which exist on your network
#This was done to reduce querry time against the list of known ports
x = 0
while x < len(port_number):
if port_number[x] in existing_ports:
print "adding ", port_number[x], port_description[x], protocol_name[x], " to the database"
cursor.execute("INSERT ignore INTO Port_Description(Port_Number, Port_Description, Port_Protocol) values('%s', '%s', '%s')" % (port_number[x], port_description[x], protocol_name[x]))
else:
print "This port is not found among the open ports on your network.... OMITTING"
x +=1
#######################################################################
def parse_os():
OS_list = []
nmap_file = open(scratch_file)
for line in nmap_file:
if line.startswith('Nmap'):
flag = 0
if last_line in line:
flag = 1
if not flag and not last_line in line:
#append the line to the list and strip the dashes away
OS_list.append(line.strip('---').rstrip())
#set the computer_id to 0. The computer_id represents the ID of the computer
#Each computer will only have a single OS at the time of scanning. Link the ID to the OS
computer_id = 0
for host_os in OS_list:
starts_with_digit = re.match(r"[0-9]", host_os) is not None
#If the line starts with a digit, skip it and look for the OS information
if starts_with_digit == True:
continue
#If the line starts with Port, increase the computer_id. Nmap lists the PORT heading only once per computer
#Therefore it is a reliable way to indicate the ID of a new computer
elif "Nmap" in host_os:
computer_id +=1
elif "OS" in host_os and "OS:" not in host_os and "Warn" not in host_os and "Running"not in host_os and "Agg" not in host_os and "Microsoft" not in host_os :
host_os = host_os.strip("OS details: ")
if "No" in host_os or "Too many" in host_os:
host_os = "Not available"
print "Not available"
cursor.execute("INSERT ignore INTO OS_Table(OS_Name) values('%s')" % (host_os))
else:
host_os = host_os.split(",")
print "Inserting: ", host_os[0]
cursor.execute("INSERT ignore INTO OS_Table(OS_Name) values('%s')" % (host_os[0]))
elif "Microsoft" in host_os and "OS" not in host_os and "JUST" not in host_os:
host_os = host_os.split("Running: ")
print "Inserting: ", host_os[1]
cursor.execute("INSERT ignore INTO OS_Table(OS_Name) values('%s')" % (host_os[1]))
##############################################################################
createNmap()
parse_ports()
parse_dns()
parse_os()
#close the database connection
database_connection.commit()
cursor.close()
database_connection.close()
#clean up after yourself
#os.remove(scratch_file)
#os.remove(nmap_output)
Here is a down and dirty UI:
Code:
#!/usr/bin/python
#This program is being designed to be a front end for mysql
from Tkinter import *
import MySQLdb
import struct
import os
import re
#This is where the bulk of the decision making is made
#This class is used to turn the checkbox input into meaning database parameters
#In ddition, it does some error checking by making sure all of the input boxes
#have text in them, as well as making sure that only 1 very ending is checked
class getResults:
def __init__(self, parent):
def formatListbox(msg, listbox_height):
fetch_results = cursor.fetchall()
global top
#top = Frame(root)
top = Toplevel()
#top.pack()
#top.title("Information retrieved")
msg_title = Message (top, text="The following computers are running '%s'" % msg, width=80)
msg_title.pack(pady=5)
scrollbar = Scrollbar(top)
scrollbar.pack(side=RIGHT, fill=Y)
listbox = Listbox(top, yscrollcommand=scrollbar.set, width=100, height=listbox_height)
listbox.pack(pady=15, padx=50)
#This sets the spacing for the listbox it explicitely tells the program to print each element, one at a time, to the list box
for single_result in fetch_results:
character_count = 0
#set the first spacing
#we know that in the quad octet of ips, 15 characters are the maximum there will ever be
#Therefore set the spacing
first_spacing = " "
spacing = " "
#print len(single_result[0]), len(single_result[1]), len(single_result[2])
if (15 - len(single_result[0])) > 2:
first_spacing = (first_spacing * 9)
elif (15 - len(single_result[0])) > 1:
first_spacing = (first_spacing * 7)
elif (15 - len(single_result[0])) == 1:
first_spacing = (first_spacing * 5)
if "Linux 2.6.13 - 2.6.28" in single_result[1] or "Linux 2.6.18 - 2.6.28" in single_result[1] or "Linux 2.6.24 - 2.6.31" in single_result[1] or "Linux 2.6.19 - 2.6.31" in single_result[1]:
spacing = (spacing * 45)
elif "Microsoft Windows XP" in single_result[1]:
spacing = (spacing * 44)
elif "Microsoft Windows Vista|2008|7" in single_result[1]:
spacing = (spacing * 29)
print "Found Vista|2008|7"
elif "Microsoft Windows 2003" in single_result[1]:
spacing = (spacing * 40)
elif "Not available" in single_result[1]:
spacing = (spacing * 58)
elif "Linux 2.4.20" in single_result[1]:
spacing = (spacing * 58)
elif "IBM InfoPrint 1140 printer" in single_result[1]:
spacing = (spacing * 37)
elif "Linux 2.4.18 - 2.4.35 (likely embedded)" in single_result[1]:
spacing = (spacing * 17)
elif "Dell 5210n or Lexmark C534dn" in single_result[1]:
spacing = (spacing * 29)
elif "HP LaserJet 4250 printer (J7949E)" in single_result[1]:
spacing = (spacing * 25)
elif "Microsoft Windows Vista" in single_result[1]:
spacing = (spacing * 41)
elif "APC AP7851 power distribution unit (AOS 2.7.0)" in single_result[1]:
spacing = (spacing * 4)
elif "WatchGuard FireBox 700 or X700 firew" in single_result[1]:
spacing = (spacing * 18)
elif "HP InkJet 2300" in single_result[1]:
spacing = (spacing * 54)
elif "FreeBSD 4.3-RELEASE or IBM AIX 5.3 - 6.1" in single_result[1]:
spacing = (spacing * 13)
elif "Netgear GSM7224 switch" in single_result[1]:
spacing = (spacing * 39)
single_result = single_result[0] + first_spacing + single_result[1] + spacing + single_result[2]
listbox.insert(END, single_result)
scrollbar.config(command=listbox.yview)
oper_sys = OS.get()
ip_get = IP.get()
database_connection = MySQLdb.connect('localhost', 'root', '', 'nmap');
cursor = database_connection.cursor()
starts_with_digit = re.match(r"[0-9]", ip_get) is not None
#display_all_ports = display_ports.get()
#if display_all_ports
if oper_sys == "" and ip_get != "":
starts_with_digit = re.match(r"[0-9]", ip_get) is not None
if starts_with_digit == True:
#cursor.execute("SELECT Computer_Info.Computer_IP_Address,OS_Table.OS_Name FROM Computer_Info, OS_Table WHERE Computer_Info.Computer_ID=OS_Table.OS_ID AND Computer_IP_Address LIKE '%%%s%%' ORDER BY inet_aton(Computer_IP_Address)" % ip_get)
cursor.execute("SELECT DISTINCT Computer_IP_Address, OS_Name, DNS_Name FROM Computer_Ports AS CP \
JOIN Computer_Info AS CI ON ( CP.Computer_ID = CI.Computer_ID ) \
JOIN Ports_Table AS PT ON ( CP.Port_ID = PT.Port_ID ) \
JOIN OS_Table AS OS ON ( CI.Computer_ID = OS.OS_ID ) \
JOIN Port_Description AS PS ON ( PT.Port_Number = PS.Port_Number ) \
WHERE Computer_IP_Address LIKE '%%%s%%' ORDER BY inet_aton( Computer_IP_Address )" % ip_get)
#we get the number of rows in order to set the height of the listbox (it gets passed to the function)
number_of_rows = int(cursor.rowcount) /4
if number_of_rows < 6:
number_of_rows = 8
formatListbox(ip_get, number_of_rows)
else:
print "you did not enter a valid IP!!!"
elif oper_sys != "" and ip_get == "":
starts_with_digit = re.match(r"[0-9]", oper_sys) is not None
if starts_with_digit == False:
cursor.execute("SELECT DISTINCT Computer_IP_Address, OS_Name, DNS_Name FROM Computer_Ports AS CP \
JOIN Computer_Info AS CI ON ( CP.Computer_ID = CI.Computer_ID ) \
JOIN Ports_Table AS PT ON ( CP.Port_ID = PT.Port_ID ) \
JOIN OS_Table AS OS ON ( CI.Computer_ID = OS.OS_ID ) \
JOIN Port_Description AS PS ON ( PT.Port_Number = PS.Port_Number ) \
WHERE OS_Name LIKE '%%%s%%' ORDER BY inet_aton( Computer_IP_Address )" % oper_sys)
#we get the number of rows in order to set the height of the listbox (it gets passed to the function)
number_of_rows = int(cursor.rowcount) /4
if number_of_rows < 6:
number_of_rows = 8
formatListbox(oper_sys, number_of_rows)
else:
print "you did not enter a valid Operating system!!!"
else:
#print "please enter ONLY the OS or the IP address!!!"
cursor.execute("SELECT DISTINCT Computer_IP_Address, OS_Name, DNS_Name \
FROM Computer_Ports AS CP \
JOIN Computer_Info AS CI ON ( CP.Computer_ID = CI.Computer_ID ) \
JOIN Ports_Table AS PT ON ( CP.Port_ID = PT.Port_ID ) \
JOIN OS_Table AS OS ON ( CI.Computer_ID = OS.OS_ID ) \
JOIN Port_Description AS PS ON ( PT.Port_Number = PS.Port_Number ) \
WHERE Computer_IP_Address LIKE '%%%s%%' and OS_Name LIKE '%%%s%%' ORDER BY inet_aton( Computer_IP_Address )" % (ip_get, oper_sys))
#we get the number of rows in order to set the height of the listbox (it gets passed to the function)
number_of_rows = int(cursor.rowcount) /4
if number_of_rows < 6:
number_of_rows = 8
formatListbox(oper_sys, number_of_rows)
#This class designs the UI and the button placement
#This class has a mix of local and global variables. Local variables are designated by the self.xxx
#Any UI element that must return a result has a seperate .pack() lines. This is because having checkButton(xxx text=xxx).pack() returns an error
#when attempting to extract a value
class createUI:
def __init__(self, parent):
#export variables from this class so they are available in other classes
global OS, IP, counter
self.panel1 = Frame(parent.title("main window"))
self.panel1.pack()
self.frame1 = Frame(self.panel1)
#in the first frame, create the directions and the input boxes
self.OS_label = Message(self.frame1, text="Search by operating system", justify=LEFT, width=180).pack(pady=2)
OS = Entry(self.frame1)
OS.pack()
OS.focus_set()
self.IP_label = Message(self.frame1, text="Search by IP", justify=LEFT, width=180).pack(pady=3)
IP = Entry(self.frame1)
IP.pack(pady=14, padx=60)
self.frame1.pack()
self.frame5 = Frame(self.panel1)
#set the variables used by the checkboxes to an IntVar so that they can be evaluated as off or on
display_ports = IntVar()
ports_checkbutton = Checkbutton(self.frame5, text='Display Ports', onvalue = 1, offvalue = 0, variable=display_ports, width=10)
ports_checkbutton.pack(side=LEFT)
self.frame5.pack()
self.frame6 = Frame(self.panel1)
#lambda was used so that the button does not execute the addToDB class before click. addToDB requires an argument and self.database_button didn't work
self.database_button = Button(self.frame6, text="Get results!")
self.database_button.pack()
self.database_button.configure(command=lambda btn = self.database_button: getResults(btn))
self.quit_button = Button(self.frame6, text="Get me outta here", command=self.panel1.quit).pack()
self.frame6.pack()
######main loop #########
root = Tk()
ui = createUI(root)
ui.panel1.mainloop()
I merged the IANA parsing and have 7zipped the xml file and attached it here
Below find an updated UI with gtk
Code:
#!/usr/bin/python
import pygtk
pygtk.require('2.0')
import gtk
import os
import sys
import MySQLdb
from Tkinter import *
database_connection = MySQLdb.connect('localhost', 'root', '', 'nmap');
cursor = database_connection.cursor()
class Table_GUI:
cells = {}
columns = {}
sort_order = gtk.SORT_ASCENDING
def delete_event(self, widget, event, data=None):
return False
def destroy(self, widget, data=None):
gtk.main_quit()
def __init__(self):
# create a new window
self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.window.set_geometry_hints(min_width=400, min_height=200)
self.window.connect("delete_event", self.delete_event)
self.window.connect("destroy", self.destroy)
self.vbox = gtk.VBox(False, 0)
self.window.add(self.vbox)
self.vbox.show()
#For some reason I can't get the scrolled window to work...
self.scrolledwindow = gtk.ScrolledWindow()
self.scrolledwindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
self.vbox.pack_start(self.scrolledwindow)
self.frm_table = gtk.Frame()
self.frm_table.set_shadow_type(gtk.SHADOW_NONE)
self.frm_table.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse('#fff'))
self.show_Table(oper_sys, ip_get, hostname_get)
self.frm_table.show()
self.vbox.pack_start(self.frm_table, True, True, 0)
self.window.show()
def show_Table(self, search_os, search_ip, search_hostname):
### Create the table
# List of items to display which represent IP, OS, DNS, Port number and Port description
self.liststore = gtk.ListStore(str, str, str, str, str)
#If the user is running a search on the hostname run these querries
if search_hostname != "":
if ports_check == 1:
cursor.execute("SELECT DISTINCT Computer_IP_Address, OS_Name, DNS_Name, Port_Description, Open_Port FROM Computer_Ports AS CP \
JOIN Computer_Info AS CI ON ( CP.Computer_ID = CI.Computer_ID ) \
JOIN Ports_Table AS PT ON ( CP.Port_ID = PT.Port_ID ) \
JOIN OS_Table AS OS ON ( CI.Computer_ID = OS.OS_ID ) \
JOIN Port_Description AS PS ON ( PT.Open_Port = PS.Port_Number ) \
WHERE DNS_Name LIKE '%%%s%%' ORDER BY inet_aton( Computer_IP_Address ), Open_Port" % (search_hostname))
#Otherwise just return the relevent data
else:
cursor.execute("SELECT DISTINCT Computer_IP_Address, OS_Name, DNS_Name FROM Computer_Ports AS CP \
JOIN Computer_Info AS CI ON ( CP.Computer_ID = CI.Computer_ID ) \
JOIN Ports_Table AS PT ON ( CP.Port_ID = PT.Port_ID ) \
JOIN OS_Table AS OS ON ( CI.Computer_ID = OS.OS_ID ) \
JOIN Port_Description AS PS ON ( PT.Open_Port = PS.Port_Number ) \
WHERE DNS_Name LIKE '%%%s%%' ORDER BY inet_aton( Computer_IP_Address )" % (search_hostname))
#If the user has specified the IP and the OS to search, run this querry
if search_os != "" and search_ip !="":
#Set up the querries. If the user has activted the checkbox, we need to include the ports in the querry
if ports_check == 1:
cursor.execute("SELECT DISTINCT Computer_IP_Address, OS_Name, DNS_Name, Port_Description, Open_Port FROM Computer_Ports AS CP \
JOIN Computer_Info AS CI ON ( CP.Computer_ID = CI.Computer_ID ) \
JOIN Ports_Table AS PT ON ( CP.Port_ID = PT.Port_ID ) \
JOIN OS_Table AS OS ON ( CI.Computer_ID = OS.OS_ID ) \
JOIN Port_Description AS PS ON ( PT.Open_Port = PS.Port_Number ) \
WHERE OS_Name LIKE '%%%s%%' and Computer_IP_Address LIKE '%%%s%%' ORDER BY inet_aton( Computer_IP_Address ), Open_Port" % (search_os, search_ip))
#Otherwise just return the relevent data
else:
cursor.execute("SELECT DISTINCT Computer_IP_Address, OS_Name, DNS_Name FROM Computer_Ports AS CP \
JOIN Computer_Info AS CI ON ( CP.Computer_ID = CI.Computer_ID ) \
JOIN Ports_Table AS PT ON ( CP.Port_ID = PT.Port_ID ) \
JOIN OS_Table AS OS ON ( CI.Computer_ID = OS.OS_ID ) \
JOIN Port_Description AS PS ON ( PT.Open_Port = PS.Port_Number ) \
WHERE OS_Name LIKE '%%%s%%' and Computer_IP_Address LIKE '%%%s%%' ORDER BY inet_aton( Computer_IP_Address )" % (search_os, search_ip))
#If the user has specified an OS but not an IP run this
elif search_os != "" and search_ip == "":
if ports_check == 1:
cursor.execute("SELECT DISTINCT Computer_IP_Address, OS_Name, DNS_Name, Port_Description, Open_Port FROM Computer_Ports AS CP \
JOIN Computer_Info AS CI ON ( CP.Computer_ID = CI.Computer_ID ) \
JOIN Ports_Table AS PT ON ( CP.Port_ID = PT.Port_ID ) \
JOIN OS_Table AS OS ON ( CI.Computer_ID = OS.OS_ID ) \
JOIN Port_Description AS PS ON ( PT.Open_Port = PS.Port_Number ) \
WHERE OS_Name LIKE '%%%s%%' ORDER BY inet_aton( Computer_IP_Address ), Open_Port" % search_os)
else:
cursor.execute("SELECT DISTINCT Computer_IP_Address, OS_Name, DNS_Name FROM Computer_Ports AS CP \
JOIN Computer_Info AS CI ON ( CP.Computer_ID = CI.Computer_ID ) \
JOIN Ports_Table AS PT ON ( CP.Port_ID = PT.Port_ID ) \
JOIN OS_Table AS OS ON ( CI.Computer_ID = OS.OS_ID ) \
JOIN Port_Description AS PS ON ( PT.Open_Port = PS.Port_Number ) \
WHERE OS_Name LIKE '%%%s%%' ORDER BY inet_aton( Computer_IP_Address )" % search_os)
#If the user has specified an IP but not an OS run this
elif search_os =="" and search_ip != "":
if ports_check == 1:
cursor.execute("SELECT DISTINCT Computer_IP_Address, OS_Name, DNS_Name, Port_Description, Open_Port FROM Computer_Ports AS CP \
JOIN Computer_Info AS CI ON ( CP.Computer_ID = CI.Computer_ID ) \
JOIN Ports_Table AS PT ON ( CP.Port_ID = PT.Port_ID ) \
JOIN OS_Table AS OS ON ( CI.Computer_ID = OS.OS_ID ) \
JOIN Port_Description AS PS ON ( PT.Open_Port = PS.Port_Number ) \
WHERE Computer_IP_Address LIKE '%%%s%%' ORDER BY inet_aton( Computer_IP_Address ), Open_Port" % search_ip)
else:
cursor.execute("SELECT DISTINCT Computer_IP_Address, OS_Name, DNS_Name FROM Computer_Ports AS CP \
JOIN Computer_Info AS CI ON ( CP.Computer_ID = CI.Computer_ID ) \
JOIN Ports_Table AS PT ON ( CP.Port_ID = PT.Port_ID ) \
JOIN OS_Table AS OS ON ( CI.Computer_ID = OS.OS_ID ) \
JOIN Port_Description AS PS ON ( PT.Open_Port = PS.Port_Number ) \
WHERE Computer_IP_Address LIKE '%%%s%%' ORDER BY inet_aton( Computer_IP_Address )" % search_ip)
#get the results and prepare to put them inside of lists
fetch_results = cursor.fetchall()
host_name_list = []
operating_list = []
ip_list = []
ports = []
#The element chosen to append to each list based on the order of retrieval in the mysql querry
for individual_result in fetch_results:
ip_list.append(individual_result[0])
operating_list.append(individual_result[1])
host_name_list.append(individual_result[2])
if ports_check == 1:
ports.append(individual_result[3])
#we are going to add blanks to the files in order to help readability
#when putting this into the chart
cleaned_host =[]
cleaned_ip = []
cleaned_os_list = []
index_counter = 0
#this loop will check to see if the entry already exists in the cleaned variables. If it does, it 'omitts' them by inserting a blank line
while index_counter < len(host_name_list):
if host_name_list[index_counter] in cleaned_host:
#print "found a duplicate in HOST....OMITTING"
cleaned_host.append("")
else:
#print "adding ", host_name_list[index_counter]
cleaned_host.append(host_name_list[index_counter])
if operating_list[index_counter] in cleaned_os_list and ip_list[index_counter] in cleaned_ip:
#print "found a duplicate in OPERATING....OMITTING"
cleaned_os_list.append("")
else:
#print "adding ", operating_list[index_counter]
cleaned_os_list.append(operating_list[index_counter])
if ip_list[index_counter] in cleaned_ip:
#print "Found a duplicate in IP.... OMITTING "
cleaned_ip.append("")
else:
#print "adding ", ip_list[index_counter]
cleaned_ip.append(ip_list[index_counter])
index_counter +=1
#this section appends to the list store depending on whether the user wants to see the ports or not
counter = 0
for single_result in fetch_results:
if ports_check == 1:
self.liststore.append(
[ cleaned_ip[counter], cleaned_os_list[counter], cleaned_host[counter], single_result[4], single_result[3] ]
)
else:
self.liststore.append(
[ single_result[0], single_result[1], single_result[2], "" , "" ]
)
counter +=1
# Treeview
self.treeview = gtk.TreeView()
self.treeview.set_property("fixed-height-mode", False)
# Columns
self.newColumn("IP Address", 0)
self.newColumn("Operating System", 1)
self.newColumn("Hostname",2)
if ports_check == 1:
self.newColumn("Ports", 3)
self.newColumn("Protocol name", 4)
self.treeview.set_model(self.liststore)
self.treeview.set_headers_clickable(True)
self.frm_table.add(self.treeview)
self.treeview.show()
def on_column_clicked(self, tc, user_data):
self.liststore.set_sort_column_id(user_data, self.sort_order)
if self.sort_order == gtk.SORT_ASCENDING:
self.sort_order = gtk.SORT_DESCENDING
else:
self.sort_order = gtk.SORT_ASCENDING
tc.set_sort_order(self.sort_order)
def newColumn(self, title, index):
self.cells[index] = gtk.CellRendererText()
self.cells[index].set_property('cell-background-gdk', gtk.gdk.color_parse("#FFF"))
self.columns[index] = gtk.TreeViewColumn(title, self.cells[index], text=index)
self.columns[index].set_resizable(True)
self.columns[index].set_reorderable(True)
self.columns[index].set_sort_indicator(True)
if(index == 0) :
self.columns[index].set_min_width(130)
if (index == 1) :
self.columns[index].set_min_width(300)
if (index == 2) :
self.columns[index].set_min_width(200)
self.columns[index].connect("clicked", self.on_column_clicked, index)
self.treeview.insert_column(self.columns[index], -1)
# The main function
def main(self):
gtk.main()
class createUI:
#this function allows the button to call the next GUI
def pushButton(self, parent):
global ports_check, oper_sys, ip_get, hostname_get
ports_check = display_ports.get()
oper_sys = OS.get()
ip_get = IP.get()
hostname_get = HOSTNAME.get()
if hostname_get != "" and (oper_sys != "" or ip_get != ""):
pass
else:
gui = Table_GUI()
gui.main()
def __init__(self, parent):
#export variables from this class so they are available in other classes
global OS, IP, HOSTNAME, counter, display_ports
self.panel1 = Frame(parent.title("main window"))
self.panel1.pack()
self.frame1 = Frame(self.panel1)
#in the first frame, create the directions and the input boxes
self.OS_label = Message(self.frame1, text="Search by Operating System", justify=LEFT, width=180).pack(pady=2)
OS = Entry(self.frame1)
OS.pack()
OS.focus_set()
self.Hostname_lable = Message(self.frame1, text="Search by Hostname", justify=LEFT, width=180).pack(pady=2)
HOSTNAME = Entry(self.frame1)
HOSTNAME.pack()
self.IP_label = Message(self.frame1, text="Search by IP", justify=LEFT, width=180).pack(pady=3)
IP = Entry(self.frame1)
IP.pack(pady=14, padx=60)
self.frame1.pack()
self.frame5 = Frame(self.panel1)
#set the variables used by the checkboxes to an IntVar so that they can be evaluated as off or on
display_ports = IntVar()
ports_checkbutton = Checkbutton(self.frame5, text='Display Ports', onvalue = 1, offvalue = 0, variable=display_ports, width=10)
ports_checkbutton.pack(side=LEFT)
self.frame5.pack()
self.frame6 = Frame(self.panel1)
#lambda was used so that the button does not execute the addToDB class before click. addToDB requires an argument and self.database_button didn't work
self.database_button = Button(self.frame6, text="Get results!")
self.database_button.pack()
self.database_button.configure(command=lambda btn = self.database_button: self.pushButton(btn))
self.quit_button = Button(self.frame6, text="Get me outta here", command=self.panel1.quit).pack()
self.frame6.pack()
if __name__ == "__main__":
root = Tk()
ui = createUI(root)
ui.panel1.mainloop()
Added a completely GTK interface. Functional but could use some design help. Scroll bars added and slight redesign substituting liststore for treestore Oct 1, 2011
Code:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import pygtk
import gtk
import os
import sys
import MySQLdb
database_connection = MySQLdb.connect('localhost', 'root', '', 'nmap');
cursor = database_connection.cursor()
class Application(gtk.Window):
cells = {}
columns = {}
sort_order = gtk.SORT_ASCENDING
####################
def __init__(self):
gtk.Window.__init__( self )
self.set_title("Netowrk Scanner")
self.set_position(gtk.WIN_POS_CENTER)
self.create_widgets()
self.connect_signals()
#self.window.show_all()
self.show_all()
gtk.main()
##################
def create_widgets(self):
#Ask the user to search by operating system
self.vbox = gtk.VBox(spacing=10)
self.operating_system_label_hbox_1 = gtk.HBox(spacing=10)
self.label = gtk.Label("Search by Operating System :")
self.operating_system_label_hbox_1.pack_start(self.label)
#Set a check box so the user can choose to display ports
self.ports_hbox_8 = gtk.HBox(spacing=10)
self.ports_check = gtk.CheckButton("Display Ports")
self.ports_hbox_8.pack_start(self.ports_check)
self.halign_ports = gtk.Alignment(0,1,1,0)
self.halign_ports.add(self.ports_hbox_8)
self.os_entry_hbox_2 = gtk.HBox(spacing=10)
self.OS = gtk.Entry()
self.os_entry_hbox_2.pack_start(self.OS)
self.hostname_label_hbox_3 = gtk.HBox(spacing=10)
self.label = gtk.Label("Search by Hostname:")
self.hostname_label_hbox_3.pack_start(self.label)
self.hostname_entry_hbox_4 = gtk.HBox(spacing=10)
self.HOSTNAME = gtk.Entry()
self.hostname_entry_hbox_4.pack_start(self.HOSTNAME)
self.ip_label_hbox_5 = gtk.HBox(spacing=10)
self.label = gtk.Label("Search by IP:")
self.ip_label_hbox_5.pack_start(self.label)
self.ip_entry_hbox_6 = gtk.HBox(spacing=10)
self.IP = gtk.Entry()
self.ip_entry_hbox_6.pack_start(self.IP)
self.buttons_hbox_7 = gtk.HBox(spacing=10)
self.button_ok = gtk.Button("Get Results!")
self.buttons_hbox_7.pack_start(self.button_ok)
self.button_exit = gtk.Button("Get me Outta Here!")
self.buttons_hbox_7.pack_start(self.button_exit)
#The order in which you pack_start a widget is the order in which it is displayed on the screen
self.vbox.pack_start(self.operating_system_label_hbox_1)
self.vbox.pack_start(self.os_entry_hbox_2)
self.vbox.pack_start(self.hostname_label_hbox_3)
self.vbox.pack_start(self.hostname_entry_hbox_4)
self.vbox.pack_start(self.ip_label_hbox_5)
self.vbox.pack_start(self.ip_entry_hbox_6)
self.vbox.pack_start(self.halign_ports, False, False, 3)
self.vbox.pack_start(self.buttons_hbox_7)
self.add(self.vbox)
##########################
def connect_signals(self):
#Have the buttons start 'listening' for user interaction
self.button_ok.connect("clicked", self.button_click)
self.button_exit.connect("clicked", self.exit_program)
########################
def button_click(self, clicked):
#This function gets the values of the input boxes as well as the check box
#And then passes them to the show_table function so it can get the correct results from the database
global ports_check, os, ip, hostname
os = self.OS.get_text()
ip = self.IP.get_text()
hostname = self.HOSTNAME.get_text()
ports_check = self.ports_check.get_active()
if hostname != "" and (os != "" or ip != ""):
error_message = gtk.MessageDialog(self, gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR, gtk.BUTTONS_CLOSE, "If you know the hostname why are you searching with other options? Please search by hostname only")
error_message.run()
error_message.destroy()
self.OS.set_text("")
self.IP.set_text("")
self.HOSTNAME.set_text("")
else:
self.show_Table(os, ip, hostname)
##############
def show_Table(self, search_os, search_ip, search_hostname):
### Create the table
# List of items to display which represent IP, OS, DNS, Port number and Port description
# Columns
if ports_check == True:
cols = ['IP Address', 'Operating System', 'Hostname', 'Ports', 'Protocol Name']
else:
cols = ['IP Address', 'Operating System', 'Hostname']
"""
self.newColumn("IP Address", 0)
self.newColumn("Operating System", 1)
self.newColumn("Hostname",2)
#I only want the ports columns to show if the user requests it because this calls different mysql querries
if ports_check == True:
self.newColumn("Ports", 3)
self.newColumn("Protocol name", 4)
"""
sequence = [str] * len(cols)
self.treestore = gtk.TreeStore( * sequence)
self.treestore.connect("rows-reordered", self.on_column_clicked)
self.treeview = gtk.TreeView(self.treestore)
self.treeview.cell = [None] * len(cols)
self.treeview_column = [None] * len(cols)
for column_number, col in enumerate(cols):
self.treeview.cell[column_number] = gtk.CellRendererText()
self.treeview_column[column_number] = gtk.TreeViewColumn(col, self.treeview.cell[column_number])
self.treeview_column[column_number].add_attribute(self.treeview.cell[column_number], 'text', column_number)
self.treeview_column[column_number].set_resizable(True)
self.treeview_column[column_number].set_reorderable(True)
self.treeview_column[column_number].set_sort_indicator(True)
self.treeview_column[column_number].set_sort_column_id(column_number)
self.treeview.append_column(self.treeview_column[column_number])
self.scrollTree = gtk.ScrolledWindow()
self.scrollTree.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
self.scrollTree.add(self.treeview)
#If the user is running a search on the hostname run these querries
if search_hostname != "":
if ports_check == True:
cursor.execute("SELECT DISTINCT Computer_IP_Address, OS_Name, DNS_Name, Port_Description, Open_Port FROM Computer_Ports AS CP \
JOIN Computer_Info AS CI ON ( CP.Computer_ID = CI.Computer_ID ) \
JOIN Ports_Table AS PT ON ( CP.Port_ID = PT.Port_ID ) \
JOIN OS_Table AS OS ON ( CI.Computer_ID = OS.OS_ID ) \
JOIN Port_Description AS PS ON ( PT.Open_Port = PS.Port_Number ) \
WHERE DNS_Name LIKE '%%%s%%' ORDER BY inet_aton( Computer_IP_Address ), Open_Port" % (search_hostname))
#Otherwise just return the relevent data
else:
cursor.execute("SELECT DISTINCT Computer_IP_Address, OS_Name, DNS_Name FROM Computer_Ports AS CP \
JOIN Computer_Info AS CI ON ( CP.Computer_ID = CI.Computer_ID ) \
JOIN Ports_Table AS PT ON ( CP.Port_ID = PT.Port_ID ) \
JOIN OS_Table AS OS ON ( CI.Computer_ID = OS.OS_ID ) \
JOIN Port_Description AS PS ON ( PT.Open_Port = PS.Port_Number ) \
WHERE DNS_Name LIKE '%%%s%%' ORDER BY inet_aton( Computer_IP_Address )" % (search_hostname))
#If the user has specified the IP and the OS to search, run this querry
if search_os != "" and search_ip !="":
#Set up the querries. If the user has activted the checkbox, we need to include the ports in the querry
if ports_check == True:
cursor.execute("SELECT DISTINCT Computer_IP_Address, OS_Name, DNS_Name, Port_Description, Open_Port FROM Computer_Ports AS CP \
JOIN Computer_Info AS CI ON ( CP.Computer_ID = CI.Computer_ID ) \
JOIN Ports_Table AS PT ON ( CP.Port_ID = PT.Port_ID ) \
JOIN OS_Table AS OS ON ( CI.Computer_ID = OS.OS_ID ) \
JOIN Port_Description AS PS ON ( PT.Open_Port = PS.Port_Number ) \
WHERE OS_Name LIKE '%%%s%%' and Computer_IP_Address LIKE '%%%s%%' ORDER BY inet_aton( Computer_IP_Address ), Open_Port" % (search_os, search_ip))
#Otherwise just return the relevent data
else:
cursor.execute("SELECT DISTINCT Computer_IP_Address, OS_Name, DNS_Name FROM Computer_Ports AS CP \
JOIN Computer_Info AS CI ON ( CP.Computer_ID = CI.Computer_ID ) \
JOIN Ports_Table AS PT ON ( CP.Port_ID = PT.Port_ID ) \
JOIN OS_Table AS OS ON ( CI.Computer_ID = OS.OS_ID ) \
JOIN Port_Description AS PS ON ( PT.Open_Port = PS.Port_Number ) \
WHERE OS_Name LIKE '%%%s%%' and Computer_IP_Address LIKE '%%%s%%' ORDER BY inet_aton( Computer_IP_Address )" % (search_os, search_ip))
#If the user has specified an OS but not an IP run this
elif search_os != "" and search_ip == "":
if ports_check == True:
cursor.execute("SELECT DISTINCT Computer_IP_Address, OS_Name, DNS_Name, Port_Description, Open_Port FROM Computer_Ports AS CP \
JOIN Computer_Info AS CI ON ( CP.Computer_ID = CI.Computer_ID ) \
JOIN Ports_Table AS PT ON ( CP.Port_ID = PT.Port_ID ) \
JOIN OS_Table AS OS ON ( CI.Computer_ID = OS.OS_ID ) \
JOIN Port_Description AS PS ON ( PT.Open_Port = PS.Port_Number ) \
WHERE OS_Name LIKE '%%%s%%' ORDER BY inet_aton( Computer_IP_Address ), Open_Port" % search_os)
else:
cursor.execute("SELECT DISTINCT Computer_IP_Address, OS_Name, DNS_Name FROM Computer_Ports AS CP \
JOIN Computer_Info AS CI ON ( CP.Computer_ID = CI.Computer_ID ) \
JOIN Ports_Table AS PT ON ( CP.Port_ID = PT.Port_ID ) \
JOIN OS_Table AS OS ON ( CI.Computer_ID = OS.OS_ID ) \
JOIN Port_Description AS PS ON ( PT.Open_Port = PS.Port_Number ) \
WHERE OS_Name LIKE '%%%s%%' ORDER BY inet_aton( Computer_IP_Address )" % search_os)
#If the user has specified an IP but not an OS run this
elif search_os =="" and search_ip != "":
if ports_check == True:
cursor.execute("SELECT DISTINCT Computer_IP_Address, OS_Name, DNS_Name, Port_Description, Open_Port FROM Computer_Ports AS CP \
JOIN Computer_Info AS CI ON ( CP.Computer_ID = CI.Computer_ID ) \
JOIN Ports_Table AS PT ON ( CP.Port_ID = PT.Port_ID ) \
JOIN OS_Table AS OS ON ( CI.Computer_ID = OS.OS_ID ) \
JOIN Port_Description AS PS ON ( PT.Open_Port = PS.Port_Number ) \
WHERE Computer_IP_Address LIKE '%%%s%%' ORDER BY inet_aton( Computer_IP_Address ), Open_Port" % search_ip)
else:
cursor.execute("SELECT DISTINCT Computer_IP_Address, OS_Name, DNS_Name FROM Computer_Ports AS CP \
JOIN Computer_Info AS CI ON ( CP.Computer_ID = CI.Computer_ID ) \
JOIN Ports_Table AS PT ON ( CP.Port_ID = PT.Port_ID ) \
JOIN OS_Table AS OS ON ( CI.Computer_ID = OS.OS_ID ) \
JOIN Port_Description AS PS ON ( PT.Open_Port = PS.Port_Number ) \
WHERE Computer_IP_Address LIKE '%%%s%%' ORDER BY inet_aton( Computer_IP_Address )" % search_ip)
#get the results and prepare to put them inside of lists
fetch_results = cursor.fetchall()
host_name_list = []
operating_list = []
ip_list = []
ports = []
#The element chosen to append to each list based on the order of retrieval in the mysql querry
for individual_result in fetch_results:
ip_list.append(individual_result[0])
operating_list.append(individual_result[1])
host_name_list.append(individual_result[2])
if ports_check == True:
ports.append(individual_result[3])
#we are going to add blanks to the files in order to help readability
#when putting this into the chart
cleaned_host =[]
cleaned_ip = []
cleaned_os_list = []
index_counter = 0
#this loop will check to see if the entry already exists in the cleaned variables. If it does, it 'omitts' them by inserting a blank line
while index_counter < len(host_name_list):
if host_name_list[index_counter] in cleaned_host:
#print "found a duplicate in HOST....OMITTING"
cleaned_host.append("")
else:
#print "adding ", host_name_list[index_counter]
cleaned_host.append(host_name_list[index_counter])
if operating_list[index_counter] in cleaned_os_list and ip_list[index_counter] in cleaned_ip:
#print "found a duplicate in OPERATING....OMITTING"
cleaned_os_list.append("")
else:
#print "adding ", operating_list[index_counter]
cleaned_os_list.append(operating_list[index_counter])
if ip_list[index_counter] in cleaned_ip:
#print "Found a duplicate in IP.... OMITTING "
cleaned_ip.append("")
else:
#print "adding ", ip_list[index_counter]
cleaned_ip.append(ip_list[index_counter])
index_counter +=1
#this section appends to the list store depending on whether the user wants to see the ports or not
counter = 0
for single_result in fetch_results:
if ports_check == True:
self.treestore.append( None,
[ cleaned_ip[counter], cleaned_os_list[counter], cleaned_host[counter], single_result[4], single_result[3] ]
)
else:
self.treestore.append(None,
[ single_result[0], single_result[1], single_result[2] ]
)
counter +=1
self.frm_table = gtk.Window()
self.frm_table.set_default_size(600, 800)
self.frm_table.set_title("Network scan results")
#Change the background to white instead of grey
self.frm_table.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse('#fff'))
self.frm_table.add(self.scrollTree)
self.frm_table.show_all()
######################
def on_column_clicked(self, col1, col2, col3, col4 ):
#This function allows the columns to be resorted upon click
if self.sort_order == gtk.SORT_ASCENDING:
self.sort_order = gtk.SORT_DESCENDING
else:
self.sort_order = gtk.SORT_ASCENDING
#tc.set_sort_order(self.sort_order)
###############
def exit_program(self, widget, callback_data=None):
gtk.main_quit()
#---------------------------------------------
if __name__ == "__main__":
app = Application()
database_connection.commit()
cursor.close()
database_connection.close()
TODO List:
--Not connect as ROOT to the database
--create a front end for retrieval
-rewrite front end in QT or other more friendly UI(requires tkinter and gtk)
--add user input with checkboxes for Nmap flags
--add user input for hosts and/or subnets to scan
--decide whether to destroy the database and recreate each time nmap is run.
--If updating is chosen over destroy, work the logic to make sure the proper tables/fields are updated
--remove duplications from OS table some how
-add a scroll bar some how
Attachments
Last edited: