feature image

2021年8月12日 | 活動紹介

CPCTFを支えたWebshell

こんにちは。19Bの@mazreanです。普段はSysAd班でanke-toというアプリケーションの開発・運用を行なっています。

CPCTF2021ではインフラとWebshellの開発を行なっていました。

インフラについては

CPCTFを支えたインフラ
こんにちは。19Bの@mazrean [/author/mazrean/]です。普段はSysAd班でanke-toというアプリケーションの開発・運用を行なっています。 CPCTFでは@hijiki51 [/author/hijiki51]、@reyu [/author/reyu]とインフラを担当していました。 この記事ではCPCTFでのインフラ環境について書いていきます。 構成サーバーは全てConoHaのVPSを利用しており、 * メモリ1GB CPU2コア(Web問用サーバー) * メモリ2GB CPU3コア(mainサーバー) * メモリ4GB CPU4コア(Webshe…

をご覧ください。

この記事ではCPCTF2021で使用したWebshellについて書いていきます[1]

CPCTFにおけるWebshell

CPCTFは競技プログラミング・CTFを体験できる新歓イベントです。
このためコアターゲットは新入生です。
しかし、新入生にはシェル環境を持たない方も多いです。
また、CTFでよく使うツール類が準備済み新入生となるとかなり限られてくるでしょう。
このようなことから、「ツールのインストールなどで手間取り競技プログラミング・CTFを楽しめない」といったことを回避するためにCPCTFでは各種CTFで使うツールなどが準備済みの環境が使えるWebshellを用意しています。

これまでのWebshellと問題点

これまでのCPCTFで用いていたWebshellは以下のような構成のものでした。
before.drawio-1
WeTTYはブラウザで開けるターミナルのUIを提供し、その入出力をssh接続に流すことのできるOSSです。
このOSSを利用して、プロセスの隠蔽や権限の設定などがされた全参加者共通のVPSへssh接続する、という方法でこれまでのWebshellは実現されていました。

しかし、この方法では

といった問題がありました。
これらの問題を回避するためにCPCTF2021では新しいWebshellの仕組みを用意しました。

新しいWebshell

これまでのWebshellの問題点は主に全参加者共通のVPSに対してssh接続が行われていることで生じていました。
このため、参加者ごとに用意された仮想環境に対してssh接続が行われるようにすれば良いです。

しかし、この方法には「WeTTYにはssh接続をユーザーごとに別のホストへ振り分けるような機能はない」という課題がありました。
この問題を解決するために開発したのがssh-separatorです。
ssh-separatorはssh接続をユーザーごとに用意したDockerコンテナへ振り分けるアプリケーションです。

これによって実現されたのが以下の構成です。
after.drawio
これまでの構成で1台のVPSであった部分がssh-separatorをはさんで、各参加者ごとに作られたdockerコンテナとなっています。
これによって、参加者1人が使用できるリソースに制限をかけることができ、cgroupにより隔離された環境内での操作しかできないように制限することができました。

ssh-separator

ここからは新しいWebshellの構成を実現するために開発したssh-separatorについて紹介していきます。
リポジトリは https://github.com/mazrean/ssh-separator です。

機能

ssh-separatorが提供する主な機能は

と言うものです。

REST APIはスコアサーバー上でWebshellの有効化やWebshell環境リセットの操作が行われた際にサーバーから叩かれます。
OpenAPIは https://mazrean.github.io/ssh-separator/openapi/ のようになっています。
Webshellの有効化時にはPOST /newが叩かれ、ユーザーのパスワードなどの認証情報の保存とユーザーごとのDockerコンテナ作成が行われます。
環境リセットではPUT /resetが叩かれ、ユーザーのDockerコンテナが消されて新しいDockerコンテナが作り直されます。

ssh接続ではパスワードを用いての認証を行い、ユーザーごとのDockerコンテナ内で起動した/bin/bashなどのシェルにssh接続の入出力を繋げます。

性能

ssh-separatorではPrometheus用のメトリクスを取れるようにしてあります。
以下はそれを利用して大会中に計測したデータです。

Dockerコンテナ数

合計で75人の参加者が使用していました。また、ピーク時で22人の参加者が同時接続し、コンテナが起動していました。
Dockerコンテナはssh接続がない時にはstopしてCPUやメモリの使用を抑える工夫をしていたのですが、それがなければそれなりに負荷が大きくなっていたと思われます。
----------2021-08-12-18.30.35

HTTPリクエスト数

スコアサーバーによりREST APIが叩かれた回数とそのレスポンスです。
全てエラーなく正常にレスポンスを返せていることがわかります。
また、スコアサーバーなどと比べると数は少ないですが、隔離環境の作成などを行うアプリケーションとしてみると悪くない数のリクエストをさばいているのではないでしょうか。
----------2021-08-12-18.31.54-1

使用技術

言語は

を踏まえてGo言語を用いています。
また、ライブラリとして

を使用しました。

Docker Engine APIを通じてのdockerの操作

普段よく使うdockerコマンドはDocker CLIがdockerdの提供するREST API、Docker Engine APIを叩くことで動いています。
ssh-separatorではDocker Engine APIをGolangのDocker Engine SDK[2:1]を用いて叩くことで、Dockerコンテナのリセットを行なっています。

Go言語でのsshサーバーの作成

Go言語の準標準パッケージのgolang.org/x/crypto/sshを利用するだけでもかなり楽にsshサーバーを作ることができます。
しかし、今回はx/crypto/sshのラッパーであるgliderlabs/sshを利用しました。
このパッケージではnet/httpに近いAPIを持つため、HTTPサーバーを書き、net/httpを見慣れている自分にとっては非常に使いやすかったです。
また、exampleが充実しており、かなり高い確率でexampleに少し手を加えるだけでやりたいことを実現できると思います。
実はssh接続をDockerコンテナに流す例もあり、ssh-separatorはそれを参考にしつつ実装しました。
ssh-separatorは1日で構想から実装まで終わらせて動くところまで持っていったのですが、この超短期間での開発を実現できた理由の1つがgliderlabs/sshだと思います。

今後の展望

CPCTFのWebshellをより安全にするために開発したssh-separatorですが、まだまだ活用できる範囲はあると考えています。
具体的には、CTFでよくあるユーザーごとに環境が用意されており、ssh接続するタイプの問題です。
2021年のCPCTFではユーザー管理まわりの調整が間に合わず問題環境構築では利用できませんでしたが、来年以降のCPCTFでは利用できるように調整中です。

また、MITライセンスとなっているのでtraP外の方でも利用できるようになっています。
CPCTF以外のCTFの大会などで利用していただけたら嬉しいと考え、Docker以外のコンテナ型仮想化やbadger以外のデータベースへの対応なども行なっています。
追加で欲しい機能などがあればissueなどで教えていただけると嬉しいです。

終わりに

今回はCPCTFで用いたWebshellとその中で用いたssh-separatorについて説明させていただきました。
かなりの短い期間で作ったWebshellですが、快適に使用していただけたなら嬉しいです。

明日の担当は@reyuです。お楽しみに!


  1. 非常に遅くなってしまい申し訳ありません… ↩︎

  2. Docker Engine SDKについては https://docs.docker.com/engine/api/sdk/ 参照 ↩︎ ↩︎

mazrean icon
この記事を書いた人
mazrean

SysAd班で活動したり、百合漫画の布教をしたりしている人。

この記事をシェア

このエントリーをはてなブックマークに追加
共有

関連する記事

2023年12月11日
DIGI-CON HACKATHON 2023『Mikage』
toshi00 icon toshi00
2022年4月7日
traPグラフィック班の活動紹介
annin icon annin
2021年5月19日
CPCTF2021を実現させたスコアサーバー
xxpoxx icon xxpoxx
2021年3月19日
traPグラフィック班の活動紹介
NABE icon NABE
2022年9月26日
競プロしかシラン人間が web アプリ QK Judge を作った話
tqk icon tqk
2022年9月16日
5日でゲームを作った #tararira
Komichi icon Komichi
記事一覧 タグ一覧 Google アナリティクスについて 特定商取引法に基づく表記