深信服安全软件拦截子进程的排查与解决方案

发布时间:2026/8/23 6:10:33
深信服安全软件拦截子进程的排查与解决方案 深信服安全软件拦截子进程的排查与解决方案最近在跑量化回测脚本时遇到一个诡异问题Python脚本执行到subprocess调用时直接卡死PowerShell窗口无响应任务管理器里能看到进程但无法结束。排查了一圈最后定位到是深信服Sangfor安全软件在拦截子进程创建。这篇文章记录完整排查过程和解决方案给同样被深信服坑过的朋友一个参考。问题现象我有个自动化脚本需要周期性调用外部程序获取行情数据import subprocess import time def fetch_market_data(): # 调用外部行情程序获取数据 result subprocess.run( [market_data_fetcher.exe, --symbol, BTCUSDT, --interval, 1m], capture_outputTrue, textTrue, timeout30 ) return result.stdout if __name__ __main__: while True: try: data fetch_market_data() print(f获取数据成功: {len(data)} bytes) except subprocess.TimeoutExpired: print(警告: 子进程执行超时) except Exception as e: print(f错误: {e}) time.sleep(5)运行后出现以下现象脚本卡在subprocess.run()既不返回也不报错任务管理器能看到market_data_fetcher.exe进程但CPU占用为0手动打开PowerShell执行相同命令PowerShell直接无响应关闭深信服安全软件后一切恢复正常排查过程第一步确认问题范围先写个最小化测试脚本排除业务代码干扰import subprocess # 测试1: 基础命令 try: result subprocess.run([echo, hello], capture_outputTrue, timeout5) print(fecho 执行成功: {result.stdout}) except Exception as e: print(fecho 执行失败: {e}) # 测试2: PowerShell命令 try: result subprocess.run( [powershell, -Command, Get-Process | Select-Object -First 5], capture_outputTrue, timeout10 ) print(fPowerShell 执行成功: {result.stdout.decode()}) except Exception as e: print(fPowerShell 执行失败: {e})测试结果echo命令正常执行powershell命令卡死cmd /c dir正常执行任何需要创建新进程的调用都可能被拦截这说明问题不是简单的权限问题而是安全软件对特定进程创建行为的拦截。第二步检查安全软件日志深信服安全软件的管理后台有详细的进程拦截日志。如果你有管理员权限可以查看终端管理→安全日志→进程防护日志重点关注被拦截的进程路径和操作类型日志中会明确显示拦截规则例如进程: powershell.exe 操作: 创建子进程 目标: cmd.exe 规则: 禁止PowerShell创建子进程第三步确认拦截规则深信服的默认策略比较激进特别是针对PowerShell和WScript这类脚本宿主。常见的拦截场景PowerShell创建子进程- 防止恶意脚本通过PowerShell下载执行Python调用系统命令- 防止Python脚本逃逸沙箱进程注入行为- 某些正常的数据采集也会被误判临时解决方案在没有IT管理员权限的情况下先用以下方法绕过方案一使用os.system替代subprocessimport os # 使用os.system替代subprocess.run os.system(market_data_fetcher.exe --symbol BTCUSDT --interval 1m) # 如果需要获取输出重定向到文件 os.system(market_data_fetcher.exe --symbol BTCUSDT --interval 1m output.txt)注意os.system有命令注入风险且无法直接获取输出仅作临时方案。方案二通过cmd中转import subprocess def run_with_cmd(command): 通过cmd.exe中转执行命令 # 将命令包装为cmd /c的形式 cmd_command fcmd /c {command} try: result subprocess.run( cmd_command, shellTrue, capture_outputTrue, textTrue, timeout15 ) return result.stdout except subprocess.TimeoutExpired: return 执行超时 # 使用示例 output run_with_cmd(market_data_fetcher.exe --symbol BTCUSDT --interval 1m) print(output)这个方法利用cmd.exe作为中间层很多时候能绕过安全软件对直接创建子进程的拦截。方案三使用ctypes调用Windows APIimport ctypes import ctypes.wintypes def run_powershell_script(script): 使用Windows API直接执行PowerShell脚本 # 创建进程的Windows API CREATE_NO_WINDOW 0x08000000 class STARTUPINFO(ctypes.Structure): _fields_ [(cb, ctypes.wintypes.DWORD), (lpReserved, ctypes.wintypes.LPWSTR), (lpDesktop, ctypes.wintypes.LPWSTR), (lpTitle, ctypes.wintypes.LPWSTR), (dwX, ctypes.wintypes.DWORD), (dwY, ctypes.wintypes.DWORD), (dwXSize, ctypes.wintypes.DWORD), (dwYSize, ctypes.wintypes.DWORD), (dwXCountChars, ctypes.wintypes.DWORD), (dwYCountChars, ctypes.wintypes.DWORD), (dwFillAttribute, ctypes.wintypes.DWORD), (dwFlags, ctypes.wintypes.DWORD), (wShowWindow, ctypes.wintypes.WORD), (cbReserved2, ctypes.wintypes.WORD), (lpReserved2, ctypes.POINTER(ctypes.c_byte)), (hStdInput, ctypes.wintypes.HANDLE), (hStdOutput, ctypes.wintypes.HANDLE), (hStdError, ctypes.wintypes.HANDLE)] class PROCESS_INFORMATION(ctypes.Structure): _fields_ [(hProcess, ctypes.wintypes.HANDLE), (hThread, ctypes.wintypes.HANDLE), (dwProcessId, ctypes.wintypes.DWORD), (dwThreadId, ctypes.wintypes.DWORD)] # 构造命令 command fpowershell -Command {script} # 创建进程 si STARTUPINFO() pi PROCESS_INFORMATION() si.cb ctypes.sizeof(STARTUPINFO) success ctypes.windll.kernel32.CreateProcessW( None, # 应用程序名 command, # 命令行 None, # 进程安全属性 None, # 线程安全属性 False, # 句柄继承 CREATE_NO_WINDOW, # 创建标志 None, # 环境变量 None, # 当前目录 ctypes.byref(si), ctypes.byref(pi) ) if not success: error_code ctypes.windll.kernel32.GetLastError() return f创建进程失败错误码: {error_code} # 等待进程结束 ctypes.windll.kernel32.WaitForSingleObject(pi.hProcess, 30000) # 关闭句柄 ctypes.windll.kernel32.CloseHandle(pi.hProcess) ctypes.windll.kernel32.CloseHandle(pi.hThread) return 执行完成 # 使用示例 result run_powershell_script(Get-Process | Select-Object -First 5) print(result)这个方案绕过常规的进程创建API直接调用Win32 API成功率较高。方案四使用计划任务import subprocess import xml.etree.ElementTree as ET def create_scheduled_task(task_name, command, args): 通过计划任务执行命令 # 创建计划任务XML task_xml f?xml version1.0 encodingUTF-16? Task version1.2 xmlnshttp://schemas.microsoft.com/windows/2004/02/mit/task Triggers CalendarTrigger StartBoundary2024-01-01T00:00:00/StartBoundary Enabledtrue/Enabled ScheduleByDay DaysInterval1/DaysInterval /ScheduleByDay /CalendarTrigger /Triggers Principals Principal idAuthor LogonTypeInteractiveToken/LogonType RunLevelLeastPrivilege/RunLevel /Principal /Principals Settings MultipleInstancesPolicyIgnoreNew/MultipleInstancesPolicy DisallowStartIfOnBatteriesfalse/DisallowStartIfOnBatteries StopIfGoingOnBatteriesfalse/StopIfGoingOnBatteries AllowHardTerminatetrue/AllowHardTerminate StartWhenAvailabletrue/StartWhenAvailable RunOnlyIfNetworkAvailablefalse/RunOnlyIfNetworkAvailable /Settings Actions Exec Command{command}/Command Arguments{args}/Arguments /Exec /Actions /Task # 保存XML文件 with open(f{task_name}.xml, w, encodingutf-16) as f: f.write(task_xml) # 导入计划任务 subprocess.run([schtasks, /Create, /TN, task_name, /XML, f{task_name}.xml, /F], capture_outputTrue, textTrue) # 立即运行 subprocess.run([schtasks, /Run, /TN, task_name], capture_outputTrue, textTrue) # 清理 subprocess.run([schtasks, /Delete, /TN, task_name, /F], capture_outputTrue, textTrue) import os os.remove(f{task_name}.xml) # 使用示例 create_scheduled_task(data_fetch, market_data_fetcher.exe, --symbol BTCUSDT --interval 1m)计划任务由系统服务启动通常能绕过安全软件的进程创建拦截。与IT部门沟通建议临时方案只能应急根本解决需要IT部门调整安全策略。建议这样沟通1. 准备证据# 收集拦截证据的脚本 import subprocess import datetime import json def collect_evidence(): 收集安全软件拦截的证据 evidence { timestamp: datetime.datetime.now().isoformat(), test_cases: [] } # 测试用例1: Python直接调用subprocess try: result subprocess.run([powershell, -Command, echo test], capture_outputTrue, timeout5) evidence[test_cases].append({ name: python_subprocess_powershell, status: success, output: result.stdout.decode() }) except Exception as e: evidence[test_cases].append({ name: python_subprocess_powershell, status: failed, error: str(e) }) # 测试用例2: 通过cmd中转 try: result subprocess.run([cmd, /c, echo test], capture_outputTrue, timeout5) evidence[test_cases].append({ name: python_subprocess_cmd, status: success, output: result.stdout.decode() }) except Exception as e: evidence[test_cases].append({ name: python_subprocess_cmd, status: failed, error: str(e) }) # 保存证据 with open(intercept_evidence.json, w, encodingutf-8) as f: json.dump(evidence, f, ensure_asciiFalse, indent2) print(f证据已保存到 intercept_evidence.json) print(json.dumps(evidence, ensure_asciiFalse, indent2)) if __name__ __main__: collect_evidence()2. 沟通要点明确业务需求说明Python脚本是量化交易系统的一部分需要调用外部程序获取行情数据提供测试结果展示证据文件说明哪些操作被拦截哪些正常请求白名单建议将Python解释器和常用工具加入白名单最小权限原则请求调整安全策略而不是完全关闭安全软件总结深信服安全软件对子进程创建的拦截确实给自动化脚本带来不少麻烦。从排查到解决核心思路是确认问题范围- 用最小化测试脚本定位被拦截的操作查看安全日志- 获取具体的拦截规则临时绕过- 使用os.system、cmd中转、Win32 API或计划任务根本解决- 与IT部门沟通调整安全策略如果你的环境里也有类似的安全软件拦截问题建议优先走正规渠道解决。临时方案只是权宜之计长期运行还是需要稳定的环境。更多Python量化与自动化实战内容请关注本站。