rcekit 2.35.0__py3-none-any.whl

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.
@@ -0,0 +1,439 @@
1
+ Metadata-Version: 2.4
2
+ Name: rcekit
3
+ Version: 2.35.0
4
+ Summary: RCE detection & confirmation toolkit for authorised penetration testing
5
+ Author: Ahmad Kabiri
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/kabiri-labs/rcekit
8
+ Project-URL: Documentation, https://github.com/kabiri-labs/rcekit/blob/main/docs/guide.md
9
+ Project-URL: Changelog, https://github.com/kabiri-labs/rcekit/blob/main/CHANGELOG.md
10
+ Project-URL: Issues, https://github.com/kabiri-labs/rcekit/issues
11
+ Keywords: rce,command-injection,ssti,oob,pentesting,security-tools
12
+ Classifier: Development Status :: 5 - Production/Stable
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Information Technology
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Topic :: Security
18
+ Requires-Python: >=3.8
19
+ Description-Content-Type: text/markdown
20
+ License-File: LICENSE
21
+ Dynamic: license-file
22
+
23
+ # RCEKit
24
+
25
+ **`confirmed` means the target executed the input. `negative` means the probes reached it.**
26
+
27
+ **Version 2.35.0** · MIT · Python 3.8+ · zero third-party dependencies
28
+
29
+ RCEKit is an **RCE detection & confirmation toolkit** for authorised penetration
30
+ testing, red teaming and security research. Point it at a target you are allowed
31
+ to test — a URL or a captured HTTP request — and every finding comes back with
32
+ the tier it earned.
33
+
34
+ Every `confirmed` rests on a value RCEKit generated at random for that probe and
35
+ that reflection cannot produce: a computed result present in the response and
36
+ absent from a payload-free control, or an out-of-band callback carrying a token
37
+ only the target ever held. Weaker signals keep their own tiers and are never
38
+ promoted into it. And a run that could not test something never reports it as
39
+ clean.
40
+
41
+ ---
42
+
43
+ ## Proof, not "maybe"
44
+
45
+ RCEKit confirms RCE through **multiple methods** under one CLI. Below it is pointed
46
+ at **real, publicly-documented CVEs** in production software — each verdict
47
+ differenced against a payload-free control:
48
+
49
+ | RCE class | `--methods` | Real-world target | Verdict |
50
+ |---|---|---|---|
51
+ | OS command injection (results-based) | `reflected` | Webmin 1.910 — CVE-2019-15107 | **`confirmed`** |
52
+ | Expression injection (OGNL) | `eval` | Apache Struts2 — S2-001 | **`confirmed`** |
53
+ | Blind / out-of-band (Log4Shell/JNDI) | *OOB listener* | Log4Shell — CVE-2021-44228 | **`confirmed`** |
54
+ | Blind command injection (no output) | `time` | Webmin 1.910 — CVE-2019-15107 | `needs-review` |
55
+
56
+ <details open>
57
+ <summary><b><code>reflected</code> — OS command injection, Webmin CVE-2019-15107 → <code>confirmed</code></b></summary>
58
+
59
+ <br>
60
+
61
+ ![RCEKit confirming OS command injection on Webmin 1.910 (CVE-2019-15107): the shell computes arithmetic on random operands, the result is reflected in the response and absent from a payload-free control](confirmation-gifs/reflected-webmin-cve-2019-15107.gif)
62
+
63
+ </details>
64
+
65
+ <details>
66
+ <summary><b><code>eval</code> — OGNL expression injection, Apache Struts2 S2-001 → <code>confirmed</code></b></summary>
67
+
68
+ <br>
69
+
70
+ ![RCEKit confirming OGNL expression injection on Apache Struts2 (S2-001): the payload %{a*b} evaluates to the product in the response while the literal a*b does not](confirmation-gifs/eval-struts2-s2-001.gif)
71
+
72
+ </details>
73
+
74
+ <details>
75
+ <summary><b>out-of-band — blind Log4Shell (CVE-2021-44228) via a DNS callback → <code>confirmed</code></b></summary>
76
+
77
+ <br>
78
+
79
+ ![RCEKit auto-confirming a blind Log4Shell RCE (CVE-2021-44228) via an OOB DNS callback, correlating the DNS hit back to the exact payload](confirmation-gifs/oob-log4shell-cve-2021-44228.gif)
80
+
81
+ </details>
82
+
83
+ <details>
84
+ <summary><b><code>time</code> — blind command injection, Webmin CVE-2019-15107 → <code>needs-review</code></b></summary>
85
+
86
+ <br>
87
+
88
+ ![RCEKit measuring a linear timing response on Webmin 1.910 (CVE-2019-15107): response time tracks a controlled 0/N/2N delay series — a needs-review timing candidate, never confirmed on its own](confirmation-gifs/time-webmin-cve-2019-15107.gif)
89
+
90
+ </details>
91
+
92
+ ---
93
+
94
+ ## Quick start
95
+
96
+ RCEKit has **two supported shapes**, and neither is a fallback for the other.
97
+
98
+ **Install it** — `pipx` keeps the CLI in its own environment, which is what you
99
+ want for a tool rather than a library:
100
+
101
+ ```bash
102
+ pipx install rcekit # or: pip install rcekit
103
+ rcekit --doctor # confirms the corpus it will run with
104
+ ```
105
+
106
+ **Or take just the one file.** The payload corpus is built into the module, so
107
+ `rcekit.py` runs on its own with nothing beside it — no install step, no
108
+ site-packages, nothing to leave behind. On a client jump box, an air-gapped
109
+ host, or anywhere `pip install` is not an option:
110
+
111
+ ```bash
112
+ curl -O https://raw.githubusercontent.com/kabiri-labs/rcekit/main/rcekit.py
113
+ python rcekit.py --doctor # same corpus, same check, zero installation
114
+ ```
115
+
116
+ Both run the same code and report the same verdicts. Working from a checkout is
117
+ the third way, and needs no install either:
118
+
119
+ ```bash
120
+ git clone https://github.com/kabiri-labs/rcekit.git
121
+ cd rcekit # Python 3.8+, standard library only
122
+ ```
123
+
124
+ Put a `FUZZ` marker where your input lands (or select a parameter with `-p` when
125
+ using a captured request), and ask RCEKit to prove RCE:
126
+
127
+ ```bash
128
+ rcekit --acknowledge-consent \
129
+ --verify-url "https://target.example/lookup?host=FUZZ" \
130
+ --methods reflected,eval
131
+ ```
132
+
133
+ ```
134
+ [detect] methods: reflected, eval
135
+ [detect] sent 13 probes: confirmed=4, negative=9
136
+
137
+ [detect] CONFIRMED execution (4):
138
+ [reflected/unix/raw] ; echo RKYZRIP$((540141+314681))RKFWVFS$(echo RKBWOOC)RKYZRIP
139
+ (target computed 'RKYZRIP854822RKFWVFSRKBWOOCRKYZRIP' — random operands, absent from control)
140
+ ```
141
+
142
+ No external infrastructure, no config file.
143
+
144
+ **Don't take the GIFs on trust** — [reproduce them yourself](docs/verify-it-yourself.md)
145
+ against dockerised Webmin and Struts2 targets in about five minutes.
146
+
147
+ **Next:** the [**field guide**](docs/guide.md) walks the real situations — captured
148
+ requests, WAFs, filtered separators, quoted sinks, blind and no-egress targets —
149
+ one worked example each.
150
+
151
+ ---
152
+
153
+ ## What a verdict means
154
+
155
+ Finding an RCE *candidate* is easy. Reporting one that survives someone else's
156
+ retest is the hard part, and it fails in two directions: a "possibly vulnerable"
157
+ that turns out to be reflection, and a "not vulnerable" from a run that never
158
+ actually tested anything.
159
+
160
+ RCEKit answers with **seven verdicts that are never collapsed into each other**:
161
+
162
+ | Verdict | What it asserts |
163
+ |---|---|
164
+ | **`confirmed`** | The target executed the input. It returned a value it could not produce otherwise — computed from operands random to that probe — and that value is absent from a payload-free control. |
165
+ | **`deserialization-sink`** | The target reconstructed an attacker-supplied object graph. Proven, but about a *different property*: reaching RCE from there depends on classpath gadgets, so it is never called RCE. |
166
+ | **`needs-review`** | A real signal that is not proof on its own — a linear timing regression, a parser fingerprint. Worth your time, never worth the word "confirmed". |
167
+ | **`inconclusive`** | The evidence appeared, but could not be attributed to execution — the payload-free control carried it too. |
168
+ | **`negative`** | Probes were built, reached the target, and found nothing. |
169
+ | **`error`** | Nothing reached the target. |
170
+ | **`nothing-tested`** | No probes were built at all. |
171
+
172
+ The moment `confirmed` and `maybe` blur, `confirmed` stops meaning anything — so
173
+ nothing is ever promoted upward. A timing regression stays `needs-review` however
174
+ clean the slope. A deserialization callback stays `deserialization-sink` however
175
+ certain you are that the classpath is exploitable.
176
+
177
+ ### The other half: a run that tested nothing is never clean
178
+
179
+ The last two rows are the ones other tools do not have, and they matter more than
180
+ they look. A scanner that could not reach the target, or built no probes because
181
+ your flags excluded every one of them, has learned **nothing** about the target —
182
+ and printing `negative` there is a lie that reads exactly like safety.
183
+
184
+ So `error` and `nothing-tested` are first-class verdicts, the run exits non-zero,
185
+ and RCEKit says which of them happened and why:
186
+
187
+ ```
188
+ [!] No probes were built, so NOTHING WAS TESTED — this is not a negative result.
189
+ [!] None of the selected methods (reflected, file) apply to environment(s): sql.
190
+ ```
191
+
192
+ It fires wherever a run can quietly become empty: a method that does not apply to
193
+ the selected environments, a `--sink-shape` rung the chosen shell has no syntax
194
+ for, a `--bridges` selection entirely held back by the safety ceiling, a request
195
+ body that broke delivery before it arrived.
196
+
197
+ A run that was only *partly* blinded gets the same treatment one level down. If
198
+ you asked for a second-order oracle and the observed endpoint never answered, the
199
+ probe verdicts still stand — but the run tells you they were decided without ever
200
+ reading the channel you pointed it at, rather than letting them pass for a
201
+ second-order negative.
202
+
203
+ ---
204
+
205
+ ## What it confirms
206
+
207
+ One CLI, one `--methods` flag, covering the main paths to RCE:
208
+
209
+ | RCE class | `--methods` | How RCEKit proves it |
210
+ |-----------|-------------|----------------------|
211
+ | **OS command injection** | `reflected` | Makes the shell compute `$((a+b))` on random operands and collapse `$(echo TAG)`; confirms the *result*, never the literal expression. Written in the sink's own dialect — POSIX, `cmd.exe` or PowerShell. |
212
+ | **Code / expression injection** — SSTI, SpEL, OGNL, Groovy, `eval()` (CWE-94) | `eval` | Injects `a*b` in every common template syntax (`${…}` `{{…}}` `#{…}` `%{…}` `<%=…%>` `@(…)`, bare); confirms the **product** appears while the literal `a*b` does not. |
213
+ | **Blind command injection** (no output) | `time` | Fires a controlled `0/N/2N` delay series and confirms the response time tracks the delay **linearly**; reported `needs-review` — jitter can't fake it, but timing isn't a computed value. |
214
+ | **Internal / no-egress** targets | `file` | Writes a random token and fetches it back through *any* read-back path — a web root, an LFI parameter, a download or export handler, a `/tmp`-backed preview. Proves execution **plus** a write primitive, with no external listener. |
215
+ | **Upload / write primitive** — PUT-a-JSP, unchecked upload (CWE-434) | `write` | Writes a one-liner that *computes* a product through your own upload request, then fetches the file: the product is `confirmed` RCE, the source coming back verbatim is `needs-review` — arbitrary file write, served but not interpreted. |
216
+ | **Deserialization sinks** — fastjson, shiro, weblogic (CWE-502) | `deser` | Proves the endpoint **deserializes** attacker data, via a non-executing DNS gadget or an error-shape differential. Reported as `deserialization-sink`, **never** as RCE. |
217
+ | **Blind / out-of-band** — Log4Shell/JNDI, exfil, async | *(OOB listener)* | Built-in HTTP/DNS listener receives callbacks and correlates each to the exact payload. |
218
+
219
+ Three things widen where those methods can reach, without changing what any of
220
+ them will call `confirmed`:
221
+
222
+ - **Second-order execution** (`--observe-url`) — when the payload lands on one
223
+ request and runs on another: stored SSTI rendered on a profile page, a payload
224
+ written to a log a template engine later renders, a queued job. The observed
225
+ endpoint is differenced against a snapshot taken *before* any probe was sent.
226
+ - **Query-language bridges** (`--bridges`) — `COPY … FROM PROGRAM`,
227
+ `xp_cmdshell`, `expect://`. A bridge is a carrier, not an oracle: it wraps the
228
+ command the methods already build, so the same tiers apply through it.
229
+ - **Injection-point enumeration** (`-p all`) — query, JSON leaves, form fields,
230
+ cookies, headers and path segments, each encoded for where it lands, with the
231
+ probe cost printed before anything fires.
232
+
233
+ Mix methods freely: `--methods reflected,eval,time` runs all three and reports each
234
+ tier separately.
235
+
236
+ > **Honest scope.** RCEKit confirms RCE that is reachable by **injecting into a
237
+ > request** and interpreted by a shell or an evaluator. It does **not** cover
238
+ > memory-corruption bugs (buffer overflow, UAF) or argument injection into a
239
+ > no-shell `argv` array — those are different problems. **Deserialization gadget
240
+ > chains stay out of scope too**: `--methods deser` proves an endpoint
241
+ > *deserializes* attacker data and says so in its own tier, but which gadget (if
242
+ > any) turns that into execution depends on the target's classpath, and RCEKit
243
+ > does not claim to know. It aims to be excellent at the injection-driven RCE
244
+ > classes above rather than mediocre at everything.
245
+
246
+ ---
247
+
248
+ ## How RCEKit compares
249
+
250
+ The other tools in this space are built to get you **in**. RCEKit is built so the
251
+ finding **survives someone else's scrutiny** — the client's retest, the triage
252
+ queue, the report review. That difference shows up three times.
253
+
254
+ ### 1. One injection point, every class, one run
255
+
256
+ You rarely know the class before you test. Covering an unknown sink with
257
+ single-class tools means running each in turn and rebuilding the request for each
258
+ one:
259
+
260
+ | Can confirm | RCEKit | [commix](https://github.com/commixproject/commix) | [SSTImap](https://github.com/vladko312/SSTImap) | [Nuclei](https://github.com/projectdiscovery/nuclei) |
261
+ |---|---|---|---|---|
262
+ | OS command injection | ✅ | ✅ *(its whole scope)* | — | per template |
263
+ | Expression injection / SSTI | ✅ | via its eval-based technique | ✅ *(its whole scope)* | per template |
264
+ | Blind — timing | ✅ *as a separate tier* | ✅ | ✅ | — |
265
+ | Blind — out-of-band | ✅ *built-in listener* | — | — | via [interactsh](https://github.com/projectdiscovery/interactsh) |
266
+ | No-egress — write &amp; fetch back | ✅ *any read-back path* | ✅ *(web root)* | — | — |
267
+ | `cmd.exe` and PowerShell sinks | ✅ *per-dialect probes* | ✅ *(cmd)* | — | per template |
268
+ | Upload → write-then-execute | ✅ *write vs. execute, separate tiers* | — | — | per template |
269
+ | Second-order — lands here, runs there | ✅ | — | — | — |
270
+ | Query-language bridge to the OS | ✅ | — | — | per template |
271
+ | Deserialization sink | ✅ *own tier, never called RCE* | — | — | per template |
272
+ | **All of the above, one CLI, one run** | **✅** | — | — | — |
273
+
274
+ <sub>Coverage per each project's own documented technique list. SSTImap is the
275
+ maintained successor to <a href="https://github.com/epinna/tplmap">tplmap</a>,
276
+ which its author has marked unmaintained.</sub>
277
+
278
+ ```bash
279
+ # Command injection, expression injection and blind timing against the same
280
+ # parameter, in one pass, with zero infrastructure
281
+ python rcekit.py --acknowledge-consent -r request.txt -p host --methods reflected,eval,time
282
+ ```
283
+
284
+ ### 2. It argues with its own results
285
+
286
+ A tool reports what it found. RCEKit also reports **what it refused to believe** —
287
+ `inconclusive` is a verdict of its own, for evidence that showed up but could not
288
+ be attributed to execution:
289
+
290
+ ```
291
+ [detect] methods: reflected, eval
292
+ [detect] sent 13 probes: confirmed=0, inconclusive=2, negative=11
293
+ ```
294
+
295
+ Those two would have been someone else's finding. Five mechanisms produce that
296
+ verdict, and they run on every confirmation:
297
+
298
+ - **A payload-free control request.** Evidence must be present *with* the payload
299
+ and absent *without* it. Anything in both is `inconclusive`, not a finding.
300
+ - **A same-token inert control.** A second request carries the identical random
301
+ token in a non-executing form. A target that merely echoes input fails here —
302
+ which is how a reflection is separated from an execution.
303
+ - **Random operands, never fixed strings.** The oracle is a tag-wrapped sum or a
304
+ boundary-fenced product computed fresh each run. Echoing the payload returns
305
+ the literal `$((a+b))`; only execution returns the value.
306
+ - **Encoding-aware evidence search.** A sink that base64-, hex-, URL-, HTML- or
307
+ unicode-escapes its output still confirms — the raw body is checked first, so
308
+ decoding only ever turns a missed hit into a hit, never the reverse.
309
+ - **Whole-response evidence search.** The computed value is looked for in every
310
+ channel of the response — body, application headers, cookie values, the
311
+ redirect target, the HTTP reason phrase, and each leaf of a JSON error
312
+ envelope — and the finding names the channel that carried it. The control
313
+ differential is applied to every channel too, so widening where RCEKit looks
314
+ does not widen what it will call `confirmed`.
315
+
316
+ The same instinct runs the other way. Timing **never self-confirms**, a
317
+ deserialization callback is **never** called RCE, and a run that built no probes
318
+ is **never** called negative.
319
+
320
+ ### 3. It is built for an authorised engagement, not a lab
321
+
322
+ The controls a client's rules of engagement actually ask about, in the tool
323
+ rather than in your notes:
324
+
325
+ | | |
326
+ |---|---|
327
+ | **Consent gate** | Nothing exploitative generates or fires without `--acknowledge-consent`. |
328
+ | **Execution plan** | Prints the exact probe count, sink shapes, safety tiers and any outbound callback destinations **before** the first request goes out. |
329
+ | **Safe by default** | Reverse shells, credential access, cloud metadata, lateral movement and container escape are held back until you raise `--verify-active-risk`; persistence and backdoors need a second flag on top. Bridges that create an object on the target are held to the same ceiling. |
330
+ | **Cleanup commands** | `file`, `write` and the stateful bridges change target state, so every finding — including a `needs-review` — prints what to run to undo it. |
331
+ | **Credentials stay put** | The `file` read-back fetch carries the run's `Authorization`/`Cookie` headers only to the *same origin*, and says so out loud when it withholds them. The observed-channel fetch sends none at all unless you hand it a request with `--observe-request`. |
332
+ | **Redacted audit trail** | Every run lands in `exploit_audit.log`, recording that a credential header was sent, never its value. |
333
+ | **Watermarking** | `--watermark` stamps a traceable token into each payload, so a payload found in the client's logs months later is attributable to your run. |
334
+ | **No third-party callbacks** | The OOB listener is yours. Nothing is routed through a public interaction server, which some engagements forbid outright. |
335
+ | **One stdlib file** | `rcekit.py` runs alone — jump box, air-gapped host, anywhere `pip install` is not an option. |
336
+
337
+ ### When to reach for something else
338
+
339
+ Want a shell rather than a verdict? commix and SSTImap continue into
340
+ post-exploitation; RCEKit stops at proof by design. Sweeping thousands of hosts
341
+ for known CVEs? That is Nuclei's job — and RCEKit *writes* Nuclei templates
342
+ (`--output-format nuclei`), so it feeds your scanner instead of competing with it.
343
+ Already know the injection is SQL and want the database itself?
344
+ [sqlmap](https://github.com/sqlmapproject/sqlmap) owns that ground — RCEKit's
345
+ bridges exist to prove the **OS** is reachable from a text parameter, not to
346
+ exploit the database.
347
+
348
+ ---
349
+
350
+ ## Find your situation
351
+
352
+ Each row is a worked example in the [field guide](docs/guide.md) — the command,
353
+ what it sends, and how to read what comes back.
354
+
355
+ | Situation | Go to |
356
+ |---|---|
357
+ | I have a URL and a parameter | [Point at a URL](docs/guide.md#point-at-a-url) |
358
+ | I have a request saved from Burp | [Point at a captured request](docs/guide.md#point-at-a-captured-request) |
359
+ | The app is JSON / the payload keeps getting mangled | [Landing the payload intact](docs/guide.md#landing-the-payload-intact) |
360
+ | I don't know which class it is | [Choosing methods](docs/guide.md#choosing-methods) |
361
+ | The sink strips `;` | [When the sink filters separators](docs/guide.md#when-the-sink-filters-separators) |
362
+ | My input lands inside `'quotes'` | [Injecting inside quotes](docs/guide.md#injecting-inside-quotes) |
363
+ | The sink runs my input as the whole command | [Whole-command sinks](docs/guide.md#whole-command-sinks) |
364
+ | The target is Windows or the sink is PowerShell | [Windows and PowerShell sinks](docs/guide.md#windows-and-powershell-sinks) |
365
+ | There's a WAF | [Working around a WAF](docs/guide.md#working-around-a-waf) |
366
+ | No output comes back at all | [Blind targets](docs/guide.md#blind-targets) |
367
+ | No output *and* no egress | [No-egress targets](docs/guide.md#no-egress-targets) |
368
+ | The request stores a file instead of running anything | [Upload and write-primitive targets](docs/guide.md#upload-and-write-primitive-targets) |
369
+ | The payload runs later, on a different request | [When execution happens on another request](docs/guide.md#when-execution-happens-on-another-request) |
370
+ | The injection point is SQL and the sink is the database host | [Query-language bridges](docs/reference.md#query-language-bridges) |
371
+ | The endpoint takes a serialized object | [Deserialization sinks](docs/reference.md#deserialization-sinks-and-the-verdict-that-is-not-rce) |
372
+ | The sink is behind a login or a file upload | [Multi-step chains](docs/guide.md#multi-step-chains) |
373
+ | I got `needs-review` / `inconclusive` / `error` | [Reading the results](docs/guide.md#reading-the-results) |
374
+ | It says the corpus is unusable | [Troubleshooting](docs/guide.md#troubleshooting) |
375
+
376
+ ---
377
+
378
+ ## Documentation
379
+
380
+ | | |
381
+ |---|---|
382
+ | [**Verify it yourself**](docs/verify-it-yourself.md) | Reproduce the confirmations above on your own machine, against dockerised vulnerable targets. **Five minutes.** |
383
+ | [**Field guide**](docs/guide.md) | Example-driven walkthrough of every real situation, from a first probe to multi-step chains. **Start here.** |
384
+ | [**Payload generation &amp; exports**](docs/generation.md) | RCEKit as a payload generator: target profiles, and Burp / ffuf / Nuclei exports. |
385
+ | [**Reference**](docs/reference.md) | Every flag, environment, category, context, encoding and code-execution sink. |
386
+ | [**CHANGELOG.md**](CHANGELOG.md) | What changed in each release, and what to re-check when upgrading. |
387
+ | [CONTRIBUTING.md](CONTRIBUTING.md) | How to add sinks, categories, encodings and detection methods. |
388
+ | [SECURITY.md](SECURITY.md) | Reporting a vulnerability in RCEKit itself. |
389
+
390
+ ---
391
+
392
+ ## Safety &amp; ethics
393
+
394
+ - **Consent gate** — exploitation generation and verification require
395
+ `--acknowledge-consent`; `--detection-only` is benign and does not.
396
+ - **Safe by default** — verification fires only low-impact proofs; reverse shells,
397
+ download-execute, credential access, lateral movement, container escape,
398
+ cloud-metadata and OOB payloads are held back until you raise
399
+ `--verify-active-risk`. Destructive payloads (persistence, backdoors) are never
400
+ fired without `--verify-allow-destructive`. An **execution plan** prints exactly
401
+ what will be sent before anything fires.
402
+ - **Safety tiers** — `safe` / `intrusive` / `stateful`, filtered by `--max-safety`.
403
+ A method or bridge that leaves something behind is held to the same ordering as
404
+ every corpus payload, and the pre-flight names the tier each held-back item
405
+ actually needs.
406
+ - **Audit &amp; logging** — every exploitation/verification run is recorded in
407
+ `exploit_audit.log`; `--watermark` embeds a traceable token; execution logs go to
408
+ `rcekit.log`.
409
+ - **Corpus integrity** — a corpus that is corrupt, or an explicit
410
+ `--template-file` that is missing, makes RCEKit refuse to run and exit non-zero
411
+ rather than silently generate nothing (`--doctor` checks it). Only an absent
412
+ *default* corpus file falls back to the built-in copy, and it says so when it
413
+ does.
414
+
415
+ This toolkit is intended for authorised penetration testing, security research,
416
+ education, and defensive training only. **Never use it against systems without
417
+ explicit permission** — unauthorized testing is illegal.
418
+
419
+ ## Development
420
+
421
+ ```bash
422
+ python -m unittest discover -s tests # dependency-free test suite
423
+ ```
424
+
425
+ Contributions welcome — new sinks/categories, encodings, environments, detection
426
+ methods, bug fixes, and docs. Payload bases live in editable JSON templates
427
+ (`templates/payloads.json`), so most coverage extends without touching the Python
428
+ source. After changing the corpus, refresh the built-in copy that ships inside
429
+ `rcekit.py`:
430
+
431
+ ```bash
432
+ python tools/embed_corpus.py # --check verifies it is current
433
+ ```
434
+
435
+ The test suite fails if the two ever drift. See [CONTRIBUTING.md](CONTRIBUTING.md).
436
+
437
+ ## License
438
+
439
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,7 @@
1
+ rcekit.py,sha256=PIkg1Nnu-RPr9vuSkZWk_ow-CXs72NSBHn-_-VYaRe4,409130
2
+ rcekit-2.35.0.dist-info/licenses/LICENSE,sha256=DAnAPN7QbnDWpKKfm92_WiORSYz3BvkHNs04PH1vPoc,1069
3
+ rcekit-2.35.0.dist-info/METADATA,sha256=J8cmjcNlpcUDWsSPRX4AVSpsNXrYQx_ki3qGuRk7fhs,24307
4
+ rcekit-2.35.0.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
5
+ rcekit-2.35.0.dist-info/entry_points.txt,sha256=TK5Jc1VJCvmK2-JCYZt3LZctO_aZfACYjaQNrT9mZ1I,39
6
+ rcekit-2.35.0.dist-info/top_level.txt,sha256=SUCIQP3N-l6vyhKwYnSiZBhR1hrfVHEvOIkR9EMETa0,7
7
+ rcekit-2.35.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (84.0.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ rcekit = rcekit:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Ahmad Kabiri
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ rcekit