diff --git a/src/api.go b/src/api.go index 4b3d557..2e81a22 100644 --- a/src/api.go +++ b/src/api.go @@ -8,6 +8,7 @@ import ( "imuslab.com/zoraxy/mod/acme/acmedns" "imuslab.com/zoraxy/mod/acme/acmewizard" "imuslab.com/zoraxy/mod/auth" + "imuslab.com/zoraxy/mod/ipscan" "imuslab.com/zoraxy/mod/netstat" "imuslab.com/zoraxy/mod/netutils" "imuslab.com/zoraxy/mod/utils" @@ -187,7 +188,8 @@ func initAPIs(targetMux *http.ServeMux) { authRouter.HandleFunc("/api/analytic/resetRange", AnalyticLoader.HandleRangeReset) //Network utilities - authRouter.HandleFunc("/api/tools/ipscan", HandleIpScan) + authRouter.HandleFunc("/api/tools/ipscan", ipscan.HandleIpScan) + authRouter.HandleFunc("/api/tools/portscan", ipscan.HandleScanPort) authRouter.HandleFunc("/api/tools/traceroute", netutils.HandleTraceRoute) authRouter.HandleFunc("/api/tools/ping", netutils.HandlePing) authRouter.HandleFunc("/api/tools/whois", netutils.HandleWhois) diff --git a/src/mod/ipscan/handlers.go b/src/mod/ipscan/handlers.go new file mode 100644 index 0000000..7e63983 --- /dev/null +++ b/src/mod/ipscan/handlers.go @@ -0,0 +1,79 @@ +package ipscan + +/* + ipscan http handlers + + This script provide http handlers for ipscan module +*/ + +import ( + "encoding/json" + "net" + "net/http" + + "imuslab.com/zoraxy/mod/utils" +) + +// HandleScanPort is the HTTP handler for scanning opened ports on a given IP address +func HandleScanPort(w http.ResponseWriter, r *http.Request) { + targetIp, err := utils.GetPara(r, "ip") + if err != nil { + utils.SendErrorResponse(w, "target IP address not given") + return + } + + // Check if the IP is a valid IP address + ip := net.ParseIP(targetIp) + if ip == nil { + utils.SendErrorResponse(w, "invalid IP address") + return + } + + // Scan the ports + openPorts := ScanPorts(targetIp) + jsonData, err := json.Marshal(openPorts) + if err != nil { + utils.SendErrorResponse(w, "failed to marshal JSON") + return + } + + utils.SendJSONResponse(w, string(jsonData)) +} + +// HandleIpScan is the HTTP handler for scanning IP addresses in a given range or CIDR +func HandleIpScan(w http.ResponseWriter, r *http.Request) { + cidr, err := utils.PostPara(r, "cidr") + if err != nil { + //Ip range mode + start, err := utils.PostPara(r, "start") + if err != nil { + utils.SendErrorResponse(w, "missing start ip") + return + } + + end, err := utils.PostPara(r, "end") + if err != nil { + utils.SendErrorResponse(w, "missing end ip") + return + } + + discoveredHosts, err := ScanIpRange(start, end) + if err != nil { + utils.SendErrorResponse(w, err.Error()) + return + } + + js, _ := json.Marshal(discoveredHosts) + utils.SendJSONResponse(w, string(js)) + } else { + //CIDR mode + discoveredHosts, err := ScanCIDRRange(cidr) + if err != nil { + utils.SendErrorResponse(w, err.Error()) + return + } + + js, _ := json.Marshal(discoveredHosts) + utils.SendJSONResponse(w, string(js)) + } +} diff --git a/src/mod/ipscan/ipscan.go b/src/mod/ipscan/ipscan.go index 8605685..6a4c908 100644 --- a/src/mod/ipscan/ipscan.go +++ b/src/mod/ipscan/ipscan.go @@ -27,7 +27,7 @@ type DiscoveredHost struct { HttpsPortDetected bool } -//Scan an IP range given the start and ending ip address +// Scan an IP range given the start and ending ip address func ScanIpRange(start, end string) ([]*DiscoveredHost, error) { ipStart := net.ParseIP(start) ipEnd := net.ParseIP(end) @@ -57,7 +57,6 @@ func ScanIpRange(start, end string) ([]*DiscoveredHost, error) { host.CheckHostname() host.CheckPort("http", 80, &host.HttpPortDetected) host.CheckPort("https", 443, &host.HttpsPortDetected) - fmt.Println("OK", host) hosts = append(hosts, host) }(thisIp) @@ -118,7 +117,7 @@ func (host *DiscoveredHost) CheckPing() error { func (host *DiscoveredHost) CheckHostname() { // lookup the hostname for the IP address names, err := net.LookupAddr(host.IP) - fmt.Println(names, err) + //fmt.Println(names, err) if err == nil && len(names) > 0 { host.Hostname = names[0] } diff --git a/src/mod/ipscan/portscan.go b/src/mod/ipscan/portscan.go new file mode 100644 index 0000000..deaccc1 --- /dev/null +++ b/src/mod/ipscan/portscan.go @@ -0,0 +1,48 @@ +package ipscan + +/* + Port Scanner + + This module scan the given IP address and scan all the opened port + +*/ + +import ( + "fmt" + "net" + "sync" + "time" +) + +// OpenedPort holds information about an open port and its service type +type OpenedPort struct { + Port int + IsTCP bool +} + +// ScanPorts scans all the opened ports on a given host IP (both IPv4 and IPv6) +func ScanPorts(host string) []*OpenedPort { + var openPorts []*OpenedPort + var wg sync.WaitGroup + var mu sync.Mutex + + for port := 1; port <= 65535; port++ { + wg.Add(1) + go func(port int) { + defer wg.Done() + address := fmt.Sprintf("%s:%d", host, port) + + // Check TCP + conn, err := net.DialTimeout("tcp", address, 5*time.Second) + if err == nil { + mu.Lock() + openPorts = append(openPorts, &OpenedPort{Port: port, IsTCP: true}) + mu.Unlock() + conn.Close() + } + }(port) + } + + wg.Wait() + return openPorts +} diff --git a/src/web/components/networktools.html b/src/web/components/networktools.html index dca3347..50c17d5 100644 --- a/src/web/components/networktools.html +++ b/src/web/components/networktools.html @@ -17,10 +17,21 @@
Discover mDNS enabled service in this gateway forwarded network
- -Discover local area network devices by pinging them one by one
- +Discover local area network devices by pinging them one by one
+ +Scan for open ports on a given IP address
+ +