
    M'Qi~+                     p    S r SSKrSSKrSSKrSSKrSSKrSSKJrJrJ	r	  SSK
Jr  SSKJr   " S S5      rg)us   
知识库脚本沙箱执行服务

提供安全的脚本执行环境，限制文件系统访问和系统调用。
    N)DictAnyOptional)Path)CategoryConfigc                       \ rS rSrSrSS\4S jjr SS\S\S\S	\\\4   S
\S\\\4   4S jjr	S\S\S\S\S\\\4   4
S jr
S\S\S\4S jrS\S\S\S\S\\\4   4
S jrSrg)KnowledgeScriptSandbox   u   知识库脚本沙箱执行器N	base_pathc                     U=(       dA    [         R                  R                  [         R                  R                  [        5      S5      U l        g)uF   
初始化沙箱执行器

Args:
    base_path: 知识库基础路径
z../../../ge10N)ospathjoindirname__file__r   )selfr   s     X   /Users/yu22x/Desktop/ddd_副本123/ctf/app/services/category/knowledge_script_sandbox.py__init__KnowledgeScriptSandbox.__init__   s,     #^bggll277??83Lo&^    category_idscript_codescript_language
user_inputscript_namereturnc                 .   [         R                  R                  U5      nU(       d  [        SU S35      e[        R
                  R                  U R                  U5      n[        R
                  R                  U5      (       d  [        SU 35      e[        R                  " SS9n UUR                  S5      UR                  S5      UR                  S/ 5      UR                  S	5      UR                  S
/ 5      UR                  SS5      UR                  SS5      S.n	[        R
                  R                  US5      n
[        U
SSS9 n[        R                  " XSSS9  SSS5        US:X  a#  [        R
                  R                  US5      nSnO7US:X  a#  [        R
                  R                  US5      nSnO[        SU 35      e[        USSS9 nUR                  U5        SSS5        US:X  a  U R                  XXx5      nOU R!                  XXx5      nU[        R
                  R                  U5      (       a  ["        R$                  " USS 9  $ $ ! , (       d  f       N= f! , (       d  f       N= f! [&         aT  nS[)        U5      S!S!S".s SnA[        R
                  R                  U5      (       a  ["        R$                  " USS 9  $ $ SnAff = f! [        R
                  R                  U5      (       a  ["        R$                  " USS 9  f f = f)#u  
在沙箱环境中执行脚本

Args:
    category_id: 方向 ID
    script_code: 脚本代码
    script_language: 脚本语言（python/javascript）
    user_input: 用户输入数据
    script_name: 脚本名称（可选）
    
Returns:
    执行结果字典
u   方向 u
    不存在u   知识库目录不存在: knowledge_script_)prefix
difficultylanguageknowledge_pointsscenetags	max_items
   max_writeups_per_item   )r   r    r!   r"   r#   r$   r%   r'   z
input.jsonwutf-8encodingF   )ensure_asciiindentNpythonz	script.pyz.py
javascriptz	script.jsz.jsu   不支持的脚本语言: T)ignore_errors successerroroutputstderr)r   queryget
ValueErrorr   r   r   r   existstempfilemkdtempopenjsondumpwrite_execute_python_sandbox_execute_javascript_sandboxshutilrmtree	Exceptionstr)r   r   r   r   r   r   categoryknowledge_dirwork_dir
input_data
input_filefscript_file
script_extresultes                   r   execute_script%KnowledgeScriptSandbox.execute_script   s    "''++K8w{m:>?? T^^[Aww~~m,,9-IJJ ##+>?1	<  +(nn\:&NN:6$.NN3Er$J#0"vr2'^^K<)38OQR)S	J h=Jj#8A		*eAF 9 (* ggll8[A"
 L0 ggll8[A"
 #=o=N!OPPk39Q$ : (*55k}g99+S`k ww~~h''hd; (C 98 :9  	 Q	  ww~~h''hd; (	 ww~~h''hd; (sb   'B#I7 
I!A3I7 I&&4I7 
I#I7 &
I40I7 7
KKKK KK <LrO   rM   rJ   rK   c                    U R                  X5      n[        R                  R                  US5      n[	        USSS9 nUR                  U5        SSS5         [        R                  " SSSXb/US	S	S
SSSS.S9nUR                  S:w  a)  SSUR                   S3UR                  UR                  S.$  [        R                  " UR                  5      n	S	U	UR                  UR                  S.$ ! , (       d  f       N= f! [        R                   a    SSUR                  UR                  S.s $ f = f! [        R                   a
    SSSSS.s $ [         a  n
SS[!        U
5       3SSS.s Sn
A
$ Sn
A
ff = f)u\   
在沙箱中执行 Python 脚本

使用受限的 Python 环境，限制文件系统访问
zrestricted_script.pyr)   r*   r+   Npython3z-Sz-ET   r3   z/usr/bin:/bin)
PYTHONPATHPATHcwdcapture_outputtexttimeoutr,   envr   F    脚本执行失败（退出码:    ）r4   '   脚本输出不是有效的 JSON 格式r5   datar7   r8   %   脚本执行超时（超过 30 秒）   执行脚本时出错: )_wrap_python_scriptr   r   r   r?   rB   
subprocessrun
returncodestdoutr8   r@   loadsJSONDecodeErrorTimeoutExpiredrG   rH   )r   rO   rM   rJ   rK   restricted_scriptrestricted_filerN   rQ   output_datarR   s              r   rC   .KnowledgeScriptSandbox._execute_python_sandboxk   s    !44[P'',,x1GH/39QGG%& :7	^^D$D# "$+F   A%$?@Q@Q?RRUV$mm$mm	 	"jj7  # -- --	 M :9: ''   %F$mm$mm	   (( 	 @	   	 23q6(;	 	sT   C.AD4 3 C? D4 .
C<?/D1.D4 0D11D4 4E7	E7E2,E72E7allowed_dirc                     [        USSS9 nUR                  5       nSSS5        SU SW S3nU$ ! , (       d  f       N= f)u7   
包装 Python 脚本，添加文件系统访问限制
rr*   r+   Nu   # -*- coding: utf-8 -*-
import os
import sys
import json
from pathlib import Path

# 沙箱限制：只允许访问知识库目录
ALLOWED_DIR = r"u  "

def _check_path(path):
    """检查路径是否在允许的目录内"""
    try:
        abs_path = os.path.abspath(path)
        allowed_abs = os.path.abspath(ALLOWED_DIR)
        if not abs_path.startswith(allowed_abs):
            raise PermissionError(f"访问被拒绝: {path} (只允许访问 {ALLOWED_DIR})")
        return abs_path
    except Exception as e:
        raise PermissionError(f"路径检查失败: {e}")

# 重写危险函数
_original_open = open
def safe_open(file, mode='r', *args, **kwargs):
    """安全的文件打开函数"""
    if isinstance(file, (str, Path)):
        _check_path(str(file))
    return _original_open(file, mode, *args, **kwargs)

# 替换内置函数
__builtins__['open'] = safe_open

# 限制 os 模块的危险函数
_original_chdir = os.chdir
def safe_chdir(path):
    _check_path(path)
    return _original_chdir(path)
os.chdir = safe_chdir

_original_listdir = os.listdir
def safe_listdir(path='.'):
    if path == '.':
        path = ALLOWED_DIR
    _check_path(path)
    return _original_listdir(path)
os.listdir = safe_listdir

_original_walk = os.walk
def safe_walk(top, topdown=True, onerror=None, followlinks=False):
    _check_path(top)
    return _original_walk(top, topdown, onerror, followlinks)
os.walk = safe_walk

# 限制 subprocess（禁止执行系统命令）
import subprocess
_original_run = subprocess.run
def blocked_run(*args, **kwargs):
    raise PermissionError("subprocess.run 被禁用")
subprocess.run = blocked_run
subprocess.call = blocked_run
subprocess.Popen = blocked_run

# 限制网络访问
import urllib
import urllib.request
def blocked_urlopen(*args, **kwargs):
    raise PermissionError("网络访问被禁用")
urllib.request.urlopen = blocked_urlopen

# 用户脚本代码

)r?   read)r   rO   rs   rN   original_codewrapped_codes         r   rg   *KnowledgeScriptSandbox._wrap_python_script   s\     +sW5FFHM 6  >|  KFN W 65s   0
>c           
      "    [         R                  " SSX/USSSSSS0S9nUR                  S	:w  a)  S
SUR                   S3UR                  UR                  S.$  [
        R                  " UR                  5      nSUUR                  UR                  S.$ ! [
        R                   a    S
SUR                  UR                  S.s $ f = f! [         R                   a
    S
SSSS.s $ [         a  nS
S[        U5       3SSS.s SnA$ SnAff = f)uj   
在沙箱中执行 JavaScript 脚本（Node.js）

注意：JavaScript 沙箱需要额外的安全措施
nodez--no-warningsTrW   r*   	NODE_PATHr3   rZ   r   Fr`   ra   r4   rb   rc   re   rf   N)rh   ri   rj   rk   r8   r@   rl   rm   rn   rG   rH   )r   rO   rM   rJ   rK   rQ   rq   rR   s           r   rD   2KnowledgeScriptSandbox._execute_javascript_sandbox  s;   3	^^+B# 
F   A%$?@Q@Q?RRUV$mm$mm	 "jj7  # -- --	  '' $F$mm$mm	  (( 	 @	   	 23q6(;	 	sH   AC  B ;C /CC CC D(	D1D	D	D)r   )N)__name__
__module____qualname____firstlineno____doc__rH   r   r   r   rS   rC   rg   rD   __static_attributes__ r   r   r	   r	      s    (_# _ EIL<# L<C L<RU L<!%c3hL<>AL<MQRUWZRZ^L<\I3 IC I.1I=@IEI#s(^IVOs O O Ob=s = =25=AD=IMcSVh=r   r	   )r   r   r@   rh   r=   rE   typingr   r   r   pathlibr   app.models.database.modelsr   r	   r   r   r   <module>r      s3   
 
     & &  5s sr   