|
@@ -27,18 +27,12 @@ package kyoketsu
|
|
import (
|
|
import (
|
|
"fmt"
|
|
"fmt"
|
|
"net"
|
|
"net"
|
|
|
|
+ "strconv"
|
|
"strings"
|
|
"strings"
|
|
"sync"
|
|
"sync"
|
|
"time"
|
|
"time"
|
|
)
|
|
)
|
|
|
|
|
|
-var PORT_MAP = map[int]string{
|
|
|
|
- 22: "ssh", 23: "telnet", 53: "dns", 80: "http", 25: "smtp", 443: "https", 8080: "unknown", 8081: "unknown",
|
|
|
|
- //8082: "unknown", 8085: "unknown", 8090: "unknown", 8091: "unknown", 9010: "unknown", 9012: "unknown", 10000: "unknown", 1433: "microsoft_sql",
|
|
|
|
- 3306: "mysql", 3050: "firebird", 5432: "postgres", 27017: "mongo", 6379: "redis", 8005: "tomcat", 6443: "kubernetes", 853: "dns-tls", 143: "imap",
|
|
|
|
- 389: "ldap", 445: "smb", 543: "kerberos", 544: "kerberos", 749: "kerberos", 760: "kerberos",
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
/*
|
|
/*
|
|
Need to work with with a database schema in mind, and revolve functionality around that
|
|
Need to work with with a database schema in mind, and revolve functionality around that
|
|
*/
|
|
*/
|
|
@@ -58,31 +52,37 @@ Perform a concurrent TCP port dial on a host, either by domain name or IP.
|
|
:param addr: the address of fqdn to scan
|
|
:param addr: the address of fqdn to scan
|
|
:param portmap: a key/value pair of port numbers to service names to dial the host with
|
|
:param portmap: a key/value pair of port numbers to service names to dial the host with
|
|
*/
|
|
*/
|
|
-func PortWalk(addr string, portmap map[int]string) *Host {
|
|
|
|
|
|
+func PortWalk(addr string, portmap map[int]string) Host {
|
|
wg := &sync.WaitGroup{}
|
|
wg := &sync.WaitGroup{}
|
|
mu := &sync.Mutex{}
|
|
mu := &sync.Mutex{}
|
|
- out := []*PortScanResult{}
|
|
|
|
|
|
+ out := map[int]string{}
|
|
for p, s := range portmap {
|
|
for p, s := range portmap {
|
|
wg.Add(1)
|
|
wg.Add(1)
|
|
go func(target string, p int, s string, mu *sync.Mutex) {
|
|
go func(target string, p int, s string, mu *sync.Mutex) {
|
|
defer wg.Done()
|
|
defer wg.Done()
|
|
scanout := singlePortScan(target, p, s)
|
|
scanout := singlePortScan(target, p, s)
|
|
- mu.Lock()
|
|
|
|
- out = append(out, scanout)
|
|
|
|
- mu.Unlock()
|
|
|
|
|
|
+ if scanout.Listening {
|
|
|
|
+ mu.Lock()
|
|
|
|
+ out[scanout.PortNumber] = scanout.Service
|
|
|
|
+ mu.Unlock()
|
|
|
|
+ }
|
|
}(addr, p, s, mu)
|
|
}(addr, p, s, mu)
|
|
}
|
|
}
|
|
wg.Wait()
|
|
wg.Wait()
|
|
- host := &Host{IpAddress: addr, ListeningPorts: map[int]string{}}
|
|
|
|
- for i := range out {
|
|
|
|
- if out[i].Listening {
|
|
|
|
- host.ListeningPorts[out[i].PortNumber] = out[i].Service
|
|
|
|
- host.PortString = fmt.Sprintf("%s,%v", host.PortString, out[i].PortNumber)
|
|
|
|
- }
|
|
|
|
- host.PortString = strings.TrimPrefix(host.PortString, ",")
|
|
|
|
-
|
|
|
|
|
|
+ var dnames string
|
|
|
|
+ var portstring string
|
|
|
|
+ dns, _ := net.LookupAddr(addr)
|
|
|
|
+ dnames = strings.Join(dns, ", ")
|
|
|
|
+ for key, _ := range out {
|
|
|
|
+ portstring = portstring + "," + strconv.Itoa(key)
|
|
|
|
+ }
|
|
|
|
+ return Host{
|
|
|
|
+ IpAddress: addr,
|
|
|
|
+ Fqdn: dnames,
|
|
|
|
+ PingResponse: false,
|
|
|
|
+ ListeningPorts: out,
|
|
|
|
+ PortString: portstring,
|
|
}
|
|
}
|
|
- return host
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
@@ -94,17 +94,18 @@ type PortScanResult struct {
|
|
Listening bool `json:"listening"` // A boolean value that depicts if the service is listening or not
|
|
Listening bool `json:"listening"` // A boolean value that depicts if the service is listening or not
|
|
}
|
|
}
|
|
|
|
|
|
-type PortScanDirective struct {
|
|
|
|
- // Struct for dependency injecting the dynamic port map used for scans
|
|
|
|
- Pairs map[int]string
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
/*
|
|
/*
|
|
Wrapper function to dependency inject the resource for a port -> service name mapping.
|
|
Wrapper function to dependency inject the resource for a port -> service name mapping.
|
|
May move to a database, or something.
|
|
May move to a database, or something.
|
|
*/
|
|
*/
|
|
-func RetrieveScanDirectives() PortScanDirective {
|
|
|
|
- return PortScanDirective{Pairs: PORT_MAP}
|
|
|
|
|
|
+func RetrieveScanDirectives() map[int]string {
|
|
|
|
+ var portmap = map[int]string{
|
|
|
|
+ 22: "ssh", 23: "telnet", 53: "dns", 80: "http", 25: "smtp", 443: "https", 8080: "unknown", 8081: "unknown",
|
|
|
|
+ 8082: "unknown", 8085: "unknown", 8090: "unknown", 8091: "unknown", 9010: "unknown", 9012: "unknown", 10000: "unknown", 1433: "microsoft_sql",
|
|
|
|
+ 3306: "mysql", 3050: "firebird", 5432: "postgres", 27017: "mongo", 6379: "redis", 8005: "tomcat", 6443: "kubernetes", 853: "dns-tls", 143: "imap",
|
|
|
|
+ 389: "ldap", 445: "smb", 543: "kerberos", 544: "kerberos", 749: "kerberos", 760: "kerberos",
|
|
|
|
+ }
|
|
|
|
+ return portmap
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -114,14 +115,13 @@ Scans a single host on a single port
|
|
:param port: the port number to dial
|
|
:param port: the port number to dial
|
|
:param svcs: the name of the service that the port is associate with
|
|
:param svcs: the name of the service that the port is associate with
|
|
*/
|
|
*/
|
|
-func singlePortScan(addr string, port int, svcs string) *PortScanResult {
|
|
|
|
|
|
+func singlePortScan(addr string, port int, svcs string) PortScanResult {
|
|
address := fmt.Sprintf("%v:%d", addr, port)
|
|
address := fmt.Sprintf("%v:%d", addr, port)
|
|
- conn, err := net.DialTimeout("tcp", address, 5*time.Second)
|
|
|
|
|
|
+ _, err := net.DialTimeout("tcp", address, 2*time.Second)
|
|
if err != nil {
|
|
if err != nil {
|
|
- return &PortScanResult{PortNumber: port, Protocol: "tcp", Service: svcs, Listening: false}
|
|
|
|
|
|
+ return PortScanResult{PortNumber: port, Protocol: "tcp", Service: svcs, Listening: false}
|
|
}
|
|
}
|
|
- conn.Close()
|
|
|
|
- return &PortScanResult{PortNumber: port, Protocol: "tcp", Service: svcs, Listening: true}
|
|
|
|
|
|
+ return PortScanResult{PortNumber: port, Protocol: "tcp", Service: svcs, Listening: true}
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -130,32 +130,16 @@ Perform a port scan sweep across an entire subnet
|
|
:param ip: the IPv4 address WITH CIDR notation
|
|
:param ip: the IPv4 address WITH CIDR notation
|
|
:param portmap: the mapping of ports to scan with (port number mapped to protocol name)
|
|
:param portmap: the mapping of ports to scan with (port number mapped to protocol name)
|
|
*/
|
|
*/
|
|
-func NetSweep(ip string, portmap map[int]string) ([]*Host, error) {
|
|
|
|
- var err error
|
|
|
|
- var addr *IpSubnetMapper
|
|
|
|
- addr, err = GetNetworkAddresses(ip)
|
|
|
|
- if err != nil {
|
|
|
|
- return nil, err
|
|
|
|
- }
|
|
|
|
- returnhosts := []*Host{}
|
|
|
|
-
|
|
|
|
- var wg sync.WaitGroup
|
|
|
|
- mu := &sync.Mutex{}
|
|
|
|
- for i := range addr.Ipv4s {
|
|
|
|
|
|
+func NetSweep(ips []net.IP, portmap map[int]string, scanned chan Host) {
|
|
|
|
+ wg := &sync.WaitGroup{}
|
|
|
|
+ for i := range ips {
|
|
wg.Add(1)
|
|
wg.Add(1)
|
|
- go func(target string, mu *sync.Mutex) {
|
|
|
|
|
|
+ go func(target string, wg *sync.WaitGroup) {
|
|
defer wg.Done()
|
|
defer wg.Done()
|
|
- out := PortWalk(target, portmap)
|
|
|
|
- if len(out.ListeningPorts) > 0 {
|
|
|
|
- dns, _ := net.LookupAddr(out.IpAddress)
|
|
|
|
- out.Fqdn = strings.Join(dns, ", ")
|
|
|
|
- mu.Lock()
|
|
|
|
- returnhosts = append(returnhosts, out)
|
|
|
|
- mu.Unlock()
|
|
|
|
- }
|
|
|
|
- }(addr.Ipv4s[i].String(), mu)
|
|
|
|
|
|
+ scanned <- PortWalk(target, portmap)
|
|
|
|
|
|
|
|
+ }(ips[i].String(), wg)
|
|
}
|
|
}
|
|
wg.Wait()
|
|
wg.Wait()
|
|
- return returnhosts, nil
|
|
|
|
|
|
+
|
|
}
|
|
}
|