def _getos(): info = uname() data = "{} {} {}".format(info.sysname, info.release, info.version) summ = "\nOS Kernel information:\n |__{}\n".format(data) detail = detailheader("OS Kernel information") detail += "{}\n".format(data) return summ, detail, data
def _gethostnames(report, precheck): summ = '\nHostname and banner info:\n' detail = detailheader("Hostnames information") if precheck.shouldread('/etc/hostname'): report.hostname = open('/etc/hostname').read() summ += ' |__hostname: ' + report.hostname detail += detailfile('/etc/hostname') detail += '{}\n'.format(report.hostname) elif precheck.checkcommand("hostname"): report.hostname = check_output(["hostname"]).decode("utf-8") summ += ' |__hostname: ' + report.hostname detail += detailfile('hostname') detail += '{}\n'.format(report.hostname) else: report.hostname = gethostname() summ += ' |__hostname: ' + report.hostname detail += detailfile('hostname') detail += '{}\n'.format(report.hostname) if precheck.checkcommand("dnsdomainname"): try: report.domainname = check_output(["dnsdomainname"], stderr=DEVNULL).decode("utf-8") if report.domainname: summ += ' |__dnsdomainname: ' + report.domainname detail += detailfile('domainname') detail += '{}\n'.format(report.hostname) except: pass if precheck.checkcommand("hostid"): report.hostid = check_output(["hostid"]).decode("utf-8") summ += ' |__hostid: ' + report.hostid detail += detailfile('hostid') detail += '{}\n'.format(report.hostid) # Check banner files if precheck.shouldread('/etc/issue'): report.issue = open('/etc/issue').read() summ += ' |__You have an issue banner\n' detail += detailfile('/etc/issue') detail += '{}\n'.format(report.issue) if precheck.shouldread('/etc/issue.net'): report.issuenet = open('/etc/issue.net').read() summ += ' |__You have an issue.net banner\n' detail += detailfile('/etc/issue.net') detail += '{}\n'.format(report.issuenet) if precheck.shouldread('/etc/motd'): report.motd = open('/etc/motd').read() summ += ' |__You have an motd banner\n' detail += detailfile('/etc/motd') detail += '{}\n'.format(report.motd) return summ, detail
def _getusb(): summ = "\nUSB devices:" detail = detailheader("USB information") linuxroot = [] hub = [] usb = [] total = [] output = check_output("lsusb", stderr=DEVNULL).decode("utf-8").splitlines() for item in output: bus = item.split(':')[0].lower().replace("bus ", "").replace(" device ", ":") usbid = item.split('ID ')[1][:9] name = item.split('ID ')[1][10:] if "1d6b:000" in usbid.lower(): linuxroot.append([usbid, name, bus]) elif "hub" in name.lower(): hub.append([usbid, name, bus]) else: usb.append([usbid, name, bus]) total.append([usbid, name, bus]) summ += "\n |__{} devices\n |__{} hubs " \ "(Linux root hubs included)\n".format(len(usb), len(linuxroot) + len(hub)) helptext = "(device ID - name - bus:device)" detail += "{:^80}\n".format(helptext) detail += "Linux root hubs:\n" for item in linuxroot: detail += " |__{} - {} - {}\n".format(item[0], item[1], item[2]) detail += "\nOther hubs:\n" for item in hub: detail += " |__{} - {} - {}\n".format(item[0], item[1], item[2]) detail += "\nUSB devices:\n" for item in usb: detail += " |__{} - {} - {}\n".format(item[0], item[1], item[2]) return summ, detail, total
def _getuserdata(precheck, report): detail = detailheader("Users information") summ = "\nUsers:\n" if precheck.checkcommand("utmpdump"): detail += "\nCurrent users:\n" output = None # For last dates counters month = datetime.now() - timedelta(days=30) week = datetime.now() - timedelta(days=7) day = datetime.now() - timedelta(days=1) # Check where is the utmp file if precheck.shouldread("/run/utmp"): output = check_output( ["utmpdump", "/run/utmp"], stderr=DEVNULL).decode("utf-8").splitlines()[1:] elif precheck.shouldread("/var/run/utmp"): output = check_output( ["utmpdump", "/var/run/utmp"], stderr=DEVNULL).decode("utf-8").splitlines()[1:] elif precheck.shouldread("/var/log/utmp"): output = check_output( ["utmpdump", "/var/log/utmp"], stderr=DEVNULL).decode("utf-8").splitlines()[1:] if output: logged = 0 for item in output: item = item.split("[") item = [x.strip()[:-1].strip() for x in item][1:] uttype = int(item[0]) # 5 INIT, 6 LOGIN, 7 USER and 8 DEAD pid = int(item[1]) user = item[3] term = item[4] origin = item[5] date = item[7] # Parse common kinds of datetime formats # if re.findall("\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}", date): # clean = re.findall("\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}", date)[0] # datet = datetime.strptime(clean, "%Y-%m-%dT%H:%M:%S") # elif re.findall("\D{3} \d{2} \d{2}:\d{2}:\d{2} \d{4}", date): # clean = re.findall("\D{3} \d{2} \d{2}:\d{2}:\d{2} \d{4}", date)[0] # datet = datetime.strptime(clean, "%b %d %H:%M:%S %Y") if uttype == 6: detail += " |__({}) - Init with process {}\n".format( date, process[pid][0]) if uttype == 7: detail += " |__({}) - {} logged on {} from " \ "{} using {}\n".format(date, user, term, origin, process[pid][0]) logged += 1 summ += " |__{} users currently logged\n".format(logged) if precheck.shouldread("/var/log/wtmp"): output = check_output( ["utmpdump", "/var/log/wtmp"], stderr=DEVNULL).decode("utf-8").splitlines()[1:] lastusers = [] originip = [] monthcounter = 0 weekcounter = 0 daycounter = 0 knownformat = False for item in output: item = item.split("[") item = [x.strip()[:-1].strip() for x in item][1:] uttype = int(item[0]) # 5 INIT, 6 LOGIN, 7 USER and 8 DEAD user = item[3] term = item[4] origin = item[5] if re.findall("\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}", origin): ipaddr = ip_address( re.findall("\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}", origin)[0]) if ipaddr not in originip: originip.append(ipaddr) report.infrastructure(ipaddr, "Logged") date = item[7] datet = None if re.findall("\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}", date): clean = re.findall("\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}", date)[0] datet = datetime.strptime(clean, "%Y-%m-%dT%H:%M:%S") elif re.findall("\D{3} \d{2} \d{2}:\d{2}:\d{2} \d{4}", date): clean = re.findall("\D{3} \d{2} \d{2}:\d{2}:\d{2} \d{4}", date)[0] datet = datetime.strptime(clean, "%b %d %H:%M:%S %Y") if uttype == 7: lastusers.append( " |__({}) - {} logged on {} from {}\n".format( date, user, term, origin)) if datet: knownformat = True if datet > day: daycounter += 1 weekcounter += 1 monthcounter += 1 elif datet > week: weekcounter += 1 monthcounter += 1 elif datet > month: monthcounter += 1 if knownformat: detail += "\nLast users logged: ({} day, {} week, {} month)\n".format( daycounter, weekcounter, monthcounter) summ += " |__Users logged last day:{}, " \ "last week: {}, last month: {}\n".format(daycounter, weekcounter, monthcounter) else: detail += "\nLast users logged:\n" for item in lastusers[-100:]: detail += item if precheck.shouldread("/var/log/btmp"): detail += "\nFailed logins:\n" output = check_output(["utmpdump", "/var/log/btmp"], stderr=DEVNULL).decode("utf-8").splitlines() originip = [] failedcounter = 0 monthcounter = 0 weekcounter = 0 daycounter = 0 knownformat = False for item in output: item = item.split("[") item = [x.strip()[:-1].strip() for x in item][1:] origin = item[5] if re.findall("\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}", origin): ipaddr = ip_address( re.findall("\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}", origin)[0]) if ipaddr not in originip: originip.append(ipaddr) report.infrastructure(ipaddr, "Failed logging") date = item[7] datet = None if re.findall("\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}", date): clean = re.findall("\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}", date)[0] datet = datetime.strptime(clean, "%Y-%m-%dT%H:%M:%S") elif re.findall("\D{3} \d{2} \d{2}:\d{2}:\d{2} \d{4}", date): clean = re.findall("\D{3} \d{2} \d{2}:\d{2}:\d{2} \d{4}", date)[0] datet = datetime.strptime(clean, "%b %d %H:%M:%S %Y") failedcounter += 1 if datet: knownformat = True if datet > day: daycounter += 1 weekcounter += 1 monthcounter += 1 elif datet > week: weekcounter += 1 monthcounter += 1 elif datet > month: monthcounter += 1 summ += " |__{} failed logins in btmp, " \ "{} from different remote ip\n".format(failedcounter, len(originip)) detail += " |__{} failed logins in btmp, " \ "{} from different remote ip\n".format(failedcounter, len(originip)) if len(originip) > 0: detail += " |__IP fails connection:\n" for item in originip: detail += " | |__{}\n".format(item) if knownformat: detail += " |__Failed logins last day:{}, " \ "last week: {}, last month: {}\n".format(daycounter, weekcounter, monthcounter) return summ, detail
def _getprocess(): summ = "\nProcess information:\n" detail = detailheader("Process information") detail += detailfile("Process Summary") keylist = list(process.keys()) keylist.sort() total = len(keylist) running = 0 runningdata = [] sleeping = 0 sleepingdata = [] idle = 0 zombie = 0 zombiedata = [] topcpu = [] topmem = [] for item in keylist: try: if process[item][6]: topcpu.append([process[item][6], item]) if process[item][4]: topmem.append([process[item][4], item]) if 'R' in process[item][1]: running += 1 runningdata.append([item, process[item]]) if 'S' in process[item][1]: sleeping += 1 sleepingdata.append([item, process[item]]) if 'I' in process[item][1]: idle += 1 if 'Z' in process[item][1]: zombie += 1 zombiedata.append([item, process[item]]) except: pass # Process deleted topcpu.sort(reverse=True) topmem.sort(reverse=True) summ += " |__{} total process, {} running, {} sleeping, " \ "{} idle and {} zombie\n".format(total, running, sleeping, idle, zombie) detail += "Total processes\n" detail += " |__{} total process, {} running, {} sleeping, " \ "{} idle and {} zombie\n".format(total, running, sleeping, idle, zombie) summ += " |__Top 5 CPU process:\n" detail += " |__Top 10 CPU process:\n" for counter in range(10): if len(process[topcpu[counter][1]][7]) > 59: if counter < 5: summ += " | |__{:_>5}% {}...\n".format( topcpu[counter][0], process[topcpu[counter][1]][7][:56]) detail += " | |__{:_>5}% {}...\n".format( topcpu[counter][0], process[topcpu[counter][1]][7][:56]) else: if counter < 5: summ += " | |__{:_>5}% {}\n".format( topcpu[counter][0], process[topcpu[counter][1]][7]) detail += " | |__{:_>5}% {}\n".format( topcpu[counter][0], process[topcpu[counter][1]][7]) summ += " |__Top 5 RAM process:\n" detail += " |__Top 10 RAM process:\n" for counter in range(10): if len(process[topmem[counter][1]][7]) > 59: if counter < 5: summ += " |__{:_>7} kB {}...\n".format( topmem[counter][0], process[topmem[counter][1]][7][:56]) detail += " |__{:_>7} kB {}...\n".format( topmem[counter][0], process[topmem[counter][1]][7][:56]) else: if counter < 5: summ += " |__{:_>7} kB {}\n".format( topmem[counter][0], process[topmem[counter][1]][7]) detail += " |__{:_>7} kB {}\n".format( topmem[counter][0], process[topmem[counter][1]][7]) detail += detailfile("Process detail") detail += "{:^80}\n".format( "(PID, user, niceness, memory in kB, %cpu and name)") if running > 0: detail += "Running processes\n" for item in runningdata: detail += " |__{:5} {:12} {:3} {:7} {:5}% {}\n".format( item[0], item[1][3][:12], item[1][5], item[1][4], item[1][6], item[1][7][:35]) if zombie > 0: detail += "\nZombie processes\n" for item in zombiedata: detail += " |__{:5} {:12} {:3} {:7} {:5}% {}\n".format( item[0], item[1][3][:12], item[1][5], item[1][4], item[1][6], item[1][0][:35]) if sleeping > 0: detail += "\nSleeping processes\n" for item in sleepingdata: detail += " |__{:5} {:12} {:3} {:7} {:5}% {}\n".format( item[0], item[1][3][:12], item[1][5], item[1][4], item[1][6], item[1][7][:35]) return summ, detail
def _getusers(report, precheck): summ = '\nUsers and groups info:\n' detail = detailheader("Users and groups") # Check users if precheck.shouldread('/etc/passwd'): output = open('/etc/passwd').readlines() for item in output: parts = item.strip().split(":") report.users[parts[0]] = ["?", parts[2], parts[3], parts[4], parts[5], parts[6], []] report.pidusers[int(parts[2])] = parts[0] # Check groups if precheck.shouldread('/etc/group'): output = open('/etc/group').readlines() for item in output: parts = item.strip().split(":") report.groups[parts[0]] = ["?", parts[2], parts[3].split(",")] # Check passwords format if precheck.shouldread('/etc/shadow'): output = open('/etc/shadow').readlines() for item in output: parts = item.split(":") data = report.users.get(parts[0], None) if data: if parts[1].startswith('$1$'): passwd = "MD5" elif parts[1].startswith('$2a$'): passwd = "Blowfish" elif parts[1].startswith('$2y$'): passwd = "Blowfish" elif parts[1].startswith('$5$'): passwd = "SHA-256" elif parts[1].startswith('$6$'): passwd = "SHA-512" else: passwd = "No password" modify = report.users[parts[0]] modify[0] = passwd report.users[parts[0]] = modify for item in report.groups: for user in report.groups[item][2]: if user: report.users[user][6].append(item) summ += " |__Users:" line = "\n | |__" upass = 0 umd5 = 0 detail += detailfile("Users with any kind of shell or password") for item in sorted(report.users): if report.users[item][0] == "No password" or report.users[item][0] == "?": if len(line) > 72: summ += line line = "\n | |__" else: line += "{} ".format(item) if "false" not in report.users[item][5] and "nologin" not in report.users[item][5]: detail += "\nUser: {}, Home: {}, Shell: {}\n |__Groups: {}\n".\ format(item, report.users[item][4], report.users[item][5], report.users[item][6]) else: if len(line) > 72: summ += line line = "\n | |__" else: line += "[{}] ".format(item) detail += "\nUser: {}, Password: {}, Home: {}, Shell: {}\n |__Groups: {}\n".\ format(item, report.users[item][0], report.users[item][4], report.users[item][5], report.users[item][6]) upass += 1 summ += line summ += "\n |__Groups:" line = "\n | |__" detail += detailfile("Summary of users and groups") for item in sorted(report.groups): if len(line) > 72: summ += line line = "\n | |__" else: line += "{} ".format(item) summ += line if precheck.root: summ += "\n |__There are {} users, {} with password ({} MD5 hashed), " \ "and {} groups.\n".format(len(report.users), upass, umd5, len(report.groups)) detail += summ else: summ += "\n |__There are {} users and {} groups.\n".format(len(report.users), len(report.groups)) detail += summ return summ, detail
def _getrunningservices(precheck, report): detail = detailheader("Services information") summ = "" if precheck.checkcommand("runlevel"): try: message = None output = check_output(["runlevel"], stderr=DEVNULL).decode("utf-8").split(" ") report.runlevel = int(output[1]) if report.runlevel == 1: message = "Runlevel 1: Single-user mode" elif report.runlevel == 2: message = "Runlevel 2: Multi-user mode" elif report.runlevel == 3: message = "Runlevel 3: Multi-user mode with networking" elif report.runlevel == 4: message = "Runlevel 4: Not used/user-definable" elif report.runlevel == 5: message = "Runlevel 5: Start the system normally with appropriate display manager" if message: detail += "{:^80}\n".format(message) summ += "\n{}\n |__{}\n".format(message.split(":")[0], message.split(":")[1]) except Exception as e: report.log("INFO", "Unknown runlevel") report.log("DEBUG", str(e)) if precheck.checkcommand("systemctl"): output = check_output(["systemctl", "list-units"], stderr=DEVNULL).decode("utf-8").splitlines() detail += detailfile("systemd services:") summ += "\nSystemd services:\n" for item in output: if " loaded" in item: item = " ".join(item.split()).split(" ") if len(item[0]) > 1: unit = item[0] sub = item[3] description = " ".join(item[4:]) else: unit = item[1] sub = item[4] description = " ".join(item[5:]) if sub == "running": report.runningservices.append([unit, description]) elif sub == "failed": report.failedservices.append([unit, description]) # Ignore mount and plugged elif sub == "waiting" or sub == "exited" or sub == "active" \ or sub == "listening" or sub == "elapsed": report.otherservices.append([sub, unit, description]) elif precheck.checkcommand("chkconfig"): output = check_output(["chkconfig", "--list"], stderr=DEVNULL).decode("utf-8").splitlines() detail += detailfile("SysV init services:") summ += "\nSysV init enabled services:\n" if 0 < report.runlevel < 6: checkon = "{}:on".format(report.runlevel) checkoff = "{}:off".format(report.runlevel) for item in output: item = " ".join(item.split()) if checkon in item: report.runningservices.append([item.split(" ")[0], ""]) elif checkoff in item: report.otherservices.append(["stopped", item.split(" ")[0], ""]) report.runningservices.sort() report.failedservices.sort() report.otherservices.sort() if report.failedservices: detail += "\nFailed services:\n" summ += " |__Failed services:\n" for item in report.failedservices: if len(item[1]) > 0: detail += " |__{} ({})\n".format(item[0], item[1]) summ += " | |__{} ({})\n".format(item[0], item[1]) else: detail += " |__{}\n".format(item[0]) summ += " | |__{}\n".format(item[0]) if report.runningservices: detail += "\nRunning services:\n" summ += " |__Running services: {}\n".format(len(report.runningservices)) for item in report.runningservices: if len(item[1]) > 0: detail += " |__{} ({})\n".format(item[0], item[1]) else: detail += " |__{}\n".format(item[0]) if report.otherservices: detail += "\nOther state:\n" summ += " |__Other state services: {}\n".format(len(report.otherservices)) state = "" for item in report.otherservices: if len(item[2]) > 0: if item[0] == state: detail += " | |__{} ({})\n".format(item[1], item[2]) else: state = item[0] detail += " |__{}\n | |__{} ({})\n".format(item[0], item[1], item[2]) else: if item[0] == state: detail += " | |__{}\n".format(item[1]) else: state = item[0] detail += " |__{}\n | |__{}\n".format(item[0], item[1]) return summ, detail
def _getram(precheck): detail = detailheader("Memory information") summ = "\nCurrent memory status:\n" if precheck.shouldread("/proc/meminfo"): meminfo = {} with open("/proc/meminfo") as f: info = f.readlines() for item in info: if ":" in item: name = item.split(":")[0].strip() data = item.split(":")[1].strip() if "memtotal" in name.lower(): meminfo["memtotal"] = round(int(data.split(" ")[0]) / 1024) if "memfree" in name.lower(): meminfo["memfree"] = round(int(data.split(" ")[0]) / 1024) if "memavailable" in name.lower(): meminfo["memavailable"] = round( int(data.split(" ")[0]) / 1024) if "buffers" in name.lower(): meminfo["buffers"] = round(int(data.split(" ")[0]) / 1024) if "cached" == name.lower(): meminfo["cached"] = round(int(data.split(" ")[0]) / 1024) if "swapcached" in name.lower(): meminfo["swapcache"] = round( int(data.split(" ")[0]) / 1024) if "swaptotal" in name.lower(): meminfo["swaptotal"] = round( int(data.split(" ")[0]) / 1024) if "swapfree" in name.lower(): meminfo["swapfree"] = round(int(data.split(" ")[0]) / 1024) if "hardwarecorrupted" in name.lower(): meminfo["hardwarecorrupted"] = round( int(data.split(" ")[0]) / 1024) if "slab" == name.lower(): meminfo["slab"] = round(int(data.split(" ")[0]) / 1024) meminfo["totalused"] = meminfo.get("memtotal", 0) - meminfo.get( "memfree", 0) meminfo["buff/cache"] = (meminfo.get("buffers", 0) + meminfo.get("cached", 0) + meminfo.get("slab", 0)) meminfo["reallyused"] = meminfo["totalused"] - meminfo["buff/cache"] meminfo["%used"] = round(meminfo["reallyused"] * 100 / meminfo.get("memtotal")) meminfo["%buff/cache"] = round(meminfo["buff/cache"] * 100 / meminfo.get("memtotal")) meminfo["%free"] = round( meminfo.get("memfree", 0) * 100 / meminfo.get("memtotal")) if meminfo.get("swaptotal"): meminfo["swapused"] = meminfo.get("swaptotal", 0) - meminfo.get( "swapfree", 0) meminfo["%swapused"] = round(meminfo["swapused"] * 100 / meminfo.get("swaptotal")) meminfo["%swapfree"] = round( meminfo.get("swapfree", 0) * 100 / meminfo.get("swaptotal")) summ += " |__Total memory of {} MB\n".format(meminfo.get( "memtotal", 0)) summ += " | |__{}% used\n".format(meminfo["%used"]) summ += " | |__{}% buffers/cache\n".format( meminfo["%buff/cache"]) summ += " | |__{}% free\n".format(meminfo["%free"]) summ += " |__Total SWAP of {} MB\n".format(meminfo.get("swaptotal", 0)) if meminfo.get("swaptotal"): summ += " |__{}% used\n".format(meminfo["%swapused"]) summ += " |__{}% free\n".format(meminfo["%swapfree"]) detail += summ detail += "\nDetailed memory status:\n" detail += " |__Total memory: {} MB\n".format( meminfo.get("memtotal", 0)) detail += " |__Memory used: {} MB\n".format( meminfo["totalused"]) detail += " |__Memory really used: {} MB\n".format( meminfo["reallyused"]) detail += " |__Free memory: {} MB\n".format( meminfo.get("memfree", 0)) detail += " |__Available memory: {} MB\n".format( meminfo.get("memavailable", 0)) detail += " |__Buffers: {} MB\n".format( meminfo.get("buffers", 0)) detail += " |__Cached: {} MB\n".format( meminfo.get("cached", 0)) detail += " |__Slab: {} MB\n".format( meminfo.get("slab", 0)) detail += " |__Buff/Cache/Slab: {} MB\n".format( meminfo["buff/cache"]) detail += " |__Hardware corrupted: {} MB\n".format( meminfo.get("hardwarecorrupted", 0)) if meminfo.get("swaptotal"): detail += " |__Total swap: {} MB\n".format( meminfo.get("swaptotal", 0)) detail += " |__Free swap: {} MB\n".format( meminfo.get("swapfree", 0)) detail += " |__Used swap: {} MB\n".format( meminfo["swapused"]) detail += " |__Cached swap: {} MB\n".format( meminfo["swapcache"]) return summ, detail
def scaninfrastructure(report, precheck, mask): # arp scan of local network if precheck.root: try: report.log("DEBUG", "Scan local networks started") if not report.ifaces: _getnetinfo(report, precheck) totalip = 0 for iface in report.ifaces: if len(report.ifaces[iface]) > 1 and iface != "lo" and \ int(report.ifaces[iface][1].split("/")[1]) >= mask: totalip += pow( 2, 32 - int(report.ifaces[iface][1].split("/")[1])) print( "\nThere are {} possible ips in all subnets to scan with a /{} " "mask or smaller. It could take some time. Do you want to " "continue with ? (y/N) ".format(totalip, mask), end="") ans = str(input()).lower().lstrip() if len(ans) > 0 and 'y' in ans[0]: summ = "\nARP scan:\n" detailed = detailheader("ARP Scan") counter = 0 total = len(report.ifaces) for iface in report.ifaces: percentagebar(total, counter) if len(report.ifaces[iface]) > 1 and iface != "lo" and \ int(report.ifaces[iface][1].split("/")[1]) > 22: _localnetworkarpscan(iface, report.ifaces[iface][0], report.ifaces[iface][1]) counter += 1 percentagebar(total, counter) for item in sorted(ipmac): summ += " |__IP: {:16} [{}]\n".format( str(item), ipmac[item]) if report.infrastructure(ip_address(item), "MAC {}".format(ipmac[item])): detailed += " IP: {:16} MAC: {}\n".format( str(item), ipmac[item]) report.summarized(5, summ) report.detailed(5, detailed) report.log("DEBUG", "Scan local networks completed") except Exception as e: report.log("ERROR", "Can't finish local networks scan") report.log("DEBUG", str(e)) report.log("DEBUG", traceback.format_exc()) else: report.log("INFO", "You don't have root permission to scan local networks") # Scan ports try: report.log("DEBUG", "Port scan started") summ, detail = _portscan(report, precheck) report.summarized(5, summ) report.detailed(5, detail) report.log("DEBUG", "Port scan completed") except Exception as e: report.log("ERROR", "Can't scan ports") report.log("DEBUG", str(e)) report.log("DEBUG", traceback.format_exc())
def _portscan(report, precheck): detail = detailheader("Port scan") summ = "\nPort scan:\n" summ += " |__Total IPs in infrastructure: {}\n".format( len(report.infrastructure_data)) detail += "\nTotal IPs in infrastructure: {}\n".format( len(report.infrastructure_data)) localmachine = [] localnetwork = [] iptables = [] outconns = [] inconns = [] carvips = [] carvfqdn = [] for item in sorted(report.infrastructure_data): if "Local machine" in report.infrastructure_data[item]: localmachine.append(item) elif [ x for x in report.infrastructure_data[item] if x.startswith("IPTables") ]: iptables.append(item) elif [ x for x in report.infrastructure_data[item] if x.startswith("Connected at") ]: outconns.append(item) elif [ x for x in report.infrastructure_data[item] if x.startswith("Connected in") ]: inconns.append(item) elif [ x for x in report.infrastructure_data[item] if x.startswith("MAC") ]: localnetwork.append(item) elif [ x for x in report.infrastructure_data[item] if x.startswith("Named") ]: carvips.append(item) elif [ x for x in report.infrastructure_data[item] if x.startswith("Found") ]: carvfqdn.append(item) print( "\n(a) TOTAL IPs: {:>10}\n(m) Local machine IPs: {:>5}\n(f) IPTables allowed: {:>5}\n" "(o) Outgoing connections: {:>3}\n(i) Incoming connections: {:>3}\n" "(n) Local network IPs: {:>5}\n(x) Carved IPs: {:>9}" "\n(y)Carved FQDN: {:>8}".format(len(report.infrastructure_data), len(localmachine), len(iptables), len(outconns), len(inconns), len(localnetwork), len(carvips), len(carvfqdn))) print( "What kind of IPs do you want to scan (write one or several letters): ", end="") ans = str(input()).lower().lstrip() scanlist = [] if 'a' in ans: scanlist = sorted(report.infrastructure_data) else: if 'm' in ans: scanlist += localmachine if 'n' in ans: scanlist += localnetwork if 'o' in ans: scanlist += outconns if 'i' in ans: scanlist += inconns if 'x' in ans: scanlist += carvips if 'y' in ans: scanlist += carvfqdn summ += " |__Total IPs to scan: {}\n".format(len(scanlist)) detail += "\nTotal IPs to scan: {}\n".format(len(scanlist)) portcounter = 0 total = len(scanlist) for idx, item in enumerate(scanlist): percentagebar(total, idx) detail += "\n{}\n".format(item) result = _ipscan(item, precheck) for port in result: detail += " |__{:5} - {}\n".format(port, precheck.portnames[port][1]) report.infrastructure( item, "Port TCP {} open ({})".format(port, precheck.portnames[port][1])) portcounter += 1 percentagebar(total, total) summ += " |__{} open ports found\n".format(portcounter) return summ, detail
def _gethardware(precheck): arch = uname().machine detail = "" summ = "\nCPU and memory information:\n" cpuinfo = {"processor": 0, "vendor_id": "", "cpu_family": 0, "model": 0, "model_name": "", "stepping": 0, "physical_id": 0, "cpu_cores": 0, "flags": "", "bugs": ""} meminfo = {"memtotal": "", "swaptotal": ""} if precheck.shouldread("/proc/cpuinfo"): detail += detailheader("CPU information") with open("/proc/cpuinfo") as f: info = f.readlines() for item in info: if ":" in item: name = item.split(":")[0].strip() data = item.split(":")[1].strip() if "processor" in name: number = int(data) if number > cpuinfo["processor"]: cpuinfo["processor"] = number if "vendor" in name: cpuinfo["vendor_id"] = data if "cpu family" in name: number = int(data) if number > cpuinfo["cpu_family"]: cpuinfo["cpu_family"] = number if name == "model": number = int(data) if number > cpuinfo["model"]: cpuinfo["model"] = number if "model name" in name: cpuinfo["model_name"] = data if "stepping" in name: number = int(data) if number > cpuinfo["stepping"]: cpuinfo["stepping"] = number if "physical" in name: number = int(data) if number > cpuinfo["physical_id"]: cpuinfo["physical_id"] = number if "cpu cores" in name: number = int(data) if number > cpuinfo["cpu_cores"]: cpuinfo["cpu_cores"] = number if "flags" in name: cpuinfo["flags"] = data if "bugs" in name: cpuinfo["bugs"] = data cpuinfo['processor'] += 1 cpuinfo['physical_id'] += 1 summ += " |__Architecture: {}\n |__CPU: {} x {}\n | |__{} stepping {} with {} " \ "cores\n".format(arch, cpuinfo["physical_id"], cpuinfo["vendor_id"], cpuinfo["model_name"], cpuinfo["stepping"], cpuinfo["cpu_cores"]) detail += "Architect.: {}\nSockets: {}\n".format(arch, cpuinfo["physical_id"]) detail += "Vendor: {}\nModel name: {}\nModel: {}\n".format(cpuinfo["vendor_id"], cpuinfo["model_name"], cpuinfo["model"]) detail += "Stepping: {}\nCores/sock: {}\nThreads: {}\n".format(cpuinfo["stepping"], cpuinfo["cpu_cores"], cpuinfo["processor"]) detail += "CPU Family: {}\nFlags: {}\nBugs: {}\n".format(cpuinfo["cpu_family"], cpuinfo["flags"], cpuinfo["bugs"]) if precheck.shouldread("/proc/meminfo"): detail += detailheader("RAM information") with open("/proc/meminfo") as f: info = f.readlines() for item in info: if ":" in item: name = item.split(":")[0].strip() data = item.split(":")[1].strip() if "memtotal" in name.lower(): meminfo["memtotal"] = data if "swaptotal" in name.lower(): meminfo["swaptotal"] = data summ += " |__Memory: {}\n |__SWAP: {}\n".format(meminfo["memtotal"], meminfo["swaptotal"]) detail += "Memory: {}\nSWAP: {}\n".format(meminfo["memtotal"], meminfo["swaptotal"]) return summ, detail, cpuinfo, meminfo
def getgeneralinfo(report, precheck): # Get hardware reports try: report.log("DEBUG", "CPU and RAM information gathering started") summ, detail, cpuinfo, meminfo = _gethardware(precheck) report.summarized(1, summ) report.detailed(1, detail) report.cpuinfo = cpuinfo report.meminfo = meminfo report.log("DEBUG", "CPU and RAM information completed") except Exception as e: report.log("ERROR", "Can't obtain CPU and RAM information") report.log("DEBUG", str(e)) report.log("DEBUG", format_exc()) try: report.log("DEBUG", "USB information gathering started") summ, detail, total = _getusb() report.summarized(1, summ) report.detailed(1, detail) report.total = total report.log("DEBUG", "USB information completed") except Exception as e: report.log("ERROR", "Can't obtain usb information") report.log("DEBUG", str(e)) report.log("DEBUG", format_exc()) # Get OS reports try: report.log("DEBUG", "Kernel information gathering started") summ, detail, data = _getos() report.summarized(1, summ) report.detailed(1, detail) report.oskernel = data report.log("DEBUG", "Kernel information completed") except Exception as e: report.log("ERROR", "Can't obtain OS uname information") report.log("DEBUG", str(e)) report.log("DEBUG", format_exc()) try: report.log("DEBUG", "Distribution release information gathering started") summ, detail, data = _getdistrorelease(precheck) report.summarized(1, summ) report.detailed(1, detail) report.osdistro = data report.log("DEBUG", "Distribution release information completed") except Exception as e: report.log("ERROR", "Can't obtain distribution release information") report.log("DEBUG", str(e)) report.log("DEBUG", format_exc()) try: report.log("DEBUG", "libc information gathering started") summ, detail = _getlibc() report.summarized(1, summ) report.detailed(1, detail) report.log("DEBUG", "libc information completed") except Exception as e: report.log("ERROR", "Can't obtain libc information") report.log("DEBUG", str(e)) report.log("DEBUG", format_exc()) # Get software reports try: report.log("DEBUG", "Software packages gathering started") summ = "\nPackages manager not found\n" if precheck.checkcommand("yum"): precheck.packages = _getyum() summ = "\nTotal RPM packages (yum):\n |__{}\n".format(len(precheck.packages)) elif precheck.checkcommand("dpkg-query"): precheck.packages = _getdpkg() summ = "\nTotal DEB packages (dpkg):\n |__{}\n".format(len(precheck.packages)) elif precheck.checkcommand("zypper"): precheck.packages = _getzypper() summ = "\nTotal RPM packages (zypper):\n |__{}\n".format(len(precheck.packages)) elif precheck.checkcommand("apt"): precheck.packages = _getapt() summ = "\nTotal DEB packages (apt):\n |__{}\n".format(len(precheck.packages)) elif precheck.checkcommand("pacman"): precheck.packages = _getpacman() summ = "\nTotal pkg.tar.xz packages (pacman):\n |__{}\n".format(len(precheck.packages)) report.summarized(1, summ) report.detailed(1, detailheader("Packages information")) for item in precheck.packages: report.detailed(1, "{:32s} - {}\n".format(item[0], item[1])) report.log("DEBUG", "Software packages information completed") except Exception as e: report.log("ERROR", "Can't obtain software packages information") report.log("DEBUG", str(e)) report.log("DEBUG", format_exc()) # Get filesystem reports try: report.log("DEBUG", "disk information gathering started") report.disks, report.unmounted, report.mounted = _getdisks(precheck) summ = "\nPartitions mounted:\n" for item in report.mounted: if "swap" in item[2].lower(): summ += " |__{:_<32}__SWAP filesystem with {}\n".format(item[2], item[1]) else: summ += " |__{:_<32}__{} filesystem with {}, used {}\n".format(item[2], item[3], item[1], item[5]) report.summarized(1, summ) detail = detailheader("Disk/Partitions information") detail += detailfile("Disks info:") for item in report.disks: detail += "{:32s} - Size: {}\n".format(item[0], item[1]) detail += detailfile("Unmounted partitions:") for item in report.unmounted: detail += "{:32s} - Size: {}\n".format(item[0], item[1]) detail += detailfile("Mounted partitions:") for item in report.mounted: detail += "\n{:32s}\n |__{}\n".format(item[0], item[2]) if "swap" in item[2].lower(): detail += " |__Size: {}\n".format(item[1]) else: detail += " |__Filesystem: {}\n |__Size: {}, used {}\n".format(item[3], item[1], item[5]) detail += " |__Options: {}\n".format(item[4]) report.detailed(1, detail) report.log("DEBUG", "disk information completed") except Exception as e: report.log("ERROR", "Can't obtain disk information") report.log("DEBUG", str(e)) report.log("DEBUG", format_exc()) try: report.log("DEBUG", "File and directory permission information gathering started") print("\naridy.py could search the filesystem in order to locate directories with no " "StickyBit and all users write permission, or files with SUID or GUID, but " "it could be very slow. Do you want to proceed? (y/N) ", end="") ans = str(input()).lower().lstrip() if len(ans) == 0 or 'y' not in ans[0]: return stickydirs, alluserwrite, readerrors, suidperm, guidperm = _checkpermissions(precheck, report) report.stickydirs = stickydirs report.alluserwrite = alluserwrite report.readerrors = readerrors report.suidperm = suidperm report.guidperm = guidperm report.detailed(1, detailheader("File/Dir information")) report.summarized(1, "\nFile and directories information:\n") report.detailed(1, "File and directories information:\n") report.summarized(1, " |__StickyBit: Found {} dirs with all users write " "permission and no stickybit\n".format(len(stickydirs))) report.detailed(1, " |__StickyBit: Found {} dirs with all users write permission and " "no stickybit.\n | You should put the sticky bit in order to avoid " "any user can modify files\n | of other " "users\n".format(len(stickydirs))) report.summarized(1, " |__All users can write: Found {} files with all " "users write permission\n".format(len(alluserwrite))) report.detailed(1, " |__All users can write: Found {} files with all users write " "permission.\n | Is it necessary?\n".format(len(alluserwrite))) report.summarized(1, " |__Read errors: Found {} files or directories with " "errors\n".format(len(readerrors))) report.detailed(1, " |__Read errors: Found {} files or directories with errors. There " "are\n | possible bad links, maybe you want to delete " "them\n".format(len(readerrors))) report.summarized(1, " |__SUID: Found {} files with SUID " "permission\n".format(len(suidperm))) report.detailed(1, " |__SUID: Found {} files with SUID permission. Are they " "necessary?\n".format(len(suidperm))) report.summarized(1, " |__GUID: Found {} files with GUID " "permission\n".format(len(guidperm))) report.detailed(1, " |__GUID: Found {} files with GUID permission. Are they " "necessary?\n".format(len(guidperm))) try: f = open("aridi.badfiles", "w") for item in stickydirs: f.write("'{}' dir has write permission for all user and " "no sticky bit\n".format(item)) for item in alluserwrite: f.write("'{}' file has write permission for all user\n".format(item)) for item in readerrors: f.write("{}\n".format(item)) for item in suidperm: if item[1]: f.write("'{}' file has SUID and it's owned by the root user\n".format(item[0])) else: f.write("'{}' file has SUID. Is it necessary?\n".format(item[0])) for item in guidperm: if item[1]: f.write("'{}' file has GUID and it's owned by the root group\n".format(item[0])) else: f.write("'{}' file has GUID. Is it necessary?\n".format(item[0])) except Exception as e: report.log("ERROR", "Can't write aridy.badfiles") report.log("DEBUG", str(e)) report.log("DEBUG", format_exc()) finally: f.close() report.log("DEBUG", "File and directory permission information completed") except Exception as e: report.log("ERROR", "Can't obtain file and directory permission information") report.log("DEBUG", str(e)) report.log("DEBUG", format_exc())
def _getlibc(): summ = "\nLibc version:\n |__{} {}\n".format(libc_ver()[0], libc_ver()[1]) detail = detailheader("Libc information") detail += "{} {}\n".format(libc_ver()[0], libc_ver()[1]) return summ, detail
def _getdistrorelease(precheck): name = '' version = '' filename = '' data = '' summ = '\nOS Release information:\n' detail = detailheader("OS Release information") # this is the current systemd version info if precheck.shouldread('/etc/os-release'): lines = open('/etc/os-release').read().split('\n') detail += detailfile('/etc/os-release') for line in lines: detail += line + "\n" if line.startswith('NAME='): name = line.split('=')[1] if name[0] == '"' and name[-1] == '"': name = name[1:-1] if line.startswith('VERSION='): version = line.split('=')[1] if version[0] == '"' and version[-1] == '"': version = version[1:-1] data = name + " " + version summ += " |__{}\n".format(data) # and now, the other release info files elif precheck.shouldread('/etc/centos-release'): filename = '/etc/centos-release' elif precheck.shouldread('/etc/lsb-release'): lines = open('/etc/lsb-release').read().split('\n') detail += detailfile('/etc/lsb-release') for line in lines: detail += line + "\n" if line.startswith('DISTRIB_ID='): name = line.split('=')[1] if name[0] == '"' and name[-1] == '"': name = name[1:-1] if line.startswith('DISTRIB_RELEASE='): version = line.split('=')[1] if version[0] == '"' and version[-1] == '"': version = version[1:-1] data = name + " " + version summ += " |__{}\n".format(data) elif precheck.shouldread('/suse/etc/SuSE-release'): filename = '/suse/etc/SuSE-release' elif precheck.shouldread('/etc/redhat-release'): filename = '/etc/redhat-release' elif precheck.shouldread('/etc/fedora-release'): filename = '/etc/fedora-release' if filename: name = open(filename).read() data = name.split('\n')[0] summ += " |__{}\n".format(data) detail += filename + '-'*len(filename) + name + "\n" # check old distribution version info if precheck.shouldread('/etc/debian-version'): other_version = open('/etc/debian-version').read() summ += " |__Debian version: " + other_version.split('\n')[0] + "\n" detail += detailfile('/etc/debian-version') detail += other_version + "\n" elif precheck.shouldread('/etc/slackware-version'): other_version = open('/etc/slackware-version').read() summ += " |__Slackware version: " + other_version.split('\n')[0] + "\n" detail += detailfile('/etc/slackware-version') detail += other_version + "\n" return summ, detail, data
def _getdisk(precheck, report): detail = detailheader("Disk status information") summ = "\nDisk status:\n" detail += "Disk load:\n" disknames = {} for item in listdir("/sys/block"): name = None for root, dirs, files in walk("/sys/block/{}".format(item)): if files: if "name" in files: with open("{}/name".format(root)) as f: name = f.read() if name: disknames[name.strip()] = item if precheck.shouldread("/proc/diskstats"): with open("/proc/diskstats") as f: info = f.readlines() if not report.disks: report.disks, report.unmounted, report.mounted = _getdisks( precheck) diskstat = {} for item in info: item = " ".join(item.split()).split(" ") name = item[2] readsectors = int(item[5]) readtime = int(item[6]) writesectors = int(item[9]) writetime = int(item[10]) diskstat[name] = [readsectors, readtime, writesectors, writetime] sleep(1) with open("/proc/diskstats") as f: info = f.readlines() for item in info: item = " ".join(item.split()).split(" ") name = item[2] readsectors = int(item[5]) readtime = int(item[6]) writesectors = int(item[9]) writetime = int(item[10]) diskstat[name] = [ readsectors - diskstat[name][0], readtime - diskstat[name][1], writesectors - diskstat[name][2], writetime - diskstat[name][3] ] for item in report.mounted: if item[5]: total = float(".".join(re.findall(r'\d+', item[1]))) used = float(".".join(re.findall(r'\d+', item[5]))) usedratio = round(used * 100 / total) else: usedratio = 0 if item[0] in diskstat: summ += " |__{} ({}): {} % read and {} " \ "% write load. Used {}%\n".format(item[0], item[2], diskstat[item[0]][1] / 1000, diskstat[item[0]][3] / 1000, usedratio) detail += " |__{} ({}):\n".format(item[0], item[2]) detail += " | |__ {} total size\n".format(item[1]) detail += " | |__ {} used size\n".format(item[5]) detail += " | |__ {} read sectors/sec\n".format( diskstat[item[0]][0]) detail += " | |__ {} write sectors/sec\n".format( diskstat[item[0]][2]) detail += " | |__ {} % load reading\n".format( diskstat[item[0]][1] / 1000) detail += " | |__ {} % load writing\n".format( diskstat[item[0]][3] / 1000) else: newname = disknames.get(item[0], None) if newname and newname in diskstat: summ += " |__{} ({}): {} % read and {} " \ "% write load. Used {}%\n".format(item[0], item[2], diskstat[newname][1] / 1000, diskstat[newname][3] / 1000, usedratio) detail += " |__{} ({}):\n".format(item[0], item[2]) detail += " | |__ {} total size\n".format(item[1]) detail += " | |__ {} used size\n".format(item[5]) detail += " | |__ {} read sectors/sec\n".format( diskstat[newname][0]) detail += " | |__ {} write sectors/sec\n".format( diskstat[newname][2]) detail += " | |__ {} % load reading\n".format( diskstat[newname][1] / 1000) detail += " | |__ {} % load writing\n".format( diskstat[newname][3] / 1000) if precheck.shouldread("/proc/sys/fs/file-nr"): with open("/proc/sys/fs/file-nr") as f: data = f.read() filenr = data.split()[0] filemax = data.split()[2] summ += " |__{} allocated file handles of a max of {}\n".format( filenr, filemax) detail += " |__{} allocated file handles of a max of {}\n".format( filenr, filemax) if precheck.shouldread("/proc/sys/fs/inode-nr"): with open("/proc/sys/fs/inode-nr") as f: inodenr = f.read().split()[0] summ += " |__{} allocated inodes\n".format(inodenr) detail += " |__{} allocated inodes\n".format(inodenr) return summ, detail
def _getnetinfo(report, precheck): detail = detailheader("Network information") # Check hosts ipv4 in /etc/hosts if precheck.shouldread('/etc/hosts'): detail += detailfile("/etc/hosts") readhost = open('/etc/hosts').readlines() for item in readhost: item = " ".join(item.split()) if len(item) > 0: if not item.startswith('#') and ":" not in item: ip = ip_address(item.split(" ")[0]) detail += "{:>15} - {}\n".format(str(ip), item.split(" ")[1]) report.infrastructure(ip, "HOSTNAME {}".format(item.split(" ")[1])) interfaces = {} if precheck.checkcommand("ip"): # Get interfaces output = check_output(["ip", "-o", "link"], stderr=DEVNULL).decode("utf-8").splitlines() for line in output: iface = line.split(":")[1].strip() mac = line.split("link")[1].split(" ")[1] interfaces[iface] = [mac] # Get interfaces address output = check_output(["ip", "-o", "address"], stderr=DEVNULL).decode("utf-8").splitlines() for line in output: line = " ".join(line.split()).split(" ") if line[2] == "inet": interfaces[line[1]] = [interfaces[line[1]][0], line[3]] report.ifaces = interfaces # Prepare the report for ifaces detail += detailfile("Interfaces") detail += " IFACE MAC ADDRESS IP ADDRESS/MASK\n" summ = '\nNetwork Information:\n' for item in interfaces: if len(interfaces[item]) > 1: detail += "{:>15s} {:17s} {}\n".format(item, interfaces[item][0], interfaces[item][1]) summ += " |__Iface {} ({}) with ip address {}.\n".format(item, interfaces[item][0], interfaces[item][1]) report.infrastructure(ip_address(interfaces[item][1].split("/")[0]), "Local machine") else: detail += "{:>15s} {:17s}\n".format(item, interfaces[item][0]) summ += " |__Iface {} ({}) without ip address.\n".format(item, interfaces[item][0]) # Get routes if precheck.shouldread("/proc/net/route"): detail += detailfile("Routes information") summ += ' |__Network routes:\n' with open("/proc/net/route") as f: info = f.readlines() for item in info[1:]: item = " ".join(item.split()).split(" ") iface = item[0] destination = converthex2ip(item[1]) gateway = converthex2ip(item[2]) mask = str(bin(int(item[7], 16)))[2:].count("1") summ += " | |__Destination: {:>15}/{:0<2} - " \ "Gateway: {:15} vía {}\n".format(destination, mask, gateway, iface) detail += "Destination: {:>15}/{:0<2} - Gateway: {:15} vía {}\n".format(destination, mask, gateway, iface) report.routes.append([destination, mask, gateway, iface]) detail += detailfile("Other information") # Get DNS if precheck.shouldread("/etc/resolv.conf"): detail += "DNS:\n" with open("/etc/resolv.conf") as f: info = f.readlines() for item in info: item = " ".join(item.split()).split(" ") if item[0].lower() == "nameserver": detail += " |__{}\n".format(item[1]) if len(report.dns) > 0: summ += " | |__{}\n".format(item[1]) else: summ += " |__DNS:\n | |__{}\n".format(item[1]) report.dns.append(item[1]) report.infrastructure(precheck.nslookup(item[1]), "DNS Server") if item[1] == "127.0.1.1": report.infrastructure(ip_address(item[1]), "Local machine") summ += " o\n" # Get NTP if precheck.shouldread("/etc/ntp.conf") or precheck.shouldread("/etc/xntp.conf"): detail += "NTP:\n" if precheck.shouldread("/etc/ntp.conf"): with open("/etc/ntp.conf") as f: info = f.readlines() else: with open("/etc/xntp.conf") as f: info = f.readlines() for item in info: item = " ".join(item.split()).split(" ") if item[0].lower() == "server": detail += " |__SERVER {}\n".format(item[1]) if len(report.dns) > 0: summ += " | |__{}\n".format(item[1]) else: summ += " |__NTP:\n | |__{}\n".format(item[1]) report.ntp.append(item[1]) report.infrastructure(precheck.nslookup(item[1]), "NTP Server") if item[0].lower() == "restrict": detail += " |__CLIENT {}\n".format(item[1]) report.infrastructure(precheck.nslookup(item[1]), "NTP Client") summ += " o\n" return summ, detail
def _getcpu(precheck): detail = detailheader("CPU information") summ = "\nCPU load average/Uptime:\n" detail += "Uptime:\n" summ += " | |__{} up\n".format( timedelta(seconds=int(uptime))) detail += " |__{} up\n".format(timedelta(seconds=int(uptime))) if precheck.shouldread("/proc/loadavg"): with open("/proc/loadavg") as f: info = f.read().split() summ += " |__{} 1 min, {} 5 min, {} 15 min\n".format( info[0], info[1], info[2]) detail += "\nLoad average:\n" detail += " |__{} 1 min, {} 5 min, {} 15 min\n".format( info[0], info[1], info[2]) if precheck.shouldread("/proc/stat"): with open("/proc/stat") as f: info = f.read().splitlines() info = info[0].split() usermode = int(info[1]) nicemode = int(info[2]) kernelmode = int(info[3]) idle = int(info[4]) iowait = int(info[5]) irq = int(info[6]) softirq = int(info[7]) usertime = usermode + nicemode irqtime = irq + softirq totaltime = usertime + kernelmode + idle + iowait + irqtime peruser = round(100 * usertime / totaltime, 2) perkernel = round(100 * kernelmode / totaltime, 2) peridle = round(100 * idle / totaltime, 2) periow = round(100 * iowait / totaltime, 2) perirq = round(100 * irqtime / totaltime, 2) summ += " |__Since boot: {}% user, {}% kernel, {}% IO wait, {}% IRQ time, " \ "{}% idle\n".format(peruser, perkernel, periow, perirq, peridle) detail += "\n% CPU:\n" detail += " |__Since boot: {}% user, {}% kernel, {}% IO wait, {}% IRQ time, " \ "{}% idle\n".format(peruser, perkernel, periow, perirq, peridle) sleep(1) with open("/proc/stat") as f: info = f.read().splitlines() info = info[0].split() usermode = int(info[1]) - usermode nicemode = int(info[2]) - nicemode kernelmode = int(info[3]) - kernelmode idle = int(info[4]) - idle iowait = int(info[5]) - iowait irq = int(info[6]) - irq softirq = int(info[7]) - softirq usertime = usermode + nicemode irqtime = irq + softirq totaltime = usertime + kernelmode + idle + iowait + irqtime peruser = round(100 * usertime / totaltime, 2) perkernel = round(100 * kernelmode / totaltime, 2) peridle = round(100 * idle / totaltime, 2) periow = round(100 * iowait / totaltime, 2) perirq = round(100 * irqtime / totaltime, 2) summ += " |__Now: {}% user, {}% kernel, {}% IO wait, {}% IRQ time, " \ "{}% idle\n".format(peruser, perkernel, periow, perirq, peridle) detail += " |__Now: {}% user, {}% kernel, {}% IO wait, {}% IRQ time, " \ "{}% idle\n".format(peruser, perkernel, periow, perirq, peridle) return summ, detail
def _getiptables(report, precheck): # Root is necesary if not precheck.root or not precheck.checkcommand("iptables"): return "", "" detail = detailheader("IPTables information") summ = "\nIPTables information\n" output = check_output(["iptables", "-S"], stderr=DEVNULL).decode("utf-8").splitlines() for item in output: if item.startswith("-P"): item = " ".join(item.split()).split(" ") report.iptables[item[1]] = ["DEFAULT {}".format(item[2])] elif item.startswith("-A") and "ACCEPT" in item: item = " ".join(item.split()).split(" ") if item[1] == "INPUT": ip = None port = None prot = None rule = None for option in range(len(item)): if item[option] == "-s": ip = item[option+1] elif item[option] == "--dport": port = item[option+1] elif item[option] == "-p": prot = item[option+1] elif item[option] == "-j": rule = item[option+1] content = "" if port or prot or ip: if rule: content += "{} ".format(rule) if ip: content += ip if re.fullmatch("\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/32", ip) \ and rule == "ACCEPT": ip = ip_address(ip[:-3]) report.infrastructure(ip, "IPTables allowed input IP") if port and prot: report.infrastructure(ip, "Consumer from local " "port {} ({})".format(port,prot)) elif port: report.infrastructure(ip, "Consumer from local " "port {}".format(port)) elif prot: report.infrastructure(ip, "Consumer only protocol {}".format(prot)) if port: content += ":{}".format(port) if prot: content += "({})".format(prot) report.iptables["INPUT"].append(content) elif item[1] == "OUTPUT": ip = None port = None prot = None rule = None for option in range(len(item)): if item[option] == "-d": ip = item[option+1] elif item[option] == "--dport": port = item[option+1] elif item[option] == "-p": prot = item[option+1] elif item[option] == "-j": rule = item[option+1] content = "" if port or prot or ip: if rule: content += "{} ".format(rule) if ip: content += ip if re.fullmatch("\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/32", ip) \ and rule == "ACCEPT": ip = ip_address(ip[:-3]) report.infrastructure(ip, "IPTables allowed output IP") if port and prot: report.infrastructure(ip, "Service in port {} ({})".format(port, prot)) elif port: report.infrastructure(ip, "Service in port {}".format(port)) elif prot: report.infrastructure(ip, "Service only protocol {}".format(prot)) if port: content += ":{}".format(port) if prot: content += "({})".format(prot) report.iptables["OUTPUT"].append(content) if report.iptables["INPUT"]: detail += "\nINPUT:\n" summ += " |__INPUT:\n" for item in report.iptables["INPUT"]: detail += " |__{}\n".format(item) summ += " | |__{}\n".format(item) if report.iptables["FORWARD"]: detail += "\nFORWARD:\n" summ += " |__FORWARD:\n" for item in report.iptables["FORWARD"]: detail += " |__{}\n".format(item) summ += " | |__{}\n".format(item) if report.iptables["OUTPUT"]: detail += "\nOUTPUT:\n" summ += " |__OUTPUT:\n" for item in report.iptables["OUTPUT"]: detail += " |__{}\n".format(item) summ += " |__{}\n".format(item) return summ, detail
def _getnetdata(precheck, report): detail = detailheader("Network live information") summ = "\nNetwork connections:\n" detail += "\nTCP Connections:\n" tcpconnections = [] udpconnections = [] if precheck.shouldread("/proc/net/tcp"): with open("/proc/net/tcp") as f: info = f.readlines() for item in info[1:]: item = item.strip().split() localip, localport = converthex2ipport(item[1]) remoteip, remoteport = converthex2ipport(item[2]) constate = tcpstate[int(item[3], 16)] uid = int(item[7]) inode = int(item[9]) tcpconnections.append([ localip, localport, remoteip, remoteport, constate, report.pidusers[uid], inode ]) if precheck.shouldread("/proc/net/udp"): with open("/proc/net/udp") as f: info = f.readlines() for item in info[1:]: item = item.strip().split() localip, localport = converthex2ipport(item[1]) remoteip, remoteport = converthex2ipport(item[2]) constate = tcpstate[int(item[3], 16)] uid = int(item[7]) inode = int(item[9]) udpconnections.append([ localip, localport, remoteip, remoteport, constate, report.pidusers[uid], inode ]) for item in listdir("/proc"): try: if re.findall(r'\d+', item): for directory in listdir("/proc/{}/fd".format(item)): try: for counter, data in enumerate(tcpconnections): name = "[{}]".format(data[6]) if name in readlink("/proc/{}/fd/{}".format( item, directory)): tcpconnections[counter].append( process[int(item)][0]) tcpconnections[counter].append( process[int(item)][7]) except: pass try: for counter, data in enumerate(udpconnections): name = "[{}]".format(data[6]) if name in readlink("/proc/{}/fd/{}".format( item, directory)): udpconnections[counter].append( process[int(item)][0]) udpconnections[counter].append( process[int(item)][7]) except: pass except: pass tcplisten = 0 tcpestablished = 0 tcpwait = 0 listenports = [] localmachine = [] for item in report.ifaces: if len(report.ifaces[item]) > 1: localmachine.append(report.ifaces[item][1].split("/")[0]) for item in tcpconnections: if len(item) > 7: servicename = item[7] else: servicename = "unknown" if precheck.portnames: portname = precheck.portnames.get(int( item[1]), ["Unknown service", "Unknown service"]) portnam2 = precheck.portnames.get(int( item[3]), ["Unknown service", "Unknown service"]) else: portname = ["Unknown service", "Unknown service"] portnam2 = ["Unknown service", "Unknown service"] if item[4] == tcpstate[10]: tcplisten += 1 listenports.append(item[1]) if not item[0] == "0.0.0.0": report.infrastructure( ip_address(item[0]), "Port TCP {} ({}) with service {}".format( item[1], portname[0], servicename)) else: for address in localmachine: report.infrastructure( ip_address(address), "Port TCP {} ({}) with service {}".format( item[1], portname[0], servicename)) elif item[4] == tcpstate[1]: tcpestablished += 1 if item[1] in listenports: report.infrastructure( ip_address(item[2]), "Connected in port {} ({}) of local" " ip {}".format(item[1], portname[0], item[0])) else: report.infrastructure( ip_address(item[2]), "Connected at port {} ({}) from local" " ip {}".format(item[3], portnam2[0], item[0])) elif item[4] == tcpstate[8]: tcpwait += 1 if item[1] in listenports: report.infrastructure( ip_address(item[2]), "Connected in port {} ({}) of local " "ip {}".format(item[1], portnam2[0], item[0])) else: report.infrastructure( ip_address(item[2]), "Connected at port {} ({}) from local " "ip {}".format(item[3], portnam2[0], item[0])) if len(item) > 7: detail += " |__{:<21} - {:<21} {:<12} {:<10} {:<12}\n".format( item[0] + ":" + item[1], item[2] + ":" + item[3], item[4], item[5][:10], servicename) detail += " | |__{}\n".format(item[8][:70]) else: detail += " |__{:<21} - {:<21} {:<12} {:<10}\n".format( item[0] + ":" + item[1], item[2] + ":" + item[3], item[4], item[5]) summ += " |__{} TCP listen ports {}\n".format(tcplisten, listenports) summ += " |__{} TCP established connections\n".format(tcpestablished) summ += " |__{} TCP sockets in close waiting\n".format(tcpwait) udplisten = 0 udpestablished = 0 udpwait = 0 listenports = [] detail += " O\n\nUDP Connections:\n" for item in udpconnections: if item[4] == tcpstate[10]: udplisten += 1 listenports.append(item[1]) elif item[4] == tcpstate[1]: udpestablished += 1 elif item[4] == tcpstate[8]: udpwait += 1 if len(item) > 7: detail += " |__{:<21} - {:<21} {:<12} {:<10} {:<12}\n".format( item[0] + ":" + item[1], item[2] + ":" + item[3], item[4], item[5][:10], item[7]) detail += " | |__{}\n".format(item[8][:70]) else: detail += " |__{:<21} - {:<21} {:<12} {:<10}\n".format( item[0] + ":" + item[1], item[2] + ":" + item[3], item[4], item[5]) detail += " O\n" summ += " |__{} UDP listen ports {}\n".format(udplisten, listenports) summ += " |__{} UDP established connections\n".format(udpestablished) summ += " |__{} UDP sockets in close waiting\n".format(udpwait) return summ, detail
def _getetc(report): detail = detailheader("/etc information") summ = "\n/etc information:\n" # Percentage calculate dirs = ['/etc/' + x for x in listdir("/etc") if isdir("/etc/" + x)] total = len(dirs) ipscounter = 0 detail += "\nIP found:\n" for root, dir, file in walk("/etc"): if root in dirs: dirs.remove(root) percentagebar(total, total - len(dirs)) for item in file: if not "dhcpd" in item: try: f = open(root + "/" + item, "r") content = f.readlines() f.close() for line in content: ips = re.findall("\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}", line) ips2 = ips.copy() for data in ips2: try: socket.inet_aton(data) if data.startswith("169.254"): ips.remove(data) elif int(data.split(".")[0]) > 223 or int( data.split(".")[0]) == 0: ips.remove(data) elif int(data.split(".")[3]) == 0: ips.remove(data) elif line.split(data)[1].startswith("/") and \ not line.split(data)[1].startswith("/32"): ips.remove(data) elif re.match("[\d.]", line.split(data)[1][0]): ips.remove(data) elif len(line.split(data)[0]) > 0: if re.match("[\d.]", line.split(data)[0][-1]): ips.remove(data) except socket.error: ips.remove(data) if ips: if not re.match("[#;]", line.split(ips[0])[0]) and \ not "version" in line.split(ips[0])[0].lower(): line = " ".join(line.strip().split()) for data in ips: detail += " |__{} named in file '{}/{}'\n".format( data, root, item) report.infrastructure( ip_address(data), "Named in file '{}/{}' " "({})".format(root, item, line)) ipscounter += 1 except: pass percentagebar(total, total) summ += " |__{} ips found in /etc directory\n".format(ipscounter) return summ, detail