Coder Social home page Coder Social logo

Comments (23)

Dadoum avatar Dadoum commented on August 15, 2024

I am pretty sure it does not exists on iOS, as they call it "ADISetAndroidID". You could try to pass the same message to vdfut768ig (which is the function doing all the logic in CoreADI), but they may not use the same convention/magic values for the arguments.

from provision.

shanling2016 avatar shanling2016 commented on August 15, 2024

I don't quite understand... I found that AKADIProxy exists in the AKD program
But... this symbol is in CoreADI, do I mean akd references it

from provision.

Dadoum avatar Dadoum commented on August 15, 2024

Yeah AKADIProxy provides the same features as StoreServicesCore on Android, (and some of them are in StoreServices on iOS too). But the underlying CoreADI framework implementation is different. They are seemingly not derived from the same source code. To my knowledge, there are at least 5 distinct CoreADI libraries, and maybe even more anisette implementations.

from provision.

Dadoum avatar Dadoum commented on August 15, 2024

Btw, if you want to try, you might want to call that vdfut768ig with the magic number of the function you are looking for. I haven't tried, and it might not work if they changed all the magic numbers across platforms, but if it does, you will get -45019 (unknown function) if the function does not exist, and -4500x (invalid parameter) if it has been implemented but you provided the wrong arguments.

from provision.

shanling2016 avatar shanling2016 commented on August 15, 2024

My idea is to use Unidbg to call and generate OTP. If possible, I want to use AKAppleIDCodeGenerator to generate verification code, but many test results have shown that it cannot be implemented on libstoreservicescore

from provision.

shanling2016 avatar shanling2016 commented on August 15, 2024

And calling AKADIProxy through Unidbg loading/System/Library/PrivateFrameworks/AuthKit.framework/akd also encountered some kind of error, seemingly due to its use of process communication resulting in -45016 error

from provision.

shanling2016 avatar shanling2016 commented on August 15, 2024

Oh... I seem to have found my solution, thank you for your help!

from provision.

Dadoum avatar Dadoum commented on August 15, 2024

By the way, if you know what was causing 45016, that would be useful since I try to document every ADI error code

from provision.

shanling2016 avatar shanling2016 commented on August 15, 2024

The reason for the occurrence of -45016 seems to be due to the failure of this system call

十二月 10, 2023 11:06:28 下午 com.github.unidbg.ios.ARM64SyscallHandler mach_msg_trap
警告: mach_msg_trap header=MachMsgHeader(unidbg@0xfbffffbd0) (24 bytes) {
  int msgh_bits@0x0=0x80001513
  int msgh_size@0x4=0x0001
  int msgh_remote_port@0x8=0x0000
  int msgh_local_port@0xC=0x0004
  int msgh_voucher_port@0x10=0x0000
  int msgh_id@0x14=0x04B0
}, size=24, lr=RX@0x100521b0c[libsystem_kernel.dylib]0x1b0c

I understand from this information that /System/Library/PrivateFrameworks/AuthKit.framework/akd does not have any substantial Otp calculations

from provision.

shanling2016 avatar shanling2016 commented on August 15, 2024

The analysis of CoreADI in the future may be a significant challenge for me

from provision.

Dadoum avatar Dadoum commented on August 15, 2024

I can give you some help on Discord if you want

from provision.

xoridius avatar xoridius commented on August 15, 2024

AKAppleIDCodeGenerator

@shanling2016 could you please tell if you have found a way to generate otp code as from AKAppleIDCodeGenerator.generateLoginCode()? Is this based on anisette otp base64 data (X-Apple-I-MD) or special call to adid is needed?

from provision.

shanling2016 avatar shanling2016 commented on August 15, 2024

AKAppleIDCodeGenerator

@shanling2016 could you please tell if you have found a way to generate otp code as from AKAppleIDCodeGenerator.generateLoginCode()? Is this based on anisette otp base64 data (X-Apple-I-MD) or special call to adid is needed?

I think it is based on a special call to adid, which can be verified by deleting or renaming the adid file. Before that, you need to kill the process first

from provision.

xoridius avatar xoridius commented on August 15, 2024

@shanling2016 @Dadoum it is certain,

