From 0d47952611198ef6b1163f366dc03922d20b1475 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 09:42:04 +0200 Subject: Adding upstream version 7.94+git20230807.3be01efb1+dfsg. Signed-off-by: Daniel Baumann --- zenmap/zenmapGUI/ScanHostDetailsPage.py | 470 ++++++++++++++++++++++++++++++++ 1 file changed, 470 insertions(+) create mode 100644 zenmap/zenmapGUI/ScanHostDetailsPage.py (limited to 'zenmap/zenmapGUI/ScanHostDetailsPage.py') diff --git a/zenmap/zenmapGUI/ScanHostDetailsPage.py b/zenmap/zenmapGUI/ScanHostDetailsPage.py new file mode 100644 index 0000000..f275c26 --- /dev/null +++ b/zenmap/zenmapGUI/ScanHostDetailsPage.py @@ -0,0 +1,470 @@ +#!/usr/bin/env python3 + +# ***********************IMPORTANT NMAP LICENSE TERMS************************ +# * +# * The Nmap Security Scanner is (C) 1996-2023 Nmap Software LLC ("The Nmap +# * Project"). Nmap is also a registered trademark of the Nmap Project. +# * +# * This program is distributed under the terms of the Nmap Public Source +# * License (NPSL). The exact license text applying to a particular Nmap +# * release or source code control revision is contained in the LICENSE +# * file distributed with that version of Nmap or source code control +# * revision. More Nmap copyright/legal information is available from +# * https://nmap.org/book/man-legal.html, and further information on the +# * NPSL license itself can be found at https://nmap.org/npsl/ . This +# * header summarizes some key points from the Nmap license, but is no +# * substitute for the actual license text. +# * +# * Nmap is generally free for end users to download and use themselves, +# * including commercial use. It is available from https://nmap.org. +# * +# * The Nmap license generally prohibits companies from using and +# * redistributing Nmap in commercial products, but we sell a special Nmap +# * OEM Edition with a more permissive license and special features for +# * this purpose. See https://nmap.org/oem/ +# * +# * If you have received a written Nmap license agreement or contract +# * stating terms other than these (such as an Nmap OEM license), you may +# * choose to use and redistribute Nmap under those terms instead. +# * +# * The official Nmap Windows builds include the Npcap software +# * (https://npcap.com) for packet capture and transmission. It is under +# * separate license terms which forbid redistribution without special +# * permission. So the official Nmap Windows builds may not be redistributed +# * without special permission (such as an Nmap OEM license). +# * +# * Source is provided to this software because we believe users have a +# * right to know exactly what a program is going to do before they run it. +# * This also allows you to audit the software for security holes. +# * +# * Source code also allows you to port Nmap to new platforms, fix bugs, and add +# * new features. You are highly encouraged to submit your changes as a Github PR +# * or by email to the dev@nmap.org mailing list for possible incorporation into +# * the main distribution. Unless you specify otherwise, it is understood that +# * you are offering us very broad rights to use your submissions as described in +# * the Nmap Public Source License Contributor Agreement. This is important +# * because we fund the project by selling licenses with various terms, and also +# * because the inability to relicense code has caused devastating problems for +# * other Free Software projects (such as KDE and NASM). +# * +# * The free version of Nmap is distributed in the hope that it will be +# * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Warranties, +# * indemnification and commercial support are all available through the +# * Npcap OEM program--see https://nmap.org/oem/ +# * +# ***************************************************************************/ + +import gi + +gi.require_version("Gtk", "3.0") +from gi.repository import Gtk + +from zenmapGUI.higwidgets.higexpanders import HIGExpander +from zenmapGUI.higwidgets.higboxes import HIGVBox, HIGHBox,\ + hig_box_space_holder +from zenmapGUI.higwidgets.higlabels import HIGEntryLabel +from zenmapGUI.higwidgets.higtables import HIGTable +from zenmapGUI.Icons import get_os_logo, get_vulnerability_logo + +import zenmapCore.I18N # lgtm[py/unused-import] + +na = _('Not available') + + +class ScanHostDetailsPage(HIGExpander): + def __init__(self, host): + HIGExpander.__init__(self, host.get_hostname()) + + self.host_details = HostDetails(host) + self.hbox._pack_expand_fill(self.host_details) + + +class HostDetails(HIGVBox): + def __init__(self, host): + HIGVBox.__init__(self) + + self.__create_widgets() + + self.set_os_image(get_os_logo(host)) + + self.set_vulnerability_image( + get_vulnerability_logo(host.get_open_ports())) + + self.set_host_status({'state': host.get_state(), + 'open': str(host.get_open_ports()), + 'filtered': str(host.get_filtered_ports()), + 'closed': str(host.get_closed_ports()), + 'scanned': str(host.get_scanned_ports()), + 'uptime': host.get_uptime()['seconds'], + 'lastboot': host.get_uptime()['lastboot']}) + + addresses = {} + if host.ip is not None: + addresses['ipv4'] = host.ip['addr'] + if host.ipv6 is not None: + addresses['ipv6'] = host.ipv6['addr'] + if host.mac is not None: + addresses['mac'] = host.mac['addr'] + self.set_addresses(addresses) + + self.set_hostnames(host.get_hostnames()) + + os = host.get_best_osmatch() + if os: + os['portsused'] = host.get_ports_used() + + self.set_os(os) + self.set_tcpseq(host.get_tcpsequence()) + self.set_ipseq(host.get_ipidsequence()) + self.set_tcptsseq(host.get_tcptssequence()) + self.set_comment(host.comment) + + def __create_widgets(self): + self.host_status_expander = Gtk.Expander.new( + '' + _('Host Status') + '') + self.address_expander = Gtk.Expander.new('' + _('Addresses') + '') + self.hostnames_expander = Gtk.Expander.new('' + _('Hostnames') + '') + self.os_expander = Gtk.Expander.new('' + _('Operating System') + '') + self.portsused_expander = Gtk.Expander.new( + '' + _('Ports used') + '') + self.osclass_expander = Gtk.Expander.new('' + _('OS Classes') + '') + self.tcp_expander = Gtk.Expander.new('' + _('TCP Sequence') + '') + self.ip_expander = Gtk.Expander.new('' + _('IP ID Sequence') + '') + self.tcpts_expander = Gtk.Expander.new( + '' + _('TCP TS Sequence') + '') + self.comment_expander = Gtk.Expander.new('' + _('Comments') + '') + self.os_image = Gtk.Image() + self.vulnerability_image = Gtk.Image() + + # Host Status expander + self.host_state_label = HIGEntryLabel(_('State:')) + self.info_host_state_label = HIGEntryLabel(na) + + self.open_label = HIGEntryLabel(_('Open ports:')) + self.info_open_ports = HIGEntryLabel(na) + + self.filtered_label = HIGEntryLabel(_('Filtered ports:')) + self.info_filtered_label = HIGEntryLabel(na) + + self.closed_label = HIGEntryLabel(_('Closed ports:')) + self.info_closed_ports = HIGEntryLabel(na) + + self.scanned_label = HIGEntryLabel(_('Scanned ports:')) + self.info_scanned_label = HIGEntryLabel(na) + + self.uptime_label = HIGEntryLabel(_('Up time:')) + self.info_uptime_label = HIGEntryLabel(na) + + self.lastboot_label = HIGEntryLabel(_('Last boot:')) + self.info_lastboot_label = HIGEntryLabel(na) + + # Addresses expander + self.ipv4_label = HIGEntryLabel('IPv4:') + self.info_ipv4_label = HIGEntryLabel(na) + + self.ipv6_label = HIGEntryLabel('IPv6:') + self.info_ipv6_label = HIGEntryLabel(na) + + self.mac_label = HIGEntryLabel('MAC:') + self.info_mac_label = HIGEntryLabel(na) + + self.vendor_label = HIGEntryLabel(_('Vendor:')) + self.info_vendor_label = HIGEntryLabel(na) + + def create_table_hbox(self): + table = HIGTable() + hbox = HIGHBox() + + hbox._pack_noexpand_nofill(hig_box_space_holder()) + hbox._pack_noexpand_nofill(table) + + return table, hbox + + def set_host_status(self, status): + self.host_status_expander.set_use_markup(True) + self.host_status_expander.set_expanded(True) + table, hbox = self.create_table_hbox() + + if ('state' in status and + status['state'] != ''): + self.info_host_state_label.set_text(status['state']) + + if ('open' in status and + status['open'] != ''): + self.info_open_ports.set_text(status['open']) + + if ('filtered' in status and + status['filtered'] != ''): + self.info_filtered_label.set_text(status['filtered']) + + if ('closed' in status and + status['closed'] != ''): + self.info_closed_ports.set_text(status['closed']) + + if ('scanned' in status and + status['scanned'] != ''): + self.info_scanned_label.set_text(status['scanned']) + + if ('uptime' in status and + status['uptime'] != ''): + self.info_uptime_label.set_text(status['uptime']) + + if ('lastboot' in status and + status['lastboot'] != ''): + self.info_lastboot_label.set_text(status['lastboot']) + + table.attach(self.host_state_label, 0, 1, 0, 1) + table.attach(self.info_host_state_label, 1, 2, 0, 1) + + table.attach(self.open_label, 0, 1, 1, 2) + table.attach(self.info_open_ports, 1, 2, 1, 2) + + table.attach(self.filtered_label, 0, 1, 2, 3) + table.attach(self.info_filtered_label, 1, 2, 2, 3) + + table.attach(self.closed_label, 0, 1, 3, 4) + table.attach(self.info_closed_ports, 1, 2, 3, 4) + + table.attach(self.scanned_label, 0, 1, 4, 5) + table.attach(self.info_scanned_label, 1, 2, 4, 5) + + table.attach(self.uptime_label, 0, 1, 5, 6) + table.attach(self.info_uptime_label, 1, 2, 5, 6) + + table.attach(self.lastboot_label, 0, 1, 6, 7) + table.attach(self.info_lastboot_label, 1, 2, 6, 7) + + table.attach(self.os_image, 2, 4, 0, 3, xoptions=Gtk.AttachOptions.EXPAND) + table.attach( + self.vulnerability_image, 2, 4, 4, 7, xoptions=Gtk.AttachOptions.EXPAND) + + table.set_col_spacing(1, 50) + + self.host_status_expander.add(hbox) + self._pack_noexpand_nofill(self.host_status_expander) + + def set_os_image(self, image): + self.os_image.set_from_stock(image, Gtk.IconSize.DIALOG) + + def set_vulnerability_image(self, image): + self.vulnerability_image.set_from_stock(image, Gtk.IconSize.DIALOG) + + def set_addresses(self, address): + self.address_expander.set_use_markup(True) + table, hbox = self.create_table_hbox() + self.address_expander.set_expanded(True) + + #print '>>> Address:', address + if ('ipv4' in address and + address['ipv4'] != 1): + self.info_ipv4_label.set_text(address['ipv4']) + + if ('ipv6' in address and + address['ipv6'] != 1): + self.info_ipv6_label.set_text(address['ipv6']) + + if ('mac' in address and + address['mac'] != 1): + self.info_mac_label.set_text(address['mac']) + + table.attach(self.ipv4_label, 0, 1, 0, 1) + table.attach(self.info_ipv4_label, 1, 2, 0, 1) + + table.attach(self.ipv6_label, 0, 1, 1, 2) + table.attach(self.info_ipv6_label, 1, 2, 1, 2) + + table.attach(self.mac_label, 0, 1, 2, 3) + table.attach(self.info_mac_label, 1, 2, 2, 3) + + self.address_expander.add(hbox) + self._pack_noexpand_nofill(self.address_expander) + + def set_hostnames(self, hostname): + if hostname: + self.hostnames_expander.set_use_markup(True) + self.hostnames_expander.set_expanded(True) + table, hbox = self.create_table_hbox() + + y1 = 1 + y2 = 2 + + for h in hostname: + name = h.get('hostname', na) + type = h.get('hostname_type', na) + + table.attach(HIGEntryLabel(_('Name - Type:')), 0, 1, y1, y2) + table.attach(HIGEntryLabel(name + ' - ' + type), 1, 2, y1, y2) + y1 += 1 + y2 += 1 + + self.hostnames_expander.add(hbox) + self._pack_noexpand_nofill(self.hostnames_expander) + + def set_os(self, os): + if os: + self.os_expander.set_use_markup(True) + self.os_expander.set_expanded(True) + table, hbox = self.create_table_hbox() + progress = Gtk.ProgressBar() + + if 'accuracy' in os: + progress.set_fraction(float(os['accuracy']) / 100.0) + progress.set_text(os['accuracy'] + '%') + else: + progress.set_text(_('Not Available')) + + table.attach(HIGEntryLabel(_('Name:')), 0, 1, 0, 1) + table.attach(HIGEntryLabel(os['name']), 1, 2, 0, 1) + + table.attach(HIGEntryLabel(_('Accuracy:')), 0, 1, 1, 2) + table.attach(progress, 1, 2, 1, 2) + + y1 = 2 + y2 = 3 + + if 'portsused' in os: + self.set_ports_used(os['portsused']) + table.attach(self.portsused_expander, 0, 2, y1, y2) + y1 += 1 + y2 += 1 + + if 'osclasses' in os: + self.set_osclass(os['osclasses']) + self.osclass_expander.set_use_markup(True) + table.attach(self.osclass_expander, 0, 2, y1, y2) + + self.os_expander.add(hbox) + self._pack_noexpand_nofill(self.os_expander) + + def set_ports_used(self, ports): + self.portsused_expander.set_use_markup(True) + table, hbox = self.create_table_hbox() + + y1 = 0 + y2 = 1 + + for p in ports: + table.attach(HIGEntryLabel( + _('Port-Protocol-State:')), 0, 1, y1, y2) + table.attach(HIGEntryLabel( + p['portid'] + ' - ' + p['proto'] + ' - ' + p['state'] + ), 1, 2, y1, y2) + y1 += 1 + y2 += 1 + + self.portsused_expander.add(hbox) + + def set_osclass(self, osclass): + if osclass: + self.osclass_expander.set_use_markup(True) + table, hbox = self.create_table_hbox() + + table.attach(HIGEntryLabel(_('Type')), 0, 1, 0, 1) + table.attach(HIGEntryLabel(_('Vendor')), 1, 2, 0, 1) + table.attach(HIGEntryLabel(_('OS Family')), 2, 3, 0, 1) + table.attach(HIGEntryLabel(_('OS Generation')), 3, 4, 0, 1) + table.attach(HIGEntryLabel(_('Accuracy')), 4, 5, 0, 1) + + y1 = 1 + y2 = 2 + + for o in osclass: + table.attach(HIGEntryLabel(o['type']), 0, 1, y1, y2) + table.attach(HIGEntryLabel(o['vendor']), 1, 2, y1, y2) + table.attach(HIGEntryLabel(o['osfamily']), 2, 3, y1, y2) + table.attach(HIGEntryLabel(o['osgen']), 3, 4, y1, y2) + + progress = Gtk.ProgressBar() + progress.set_text(o['accuracy'] + '%') + progress.set_fraction(float(o['accuracy']) / 100.0) + table.attach(progress, 4, 5, y1, y2) + y1 += 1 + y2 += 1 + + self.osclass_expander.add(hbox) + + def set_tcpseq(self, tcpseq): + if tcpseq: + self.tcp_expander.set_use_markup(True) + table, hbox = self.create_table_hbox() + + combo = Gtk.ComboBoxText() + for v in tcpseq['values'].split(','): + combo.append_text(v) + + table.attach(HIGEntryLabel(_('Difficulty:')), 0, 1, 1, 2) + table.attach(HIGEntryLabel(tcpseq['difficulty']), 1, 2, 1, 2) + + table.attach(HIGEntryLabel(_('Index:')), 0, 1, 2, 3) + table.attach(HIGEntryLabel(tcpseq['index']), 1, 2, 2, 3) + + table.attach(HIGEntryLabel(_('Values:')), 0, 1, 3, 4) + table.attach(combo, 1, 2, 3, 4) + + self.tcp_expander.add(hbox) + self._pack_noexpand_nofill(self.tcp_expander) + + def set_ipseq(self, ipseq): + if ipseq: + self.ip_expander.set_use_markup(True) + table, hbox = self.create_table_hbox() + + combo = Gtk.ComboBoxText() + + for i in ipseq['values'].split(','): + combo.append_text(i) + + table.attach(HIGEntryLabel(_('Class:')), 0, 1, 0, 1) + table.attach(HIGEntryLabel(ipseq['class']), 1, 2, 0, 1) + + table.attach(HIGEntryLabel(_('Values:')), 0, 1, 1, 2) + table.attach(combo, 1, 2, 1, 2) + + self.ip_expander.add(hbox) + self._pack_noexpand_nofill(self.ip_expander) + + def set_tcptsseq(self, tcptsseq): + if tcptsseq: + self.tcpts_expander.set_use_markup(True) + table, hbox = self.create_table_hbox() + + combo = Gtk.ComboBoxText() + + for i in tcptsseq['values'].split(','): + combo.append_text(i) + + table.attach(HIGEntryLabel(_('Class:')), 0, 1, 0, 1) + table.attach(HIGEntryLabel(tcptsseq['class']), 1, 2, 0, 1) + + table.attach(HIGEntryLabel(_('Values:')), 0, 1, 1, 2) + table.attach(combo, 1, 2, 1, 2) + + self.tcpts_expander.add(hbox) + self._pack_noexpand_nofill(self.tcpts_expander) + + def set_comment(self, comment=''): + self.comment_expander.set_use_markup(True) + if comment: + self.comment_expander.set_expanded(True) + + hbox = HIGHBox() + + self.comment_scrolled = Gtk.ScrolledWindow() + self.comment_scrolled.set_border_width(5) + self.comment_scrolled.set_policy( + Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) + + self.comment_txt_vw = Gtk.TextView() + self.comment_txt_vw.set_wrap_mode(Gtk.WrapMode.WORD) + self.comment_txt_vw.get_buffer().set_text(comment) + + self.comment_scrolled.add(self.comment_txt_vw) + hbox._pack_expand_fill(self.comment_scrolled) + + self.comment_expander.add(hbox) + self._pack_noexpand_nofill(self.comment_expander) + + def get_comment(self): + buffer = self.comment_txt_vw.get_buffer() + return buffer.get_text(buffer.get_start_iter(), buffer.get_end_iter()) -- cgit v1.2.3