def publish(self, timeline, kind, des, root_cause, suggestion, activities, icon, introduction, score): ueba = Kdatabase().get_obj("ueba") threat_id = Krandom().purely(16) threat = { "kind": kind, "timeline": timeline, "resolved": False, "resolved_ts": -1, "unread": True, "read_ts": -1, "description": des, "root_cause": root_cause, "suggestion": suggestion, "activities": activities, "icon": icon, "introduction": introduction, "ts": time_op.now(), "score": score } ueba["lasttime"] = time_op.now() ueba["storys"][threat_id] = threat Kdatabase().dump("ueba") threat["description"] = Klanguage().decode_ts(threat["description"]) threat["root_cause"] = Klanguage().decode_ts(threat["root_cause"]) threat["suggestion"] = Klanguage().decode_ts(threat["suggestion"]) KCybertek().publish_threat(threat_id, threat) print(threat) print("KUEBA timeline add one!")
def check_selinux(self): selinux_config = "/etc/selinux/config" selinux_root = ["/sys/fs/selinux", "/selinux"] mode = ["disabled", "permissive", "enforcing"] level = [ macro.BASELINE_LEVEL["MEDIUM"], macro.BASELINE_LEVEL["LOW"], macro.BASELINE_LEVEL["SECURITY"] ] suggest = [ Klanguage().to_ts(1189), Klanguage().to_ts(1190), Klanguage().to_ts(1191) ] if os.path.exists(selinux_config): with open(selinux_config, "r") as f: for line in f.readlines(): if line: if line.startswith("#"): continue if "=" in line: key, value = line.split("=") value = value.strip() if value in mode: return value, level[mode.index( value)], suggest[mode.index(value)] return mode[0], level[0], suggest[0]
def run(payload, socket): response = { "cmd_id" : payload["cmd_id"], "session_id" : payload["args"]["session_id"], "error" : "" } ueba = Kdatabase().get_obj("ueba") for key, story in ueba["storys"].items(): if key == payload["args"]["key"]: response["ueba"] = { "key" : key, "description" : Klanguage().decode_ts(story["description"]), "root_cause" : Klanguage().decode_ts(story["root_cause"]), "suggestion" : Klanguage().decode_ts(story["suggestion"]), "timeline" : translate(story["timeline"]), "unread" : story["unread"], "resolved" : story["resolved"], "resolved_ts" : story["resolved_ts"] } story["unread"] = False story["read_ts"] = time_op.now() Kdatabase().dump("ueba") break socket.response(response)
def run(payload, socket): response = { "cmd_id": payload["cmd_id"], "session_id": payload["args"]["session_id"], "error": "" } if payload["args"]["user_id"] != Kdatabase().get_obj( 'setting')["username"]: response["error"] = Klanguage().to_ts(4007) socket.response(response) return with Kcleaner().get_lock(): total_failed, total_size = clean(payload["args"]["items"], socket, payload["args"]["session_id"]) if total_failed + total_size > 0: prompt = "{} {}".format(common.size_human_readable(total_size), Klanguage().to_ts(1830)) ''' if total_failed > 0: response["error"] = "{}, {}".format(prompt, Klanguage().to_ts(1831)) else: response["prompt"] = prompt ''' response["prompt"] = prompt else: response["error"] = Klanguage().to_ts(4006) socket.response(response)
def check_need_reboot(response): #linux-image-4.4.0-96-generic #linux-base pkgs = "/var/run/reboot-required.pkgs" #*** System restart required *** reboot = "/var/run/reboot-required" values = [["Packages"]] exists_pkgs = [] if os.path.exists(reboot) and os.path.exists(pkgs): response["kernel"].append({ "name": Klanguage().to_ts(1164), "value": "Yes" }) data = file_op.cat(pkgs, "r") if data: lines = data.split("\n") for line in lines: if line: if line not in exists_pkgs: values.append([line]) exists_pkgs.append(line) if len(values) > 1: response["kernel"].append({ "name": Klanguage().to_ts(1158), "values": values })
def kernel_available_version(response): available_kernel = "" if common.check_programs_installed("yum"): data, success, retcode = common.exec_command( ["yum", "list", "updates", "kernel"]) if success: lines = data.split("\n") begin_pattern = re.compile(r"^Available Upgrades") begin_pattern2 = re.compile(r"^Updated Packages") begin_pattern3 = re.compile(r"^Upgraded Packages") is_begin = False for line in lines: if not is_begin: if begin_pattern.match(line) or begin_pattern2.match( line) or begin_pattern3.match(line): is_begin = True continue else: result = line.split() if len(result) == 3: available_kernel = result[1] break elif common.check_programs_installed("apt-cache"): data, success, retcode = common.exec_command( ["apt-cache", "search", "linux-image"]) if success: lines = data.split("\n") pattern = re.compile(r"^linux-image-([\d\.]+)-(\d*)-") kernel_versions = [] for line in lines: match = pattern.match(line.strip()) if match and len(match.groups()) == 2: kernel_versions.append(match.groups()) kernel_versions.sort(key=lambda v: "".join( x.zfill(5) for x in v[0].split(".") + [v[1]]), reverse=True) if len(kernel_versions): available_kernel = "-".join(kernel_versions[0]) response["kernel"].append({ "name": Klanguage().to_ts(1129), "value": platform.release() }) if available_kernel: response["kernel"].append({ "name": Klanguage().to_ts(1130), "value": available_kernel })
def is_smep_enable(): suggest = Klanguage().to_ts(1197) if os.path.exists("/proc/cpuinfo"): with open("/proc/cpuinfo") as f: if "smep" in f.read(): return Klanguage().to_ts(1120), LEVEL_SECURITY, suggest return Klanguage().to_ts(1121), LEVEL_WARNING, suggest
def is_smep_enable(self): suggest = Klanguage().to_ts(1197) if os.path.exists("/proc/cpuinfo"): with open("/proc/cpuinfo") as f: if "smep" in f.read(): return Klanguage().to_ts( 1120), macro.BASELINE_LEVEL["SECURITY"], suggest return Klanguage().to_ts(1121), macro.BASELINE_LEVEL["LOW"], suggest
def check_magickey_configuration(response): magickey = "/proc/sys/kernel/sysrq" if os.path.exists(magickey): data_magickey = file_op.cat(magickey, "r") response["kernel"].append({ "name": Klanguage().to_ts(1133), "value": Klanguage().to_ts(1121) if data_magickey == "0" else Klanguage().to_ts(1120) })
def publish(self, *args, **kwargs): proc_info = args[0] ip_report = args[1] KUEBA_timeline().publish( [{ "kind": macro.EVENTS["MALWARE_PROC_DETAIL"], "extra": proc_info, "des": Klanguage().encode_ts(5009), "time": proc_info["create_time"], "title": Klanguage().encode_ts(5010), "distro": common.get_distribution(), "hostname": platform.node(), }, { "kind": macro.EVENTS["MALICIOUS_IP_REPORT"], "extra": ip_report, "des": Klanguage().encode_ts(5011), "time": time_op.now(), "title": Klanguage().encode_ts(5012), "distro": common.get_distribution(), "hostname": platform.node(), }], macro.STORY_KIND["CC"], Klanguage().encode_ts( 5013, str(datetime.fromtimestamp(proc_info["create_time"]))), Klanguage().encode_ts(5014, ip_report["ip"]), Klanguage().encode_ts(5015), [macro.ACTIVITY["10003"]], macro.SUB_STORY_KIND["1002"][0], [ macro.SUB_STORY_KIND["1002"][1], proc_info["exe"], Klanguage().encode_ts(5014, ip_report["ip"]) ], macro.SCORE["VULNERABLE"])
def get_system_info(response): system_info = response["system_info"] system_info.append({ Klanguage().to_ts(1024): "{}/{}".format(get_windows_product_info(), platform.machine()) }) system_info.append({Klanguage().to_ts(1025): common.get_distribution()}) system_info.append({ Klanguage().to_ts(1027): time_op.timestamp2string(psutil.boot_time()) }) system_info.append( {Klanguage().to_ts(1028): time_op.timestamp2string(time.time())})
def get_hardware_info(response): pythoncom.CoInitialize() win32 = wmi.WMI() hardware = response["hardware"] hardware.append({Klanguage().to_ts(1011): [get_cpu_info()]}) #hardware.append({'Memory' : [""]}) hardware.append({Klanguage().to_ts(1016): get_disk_partition(win32)}) hardware.append({Klanguage().to_ts(1017): [get_bios_info()]}) hardware.append({Klanguage().to_ts(1013): get_gpu_info(win32)}) hardware.append({Klanguage().to_ts(1012): get_network_card_info()}) pythoncom.CoUninitialize()
def translate(timeline): ret = [] for i in range(len(timeline)): ret.append({ "kind" : timeline[i]["kind"], "extra" : timeline[i]["extra"], "des" : Klanguage().decode_ts(timeline[i]["des"]), "time" : timeline[i]["time"], "title" : Klanguage().decode_ts(timeline[i]["title"]), "distro" : timeline[i]["distro"], "hostname" : timeline[i]["hostname"] }) return ret
def runlevel2means(): global runlevel levels_mean = { "0": Klanguage().to_ts(1825), "1": Klanguage().to_ts(1826), "234": Klanguage().to_ts(1827), "5": Klanguage().to_ts(1828), "6": Klanguage().to_ts(1829) } for level, value in levels_mean.items(): if str(runlevel) in level: return value return runlevel
def get_model_info(response): sys_vendor = "" product_name = "" product_version = "" try: with open("/sys/class/dmi/id/sys_vendor", "r") as f: sys_vendor = f.read().strip() except: pass try: with open("/sys/class/dmi/id/product_name", "r") as f: product_name = f.read().strip() if product_name == "None": product_name = "" except: pass try: with open("/sys/class/dmi/id/product_version", "r") as f: product_version = f.read().strip() if product_version == "None": product_version = "" except: pass if sys_vendor or product_name or product_version: response["hardware"].append({ Klanguage().to_ts(1014): ["{} {} {}".format(sys_vendor, product_name, product_version)] })
def get_motherboard_info(response): board_vendor = "" board_name = "" try: with open("/sys/class/dmi/id/board_vendor", "r") as f: board_vendor = f.read().strip() except: pass try: with open("/sys/class/dmi/id/board_name", "r") as f: board_name = f.read().strip() if board_name == "None": with open("/sys/class/dmi/id/board_version", "r") as f: board_name = f.read().strip() if board_name == "None": board_name = "" except: pass if board_vendor or board_name: response["hardware"].append({ Klanguage().to_ts(1017): ["{} {}".format(board_vendor, board_name)] })
def check_upgradable_packages(response): count = Kvuls().get_upgradable_packages_num() response["kernel"].append({ "name": Klanguage().to_ts(1161), "value": count })
def kernel_default_limits(response): data = file_op.cat("/proc/1/limits", "r") values = [["Limit", "Soft Limit", "Hard Limit", "Units"]] if data: lines = data.split("\n") keys = [ "Max cpu time", "Max file size", "Max data size", "Max stack size", "Max core file size", "Max resident set", "Max processes", "Max open files", "Max locked memory", "Max address space", "Max file locks", "Max pending signals", "Max msgqueue size", "Max nice priority", "Max realtime priority", "Max realtime timeout" ] for line in lines: if line: for key in keys: pattern = re.compile( r"^({})\s*(\S*)\s*(\S*)\s*(\S*)".format(key)) match = pattern.match(line) if match: _, soft, hard, units = match.groups() values.append([key, soft, hard, units]) if len(values) > 1: response["kernel"].append({ "name": Klanguage().to_ts(1163), "values": values })
def cpu_nx_support(): suggest = Klanguage().to_ts(1185) try: data = file_op.cat("/proc/cpuinfo", "r") if data: flags, num = common.grep(data, r"flags\s*:\s(.*)") nx, num = common.grep(flags, r"nx") if nx == "nx": return Klanguage().to_ts(1120), LEVEL_SECURITY, suggest except Exception as e: pass return Klanguage().to_ts(1121), LEVEL_WARNING, suggest
def check_sudoers_file(response): sudoers = [ "/etc/sudoers", "/usr/local/etc/sudoers", "/usr/pkg/etc/sudoers" ] values = [[ Klanguage().to_ts(1145), Klanguage().to_ts(1146), Klanguage().to_ts(1119) ]] for path in sudoers: if os.path.exists(path): _stat = os.lstat(path) permissions = lib.permissions_to_unix_name(_stat.st_mode) if permissions == "-r--r-----": level = LEVEL_SECURITY suggest = Klanguage().to_ts(1181) elif permissions == "-rw-------" or permissions == "-rw-rw----": level = LEVEL_WARNING suggest = Klanguage().to_ts(1182) response["statistic"]["warning"] += 1 else: level = LEVEL_CRITICAL suggest = Klanguage().to_ts(1183) response["statistic"]["critical"] += 1 values.append([path, permissions, level, suggest]) if len(values) > 1: response["authentication"].append({ "name": Klanguage().to_ts(1184), "values": values })
def get_pci_info(response): graphics = [] nics = [] sounds = [] for pci_dev in file_op.listdir("/sys/bus/pci/devices"): vendor = "" device = "" try: with open(os.path.join(pci_dev, "class"), "r") as f: _class = f.read() _class = int(_class, 16) >> 8 if _class == 0x0300 or _class == 0x0301 or _class == 0x0380: category = graphics elif _class == 0x0200: category = nics elif _class == 0x0401 or _class == 0x0403: category = sounds else: continue except: continue try: with open(os.path.join(pci_dev, "vendor"), "r") as f: vendor = f.read().strip() except: continue try: with open(os.path.join(pci_dev, "device"), "r") as f: device = f.read().strip() except: pass category.append(get_pci_string(vendor, device)) if graphics: response["hardware"].append({Klanguage().to_ts(1013): graphics}) if nics: response["hardware"].append({Klanguage().to_ts(1012): nics}) if sounds: response["hardware"].append({Klanguage().to_ts(1029): sounds})
def check_startup_time(response): if common.is_linux(): boot_time = lib.get_boot_time() if boot_time: if len(boot_time) == 4: response["startup_time"] = { "name": [ Klanguage().to_ts(1808), Klanguage().to_ts(1809), Klanguage().to_ts(1810), Klanguage().to_ts(1811) ], "time": [0, boot_time[0], boot_time[1], boot_time[3]], "icon": [0, 1, 2, 3] } return if len(boot_time) == 3: response["startup_time"] = { "name": [ Klanguage().to_ts(1808), Klanguage().to_ts(1809), Klanguage().to_ts(1811) ], "time": [0, boot_time[0], boot_time[2]], "icon": [0, 1, 3] } return
def security_info(response): selinux = check_selinux() smep = is_smep_enable() aslr = is_aslr_enable() nx = cpu_nx_support() if selinux[1] == LEVEL_WARNING: response["statistic"]["warning"] += 1 elif selinux[1] == LEVEL_CRITICAL: response["statistic"]["critical"] += 1 if smep[1] == LEVEL_WARNING: response["statistic"]["warning"] += 1 elif smep[1] == LEVEL_CRITICAL: response["statistic"]["critical"] += 1 if aslr[1] == LEVEL_WARNING: response["statistic"]["warning"] += 1 elif aslr[1] == LEVEL_CRITICAL: response["statistic"]["critical"] += 1 if nx[1] == LEVEL_WARNING: response["statistic"]["warning"] += 1 elif nx[1] == LEVEL_CRITICAL: response["statistic"]["critical"] += 1 response["feature"] = [[ Klanguage().to_ts(1117), Klanguage().to_ts(1118), Klanguage().to_ts(1119) ], [Klanguage().to_ts(1125), selinux[0], selinux[1], selinux[2]], [Klanguage().to_ts(1126), smep[0], smep[1], smep[2] ], [Klanguage().to_ts(1127), aslr[0], aslr[1], aslr[2]], [Klanguage().to_ts(1128), nx[0], nx[1], nx[2]]]
def run(payload, socket): response = { "cmd_id" : payload["cmd_id"], "session_id" : payload["args"]["session_id"], "items" : {}, "lasttime" : 0, "error" : "" } cleaner = Kdatabase().get_obj("cleaner") for kind, info in cleaner["kinds"].items(): values = [] for key, array in info["items"].items(): values.append([Klanguage().to_ts(array[0]), array[1], array[2], key]) response["items"][kind] = { "name" : Klanguage().to_ts(info["name"]), "des" : Klanguage().to_ts(info["des"]), "size" : info["size"], "values" : values } last_8week_ts = time_op.get_last_nmonday_ts(8) history = list(range(8)) for i in range(len(last_8week_ts)): history[i] = { "time" : last_8week_ts[i], "size" : 0 } for record in cleaner["record"]: for value in history: if record["time"] >= value["time"]: value["size"] += record["size"] break history = sorted(history, key = lambda t : t["time"]) response["lasttime"] = cleaner["lasttime"] response["record"] = history socket.response(response)
def cpu_nx_support(self): suggest = Klanguage().to_ts(1185) try: data = file_op.cat("/proc/cpuinfo", "r") if data: flags, num = common.grep(data, r"flags\s*:\s(.*)") nx, num = common.grep(flags, r"nx") if nx == "nx": return Klanguage().to_ts( 1120), macro.BASELINE_LEVEL["SECURITY"], suggest except Exception as e: pass return Klanguage().to_ts(1121), macro.BASELINE_LEVEL["LOW"], suggest
def run(payload, socket): response = { 'cmd_id': payload['cmd_id'], "session_id": payload["args"]["session_id"], "name": [ Klanguage().to_ts(1114), Klanguage().to_ts(1115), Klanguage().to_ts(1116) ], } audit = Kdatabase().get_obj('audit') response['feature'] = audit['feature'] response['authentication'] = audit['authentication'] response['kernel'] = audit['kernel'] socket.response(response)
def logged_user(response): values = [[ Klanguage().to_ts(1135), Klanguage().to_ts(1141), Klanguage().to_ts(1142), Klanguage().to_ts(1143) ]] for user in psutil.users(): values.append([ user[0], user[1], user[2], time_op.timestamp2string(int(user[3])) ]) response["authentication"].append({ "name": Klanguage().to_ts(1140), "values": values })
def is_aslr_enable(): status = [ Klanguage().to_ts(1192), Klanguage().to_ts(1193), Klanguage().to_ts(1194) ] level = [LEVEL_CRITICAL, LEVEL_WARNING, LEVEL_SECURITY] suggest_0 = Klanguage().to_ts(1195) suggest = [suggest_0, suggest_0, Klanguage().to_ts(1196)] if os.path.exists("/proc/sys/kernel/randomize_va_space"): with open("/proc/sys/kernel/randomize_va_space") as f: v = f.read().strip() if v.isdigit(): if int(v) in [0, 1, 2]: return status[int(v)], level[int(v)], suggest[int(v)] return status[0], level[0], suggest[0]
def run(payload, socket): response = { 'cmd_id' : payload['cmd_id'], "session_id" : payload["args"]["session_id"], 'status' : "", 'error' : "" } if payload["args"]["user_id"] != KProfile().read_key("username"): response["error"] = Klanguage().to_ts(4007) socket.response(response) return if lib.check_root(): op_service(payload["args"]["name"], payload["args"]["op"], response) else: response["error"] = Klanguage().to_ts(4002) socket.response(response)
def get_garbage(response): cleaner = Kdatabase().get_obj("cleaner") for kind, info in cleaner["kinds"].items(): size = info["size"] if size > 0: response["garbage"].append({ "name" : Klanguage().to_ts(info["name"]), "size" : info["size"] })