Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
cve-2010-4221-lab — パッチからRCEへ:CVE-2010-4221(ProFTPD TELNET IACスタックオーバーフロー)向けに手作業で構築したエクスプロイト。失敗から学ぶ全プロセスを詳細に記録。 | Kitploit
ツール/GitHubGitHub/diegslva/cve-2010-4221-lab
エクスプロイトフレームワーク脆弱性分析エクスプロイトリバースエンジニアリングペネトレーションテスト学習と教育バイナリエクスプロイトラボと実践
GitHubdiegslva/cve-2010-4221-lab

cve-2010-4221-lab

パッチからRCEへ:CVE-2010-4221(ProFTPD TELNET IACスタックオーバーフロー)向けに手作業で構築したエクスプロイト。失敗から学ぶ全プロセスを詳細に記録。

リポジトリを見る
12時間14分前未レビュー

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

CVE-2010-4221 — ProFTPD TELNET IAC スタックオーバーフロー:パッチからRCEまで

CVE-2010-4221 — ProFTPDのpr_netio_telnet_gets()における認証前スタックバッファオーバーフロー — に対する、完全に再現可能なラボと手書きのrawソケットエクスプロイトです。脆弱性研究とエクスプロイト開発の学習演習として構築されました。

すべての失敗は記録されています。順調な道のりは嘘であり、回り道こそが教訓です。


法的および倫理的な注意事項 — 最初にお読みください

このリポジトリは教育的な成果物です。メンターやトレーニングを受ける余裕のない人々が、メモリ破壊エクスプロイトが実際にどのように生まれるかを学ぶために存在します:パッチから、失敗を経て、自分が所有するラボ内での動作する概念実証まで。

レッドチーム業務 — 本物のプロフェッショナルな攻撃的セキュリティ — は、一言で定義されます:許可。プロフェッショナルが行うすべては、書面による合意の中で行われます:スコープ、ターゲット、許可された技術、時間枠、承認した人物を明記した署名済みの交戦規則文書です。その書類がなければ、まったく同じキーストロークは職業ではなく、地球上のほぼすべての法域で犯罪です。

したがって、このリポジトリの契約は以下の通りで、交渉の余地はありません:

  • 同梱のDockerラボまたは自分が所有するシステムに対してのみ実行してください。
  • 明示的かつ書面による許可なしに、いかなるものに対しても実行しないでください。
  • 学習している場合:ようこそ、これはあなたのために作られました。
  • 他人に対して使用する武器を探している場合:このタブを閉じてください。このバグは2010年のものです。前科以外には何も得られません。

技術は学ぶ価値があります。技術は、それに伴う規律があって初めて価値を持つのです。


バグ

ProFTPDはFTP制御チャネル上でTELNETエスケープシーケンスを処理します。TELNETでは、0xFF(IAC、「Interpret As Command」)がエスケープバイトであり、リテラルの0xFFはとして送信されます。

0xFF 0xFF

pr_netio_telnet_gets()はクライアントのバイトをスタックバッファ(pr_cmd_readのchar buf[PR_DEFAULT_CMD_BUFSZ+1]、glibcのMAXPATHLEN=4096で4104バイト)にコピーし、残り容量をbuflen — size_t、符号なし — で追跡します。

脆弱なパス(1.3.3a、netio.c):

root@kitploit:~
case TELNET_IAC:
  switch (cp) {
    ...
    default:
      *bp++ = TELNET_IAC;   // 書き込み #1
      buflen--;             // デクリメント #1
      telnet_mode = 0;
      break;
  }
  break;
...
*bp++ = cp;                 // 書き込み #2
buflen--;                   // デクリメント #2  <-- 間にチェックなし

2回の書き込み、2回のデクリメント、その間にゼロチェックなし。buflenがちょうど1のとき、このペアはそれを0にデクリメントし、その後SIZE_MAX(1800京)にアンダーフローします。ループはバッファが無限であると信じ、攻撃者が制御するバイトをスタック上に書き続けます — 保存されたレジスタ、保存されたRBP、そしてリターンアドレスを越えて。

