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

Show prevalence of rules in the output #1737

Open
wants to merge 50 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
7603f85
Entropy Methods
Aayush-Goel-04 Jul 29, 2023
f5b38d5
Merge branch 'mandiant:master' into Aayush-Goel-04/Issue#520
Aayush-Goel-04 Aug 2, 2023
bf1f59b
Sort rules in render based on match probability
Aayush-Goel-04 Aug 5, 2023
31bd6b3
Rendering rules into two sections. * for interesting rules.
Aayush-Goel-04 Aug 6, 2023
9ca4f9d
Merge branch 'mandiant:master' into Aayush-Goel-04/Issue#520
Aayush-Goel-04 Aug 7, 2023
78877f2
Merge branch 'mandiant:master' into Aayush-Goel-04/Issue#520
Aayush-Goel-04 Aug 13, 2023
f5f3e87
update
Aayush-Goel-04 Aug 13, 2023
a6797de
Merge branch 'mandiant:master' into Aayush-Goel-04/Issue#520
Aayush-Goel-04 Aug 19, 2023
0b5a326
Update default.py
Aayush-Goel-04 Aug 19, 2023
def2d98
Merge branch 'Aayush-Goel-04/Issue#520' of https://github.com/Aayush-…
Aayush-Goel-04 Aug 19, 2023
039fdbd
Update utils.py
Aayush-Goel-04 Aug 19, 2023
8a0e61b
Merge branch 'master' into Aayush-Goel-04/Issue#520
Aayush-Goel-04 Aug 19, 2023
f6058b1
Update default.py
Aayush-Goel-04 Aug 19, 2023
dc399c3
Merge branch 'master' into Aayush-Goel-04/Issue#520
Aayush-Goel-04 Aug 27, 2023
c5302cd
prevalence db update
Aayush-Goel-04 Aug 27, 2023
430bde6
Update default.py
Aayush-Goel-04 Aug 27, 2023
7f1566d
Update capa/render/default.py
Aayush-Goel-04 Aug 28, 2023
24541b6
Merge branch 'mandiant:master' into Aayush-Goel-04/Issue#520
Aayush-Goel-04 Sep 6, 2023
6787555
updated default render
Aayush-Goel-04 Sep 6, 2023
7c84926
Update utils.py
Aayush-Goel-04 Sep 6, 2023
c1f9e72
Revert "Update utils.py"
Aayush-Goel-04 Sep 6, 2023
7d6ec15
Merge branch 'mandiant:master' into Aayush-Goel-04/Issue#520
Aayush-Goel-04 Oct 9, 2023
5c1464c
Merge branch 'mandiant:master' into Aayush-Goel-04/Issue#520
Aayush-Goel-04 Oct 10, 2023
8ede526
Resolving path issues
Aayush-Goel-04 Oct 10, 2023
4476b2c
Update utils.py
Aayush-Goel-04 Oct 10, 2023
6077e99
Update utils.py
Aayush-Goel-04 Oct 10, 2023
bc0d129
Update pyinstaller.spec
Aayush-Goel-04 Oct 16, 2023
12dea73
Merge branch 'mandiant:master' into Aayush-Goel-04/Issue#520
Aayush-Goel-04 Oct 16, 2023
3bce5a9
Merge branch 'mandiant:master' into Aayush-Goel-04/Issue#520
Aayush-Goel-04 Oct 17, 2023
5a0a3a5
Update CHANGELOG.md
Aayush-Goel-04 Oct 20, 2023
e4bb521
Merge branch 'master' into Aayush-Goel-04/Issue#520
Aayush-Goel-04 Oct 20, 2023
fe4af5c
render output with prevalence for (v) verbose
Aayush-Goel-04 Oct 20, 2023
95bdf5d
Update utils.py
Aayush-Goel-04 Oct 20, 2023
af57da8
Update RuleMetaData with Prevalence
Aayush-Goel-04 Nov 12, 2023
8057a73
Apply suggestions from code review
Aayush-Goel-04 Nov 12, 2023
5102ca1
Imports, Paths, Comments & Exceptions handled
Aayush-Goel-04 Nov 16, 2023
07553a6
Update result_document.py
Aayush-Goel-04 Nov 16, 2023
2c4931d
Update result_document.py
Aayush-Goel-04 Nov 20, 2023
c531a15
Merge branch 'master' into Aayush-Goel-04/Issue#520
Aayush-Goel-04 Feb 3, 2024
61e7459
Added prevalence to verbose
Aayush-Goel-04 Feb 3, 2024
66d0ab7
linter checks
Aayush-Goel-04 Feb 3, 2024
e3ca32b
Revert "linter checks"
Aayush-Goel-04 Feb 3, 2024
f084040
Update result_document.py
Aayush-Goel-04 Feb 3, 2024
b07d600
Merge branch 'master' into Aayush-Goel-04/Issue#520
Aayush-Goel-04 Feb 5, 2024
10d2140
Convert database to python files
Aayush-Goel-04 Feb 5, 2024
9bebffc
Lint checks
Aayush-Goel-04 Feb 5, 2024
fa89f44
Delete rules_prevalence.json.gz
Aayush-Goel-04 Feb 25, 2024
d93f135
Merge branch 'mandiant:master' into Aayush-Goel-04/Issue#520
Aayush-Goel-04 Feb 25, 2024
08ea4a9
Merge branch 'mandiant:master' into Aayush-Goel-04/Issue#520
Aayush-Goel-04 Mar 6, 2024
7992b1b
Merge branch 'master' into Aayush-Goel-04/Issue#520
mr-tz Mar 13, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ Speaking of new rules, we have eight additions, coming from Ronnie, Jakub, Morit
- ELF: implement import and export name extractor #1607 #1608 @Aayush-Goel-04
- bump pydantic from 1.10.9 to 2.1.1 #1582 @Aayush-Goel-04
- develop script to highlight features not used during matching #331 @Aayush-Goel-04
- Show prevalence of rules in the output #520 @Aayush-Goel-04

