| 4 | import os, glob |
| 5 | |
| 6 | class CherryTree(Report): |
| 7 | |
| 8 | def __init__(self): |
| 9 | super().__init__() |
| 10 | self.name = 'CherryTree' |
| 11 | self.tags = [] |
| 12 | |
| 13 | async def run(self, targets): |
| 14 | if len(targets) > 1: |
| 15 | report = os.path.join(config['output'], 'report.xml.ctd') |
| 16 | elif len(targets) == 1: |
| 17 | report = os.path.join(targets[0].reportdir, 'report.xml.ctd') |
| 18 | else: |
| 19 | return |
| 20 | |
| 21 | with open(report, 'w') as output: |
| 22 | output.writelines('<?xml version="1.0" encoding="UTF-8"?>\n<cherrytree>\n') |
| 23 | for target in targets: |
| 24 | output.writelines('<node name="' + escape(target.address) + '" is_bold="1" custom_icon_id="1">\n') |
| 25 | |
| 26 | files = [os.path.abspath(filename) for filename in glob.iglob(os.path.join(target.scandir, '**/*'), recursive=True) if os.path.isfile(filename) and filename.endswith(('.txt', '.html'))] |
| 27 | |
| 28 | if target.scans['ports']: |
| 29 | output.writelines('<node name="Port Scans" custom_icon_id="2">\n') |
| 30 | for scan in target.scans['ports'].keys(): |
| 31 | if len(target.scans['ports'][scan]['commands']) > 0: |
| 32 | output.writelines('<node name="PortScan: ' + escape(target.scans['ports'][scan]['plugin'].name) + '" custom_icon_id="21">\n') |
| 33 | for command in target.scans['ports'][scan]['commands']: |
| 34 | output.writelines('<rich_text>' + escape(command[0])) |
| 35 | for filename in files: |
| 36 | if filename in command[0] or (command[1] is not None and filename == command[1]) or (command[2] is not None and filename == command[2]): |
| 37 | output.writelines('\n\n' + escape(filename) + ':\n\n') |
| 38 | with open(filename, 'r') as file: |
| 39 | output.writelines(escape(file.read()) + '\n') |
| 40 | output.writelines('</rich_text>\n') |
| 41 | output.writelines('</node>\n') |
| 42 | output.writelines('</node>\n') |
| 43 | if target.scans['services']: |
| 44 | output.writelines('<node name="Services" custom_icon_id="2">\n') |
| 45 | for service in target.scans['services'].keys(): |
| 46 | output.writelines('<node name="Service: ' + escape(service.tag()) + '" custom_icon_id="3">\n') |
| 47 | for plugin in target.scans['services'][service].keys(): |
| 48 | if len(target.scans['services'][service][plugin]['commands']) > 0: |
| 49 | output.writelines('<node name="' + escape(target.scans['services'][service][plugin]['plugin'].name) + '" custom_icon_id="21">\n') |
| 50 | for command in target.scans['services'][service][plugin]['commands']: |
| 51 | output.writelines('<rich_text>' + escape(command[0])) |
| 52 | for filename in files: |
| 53 | if filename in command[0] or (command[1] is not None and filename == command[1]) or (command[2] is not None and filename == command[2]): |
| 54 | output.writelines('\n\n' + escape(filename) + ':\n\n') |
| 55 | with open(filename, 'r') as file: |
| 56 | output.writelines(escape(file.read()) + '\n') |
| 57 | output.writelines('</rich_text>\n') |
| 58 | output.writelines('</node>\n') |
| 59 | output.writelines('</node>\n') |
| 60 | output.writelines('</node>\n') |
| 61 | |
| 62 | manual_commands = os.path.join(target.scandir, '_manual_commands.txt') |
| 63 | if os.path.isfile(manual_commands): |
nothing calls this directly
no outgoing calls
no test coverage detected