or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

data-storage.mdequivalence.mdindex.mdmarkings.mdobject-creation.mdpattern-matching.mdrelationships.mdstix-domain-objects.mdstix-observables.mdutilities.mdversioning.md

pattern-matching.mddocs/

0

# Pattern Matching and Expressions

1

2

Comprehensive pattern expression system for STIX indicator patterns including observation expressions, boolean logic, comparison operations, and temporal qualifiers for complex threat detection rules.

3

4

## Capabilities

5

6

### Pattern Expression Classes

7

8

Core classes for building STIX pattern expressions programmatically.

9

10

```python { .api }

11

class ObservationExpression:

12

"""

13

Base class for STIX observation expressions in patterns.

14

15

Constructor Parameters:

16

- operand: The operand expression (comparison, boolean, etc.)

17

"""

18

19

class AndObservationExpression:

20

"""

21

AND operation between two observation expressions.

22

23

Constructor Parameters:

24

- operands (list): List of observation expressions to AND together

25

"""

26

27

class OrObservationExpression:

28

"""

29

OR operation between two observation expressions.

30

31

Constructor Parameters:

32

- operands (list): List of observation expressions to OR together

33

"""

34

35

class FollowedByObservationExpression:

36

"""

37

Temporal FOLLOWEDBY operation between observation expressions.

38

39

Constructor Parameters:

40

- operands (list): List of observation expressions in temporal order

41

"""

42

43

class QualifiedObservationExpression:

44

"""

45

Observation expression with temporal qualifiers.

46

47

Constructor Parameters:

48

- observation_expression: Base observation expression

49

- qualifier: Temporal qualifier (WITHIN, REPEATS, etc.)

50

"""

51

52

class ParentheticalExpression:

53

"""

54

Parenthetical grouping of expressions.

55

56

Constructor Parameters:

57

- expression: Expression to wrap in parentheses

58

"""

59

```

60

61

### Boolean Expressions

62

63

Boolean logic operations for combining pattern conditions.

64

65

```python { .api }

66

class AndBooleanExpression:

67

"""

68

Boolean AND operation between expressions.

69

70

Constructor Parameters:

71

- operands (list): List of expressions to AND together

72

"""

73

74

class OrBooleanExpression:

75

"""

76

Boolean OR operation between expressions.

77

78

Constructor Parameters:

79

- operands (list): List of expressions to OR together

80

"""

81

```

82

83

Usage examples:

84

85

```python

86

from stix2 import (

87

ObjectPath, EqualityComparisonExpression, StringConstant,

88

AndBooleanExpression, OrBooleanExpression, ObservationExpression

89

)

90

91

# Create basic comparison expressions

92

ip_comparison = EqualityComparisonExpression(

93

ObjectPath("ipv4-addr", ["value"]),

94

StringConstant("192.168.1.100")

95

)

96

97

port_comparison = EqualityComparisonExpression(

98

ObjectPath("network-traffic", ["dst_port"]),

99

IntegerConstant(80)

100

)

101

102

# Combine with boolean AND

103

and_expression = AndBooleanExpression([ip_comparison, port_comparison])

104

105

# Create observation expression

106

observation = ObservationExpression(and_expression)

107

108

# Pattern string would be: "[ipv4-addr:value = '192.168.1.100' AND network-traffic:dst_port = 80]"

109

110

# Boolean OR example

111

protocol_http = EqualityComparisonExpression(

112

ObjectPath("network-traffic", ["protocols", 0]),

113

StringConstant("http")

114

)

115

116

protocol_https = EqualityComparisonExpression(

117

ObjectPath("network-traffic", ["protocols", 0]),

118

StringConstant("https")

119

)

120

121

or_expression = OrBooleanExpression([protocol_http, protocol_https])

122

```

123

124

### Comparison Expressions

125

126

Various comparison operations for pattern matching.

127

128