認証前。 この関数はUSER/PASSが処理される前に実行されます。

パッチ

修正(コミット 3cc69b8388、 「Bug#3521 - Telnet IAC processing stack overflow」、1.3.3cでリリース) は12行です。セキュリティ境界全体は以下の通りです:

root@kitploit:~
if (buflen == 0) {
  break;
}

patch.diffを参照してください。パッチを読むことで傷がどこにあったかがわかります — それがスキルです。

ラボ

Dockerfileは、歴史的なDebianスナップショットソースからProFTPD 1.3.3aをコンパイルします。意図的に安全ではありません(これが2010年の姿です):

  • -fno-stack-protector — カナリアなし
  • -z execstack — 実行可能スタック(NXなし)
  • -no-pie — 固定バイナリアドレス
  • gdbの下で実行。デフォルトでASLRを無効化 → 決定論的スタック
root@kitploit:~
docker build -t proftpd-133a .
docker rm -f lab133 2>/dev/null
docker run -d --name lab133 --cap-add SYS_PTRACE \
  --security-opt seccomp=unconfined -p 127.0.0.1:2122:21 \
  proftpd-133a sh -c 'gdb -batch -ex "set follow-fork-mode child" \
  -ex "run" -ex "continue" --args /usr/local/sbin/proftpd -n -d1 \
  > /tmp/gdb.txt 2>&1; sleep 600'
python3 exploit.py

期待される出力:

root@kitploit:~
[S] 220 ProFTPD 1.3.3a Server (lab-iac) ...
[S] THE SERVER SAID: b'PWNED!!PWNED!!'

(シェルコードはfd 0、1、2に書き込みます。これは、どれが制御チャネルを担うかを知ることに依存したくなかったためです — そのうちの2つが応答します。)

エクスプロイトアーキテクチャ

root@kitploit:~
"SITE " + NOPスレッド + シェルコード + [\xff\xffフラッド] + パディング + [ret] + "\n"
 ^^^^^^^^^^^^^^^^^^^^                             ^^^^
 シェルコードはコマンド                    オーバーフローの末尾は
 バッファ内に存在する —                      1つのアドレスだけを
 誰も触れない領域                          配信する
  1. "SITE " はFTPパーサーを生かし続けます — コマンドはクリーンに処理されます。
  2. シェルコードはコマンドの内容です。 バッファはスタック上で最も安全な場所です:読み取り後、buf[4102]だけが触れられます(切り詰めNUL)。フレームの生存ローカル変数より下はすべて静かです。
  3. IACフラッドはbuflenをアンダーフローに導きます(パリティ問題については「旅路」を参照)。
  4. retスロット(buf + 4152)はNOPスレッドの中央のアドレスを受け取ります。pr_cmd_readが解析後にreturn 0に達すると、CPUはスレッドに着地し、シェルコードに滑り込みます。

この逆転アーキテクチャ — ペイロードが最初、フラッドが2番目、アドレスが最後 — は、同じレイアウトを使用する標準的なMetasploitモジュール(proftp_telnet_iac)に対して検証されました。彼らのターゲットにはNXがあったため、resポインタの「4重デリファレンス」を備えたROPチェーンが必要でした。私たちのラボには実行可能スタックがあるため、単一の直接リターンで十分です。

旅路(このリポジトリの実際の要点)

最終的なエクスプロイトは60行です。その代償:

  1. 盲目的な\xffフラッド → 何も起きない。 サーバーは丁寧にセッションを閉じました。根本原因:buflenは4102(偶数)から始まり、各IACペアは2ずつデクリメントするため、1ではなく0にきれいに着地します。アンダーフローにはパリティの破壊が必要です。教訓:状態機械を読むことはスプレーよりも優れています。

  2. 誤ったバッファサイズ。 最初の較正試行は1024バイトのバッファを想定しました。実際はLinux/glibcでMAXPATHLEN+8 = 4104です。フラッドはターゲットの3KB手前で停止しました。教訓:ターゲットを想定せず、測定してください。

  3. 最初のSIGSEGV。 周期的なde Bruijnパターン(Aa0Aa1...)はリターンスロットをbuf+4152に配置し、2回相互検証されました(フレーム計算+パターンオフセット)。教訓:周期的パターンは巻尺であり、エクスプロイトではありません。

  4. RIP制御。 スロットを0x4141414141414141に設定すると、ret命令自体がクラッシュしました — x86-64は非正規アドレスを拒否し、フォールトはret上に発生し、私たちの値はバックトレースで待機しています。教訓:フレーム内に自分の値がある状態でretでクラッシュ = 制御。

  5. retスロットより上のシェルコード → 破壊される。 8バイトがヒープポインタ(0x4d7838 — 後にcmd_recプール割り当てと特定)によって上書きされました。スロットより上のスタックフレームは、着地と乗っ取りの間もまだ動作している関数に属しています。教訓:オーバーフローが最後の書き込みではありません。プログラムは、あなたが破壊したばかりのスタック上で生き続けます。

  6. スロットより下の「デッドゾーン」→ 同様に書き荒らされる。 pr_cmd_read自身のローカル変数(cmd、buflen、cp)がすぐそこに存在し、解析中に保存され続けます。

  7. ハードウェアウォッチポイントによるフォレンジック。 gdbでのwatch *(long*)ADDRは謎をカメラに変えました:破壊されたアドレスへのすべての書き込みを、バックトレース付きで、順番に記録します。教訓:「誰がこのメモリを書いたのか」という疑問に対する答えは、1つのgdbコマンドで得られます。

  8. リファレンスを読み、そして理解する。 標準モジュールは逆転アーキテクチャを確認しました。独自のメンタルモデルを構築した後に他のエクスプロイトを読むことは研究です。前に読むことはコピーです。

学んだ教訓

  • size_tは決して負にならない — 巨大になる。 残り容量カウンタの整数アンダーフローは、追加の手順を伴うスタックオーバーフローです。
  • パリティは武器です。 プリミティブが2ずつデクリメントする場合、サイズだけでなく奇数/偶数を制御することでアンダーフローを制御できます。
  • 悪い文字はプロトコルの問題です。 私たちのシェルコードは\x0a(読み取りを終了)を回避し、設計により\xff(TELNETエスケープ)を生き延びます。
  • Preforkサーバーはクラッシュを許容します。 子プロセスは死に、親プロセスは受け入れ続けます:無限の試行。信頼性エンジニアリングはエクスプロイトの一部です。
  • 同じ成果物を測定し、悪用する。 argv[0]の11バイトの違い(ビルドツリーのバイナリとインストール済みバイナリ)がスタック全体を0x40シフトさせ、完璧なエクスプロイトを静かに無効化しました。
  • シグナルハンドラは自白します。 ProFTPDはSIGSEGVを捕捉し、「terminating (signal 11)」をログに記録します — カーネルが静かでも、ターゲットは自分が死んだことを教えてくれます。

参考文献

  • 修正コミット: https://github.com/proftpd/proftpd/commit/3cc69b8388
  • CVE: https://nvd.nist.gov/vuln/detail/CVE-2010-4221
  • 標準モジュール: modules/exploits/linux/ftp/proftp_telnet_iac.rb (rapid7/metasploit-framework)
  • 姉妹ラボ(ロジックバグ、同じデーモン): CVE-2015-3306 mod_copy

著者

diegslvaによって構築されました。公開で学習しています — 「エクスプロイトを書いたことがない」状態から、手作りのシェルコードによる認証前RCEまで、記録された1日で到達しました。このリポジトリが何かを教えてくれたなら、それを次の人に渡してください。

ツールをダウンロード