Some observations regarding the CoreADI framework in macOS:

  1. The CoreADI framework isn't dynamically used (no instances of dlopen or dlsym). Instead, it's statically linked into the ADID executable daemon found at /System/Library/PrivateFrameworks/CoreADI.framework/adid. Interestingly, CoreADI is not compiled for Apple Silicon as it lacks an ARM64 slice.
  2. The ADID daemon is heavily obfuscated and doesn't export worker functions like vdfut768ig or cvu8io98wun. Managed by launchd, it's shielded with PT_DENY_ATTACH. To attach a debugger, one may need to delve into kernel-level debugging...
  3. IPC: Libraries exposing external symbols (e.g., aslgmuibau in AuthKit.framework/akd, AOSKit.framework, AppleMediaServices.framework) communicate with ADID using low-level IPC, specifically Mach Ports with MIG (refer to mach_msg, mig_get_reply_port, NDR_record). The code paths leading up to mach_msg are obfuscated. ADID registers its port using bootstrap_check_in with name com.apple.adid and processes messages in a run loop created with CFMachPortCreateRunLoopSource.

Message for generating a login code might look something like this (with msgh_id 1200 or 1300):

typedef struct {
    mach_msg_header_t header; // Mach message header, 4 bytes
    int v13;                  // Custom field, 4 bytes
    int64_t v14;              // Custom field, 8 bytes (possibly a 64-bit integer or pointer)
    int v15;                  // Custom field, 4 bytes
    int v16;                  // Custom field, 4 bytes
    NDR_record_t NDR;         // Network Data Representation record, 32 bytes
    int v18;                  // Custom field, 4 bytes
} my_mach_msg_t;

When attempting to trace register activity with LLDB and Frida, I couldn't locate any references to the generated code near the mach_msg calls. Significant logic might be hidden within the wrappers, or maybe I was observing the wrong registers.

A solution for macOS might be loading both libraries and using DYLD_INTERPOSE stubs to add a shim for Mach messaging. But how difficult would it be to emulate in Unicorn or anything else? Or maybe repack for Darling on Linux?


Script to generate 2fa login code from another process:

#/usr/bin/osascript -l JavaScript -i
ObjC.bindFunction('dlopen', ['void*', ['char*', 'int']]);
$.dlopen('/System/Library/PrivateFrameworks/AuthKit.framework/Versions/A/Support/akd', 0xa);
const AKAppleIDCodeGenerator = $.NSClassFromString($.NSString.alloc.initWithUTF8String('AKAppleIDCodeGenerator'));
AKAppleIDCodeGenerator.generateLoginCode(undefined);
sudo lsmp -p $(pgrep osascript) | grep adid # confirm IPC for launched script
sudo fs_usage | grep adi
21:26:33  lstat64           private/var/db/.AppleSetupUser                    0.000031   adid        
21:26:33  lstat64           private/var/setup>>>>>>>                          0.000008   adid        
21:26:33  lstat64           private/var/db/fpsd/adi                           0.000026   adid        
21:26:33  lstat64           private/var/db/fpsd/adi/adi-gb                    0.000022   adid        
21:26:33  getxattr          private/var/db/fpsd/adi                           0.000069   adid        
21:26:33  umask                                                               0.000001   adid        
21:26:33  open              private/var/db/fpsd/adi/adi-gb.lck                0.000066   adid        
21:26:33  umask                                                               0.000001   adid        
21:26:33  fstat64                                                             0.000005   adid        
21:26:33  fcntl                                                               0.000004   adid        
21:26:33  statfs64          /private/var/db/fpsd/adi/adi-gb.lck               0.000011   adid        
21:26:33  fcntl                                                               0.000006   adid        
21:26:33  lstat64           private/var/db/fpsd/adi/adi.pb                    0.000013   adid        
21:26:33  lstat64           private/var/db/.AppleSetupUser                    0.000007   adid        
21:26:33  lstat64           private/var/setup>>>>>>>                          0.000005   adid        
21:26:33  fcntl                                                               0.000003   adid        
21:26:33  close                                                               0.000006   adid  

from provision.

Dadoum avatar Dadoum commented on August 15, 2024

