Skip to content

Commit

Permalink
Merge pull request #2 from kaje11/rng_update
Browse files Browse the repository at this point in the history
Nmap scans, document title, charts cloning, minor fixes
  • Loading branch information
hvqzao committed Jan 12, 2021
2 parents 80c9532 + 1d26006 commit 3b4b2ff
Show file tree
Hide file tree
Showing 7 changed files with 331 additions and 41 deletions.
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ Main application window contains four fields that act as an input
- Scan - HP WebInspect / Burp Suite Pro scan
- Knowledge base - knowledge base that could be used to reinforce
final report customization
- Nmap scan - parse XML output files from Nmap scans and include them
in the report

Double click on given text area will popup the content on larger area.

Expand All @@ -55,14 +57,14 @@ Command-line support has been added in order to allow bulk generation
of report-files. Application currently supports one set of switches:

```
-t template-file [-c content-file] [-k kb-file] [-s scan-file]
-r report-file
-t template-file [-c content-file] [-k kb-file] [-s scan-file] [-n nmap-file]
-r report-file [-o output-content-file]
```

Example use:

```
python report-ng.py -t examples/example-2-scan-report-template.xml -c examples/example-2-content.yaml -k examples/example-2-kb.yaml -s examples/example-2-scan-export-Burp.xml -r examples/\!.xml
python report-ng.py -t examples/example-2-scan-report-template.xml -c examples/example-2-content.yaml -k examples/example-2-kb.yaml -s examples/example-2-scan-export-Burp.xml -r examples/\!.xml -o examples/\!.yaml
```

## Word Template Preparation
Expand Down
2 changes: 1 addition & 1 deletion cxfreeze_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

# Dependencies are automatically detected, but it might need
# fine tuning.
buildOptions = dict(packages=['lxml._elementpath', 'gzip'], excludes=[], compressed=True)
buildOptions = dict(packages=['lxml._elementpath', 'gzip'], excludes=['collections.abc'], compressed=True)

import sys
base = 'Win32GUI' if sys.platform=='win32' else None
Expand Down
11 changes: 9 additions & 2 deletions src/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def value (key):
def values (key):
if key in sys.argv:
return map(lambda x: sys.argv[x + 1], filter(lambda x: x + 1 < len(sys.argv), filter(lambda x: sys.argv[x] == key, range(len(sys.argv)))))
return None
return [] #None caused error if empty.

def is_csv (filename):
ext = '.csv'
Expand All @@ -53,24 +53,31 @@ def is_yaml (filename):
content_file = value('-c')
kb_file = value('-k')
scan_files = values('-s')
nmap_files = values('-n')
report_file = value('-r')
output_file = value('-o')
summary_file = value('-u')

if template_file and report_file:
report = Report()
report.template_load_xml(template_file)

if content_file:
if is_yaml(content_file):
report.content_load_yaml(content_file)
else:
report.content_load_json(content_file)

for scan_file in scan_files:
#report.scan = Scan(scan_file)
scan = Scan(scan_file)
report.merge_scan(scan.modify())
report.content_refresh()
del scan

for nmap_file in nmap_files:
report.nmap_load_xml(nmap_file)

