成果物

今回のセキュリティキャンプZ-Vトラックではハッカソン形式を採用しており,期間中にテーマに沿った一つの成果物を作り上げる事を目標としている.

私は「RustでAVに使えるライブラリを作り上げる」事を目標にし,実装した.

以下のリポジトリが作成したライブラリ(crate)で,

fanotify-rs

以下のリポジトリにはこのライブラリを使ったアプリケーションのサンプルが置いてある

deis

スライド

ハッカソンの発表で使ったスライドも貼っておきます.文字にするのがめんどいので

slide

fanotify-rs

第一回ハッカソンでの調査の結果,fanotifyをRustから使う為のライブラリを拡張し,よりAVに適した形にしていく事を目標に決めた.

fanotify

fanotifyとは,Linuxカーネルに導入されている,監視対象として設定したマウントポイントやディレクトリで発生するファイルシステムのイベントをユーザーランドに通知する機構である.

監視できるイベントは限られているものの,最近(主に5.1以降)は実行等のイベントも追加されており,AVには充分有用であると考えた.

監視対象とするイベントにFAN_OPEN_EXEC_PERMという種類があり,これを指定することで,「監視下で任意のファイルを実行しようとした際,fanotify_init(2)で作成したファイルディスクリプタに通知が行き,実行の可否を選べる」というAVにぴったりな使い方が出来る.

Rustらしく

今回ベースとして選んだfanotify-rsは,網羅的な実装はされているものの,Rustらしくない,「C APIの薄いラッパー」の様な印象を受けた.

そこで,第二回ハッカソンでは,

事を目標に実装を行った.

結果として,この時点で機能面ではほぼ全て完成し,残りの課題は利便性,実用性の向上となった.

AVへ

機能面での(とはいっても,実際にはLinuxカーネルの機能を呼び出しているだけなので簡単な)実装は終わったところで,実際にAV的な用途で使用できる事を確認してみる.

logging

まずは「実行の為に開かれたファイル,書き込みが行われたファイルをログに残す」というシンプルな機能のプログラム作成する.

これはfanotify-rsのリポジトリにもデモとして置いてある

extern crate fanotify;
extern crate nix;

use fanotify::high_level::*;
use nix::poll::{poll, PollFd, PollFlags};

fn main() {
    let args = std::env::args().collect::<Vec<String>>();
    if args.len() < 2 {
        eprintln!("Usage: {} mountpoint", args[0]);
        std::process::exit(1);
    }
    let path = &args[1];
    let fd = Fanotify::new_with_nonblocking(FanotifyMode::CONTENT);
    fd.add_mountpoint(FAN_OPEN_EXEC | FAN_CLOSE_WRITE, path).unwrap();

    let mut fds = [PollFd::new(fd.as_raw_fd(), PollFlags::POLLIN)];
    loop {
        let poll_num = poll(&mut fds, -1).unwrap();
        if poll_num > 0 {
            for event in fd.read_event() {
                println!("{:#?}", event);
            }
        } else {
            eprintln!("poll_num <= 0!");
            break;
        }
    }
}

poll(2)を使ってfanotifyのfdを監視し,イベントの発生(fdへの書き込みがあった)時にそのイベントを読み出し,出力する.

というモノ.

このデモでは監視するイベントにFAN_OPEN_EXECFAN_CLOSE_WRITEを指定している.

非常にシンプルで機能も分かり易いコードになっていると思う.

insert scan

次は,FAN_OPEN_EXEC_PERMを利用し,実行に割り込んでスキャンをしてみる.

リポジトリはここ

これは正直あまり綺麗なコードでは無いが,fanotifyとスキャナの併用の例にはなっていると思う.

fanotifyFAN_OPEN_EXEC_PERMのイベントを受け取り,そのファイルをスキャナでスキャン.正常値で終了した(マルウェアではないと判断された)場合のみ実行を許可する」という機能

利点

「変更のあったファイルをスキャン」や,「定期的にまとめてスキャン」などの網羅的な方法とは違い,「実行するファイルのみスキャン」することができるので,非常に効率が良い.

欠点

このデモのコードだとスクリプトファイルを引数として与えられると検知できない.

まとめ

今回がセキュリティキャンプへの初参加だった.

初のオンライン開催で予想外の点も少なくなかったが,非常に学びが多かった.

追加で参加できた講義についても,非常に濃密で勉強になった.

次回は受講者とチューター,どちらの立場で参加しようか迷う.

あとこの記事はIPFactory Advent Calendar 2020の6日目の分ということにさせて下さい.

明日は未定です.誰かなんとかしてくれ

御礼

最後になりますが,講師やチューター,関係者の皆様方,本当にありがとうございました.