augure 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +136 -0
  3. data/LICENSE +21 -0
  4. data/README.md +217 -0
  5. data/exe/augure +181 -0
  6. data/exe/augure-benchmark +67 -0
  7. data/home/runner/work/augure/augure/docs/agent-snippet.md +31 -0
  8. data/home/runner/work/augure/augure/docs/auditability.md +160 -0
  9. data/home/runner/work/augure/augure/docs/build-format.md +119 -0
  10. data/home/runner/work/augure/augure/docs/explanation-architecture.md +74 -0
  11. data/home/runner/work/augure/augure/docs/how-to-swap-solver.md +73 -0
  12. data/home/runner/work/augure/augure/docs/how-to-write-rules.md +71 -0
  13. data/home/runner/work/augure/augure/docs/pack-format.md +137 -0
  14. data/home/runner/work/augure/augure/docs/reference.md +293 -0
  15. data/home/runner/work/augure/augure/docs/tutorial.md +108 -0
  16. data/home/runner/work/augure/augure/examples/ret2win.facts +11 -0
  17. data/home/runner/work/augure/augure/examples/split.facts +12 -0
  18. data/home/runner/work/augure/augure/exe/augure +181 -0
  19. data/home/runner/work/augure/augure/exe/augure-benchmark +67 -0
  20. data/home/runner/work/augure/augure/lib/augure/bandit.rb +118 -0
  21. data/home/runner/work/augure/augure/lib/augure/coverage.rb +56 -0
  22. data/home/runner/work/augure/augure/lib/augure/ctf_corpus.json +773 -0
  23. data/home/runner/work/augure/augure/lib/augure/engine.rb +128 -0
  24. data/home/runner/work/augure/augure/lib/augure/facts.rb +194 -0
  25. data/home/runner/work/augure/augure/lib/augure/kb_corpus.json +345 -0
  26. data/home/runner/work/augure/augure/lib/augure/knowledge_base.rb +109 -0
  27. data/home/runner/work/augure/augure/lib/augure/mcts.rb +178 -0
  28. data/home/runner/work/augure/augure/lib/augure/pack.rb +244 -0
  29. data/home/runner/work/augure/augure/lib/augure/pack_loader.rb +93 -0
  30. data/home/runner/work/augure/augure/lib/augure/parity.rb +69 -0
  31. data/home/runner/work/augure/augure/lib/augure/pipeline.rb +107 -0
  32. data/home/runner/work/augure/augure/lib/augure/priors.rb +32 -0
  33. data/home/runner/work/augure/augure/lib/augure/rules.rb +300 -0
  34. data/home/runner/work/augure/augure/lib/augure/smt_process.rb +48 -0
  35. data/home/runner/work/augure/augure/lib/augure/verifier.rb +40 -0
  36. data/home/runner/work/augure/augure/lib/augure/version.rb +5 -0
  37. data/home/runner/work/augure/augure/lib/augure.rb +25 -0
  38. data/home/runner/work/augure/augure/packs/banner_leak.yml +46 -0
  39. data/home/runner/work/augure/augure/packs/brop.yml +46 -0
  40. data/home/runner/work/augure/augure/packs/fastbin_hook.yml +45 -0
  41. data/home/runner/work/augure/augure/packs/got_partial_overwrite.yml +45 -0
  42. data/home/runner/work/augure/augure/packs/got_partial_overwrite_deref.yml +39 -0
  43. data/home/runner/work/augure/augure/packs/house_botcake.yml +38 -0
  44. data/home/runner/work/augure/augure/packs/house_force.yml +37 -0
  45. data/home/runner/work/augure/augure/packs/house_of_apple2.yml +45 -0
  46. data/home/runner/work/augure/augure/packs/house_orange.yml +38 -0
  47. data/home/runner/work/augure/augure/packs/jop.yml +39 -0
  48. data/home/runner/work/augure/augure/packs/large_bin_attack.yml +39 -0
  49. data/home/runner/work/augure/augure/packs/one_gadget.yml +38 -0
  50. data/home/runner/work/augure/augure/packs/orw.yml +55 -0
  51. data/home/runner/work/augure/augure/packs/ret2csu_v2.yml +55 -0
  52. data/home/runner/work/augure/augure/packs/ret2dlresolve_x86.yml +39 -0
  53. data/home/runner/work/augure/augure/packs/ret2partial_overwrite.yml +38 -0
  54. data/home/runner/work/augure/augure/packs/ret2vdso.yml +39 -0
  55. data/home/runner/work/augure/augure/packs/setcontext_srop.yml +46 -0
  56. data/home/runner/work/augure/augure/packs/uaf_tcache.yml +45 -0
  57. data/home/runner/work/augure/augure/packs/unsorted_bin_attack.yml +38 -0
  58. metadata +103 -0