if kb_file:
if is_csv(kb_file):
report.kb_load_csv(kb_file)
Expand Down Expand Up @@ -112,7 +119,7 @@ def is_yaml (filename):
else:
print 'Usage: '
print
print ' ' + self.title + '.exe -t template-file [-c content-file] [-k kb-file] [[-s scan-file] ...] -r output-report-file [-o output-content-file]'
print ' ' + self.title + '.exe -t template-file [-c content-file] [-k kb-file] [[-s scan-file] ...] [[-n nmap-file] ...] -r output-report-file [-o output-content-file]'
print ' generate report (and optionally - content as yaml / json)'
print
print ' ' + self.title + '.exe -s scan-file -o output-scan-file'
Expand Down
105 changes: 96 additions & 9 deletions src/gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,9 @@ def next(self):
self.menu_file_open_k = menu_file.Append(index.next(), 'Open &Knowledge Base...')
self.menu_file_open_k.Enable(False)
self.Bind(wx.EVT_MENU, self.Open_Knowledge_Base, id=index.current)
self.menu_file_open_m = menu_file.Append(index.next(), 'Open &Nmap Scan...')
self.menu_file_open_m.Enable(False)
self.Bind(wx.EVT_MENU, self.Open_Nmap_Scan, id=index.current)
#menu_file.AppendSeparator()
#self.menu_file_generate_c = menu_file.Append(index.next(), '&Generate Content')
#self.menu_file_generate_c.Enable(False)
Expand Down Expand Up @@ -205,6 +208,11 @@ def next(self):
self.menu_tools_merge_kb_into_content = menu_tools.Append(index.next(), 'Merge KB into Content')
self.menu_tools_merge_kb_into_content.Enable(False)
self.Bind(wx.EVT_MENU, self.Merge_KB_Into_Content, id=index.current)
# remove nmap
self.menu_tools_remove_nmap_scan = menu_tools.Append(index.next(), 'Remove Nmap Scan')
self.menu_tools_remove_nmap_scan.Enable(False)
self.Bind(wx.EVT_MENU, self.Remove_Nmap_Scan, id=index.current)

self.menu_tools_generate_few_passwords = menu_tools.Append(index.next(), 'Generate &few passwords')
self.Bind(wx.EVT_MENU, self.Generate_few_passwords, id=index.current)

Expand All @@ -230,7 +238,7 @@ def __init__(self, target, handler):
self.target = target
self.handler = handler
def OnDropFiles(self, x, y, filenames):
self.handler(filenames)
return self.handler(filenames)
panel = wx.Panel(self)
vbox = wx.BoxSizer(wx.VERTICAL)
fgs = wx.FlexGridSizer(5, 2, 9, 25)
Expand Down Expand Up @@ -260,8 +268,9 @@ def ctrl_tc_t_OnMouseOver(e):
def ctrl_tc_t_OnDropFiles(filenames):
if len(filenames) != 1:
wx.MessageBox('Single file is expected!', 'Error', wx.OK | wx.ICON_ERROR)
return
return False
self._open_template(filenames[0])
return True
ctrl_tc_t_dt = FileDropTarget(self.ctrl_tc_t, ctrl_tc_t_OnDropFiles)
self.ctrl_tc_t.SetDropTarget(ctrl_tc_t_dt)
fgs.AddMany([(self.ctrl_st_t, 1, wx.EXPAND), (self.ctrl_tc_t, 1, wx.EXPAND)])
Expand Down Expand Up @@ -314,10 +323,12 @@ def ctrl_tc_c_OnMouseOver(e):
def ctrl_tc_c_OnDropFiles(filenames):
if len(filenames) != 1:
wx.MessageBox('Single file is expected!', 'Error', wx.OK | wx.ICON_ERROR)
return
return False
self._open_content(filenames[0])
if self.ctrl_st_c.IsEnabled(): # Yamled
self.ctrl_tc_c_b.Show()

return True
ctrl_tc_c_dt = FileDropTarget(self.ctrl_tc_c, ctrl_tc_c_OnDropFiles)
self.ctrl_tc_c.SetDropTarget(ctrl_tc_c_dt)
fgs.AddMany([(self.ctrl_st_c, 1, wx.EXPAND), (self.ctrl_tc_c, 1, wx.EXPAND)])
Expand Down Expand Up @@ -367,10 +378,12 @@ def ctrl_tc_s_OnMouseOver(e):
def ctrl_tc_s_OnDropFiles(filenames):
if len(filenames) != 1:
wx.MessageBox('Single file is expected!', 'Error', wx.OK | wx.ICON_ERROR)
return
return False
self._open_scan(filenames[0])
if self.ctrl_st_s.IsEnabled(): # Yamled
self.ctrl_tc_s_b.Show()

