|
| 1 | +import tempfile |
1 | 2 | import os |
2 | | - |
| 3 | +from pydantic_core import ValidationError |
3 | 4 | from azul_runner import FV, APIFeatureValue, Event, JobResult, State, test_template |
4 | 5 | from azul_runner.models import EventData |
5 | 6 |
|
@@ -296,6 +297,95 @@ def test_yara_match_result_disk(self): |
296 | 297 | inspect_data=True, |
297 | 298 | ) |
298 | 299 |
|
| 300 | + def test_yara_100_matching_rules(self): |
| 301 | + """Ensure when there are a 100+ matching rules that ony the first 50 streams are kept. |
| 302 | +
|
| 303 | + This is because the binary ingestor can only process up to 100 streams before it rejects files anyway. |
| 304 | + """ |
| 305 | + with tempfile.TemporaryDirectory("-yara-test") as temp_rule_dir: |
| 306 | + for iteration in range(101): |
| 307 | + raw_rule = ( |
| 308 | + """rule Exploit_CVE_2015_0313_NewStream%d { |
| 309 | + meta: |
| 310 | + rule_group = "Exploit" |
| 311 | +
|
| 312 | + //required |
| 313 | + classification = "UNCLASSIFIED" |
| 314 | + description = "Looks for presence of code that could indicate ANGLER EK use of this flash vuln" |
| 315 | + exploit = "CVE-2015-0313" |
| 316 | + info = "SWF" |
| 317 | + organisation = "Defence" |
| 318 | + poc = "azul@asd.gov.au" |
| 319 | + rule_version = "1" |
| 320 | + yara_version = "1.6" |
| 321 | +
|
| 322 | + //optional |
| 323 | + weight = 51 |
| 324 | +
|
| 325 | + strings: |
| 326 | + $ = "take_over_32(" |
| 327 | + $ = "get_x86_shellcode(" |
| 328 | + $ = "exploit_primordial_start(" |
| 329 | + $ = "exploit_primarodial_finish(" |
| 330 | + $ = "this.shellcodes.GetX86Shellcode(" |
| 331 | + $ = "Shellcodes(" |
| 332 | + $ = "attacking_buffer" |
| 333 | + $ = "take_over_buffer" |
| 334 | + $ = "make_spray_by_buffers_no_holes" |
| 335 | + $ = "fake_object_address" |
| 336 | + condition: |
| 337 | + any of them |
| 338 | +}""" |
| 339 | + % iteration |
| 340 | + ) |
| 341 | + with open(os.path.join(temp_rule_dir, f"ruleVersion-{iteration}.yara"), "w+") as f: |
| 342 | + f.write(raw_rule) |
| 343 | + |
| 344 | + result = self.do_execution( |
| 345 | + # This content should hit on the CVE-2015-0313 Angler EK rule in rules |
| 346 | + data_in=[("content", b'example -> "exploit_primarodial_finish(" <-')], |
| 347 | + config={ |
| 348 | + "yara_rules_path": temp_rule_dir, |
| 349 | + "version_suffix": "0", |
| 350 | + "name_suffix": "0", |
| 351 | + "security_override": "OFFICIAL", |
| 352 | + }, |
| 353 | + ) |
| 354 | + self.assertEqual(len(result.data.keys()), 50, "Must be capping the returned yara hits to 50") |
| 355 | + |
| 356 | + # If option is overridden the number of streams kept should match that. |
| 357 | + CONFIGURATION_OVERRIDE_FOR_MAX_YARA_STREAMS = 60 |
| 358 | + result = self.do_execution( |
| 359 | + # This content should hit on the CVE-2015-0313 Angler EK rule in rules |
| 360 | + data_in=[("content", b'example -> "exploit_primarodial_finish(" <-')], |
| 361 | + config={ |
| 362 | + "yara_rules_path": temp_rule_dir, |
| 363 | + "version_suffix": "0", |
| 364 | + "name_suffix": "0", |
| 365 | + "security_override": "OFFICIAL", |
| 366 | + "max_yara_hit_streams_to_keep": CONFIGURATION_OVERRIDE_FOR_MAX_YARA_STREAMS, |
| 367 | + }, |
| 368 | + ) |
| 369 | + self.assertEqual( |
| 370 | + len(result.data.keys()), |
| 371 | + CONFIGURATION_OVERRIDE_FOR_MAX_YARA_STREAMS, |
| 372 | + f"Must be capping the returned yara hits to {CONFIGURATION_OVERRIDE_FOR_MAX_YARA_STREAMS}", |
| 373 | + ) |
| 374 | + |
| 375 | + # Fails when attempting to configure a value that must be less than 100. |
| 376 | + with self.assertRaises(ValidationError): |
| 377 | + result = self.do_execution( |
| 378 | + # This content should hit on the CVE-2015-0313 Angler EK rule in rules |
| 379 | + data_in=[("content", b'example -> "exploit_primarodial_finish(" <-')], |
| 380 | + config={ |
| 381 | + "yara_rules_path": temp_rule_dir, |
| 382 | + "version_suffix": "0", |
| 383 | + "name_suffix": "0", |
| 384 | + "security_override": "OFFICIAL", |
| 385 | + "max_yara_hit_streams_to_keep": 200, |
| 386 | + }, |
| 387 | + ) |
| 388 | + |
299 | 389 | def test_yara_blacklist(self): |
300 | 390 | """Blacklist should filter the only rule.""" |
301 | 391 | path = os.path.join(os.path.dirname(__file__), rel_rules_dir) |
|
0 commit comments