@pensar/apex 0.0.13 → 0.0.15
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.
- package/build/benchmark.js +142 -49
- package/build/index.js +142 -49
- package/build/quicktest.js +2 -47
- package/build/swarm.js +148 -51
- package/package.json +2 -1
package/build/benchmark.js
CHANGED
|
@@ -43280,54 +43280,9 @@ Create this POC, test it, then retry document_finding.`,
|
|
|
43280
43280
|
};
|
|
43281
43281
|
const safeTitle = finding2.title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").substring(0, 50);
|
|
43282
43282
|
const findingId = `${timestamp.split("T")[0]}-${safeTitle}`;
|
|
43283
|
-
const filename = `${findingId}.
|
|
43283
|
+
const filename = `${findingId}.json`;
|
|
43284
43284
|
const filepath = join2(session.findingsPath, filename);
|
|
43285
|
-
|
|
43286
|
-
|
|
43287
|
-
**Severity:** ${finding2.severity}
|
|
43288
|
-
**Target:** ${session.target}
|
|
43289
|
-
**Date:** ${timestamp}
|
|
43290
|
-
**Session:** ${session.id}
|
|
43291
|
-
**POC:** \`${finding2.pocPath}\`
|
|
43292
|
-
|
|
43293
|
-
## Description
|
|
43294
|
-
|
|
43295
|
-
${finding2.description}
|
|
43296
|
-
|
|
43297
|
-
## Impact
|
|
43298
|
-
|
|
43299
|
-
${finding2.impact}
|
|
43300
|
-
|
|
43301
|
-
## Evidence
|
|
43302
|
-
|
|
43303
|
-
\`\`\`
|
|
43304
|
-
${finding2.evidence}
|
|
43305
|
-
\`\`\`
|
|
43306
|
-
|
|
43307
|
-
## Proof of Concept
|
|
43308
|
-
|
|
43309
|
-
A working POC script is available at: \`${finding2.pocPath}\`
|
|
43310
|
-
|
|
43311
|
-
To reproduce this vulnerability, run:
|
|
43312
|
-
\`\`\`bash
|
|
43313
|
-
cd ${session.rootPath}
|
|
43314
|
-
./${finding2.pocPath}
|
|
43315
|
-
\`\`\`
|
|
43316
|
-
|
|
43317
|
-
## Remediation
|
|
43318
|
-
|
|
43319
|
-
${finding2.remediation}
|
|
43320
|
-
|
|
43321
|
-
${finding2.references ? `## References
|
|
43322
|
-
|
|
43323
|
-
${finding2.references}` : ""}
|
|
43324
|
-
|
|
43325
|
-
---
|
|
43326
|
-
|
|
43327
|
-
*This finding was automatically documented by the Pensar penetration testing agent.*
|
|
43328
|
-
*POC verified and available at: ${finding2.pocPath}*
|
|
43329
|
-
`;
|
|
43330
|
-
writeFileSync2(filepath, markdown);
|
|
43285
|
+
writeFileSync2(filepath, JSON.stringify(findingWithMeta, null, 2));
|
|
43331
43286
|
const summaryPath = join2(session.rootPath, "findings-summary.md");
|
|
43332
43287
|
const summaryEntry = `- [${finding2.severity}] ${finding2.title} - \`findings/${filename}\` - POC: \`${finding2.pocPath}\`
|
|
43333
43288
|
`;
|
|
@@ -44540,6 +44495,143 @@ function saveSubagentMessages(orchestratorSession, subagentId, messages) {
|
|
|
44540
44495
|
fs.writeFileSync(`${subagentDir}/messages.json`, JSON.stringify(messages, null, 2));
|
|
44541
44496
|
}
|
|
44542
44497
|
|
|
44498
|
+
// node_modules/yocto-queue/index.js
|
|
44499
|
+
class Node {
|
|
44500
|
+
value;
|
|
44501
|
+
next;
|
|
44502
|
+
constructor(value) {
|
|
44503
|
+
this.value = value;
|
|
44504
|
+
}
|
|
44505
|
+
}
|
|
44506
|
+
|
|
44507
|
+
class Queue {
|
|
44508
|
+
#head;
|
|
44509
|
+
#tail;
|
|
44510
|
+
#size;
|
|
44511
|
+
constructor() {
|
|
44512
|
+
this.clear();
|
|
44513
|
+
}
|
|
44514
|
+
enqueue(value) {
|
|
44515
|
+
const node = new Node(value);
|
|
44516
|
+
if (this.#head) {
|
|
44517
|
+
this.#tail.next = node;
|
|
44518
|
+
this.#tail = node;
|
|
44519
|
+
} else {
|
|
44520
|
+
this.#head = node;
|
|
44521
|
+
this.#tail = node;
|
|
44522
|
+
}
|
|
44523
|
+
this.#size++;
|
|
44524
|
+
}
|
|
44525
|
+
dequeue() {
|
|
44526
|
+
const current = this.#head;
|
|
44527
|
+
if (!current) {
|
|
44528
|
+
return;
|
|
44529
|
+
}
|
|
44530
|
+
this.#head = this.#head.next;
|
|
44531
|
+
this.#size--;
|
|
44532
|
+
return current.value;
|
|
44533
|
+
}
|
|
44534
|
+
peek() {
|
|
44535
|
+
if (!this.#head) {
|
|
44536
|
+
return;
|
|
44537
|
+
}
|
|
44538
|
+
return this.#head.value;
|
|
44539
|
+
}
|
|
44540
|
+
clear() {
|
|
44541
|
+
this.#head = undefined;
|
|
44542
|
+
this.#tail = undefined;
|
|
44543
|
+
this.#size = 0;
|
|
44544
|
+
}
|
|
44545
|
+
get size() {
|
|
44546
|
+
return this.#size;
|
|
44547
|
+
}
|
|
44548
|
+
*[Symbol.iterator]() {
|
|
44549
|
+
let current = this.#head;
|
|
44550
|
+
while (current) {
|
|
44551
|
+
yield current.value;
|
|
44552
|
+
current = current.next;
|
|
44553
|
+
}
|
|
44554
|
+
}
|
|
44555
|
+
*drain() {
|
|
44556
|
+
while (this.#head) {
|
|
44557
|
+
yield this.dequeue();
|
|
44558
|
+
}
|
|
44559
|
+
}
|
|
44560
|
+
}
|
|
44561
|
+
|
|
44562
|
+
// node_modules/p-limit/index.js
|
|
44563
|
+
function pLimit(concurrency) {
|
|
44564
|
+
validateConcurrency(concurrency);
|
|
44565
|
+
const queue = new Queue;
|
|
44566
|
+
let activeCount = 0;
|
|
44567
|
+
const resumeNext = () => {
|
|
44568
|
+
if (activeCount < concurrency && queue.size > 0) {
|
|
44569
|
+
activeCount++;
|
|
44570
|
+
queue.dequeue()();
|
|
44571
|
+
}
|
|
44572
|
+
};
|
|
44573
|
+
const next = () => {
|
|
44574
|
+
activeCount--;
|
|
44575
|
+
resumeNext();
|
|
44576
|
+
};
|
|
44577
|
+
const run = async (function_, resolve2, arguments_) => {
|
|
44578
|
+
const result = (async () => function_(...arguments_))();
|
|
44579
|
+
resolve2(result);
|
|
44580
|
+
try {
|
|
44581
|
+
await result;
|
|
44582
|
+
} catch {}
|
|
44583
|
+
next();
|
|
44584
|
+
};
|
|
44585
|
+
const enqueue = (function_, resolve2, arguments_) => {
|
|
44586
|
+
new Promise((internalResolve) => {
|
|
44587
|
+
queue.enqueue(internalResolve);
|
|
44588
|
+
}).then(run.bind(undefined, function_, resolve2, arguments_));
|
|
44589
|
+
if (activeCount < concurrency) {
|
|
44590
|
+
resumeNext();
|
|
44591
|
+
}
|
|
44592
|
+
};
|
|
44593
|
+
const generator = (function_, ...arguments_) => new Promise((resolve2) => {
|
|
44594
|
+
enqueue(function_, resolve2, arguments_);
|
|
44595
|
+
});
|
|
44596
|
+
Object.defineProperties(generator, {
|
|
44597
|
+
activeCount: {
|
|
44598
|
+
get: () => activeCount
|
|
44599
|
+
},
|
|
44600
|
+
pendingCount: {
|
|
44601
|
+
get: () => queue.size
|
|
44602
|
+
},
|
|
44603
|
+
clearQueue: {
|
|
44604
|
+
value() {
|
|
44605
|
+
queue.clear();
|
|
44606
|
+
}
|
|
44607
|
+
},
|
|
44608
|
+
concurrency: {
|
|
44609
|
+
get: () => concurrency,
|
|
44610
|
+
set(newConcurrency) {
|
|
44611
|
+
validateConcurrency(newConcurrency);
|
|
44612
|
+
concurrency = newConcurrency;
|
|
44613
|
+
queueMicrotask(() => {
|
|
44614
|
+
while (activeCount < concurrency && queue.size > 0) {
|
|
44615
|
+
resumeNext();
|
|
44616
|
+
}
|
|
44617
|
+
});
|
|
44618
|
+
}
|
|
44619
|
+
},
|
|
44620
|
+
map: {
|
|
44621
|
+
async value(iterable, function_) {
|
|
44622
|
+
const promises = Array.from(iterable, (value, index) => this(function_, value, index));
|
|
44623
|
+
return Promise.all(promises);
|
|
44624
|
+
}
|
|
44625
|
+
}
|
|
44626
|
+
});
|
|
44627
|
+
return generator;
|
|
44628
|
+
}
|
|
44629
|
+
function validateConcurrency(concurrency) {
|
|
44630
|
+
if (!((Number.isInteger(concurrency) || concurrency === Number.POSITIVE_INFINITY) && concurrency > 0)) {
|
|
44631
|
+
throw new TypeError("Expected `concurrency` to be a number from 1 and up");
|
|
44632
|
+
}
|
|
44633
|
+
}
|
|
44634
|
+
|
|
44543
44635
|
// src/core/agent/thoroughPentestAgent/agent.ts
|
|
44544
44636
|
function runAgent3(opts) {
|
|
44545
44637
|
const {
|
|
@@ -44780,7 +44872,8 @@ You can spawn multiple agents in parallel - they will run concurrently.`,
|
|
|
44780
44872
|
execute: async ({ targets }) => {
|
|
44781
44873
|
try {
|
|
44782
44874
|
logger?.log(`[Orchestrator] Spawning ${targets.length} pentest agents...`);
|
|
44783
|
-
const
|
|
44875
|
+
const limit = pLimit(5);
|
|
44876
|
+
const promises = targets.map((targetInfo, index) => limit(async () => {
|
|
44784
44877
|
try {
|
|
44785
44878
|
const { streamResult: result } = runAgent({
|
|
44786
44879
|
session,
|
|
@@ -44900,7 +44993,7 @@ Objective: ${targetInfo.objective}`,
|
|
|
44900
44993
|
error: error46.message
|
|
44901
44994
|
};
|
|
44902
44995
|
}
|
|
44903
|
-
});
|
|
44996
|
+
}));
|
|
44904
44997
|
const results = await Promise.all(promises);
|
|
44905
44998
|
const successful = results.filter((r) => r.success).length;
|
|
44906
44999
|
const failed = results.filter((r) => !r.success).length;
|
package/build/index.js
CHANGED
|
@@ -73392,54 +73392,9 @@ Create this POC, test it, then retry document_finding.`,
|
|
|
73392
73392
|
};
|
|
73393
73393
|
const safeTitle = finding2.title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").substring(0, 50);
|
|
73394
73394
|
const findingId = `${timestamp.split("T")[0]}-${safeTitle}`;
|
|
73395
|
-
const filename = `${findingId}.
|
|
73395
|
+
const filename = `${findingId}.json`;
|
|
73396
73396
|
const filepath = join3(session.findingsPath, filename);
|
|
73397
|
-
|
|
73398
|
-
|
|
73399
|
-
**Severity:** ${finding2.severity}
|
|
73400
|
-
**Target:** ${session.target}
|
|
73401
|
-
**Date:** ${timestamp}
|
|
73402
|
-
**Session:** ${session.id}
|
|
73403
|
-
**POC:** \`${finding2.pocPath}\`
|
|
73404
|
-
|
|
73405
|
-
## Description
|
|
73406
|
-
|
|
73407
|
-
${finding2.description}
|
|
73408
|
-
|
|
73409
|
-
## Impact
|
|
73410
|
-
|
|
73411
|
-
${finding2.impact}
|
|
73412
|
-
|
|
73413
|
-
## Evidence
|
|
73414
|
-
|
|
73415
|
-
\`\`\`
|
|
73416
|
-
${finding2.evidence}
|
|
73417
|
-
\`\`\`
|
|
73418
|
-
|
|
73419
|
-
## Proof of Concept
|
|
73420
|
-
|
|
73421
|
-
A working POC script is available at: \`${finding2.pocPath}\`
|
|
73422
|
-
|
|
73423
|
-
To reproduce this vulnerability, run:
|
|
73424
|
-
\`\`\`bash
|
|
73425
|
-
cd ${session.rootPath}
|
|
73426
|
-
./${finding2.pocPath}
|
|
73427
|
-
\`\`\`
|
|
73428
|
-
|
|
73429
|
-
## Remediation
|
|
73430
|
-
|
|
73431
|
-
${finding2.remediation}
|
|
73432
|
-
|
|
73433
|
-
${finding2.references ? `## References
|
|
73434
|
-
|
|
73435
|
-
${finding2.references}` : ""}
|
|
73436
|
-
|
|
73437
|
-
---
|
|
73438
|
-
|
|
73439
|
-
*This finding was automatically documented by the Pensar penetration testing agent.*
|
|
73440
|
-
*POC verified and available at: ${finding2.pocPath}*
|
|
73441
|
-
`;
|
|
73442
|
-
writeFileSync3(filepath, markdown);
|
|
73397
|
+
writeFileSync3(filepath, JSON.stringify(findingWithMeta, null, 2));
|
|
73443
73398
|
const summaryPath = join3(session.rootPath, "findings-summary.md");
|
|
73444
73399
|
const summaryEntry = `- [${finding2.severity}] ${finding2.title} - \`findings/${filename}\` - POC: \`${finding2.pocPath}\`
|
|
73445
73400
|
`;
|
|
@@ -77546,6 +77501,143 @@ You MUST provide the details final report using create_attack_surface_report too
|
|
|
77546
77501
|
return { streamResult, session };
|
|
77547
77502
|
}
|
|
77548
77503
|
|
|
77504
|
+
// node_modules/yocto-queue/index.js
|
|
77505
|
+
class Node {
|
|
77506
|
+
value;
|
|
77507
|
+
next;
|
|
77508
|
+
constructor(value) {
|
|
77509
|
+
this.value = value;
|
|
77510
|
+
}
|
|
77511
|
+
}
|
|
77512
|
+
|
|
77513
|
+
class Queue {
|
|
77514
|
+
#head;
|
|
77515
|
+
#tail;
|
|
77516
|
+
#size;
|
|
77517
|
+
constructor() {
|
|
77518
|
+
this.clear();
|
|
77519
|
+
}
|
|
77520
|
+
enqueue(value) {
|
|
77521
|
+
const node = new Node(value);
|
|
77522
|
+
if (this.#head) {
|
|
77523
|
+
this.#tail.next = node;
|
|
77524
|
+
this.#tail = node;
|
|
77525
|
+
} else {
|
|
77526
|
+
this.#head = node;
|
|
77527
|
+
this.#tail = node;
|
|
77528
|
+
}
|
|
77529
|
+
this.#size++;
|
|
77530
|
+
}
|
|
77531
|
+
dequeue() {
|
|
77532
|
+
const current = this.#head;
|
|
77533
|
+
if (!current) {
|
|
77534
|
+
return;
|
|
77535
|
+
}
|
|
77536
|
+
this.#head = this.#head.next;
|
|
77537
|
+
this.#size--;
|
|
77538
|
+
return current.value;
|
|
77539
|
+
}
|
|
77540
|
+
peek() {
|
|
77541
|
+
if (!this.#head) {
|
|
77542
|
+
return;
|
|
77543
|
+
}
|
|
77544
|
+
return this.#head.value;
|
|
77545
|
+
}
|
|
77546
|
+
clear() {
|
|
77547
|
+
this.#head = undefined;
|
|
77548
|
+
this.#tail = undefined;
|
|
77549
|
+
this.#size = 0;
|
|
77550
|
+
}
|
|
77551
|
+
get size() {
|
|
77552
|
+
return this.#size;
|
|
77553
|
+
}
|
|
77554
|
+
*[Symbol.iterator]() {
|
|
77555
|
+
let current = this.#head;
|
|
77556
|
+
while (current) {
|
|
77557
|
+
yield current.value;
|
|
77558
|
+
current = current.next;
|
|
77559
|
+
}
|
|
77560
|
+
}
|
|
77561
|
+
*drain() {
|
|
77562
|
+
while (this.#head) {
|
|
77563
|
+
yield this.dequeue();
|
|
77564
|
+
}
|
|
77565
|
+
}
|
|
77566
|
+
}
|
|
77567
|
+
|
|
77568
|
+
// node_modules/p-limit/index.js
|
|
77569
|
+
function pLimit(concurrency) {
|
|
77570
|
+
validateConcurrency(concurrency);
|
|
77571
|
+
const queue = new Queue;
|
|
77572
|
+
let activeCount = 0;
|
|
77573
|
+
const resumeNext = () => {
|
|
77574
|
+
if (activeCount < concurrency && queue.size > 0) {
|
|
77575
|
+
activeCount++;
|
|
77576
|
+
queue.dequeue()();
|
|
77577
|
+
}
|
|
77578
|
+
};
|
|
77579
|
+
const next = () => {
|
|
77580
|
+
activeCount--;
|
|
77581
|
+
resumeNext();
|
|
77582
|
+
};
|
|
77583
|
+
const run = async (function_, resolve4, arguments_) => {
|
|
77584
|
+
const result = (async () => function_(...arguments_))();
|
|
77585
|
+
resolve4(result);
|
|
77586
|
+
try {
|
|
77587
|
+
await result;
|
|
77588
|
+
} catch {}
|
|
77589
|
+
next();
|
|
77590
|
+
};
|
|
77591
|
+
const enqueue = (function_, resolve4, arguments_) => {
|
|
77592
|
+
new Promise((internalResolve) => {
|
|
77593
|
+
queue.enqueue(internalResolve);
|
|
77594
|
+
}).then(run.bind(undefined, function_, resolve4, arguments_));
|
|
77595
|
+
if (activeCount < concurrency) {
|
|
77596
|
+
resumeNext();
|
|
77597
|
+
}
|
|
77598
|
+
};
|
|
77599
|
+
const generator = (function_, ...arguments_) => new Promise((resolve4) => {
|
|
77600
|
+
enqueue(function_, resolve4, arguments_);
|
|
77601
|
+
});
|
|
77602
|
+
Object.defineProperties(generator, {
|
|
77603
|
+
activeCount: {
|
|
77604
|
+
get: () => activeCount
|
|
77605
|
+
},
|
|
77606
|
+
pendingCount: {
|
|
77607
|
+
get: () => queue.size
|
|
77608
|
+
},
|
|
77609
|
+
clearQueue: {
|
|
77610
|
+
value() {
|
|
77611
|
+
queue.clear();
|
|
77612
|
+
}
|
|
77613
|
+
},
|
|
77614
|
+
concurrency: {
|
|
77615
|
+
get: () => concurrency,
|
|
77616
|
+
set(newConcurrency) {
|
|
77617
|
+
validateConcurrency(newConcurrency);
|
|
77618
|
+
concurrency = newConcurrency;
|
|
77619
|
+
queueMicrotask(() => {
|
|
77620
|
+
while (activeCount < concurrency && queue.size > 0) {
|
|
77621
|
+
resumeNext();
|
|
77622
|
+
}
|
|
77623
|
+
});
|
|
77624
|
+
}
|
|
77625
|
+
},
|
|
77626
|
+
map: {
|
|
77627
|
+
async value(iterable, function_) {
|
|
77628
|
+
const promises = Array.from(iterable, (value, index) => this(function_, value, index));
|
|
77629
|
+
return Promise.all(promises);
|
|
77630
|
+
}
|
|
77631
|
+
}
|
|
77632
|
+
});
|
|
77633
|
+
return generator;
|
|
77634
|
+
}
|
|
77635
|
+
function validateConcurrency(concurrency) {
|
|
77636
|
+
if (!((Number.isInteger(concurrency) || concurrency === Number.POSITIVE_INFINITY) && concurrency > 0)) {
|
|
77637
|
+
throw new TypeError("Expected `concurrency` to be a number from 1 and up");
|
|
77638
|
+
}
|
|
77639
|
+
}
|
|
77640
|
+
|
|
77549
77641
|
// src/core/agent/thoroughPentestAgent/agent.ts
|
|
77550
77642
|
function runAgent3(opts) {
|
|
77551
77643
|
const {
|
|
@@ -77786,7 +77878,8 @@ You can spawn multiple agents in parallel - they will run concurrently.`,
|
|
|
77786
77878
|
execute: async ({ targets }) => {
|
|
77787
77879
|
try {
|
|
77788
77880
|
logger?.log(`[Orchestrator] Spawning ${targets.length} pentest agents...`);
|
|
77789
|
-
const
|
|
77881
|
+
const limit = pLimit(5);
|
|
77882
|
+
const promises = targets.map((targetInfo, index) => limit(async () => {
|
|
77790
77883
|
try {
|
|
77791
77884
|
const { streamResult: result } = runAgent({
|
|
77792
77885
|
session,
|
|
@@ -77906,7 +77999,7 @@ Objective: ${targetInfo.objective}`,
|
|
|
77906
77999
|
error: error46.message
|
|
77907
78000
|
};
|
|
77908
78001
|
}
|
|
77909
|
-
});
|
|
78002
|
+
}));
|
|
77910
78003
|
const results = await Promise.all(promises);
|
|
77911
78004
|
const successful = results.filter((r) => r.success).length;
|
|
77912
78005
|
const failed = results.filter((r) => !r.success).length;
|
package/build/quicktest.js
CHANGED
|
@@ -42026,54 +42026,9 @@ Create this POC, test it, then retry document_finding.`,
|
|
|
42026
42026
|
};
|
|
42027
42027
|
const safeTitle = finding2.title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").substring(0, 50);
|
|
42028
42028
|
const findingId = `${timestamp.split("T")[0]}-${safeTitle}`;
|
|
42029
|
-
const filename = `${findingId}.
|
|
42029
|
+
const filename = `${findingId}.json`;
|
|
42030
42030
|
const filepath = join3(session.findingsPath, filename);
|
|
42031
|
-
|
|
42032
|
-
|
|
42033
|
-
**Severity:** ${finding2.severity}
|
|
42034
|
-
**Target:** ${session.target}
|
|
42035
|
-
**Date:** ${timestamp}
|
|
42036
|
-
**Session:** ${session.id}
|
|
42037
|
-
**POC:** \`${finding2.pocPath}\`
|
|
42038
|
-
|
|
42039
|
-
## Description
|
|
42040
|
-
|
|
42041
|
-
${finding2.description}
|
|
42042
|
-
|
|
42043
|
-
## Impact
|
|
42044
|
-
|
|
42045
|
-
${finding2.impact}
|
|
42046
|
-
|
|
42047
|
-
## Evidence
|
|
42048
|
-
|
|
42049
|
-
\`\`\`
|
|
42050
|
-
${finding2.evidence}
|
|
42051
|
-
\`\`\`
|
|
42052
|
-
|
|
42053
|
-
## Proof of Concept
|
|
42054
|
-
|
|
42055
|
-
A working POC script is available at: \`${finding2.pocPath}\`
|
|
42056
|
-
|
|
42057
|
-
To reproduce this vulnerability, run:
|
|
42058
|
-
\`\`\`bash
|
|
42059
|
-
cd ${session.rootPath}
|
|
42060
|
-
./${finding2.pocPath}
|
|
42061
|
-
\`\`\`
|
|
42062
|
-
|
|
42063
|
-
## Remediation
|
|
42064
|
-
|
|
42065
|
-
${finding2.remediation}
|
|
42066
|
-
|
|
42067
|
-
${finding2.references ? `## References
|
|
42068
|
-
|
|
42069
|
-
${finding2.references}` : ""}
|
|
42070
|
-
|
|
42071
|
-
---
|
|
42072
|
-
|
|
42073
|
-
*This finding was automatically documented by the Pensar penetration testing agent.*
|
|
42074
|
-
*POC verified and available at: ${finding2.pocPath}*
|
|
42075
|
-
`;
|
|
42076
|
-
writeFileSync3(filepath, markdown);
|
|
42031
|
+
writeFileSync3(filepath, JSON.stringify(findingWithMeta, null, 2));
|
|
42077
42032
|
const summaryPath = join3(session.rootPath, "findings-summary.md");
|
|
42078
42033
|
const summaryEntry = `- [${finding2.severity}] ${finding2.title} - \`findings/${filename}\` - POC: \`${finding2.pocPath}\`
|
|
42079
42034
|
`;
|
package/build/swarm.js
CHANGED
|
@@ -42026,54 +42026,9 @@ Create this POC, test it, then retry document_finding.`,
|
|
|
42026
42026
|
};
|
|
42027
42027
|
const safeTitle = finding2.title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").substring(0, 50);
|
|
42028
42028
|
const findingId = `${timestamp.split("T")[0]}-${safeTitle}`;
|
|
42029
|
-
const filename = `${findingId}.
|
|
42029
|
+
const filename = `${findingId}.json`;
|
|
42030
42030
|
const filepath = join3(session.findingsPath, filename);
|
|
42031
|
-
|
|
42032
|
-
|
|
42033
|
-
**Severity:** ${finding2.severity}
|
|
42034
|
-
**Target:** ${session.target}
|
|
42035
|
-
**Date:** ${timestamp}
|
|
42036
|
-
**Session:** ${session.id}
|
|
42037
|
-
**POC:** \`${finding2.pocPath}\`
|
|
42038
|
-
|
|
42039
|
-
## Description
|
|
42040
|
-
|
|
42041
|
-
${finding2.description}
|
|
42042
|
-
|
|
42043
|
-
## Impact
|
|
42044
|
-
|
|
42045
|
-
${finding2.impact}
|
|
42046
|
-
|
|
42047
|
-
## Evidence
|
|
42048
|
-
|
|
42049
|
-
\`\`\`
|
|
42050
|
-
${finding2.evidence}
|
|
42051
|
-
\`\`\`
|
|
42052
|
-
|
|
42053
|
-
## Proof of Concept
|
|
42054
|
-
|
|
42055
|
-
A working POC script is available at: \`${finding2.pocPath}\`
|
|
42056
|
-
|
|
42057
|
-
To reproduce this vulnerability, run:
|
|
42058
|
-
\`\`\`bash
|
|
42059
|
-
cd ${session.rootPath}
|
|
42060
|
-
./${finding2.pocPath}
|
|
42061
|
-
\`\`\`
|
|
42062
|
-
|
|
42063
|
-
## Remediation
|
|
42064
|
-
|
|
42065
|
-
${finding2.remediation}
|
|
42066
|
-
|
|
42067
|
-
${finding2.references ? `## References
|
|
42068
|
-
|
|
42069
|
-
${finding2.references}` : ""}
|
|
42070
|
-
|
|
42071
|
-
---
|
|
42072
|
-
|
|
42073
|
-
*This finding was automatically documented by the Pensar penetration testing agent.*
|
|
42074
|
-
*POC verified and available at: ${finding2.pocPath}*
|
|
42075
|
-
`;
|
|
42076
|
-
writeFileSync3(filepath, markdown);
|
|
42031
|
+
writeFileSync3(filepath, JSON.stringify(findingWithMeta, null, 2));
|
|
42077
42032
|
const summaryPath = join3(session.rootPath, "findings-summary.md");
|
|
42078
42033
|
const summaryEntry = `- [${finding2.severity}] ${finding2.title} - \`findings/${filename}\` - POC: \`${finding2.pocPath}\`
|
|
42079
42034
|
`;
|
|
@@ -42435,6 +42390,145 @@ Remember to follow a systematic methodology and explain your reasoning for each
|
|
|
42435
42390
|
}
|
|
42436
42391
|
// scripts/swarm.ts
|
|
42437
42392
|
import { readFileSync as readFileSync4 } from "fs";
|
|
42393
|
+
|
|
42394
|
+
// node_modules/yocto-queue/index.js
|
|
42395
|
+
class Node {
|
|
42396
|
+
value;
|
|
42397
|
+
next;
|
|
42398
|
+
constructor(value) {
|
|
42399
|
+
this.value = value;
|
|
42400
|
+
}
|
|
42401
|
+
}
|
|
42402
|
+
|
|
42403
|
+
class Queue {
|
|
42404
|
+
#head;
|
|
42405
|
+
#tail;
|
|
42406
|
+
#size;
|
|
42407
|
+
constructor() {
|
|
42408
|
+
this.clear();
|
|
42409
|
+
}
|
|
42410
|
+
enqueue(value) {
|
|
42411
|
+
const node = new Node(value);
|
|
42412
|
+
if (this.#head) {
|
|
42413
|
+
this.#tail.next = node;
|
|
42414
|
+
this.#tail = node;
|
|
42415
|
+
} else {
|
|
42416
|
+
this.#head = node;
|
|
42417
|
+
this.#tail = node;
|
|
42418
|
+
}
|
|
42419
|
+
this.#size++;
|
|
42420
|
+
}
|
|
42421
|
+
dequeue() {
|
|
42422
|
+
const current = this.#head;
|
|
42423
|
+
if (!current) {
|
|
42424
|
+
return;
|
|
42425
|
+
}
|
|
42426
|
+
this.#head = this.#head.next;
|
|
42427
|
+
this.#size--;
|
|
42428
|
+
return current.value;
|
|
42429
|
+
}
|
|
42430
|
+
peek() {
|
|
42431
|
+
if (!this.#head) {
|
|
42432
|
+
return;
|
|
42433
|
+
}
|
|
42434
|
+
return this.#head.value;
|
|
42435
|
+
}
|
|
42436
|
+
clear() {
|
|
42437
|
+
this.#head = undefined;
|
|
42438
|
+
this.#tail = undefined;
|
|
42439
|
+
this.#size = 0;
|
|
42440
|
+
}
|
|
42441
|
+
get size() {
|
|
42442
|
+
return this.#size;
|
|
42443
|
+
}
|
|
42444
|
+
*[Symbol.iterator]() {
|
|
42445
|
+
let current = this.#head;
|
|
42446
|
+
while (current) {
|
|
42447
|
+
yield current.value;
|
|
42448
|
+
current = current.next;
|
|
42449
|
+
}
|
|
42450
|
+
}
|
|
42451
|
+
*drain() {
|
|
42452
|
+
while (this.#head) {
|
|
42453
|
+
yield this.dequeue();
|
|
42454
|
+
}
|
|
42455
|
+
}
|
|
42456
|
+
}
|
|
42457
|
+
|
|
42458
|
+
// node_modules/p-limit/index.js
|
|
42459
|
+
function pLimit(concurrency) {
|
|
42460
|
+
validateConcurrency(concurrency);
|
|
42461
|
+
const queue = new Queue;
|
|
42462
|
+
let activeCount = 0;
|
|
42463
|
+
const resumeNext = () => {
|
|
42464
|
+
if (activeCount < concurrency && queue.size > 0) {
|
|
42465
|
+
activeCount++;
|
|
42466
|
+
queue.dequeue()();
|
|
42467
|
+
}
|
|
42468
|
+
};
|
|
42469
|
+
const next = () => {
|
|
42470
|
+
activeCount--;
|
|
42471
|
+
resumeNext();
|
|
42472
|
+
};
|
|
42473
|
+
const run = async (function_, resolve2, arguments_) => {
|
|
42474
|
+
const result = (async () => function_(...arguments_))();
|
|
42475
|
+
resolve2(result);
|
|
42476
|
+
try {
|
|
42477
|
+
await result;
|
|
42478
|
+
} catch {}
|
|
42479
|
+
next();
|
|
42480
|
+
};
|
|
42481
|
+
const enqueue = (function_, resolve2, arguments_) => {
|
|
42482
|
+
new Promise((internalResolve) => {
|
|
42483
|
+
queue.enqueue(internalResolve);
|
|
42484
|
+
}).then(run.bind(undefined, function_, resolve2, arguments_));
|
|
42485
|
+
if (activeCount < concurrency) {
|
|
42486
|
+
resumeNext();
|
|
42487
|
+
}
|
|
42488
|
+
};
|
|
42489
|
+
const generator = (function_, ...arguments_) => new Promise((resolve2) => {
|
|
42490
|
+
enqueue(function_, resolve2, arguments_);
|
|
42491
|
+
});
|
|
42492
|
+
Object.defineProperties(generator, {
|
|
42493
|
+
activeCount: {
|
|
42494
|
+
get: () => activeCount
|
|
42495
|
+
},
|
|
42496
|
+
pendingCount: {
|
|
42497
|
+
get: () => queue.size
|
|
42498
|
+
},
|
|
42499
|
+
clearQueue: {
|
|
42500
|
+
value() {
|
|
42501
|
+
queue.clear();
|
|
42502
|
+
}
|
|
42503
|
+
},
|
|
42504
|
+
concurrency: {
|
|
42505
|
+
get: () => concurrency,
|
|
42506
|
+
set(newConcurrency) {
|
|
42507
|
+
validateConcurrency(newConcurrency);
|
|
42508
|
+
concurrency = newConcurrency;
|
|
42509
|
+
queueMicrotask(() => {
|
|
42510
|
+
while (activeCount < concurrency && queue.size > 0) {
|
|
42511
|
+
resumeNext();
|
|
42512
|
+
}
|
|
42513
|
+
});
|
|
42514
|
+
}
|
|
42515
|
+
},
|
|
42516
|
+
map: {
|
|
42517
|
+
async value(iterable, function_) {
|
|
42518
|
+
const promises = Array.from(iterable, (value, index) => this(function_, value, index));
|
|
42519
|
+
return Promise.all(promises);
|
|
42520
|
+
}
|
|
42521
|
+
}
|
|
42522
|
+
});
|
|
42523
|
+
return generator;
|
|
42524
|
+
}
|
|
42525
|
+
function validateConcurrency(concurrency) {
|
|
42526
|
+
if (!((Number.isInteger(concurrency) || concurrency === Number.POSITIVE_INFINITY) && concurrency > 0)) {
|
|
42527
|
+
throw new TypeError("Expected `concurrency` to be a number from 1 and up");
|
|
42528
|
+
}
|
|
42529
|
+
}
|
|
42530
|
+
|
|
42531
|
+
// scripts/swarm.ts
|
|
42438
42532
|
var TargetSchema = exports_external.array(exports_external.object({
|
|
42439
42533
|
target: exports_external.string().describe("The target to perform a pentest on"),
|
|
42440
42534
|
objective: exports_external.string().describe("The objective of the pentest")
|
|
@@ -42478,7 +42572,8 @@ async function swarm(options) {
|
|
|
42478
42572
|
}
|
|
42479
42573
|
const session = createSession("swarm", "Multi-target swarm pentest");
|
|
42480
42574
|
const results = [];
|
|
42481
|
-
const
|
|
42575
|
+
const limit = pLimit(5);
|
|
42576
|
+
const promises = targetsArray.map((target, idx) => limit(async () => {
|
|
42482
42577
|
if (!silent) {
|
|
42483
42578
|
console.log("=".repeat(80));
|
|
42484
42579
|
console.log(`[${idx + 1}/${targetsArray.length}] Starting pentest for: ${target.target}`);
|
|
@@ -42518,8 +42613,8 @@ async function swarm(options) {
|
|
|
42518
42613
|
error: error46.message
|
|
42519
42614
|
});
|
|
42520
42615
|
}
|
|
42521
|
-
});
|
|
42522
|
-
await Promise.
|
|
42616
|
+
}));
|
|
42617
|
+
await Promise.allSettled(promises);
|
|
42523
42618
|
if (!silent) {
|
|
42524
42619
|
console.log("=".repeat(80));
|
|
42525
42620
|
console.log("SWARM PENTEST SUMMARY");
|
|
@@ -42616,7 +42711,9 @@ async function main() {
|
|
|
42616
42711
|
objective: session.objective
|
|
42617
42712
|
}, null, 2));
|
|
42618
42713
|
} catch (error46) {
|
|
42619
|
-
|
|
42714
|
+
if (!silent) {
|
|
42715
|
+
console.error("Fatal error:", error46.message);
|
|
42716
|
+
}
|
|
42620
42717
|
process.exit(1);
|
|
42621
42718
|
}
|
|
42622
42719
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pensar/apex",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.15",
|
|
4
4
|
"description": "AI-powered penetration testing CLI tool with terminal UI",
|
|
5
5
|
"module": "src/tui/index.tsx",
|
|
6
6
|
"main": "build/index.js",
|
|
@@ -59,6 +59,7 @@
|
|
|
59
59
|
"@opentui/react": "0.1.26",
|
|
60
60
|
"ai": "^5.0.68",
|
|
61
61
|
"marked": "^16.4.0",
|
|
62
|
+
"p-limit": "^7.2.0",
|
|
62
63
|
"react": "^19.2.0",
|
|
63
64
|
"sharp": "^0.34.4",
|
|
64
65
|
"zod": "^4.1.12"
|