LoginSignup
2
1

More than 5 years have passed since last update.

TAMUctf 2018 Write-up

Posted at

TAMUctf

ということで、試しに解いてみた。大学の学生向けのコンテストを外にもう公開している(?)からか、見た問題はどれもわりと簡単。コンテストは終了したけれど、しばらくは問題を公開したままらしい。

システム

運営がGitLabサーバーを動かしていて、各問題ではリポジトリのURLが与えられる。forkして脆弱性を修正してpushすると、CIが走る。正常系が動作することと、脆弱性が無いことが自動でチェックされ、パスすれば、フラグが表示される。競技プログラミングっぽい。

nginx

nginxの設定ファイル。

    root /;

    # Add index.php to the list if you are using PHP
    index index.html index.htm index.nginx-debian.html;

    server_name _;

    location / {
        try_files $uri $uri/ =404;
        index /usr/share/nginx/html/index.html;
        autoindex on;
    }

/を公開しているw

    root /usr/share/nginx/html;

    # Add index.php to the list if you are using PHP
    index index.html index.htm index.nginx-debian.html;

    server_name _;

    location / {
    }

で通った。

gigem{f1x1N_conF1g5_0533cfc}

sql

ログインフォーム。

    // Ensure admin will always be the first record, though really unnecessary
    $sql = "SELECT * FROM Users WHERE User='$user' AND Password='$pass' ORDER BY ID";

プリペアドステートメントを使うべき。ただ、全体的に書き換える必要がある。エスケープをするにしても自分で実装はせずに用意された関数を使うべき。しかし、mysql_real_escape_stringはPHP7で削除された。仕方がないので、自分で'''に書き換えたら通った。

    // Ensure admin will always be the first record, though really unnecessary
    $sql = "SELECT * FROM Users WHERE User='".str_replace("'","''",$user)."' AND Password='".str_replace("'","''",$pass)."' ORDER BY ID";

gigem{cAn_y0U_sQL_TH3_Pr0bL3m?_9f431b}

maze

express製のサーバー。

app.get('/*', function(request, response){
    console.log('request starting...');

    var filePath = __dirname + '/..' +request.url;
    if (filePath == __dirname)
        filePath = __dirname + '/../public/index.html';
    var extname = path.extname(filePath);

これで、ディレクトリトラバーサルができるようになっていたので、

    var filePath = __dirname + '/../public' +path.normalize(request.url);

に直した。

gigem{LifES_4_m4ze_37c83f}

shell-plugin

PythonのSimpleXMLRPCServerで、OSのユーザーを追加するスクリプト。

def add_user_func(name, password):
    os.system("./add-user.sh " + name + " " + password)

この部分はsubprocessを使えば良いけれど、add-user.shの中身は、

#!/bin/bash

mkdir /home/$1
useradd -G ctf-users --home /home/$1 -s /bin/bash $1

chown $1:$1 /home/$1

echo -e "$2\n$2" | passwd $1

シェルスクリプトでのエスケープなんてどうするのだろう? ということで、英数字以外は弾くようにしたら通った。

def add_user_func(name, password):
    name = re.sub(r'\W', '', name)
    password = re.sub(r'\W', '', password)
    os.system("./add-user.sh " + name + " " + password)

gigem{gH0s7_in_7h3_Sh3ll_fb63a0}

感想

たしかに、「守るためのコンテスト」感はある。SQLインジェクションとか他のコンテストで攻撃するのは慣れていても、「じゃあ守ってみて」と言われると戸惑いがあって、面白い。

とはいえ、これで正しい守り方が学べるかというと、上のような雑な回答でも通ってしまうという問題がある。mazeはまだディレクトリトラバーサルができるし、shell-pluginもユーザーが入力したもの違うnameとpasswordを渡してしまっているのは良くない。password*|>?+$|!('"-というパスワードがpasswordになるので辞書攻撃で破られる。

この方式だと、テストを通るようなプログラムを一から実装するという最終手段があるので、一定以上に難しい問題は作れない。

防御側を問題にするのは難しそうだ。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1