Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change regex engine? #191

Closed
hach1yon opened this issue Nov 11, 2021 · 25 comments
Closed

Change regex engine? #191

hach1yon opened this issue Nov 11, 2021 · 25 comments
Assignees
Labels
enhancement New feature or request

Comments

@hach1yon
Copy link
Collaborator

hach1yon commented Nov 11, 2021

SIGMAルールの正規表現とRustの正規表現に違いがあって、パースできないケースがある。というか、Rustの正規表現エンジンはちょっと特殊で細かいルールが普通の正規表現エンジンとちょっと違う。例えば、\/rという正規表現はSIGMAルール的にはOKだが、Rustではパースエラーになってしまう。他にも.*{という正規表現もSIGMAルール的にはOKだが、Rustではパースエラーになってしまう。

今は小手先の修正で対応しているが、結構怪しい実装になっているので他の正規表現エンジンを使いたい。他の正規表現のクレートを探すか、Rustから他の言語(例えばGolangとか)の正規表現エンジンを呼び出すような実装にしておいた方が無難。

現状での候補

@hach1yon hach1yon added this to the v2.0 milestone Nov 11, 2021
@hach1yon hach1yon added the enhancement New feature or request label Nov 15, 2021
@kazuminn
Copy link
Collaborator

kazuminn commented Jan 9, 2022

#148 でいっぺんにやっちゃう感じになるかな。と思いました。

@hach1yon
Copy link
Collaborator Author

hach1yon commented Jan 9, 2022

ちょっと、どうするのが良いのか話す必要が有りますねー

@YamatoSecurity YamatoSecurity changed the title 正規表現のエンジンの変更 Change regex engine? Jun 30, 2022
@hitenkoku
Copy link
Collaborator

hitenkoku commented Sep 22, 2022

擬似メモ: Rustでなければokかもしれないが、基準となるルールがわからない状態
SIGMAが何で書くことを前提としているのかがわからない……

@YamatoSecurity
Copy link
Collaborator

主なregexエンジンがrustのデフォルトcrate、hyperscan、PCRE2のようです。(参考: https://sr.ht/~pierrenn/ripgrep/)
hyperscanが昔から一番速いので、そちらに変えた方が速くなる可能性があります。
参考: https://rust-leipzig.github.io/regex/2017/03/28/comparison-of-regex-engines/

SigmaがPCRE2を使っている情報は見つからなかったけど、昔から人気な正規表現なので、もしかしてPCRE2を使ったら、より多く検知できるかもしれません。実装してみないとなんともいえませんが。とりあえずhyperscanに変えてみましょう。

@kazuminn さんがやりたいと仰っているので、アサインします。

@kazuminn
Copy link
Collaborator

ありがとうございます。

現在、sigmaは、ElasticSearchの正規表現だけをサポートしており、それはjavaで実装されており、ライブラリはjava.util.regexのようです。
java.util.regexのexpressionを調べてみると、公式に

Perlに似た文字列形式で指定します。

と書いてありました。
https://docs.oracle.com/javase/jp/17/docs/api/java.base/java/util/regex/package-summary.html

Perlなので、PCRE2があってるかもしれませんが、perlと"似た"なので、何とも言えません。

とりあえず、hyperscanで実装してみます。

@YamatoSecurity
Copy link
Collaborator

なるほど、調べてくれてありがとうございます!
コンパイルが少し面倒になりますが、HyperscanのChimera APIを使ったら、PCRE2も使えるみたいですね。
https://crates.io/crates/hyperscan

@hitenkoku hitenkoku moved this from To do to In progress in hayabusa development board Sep 26, 2022
@YamatoSecurity
Copy link
Collaborator

@kazuminn
Sigmaの元々のregexがそのままrust crateだとパースエラーを起こしています:

[WARN] Failed to parse rule file. (FilePath : ../sigma/rules/windows/powershell/powershell_module/posh_pm_invoke_obfuscation_via_var.yml)
[WARN] Cannot parse regex. [regex:(?i).*&&set.*(\{\d\}){2,}\\\"\s+?\-f.*&&.*cmd.*\/c, key:detection -> selection -> Payload|re]

[WARN] Failed to parse rule file. (FilePath : ../sigma/rules/windows/powershell/powershell_module/posh_pm_invoke_obfuscation_stdin.yml)
[WARN] Cannot parse regex. [regex:.*cmd.{0,5}(?:\/c|\/r).+powershell.+(?:\$\{?input\}?|noexit).+\", key:detection -> selection -> Payload|re]

[WARN] Failed to parse rule file. (FilePath : ../sigma/rules/windows/powershell/powershell_module/posh_pm_invoke_obfuscation_via_stdin.yml)
[WARN] Cannot parse regex. [regex:(?i).*(set).*&&\s?set.*(environment|invoke|\${?input).*&&.*", key:detection -> selection -> Payload|re]

[WARN] Failed to parse rule file. (FilePath : ../sigma/rules/windows/powershell/powershell_module/posh_pm_invoke_obfuscation_clip.yml)
[WARN] Cannot parse regex. [regex:.*cmd.{0,5}(?:\/c|\/r).+clip(?:\.exe)?.{0,4}&&.+clipboard]::\(\s\\\"\{\d\}.+\-f.+\", key:detection -> selection -> Payload|re]

が、 https://regex101.com/ で試したら、PCREもPCRE2もパースできました。hyperscanはPCREベースなので、そちらを使った方が速くなるだけではなくて、Sigmaルールとの互換性があって、コンバータスクリプトで正規表現を手直ししなくても良いようになるかも。

@kazuminn
Copy link
Collaborator

hyperscanのPCREを使ったhayabusaをコンパイルできましたが、リンクできませんでした。
git2ライブラリの方にも、PCREが使われており、リンク時に「二個あるのだめ」と怒られます。
どちらかに統一させようとしましたが、方法が提供されておらず、できませんでした。
hyperscanのPCREは、個別でビルドしており、依存関係の考慮に入らないようです。

@YamatoSecurity どうしましょうか?

  1. git2を別のに変える(いや、まぁ無理か
  2. PCREなしのhyperscanを実装
  3. PCRE2

@YamatoSecurity
Copy link
Collaborator

@kazuminn
ありがとうございます!
最近のバージョンのPHP等はPCRE2を使っているので、その実装が良さそうですが、Sigmaの運営者に聞いてみました:
SigmaHQ/sigma-specification#25
返事が返ってきたら、ご連絡します。

@kazuminn
Copy link
Collaborator

kazuminn commented Nov 1, 2022

うっ。私も二日前に質問していました。報告漏れてすみません。
SigmaHQ/sigma#3658

このまま両方残しておいて、レスポンスの遅い方をdeprecatedってことで閉じるのでいいかなとおもいます。

@YamatoSecurity
Copy link
Collaborator

なるほど、決まっていないっぽいので、返事は少し時間がかかるかもしれません。。(作者によって正規表現の書き方が違う気がします・・)
そうですね。このまま両方を残しておいて、レスポンスを待ちましょう。
PCREとPCRE2は書き方が若干違うみたいです: https://stackoverflow.com/questions/70273084/regex-differences-between-pcre-and-pcre2

こちらで、Python等でルールの正規表現を抽出して、PCREとPCRE2で書き方が正しいかどうかチェックするしかないかもしれません。

@YamatoSecurity
Copy link
Collaborator

@kazuminn こちらで確認しました。Sigmaルールの正規表現はPCREでもPCRE2でもパースエラーが出ませんでした。
ということで、PCRE2での実装をお願いできますか?

@kazuminn
Copy link
Collaborator

kazuminn commented Nov 5, 2022

@YamatoSecurity 承知しました。

@YamatoSecurity
Copy link
Collaborator

@kazuminn
sigmaの人から返事が返ってきました。 ( SigmaHQ/sigma-specification#25 (comment) )
やはり、ちゃんと定義されていないようです。正規表現をそのままバックエンドに渡しているので、一番よく使われているPCREの正規表現だったら問題がないはずだけど、高度な正規表現だと、うまくいかない可能性があるので、以下の条件に絞った方が良いんじゃないかな〜?て言っています.

It's indeed not specified and currently existing conversion logic (pySigma, sigmac) passes it through to the query. I think PCRE is currently most prevalent in most query languages and other software, but usage of advanced features in rules could cause incompatibilities. Therefore I suggest to restrict to a basic subset of features, more specific:

    . placeholder
    [a-z] character sets with negation syntax [^...] but no character class syntax like [:...:].
    *, ? and + quantifiers.
    {min,max} repetition syntax.
    Grouping with (...), omitting all modifiers like lookahead/behind etc.
    OR operator | inside of groups.

@kazuminn
Copy link
Collaborator

@YamatoSecurity お知らせありがとうございます。

なるほど。
PCRE2で実装するのは、変わりないですか?jitなので早くて。
また、
条件に絞るのは、どうしましょう。(ドキュメントに書くやら、エラーをもうちょっと工夫るするとか?)

@YamatoSecurity
Copy link
Collaborator

@kazuminn
PCREで実装するのは、代わりありません。
条件は気にしなくて良いと思います。Sigmaのドキュメンテーションに書くものなので。
実装が終わったら、「HayabusaはPCRE2を使っています」とHayabusa-rulesのreadmeに書こうと思っています。

@YamatoSecurity
Copy link
Collaborator

@kazuminn 実装はどこまで進んでいますか?

@kazuminn
Copy link
Collaborator

@YamatoSecurity 今、一度コンパイルが成功しましたが、テストとclippyが通らない状況です。
思った以上にコンパイルを通すのに、疲れたので、少し作業を休憩していますが、年内リリースの意気込みです。

@YamatoSecurity
Copy link
Collaborator

@kazuminn ありがとうございます!
了解です。無理しないようにね!年内で大丈夫です。

@YamatoSecurity
Copy link
Collaborator

@kazuminn まだテストとclippyに失敗しても良いので、コンパイルできる状態だったら、こちらでどのぐらい速くなっているか等検証したいのですが、ドラフトのPRを上げて頂けますか?

@kazuminn
Copy link
Collaborator

@YamatoSecurity 上げましたー。#821

@YamatoSecurity
Copy link
Collaborator

参考: hscheckツールでsigmaの正規表現をPCREなしのHyperscanで使えるかどうかチェックできるようです: https://intel.github.io/hyperscan/dev-reference/tools.html

@YamatoSecurity
Copy link
Collaborator

今更気づいて、申し訳ございませんが、hyperscanはIntelが作っているせいかARMに対応していないようなので、そもそも使えないです。。(MAC M1にも対応したいので・・)

PCRE-JITはMac M1に対応しているかな?(ARM v5, v7, and Thumb2に対応しているようですが)
リンク: https://www.pcre.org/original/doc/html/pcrejit.html

@YamatoSecurity
Copy link
Collaborator

メモ:
rust-lang/regex#501 (comment)
regexの焼き寿司さんがデフォルトのunicode対応要らないんじゃない?というコメントを頂いたので、なしでコンパイルして比較してみました。
14GBに対して、unicode ONの場合はメモリが14GB、OFFの場合は13.7GBで約300MBメモリが減りました。また、約32分のスキャンが6秒速くなりました。検知数は同様でした。フィールドに日本語を探す場合があって、メモリ使用+スキャン時間は対して変わらないので、今のままデフォルトのunicode ONの設定にしようと思います。

@YamatoSecurity
Copy link
Collaborator

The parsing errors in sigma rules were due to unneeded escapes in the regex so we submitted PRs to fix them and now we have no parsing errors with the regex crate. The regex crate is faster than PCRE2-JIT now, has the highest number of detections, and is more maintained than the pcre2 crate. hyperscan was also a candidate but only works on intel CPUs so we decided to keep using the regex crate. The only problem would be if people write regular expressions with lookarounds and/or back references which the regex crate does not support for performance reasons. In that case we may use pcre2 just for those rules but is not needed at the moment.

@hitenkoku hitenkoku removed this from In progress in hayabusa development board Jan 10, 2023
@hitenkoku hitenkoku removed this from the v3.0 milestone Jan 10, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants