之前,我从没参加过GitHub官方的一些漏洞众测项目,在HackerOne发起的HackTheWorld比赛中,主办方宣传除了赏金以外,还有机会获得Github提供的终身无限制私有库(unlimited private repositories)使用权,这激发了我的挖洞兴趣。经过努力,我发现了Github Organization的一个高危提权漏洞,可以利用 GitHub 应用,实现从Organization成员(Member)到所有者(Owner)的权限提升。最终我也获得了GitHub官方 $10000美金奖励。
背景介绍
首先,我们要来了解一下Github 组织( Organization ) 账号的角色,我在这里着重讲一下组织账号所有者的功能,以及其最小权限设置问题。
GitHub Organization:除了个人帐户之外,GitHub 还提供被称为组织(Organizations)的帐户,组织帐户代表了一组共同拥有多个项目的人,同时也提供一些工具用于对成员进行分组管理。GitHub推出了组织这一新的账号管理模式,以满足大型开发团队的需要。组织账号是非登录账号,不能像创建普通登录账号那样直接创建,而是需要以GitHub用户身份登录,然后再创建自己的组织,创建者成为组织原有的管理者(Owner)。 GitHub Organization适用于商业用途和大型开源项目。
Outside collaborator:外部协作者,从完整性和技术角度上来说,该角色不可以创建库(repository),但是只对组织内部特定库有访问权限。对一个 organization 分组来说,有Members 和 Outside collaborators两类成员,但不论 member,还是 outside collaborator,都是 collaborator(协作者)。
Member:成员,组织( Organization )分组内权限最低的角色,按照不同的组织设置,有些Member仅只限于对某些子库具备查看或写权限。能对特定库(Repository)大多数设置进行修改的库(Repository)管理员具备对Member成员访问权限的分配指定。
Team:团队,由若干 Member 组成,参与若干库Repository,Team 是 Organization 内部的管理内容,不对外公开。Member 在一个 Organization 中可以加入多个 Team。
Owner :组织所有者,通常做法是先注册一个 user 账号,在这个账号下创建一个 Organization,你就是这个 Organization 分组的 Owner。所有者是组织分组内的最高权限管理角色,和管理员相当,该角色可以查看编辑所有组织和库数据,当然,更严重的是,它能不可逆地删除整个组织分组的所有数据和代码信息。
在GitHub应用中,组织分组(Organization)功能被广泛应用,在其通常的访问控制策略中,只要设置适当(如不分配所有组织库的管理权限),分组成员(Member)权限是不会形成安全威胁的。由于在一个组织分组中可以加入多个团队( Team),通常的设置模型是把成员(Member)归类为不同Teams,以此便于成员对不同库的访问权限控制。使用这种模型,因为基于Team的权限控制足以在必要时提供权限扩展,所以组织所有者最终面对的只是一些非常小的用户限分子集。
深入分析 GitHub 应用程序
在以组织所有者身份(Owner)对组织分组功能深入分析过后,我发现了一个“第三方访问策略”开关,该设置的目的是通过OAuth app应用方式防止组织成员,向不受信任的第三方授予组织分组内存储库(Repository)的访问权限。启用该功能后,OAuth会跳出一个权限请求提示,然后需要组织所有者批准该请求,成员才能访问任何组织分组内的数据。
接下来,我要来分析的是一些集成功能(Integration)的app应用,这种集成类app与OAuth app功能类似,只是它们的操作代表的是组织分组,而非像 OAuth app 的用户。我的想法是去检查 “第三方访问策略” 是否也适用于这种集成应用上,或者是就根本没有这种访问策略设置。我来到GitHub 开发工具市场 Marketplace 页面,分析了一些简单应用(app)的安装过程。结果明显的是,作为组织成员,只能将集成类app安装到自己所属的帐户中,或者安装到你拥有的组织分组中。我后来在Github 说明文档中找到了以下解释。
Organization members can’t request a GitHub App installation.
组织分组成员不能请求安装GitHub应用程序。
在对集成类app的安装过程过程中,我注意到,在选择了 “Billing account”(账单账号)之后,会出现一个和以下URL链接对应的页面:
https://github.com/apps/:app_name/installations/new/permissions?target_id=:id
其中,看到target_id,这是不是可以做点文章呢?它可以是 organization_id 或是安装应用(app)身份的 account_id。理所当然的,我会想到,如果用另外一个组织分组来替换这个组织的安装过程会是怎样呢?所以,我以另外一个组织成员(member)的身份,把上述对应URL链接中原先组织的 target_id 替换成另外一个组织的 organization_id。由于我在另外组织的成员身份(Member)是库(Repository)管理员,所以,按照Github说明文档规定,我只能把集成类app安装到我自己管理的库(Repository)中。但当我用当前组织所有者(Organization Owner)身份,查看当前组织内已安装的Github 应用(Installed GitHub Apps)时,竟然,这个集成类app已经安装成功!
做完这波测试,此时已是凌晨3点了,这种间接绕过 “第三方访问策略” 限制的方式肯定会是一个有效漏洞,我一鼓作气马上向Github官方安全团队作了上报,当然我也在报告中作了备注,希望之后能有更多深入发现。
提权测试
第二天,我想是否能再深入对这个漏洞进行一些利用,由此,在创建安装了GitHub集成类app之后,我发现可以发起的请求权限非常敏感,特别是允许所有组织成员(Member)和团队(Team)的写权限。按照Github说明文档的规定,如果我能对某个我自己的可管理库(Repository)具备安装某些集成类app的权限,那么我的身份顶多也就是一个库管理成员(Member),当然也不能对组织内其它成员授予写权限咯,但真实情况是,我可以的!因为Github的预期设计是只有组织所有者才能安装集成类app,在这种最高权限下,默认组织所有者具备授权权限。像以下安装app时,会默认具备多种权限:
接下来,我要看看内置相应的API是否能够正常预期工作而不会发生任何权限错误,最终,我可以互相利用一些服务端,在某个角色参数帮助下添加或更新组织成员身份,在此场景下,我还能邀请其它用户以账户所有者身份加入该组织分组。像下图中,我可用不具备权限的“OrgMember” 账户去安装集成类app,也能通过API以所有者身份邀请 “NewMember”账户加入当前组织。
总结
该漏洞可能会被某些组织内的库管理员利用,但经过调查分析,我发现,所有允许成员创建库的组织(Organization)都会存在该漏洞,因为这样一来,创建库的成员可以通过创建虚拟库的方式来安装app,该功能在Github中是默认的,通常来说,由于GitHub支持模型不再与库绑定,所以大多数组织内的该功能也是启用的。
另外,该漏洞的利用主体除了组织内成员,还可能是其他入侵掌握了组织成员的恶意攻击者。假设某组织分组包含300名成员,那么对攻击者来说,他的攻击面就非常之大了。
漏洞上报进程
2017/11/11 凌晨 3:30 漏洞初报
2017/11/11 晚上8:30 深入发现提权漏洞
2017/11/13 早上5:30,GitHub官方分析漏洞
2017/11/14 下午 1:40,GitHub发放 $10,000 赏金
2017/11/15 新版本Github应用中漏洞修复
2017/12/1 Github彻底修复该漏洞
*参考来源:medium,clouds 编译,转载请注明来自 FreeBuf.COM