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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +136 -0
- data/LICENSE +21 -0
- data/README.md +217 -0
- data/exe/augure +181 -0
- data/exe/augure-benchmark +67 -0
- data/home/runner/work/augure/augure/docs/agent-snippet.md +31 -0
- data/home/runner/work/augure/augure/docs/auditability.md +160 -0
- data/home/runner/work/augure/augure/docs/build-format.md +119 -0
- data/home/runner/work/augure/augure/docs/explanation-architecture.md +74 -0
- data/home/runner/work/augure/augure/docs/how-to-swap-solver.md +73 -0
- data/home/runner/work/augure/augure/docs/how-to-write-rules.md +71 -0
- data/home/runner/work/augure/augure/docs/pack-format.md +137 -0
- data/home/runner/work/augure/augure/docs/reference.md +293 -0
- data/home/runner/work/augure/augure/docs/tutorial.md +108 -0
- data/home/runner/work/augure/augure/examples/ret2win.facts +11 -0
- data/home/runner/work/augure/augure/examples/split.facts +12 -0
- data/home/runner/work/augure/augure/exe/augure +181 -0
- data/home/runner/work/augure/augure/exe/augure-benchmark +67 -0
- data/home/runner/work/augure/augure/lib/augure/bandit.rb +118 -0
- data/home/runner/work/augure/augure/lib/augure/coverage.rb +56 -0
- data/home/runner/work/augure/augure/lib/augure/ctf_corpus.json +773 -0
- data/home/runner/work/augure/augure/lib/augure/engine.rb +128 -0
- data/home/runner/work/augure/augure/lib/augure/facts.rb +194 -0
- data/home/runner/work/augure/augure/lib/augure/kb_corpus.json +345 -0
- data/home/runner/work/augure/augure/lib/augure/knowledge_base.rb +109 -0
- data/home/runner/work/augure/augure/lib/augure/mcts.rb +178 -0
- data/home/runner/work/augure/augure/lib/augure/pack.rb +244 -0
- data/home/runner/work/augure/augure/lib/augure/pack_loader.rb +93 -0
- data/home/runner/work/augure/augure/lib/augure/parity.rb +69 -0
- data/home/runner/work/augure/augure/lib/augure/pipeline.rb +107 -0
- data/home/runner/work/augure/augure/lib/augure/priors.rb +32 -0
- data/home/runner/work/augure/augure/lib/augure/rules.rb +300 -0
- data/home/runner/work/augure/augure/lib/augure/smt_process.rb +48 -0
- data/home/runner/work/augure/augure/lib/augure/verifier.rb +40 -0
- data/home/runner/work/augure/augure/lib/augure/version.rb +5 -0
- data/home/runner/work/augure/augure/lib/augure.rb +25 -0
- data/home/runner/work/augure/augure/packs/banner_leak.yml +46 -0
- data/home/runner/work/augure/augure/packs/brop.yml +46 -0
- data/home/runner/work/augure/augure/packs/fastbin_hook.yml +45 -0
- data/home/runner/work/augure/augure/packs/got_partial_overwrite.yml +45 -0
- data/home/runner/work/augure/augure/packs/got_partial_overwrite_deref.yml +39 -0
- data/home/runner/work/augure/augure/packs/house_botcake.yml +38 -0
- data/home/runner/work/augure/augure/packs/house_force.yml +37 -0
- data/home/runner/work/augure/augure/packs/house_of_apple2.yml +45 -0
- data/home/runner/work/augure/augure/packs/house_orange.yml +38 -0
- data/home/runner/work/augure/augure/packs/jop.yml +39 -0
- data/home/runner/work/augure/augure/packs/large_bin_attack.yml +39 -0
- data/home/runner/work/augure/augure/packs/one_gadget.yml +38 -0
- data/home/runner/work/augure/augure/packs/orw.yml +55 -0
- data/home/runner/work/augure/augure/packs/ret2csu_v2.yml +55 -0
- data/home/runner/work/augure/augure/packs/ret2dlresolve_x86.yml +39 -0
- data/home/runner/work/augure/augure/packs/ret2partial_overwrite.yml +38 -0
- data/home/runner/work/augure/augure/packs/ret2vdso.yml +39 -0
- data/home/runner/work/augure/augure/packs/setcontext_srop.yml +46 -0
- data/home/runner/work/augure/augure/packs/uaf_tcache.yml +45 -0
- data/home/runner/work/augure/augure/packs/unsorted_bin_attack.yml +38 -0
- 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
|