```python { .api }

129

class EqualityComparisonExpression:

130

"""

131

Equality comparison (=) between object path and constant.

132

133

Constructor Parameters:

134

- lhs: Left-hand side (typically ObjectPath)

135

- rhs: Right-hand side (typically constant value)

136

"""

137

138

class GreaterThanComparisonExpression:

139

"""Greater than comparison (>) between object path and constant."""

140

141

class GreaterThanEqualComparisonExpression:

142

"""Greater than or equal comparison (>=) between object path and constant."""

143

144

class LessThanComparisonExpression:

145

"""Less than comparison (<) between object path and constant."""

146

147

class LessThanEqualComparisonExpression:

148

"""Less than or equal comparison (<=) between object path and constant."""

149

150

class InComparisonExpression:

151

"""IN comparison for checking membership in a set."""

152

153

class LikeComparisonExpression:

154

"""LIKE comparison for pattern matching with wildcards."""

155

156

class MatchesComparisonExpression:

157

"""MATCHES comparison for regular expression matching."""

158

159

class IsSubsetComparisonExpression:

160

"""ISSUBSET comparison for subset relationships."""

161

162

class IsSupersetComparisonExpression:

163

"""ISSUPERSET comparison for superset relationships."""

164

```

165

166

Usage examples:

167

168

```python

169

from stix2 import (

170

ObjectPath, EqualityComparisonExpression, GreaterThanComparisonExpression,

171

LikeComparisonExpression, MatchesComparisonExpression, InComparisonExpression,

172

StringConstant, IntegerConstant, ListConstant

173

)

174

175

# Equality comparison

176

file_hash_eq = EqualityComparisonExpression(

177

ObjectPath("file", ["hashes", "MD5"]),

178

StringConstant("d41d8cd98f00b204e9800998ecf8427e")

179

)

180

181

# Numeric comparisons

182

file_size_gt = GreaterThanComparisonExpression(

183

ObjectPath("file", ["size"]),

184

IntegerConstant(1000000) # Files larger than 1MB

185

)

186

187

# Pattern matching with LIKE (SQL-style wildcards)

188

domain_like = LikeComparisonExpression(

189

ObjectPath("domain-name", ["value"]),

190

StringConstant("*.evil.com") # Subdomains of evil.com

191

)

192

193

# Regular expression matching

194

email_regex = MatchesComparisonExpression(

195

ObjectPath("email-addr", ["value"]),

196

StringConstant(r"^[a-zA-Z0-9._%+-]+@evil\.com$")

197

)

198

199

# IN comparison for membership

200

suspicious_ports = InComparisonExpression(

201

ObjectPath("network-traffic", ["dst_port"]),

202

ListConstant([1337, 31337, 4444, 5555]) # Common backdoor ports

203

)

204

```

205

206

### Object Paths

207

208

Specify paths to properties within STIX Cyber Observable Objects.

209

210

```python { .api }

211

class ObjectPath:

212

"""

213

Path to a property within a STIX Cyber Observable Object.

214

215

Constructor Parameters:

216

- object_type_name (str): Type of STIX object (e.g., "file", "ipv4-addr")

217

- property_path (list): List of property names/indices forming the path

218

"""

219

220

class BasicObjectPathComponent:

221

"""

222

Basic property name component of an object path.

223

224

Constructor Parameters:

225

- property_name (str): Name of the property

226

"""

227

228

class ListObjectPathComponent:

229

"""

230

List index component of an object path.

231

232

Constructor Parameters:

233

- index (int): List index (0-based)

234

"""

235

236

class ReferenceObjectPathComponent:

237

"""

238

Object reference component of an object path.

239

240

Constructor Parameters:

241

- reference_property (str): Name of reference property

242

"""

243

```

244

245

Usage examples:

246

247

```python

248

from stix2 import ObjectPath

249

250

# Simple property paths

251

ip_address = ObjectPath("ipv4-addr", ["value"])

252

file_name = ObjectPath("file", ["name"])

253

email_subject = ObjectPath("email-message", ["subject"])

254

255

# Nested property paths

256

file_hash_md5 = ObjectPath("file", ["hashes", "MD5"])

257

file_hash_sha256 = ObjectPath("file", ["hashes", "SHA-256"])

258

259

# Array/list index paths

260

first_protocol = ObjectPath("network-traffic", ["protocols", 0])

261

second_protocol = ObjectPath("network-traffic", ["protocols", 1])

262

263

# Extension property paths

264

http_method = ObjectPath("network-traffic", ["extensions", "http-request-ext", "request_method"])

265

pe_file_type = ObjectPath("file", ["extensions", "windows-pebinary-ext", "pe_type"])

266

267

# Complex nested paths

268

ntfs_ads_name = ObjectPath("file", ["extensions", "ntfs-ext", "alternate_data_streams", 0, "name"])

269

registry_value = ObjectPath("windows-registry-key", ["values", 0, "data"])

270

271

# Object reference paths (following references)

272

parent_dir = ObjectPath("file", ["parent_directory_ref"])

273

creator_user = ObjectPath("process", ["creator_user_ref"])

274

275

# Patterns using these paths

276

patterns = [

277

f"[{ip_address} = '192.168.1.1']",

278

f"[{file_hash_md5} = 'abc123def456']",

279

f"[{first_protocol} = 'tcp']",

280

f"[{http_method} = 'POST']"

281

]

282

```

283

284

### Constant Values

285

286

Various types of constant values used in pattern expressions.

287

288

```python { .api }

289

class StringConstant:

290

"""String constant value."""

291

def __init__(self, value): ...

292

293

class IntegerConstant:

294

"""Integer constant value."""

295

def __init__(self, value): ...

296

297

class FloatConstant:

298

"""Float constant value."""

299

def __init__(self, value): ...

300

301

class BooleanConstant:

302

"""Boolean constant value."""

303

def __init__(self, value): ...

304

305

class BinaryConstant:

306

"""Binary data constant value."""

307

def __init__(self, value): ...

308

309

class HashConstant:

310

"""Hash value constant."""

311

def __init__(self, value): ...

312

313

class HexConstant:

314

"""Hexadecimal constant value."""

315

def __init__(self, value): ...

316

317

class TimestampConstant:

318

"""Timestamp constant value."""

319

def __init__(self, value): ...

320

321

class ListConstant:

322

"""List of constant values."""

323

def __init__(self, value): ...

324

```

325

326

Usage examples:

327

328

```python

329

from stix2 import (

330

StringConstant, IntegerConstant, FloatConstant, BooleanConstant,

331

HashConstant, HexConstant, TimestampConstant, ListConstant, BinaryConstant

332

)

333

334

# String constants

335

domain_str = StringConstant("malicious.com")

336

user_agent = StringConstant("Malicious-Bot/1.0")

337

338

# Numeric constants

339

file_size = IntegerConstant(1048576) # 1MB

340

confidence_score = FloatConstant(0.85)

341

342

# Boolean constants

343

is_encrypted = BooleanConstant(True)

344

is_signed = BooleanConstant(False)

345

346

# Hash constants

347

md5_hash = HashConstant("d41d8cd98f00b204e9800998ecf8427e")

348

sha256_hash = HashConstant("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")

349

350

# Hex constants

351

magic_bytes = HexConstant("4D5A") # PE file magic bytes

352

byte_pattern = HexConstant("DEADBEEF")

353

354

# Timestamp constants

355

start_time = TimestampConstant("2021-04-23T10:30:00.000Z")

356

end_time = TimestampConstant("2021-04-23T11:00:00.000Z")

357

358

# List constants

359

port_list = ListConstant([80, 443, 8080, 8443])

360

protocol_list = ListConstant(["tcp", "http"])

361

hash_list = ListConstant([

362

"abc123def456",

363

"def456ghi789",

364

"ghi789jkl012"

365

])

366

367

# Binary constants

368

binary_data = BinaryConstant(b"\\x4D\\x5A\\x90\\x00") # PE header bytes

369

```

370

371

### Temporal Qualifiers

372

373

Add temporal constraints to observation expressions.

374

375

```python { .api }

376

class WithinQualifier:

377

"""

378

WITHIN qualifier for time-bounded observations.

379

380

Constructor Parameters:

381

- time_interval (int): Time interval in seconds

382

"""

383

384

class RepeatQualifier:

385

"""

386

REPEATS qualifier for repeated observations.

387

388

Constructor Parameters:

389

- times (int): Number of repetitions required

390

"""

391

392

class StartStopQualifier:

393

"""

394

START/STOP qualifier for time-bounded observations.

395

396

Constructor Parameters:

397

- start_time (timestamp): Start time for observations

398

- stop_time (timestamp): Stop time for observations

399

"""

400

```