return False
ctrl_tc_s_dt = FileDropTarget(self.ctrl_tc_s, ctrl_tc_s_OnDropFiles)
self.ctrl_tc_s.SetDropTarget(ctrl_tc_s_dt)
fgs.AddMany([(self.ctrl_st_s, 1, wx.EXPAND), (self.ctrl_tc_s, 1, wx.EXPAND)])
Expand Down Expand Up @@ -401,11 +414,46 @@ def ctrl_tc_k_OnMouseLeave(e):
def ctrl_tc_k_OnDropFiles(filenames):
if len(filenames) != 1:
wx.MessageBox('Single file is expected!', 'Error', wx.OK | wx.ICON_ERROR)
return
return False
self._open_kb(filenames[0])
return True
ctrl_tc_k_dt = FileDropTarget(self.ctrl_tc_k, ctrl_tc_k_OnDropFiles)
self.ctrl_tc_k.SetDropTarget(ctrl_tc_k_dt)
fgs.AddMany([(self.ctrl_st_k, 1, wx.EXPAND), (self.ctrl_tc_k, 1, wx.EXPAND)])

# Nmap Scan
self.ctrl_st_n = wx.StaticText(panel, label='Nmap Scan:')
self.ctrl_st_n.Enable(False)
self.ctrl_tc_n = wx.TextCtrl(panel, style=wx.TE_MULTILINE | wx.TE_READONLY, size=(200, 3 * 17,))
self.ctrl_tc_n.Enable(False)
self.ctrl_tc_n.SetBackgroundColour(self.color_tc_bg_d)
def ctrl_tc_n_OnFocus(e):
self.ctrl_tc_n.ShowNativeCaret(False)
e.Skip()
def ctrl_tc_n_OnDoubleclick(e):
if self.ctrl_st_n.IsEnabled():
self.application.TextWindow(self, title='Nmap Scan Preview', content=self.ctrl_tc_n.GetValue())
e.Skip()
self.ctrl_tc_n.Bind(wx.EVT_SET_FOCUS, ctrl_tc_n_OnFocus)
self.ctrl_tc_n.Bind(wx.EVT_LEFT_DCLICK, ctrl_tc_n_OnDoubleclick)
def ctrl_tc_n_OnMouseOver(e):
self.status('You might use drag & drop', hint=True)
e.Skip()
def ctrl_tc_n_OnMouseLeave(e):
self.status('')
e.Skip()
self.ctrl_tc_n.Bind(wx.EVT_ENTER_WINDOW, ctrl_tc_n_OnMouseOver)
self.ctrl_tc_n.Bind(wx.EVT_LEAVE_WINDOW, ctrl_tc_n_OnMouseLeave)
def ctrl_tc_n_OnDropFiles(filenames):
if self.ctrl_st_n.IsEnabled():
for scan in filenames:
self._open_nmap_scan(scan)
return True

ctrl_tc_n_dt = FileDropTarget(self.ctrl_tc_n, ctrl_tc_n_OnDropFiles)
self.ctrl_tc_n.SetDropTarget(ctrl_tc_n_dt)
fgs.AddMany([(self.ctrl_st_n, 1, wx.EXPAND), (self.ctrl_tc_n, 1, wx.EXPAND)])

def panel_OnMouseOver(e):
self.status('')
self.ctrl_tc_c_b.Hide()
Expand Down Expand Up @@ -542,6 +590,12 @@ def _open_template(self, filename):
self.ctrl_tc_t.SetValue('')
self.ctrl_st_c.Enable(False)
self.ctrl_tc_c.SetValue('')

# nmap
self.ctrl_st_n.Enable(False)
self.ctrl_tc_n.SetValue('')
self.ctrl_tc_n.Enable(False)

self.menu_file_open_k.Enable(False)
self.menu_file_save_t.Enable(False)
self.menu_file_save_r.Enable(False)
Expand Down Expand Up @@ -570,6 +624,11 @@ def _open_template(self, filename):
self.menu_tools_merge_scan_into_content.Enable(True)
if self.ctrl_st_k.IsEnabled():
self.menu_tools_merge_kb_into_content.Enable(True)

if self.report.is_template_with_nmap():
self.ctrl_st_n.Enable(True)
self.ctrl_tc_n.Enable(True)
self.ctrl_tc_n.SetBackgroundColour(self.color_tc_bg_e)
self.status('Template loaded')

def Open_Content(self, e):
Expand Down Expand Up @@ -656,6 +715,11 @@ def Merge_KB_Into_Content(self, e):
self.menu_tools_merge_kb_into_content.Enable(False)
self.status('Merged')

