mirror of
https://github.com/elder-plinius/P4RS3LT0NGV3.git
synced 2026-06-06 06:53:56 +02:00
Add Fuzzer tab: generate mutated payloads via Random Mix, ZW/invisible noise, Zalgo, whitespace/casing chaos, and encode shuffle; copy/download support
This commit is contained in:
+55
@@ -85,6 +85,13 @@
|
||||
>
|
||||
<i class="fas fa-layer-group"></i> Tokenizer
|
||||
</button>
|
||||
<button
|
||||
:class="{ active: activeTab === 'fuzzer' }"
|
||||
@click="switchToTab('fuzzer')"
|
||||
title="Generate many mutated payloads for testing"
|
||||
>
|
||||
<i class="fas fa-bug"></i> Fuzzer
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Steganography Tab -->
|
||||
@@ -389,6 +396,54 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Fuzzer Tab -->
|
||||
<div v-if="activeTab === 'fuzzer'" class="tab-content">
|
||||
<div class="transform-layout">
|
||||
<div class="transform-section">
|
||||
<div class="section-header">
|
||||
<h3><i class="fas fa-bug"></i> Fuzzer <small>mutate text into diverse payloads</small></h3>
|
||||
</div>
|
||||
<div class="options-grid">
|
||||
<label>
|
||||
Base text
|
||||
<textarea v-model="fuzzerInput" placeholder="Enter seed text to fuzz..." rows="3"></textarea>
|
||||
</label>
|
||||
<label>
|
||||
Cases
|
||||
<input type="number" v-model.number="fuzzerCount" min="1" max="500" />
|
||||
</label>
|
||||
<label>
|
||||
Seed (optional)
|
||||
<input type="text" v-model="fuzzerSeed" placeholder="e.g., 1337" />
|
||||
</label>
|
||||
</div>
|
||||
<div class="options-grid">
|
||||
<label class="switch neon"><input type="checkbox" v-model="fuzzUseRandomMix" /><span>Random Mix (transforms)</span></label>
|
||||
<label class="switch neon"><input type="checkbox" v-model="fuzzZeroWidth" /><span>Zero‑width pepper</span></label>
|
||||
<label class="switch neon"><input type="checkbox" v-model="fuzzUnicodeNoise" /><span>Unicode noise</span></label>
|
||||
<label class="switch neon"><input type="checkbox" v-model="fuzzZalgo" /><span>Zalgo</span></label>
|
||||
<label class="switch neon"><input type="checkbox" v-model="fuzzWhitespace" /><span>Whitespace chaos</span></label>
|
||||
<label class="switch neon"><input type="checkbox" v-model="fuzzCasing" /><span>Casing chaos</span></label>
|
||||
<label class="switch neon"><input type="checkbox" v-model="fuzzEncodeShuffle" /><span>Encode shuffle (Base64/URL/Hex)</span></label>
|
||||
</div>
|
||||
<div class="token-bomb-actions">
|
||||
<button class="transform-button" @click="generateFuzzCases"><i class="fas fa-hammer"></i> Generate Cases</button>
|
||||
<button class="copy-button" v-if="fuzzerOutputs.length" @click="copyAllFuzz"><i class="fas fa-copy"></i> Copy All</button>
|
||||
<button class="copy-button" v-if="fuzzerOutputs.length" @click="downloadFuzz"><i class="fas fa-download"></i> Download</button>
|
||||
</div>
|
||||
<div class="output-container" v-if="fuzzerOutputs.length">
|
||||
<div class="token-tiles" style="display:flex; flex-direction:column; gap:8px;">
|
||||
<div v-for="(out, i) in fuzzerOutputs" :key="'fz-'+i" class="token-chip" style="display:flex; align-items:center; gap:8px;">
|
||||
<span style="opacity:.7; min-width:32px;">#{{ i+1 }}</span>
|
||||
<textarea :value="out" readonly style="flex:1; min-height:46px;"></textarea>
|
||||
<button class="copy-button" @click="copyToClipboard(out)" title="Copy"><i class="fas fa-copy"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Text Transforms Tab -->
|
||||
<div v-if="activeTab === 'transforms'" class="tab-content">
|
||||
<div class="transform-layout">
|
||||
|
||||
@@ -82,6 +82,19 @@ window.app = new Vue({
|
||||
tokenizerCharCount: 0,
|
||||
tokenizerWordCount: 0,
|
||||
|
||||
// Fuzzer
|
||||
fuzzerInput: '',
|
||||
fuzzerCount: 20,
|
||||
fuzzerSeed: '',
|
||||
fuzzUseRandomMix: true,
|
||||
fuzzZeroWidth: true,
|
||||
fuzzUnicodeNoise: true,
|
||||
fuzzZalgo: false,
|
||||
fuzzWhitespace: true,
|
||||
fuzzCasing: true,
|
||||
fuzzEncodeShuffle: false,
|
||||
fuzzerOutputs: [],
|
||||
|
||||
// History of copied content
|
||||
copyHistory: [],
|
||||
maxHistoryItems: 10,
|
||||
@@ -1702,6 +1715,74 @@ window.app = new Vue({
|
||||
});
|
||||
}
|
||||
,
|
||||
// -------- Fuzzer --------
|
||||
seededRandomFactory(seedStr) {
|
||||
if (!seedStr) return Math.random;
|
||||
let h = 1779033703 ^ seedStr.length;
|
||||
for (let i=0;i<seedStr.length;i++) {
|
||||
h = Math.imul(h ^ seedStr.charCodeAt(i), 3432918353);
|
||||
h = (h << 13) | (h >>> 19);
|
||||
}
|
||||
return function() {
|
||||
h ^= h >>> 16; h = Math.imul(h, 2246822507); h ^= h >>> 13; h = Math.imul(h, 3266489909); h ^= h >>> 16;
|
||||
return (h >>> 0) / 4294967296;
|
||||
};
|
||||
},
|
||||
pick(arr, rnd) { return arr[Math.floor(rnd()*arr.length)]; },
|
||||
injectZeroWidth(text, rnd) {
|
||||
const zw = ['\u200B','\u200C','\u200D','\u2060'];
|
||||
return [...text].map(ch => (rnd()<0.2 ? ch+this.pick(zw,rnd) : ch)).join('');
|
||||
},
|
||||
injectUnicodeNoise(text, rnd) {
|
||||
const marks = ['\u0301','\u0300','\u0302','\u0303','\u0308','\u0307','\u0304'];
|
||||
return [...text].map(ch => (rnd()<0.15 ? ch+this.pick(marks,rnd) : ch)).join('');
|
||||
},
|
||||
whitespaceChaos(text, rnd) {
|
||||
return text.replace(/\s/g, (m)=> (rnd()<0.5? m : (rnd()<0.5?'\t':'\u00A0')));
|
||||
},
|
||||
casingChaos(text, rnd) {
|
||||
return [...text].map(c => /[a-z]/i.test(c)? (rnd()<0.5? c.toUpperCase():c.toLowerCase()) : c).join('');
|
||||
},
|
||||
encodeShuffle(text, rnd) {
|
||||
const opts = ['base64','base32','hex','base58','base62','url'];
|
||||
const t = this.pick(opts, rnd);
|
||||
const tx = {
|
||||
base64: ()=> window.transforms.base64.func(text),
|
||||
base32: ()=> window.transforms.base32.func(text),
|
||||
hex: ()=> window.transforms.hex.func(text),
|
||||
base58: ()=> window.transforms.base58.func(text),
|
||||
base62: ()=> window.transforms.base62.func(text),
|
||||
url: ()=> window.transforms.url.func(text)
|
||||
};
|
||||
return (tx[t]||(()=>text))();
|
||||
},
|
||||
generateFuzzCases() {
|
||||
const src = String(this.fuzzerInput || '');
|
||||
if (!src) { this.fuzzerOutputs = []; return; }
|
||||
const rnd = this.seededRandomFactory(String(this.fuzzerSeed||''));
|
||||
const out = [];
|
||||
for (let i=0;i<Math.max(1,Math.min(500,Number(this.fuzzerCount)||1)); i++) {
|
||||
let s = src;
|
||||
if (this.fuzzUseRandomMix) {
|
||||
try { s = window.transforms.randomizer.func(s, { minTransforms:2, maxTransforms:4 }); } catch(_) {}
|
||||
}
|
||||
if (this.fuzzZeroWidth) s = this.injectZeroWidth(s, rnd);
|
||||
if (this.fuzzUnicodeNoise) s = this.injectUnicodeNoise(s, rnd);
|
||||
if (this.fuzzWhitespace) s = this.whitespaceChaos(s, rnd);
|
||||
if (this.fuzzCasing) s = this.casingChaos(s, rnd);
|
||||
if (this.fuzzZalgo) { try { s = window.transforms.zalgo.func(s); } catch(_) {} }
|
||||
if (this.fuzzEncodeShuffle) s = this.encodeShuffle(s, rnd);
|
||||
out.push(s);
|
||||
}
|
||||
this.fuzzerOutputs = out;
|
||||
},
|
||||
copyAllFuzz() { this.copyToClipboard(this.fuzzerOutputs.join('\n')); },
|
||||
downloadFuzz() {
|
||||
const blob = new Blob([this.fuzzerOutputs.join('\n')], { type: 'text/plain;charset=utf-8' });
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement('a'); a.href = url; a.download = 'fuzz_cases.txt'; a.click();
|
||||
setTimeout(()=>URL.revokeObjectURL(url), 200);
|
||||
},
|
||||
// Quick estimate of token count for Tokenade
|
||||
estimateTokenadeTokens() {
|
||||
// Roughly approximate tokens by estimated character length
|
||||
|
||||
Reference in New Issue
Block a user