### New Rules (8)

Expand Down
Binary file added assets/rules_prevalence.json.gz
Binary file not shown.
62 changes: 53 additions & 9 deletions capa/render/default.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@
# is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and limitations under the License.

import gzip
import json
import collections
from typing import Dict
from pathlib import Path

import tabulate

Expand Down Expand Up @@ -82,26 +86,66 @@ def render_capabilities(doc: rd.ResultDocument, ostream: StringIO):
| ... | ... |
+-------------------------------------------------------+-------------------------------------------------+
"""

def load_rules_prevalence(file: Path) -> Dict[str, str]:
if not file.exists():
raise FileNotFoundError(f"File '{file}' not found.")
try:
with gzip.open(file, "rb") as gzfile:
return json.loads(gzfile.read().decode("utf-8"))
except Exception as e:
raise RuntimeError(f"An error occurred while loading '{file}': {e}")

subrule_matches = find_subrule_matches(doc)
CD = Path(__file__).resolve().parent.parent.parent
rules_prevalence = load_rules_prevalence(CD / "assets" / "rules_prevalence.json.gz")

rows = []
# seperate rules based on their prevalence
common = []
rare = []
for rule in rutils.capability_rules(doc):
if rule.meta.name in subrule_matches:
# rules that are also matched by other rules should not get rendered by default.
# this cuts down on the amount of output while giving approx the same detail.
# see #224
Aayush-Goel-04 marked this conversation as resolved.
Show resolved Hide resolved
continue

count = len(rule.matches)
if count == 1:
capability = rutils.bold(rule.meta.name)
matches = f"({count} matches)" if count > 1 else ""

prevalence = rules_prevalence.get(rule.meta.name, None)
Aayush-Goel-04 marked this conversation as resolved.
Show resolved Hide resolved

if prevalence == "rare":
rare.append((rule.meta.namespace, rule.meta.name, matches, rutils.bold(prevalence)))
elif prevalence == "common":
common.append((rule.meta.namespace, rule.meta.name, matches, rutils.bold(prevalence)))
else:
capability = f"{rutils.bold(rule.meta.name)} ({count} matches)"
rows.append((capability, rule.meta.namespace))
common.append((rule.meta.namespace, rule.meta.name, matches, "unknown"))

rows = []

def process_data(data):
"joins combine similar rules into a single section"
if len(data) == 0:
return
capabilities = ""
namespaces = ""
prevalences = ""

for ns, c, i, p in sorted(data, key=lambda x: (x[0], x[1])):
capabilities += f"{rutils.bold(c)} {i}\n"
namespaces += ns + "\n"
prevalences += p + "\n"

rows.append((capabilities.strip(), namespaces.strip(), prevalences.strip()))

process_data(rare)
process_data(common)

if rows:
ostream.write(
tabulate.tabulate(rows, headers=[width("Capability", 50), width("Namespace", 50)], tablefmt="mixed_outline")
tabulate.tabulate(
rows,
headers=[width("Capability", 50), width("Namespace", 50), width("Prevalence", 10)],
tablefmt="mixed_grid",
)
)
ostream.write("\n")
else:
Expand Down