• XSS.stack #1 – первый литературный журнал от юзеров форума

IOS: SMS text message forwarding plug-in development

boxilai

(L3) cache
Пользователь
Регистрация
08.09.2023
Сообщения
164
Реакции
51
Депозит
0.0096 Ł
1. Tools
mac system
Jailbroken iOS device: unpacking and frida debugging
IDA Pro: Static Analysis
Test device: iphone6-ios12.5.5

2.
Corresponding configuration directory:

/Library/LaunchAgents: Administrator controls agents for specific users

/Library/LaunchDaemons: System-level daemons provided by the administrator (cydia, filza, frida, etc. are here)

/System/Library/LaunchDaemons: The default daemon process provided by iOS

Use the file management tool on the iPhone to view the key information of the /System/Library/LaunchDaemons/com.apple.imagent file as follows:
Код:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>EnvironmentVariables</key>
    <dict>
        <key>NSRunningFromLaunchd</key>
        <string>1</string>
    </dict>
    <key>ProgramArguments</key>
    <array>
        <string>/System/Library/PrivateFrameworks/IMCore.framework/imagent.app/imagent</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
</dict>
</plist>

The path corresponding to ProgramArguments is the binary file executed by the process. After executing frida-trace -U -m "*[IM* *]" imagent -o a.log, the log after the phone receives the text message is as follows:
Код:
-[SMSServiceSession smsMessageReceived:0x10524abc0 msgID:0x80000006]
-[SMSServiceSession _processSMSorMMSMessageReceivedWithContext:0x10524abc0 messageID:0x80000006]
+[IMMetricsCollector sharedInstance]
-[IMMetricsCollector trackEvent:0x1d02ab1e8]
-[SMSServiceSession _convertCTMessageToDictionary:0x109a0e510 requiresUpload:0x16f832c2f]
-[IMMetricsCollector _trackEvent:0x1d02ab1e8]
-[SMSServiceSession _fixIncomingDate:0xd13d420d70d597e6]
-[SMSServiceSession shouldFixIncomingDate]
-[SMSServiceSession _myCTPhoneNumber]
+[IMCTSubscriptionUtilities sharedInstance]
-[IMCTSubscriptionUtilities deviceSupportsMultipleSubscriptions]
+[IMCTSubscriptionUtilities sharedInstance]
-[IMCTSubscriptionUtilities deviceSupportsMultipleSubscriptions]
+[IMCTSMSUtilities IMMMSEmailAddressToMatchForPhoneNumber:0x100830240 simID:0x0]
+[IMCTSubscriptionUtilities sharedInstance]
-[IMCTSubscriptionUtilities deviceSupportsMultipleSubscriptions]
-[SMSServiceSession _convertCTMessagePartToDictionary:0x109a28610]
-[SMSServiceSession _shouldUploadToMMCS:0x10524aca0]
-[SMSServiceSession _receivedSMSDictionary:0x10524aca0 requiresUpload:0x0 isBeingReplayed:0x0]
-[SMSServiceSession _processReceivedDictionary:0x10524aca0 storageContext:0x0]
+[IMMessageNotificationTimeManager sharedInstance]
-[IMMessageNotificationTimeManager acquireAssertionToUnsuspendProcess]
+[IMLockdownManager sharedInstance]
-[IMLockdownManager isInternalInstall]
-[IMLockdownManager _calculateInstallType]
-[IMMessageItem initWithSender:0x100890210 time:0x1008831d0 body:0x10083ba80 attributes:0x0 fileTransferGUIDs:0x1007081d0 flags:0x1 error:0x0 guid:0x10524acc0]
-[IMMessageItem initWithSender:0x100890210 time:0x1008831d0 body:0x10083ba80 attributes:0x0 fileTransferGUIDs:0x1007081d0 flags:0x1 error:0x0 guid:0x10524acc0 type:0x0]
-[IMMessageItem initWithSenderInfo:0x10085c330 time:0x1008831d0 timeRead:0x0 timeDelivered:0x0 timePlayed:0x0 subject:0x0 body:0x10083ba80 bodyData:0x0 attributes:0x0 fileTransferGUIDs:0x1007081d0 flags:0x1 guid:0x10524acc0 messageID:0x0 account:0x0 accountID:0x0 service:0x0 handle:0x0 roomName:0x0 unformattedID:0x0 countryCode:0x0 expireState:0x0 balloonBundleID:0x0 payloadData:0x0 expressiveSendStyleID:0x0 timeExpressiveSendPlayed:0x0 bizIntent:0x0 locale:0x0 errorType:0x0 type:0x0]
-[IMItem initWithSenderInfo:0x10085c330 time:0x1008831d0 guid:0x10524acc0 messageID:0x0 account:0x0 accountID:0x0 service:0x0 handle:0x0 roomName:0x0 unformattedID:0x0 countryCode:0x0 type:0x0]
-[IMItem setSenderInfo:0x10085c330]