@@ -0,0 +1,45 @@
1
+ technique: fastbin_hook
2
+ author: Gregory Epp
3
+ source: https://github.com/shellphint/how2heap (fastbin dup into hooks)
4
+
5
+ rules:
6
+ - id: app_fastbin_hook
7
+ head: [applicable, fastbin_hook]
8
+ conditions:
9
+ - [fact, vuln, heap]
10
+ - [fact, allocator, tcache]
11
+ - [cmp, glibc_minor, lt, 34]
12
+
13
+ kb:
14
+ - id: fastbin_hook_001
15
+ technique: fastbin_hook
16
+ description: >
17
+ Fastbin dup with a forged fd pointing near __malloc_hook /
18
+ __free_hook (size-aligned); the next malloc of that bin returns
19
+ the hook. __free_hook died in glibc 2.34.
20
+ chain: [fastbin_dup, fd_forge, hook_alloc]
21
+ unlocks: [arb_write]
22
+ success_rate: 0.40
23
+
24
+ mcts:
25
+ requires: []
26
+ provides: [arb_write]
27
+ terminal: true
28
+ success: 0.40
29
+
30
+ priors: [8, 12]
31
+
32
+
33
+ # The defender side (the corpus read backwards): what this technique
34
+ # looks like to the defenses. Armored by check 9.
35
+ detection:
36
+ - channel: syslog
37
+ signature: "double free on same size class then rapid controlled-size allocations"
38
+ note: "the fastbin poisoning sequence"
39
+ - channel: crash
40
+ signature: "execution redirected into the heap or a fake fd target"
41
+ note: "the hook firing into attacker memory"
42
+
43
+ # The ATT&CK mapping (the navigator export consumes it)
44
+ mitre:
45
+ - T1068
@@ -0,0 +1,45 @@
1
+ technique: got_partial_overwrite
2
+ author: Gregory Epp
3
+ source: https://ctf-wiki.org/pwn/linux/user-mode/io-file/got-hijack/
4
+
5
+ rules:
6
+ - id: app_got_partial_overwrite
7
+ head: [applicable, got_partial_overwrite]
8
+ conditions:
9
+ - [fact, relro, partial]
10
+ - [fact, got_overwrite_target, true]
11
+
12
+ kb:
13
+ - id: got_partial_overwrite_001
14
+ technique: got_partial_overwrite
15
+ description: >
16
+ Partial RELRO leaves the GOT writable: overwrite only the low
17
+ bytes of a resolved entry so the imported function lands on a
18
+ nearby win path. Two bytes beat a leak when PIE keeps the page
19
+ fixed.
20
+ chain: [low_bytes_overwrite, reimport_call]
21
+ unlocks: [shell]
22
+ success_rate: 0.50
23
+
24
+ mcts:
25
+ requires: []
26
+ provides: [shell]
27
+ terminal: true
28
+ success: 0.50
29
+
30
+ priors: [8, 12]
31
+
32
+
33
+ # The defender side (the corpus read backwards): what this technique
34
+ # looks like to the defenses. Armored by check 9.
35
+ detection:
36
+ - channel: syscall
37
+ signature: "partial write to a GOT page after a stack overflow"
38
+ note: "the GOT edit itself (write to a mapping that should be read-only under full RELRO)"
39
+ - channel: crash
40
+ signature: "unexpected control transfer through a PLT stub"
41
+ note: "the hijacked call"
42
+
43
+ # The ATT&CK mapping (the navigator export consumes it)
44
+ mitre:
45
+ - T1068
@@ -0,0 +1,39 @@
1
+ technique: got_partial_overwrite_deref
2
+ author: Gregory Epp
3
+ source: https://ctf-wiki.org/pwn/linux/user-mode/io-file/got-hijack/
4
+
5
+ rules:
6
+ - id: app_got_partial_overwrite_deref
7
+ head: [applicable, got_partial_overwrite_deref]
8
+ conditions:
9
+ - [fact, relro, partial]
10
+ - [fact, got_overwrite_target, true]
11
+ - [fact, has_reg_control, true]
12
+
13
+ kb:
14
+ - id: got_partial_overwrite_deref_001
15
+ technique: got_partial_overwrite_deref
16
+ description: >
17
+ The partial-GOT write with register control: overwrite the low
18
+ bytes of a resolved entry AND steer its argument registers - the
19
+ one-byte move that turns an arbitrary call into an arbitrary call
20
+ with your argument.
21
+ chain: [low_bytes_overwrite, reg_seed, reimport_call]
22
+ unlocks: [shell]
23
+ success_rate: 0.45
24
+
25
+ mcts:
26
+ requires: []
27
+ provides: [shell]
28
+ terminal: true
29
+ success: 0.45
30
+
31
+ priors: [6, 14]
32
+
33
+
34
+ # The defender side (the corpus read backwards): what this technique
35
+ # looks like to the defenses. Armored by check 9.
36
+ detection:
37
+ - channel: syscall
38
+ signature: "the same partial GOT write plus gadget-sourced register setup"
39
+ note: "the deref variant's chain"
@@ -0,0 +1,38 @@
1
+ technique: house_botcake
2
+ author: Gregory Epp
3
+ source: https://github.com/shellphint/how2heap (house_of_botcake)
4
+
5
+ rules:
6
+ - id: app_house_botcake
7
+ head: [applicable, house_botcake]
8
+ conditions:
9
+ - [fact, vuln, heap]
10
+ - [fact, allocator, tcache]
11
+ - [cmp, glibc_minor, ge, 29]
12
+
13
+ kb:
14
+ - id: house_botcake_001
15
+ technique: house_botcake
16
+ description: >
17
+ Tcache-era consolidation overlap: fill the tcache, force a
18
+ consolidated chunk into the unsorted bin, double-take it through
19
+ the tcache. The modern answer to double-free after the tcache key.
20
+ chain: [tcache_fill, consolidate, double_take]
21
+ unlocks: [arb_write]
22
+ success_rate: 0.45
23
+
24
+ mcts:
25
+ requires: []
26
+ provides: [arb_write]
27
+ terminal: true
28
+ success: 0.45
29
+
30
+ priors: [8, 12]
31
+
32
+
33
+ # The defender side (the corpus read backwards): what this technique
34
+ # looks like to the defenses. Armored by check 9.
35
+ detection:
36
+ - channel: syscall
37
+ signature: "7 tcache fills then a double free across unsorted/tcache boundary"
38
+ note: "the consolidation window the technique requires"
@@ -0,0 +1,37 @@
1
+ technique: house_force
2
+ author: Gregory Epp
3
+ source: https://github.com/shellphint/how2heap (house_of_force)
4
+
5
+ rules:
6
+ - id: app_house_force
7
+ head: [applicable, house_force]
8
+ conditions:
9
+ - [fact, vuln, heap]
10
+ - [fact, allocator, dlmalloc]
11
+
12
+ kb:
13
+ - id: house_force_001
14
+ technique: house_force
15
+ description: >
16
+ Overwrite the top chunk size with a huge value; the next malloc
17
+ returns a chunk overlapping any address. Killed by the top-chunk
18
+ sanity check in glibc 2.29; dlmalloc-era targets only.
19
+ chain: [top_size_overwrite, next_malloc_overlap, fnptr_takeover]
20
+ unlocks: [arb_write]
21
+ success_rate: 0.35
22
+
23
+ mcts:
24
+ requires: []
25
+ provides: [arb_write]
26
+ terminal: true
27
+ success: 0.35
28
+
29
+ priors: [8, 12]
30
+
31
+
32
+ # The defender side (the corpus read backwards): what this technique
33
+ # looks like to the defenses. Armored by check 9.
34
+ detection:
35
+ - channel: syscall
36
+ signature: "a huge malloc size passed to a fixed buffer-controlled value"
37
+ note: "the topchunk extension"
@@ -0,0 +1,45 @@
1
+ technique: house_of_apple2
2
+ author: Gregory Epp
3
+ source: https://github.com/ROPgadget - the _IO_wfile_jumps era (roderick01)
4
+
5
+ rules:
6
+ - id: app_house_of_apple2
7
+ head: [applicable, house_of_apple2]
8
+ conditions:
9
+ - [fact, vuln, heap]
10
+ - [cmp, glibc_minor, ge, 34]
11
+
12
+ kb:
13
+ - id: house_of_apple2_001
14
+ technique: house_of_apple2
15
+ description: >
16
+ glibc 2.34 killed the classic hooks; the FILE structure survived.
17
+ House of Apple 2 walks _IO_wfile_overflow's vtable path to
18
+ _IO_wfile_jumps, turning a forged FILE into an arbitrary call -
19
+ the modern FSOP answer to the hookless age.
20
+ chain: [file_forge, wfile_jumps, wide_vtable_call]
21
+ unlocks: [arb_call]
22
+ success_rate: 0.30
23
+
24
+ mcts:
25
+ requires: []
26
+ provides: [arb_call]
27
+ terminal: true
28
+ success: 0.30
29
+
30
+ priors: [5, 15]
31
+
32
+
33
+ # The defender side (the corpus read backwards): what this technique
34
+ # looks like to the defenses. Armored by check 9.
35
+ detection:
36
+ - channel: syscall
37
+ signature: "FILE structure writes into _IO_list_all territory (heap chunks at unusual sizes)"
38
+ note: "the fake FILE being groomed"
39
+ - channel: crash
40
+ signature: "abort inside _IO_flush_all_lockp with attacker-controlled pointers"
41
+ note: "the wide-character exit path firing"
42
+
43
+ # The ATT&CK mapping (the navigator export consumes it)
44
+ mitre:
45
+ - T1068
@@ -0,0 +1,38 @@
1
+ technique: house_orange
2
+ author: Gregory Epp
3
+ source: https://github.com/shellphint/how2heap (house_of_orange)
4
+
5
+ rules:
6
+ - id: app_house_orange
7
+ head: [applicable, house_orange]
8
+ conditions:
9
+ - [fact, vuln, heap]
10
+ - [fact, function_pointer_on_heap, true]
11
+ - [cmp, glibc_minor, lt, 26]
12
+
13
+ kb:
14
+ - id: house_orange_001
15
+ technique: house_orange
16
+ description: >
17
+ No free needed: shrink the top chunk through a heap extension,
18
+ free it into the unsorted bin, then forge the _IO_list_all path
19
+ to a fake FILE structure. Dead above glibc 2.25 (vtable checks).
20
+ chain: [top_extend, unsorted_free, file_struct_forge]
21
+ unlocks: [arb_write]
22
+ success_rate: 0.30
23
+
24
+ mcts:
25
+ requires: []
26
+ provides: [arb_write]
27
+ terminal: true
28
+ success: 0.30
29
+
30
+ priors: [7, 13]
31
+
32
+
33
+ # The defender side (the corpus read backwards): what this technique
34
+ # looks like to the defenses. Armored by check 9.
35
+ detection:
36
+ - channel: crash
37
+ signature: "abort in _IO_flush_all with a fake vtable pointer"
38
+ note: "the classic FSOP exit"
@@ -0,0 +1,39 @@
1
+ technique: jop
2
+ author: Gregory Epp
3
+ source: https://ctf-wiki.org/pwn/linux/user-mode/stackoverflow/x86/medium-rop/ (JOP/COP)
4
+
5
+ rules:
6
+ - id: app_jop
7
+ head: [applicable, jop]
8
+ conditions:
9
+ - [fact, vuln, sof]
10
+ - [fact, nx, true]
11
+ - [fact, has_reg_control, true]
12
+ - [fact, has_pivot_gadget, true]
13
+
14
+ kb:
15
+ - id: jop_001
16
+ technique: jop
17
+ description: >
18
+ Jump-oriented programming: the dispatcher is a jmp fed by a
19
+ controlled register - the shape CET-era defenses leave standing
20
+ when they watch returns. The facts name the dispatch gadget.
21
+ chain: [dispatcher_hunt, register_seed, dispatch_chain]
22
+ unlocks: [reg_control]
23
+ success_rate: 0.35
24
+
25
+ mcts:
26
+ requires: []
27
+ provides: [reg_control]
28
+ terminal: true
29
+ success: 0.35
30
+
31
+ priors: [6, 14]
32
+
33
+
34
+ # The defender side (the corpus read backwards): what this technique
35
+ # looks like to the defenses. Armored by check 9.
36
+ detection:
37
+ - channel: crash
38
+ signature: "control transfer through rip-relative jmp sequences in .text"
39
+ note: "the JOP dispatch loop"
@@ -0,0 +1,39 @@
1
+ technique: large_bin_attack
2
+ author: Gregory Epp
3
+ source: https://ctf-wiki.org/pwn/linux/user-mode/heap/ptmalloc2/large-bin-attack/
4
+
5
+ rules:
6
+ - id: app_large_bin_attack
7
+ head: [applicable, large_bin_attack]
8
+ conditions:
9
+ - [fact, vuln, heap]
10
+ - [fact, allocator, tcache]
11
+ - [cmp, glibc_minor, ge, 26]
12
+
13
+ kb:
14
+ - id: large_bin_attack_001
15
+ technique: large_bin_attack
16
+ description: >
17
+ A forged bk_nextsize/bk in the large-bin insertion writes two
18
+ chosen addresses over the target - the unsorted-bin write's big
19
+ sibling, alive in every modern glibc. Two writes, unknown values,
20
+ one target each.
21
+ chain: [large_bin_entry, forged_pointers, double_write]
22
+ unlocks: [arb_write]
23
+ success_rate: 0.35
24
+
25
+ mcts:
26
+ requires: []
27
+ provides: [arb_write]
28
+ terminal: true
29
+ success: 0.35
30
+
31
+ priors: [6, 14]
32
+
33
+
34
+ # The defender side (the corpus read backwards): what this technique
35
+ # looks like to the defenses. Armored by check 9.
36
+ detection:
37
+ - channel: syscall
38
+ signature: "unsorted bin scans with attacker-controlled bk writes (the two-chunk dance)"
39
+ note: "the largebin fd/bk corruption"
@@ -0,0 +1,38 @@
1
+ technique: one_gadget
2
+ author: Gregory Epp
3
+ source: https://github.com/david942j/one_gadget
4
+
5
+ rules:
6
+ - id: app_one_gadget
7
+ head: [applicable, one_gadget]
8
+ conditions:
9
+ - [fact, libc_present, true]
10
+ - [fact, nx, true]
11
+
12
+ kb:
13
+ - id: one_gadget_001
14
+ technique: one_gadget
15
+ description: >
16
+ A single libc address that execs /bin/sh when its register
17
+ constraints hold at the call site. Cheaper than a chain once the
18
+ base is known - the constraints (rsp alignment, null registers)
19
+ are the whole gamble.
20
+ chain: [constraint_check, base_apply, exec_sh]
21
+ unlocks: [shell]
22
+ success_rate: 0.50
23
+
24
+ mcts:
25
+ requires: [libc_base]
26
+ provides: [shell]
27
+ terminal: true
28
+ success: 0.50
29
+
30
+ priors: [5, 15]
31
+
32
+
33
+ # The defender side (the corpus read backwards): what this technique
34
+ # looks like to the defenses. Armored by check 9.
35
+ detection:
36
+ - channel: crash
37
+ signature: "execution into libc internals without a prior leak-print"
38
+ note: "a one_gadget constraint path"
@@ -0,0 +1,55 @@
1
+ technique: orw
2
+ author: Gregory Epp
3
+ source: https://ctf-wiki.org/pwn/linux/user-mode/sandbox/seccomp/c-sandbox-escape/
4
+
5
+ rules:
6
+ # sibling rules share the head: the OR the DSL expresses by
7
+ # splitting (the provenance carries every firing - engine B3).
8
+ # nx false: the stub rides the executable stack (the lab's case);
9
+ # nx true: the ROP path needs a syscall gadget in the binary.
10
+ - id: app_orw_stack
11
+ head: [applicable, orw]
12
+ conditions:
13
+ - [fact, seccomp, true]
14
+ - [fact, nx, false]
15
+ - id: app_orw_rop
16
+ head: [applicable, orw]
17
+ conditions:
18
+ - [fact, seccomp, true]
19
+ - [fact, nx, true]
20
+ - [fact, has_syscall_gadget, true]
21
+
22
+ kb:
23
+ - id: orw_001
24
+ technique: orw
25
+ description: >
26
+ seccomp blocks execve: the open/read/write chain reads the flag
27
+ without ever spawning a shell. The chain needs the syscall gadget
28
+ the profiler already hunts, and every gadget the facts carry.
29
+ chain: [open_flag, read_fd, write_stdout]
30
+ unlocks: [flag_read]
31
+ success_rate: 0.45
32
+
33
+ mcts:
34
+ requires: []
35
+ provides: [flag_read]
36
+ terminal: true
37
+ success: 0.45
38
+
39
+ priors: [6, 14]
40
+
41
+
42
+ # The defender side (the corpus read backwards): what this technique
43
+ # looks like to the defenses. Armored by check 9.
44
+ detection:
45
+ - channel: syscall
46
+ signature: "open+read+write syscall sequence without execve, on a filtered process"
47
+ note: "THE orw chain: execve blocked, orw the only path"
48
+ - channel: crash
49
+ signature: "SIGSYS (bad system call) following an execve attempt"
50
+ note: "the filter doing its job - the operator probed execve"
51
+
52
+ # The ATT&CK mapping (the navigator export consumes it)
53
+ mitre:
54
+ - T1083
55
+ - T1056
@@ -0,0 +1,55 @@
1
+ # Canonique: le modele de technique pack pour agents et operateurs.
2
+ # Structure, vocabulaire et limites: voir docs/pack-format.md.
3
+ technique: ret2csu_v2
4
+ author: Gregory Epp
5
+ source: https://ropemporium.com/challenge/ret2csu.html
6
+
7
+ rules:
8
+ - id: app_ret2csu_v2
9
+ head: [applicable, ret2csu_v2]
10
+ conditions:
11
+ - [fact, vuln, sof]
12
+ - [fact, nx, true]
13
+ - [match, gadget, 0, csu]
14
+
15
+ kb:
16
+ - id: ret2csu_v2_001
17
+ technique: ret2csu_v2
18
+ description: >
19
+ __libc_csu_init universal gadget populates rdx/rsi/rdi in
20
+ gadget-sparse binaries; the popper and mov gadgets enable
21
+ controlled multi-argument calls.
22
+ chain: [csu_popper, csu_mov, target_fn]
23
+ unlocks: [libc_base]
24
+ success_rate: 0.75
25
+
26
+ mcts:
27
+ requires: []
28
+ provides: [libc_base]
29
+ terminal: false
30
+ success: 0.70
31
+
32
+ priors: [14, 6]
33
+
34
+ # The assembly order, resolved by lictor's builder from the facts: the
35
+ # csu popper sets rbx=0, rbp=1, r12=fn@got, r13=arg2, r14=arg1, r15=arg0
36
+ # then csu_mov issues mov rdx,r13 / mov rsi,r14 / mov edi,r15d / call
37
+ # [r12+rbx*8]; 7 junk qwords fall through the second pop; the chain
38
+ # ends on the technique that follows (leak:main keeps the process
39
+ # alive). The arg values here are the canonical puts(puts@got) leak;
40
+ # an operator edits the consts for their call.
41
+ build:
42
+ technique: ret2csu_v2
43
+ layout:
44
+ - [padding, measured_offset]
45
+ - [chain, "gadget:csu_popper", "const:0", "const:1", "got_addr:puts",
46
+ "const:8", "got_addr:puts", "const:1", "gadget:csu_mov",
47
+ "const:0", "const:0", "const:0", "const:0", "const:0", "const:0", "const:0"]
48
+
49
+
50
+ # The defender side (the corpus read backwards): what this technique
51
+ # looks like to the defenses. Armored by check 9.
52
+ detection:
53
+ - channel: crash
54
+ signature: "call through __libc_csu_init gadget territory on a gadget-poor binary"
55
+ note: "the csu chain issuing calls"
@@ -0,0 +1,39 @@
1
+ technique: ret2dlresolve_x86
2
+ author: Gregory Epp
3
+ source: https://ropemporium.com/challenge/ret2dlresolve.html
4
+
5
+ rules:
6
+ - id: app_ret2dlresolve_x86
7
+ head: [applicable, ret2dlresolve_x86]
8
+ conditions:
9
+ - [fact, dt_lazy, true]
10
+ - [fact, reloc_writable, true]
11
+ - [fact, pie, false]
12
+
13
+ kb:
14
+ - id: ret2dlresolve_x86_001
15
+ technique: ret2dlresolve_x86
16
+ description: >
17
+ The 32-bit flavor of lazy-binding abuse: forge a fake
18
+ Rel/Sym/string triple at a known address and let _dl_runtime_resolve
19
+ fetch system() out of thin air. No leak, no libc needed - the
20
+ index arithmetic is the whole craft.
21
+ chain: [fake_reloc, fake_sym, resolve_system]
22
+ unlocks: [shell]
23
+ success_rate: 0.45
24
+
25
+ mcts:
26
+ requires: []
27
+ provides: [shell]
28
+ terminal: true
29
+ success: 0.45
30
+
31
+ priors: [8, 12]
32
+
33
+
34
+ # The defender side (the corpus read backwards): what this technique
35
+ # looks like to the defenses. Armored by check 9.
36
+ detection:
37
+ - channel: syscall
38
+ signature: "relocation resolution against a forged reloc index"
39
+ note: "the dlresolve structure"
@@ -0,0 +1,38 @@
1
+ technique: ret2partial_overwrite
2
+ author: Gregory Epp
3
+ source: https://ctf-wiki.org/pwn/linux/user-mode/stackoverflow/x86/partial-overwrite/
4
+
5
+ rules:
6
+ - id: app_ret2partial_overwrite
7
+ head: [applicable, ret2partial_overwrite]
8
+ conditions:
9
+ - [fact, pie, true]
10
+ - [fact, vuln, sof]
11
+ - [fact, canary, false]
12
+
13
+ kb:
14
+ - id: ret2partial_overwrite_001
15
+ technique: ret2partial_overwrite
16
+ description: >
17
+ PIE randomizes pages, not the low 12 bits: overwrite only the
18
+ saved return address's low bytes to hop onto a nearby gadget or
19
+ function. No leak needed when the canary is absent.
20
+ chain: [low_bytes_ret_overwrite, page_hop]
21
+ unlocks: [reg_control]
22
+ success_rate: 0.40
23
+
24
+ mcts:
25
+ requires: []
26
+ provides: [reg_control]
27
+ terminal: true
28
+ success: 0.40
29
+
30
+ priors: [8, 12]
31
+
32
+
33
+ # The defender side (the corpus read backwards): what this technique
34
+ # looks like to the defenses. Armored by check 9.
35
+ detection:
36
+ - channel: crash
37
+ signature: "low-byte-only return addresses (single NUL write) on a PIE target"
38
+ note: "the partial overwrite probes"
@@ -0,0 +1,39 @@
1
+ technique: ret2vdso
2
+ author: Gregory Epp
3
+ source: https://ctf-wiki.org/pwn/linux/user-mode/stackoverflow/x86/advanced-rop/ret2vdso/
4
+
5
+ rules:
6
+ - id: app_ret2vdso
7
+ head: [applicable, ret2vdso]
8
+ conditions:
9
+ - [fact, vuln, sof]
10
+ - [fact, nx, true]
11
+ - [fact, pie, true]
12
+
13
+ kb:
14
+ - id: ret2vdso_001
15
+ technique: ret2vdso
16
+ description: >
17
+ The vDSO is mapped at a near-static offset for the process's
18
+ lifetime: gadgets in it survive PIE randomization of the main
19
+ image. A syscall-bearing page the loader itself mapped - scarce
20
+ gadgets, but exactly where the main binary has none.
21
+ chain: [vdso_base_establish, gadget_hunt, syscall_hop]
22
+ unlocks: [reg_control]
23
+ success_rate: 0.30
24
+
25
+ mcts:
26
+ requires: []
27
+ provides: [reg_control]
28
+ terminal: true
29
+ success: 0.30
30
+
31
+ priors: [5, 15]
32
+
33
+
34
+ # The defender side (the corpus read backwards): what this technique
35
+ # looks like to the defenses. Armored by check 9.
36
+ detection:
37
+ - channel: crash
38
+ signature: "control into the vDSO mapping"
39
+ note: "the vDSO landing"
@@ -0,0 +1,46 @@
1
+ technique: setcontext_srop
2
+ author: Gregory Epp
3
+ source: https://ctf-wiki.org/pwn/linux/user-mode/stackoverflow/x86/advanced-rop/srop/
4
+
5
+ rules:
6
+ - id: app_setcontext_srop
7
+ head: [applicable, setcontext_srop]
8
+ conditions:
9
+ - [fact, libc_present, true]
10
+ - [fact, sigreturn_frame, true]
11
+ - [fact, has_syscall_gadget, true]
12
+
13
+ kb:
14
+ - id: setcontext_srop_001
15
+ technique: setcontext_srop
16
+ description: >
17
+ The sigreturn path has two doors: the classic SROP frame and the
18
+ setcontext gadget (offset +53/+61 in modern glibc) that loads a
19
+ full register state from a controlled ucontext. Same primitive,
20
+ fewer gadgets, no mprotect needed.
21
+ chain: [frame_or_ucontext, setcontext_load, syscall_shell]
22
+ unlocks: [shell]
23
+ success_rate: 0.45
24
+
25
+ mcts:
26
+ requires: [libc_base]
27
+ provides: [shell]
28
+ terminal: true
29
+ success: 0.45
30
+
31
+ priors: [7, 13]
32
+
33
+
34
+ # The defender side (the corpus read backwards): what this technique
35
+ # looks like to the defenses. Armored by check 9.
36
+ detection:
37
+ - channel: syscall
38
+ signature: "rt_sigreturn issued far from a real signal (the frame pivot)"
39
+ note: "the SROP frame being restored"
40
+ - channel: crash
41
+ signature: "register sets that never came from a signal delivery"
42
+ note: "the forged context"
43
+
44
+ # The ATT&CK mapping (the navigator export consumes it)
45
+ mitre:
46
+ - T1068