iOSアプリでのセキュリティの解析





Parseは、モバイルアプリケーション用の本格的なサーバーインフラストラクチャを迅速に構築できる最も美しいBaaSです。 おそらく、多くの開発者がこの新たなセキュリティの問題と新たな脆弱性を忘れているのは、この単純さのためです。



サービスに精通していない人のために、私たちはそれが何であるかについて短いエクスカーションを取ります。 Parseは、クラウドストレージ、プッシュ通知、独自のAPIの作成、統計の収集、クラッシュログなどのサービスを開発者に提供します。 この調査の一環として、Cloud Coreと呼ばれるデータウェアハウスに興味があります。

Parseのすべてのデータは、完全な関係を確立できるレコード間で、クラス(基本的にはテーブル)に格納されます。







クラスごとに、検索、新しいエントリの追加、既存のエントリの変更などの機能に影響するクライアントアクセス権が構成されます。 デフォルトでは、すべてのアクションが許可されています。 もちろん、いつものように、ほとんどの開発者は、必要なテーブルを設定すると、クライアントのアクセス許可の設定を忘れます。







作業中のプロジェクトの1つでParseと密接に遭遇し、ACL設定をいじくり回したため、他の人のアプリケーションで遊ぶことにしました。 parse.com/customersで直接調査するオブジェクトを選択しましたCubefree-コワーキングの場所を見つけるサービスになりました



iOSアプリケーションのParseアカウントに接続するために、2つのキー( アプリケーションIDクライアントキー)が使用されます。 Cloud Coreのデータに対してアクションを実行するには、まずそのデータを見つける必要があります。 ペンテスト中の多くのルーチンアクションを自動化するスマートIDBユーティリティを使用して、アプリケーションの実行可能ファイルを解読します。 プロセスの進行中に、 NSUserDefaultsを確認します。NSUserDefaultsは、関心のあるキーを格納する可能性が高い場所です。



この場合、すべては完全に無害です-機密データはありません。 復号化されたバイナリに戻り、Objective-Cで記述されたリバースエンジニアリングアプリケーションに特化したHopper逆アセンブラーにフィードします。 AppDelegateアプリケーションdidFinishLaunchingWithOptions:メソッドでキーの検索を開始します。 Hopperの優れた機能の1つは、メソッドを擬似コードとして提示することです。これにより、解読されたコードを理解するためのしきい値が大幅に低下します。







予想どおり、Parseアカウントへの接続はここで発生します。 これらのキーを使用して、アプリケーションのデータ構造とそれらへのアクセス権を分析します。



次のステップは、Parseテーブルの名前を検索することです。 実際、それらを探す場所は同じスクリーンショットから明らかになります-サーバーに接続した直後に、ルートPFObjectのいくつかの継承クラスでregisterSubclassメソッドを呼び出します。 それらのそれぞれは、 parseClassNameメソッドを必ず実装する必要があります。このメソッドは、対象のサーバー上のテーブル名前を返します







このようにして得られた各クラスの構造を研究します。

PFQuery *query = [PFQuery queryWithClassName:@"ParseClassName"]; [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) { NSLog(@"%@", objects); }];
      
      





ただし、構造に関する知識だけでは十分ではありません。 アプリケーションの動作にどのように影響するかを理解するには、すべてのParseクラスへのアクセス権を定義する必要があります。 これは非常に簡単に行われます-異なる許可に対応するサーバーへのリクエストを実行し、その結果を分析するだけです。 これらのルーチンアクションを簡素化するために、既知のすべてのクラスへのアクセスレベルを自動的に決定するParse Revealerという簡単なユーティリティを作成しました。



受け取ったデータに基づいて、テーブルを作成できます。

クラス名 データ構造 アクセス権
チャットルーム chatId(文字列)

user1(ユーザー)

user2(ユーザー)
GET:False

見つける:True

更新:True

作成:True

削除:偽

フィールドの追加:True
チェックイン availableToShareTable(ブール値)

日付(Date)

見えない(bool)

statusCheckin(文字列)

statusUser(文字列)

ユーザー(ユーザー)

ワークスペース(ワークスペース)
GET:True

見つける:True

更新:True

作成:True

削除:True

フィールドの追加:True
チャットメッセージ chatId(文字列)

メッセージ(文字列)

送信者(ユーザー)

未読(bool)
GET:False

見つける:True

更新:True

作成:True

削除:偽

フィールドの追加:True
通告 日付(Date)

sendUser(ユーザー)

チェキン

ステータス(ブール)

タイプ(数値)

受け入れられた(Bool)
GET:True

見つける:True

更新:True

作成:True

削除:偽

フィールドの追加:True
復習 日付(Date)

parkingStatus(番号)

powerStatus(数値)

soundStatus(数値)

ユーザー(PFUser)

wifiStatus(数値)

ワークスペース(ワークスペース)
GET:True

見つける:True

更新:偽

作成:True

削除:偽

フィールドの追加:True
ワークスペース アドレス(文字列)

cc(文字列)

都市(ストリング)

国(文字列)

foursquareId(文字列)

lat(文字列)

lng(文字列)

ロケーション(PFGeoPoint)

名前(文字列)

postalCode(文字列)

状態(文字列)
GET:True

見つける:True

更新:True

作成:True

削除:偽

フィールドの追加:True


取得したアクセス権からわかるように、開発者は特定のセキュリティポリシーを実装しましたが、それでも不十分です。 ChatMessageクラスで遊ぶことでどのような結果が得られるかを示します。



最も明らかな脆弱性-オープンチャットのいずれでも、自分のメッセージと他のメッセージの両方を変更できます。 このコードを実行すると、素敵な挨拶が殺人事件に変わります。

 PFQuery *query = [PFQuery queryWithClassName:@"ChatMessage"]; [query whereKey:@"message" equalTo:@", !"]; [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) { PFObject *object = [objects firstObject]; object[@"message"] = @",   !"; [object saveInBackground]; }];
      
      









同様に、新しいPFObjectに正しいchatId 提供するだけで、新しいメッセージを追加できます。 ただし、 falseに設定されたDeleteでは、作成されたオブジェクトを削除できないことに注意してください。



さらに深刻な脆弱性は、Parseから受信したデータのマッピングが正しくないことです。 新しく作成されたChatMessageオブジェクトに送信者フィールドない場合、アプリケーションはクラッシュします。 したがって、これまでに作成されたすべてのウォッチを実行し、それらに無効なメッセージを追加することを妨げるものはありません。アプリケーションはすべてのユーザーからクラッシュします。 これにはすでに、App Storeでの低い評価、ユーザーの流出、およびプロジェクト全体の失敗に悩まされています。

残りのクラスには同様の脆弱性がありますが、すでに現在の調査の範囲外です。



セキュリティに関しては、ここではすべてが非常に透明です。 従う必要があるのはいくつかのルールのみです。



この調査で機能とアプリケーションが表示される場合は、Parseをscらないでください。前述のように、これはアプリケーションのサーバー側の作成コストを最小限に抑える優れたサービスです。 また、考慮されるすべての脆弱性は、アプリケーション開発者の責任のみです。



便利なリンク:



iOSアプリのその他のセキュリティコンテンツ:




All Articles