According to the log, we can see the key function -[SMSServiceSession smsMessageReceived:0x10524abc0 msgID:0x80000006]. Use the command frida-trace -U -m "-[SMSServiceSession smsMessageReceived:msgID:]" imagent to trace this function. The js code is as follows:
Код:
{
  onEnter(log, args, state) {
    log(`-[SMSServiceSession smsMessageReceived:${ObjC.Object(args[2])} msgID:${args[3]}]`);
  },
  onLeave(log, retval, state) {
  }
}
When the mobile phone receives a text message, the corresponding log output is as follows:
Код:
-[SMSServiceSession smsMessageReceived:<CTXPCServiceSubscriptionContext 0x10bfd1240 slotID=CTSubscriptionSlotOne, uuid=00000000-0000-0000-0000-000000000001, labelID="90D990CE-3484-4310-9F39-49A66EB80541", label="USER_LABEL_PRIMARY", phoneNumber="+861812186xxxx", userDataPreferred=1, userDefaultVoice=1> msgID:0x80000010]

According to the log information, this method does not contain the SMS and sender-related information we need except msgID. Then we continue to look down in the order of the log, -[SMSServiceSession _convertCTMessageToDictionary:requiresUpload:] This function looks more friendly. Trace the function and get the log as follows:
Код:
-[SMSServiceSession _convertCTMessageToDictionary:<[CTMessageAddress: 189xxxxxx/TYPE=PLMN]
    [Recipients: (
)]
    [Items: (
    "<CTMessagePart: 0x10be7f340>"
)]
    [Raw Headers: (null)]
    [Date: 2023-07-30 14:43:23 +0000]
    [message ID: -2147483630]
    [message Type: 1]
    [service center: (null)]
    [Content-type: (null)]
    [Content-type params: {
}]
    [replace message: 0]
 requiresUpload:0x16edaec2f]
-[SMSServiceSession _convertCTMessageToDictionary:requiresUpload:]={
    co = "+86181xxxxxx";
    g = "00ECAC3B-0790-8674-CAD5-58DD07F4DEBA";
    h = 189xxxxxx;
    k =     (
                {
            data = <e58fa6>;
            type = "text/plain";
        }
    );
    l = 0;
    m = sms;
    n = 460;
    re =     (
    );
    sV = 1;
    w = "2023-07-30 14:43:25 +0000";
}}=
It can be seen from the log. This method is the hook method we want, recipient: co, sender: h, text message content: k

The source code is as follows:
Код:
#import <Foundation/Foundation.h>
#import "CaptainHook/CaptainHook.h"

@interface SMSServiceSession

@end

@interface IMDService

-(void)loadServiceBundle;
@property (nonatomic,retain,readonly) NSBundle * bundle;

@end

CHDeclareClass(SMSServiceSession); // declare class
CHOptimizedMethod2(self, id, SMSServiceSession, _convertCTMessageToDictionary, NSDictionary *, arg1, requiresUpload, BOOL*, arg2) {
    id result = CHSuper2(SMSServiceSession, _convertCTMessageToDictionary, arg1, requiresUpload, arg2);

    @try {
        NSString *from = result[@"h"];
        NSString *to = result[@"co"];
        NSArray *msgList = result[@"k"];
        if (msgList.count > 0) {
            NSData *data = msgList[0][@"data"];
            NSString *content = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
            NSLog(@"witwit =from %@=to %@=content %@=",from, to, content);
        } else {
            NSLog(@"witwit =sms为空=");
        }
    } @catch (NSException *exception) {
        NSLog(@"witwit =SMSServiceSession _convertCTMessageToDictionary=err=%@=", exception);

    } @finally {

    }

    return result;
}

CHDeclareClass(IMDService)
CHOptimizedMethod0(self, void, IMDService, loadServiceBundle) {

    CHSuper0(IMDService, loadServiceBundle);
    NSString *bundleId = [[self bundle] bundleIdentifier];
    NSLog(@"witwit =IMDService loadServiceBundle=%@=", bundleId);

    if ([bundleId isEqualToString:@"com.apple.imservice.sms"]) {
        CHLoadLateClass(SMSServiceSession);
        CHHook2(SMSServiceSession, _convertCTMessageToDictionary, requiresUpload);
    }
}

CHConstructor // code block that runs immediately upon load
{
    @autoreleasepool
    {
        NSLog(@"witwit SMSForward load success");

        CHLoadLateClass(IMDService);
        CHHook0(IMDService, loadServiceBundle);
    }
}
The info.plist file is configured as follows:
Код:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Filter</key>
    <dict>
        <key>Bundles</key>
        <array>
            <string>com.apple.imagent</string>
        </array>
    </dict>
</dict>
</plist>
After the plug-in installation is completed. Please restart imagent:
Код:
launchctl unload /System/Library/LaunchDaemons/com.apple.imagent.plist
launchctl load /System/Library/LaunchDaemons/com.apple.imagent.plist
 
This article mainly analyzes and tests the core method of the SMS forwarder. After getting the SMS content, please implement the specific forwarding logic by yourself.

My English is not my native language. There may be some problems in my expression. Welcome to consult and correct me.
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх