
2026/01/23 1:45
**Lyftバイクを逆解析して楽しむ(お金になる?)**
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
記事では、ハッカーがアプリの「レンタル」APIリクエストを再送信することでLyftバイクを遠隔でロック解除できる方法を示しています。
iPhoneにCharles ProxyのルートCAをインストールしてトラフィックを捕捉し、レンタルエンドポイントを特定しました:
POST https://layer.bicyclesharing.net/mobile/v2/fgb/rent。このリクエストにはヘッダー api-key と authorization が必要で、ボディにはユーザーの緯度/経度(userLocation)と、memberId および5桁のバイクIDを含むネストされた qrCode オブジェクトが入っています。この情報をもとに著者はPythonスクリプトを作成し、10 000〜20 000 の範囲内のすべての 10,000 個のバイクIDを順番に試しながらレンタルリクエストを送信しました。単純な逐次ループでは約3時間かかりますが、非同期
aiohttp バージョンでは15秒程度(約650 RPS)でスキャン完了します。Lyftは2019年にこの脆弱性を通知され、クライアント側の操作をブロックする予約機能を追加してパッチを適用したため、攻撃は無効化されました。著者はHackerOne経由でLyftから$500の報奨金を受け取りました。
この脆弱性は、おそらくFord GoBikes の元々のコードベースにおいて同時実行レンタルリクエストを正しく処理できないレースコンディションが原因と考えられます。このケースは、クライアント提供のGPSデータに頼るのではなく、より堅牢なサーバー側検証(例:厳格なジオフェンシングや追加チェック)が必要であることを示しています。
本文
イントロダクション
サンフランシスコ・ハイト=アッシュベリーでの寒い夏の朝、マーケットへ向かう通勤途中に「またしても最後のリフト自転車を奪われた」という光景に遭遇しました。
「15 分早く起きればいいんだろう」と瞬間的に思ったものの、
その翌月はリフトのプライベート API を逆解析し、SSL 暗号化を突破し、市内で離れた自転車を追跡し、内部インシデントを引き起こして、かつては利益まで上げることに費やしました。
この経験から多くを学んだので、もしあなたも興味があるなら共有したいと思います。
技術的要約(スプライヤー!)
目的:リフト自転車を遠隔でロック解除する
手順
- iOS アプリの通信をキャプチャ
- 暗号化されたトラフィックからリクエストを再構築
- 変更したリクエストを再送信
- 自転車 ID をブルートフォース(遠隔で取得不可)
1. iOS アプリの暗号化通信をキャプチャ
Charles Proxy を使って、iPhone 上のリフトアプリから発信するリクエストを捕捉しました。
- Charles は SSL プロキシングに対応しており、SSL ハンドシェイク時に自ら生成した 一時的な証明書 を注入します。
- これによりすべての通信が自身の鍵で署名されるため、デコード・閲覧・再暗号化が可能です。
- ただし、生成された証明書は Charles Certificate Authority によって署名されているので、携帯電話にこの CA をインストールしていないと受理されません。
これでトラフィックを途中で解読・再暗号化できます。
2. 修正したロック解除リクエストを再送
Charles から確認できたのは、ロック解除リクエストが以下のような
rent エンドポイントを使っていることです。
POST https://layer.bicyclesharing.net/mobile/v2/fgb/rent Headers: { "api-key": "sk-XXXXX", "authorization": "bearer-XXXXX" } Body (JSON): { "userLocation": { "lat": 37.7714859, "lon": -122.4449036 }, "qrCode": { "memberId": "user-XXXXX", "qrCode": "12345" } }
Python で簡単に再送するスクリプトは次のようになります。
import requests url = "https://layer.bicyclesharing.net/mobile/v2/fgb/rent" headers = { "api-key": "sk-XXXXX", "authorization": "bearer-XXXXX", } station_coords = { "lat": 37.7730627, "lon": -122.4390777 } # 地図から取得 bike_id = "12345" # ダミー ID data = { "userLocation": station_coords, "qrCode": { "memberId": "user-XXXXX", "qrCode": bike_id }, } requests.post(url, headers=headers, json=data)
3. 自転車 ID をブルートフォース
自転車の ID は実際に自転車上に印字されており、eBikes にはありません。遠隔でロック解除するためには、この ID を試行錯誤で当てる必要があります。
- ID は 5 桁ですが、実際は 10000–20000 の範囲のみが使用されています → 約 10,000 通り
- 単純な実装だと約 3 時間かかります:
def payload(i): return { "userLocation": station_coords, "qrCode": { "memberId": "mem123", "qrCode": i }, } def send_one(i): requests.post(url, headers=headers, json=payload(i)) for i in range(10_000, 20_000): send_one(i)
とasyncio
を使えば約 15 秒 に短縮可能です:aiohttp
import asyncio, aiohttp async def send_one(session, i): async with session.post(url, headers=headers, json=payload(i)): pass async def main(): async with aiohttp.ClientSession() as s: tasks = [send_one(s, i) for i in range(10_000, 20_000)] await asyncio.gather(*tasks) asyncio.run(main())
注意事項
本稿は教育目的のみです。議論されている脆弱性は 2019 年にリフトへ報告され、すぐに修正されました。その後直ちにリフトは公式機能として自転車予約を導入し、本手法は実用的ではなくなりました。
目次(抜粋)
- アクイジション
- iOS アプリのリクエストを傍受
- SSL / Root CA のスプーフィング
- リフトリクエストの構造
- 実際に DoS 攻撃ではない理由
- テスト実行例
- HackerOne での責任ある開示
- 終わりに
1. アクイジション
2019 年、リフトバイク(BayWheels)は Ford GoBikes と呼ばれ、駅ごとに一時コードでロック解除されていました。ブランド変更後は QR コードをスキャンするか、5 桁の ID を入力して直接ロック解除できるようになりました。
ジオフェンスが遠隔からのロック解除を防いでいたため、その制限を突破したかったのです。
2. iOS アプリのリクエストを傍受
- 携帯電話の Wi‑Fi HTTP プロキシを
(自分のラップトップ IP と Charles のポート)に設定192.168.0.7:8888 - Charles で SSL プロキシングを有効化し、携帯に Charles CA をインストール
- トラフィックをキャプチャし、注入された証明書で復号
3. SSL / Root CA のスプーフィング
Charles はリフトの実際の SSL 証明書を自ら生成したもの(Charles root CA によって署名)に置き換えます。携帯電話がこの CA を信頼しているため、暗号化された通信を読むことが可能です。
4. リフトリクエストの構造
ロック解除リクエスト (
/mobile/v2/fgb/rent) は次の要素から成ります:
とapi-key
ヘッダーauthorization
(緯度/経度)userLocation
オブジェクトにqrCode
とmemberId
(自転車 ID)qrCode
目的地駅近くの座標でリクエストを再送すればロック解除できます。
5. 実際に DoS 攻撃ではない理由
10,000 通りの ID を試行することで、最大 650 RPS の突発的負荷がかかります。リフトは日平均約9,000 回の利用を抱えており、この突発的負荷はピークトラフィックを上回るものの、多くのサーバーで耐えられるレベルです。また、事前にリフトと連絡して疑念が生じないよう配慮しました。
6. テスト実行例
ブルートフォーススクリプトを走らせた結果、時折 2 台の自転車が同時にロック解除 されるという予期せぬ競合状態が確認できました。ロック後は足元で再ロックし、仕事へ向かうことが可能でした。
7. HackerOne & 責任ある開示
HackerOne を通じて脆弱性を報告しました。通常、ブルートフォースに関する報告は除外対象ですが、リフトはこの報告を有効な脆弱性(複数台ロック解除)として受け入れ、$500 の報奨金+$250 ボーナスを授与しました。
8. 終わりに
物理的な自転車システムでもデジタルインターフェースが依存しているため、逆解析は非常に強力です。GPS によるジオフェンスの信頼性はリスクが高く、サーバー側でより堅牢な検証を行うべきです。
責任ある開示を通じて報奨金を得られることもありますし、法的措置を取られないケースも多いです。
ハッキングを楽しんでください!