def Remove_Nmap_Scan(self, e):
self.report.nmap_remove()
self.ctrl_tc_n.SetValue('')
self.status('Removed')

def Generate_few_passwords(self, e):
self.application.TextWindow(self, title='Random Password Generator', content='\n'.join(pwgen.Few(15)), size=(235, 270,))

Expand All @@ -670,7 +734,7 @@ def Generate_few_passwords(self, e):
def Save_Template_As(self, e):
openFileDialog = wx.FileDialog(self, 'Save Template As', self.save_into_directory, '',
'Content files (*.yaml; *.json)|*.yaml;*.json|All files (*.*)|*.*',
wx.FD_SAVE | wx.wx.FD_OVERWRITE_PROMPT)
wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
if openFileDialog.ShowModal() == wx.ID_CANCEL:
return
json_ext = '.json'
Expand All @@ -687,7 +751,7 @@ def Save_Template_As(self, e):
def Save_Content_As(self, e):
openFileDialog = wx.FileDialog(self, 'Save Content As', self.save_into_directory, '',
'Content files (*.yaml; *.json)|*.yaml;*.json|All files (*.*)|*.*',
wx.FD_SAVE | wx.wx.FD_OVERWRITE_PROMPT)
wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
if openFileDialog.ShowModal() == wx.ID_CANCEL:
return
json_ext = '.json'
Expand All @@ -703,7 +767,7 @@ def Save_Content_As(self, e):
def Save_Scan_As(self, e):
openFileDialog = wx.FileDialog(self, 'Save Scan As', self.save_into_directory, '',
'Content files (*.yaml; *.json)|*.yaml;*.json|All files (*.*)|*.*',
wx.FD_SAVE | wx.wx.FD_OVERWRITE_PROMPT)
wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
if openFileDialog.ShowModal() == wx.ID_CANCEL:
return
json_ext = '.json'
Expand Down Expand Up @@ -732,6 +796,9 @@ def _clean_template(self, force=False):
self.report.content_reload()
if self.ctrl_st_k.IsEnabled():
self.report.kb_reload()
if self.ctrl_st_n.IsEnabled():
self.report.nmap_reload()

self._refresh()
# print 'cleanup performed.'
#else:
Expand All @@ -745,7 +812,7 @@ def Clean_template(self, e):
def Save_Report_As(self, e):
openFileDialog = wx.FileDialog(self, 'Save Report As', self.save_into_directory, '',
'XML files (*.xml)|*.xml|All files (*.*)|*.*',
wx.FD_SAVE | wx.wx.FD_OVERWRITE_PROMPT)
wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
if openFileDialog.ShowModal() == wx.ID_CANCEL:
return
filename = openFileDialog.GetPath()
Expand Down Expand Up @@ -850,6 +917,26 @@ def _open_kb(self, filename):
self.menu_tools_merge_kb_into_content.Enable(True)
self.menu_tools_merge_kb_into_content.Enable(True)

def Open_Nmap_Scan(self, e):
openFileDialog = wx.FileDialog(self, 'Open Nmap Scan', '', '',
'Nmap XML output file (*.xml)|*.xml;|All files (*.*)|*.*',
wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)
if openFileDialog.ShowModal() == wx.ID_CANCEL:
return
self._open_nmap_scan(openFileDialog.GetPath())

def _open_nmap_scan(self, filename):
self.ctrl_st_n.Enable(False)
result = self.report.nmap_load_xml(filename)
if result == True:
self.ctrl_tc_n.SetValue(self.report.nmap_dump())
self.menu_tools_remove_nmap_scan.Enable(True)
else:
self.ctrl_tc_n.SetValue("")
wx.MessageBox('There was an error parsing the file!', 'Error',
wx.OK | wx.ICON_ERROR)
self.ctrl_st_n.Enable(True)

class YamledWindowWrapper(YamledWindow):

def __init__(self, parent=None, title='', content=None, size=(800, 600,), *args, **kwargs):
Expand Down
Loading

0 comments on commit 3b4b2ff

Please sign in to comment.