@xoridius I mostly figured out how calls to vdfut768ig work.

The message structure you gave reminds me of the structure of a vdfut768ig call:

typedef struct {
    mach_msg_header_t header; 
    int v13;                  // Magic number referring to the function called?
    int64_t v14;              // Pointer to the ADICall structure. Size of it is max(8 + inputSize, outputSize) 
    int v15;                  // Input size
    int v16;                  // Output size
    NDR_record_t NDR;         // ...
    int v18;                  // ...
} my_mach_msg_t;

And an ADICall is made of a data encryption type int (telling how the following data is encrypted. It's generally 1 or 2. 2 is the unencrypted type, if you want to try to make a call), then the remaining is encrypted accordingly. Decrypted, the following fields are an unknown int (which is constant set to 1) and then the arguments in order. Then, after the call, the ADICall structure is overwritten and the data is replaced by the output, which generally consists of an int (and thus the output size is set to 4), which is the return code of the call.

from provision.

Dadoum avatar Dadoum commented on August 15, 2024

@xoridius do you have a discord account?

from provision.

Dadoum avatar Dadoum commented on August 15, 2024

After further investigation, no, Sph98paBcz doesn't exist on macOS, and is not implemented in the executable. Sorry.

from provision.

shanling2016 avatar shanling2016 commented on August 15, 2024

After testing, it was found that in lower versions of OSX systems, the OTP challenge was carried out through akd dynamic linking, which also includes AKAppleIDCodeGenerator, which may serve as an entry point

from provision.

xoridius avatar xoridius commented on August 15, 2024

@shanling2016

  • Which version of OSX are you referring to?
  • Does this OSX version allow generating 2FA codes from the Settings app? This is particularly interesting considering the Apple support page mentions that "trusted devices running iOS 9 and later, OS X El Capitan and later, etc., display the verification code automatically on your trusted devices". And akd from iOS 9.3.6 13G37 year 2019 already relies on adid daemon.
  • Does akd use vdfut768ig? What's the calling convention?

Some magic numbers for calls to test:

  • ADIGenerateCode: 0x385b2ce8 (generate 2FA login code)
  • ADIOTPRequest: 0xcfe0b46a
  • ADIGetIDMSRouting: 0x85fe63b0
  • AKADIProxy.isMachineProvisioned: 0xb0eda7af

from provision.

shanling2016 avatar shanling2016 commented on August 15, 2024

@xoridius
I found dlopen loading CoreADI in akd in macOS 10.12.
The following is the data I captured through Frida

{
        "base": "0x1093ae000",
        "name": "CoreADI",
        "path": "/System/Library/PrivateFrameworks/CoreADI.framework/CoreADI",
        "size": 1503232
}

from provision.

shanling2016 avatar shanling2016 commented on August 15, 2024

@xoridius
Do you know the magical number to overload adi.pb with adid?
I hope to switch between different devices by modifying the adi.pb file, but Every time we need to restart the adid process, it's really too slow

Before that, I also tried writing code using xcode to send messages to com.apple.adid, but…… it told me 0x1000000F "Invalid msg type specification"

bootstrap_look_up(bootstrapPort, "com.apple.adid", &port);

message.header.msgh_bits = 0x80131513;
message.header.msgh_size = 0;
message.header.msgh_remote_port = port;
message.header.msgh_local_port = mig_get_reply_port();;
message.header.msgh_id = 1200;
message.header.msgh_voucher_port = MACH_PORT_NULL;

/* Ignoring partial code */

mach_msg_return_t res = mach_msg((mach_msg_header_t*)&message, MACH_SEND_MSG, sizeof(message), 0, 0, 0, 0);

from provision.

xoridius avatar xoridius commented on August 15, 2024

@shanling2016 oh nice, that's Sierra, right? I was about to check High Sierra, looking for working boot image.
Not sure about magic code to reset adi.pb, but maybe eraseProvisioningForDSID will work? Can get those.

@interface AKADIProxy : NSObject

+(int)getIDMSRoutingInfo:(*NSUInteger)arg0 forDSID:(NSUInteger)arg1 ;
+(int)setIDMSRoutingInfo:(NSUInteger)arg0 forDSID:(NSUInteger)arg1 ;
+(int)requestOTPForDSID:(NSUInteger)arg0 outMID:(*char *)arg1 outMIDSize:(*unsigned int)arg2 outOTP:(*char *)arg3 outOTPSize:(*unsigned int)arg4 ;
+(int)dispose:(*void)arg0 ;
+(int)isMachineProvisioned:(NSUInteger)arg0 ;
+(int)startProvisioningWithDSID:(NSUInteger)arg0 SPIM:(char *)arg1 SPIMLength:(unsigned int)arg2 outCPIM:(*char *)arg3 outCPIMLength:(*unsigned int)arg4 outSession:(*unsigned int)arg5 ;
+(int)endProvisioningWithSession:(unsigned int)arg0 PTM:(char *)arg1 PTMLength:(unsigned int)arg2 TK:(char *)arg3 TKLength:(unsigned int)arg4 ;
+(int)destroyProvisioningSession:(unsigned int)arg0 ;
+(int)synchronizeWithDSID:(NSUInteger)arg0 SIM:(char *)arg1 SIMLength:(unsigned int)arg2 outMID:(*char *)arg3 outMIDLength:(*unsigned int)arg4 outSRM:(*char *)arg5 outSRMLength:(*unsigned int)arg6 ;
+(int)eraseProvisioningForDSID:(NSUInteger)arg0 ;

@end

Do you have discord? (Contact me at @bfmxor)

from provision.

xoridius avatar xoridius commented on August 15, 2024
#import <mach/mach.h>
#import <bootstrap.h>

typedef struct {
    mach_msg_header_t header;
    mach_msg_body_t body;
    mach_msg_ool_descriptor_t ool_ports;
    NDR_record_t NDR;
    uint32_t p1;
} adi_mach_msg_t;

unsigned long ADIGenerateCode(void) {
    mach_port_t p = MACH_PORT_NULL;
    bootstrap_look_up(bootstrap_port, "com.apple.adid", &p);
    printf("bootstrap_look_up(com.apple.adid)=%d\n", p);
    
    adi_mach_msg_t *m = malloc(64);
    
    m->header.msgh_bits = MACH_MSGH_BITS_COMPLEX | MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND_ONCE);
    m->header.msgh_size = 0;
    m->header.msgh_local_port = mig_get_reply_port();
    m->header.msgh_remote_port = p;
    m->header.msgh_id = 1200;
    m->header.msgh_voucher_port = 0;

    m->body.msgh_descriptor_count = 1;
    
    char cmd[] = {
        0x00, 0x00, 0x00, 0x01, 0x38, 0x5b, 0x2c, 0xe8,
        0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xfe
    };
    
    m->ool_ports.address = &cmd;
    m->ool_ports.deallocate = 0;
    m->ool_ports.copy = MACH_MSG_VIRTUAL_COPY;
    m->ool_ports.pad1 = 0;
    m->ool_ports.type = MACH_MSG_OOL_DESCRIPTOR;
    m->ool_ports.size = 20;

    m->NDR.mig_vers = 0;
    m->NDR.if_vers = 0;
    m->NDR.reserved1 = 0;
    m->NDR.mig_encoding = 0;
    m->NDR.int_rep = 1;
    m->NDR.char_rep = 0;
    m->NDR.float_rep = 0;
    m->NDR.reserved2 = 0;
    m->p1 = 0x00000014;
    
    mach_msg_option_t option = MACH_SEND_MSG | MACH_RCV_MSG;
    mach_msg_size_t send_size = 56;
    mach_msg_size_t rcv_size = 64;
    mach_port_name_t rcv_name = mig_get_reply_port();
    
    mach_msg_header_t *msg = (mach_msg_header_t *)m;
    mach_msg_return_t ret = mach_msg(msg, option, send_size, rcv_size, rcv_name, 0, 0);
    if (ret == MACH_SEND_INVALID_DEST) { 
        return -1;
    }
    
    unsigned long value = OSReadSwapInt64(m->ool_ports.address, 0);
    printf("ADIGenerateCode %ld\n", value);
    
    return value;
}

from provision.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.