1、Github信息收集
对于白帽子来说,Github是一个获取攻击目标信息的好资源,在上面通过搜索公司关键字,可以获取一些关于公司的信息。因为总会有一些开发者的疏忽大意,将公司的源码上传到Github,其中可能含有一些密钥、密码之类的敏感信息。
1.1 手工搜索
思路是:公司特征+关键字(company_name pass)
搜索敏感密钥和密码的关键字列表可参考:random-robbie/keywords
1.1.1 google+github
1 | 邮箱配置信息泄露 |
1.1.1 github关键字设置
1 | 综合信息泄露: |
1.1.3 结果选择
- 搜索结果语言的设置,例如搜索的是特定语言java的配置文件,把搜索结果的语言设置为java,往往会更精确
- 排序的选择,优先考虑时间靠前的搜索结果,时间越靠前风险项越可能还存在
- 搜索的递归,通过组织找人,然后在该用户中进行信息的二次搜索。
1.2 自动化工具
设置关键字和提醒后,定期检测是否有泄露情况,推荐下面的自动化开源工具(自研会更好):
- Github-Monitor
- Gitrob
1.3 爬虫实践
1.3.1 github爬虫代码
使用方法:
1、修改登录参数:2、修改监控关键字(多个关键字用空格隔开):1
2
3loign_username = '**'
login_password = '**'
注:账号需要登录过网页端,且关闭二次认证
scan_keywords = [‘company_name accesskey’,’company_name database password’’]
注:github能取得上传时间,如需取上传时间,可以把121行代码注释打开,122行注释上。
全部代码如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129from bs4 import BeautifulSoup
import requests
import time,hashlib
loign_username = ''
login_password = ''
class GitScan(object):
def __init__(self):
self.search_url = "https://github.com/search?o=desc&p={page}&q={keyword}&ref=searchresults&s=indexed&type=Code&utf8=%E2%9C%93"
self.headers = {
'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36"}
self.cookies = ""
def _auto_login(self):
"""
登录github,获取cookie
:returns: None
"""
login_request = requests.Session()
login_html = login_request.get("https://github.com/login", headers=self.headers)
post_data = {}
soup = BeautifulSoup(login_html.text, "lxml")
input_items = soup.find_all('input')
for item in input_items:
post_data[item.get('name')] = item.get('value')
post_data['login'], post_data['password'] = loign_username, login_password
login_request.post("https://github.com/session", data=post_data, headers=self.headers)
self.cookies = login_request.cookies
if self.cookies['logged_in'] == 'no':
print('[!_!] ERROR INFO: Login Github failed, please check account in config file.')
exit()
def _get_page_html(self, url):
"""
获得请求的响应包
:param url: Requesting url
:returns: Parsed html page
"""
try:
page_html = requests.get(url, headers=self.headers, cookies=self.cookies,timeout=18)
if page_html.status_code == 429:
time.sleep(10)
self._get_page_html(url)
return page_html.text
except Exception as e:
print("[!_!] ERROR INFO: There is '%s' problem in requesting html page." % str(e))
return ''
@staticmethod
def _get_github_list(page_html):
"""
解析响应包获取内容、文件链接、更新时间
:param page_html: Html page content
:returns: Project list of per page
"""
cur_par_html = BeautifulSoup(page_html, "lxml")
github_urls = cur_par_html.select(
"#code_search_results > div > div > div > div.text-normal > a")
github_comments = cur_par_html.select("#code_search_results > div > div > div > div.blob-wrapper")
github_uploadtimes = cur_par_html.select(
"#code_search_results > div > div > div > div.d-flex > span.updated-at > relative-time")
return github_comments,github_urls,github_uploadtimes
def github_check(scan_keywords, page):
'''
请求github查询
:param scan_keywords 关键字
:param page
:return:
'''
scan_keywords = scan_keywords
git_scan = GitScan()
git_scan._auto_login()
keyword_length = len(scan_keywords)
res_json = {}
error_i,i = 0,1 #错误计数器、计数器
print('scan_keyword num:', keyword_length)
for scan_keyword in scan_keywords:
res_json[scan_keyword] = []
while i < page + 1:
if error_i >= 10: #重试次数太多可能是网络不通
print("maybe network error,please check network connection!")
return res_json
search_url = git_scan.search_url.format(page=i, keyword=scan_keyword)
page_html_parse = git_scan._get_page_html(search_url)
if page_html_parse:
error_i = 0
i += 1
(github_comments, github_urls, github_uploadtimes) = git_scan._get_github_list(page_html_parse)
else:
print("retry %s" %error_i)
error_i += 1
continue
if (len(github_urls) == 0):
break
print('search: ', search_url)
for u, c, d in zip(github_urls, github_comments, github_uploadtimes):
url = u.get('href')
# username = url.split('/')[1]
# filename = url.split('/')[-1]
real_url = "https://github.com" + url
uploadtime = d.get('datetime')
comment = str(c)
# MD5 = hashlib.md5()
# MD5.update(bytes(str(real_url) + scan_keyword, 'utf-8'))
#hash_url = MD5.hexdigest()
#res_json[scan_keyword].append({"url":real_url,"comment":comment,"uploadtime":uploadtime})
res_json[scan_keyword].append({"url":real_url,"comment":comment})
return res_json
if __name__ == '__main__':
#github只能搜索到前100页
scan_keywords = ['company_name accesskey','company_name database password']
res = github_check(scan_keywords,100)
print(res) #返回的是json格式,可接入vue前端展示
1.3.2 gitlab爬虫代码
使用方法:
1、修改登录参数:1
2login_token = "wttoE9x_6_PiE9MfT1AL" gitlab的token
gitlab_host = "127.0.0.1:8999" gitlab项目主域名,默认会加上http前缀,如果是https,需要写全,如:https://www.baidu.com
2、修改监控关键字(gitlab不支持复合查询,即只能查询单关键字):
scan_keywords = [‘pass’,’pay’,’key’]
全部代码如下:
1 | # coding=utf-8 |
2、Github安全实践十要点
- 1.不要将凭证作为代码/配置存储在GitHub中
- 2.删除文件中的敏感数据和GitHub历史记录
- 3.限制访问控制
- 4.增加SECURITY.md文件
- 5.严格验证GitHub上的第三方应用
- 6.在PR阶段添加安全性测试
- 7.选择合适的GitHub来满足安全需求
- 8.及时更换SSH key和个人访问token
- 9.创建新项目时就考虑到安全性
- 10.审核任何引入到GitHub的代码
2.1 不要将凭证作为代码/配置存储在GitHub中
在 github 上执行一次搜索删除密码操作(https://github.com/search?q=removed+password&type=Commits),
可以发现在 repo 中存储密码的情况是如此普遍,简单的搜索就返回来47万次 commit 记录,这还没有覆盖到没有填写详细的commit 信息,或者已经通过删除历史记录来掩饰活动的情况。总体而言这是由来已久的安全隐患。工具使用者应当遵循最佳实践来防止将敏感数据放置到代码库中。
对于企业内部的存量代码应当也有手段去解决存量的代码中的大量密码。通过工单肯定是不现实的。有一些有用的本地工具比如git-secrets,可以通过在 pre-commit 阶段对 Git 进行 hook 来执行静态分析,以确保不会将任何密码或敏感信息 push 到 GitHub 仓库中。如果该工具配置的正则表达式匹配到任何敏感信息就会拒绝这一次 commit。这样可能会让 push 阶段延时一些,但是还是值得去做的。
还可以在 CI 和 CD 的流水线中使用 git-secrets 之类的工具,以便在代码或配置文件中发现敏感信息时就主动终止构建活动。在团队范围内推行这类的规则是检测目前开发人员工作流程中的 “坏习惯” 的好办法。唯一正确的做法是使用现有 CI/CD 流水线工具如 Jenkins 或 TeamCity 来设置环境变量来保存或者传递敏感信息。当然还可以使用 Vault 之类的工具来帮助进行生产环境的密码管理。最后还可以考虑使用身份和用户管理类的工具链 - 如Keycloak(当前由 Red Hat 的的一些开发人员维护)。
应当在早期就尝试尽可能多使用多种手段去避免将凭据引入到仓库中,但是不可避免有些敏感信息依然有可能会被带入(工具对片段代码的漏报)。隐私应该考虑定期审核代码仓库,利用 GitRob 或 truffleHog 等工具,这两个工具都可以全量扫描代码库,通过模式匹配搜索敏感信息。另外一种好方法是对每次的 git diff 阶段建立 es 索引,不过工作量相对较大。
2.2 删除文件中的敏感数据和GitHub历史记录
如果已经在 GitHub 仓库中发现敏感数据就需要做一些应急来处理。第一步是需要将曾经过公开的 token 令牌和密码失效。一旦一个口令在互联网上公开,应该假设它已经被掌握在攻击者的手中,并做出相应动作。
当然,肯定还需要从仓库中删除敏感数据,但是不要忘记 GitHub 非常擅长保存所有 commit 的完整历史记录。包括列出敏感信息的修改日志。在从 repo 中删除敏感数据时,清除 GitHub 历史记录非常重要。有关更多信息,参考 https://help.github.com/en/articles/removing-sensitive-data-from-a-repository 。总是有通过git修改了密码,但是commit记录还存在的情况。
2.3 限制访问控制
我们可以一直专注于分析更复杂的攻击手段,但总是对一些最简单的事情上却失败得很惨。例如只需要一个开发人员在便利贴上留下他们的密码挂在电脑显示器上让攻击者访问。无论是在 GitHub 平台上,还是在一般场景下都应当遵守基本的安全设置。要求贡献者(contributors)遵循以下基本实践:
- 需要在每个贡献者的 GitHub 帐户上启用双因素身份验证。
- 永远不要让用户共享 GitHub 帐号 / 密码。
- 任何可以访问源代码的笔记本电脑 / 设备都必须得到适当的保护。
- 仓库配置管理员应该管理团队对数据的访问。只允许贡献者访问他们工作所需的数据。
- GitHub 账户通常是个人账户,用户离开公司后不会自然注销。确保及时检查离职用户的访问权限。
2.4 增加 SECURITY.md 文件
对于大多数项目所有者和维护者来说为仓库添加 README.MD 是很自然的,事实上人们也不愿意没有这个描述文件。同样,添加一个突出显示项目安全相关信息的 SECURITY.md 文件也变得越来越普遍。它不仅为用户提供了他们需要的重要安全信息,而且还迫使维护人员考虑如何处理安全披露、更新和一般的安全实践。可惜的是目前国内的开源项目大都未满足这样的条件,360代码卫士或者个人研究者提交的漏洞只能以issue方式暴露给大家。
以下是一个 SECURITY.md 文件大致应该涵盖的一些内容:
- 信息披露政策
2017 年 Snyk 开源安全报告显示,只有 21% 没有公开披露政策的维护者私下被告知存在漏洞。这使得 73% 的维护人员是公开的披露政策。安全说明了定义白帽子如何去负责任地披露安全问题的重要性。应该包括与谁联系以及如何联系。这很重要因为它允许从用户那里获得重要的反馈。其他人可能会将漏洞的存在作为一个公开 issue 进行日志记录,从而在修复方案发布之前无意中让全世界意识到漏洞的存在。当发现问题时,确保向用户提供了他们需要的所有信息,以便向项目维护者提供了正确的信息。 - 安全更新策略
软件漏洞每天都在被发现。当应用程序或库中已发现漏洞时,开发者有责任向用户说明。他们可能在关键系统的生产环境中使用的开放源代码。需要一个定义良好的流程来与他们共享相关信息,包括漏洞的严重性、带来的风险以及如何迁移到代码的release版本。预先定义此流程以便将信息推送给用户,允许用户在发现和修复新的安全漏洞时尽早更新这些漏洞。这可能与安全邮件列表一样简单。一个SECURITY.md 文件作为保存此类信息的主页,如果有一个网站可以考虑设置一个独立的页面-以 Express.js的网页https://expressjs.com/en/advanced/security-updates.html为例。 - 相关的安全配置
项目的安全性考虑超出了代码本身。用户可能需要配置的项目并创建设置,以便它在他们的环境中按需工作。应该为用户提供建议设置,以考虑在部署此项目时是否会加强他们的安全性。例如,打开 HTTPS、添加授权,当然还有替换默认密码 (许多 MongoDB 用户希望自己已经获得了这些指导=_=)。请记住,用户通常对安全性的理解相当低,因此提供任何建议都将极大地帮助他们。 - 已知的安全不足和后续的安全提升
很少有项目处于用户所希望的所有安全性改进都已实现的情况。通知用户当前尚未实现的安全控制措施很重要。使用者应了解全部情况,这样他们就可以对如何使用开源项目做出正确的决定。谁知道呢——或许用户可以主动贡献代码去实现你所提到的安全控制措施。在为用户提供加固环境所需的信息和为攻击者提供有限的信息之间需要做出权衡。始终要考虑双方如何使用你所分享出来的信息。
在 Apache Storm 和 TensorFlow 的代码仓库中可以看到 SECURITY.md 的优秀案例。2.5 严格验证 GitHub 上的应用程序
所有好的平台都可以扩展,GitHub 及其应用程序市场也不例外。在将它们添加到代码仓库时要记住第三方应用扩展是由组织和第三方开发人员编写的。在选择和安装 GitHub 应用程序时,请考虑以下几点:
- 不要给应用程序过多的访问权限。
- 询问为什么应用需要它所要求的访问级别,并考虑这种访问级别可能造成的危害。
- 在让应用背后的作者或组织访问代码库之前,验证他们的合法性和可信性,就像引入一个新的提交者一样。
- 安全性取决于最薄弱的环节,因此,如果要访问的应用的安全性较差,那么攻击者可以通过攻击它们的应用来访问你的代码——这是开发者最敏感的资产之一。
- 最后,确保定期检查或审计第三方应用及其贡献者,以确保仍然需要他们、信任他们、认为他们值得赋予权限去访问代码。
2.6 向 PR 阶段添加安全性测试
GitHub 有一个功能强大的事件驱动 Git hook 框架,它允许在触发事件时向所选择的服务器发送 HTTP POST 请求。你可以选择处理大量事件,但是对于测试增量代码更改最有用的事件之一是 pull_request 事件。有许多静态代码分析工具支持 Git Hook,当创建 PR 时,会触发一个 HTTP POST 来提示它们测试最新更新的代码。这是确保正在进行的代码和配置更改符合安全预期的最佳时机。
除了方便地集成到 GitHub 之外,pull request 请求比 “中断构建” 更好,因为它们不必阻止 merge(合并),以及 pr 阶段的这些能力用来测试代码变更,而不是已存在的代码(例如,如果你引入了一个易受攻击的库就 pr 会失败,而不是去检测历史已经存在的高危组件)。
Snyk、SonarCloud 和 CodeClimate 工具都可以在自动进行代码 review 审核,自研也是一个出路,可以更好兼容于研发流程。2.7 选择合适的 GitHub 来满足安全需求
根据项目或组织制度,开发者可能被限制使用只能在本地运行的软件。或者这些限制可能是针对源代码存储在何处、哪些其他组织也可以访问。金融机构、政府部门或其他受到严格监管行业的普遍限制如此。然而这并不意味着你不能使用 GitHub!
考虑下完整版的 on-prem GitHub 企业版,它允许在组织中完全托管 GitHub 仓库。这意味着可以断开与 internet 的连接,并且仍然可以访问 GitHub 企业仓库中的项目。甚至 GitHub 都不能访问你的代码库!2.8及时更换SSH key和个人访问token
GitHub 访问通常使用 SSH 密钥或个人用户令牌 (代替密码,因为已经启用了双因素身份认证!) 但是如果这些 token 被窃取了但你不知道如何处理? 请确保定期更新密钥和 token以降低密钥泄漏造成的任何损失。2.9 创建新项目时就考虑到安全性
当创建一个新项目时,开发人员通常会很愉快地去进行修改、走捷径以便让应用程序启动并运行。这可能会导致开发人员草率处理密码之类的敏感信息,密码可能是硬编码的或者存储在本地配置中比如属性文件。不那么安全的认证措施包括:依赖一个私有加密算法来授权输入,或者暴露如何选择的随机种子。即使对于一个私有的源代码项目,用开源的思想来选择随机数也是一个很好的实践。如果时刻想着去编写其他人将看到并可能去复用的代码,才更有可能编写出更安全的代码。
此外,如果曾经想过要开放源代码,那么就会更容易、更安全,因为已经在以更安全的开放心态考虑问题,所以不会错过隐藏在代码中的密码或密钥。对于数据安全的敏感性组织可以自助度量,有的公司不容许泄露任何个人,但是笔者看到谷歌的项目里甚至都有作者的邮箱地址。2.10 审核任何引入到GitHub的代码
当你将项目或大量代码引入到 GitHub 时,这里将很好地引导了你要做的事情。 导入到 GitHub 的源代码可能已存在数月或数年,并且可能已在封闭的源代码仓库中开发。 这可能导致在封闭源代码环境中做出的许多曾经合理的假设现在都是无效的。在将任何内容引入 GitHub 之前,一定要确保进行了完整的审计。对于较小的项目来说这可能是个顺手的测试,但是一旦代码库达到一定的大小,团队可能需要花费数周或数月的时间来完全审计、更新和导入一个开源仓库。
要进一步了解 GitHub 安全性,请确保阅读了 GitHub 安全文档和 GitHub 业务安全站点,以获得诸如外部 auth/SAML 支持等额外特性。
3、 总结
本文探究了github敏感信息收集方法和安全要点,github信息泄露风险普遍存在,包括但不限于硬编码用户名和密码、硬编码的API密钥、硬编码OAuth令牌、内部服务和环境配置,企业怎么安全使用github与监控github泄露成为安全部门的重要工作之一。
参考链接:
GitHub安全最佳实践
Github信息收集
GitHub Recon and Sensitive Data Exposure
本文链接: http://dayun.shystartree.online/2020/03/27/%E4%BD%BF%E7%94%A8github%E8%BF%9B%E8%A1%8C%E4%BF%A1%E6%81%AF%E6%94%B6%E9%9B%86%E4%B8%8E%E5%AE%89%E5%85%A8%E9%98%B2%E5%BE%A1/
版权声明:本博客所有文章除特别声明外,均采用知识共享署名-非商业性使用-相同方式共享4.0国际许可协议许可协议。欢迎转载,但转载请注明来自qingyu’s blog,并保持转载后文章内容的完整,本人保留所有版权相关权利。