401

402

Usage examples:

403

404

```python

405

from stix2 import (

406

WithinQualifier, RepeatQualifier, StartStopQualifier,

407

QualifiedObservationExpression, ObservationExpression

408

)

409

410

# Create base observation

411

base_observation = ObservationExpression(

412

EqualityComparisonExpression(

413

ObjectPath("ipv4-addr", ["value"]),

414

StringConstant("192.168.1.100")

415

)

416

)

417

418

# WITHIN qualifier - observe within 300 seconds (5 minutes)

419

within_qualifier = WithinQualifier(300)

420

within_observation = QualifiedObservationExpression(

421

base_observation,

422

within_qualifier

423

)

424

# Pattern: "[ipv4-addr:value = '192.168.1.100'] WITHIN 300 SECONDS"

425

426

# REPEATS qualifier - must be observed 3 times

427

repeat_qualifier = RepeatQualifier(3)

428

repeat_observation = QualifiedObservationExpression(

429

base_observation,

430

repeat_qualifier

431

)

432

# Pattern: "[ipv4-addr:value = '192.168.1.100'] REPEATS 3 TIMES"

433

434

# START/STOP qualifier - observe within specific time window

435

start_stop_qualifier = StartStopQualifier(

436

TimestampConstant("2021-04-23T10:00:00.000Z"),

437

TimestampConstant("2021-04-23T18:00:00.000Z")

438

)

439

bounded_observation = QualifiedObservationExpression(

440

base_observation,

441

start_stop_qualifier

442

)

443

# Pattern: "[ipv4-addr:value = '192.168.1.100'] START t'2021-04-23T10:00:00.000Z' STOP t'2021-04-23T18:00:00.000Z'"

444

445

# Combining qualifiers with complex observations

446

complex_observation = QualifiedObservationExpression(

447

AndObservationExpression([

448

ObservationExpression(EqualityComparisonExpression(

449

ObjectPath("network-traffic", ["dst_ref.value"]),

450

StringConstant("192.168.1.100")

451

)),

452

ObservationExpression(EqualityComparisonExpression(

453

ObjectPath("network-traffic", ["dst_port"]),

454

IntegerConstant(4444)

455

))

456

]),

457

RepeatQualifier(5)

458

)

459

# Pattern: "[network-traffic:dst_ref.value = '192.168.1.100' AND network-traffic:dst_port = 4444] REPEATS 5 TIMES"

460

```

461

462

### Complex Pattern Construction

463

464

Build sophisticated detection patterns using combinations of expressions.

465

466

