Merged
Fix bugs and update for SP4 #15
wangweize_yewuAdd on Jun 8
Fix bugs and update for SP4 #15
Merged
Total: 7 files changed+143-38
| @@ -24,11 +24,6 @@ sys.path.insert(0,parentdir) | |||
| 24 | from secScanner.gconfig import * | 24 | from secScanner.gconfig import * |
| 25 | from secScanner.scan_func import * | 25 | from secScanner.scan_func import * |
| 26 | 26 | ||
| 27 | - | ||
| 28 | -def quiet_output(args): | ||
| 29 | - QUIET = 1 | ||
| 30 | - QUIET = set_value("QUIET", QUIET) | ||
| 31 | - | ||
| 32 | def fix_basic(args): | 27 | def fix_basic(args): |
| 33 | display_info() | 28 | display_info() |
| 34 | check_isvirtualmachine() | 29 | check_isvirtualmachine() |
| @@ -55,15 +50,6 @@ def fix_level3(args): | |||
| 55 | check_isvirtualmachine() | 50 | check_isvirtualmachine() |
| 56 | scan_fix_sys('level3') | 51 | scan_fix_sys('level3') |
| 57 | 52 | ||
| 58 | -def sep_permit(args): | ||
| 59 | - display_info() | ||
| 60 | - main_path = os.path.join(parentdir, "enhance/level3") | ||
| 61 | - path = os.path.join(main_path, 'sep_permit.py') | ||
| 62 | - try: | ||
| 63 | - subprocess.run(path, check=True) | ||
| 64 | - except subprocess.CalledProcessError as e: | ||
| 65 | - print(f"脚本执行出错,返回码:{e.returncode}") | ||
| 66 | - | ||
| 67 | def fix_euler(args): | 53 | def fix_euler(args): |
| 68 | display_info() | 54 | display_info() |
| 69 | check_isvirtualmachine() | 55 | check_isvirtualmachine() |
| @@ -167,14 +153,10 @@ def scan_command(): | |||
| 167 | 153 | ||
| 168 | parser.add_argument('--config', action='store_true', help='Show settings file path') | 154 | parser.add_argument('--config', action='store_true', help='Show settings file path') |
| 169 | 155 | ||
| 170 | - parser.add_argument('-q', '--quiet', dest='quiet', action='store_true',default=False, help='Quiet mode') | 156 | + parser.add_argument('-V', '--version', action='version', version='secScanner 1.3.6', help='Show version') |
| 171 | - parser.add_argument('-V', '--version', action='version', version='SecScanner 1.3.1', help='Show version') | ||
| 172 | 157 | ||
| 173 | subparsers = parser.add_subparsers(dest='command') | 158 | subparsers = parser.add_subparsers(dest='command') |
| 174 | 159 | ||
| 175 | - useradd_parser = subparsers.add_parser('useradd', help="Create a new user to achieve permission separation") | ||
| 176 | - useradd_parser.set_defaults(func=sep_permit) | ||
| 177 | - | ||
| 178 | fix_parser = subparsers.add_parser('fix', help="Fix command") | 160 | fix_parser = subparsers.add_parser('fix', help="Fix command") |
| 179 | fix_subparsers = fix_parser.add_subparsers(dest='mode') | 161 | fix_subparsers = fix_parser.add_subparsers(dest='mode') |
| 180 | 162 | ||
| @@ -242,6 +224,13 @@ def scan_command(): | |||
| 242 | 224 | ||
| 243 | args = parser.parse_args() | 225 | args = parser.parse_args() |
| 244 | 226 | ||
| 227 | + find_profile() | ||
| 228 | + if args.config: | ||
| 229 | + PROFILE = get_value("PROFILE") | ||
| 230 | + print("") | ||
| 231 | + print(f"Default config: {PROFILE}") | ||
| 232 | + print("") | ||
| 233 | + return | ||
| 245 | 234 | ||
| 246 | if args.command == None: | 235 | if args.command == None: |
| 247 | parser.error('Command line parameters not provided. Please use - h or -- help to view help information.') | 236 | parser.error('Command line parameters not provided. Please use - h or -- help to view help information.') |
| @@ -262,17 +251,6 @@ def scan_command(): | |||
| 262 | if args.action is None or (args.action in ['on', 'off', 'status'] and not args.servicename): | 251 | if args.action is None or (args.action in ['on', 'off', 'status'] and not args.servicename): |
| 263 | parser.error('The "servicename" is required when using service commands.') | 252 | parser.error('The "servicename" is required when using service commands.') |
| 264 | 253 | ||
| 265 | - | ||
| 266 | - find_profile() | ||
| 267 | - | ||
| 268 | if hasattr(args, 'func'): | 254 | if hasattr(args, 'func'): |
| 269 | args.func(args) | 255 | args.func(args) |
| 270 | 256 | ||
| 271 | - if args.config: | ||
| 272 | - PROFILE = get_value("PROFILE") | ||
| 273 | - print("") | ||
| 274 | - print(f"Default config: {PROFILE}") | ||
| 275 | - | ||
| 276 | - if args.quiet: | ||
| 277 | - quiet_output(args) | ||
| 278 | - | ||
| @@ -43,6 +43,8 @@ def distro_detection(): | |||
| 43 | OS_DISTRO = tmp_distro | 43 | OS_DISTRO = tmp_distro |
| 44 | elif tmp_distro.startswith("v"): #v24系列 | 44 | elif tmp_distro.startswith("v"): #v24系列 |
| 45 | OS_DISTRO = tmp_distro | 45 | OS_DISTRO = tmp_distro |
| 46 | + elif tmp_distro.startswith("V"): #V25系列 | ||
| 47 | + OS_DISTRO = tmp_distro | ||
| 46 | else: | 48 | else: |
| 47 | print("secScanner not support this system for now!") | 49 | print("secScanner not support this system for now!") |
| 48 | exit(1) | 50 | exit(1) |
| @@ -47,17 +47,13 @@ The above functions is a dict to save global values | |||
| 47 | ''' | 47 | ''' |
| 48 | # Program information | 48 | # Program information |
| 49 | PROGRAM_VERSION = "1.3" | 49 | PROGRAM_VERSION = "1.3" |
| 50 | -PROGRAM_RELEASE = "v1.3.1" | ||
| 51 | PROGRAM_NAME = "secScanner" | 50 | PROGRAM_NAME = "secScanner" |
| 52 | -PROGRAM_UPDATEDATE = "2025-11-07" | ||
| 53 | PROGRAM_AUTHOR = "wangweize" | 51 | PROGRAM_AUTHOR = "wangweize" |
| 54 | PROGRAM_CONTACTEMAIL = "wangweize_yewu@cmss.chinamobile.com" | 52 | PROGRAM_CONTACTEMAIL = "wangweize_yewu@cmss.chinamobile.com" |
| 55 | PROGRAM_WEBSITE = "https://gitee.com/openeuler/secscanner" | 53 | PROGRAM_WEBSITE = "https://gitee.com/openeuler/secscanner" |
| 56 | PROGRAM_COPYRIGHT = "Copyright (c) 2023. China Mobile(SuZhou)Software Technology Co.,Ltd. All rights reserved." | 54 | PROGRAM_COPYRIGHT = "Copyright (c) 2023. China Mobile(SuZhou)Software Technology Co.,Ltd. All rights reserved." |
| 57 | 55 | ||
| 58 | # Script Info | 56 | # Script Info |
| 59 | -VER_ID = "SecurityHarden, by wangweize, 2025-11-07" | ||
| 60 | - | ||
| 61 | LOGDIR = "/var/log/secScanner/" | 57 | LOGDIR = "/var/log/secScanner/" |
| 62 | LOGFILE = os.path.join(LOGDIR, "secscanner.log") | 58 | LOGFILE = os.path.join(LOGDIR, "secscanner.log") |
| 63 | 59 | ||
| @@ -0,0 +1,126 @@ | |||
| 1 | +import ctypes | ||
| 2 | +import os | ||
| 3 | +import subprocess | ||
| 4 | +import time | ||
| 5 | +import threading | ||
| 6 | +import logging | ||
| 7 | +from threading import Thread | ||
| 8 | +from secScanner.gconfig import * | ||
| 9 | +from secScanner.lib import * | ||
| 10 | + | ||
| 11 | +logger = logging.getLogger("secscanner") | ||
| 12 | + | ||
| 13 | +DATA_LEN = 4096 | ||
| 14 | +READ_WAIT_SECOND = 3 | ||
| 15 | +CHECK_WAIT_SECOND = 15 | ||
| 16 | +KMODULELIST_TYPE = 0x00800000 | ||
| 17 | +sdklib_path = '/usr/lib64/secDetector/libsecDetectorsdk.so' | ||
| 18 | +g_cli_reader = ctypes.c_void_p | ||
| 19 | +g_cli_reader_lock = threading.Lock() | ||
| 20 | + | ||
| 21 | +def init_sdklib(): | ||
| 22 | + global secDetectorsdklib | ||
| 23 | + secDetectorsdklib = ctypes.cdll.LoadLibrary(sdklib_path) | ||
| 24 | + secDetectorsdklib.secSub.argtypes = [ctypes.c_int] | ||
| 25 | + secDetectorsdklib.secSub.restype = ctypes.c_void_p | ||
| 26 | + secDetectorsdklib.secUnsub.argtypes = [ctypes.c_void_p] | ||
| 27 | + secDetectorsdklib.secUnsub.restype = None | ||
| 28 | + secDetectorsdklib.secReadFrom.argtypes = [ctypes.c_void_p, ctypes.c_char_p, ctypes.c_int] | ||
| 29 | + secDetectorsdklib.secReadFrom.restype = None | ||
| 30 | + | ||
| 31 | +g_module_lsmod = [] | ||
| 32 | +g_module_baseline = [] | ||
| 33 | + | ||
| 34 | +def get_lsmod(): | ||
| 35 | + global g_module_lsmod | ||
| 36 | + cmd = "lsmod" | ||
| 37 | + ret, result = subprocess.getstatusoutput(cmd) | ||
| 38 | + if ret != 0: | ||
| 39 | + logger.warning("R02 chkrootkit kmodule get lsmod error") | ||
| 40 | + Display("- secDetector get lsmod error...", "WARNING") | ||
| 41 | + return | ||
| 42 | + | ||
| 43 | + lsmod_list = result.splitlines() | ||
| 44 | + # remove "Module Size Used by" | ||
| 45 | + lsmod_list.pop(0) | ||
| 46 | + for mod in lsmod_list: | ||
| 47 | + modname = mod.split(" ") | ||
| 48 | + g_module_lsmod.append(modname[0]) | ||
| 49 | + | ||
| 50 | +def check_module(data_string: str =""): | ||
| 51 | + global g_module_baseline | ||
| 52 | + timeprefix = "" | ||
| 53 | + if data_string.endswith(", "): | ||
| 54 | + data_string = data_string[:-2] | ||
| 55 | + timeprefix, module_list = data_string.split(" event_type=kmodulelist module_name=") | ||
| 56 | + g_module_baseline = module_list.strip().split(", ") | ||
| 57 | + | ||
| 58 | + get_lsmod() | ||
| 59 | + module_diff = set(g_module_baseline).difference(set(g_module_lsmod)) | ||
| 60 | + if module_diff: | ||
| 61 | + logger.warning(f"HIDEKMODULE {module_diff}") | ||
| 62 | + Display("- secDetector found hidekmoule...", "WARNING") | ||
| 63 | + else: | ||
| 64 | + logger.info("R02 chkrootkit kmodule no hide module") | ||
| 65 | + Display("- secDetector check no hide module...", "OK") | ||
| 66 | + | ||
| 67 | +def thread_func_sub_and_read(num=0): | ||
| 68 | + global g_cli_reader | ||
| 69 | + | ||
| 70 | + cli_reader = secDetectorsdklib.secSub(KMODULELIST_TYPE) | ||
| 71 | + g_cli_reader_lock.acquire() | ||
| 72 | + g_cli_reader = cli_reader | ||
| 73 | + g_cli_reader_lock.release() | ||
| 74 | + | ||
| 75 | + data = ctypes.create_string_buffer(DATA_LEN) | ||
| 76 | + data_len = ctypes.c_int(DATA_LEN) | ||
| 77 | + secDetectorsdklib.secReadFrom(cli_reader, data, data_len) | ||
| 78 | + | ||
| 79 | + data_string = "" | ||
| 80 | + check_module_flag = 0 | ||
| 81 | + while True: | ||
| 82 | + if data_string == 'end': | ||
| 83 | + break | ||
| 84 | + ret = data_string.find("event_type=kmodulelist") | ||
| 85 | + if ret != -1: | ||
| 86 | + check_module_flag = 1 | ||
| 87 | + break | ||
| 88 | + time.sleep(READ_WAIT_SECOND) | ||
| 89 | + secDetectorsdklib.secReadFrom(cli_reader, data, data_len) | ||
| 90 | + data_string = data.value.decode() | ||
| 91 | + | ||
| 92 | + if check_module_flag == 1: | ||
| 93 | + check_module(data_string) | ||
| 94 | + logger.info("R02 chkrootkit kmodule read success") | ||
| 95 | + | ||
| 96 | +def thread_func_unsub(num=0): | ||
| 97 | + global g_cli_reader | ||
| 98 | + g_cli_reader_lock.acquire() | ||
| 99 | + try: | ||
| 100 | + secDetectorsdklib.secUnsub(g_cli_reader) | ||
| 101 | + finally: | ||
| 102 | + g_cli_reader_lock.release() | ||
| 103 | + logger.info("R02 chkrootkit kmodule unsub") | ||
| 104 | + | ||
| 105 | +def R02_chkrootkit_kmodule(): | ||
| 106 | + InsertSection("using secDetector check kmodule rootkit") | ||
| 107 | + if not os.path.exists(sdklib_path): | ||
| 108 | + logger.info("the system doesn't install secDetector, please install it ...") | ||
| 109 | + Display("- No secDetector install...", "WARNING") | ||
| 110 | + return | ||
| 111 | + init_sdklib() | ||
| 112 | + threadlist = [] | ||
| 113 | + | ||
| 114 | + tsub_read = Thread(target=thread_func_sub_and_read,args=(1,)) | ||
| 115 | + tsub_read.start() | ||
| 116 | + | ||
| 117 | + time.sleep(CHECK_WAIT_SECOND) | ||
| 118 | + tunsub = Thread(target=thread_func_unsub,args=(2,)) | ||
| 119 | + tunsub.start() | ||
| 120 | + | ||
| 121 | + threadlist.append(tsub_read) | ||
| 122 | + threadlist.append(tunsub) | ||
| 123 | + | ||
| 124 | + for t in threadlist: | ||
| 125 | + t.join() | ||
| 126 | + | ||
| @@ -333,7 +333,7 @@ def scan_restore_basic_inline(): | |||
| 333 | pro_val = int(pro_val, 8) | 333 | pro_val = int(pro_val, 8) |
| 334 | os.chmod(name, pro_val) | 334 | os.chmod(name, pro_val) |
| 335 | Display(f"- Restoring property of file or dir:{name}...", "FINISHED") | 335 | Display(f"- Restoring property of file or dir:{name}...", "FINISHED") |
| 336 | - os.remove(i) | 336 | + os.remove(single_property) |
| 337 | 337 | ||
| 338 | restore_unused_user() | 338 | restore_unused_user() |
| 339 | 339 | ||
| @@ -784,7 +784,7 @@ def scan_vulnerabilities_by_items(): | |||
| 784 | sys.exit(1) | 784 | sys.exit(1) |
| 785 | #check system architecture | 785 | #check system architecture |
| 786 | ret, sys_arch = subprocess.getstatusoutput('uname -m') | 786 | ret, sys_arch = subprocess.getstatusoutput('uname -m') |
| 787 | - if sys_arch not in ['arm', 'x86_64']: | 787 | + if sys_arch not in ['aarch64', 'x86_64']: |
| 788 | print("This architecture is not supported by the vulnerability scanning feature at this time") | 788 | print("This architecture is not supported by the vulnerability scanning feature at this time") |
| 789 | sys.exit(1) | 789 | sys.exit(1) |
| 790 | 790 | ||
| @@ -28,7 +28,7 @@ def check_python_version(): | |||
| 28 | if __name__ == "__main__": | 28 | if __name__ == "__main__": |
| 29 | check_python_version() | 29 | check_python_version() |
| 30 | gconfig.prepare_seconf() | 30 | gconfig.prepare_seconf() |
| 31 | - logger = logging.getLogger("secScanner") | 31 | + logger = logging.getLogger("secscanner") |
| 32 | gconfig.seconf.LOGFILE = gconfig.seconf.get('main', 'LOGFILE') | 32 | gconfig.seconf.LOGFILE = gconfig.seconf.get('main', 'LOGFILE') |
| 33 | gconfig.seconf.LOG_LEVEL = gconfig.seconf.get('main', 'LOG_LEVEL') | 33 | gconfig.seconf.LOG_LEVEL = gconfig.seconf.get('main', 'LOG_LEVEL') |
| 34 | 34 | ||
| @@ -1,7 +1,7 @@ | |||
| 1 | %define debug_package %{nil} | 1 | %define debug_package %{nil} |
| 2 | %define name secScanner | 2 | %define name secScanner |
| 3 | %define version 1.3 | 3 | %define version 1.3 |
| 4 | -%define release 5 | 4 | +%define release 6 |
| 5 | %define os_version %(source /etc/os-release; echo ${VERSION}) | 5 | %define os_version %(source /etc/os-release; echo ${VERSION}) |
| 6 | %define os_id %(source /etc/os-release; echo ${ID}) | 6 | %define os_id %(source /etc/os-release; echo ${ID}) |
| 7 | 7 | ||
| @@ -113,6 +113,9 @@ exit 0 | |||
| 113 | /var/log/secScanner/secscanner.log | 113 | /var/log/secScanner/secscanner.log |
| 114 | 114 | ||
| 115 | %changelog | 115 | %changelog |
| 116 | +* Mon Jun 8 2026 wangweize <wangweize@cmss.chinamobile.com> 1.3-6 | ||
| 117 | +- Update for openEuler SP4 | ||
| 118 | + | ||
| 116 | * Tue Apr 28 2026 wangweize <wangweize@cmss.chinamobile.com> 1.3-5 | 119 | * Tue Apr 28 2026 wangweize <wangweize@cmss.chinamobile.com> 1.3-5 |
| 117 | - Add fix bug and add unit test | 120 | - Add fix bug and add unit test |
| 118 | 121 | ||