# $Id: repadv.py.txt 445 2008-11-11 12:57:39Z hc $ import socket import re import cPickle import os import tempfile import sys from time import sleep from sys import exit def die(reason): sys.stderr.write("%s\n" % reason) sys.exit(111) def RecvAll(s, maxlen): res = [] recv = 0 while True: buf = s.recv(maxlen) if buf == None: break if len(buf) == 0: break if recv >= maxlen: break recv = recv + len(buf) res.append(buf) res = "".join(res) return res def RepAdv(host, port, team, user, service, severity, text): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.settimeout(60) lines = [] for line in text.split("\n"): if line == '.': line = ' .' lines.append(line) text = "\n".join(lines) text = """New advisory by : %s Affected service(s): %s Severity [lmh] : %s %s """ % (user, service, severity, text) txt = "reportadvisory(%d, readtext())\n%s\n.\nquit()\n" % (team, text) s.connect((host, port)) s.sendall(txt) res = RecvAll(s, 8192) return res.find("Your advisory has been reported") != -1 def GetTeams(host, port): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.settimeout(60) s.connect((host, port)) s.sendall("lt()\nquit()\n") res = RecvAll(s, 1 << 16) r = re.compile("^([0-9]+)\t([^\t]+)\t") teams = [] for line in res.split("\n"): res = r.search(line) if res != None: teams.append(res.groups()) return teams Settings = [('host', 'Enter the hostname of the scoringbot', '10.100.1.1'), ('port', 'Enter the port of the scoringbot', '8080'), ('team', 'Enter your team_number_', '', lambda(d): sys.stdout.write("%s\n" % "\n".join(["%2d: %s" % (int(tid), tn) for tid, tn in GetTeams(d['host'], int(d['port']))]))), ('user', 'Enter your (nick)name', 'anonymous coward')] def DoSetting(d, n, description, default): if n in d: default = d[n] sys.stdout.write("%s [%s] " % (description, default)) sys.stdout.flush() res = sys.stdin.readline()[:-1] if len(res) == 0: res = default d[n] = res def AskIfUnset(d, n, desc, default): if n not in d: DoSetting(d, n, desc, default) def CheckSettings(d): for setting in Settings: proc = None try: n, desc, default = setting except: n, desc, default, proc = setting if proc != None: if n not in d: try: proc(d) except Exception, e: die("Running proc failed: %s" % e) AskIfUnset(d, n, desc, default) def p_exists(executable): paths = os.getenv('PATH', '/usr/bin:/bin') for path in [''] + paths.split(":"): fn = os.path.join(path, executable) try: os.stat(fn) return True except: pass return False if __name__ == '__main__': try: EDITOROFCHOICE = os.getenv('EDITOR', 'vi') except: die("Error getting default editor") if not p_exists(EDITOROFCHOICE): die("Cannot find executable \"%s\". Set the EDITOR environment variable correctly!" % EDITOROFCHOICE) print "Advisory reporting utility." sdir = os.path.join(os.getenv("HOME", "."), '.reportadvisory') try: os.makedirs(sdir) except: pass spath = os.path.join(os.getenv("HOME", "."), '.reportadvisory', 'settings') try: f = open(spath, 'r') settings = cPickle.load(f) f.close() except: settings = {} CheckSettings(settings) try: f = open(spath, 'w') cPickle.dump(settings, f) f.close() except Exception, e: print "Warning: couldn't save settings: %s" % e AskIfUnset(settings, 'service', 'Which service do you report a vuln for', '') AskIfUnset(settings, 'severity', 'How severe is the vuln? (low/medium/high)', 'low') f, advfile = tempfile.mkstemp(".txt", "advisory", text=True) f = os.fdopen(f, 'w') template = """===== Problem ===== ===== Impact ===== ===== Fix ===== """ f.write(template) f.close() os.system("%s %s" % (EDITOROFCHOICE, advfile)) f = open(advfile, 'r') adv = f.read() f.close() if adv == template: print "Unmodified file; aborting" else: print "Reporting advisory..." try: res = RepAdv(settings['host'], int(settings['port']), int(settings['team']), settings['user'], settings['service'], settings['severity'], adv) except Exception, e: print "Error: %s" % e res = False if res: print "Success! A copy of your advisory has been saved as %s" % advfile else: print "Reporting was not successful. Trying again..." c = 0 sleep(6) while not res: try: res = RepAdv(settings['host'], int(settings['port']), int(settings['team']), settings['user'], settings['service'], settings['severity'], adv) if res: break except Exception, e: print "Error: %s" % e res = False print "Retrying..." sleep(6) c = c + 1 if c > 10: print "Error. Aborting. A copy of your advisory has been saved as %s. Try again manually; check your team number + all the settings..." % advfile break if res: print "Success at last! A copy of your advisory has been saved as %s" % advfile try: exit({True: 0, False: 1}[res]) except: exit(1)