```python

467

from stix2 import Indicator

468

469

# File-based indicator with multiple conditions

470

file_pattern = AndBooleanExpression([

471

EqualityComparisonExpression(

472

ObjectPath("file", ["hashes", "MD5"]),

473

StringConstant("d41d8cd98f00b204e9800998ecf8427e")

474

),

475

EqualityComparisonExpression(

476

ObjectPath("file", ["name"]),

477

StringConstant("malware.exe")

478

),

479

GreaterThanComparisonExpression(

480

ObjectPath("file", ["size"]),

481

IntegerConstant(50000)

482

)

483

])

484

485

file_indicator = Indicator(

486

name="Malicious PE File",

487

indicator_types=["malicious-activity"],

488

pattern_type="stix",

489

pattern=f"[{file_pattern}]"

490

)

491

492

# Network-based indicator with temporal constraints

493

network_base = AndBooleanExpression([

494

InComparisonExpression(

495

ObjectPath("network-traffic", ["dst_ref.value"]),

496

ListConstant(["192.168.1.100", "10.0.0.1", "172.16.0.1"])

497

),

498

InComparisonExpression(

499

ObjectPath("network-traffic", ["dst_port"]),

500

ListConstant([4444, 5555, 6666])

501

),

502

EqualityComparisonExpression(

503

ObjectPath("network-traffic", ["protocols", 0]),

504

StringConstant("tcp")

505

)

506

])

507

508

network_observation = QualifiedObservationExpression(

509

ObservationExpression(network_base),

510

WithinQualifier(3600) # Within 1 hour

511

)

512

513

network_indicator = Indicator(

514

name="C2 Communication Pattern",

515

indicator_types=["malicious-activity"],

516

pattern_type="stix",

517

pattern=f"{network_observation}"

518

)

519

520

# Multi-observable pattern with FOLLOWEDBY

521

initial_access = ObservationExpression(

522

EqualityComparisonExpression(

523

ObjectPath("email-message", ["subject"]),

524

StringConstant("Urgent: Account Verification Required")

525

)

526

)

527

528

payload_download = ObservationExpression(

529

LikeComparisonExpression(

530

ObjectPath("url", ["value"]),

531

StringConstant("http://malicious.com/*")

532

)

533

)

534

535

file_execution = ObservationExpression(

536

AndBooleanExpression([

537

LikeComparisonExpression(

538

ObjectPath("process", ["name"]),

539

StringConstant("*.exe")

540

),

541

EqualityComparisonExpression(

542

ObjectPath("process", ["parent_ref.name"]),

543

StringConstant("outlook.exe")

544

)

545

])

546

)

547

548

attack_chain = FollowedByObservationExpression([

549

initial_access,

550

payload_download,

551

file_execution

552

])

553

554

chain_indicator = Indicator(

555

name="Email-Based Attack Chain",

556

indicator_types=["malicious-activity"],

557

pattern_type="stix",

558

pattern=f"{attack_chain}"

559

)

560

561

# Advanced pattern with multiple qualifiers

562

advanced_pattern = QualifiedObservationExpression(

563

OrObservationExpression([

564

QualifiedObservationExpression(

565

ObservationExpression(

566

EqualityComparisonExpression(

567

ObjectPath("process", ["name"]),

568

StringConstant("cmd.exe")

569

)

570

),

571

RepeatQualifier(3)

572

),

573

QualifiedObservationExpression(

574

ObservationExpression(

575

EqualityComparisonExpression(

576

ObjectPath("process", ["name"]),

577

StringConstant("powershell.exe")

578

)

579

),

580

RepeatQualifier(2)

581

)

582

]),

583

WithinQualifier(600) # Within 10 minutes

584

)

585

586

advanced_indicator = Indicator(

587

name="Suspicious Process Activity",

588

indicator_types=["malicious-activity"],

589

pattern_type="stix",

590

pattern=f"{advanced_pattern}"

591

)

592

```

593

594

### Pattern Validation and Testing

595

596

Validate pattern syntax and test against observed data.

597

598

```python

599

from stix2 import parse_observable

600

601

def validate_pattern_against_data(pattern_str, observed_objects):

602

"""

603

Validate a STIX pattern against observed data.

604

Note: This is a simplified example - real pattern matching

605

would require a full STIX pattern engine.

606

"""

607

# Parse observed data

608

observables = []

609

for obj_data in observed_objects:

610

try:

611

observable = parse_observable(obj_data)

612

observables.append(observable)

613

except Exception as e:

614

print(f"Error parsing observable: {e}")

615

continue

616

617

# Simple pattern validation (would need full parser in reality)

618

print(f"Pattern: {pattern_str}")

619

print(f"Observables to test: {len(observables)}")

620

621

# Example: check if pattern references match observable types

622

for observable in observables:

623

print(f"Observable type: {observable.type}")

624

if observable.type in pattern_str:

625

print(f" - Pattern may match {observable.type}")

626

627

# Test data

628

test_observables = [

629

{

630

"type": "file",

631

"hashes": {

632

"MD5": "d41d8cd98f00b204e9800998ecf8427e"

633

},

634

"name": "malware.exe",

635

"size": 75000

636

},

637

{

638

"type": "ipv4-addr",

639

"value": "192.168.1.100"

640

},

641

{

642

"type": "network-traffic",

643

"protocols": ["tcp"],

644

"dst_port": 4444

645

}

646

]

647

648

# Validate patterns

649

validate_pattern_against_data(

650

"[file:hashes.MD5 = 'd41d8cd98f00b204e9800998ecf8427e' AND file:size > 50000]",

651

test_observables

652

)

653

```