Skip to content

Instantly share code, notes, and snippets.

@phin3has
Created December 11, 2018 22:07
Show Gist options
  • Save phin3has/74b39002389848fd299187666661cef1 to your computer and use it in GitHub Desktop.
Save phin3has/74b39002389848fd299187666661cef1 to your computer and use it in GitHub Desktop.
Masscan XML Parser
__author__ = '@awhitehatter'
__version__ = '0.1'
import xml.etree.ElementTree as ET
import argparse
import sys
'''
###########################################################################
Quick and Dirty Masscan XML parser.
Can yank out hosts, ports or both (colon seperator)
usage: scanparser.py [-h] -f FILE [-p] [-i] [--pretty] [--nospace]
Command line arguments
optional arguments:
-h, --help show this help message and exit
-f FILE, --file FILE XML File to parse
-p, --ports Lists ports
-i, --ips Lists host ip addresses
--pretty Outputs a comma seperated list (instead of every line)
--nospace Sets pretty output to no spaces, usefule for copy
pasta into other tools
###########################################################################
'''
def parseAll(root):
# Parses out host address and port number, prints them host:port
for item in root.findall('./host'):
for child in item:
if child.tag == 'address':
address = child.attrib['addr']
elif child.tag == 'ports':
for grandchild in child:
print(address + ":" + grandchild.attrib['portid'])
def parsePorts(root):
# Parses and prints out ports
for item in root.findall('./host'):
for child in item:
if child.tag == 'ports':
for grandchild in child:
print(grandchild.attrib['portid'])
def parseIPs(root):
# Parses and prints out IP addresses
for item in root.findall('./host'):
for child in item:
if child.tag == 'address':
address = child.attrib['addr']
print(address)
def prettyPorts(root):
# Parses and prints out comma separated ports with spaces
#create an empty list
plist = []
#parse ports and add to list
for item in root.findall('./host'):
for child in item:
if child.tag == 'ports':
for grandchild in child:
if grandchild.attrib['portid'] not in plist:
plist.append(grandchild.attrib['portid'])
# Join comma list
pstring = ", ".join(plist)
# Print the list
print(pstring)
def prettyPortsNoSpaces(root):
# Parses and prints out comma seperated ports with no spaces
#create an empty list
plist = []
#parse ports and add to list
for item in root.findall('./host'):
for child in item:
if child.tag == 'ports':
for grandchild in child:
if grandchild.attrib['portid'] not in plist:
plist.append(grandchild.attrib['portid'])
# Join comma list
plist.sort()
pstring = ",".join(plist)
# Print the list
print(pstring)
def prettyHosts(root):
# parses and prints out comma separted IP addresses with spaces
#create an empty list
phosts = []
# Parses and prints out IP addresses
for item in root.findall('./host'):
for child in item:
if child.tag == 'address':
if child.attrib['addr'] not in phosts:
phosts.append(child.attrib['addr'])
#Join comma list
phosts.sort()
pstring = ", ".join(phosts)
print(pstring)
def prettyHostsNoSpaces(root):
# parses and prints out comma separted IP addresses with no spaces
#create an empty list
phosts = []
# Parses and prints out IP addresses
for item in root.findall('./host'):
for child in item:
if child.tag == 'address':
if child.attrib['addr'] not in phosts:
phosts.append(child.attrib['addr'])
#Join comma list
phosts.sort()
pstring = ",".join(phosts)
print(pstring)
if __name__ == "__main__":
# parse the command line arguments
parser = argparse.ArgumentParser(description="Command line arguments")
parser.add_argument('-f', '--file', action='store', help='XML File to parse', required=True)
parser.add_argument('-p', '--ports', action='store_true', default=False, help='Lists ports')
parser.add_argument('-i', '--ips', action='store_true', default=False, help='Lists host ip addresses')
parser.add_argument('--pretty', action='store_true', default=False, help='Outputs a comma seperated list')
parser.add_argument('--nospace', action='store_true', default=False, help='Sets pretty output to no spaces, usefule for copy pasta into other tools')
args = parser.parse_args()
xmldata = args.file
ports = args.ports
ips = args.ips
pretty = args.pretty
spaces = args.nospace
if pretty == False and spaces == True:
print("You must specify --pretty with --nospace")
sys.exit(1)
if pretty and ports == False and ips == False:
print("You must specify ports (-p) or ips (-i) for comma list")
sys.exit(1)
#Parse XML
tree = ET.parse(xmldata)
root = tree.getroot()
#Parse according to specified options
if ips == False and ports == False:
parseAll(root)
elif pretty:
if spaces:
if ips:
prettyHostsNoSpaces(root)
if ports:
prettyPortsNoSpaces(root)
else:
if ips:
prettyHosts(root)
if ports:
prettyPorts(root)
else:
if ips:
parseIPs(root)
if ports:
parsePorts(root)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment