iOSでアクセスできない情報を取得するカスタム方法





Positive Hack Daysに関するプレゼンテーションの手順に従って、iOS 6のMACHレベルでconfigdデーモンを調査した結果を共有したいと思います。ご存知のように、iOSではWi-Fi接続ステータスに関する情報はあまりありません。 一般に、パブリックAPIでは、アダプターのSSID、BSSID、およびネットワーク設定以外の情報を見つけることはできません。 暗号化モードはどうですか? 信号強度? カットの下で、プライベートAPIと脱獄を使用せずにこれらすべてを学習する方法を紹介します。



事前に謝罪しますが、この記事では多くのソースコードをアップロードします。 最初に、これがiOS 5で以前に行われた方法を思い出しましょう。*ファームウェア。 Apple System Log機能を使用:ネットワークへの接続時にOSが表示するシステムメッセージを受信できました。 暗号化モードと信号強度が特徴でした。 そして、私たちは次のようにそれらを手に入れました:



aslmsg asl, message; aslresponse searchResult; int i; const char *key, *val; NSMutableArray *result_dicts = [NSMutableArray array]; asl = asl_new(ASL_TYPE_QUERY); if (!asl) { DDLogCError(@"Failed creating ASL query"); } asl_set_query(asl, "Sender", "kernel", ASL_QUERY_OP_EQUAL); asl_set_query(asl, "Message", "AppleBCMWLAN Joined BSS:", ASL_QUERY_OP_PREFIX|ASL_QUERY_OP_EQUAL); searchResult = asl_search(NULL, asl); while (NULL != (message = aslresponse_next(searchResult))) { NSMutableDictionary *tmpDict = [NSMutableDictionary dictionary]; for (i = 0; (NULL != (key = asl_key(message, i))); i++) { NSString *keyString = [NSString stringWithUTF8String:(char *)key]; val = asl_get(message, key); NSString *string = [NSString stringWithUTF8String:val]; [tmpDict setObject:string forKey:keyString]; } [result_dicts addObject:tmpDict]; } aslresponse_free(searchResult); asl_free(asl);
      
      







しかし、Appleの場合と同様に、これについて知ると、彼らはASLのシステムメッセージへのアクセスをブロックしました。 このデータを取得する新しい方法を探す必要がありました。 それから質問は異なって提起されました:Mac OSとiOSでこのデータをどのように取得できますか?



まず、 scutilユーティリティを使用します。これにより、必要なシステム構成を含むシステム構成に関するデータを取得できます。 iOS 6およびJailbreakを搭載したテストiPhoneは、ユーティリティも適切に動作することを示しました。 私にとってこれはヒントであり、指針となるスレッドでした。iOSでSystemConfigurationに「手を差し伸べる」他の方法を探し始めました。



パスは、 SystemConfiguration.frameworkライブラリである、狂気に単純で些細なものであることが判明しました。 これにより、Mac OSで、プログラムを使用してバリューストアに接続し、ワイヤレスネットワーク上のデータを含むプロパティリストを取得できます。



しかし、iOSでこのライブラリのヘッダーファイルを見ると悲しくなります。必要なメソッドの使用は禁止されています。



 CFPropertyListRef SCDynamicStoreCopyValue ( SCDynamicStoreRef store, CFStringRef key ) __OSX_AVAILABLE_STARTING(__MAC_10_1,__IPHONE_NA);
      
      







まず、メソッドが一般的に実行可能であることを確認してください。



  void *handle = dlopen("/System/Library/Frameworks/SystemConfiguration.framework/SystemConfiguration", RTLD_LAZY); CFArrayRef (*_SCDynamicStoreCopyKeyList)(int store, CFStringRef pattern) = dlsym(handle, "SCDynamicStoreCopyKeyList"); NSLog(@"Lib handle: %u", handle); NSString *key = @"State:/Network/Global/DNS"; CFArrayRef testarrray = _SCDynamicStoreCopyKeyList(0, CFSTR("State:/Network/Interface/en0/AirPort")); NSLog(@"Tested array res: %@", testarrray);
      
      







すべてが正常で、結果が返されます。 そのため、Appleに対する正式な禁止を除き、AppStoreでの検証に合格できないソフトウェアロックはありません。 しかし、このライブラリの一部を自分で書いてみませんか?



ソース検索は非常に簡単であることが判明しました。これはconfigdデーモンの一部です。 最も興味深い部分は、 SCDynamicStoreCopyValue関数の説明を読むときに始まります。



 #include "config.h" /* MiG generated file */ ... /* send the key & fetch the associated data from the server */ status = configget(storePrivate->server, myKeyRef, myKeyLen, &xmlDataRef, (int *)&xmlDataLen, &newInstance, (int *)&sc_status);
      
      







わかった MACH Interface Generatorファイルを使用してファイルが生成されています。 したがって、ファイル内の近くにあるMIG言語の説明があります。



 routine configget ( server : mach_port_t; key : xmlData; out data : xmlDataOut, dealloc; out newInstance : int; out status : int);
      
      







その後、2つのパスがあります。普通の人のパスとジェダイのパスです。 config.defsファイルでmigユーティリティを実行し、プロジェクトに挿入するコードを取得できます。 しかし、残念ながら、調査の時点ではこのファイルが見つからず、リバースエンジニアリングを行う必要がありました:)その結果、MACHポートconfigdにアクセスするプロセスを復元できたDima Sklyarovが復元されました。 その助けを借りて、メソッド全体を復元することが判明しました。



 #define kMachPortConfigd "com.apple.SystemConfiguration.configd" -(NSDictionary *)getSCdata:(NSString *)key { if(SYSTEM_VERSION_LESS_THAN(@"6.0")) { // It does not work on iOS 5.* return nil; } struct send_body {mach_msg_header_t header; int count; UInt8 *addr; CFIndex size0; int flags; NDR_record_t ndr; CFIndex size; int retB; int rcB; int f24; int f28;}; mach_port_t bootstrapport = MACH_PORT_NULL; mach_port_t configport = MACH_PORT_NULL; mach_msg_header_t *msg; mach_msg_return_t msg_return; struct send_body send_msg; // Make request CFDataRef extRepr; extRepr = CFStringCreateExternalRepresentation(NULL, (__bridge CFStringRef)(key), kCFStringEncodingUTF8, 0); // Connect to Mach MIG port of configd task_get_bootstrap_port(mach_task_self(), &bootstrapport); bootstrap_look_up2(bootstrapport, kMachPortConfigd, &configport, 0, 8LL); // Make request send_msg.count = 1; send_msg.addr = (UInt8*)CFDataGetBytePtr(extRepr); send_msg.size0 = CFDataGetLength(extRepr); send_msg.size = CFDataGetLength(extRepr); send_msg.flags = 0x1000100u; send_msg.ndr = NDR_record; // Make message header msg = &(send_msg.header); msg->msgh_bits = 0x80001513u; msg->msgh_remote_port = configport; msg->msgh_local_port = mig_get_reply_port(); msg->msgh_id = 20010; // Request server msg_return = mach_msg(msg, 3, 0x34u, 0x44u, msg->msgh_local_port, 0, 0); if(msg_return) { if (msg_return - 0x10000002u >= 2 && msg_return != 0x10000010 ) { mig_dealloc_reply_port(msg->msgh_local_port); } else { mig_put_reply_port(msg->msgh_local_port); } } else if ( msg->msgh_id != 71 && msg->msgh_id == 20110 && msg->msgh_bits <= -1 ) { if ((send_msg.flags & 0xFF000000) == 0x1000000) { CFDataRef deserializedData = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, send_msg.addr,send_msg.size0, kCFAllocatorNull); CFPropertyListRef proplist = CFPropertyListCreateWithData(kCFAllocatorDefault, deserializedData, kCFPropertyListImmutable, NULL, NULL); mig_dealloc_reply_port(msg->msgh_local_port); mach_port_deallocate(mach_task_self(), bootstrapport); mach_port_deallocate(mach_task_self(), configport); mach_msg_destroy(msg); NSDictionary *property_list = (__bridge NSDictionary*)proplist; if(proplist) CFRelease(proplist); CFRelease(deserializedData); CFRelease(extRepr); return property_list; } } mig_dealloc_reply_port(msg->msgh_local_port); mach_port_deallocate(mach_task_self(), bootstrapport); mach_port_deallocate(mach_task_self(), configport); mach_msg_destroy(msg); CFRelease(extRepr); return nil; }
      
      







関心のある値は、キー@ "Setup:/ Network / Interface / en0 / AirMac"にあります。



そのため、SystemConfiguration.frameworkの一部を独自に実装し、脱獄やライブラリの違法使用に頼らずに必要なデータを受け取りました。 不思議なことに、iOS 6では、さまざまな名前で接続するために100以上のMACHポートが開いています。 これは、さまざまな研究のためのかなり豊かな基盤を提供するように思えます。 残念ながら、これまでのところ、AppStoreで同様のコードが渡されるかどうかは言えませんが、試してみる価値はあります。



ご清聴ありがとうございました。



参照:



-MACH Kernelプログラミングガイド



-iOSハッカーハンドブック



-Mac OS Xの内部



All Articles