Sfoglia il codice sorgente

added filter to the landing page

AETH-erial 10 mesi fa
parent
commit
1f35c59c59

+ 1 - 1
cmd/kyoketsu/kyoketsu.go

@@ -88,6 +88,6 @@ func main() {
 			}
 		}
 	}()
-	kyoketsu.NetSweep(addr.Ipv4s, kyoketsu.RetrieveScanDirectives(), scanned)
+	kyoketsu.NetSweep(addr.Ipv4s, addr.Mask, kyoketsu.RetrieveScanDirectives(), scanned)
 
 }

+ 25 - 13
pkg/html/templates/home.html

@@ -6,23 +6,34 @@
     </head>
 
     <body style="background-color: black;">
-        <div class="container-fluid sticky-top pb-0" style="background-color: black; opacity: 0.5;">
-            <div class="row align-items-center justify-content-center h-100 shadow-lg p-0 mb-0 rounded">
-                <div class="col-sm-8 p-3">
+        <div class="container-fluid row sticky-top pb-0" style="background-color: black; opacity: 0.75;">
+            <div class="container-fluid row h-100 shadow-lg p-0 mb-0 rounded">
+                <div class="col-2 p-1">
                     <div style="color: rgba(35, 207, 0, 0.87); font-size: xx-large; font-family: monospace; opacity: 1;">
                         <a href="/home" style="color: rgba(35, 207, 0, 0.87)">// Kyoketsu</a>
                     </div>
                 </div>
-                <div class="col-sm-8 p-3">
-                    <form method="post"
-                          hx-target="#response-div"
-                          hx-post="/refresh"
-                          hx-ext="json-enc">
-                          <input type="text" name="ip_address" placeholder="192.168.50.1/24" required>
-                          <button type="submit">send</button>
-                    </form>
-
-
+                <div class="row container-fluid p-1">
+                    <div class="col-2">
+                        <a style="color: white; font-family: monospace;">Target network to enumerate:</a>
+                        <form method="post"
+                              hx-target="#response-div"
+                              hx-post="/refresh"
+                              hx-ext="json-enc">
+                              <input type="text" name="ip_address" placeholder="192.168.50.1/24" required>
+                              <button type="submit">scan</button>
+                        </form>
+                    </div>
+                    <div class="col-2">
+                        <a style="color: white; font-family: monospace;">Filter on network address:</a>
+                        <form method="post"
+                              hx-target="#response-div"
+                              hx-post="/subnets"
+                              hx-ext="json-enc">
+                              <input type="text" name="ip_address" placeholder="192.168.50.0" required>
+                              <button type="submit">filter</button>
+                        </form>
+                    </div>
                 </div>
             </div>
         </div>
@@ -32,6 +43,7 @@
                 <tr>
                     <th scope="col"><p style="font-family: monospace;">FQDN</p></th>
                     <th scope="col"><p style="font-family: monospace;">IPv4 Address</p></th>
+                    <th scope="col"><p style="font-family: monospace;">IPv4 Network</p></th>
                     <th scope="col"><p style="font-family: monospace;">Ping Response?</p></th>
                     <th scope="col"><p style="font-family: monospace;">Listening Ports</p></th>
                 </tr>

+ 1 - 0
pkg/html/templates/ip_table.html

@@ -2,6 +2,7 @@
 <tr>
 <th scope="row"><p style="font-family: monospace;">{{ .Fqdn }}</p></th>
         <td><p style="font-family: monospace;">{{ .IpAddress }}</p></td>
+        <td><p style="font-family: monospace;">{{ .Network }}</p></td>
         <td><p style="font-family: monospace;">{{ .PingResponse }}</p></td>
         <td><p style="font-family: monospace;">{{ .PortString }}</p></td>
 </tr>

+ 7 - 5
pkg/scanner.go

@@ -44,6 +44,7 @@ type Host struct {
 	IpAddress      string // the IPv4 address (no ipv6 support yet)
 	PingResponse   bool   // boolean value representing if the host responded to ICMP
 	ListeningPorts []int  // list of maps depicting a port number -> service name
+	Network        string
 	PortString     string
 	Id             int64
 }
@@ -109,14 +110,14 @@ Perform a port scan sweep across an entire subnet
 	:param ip: the IPv4 address WITH CIDR notation
 	:param portmap: the mapping of ports to scan with (port number mapped to protocol name)
 */
-func NetSweep(ips []net.IP, ports []int, scanned chan Host) {
-
+func NetSweep(ips []net.IP, cidr int, ports []int, scanned chan Host) {
 	wg := &sync.WaitGroup{}
-	killswitch, cancel := context.WithDeadline(context.Background(), time.Now().Add(18*time.Second))
+	killswitch, cancel := context.WithDeadline(context.Background(), time.Now().Add(5*time.Second))
 	defer cancel()
+	network := getNetwork(ips[0].String(), cidr)
 	for i := range ips {
 		wg.Add(1)
-		go func(target string, portnum []int, wgrp *sync.WaitGroup, output chan Host) {
+		go func(target string, ntwrk string, portnum []int, wgrp *sync.WaitGroup, output chan Host) {
 			select {
 			case <-killswitch.Done():
 				fmt.Println("UNTO DEATH :::: WHILE THE SUN BEAMS DOWN")
@@ -129,9 +130,10 @@ func NetSweep(ips []net.IP, ports []int, scanned chan Host) {
 					IpAddress:      target,
 					ListeningPorts: portscanned,
 					PortString:     strings.Trim(strings.Join(strings.Fields(fmt.Sprint(portscanned)), ","), "[]"),
+					Network:        ntwrk,
 				}
 			}
-		}(ips[i].String(), ports, wg, scanned)
+		}(ips[i].String(), network, ports, wg, scanned)
 
 	}
 	wg.Wait()

+ 25 - 5
pkg/storage.go

@@ -43,6 +43,7 @@ type TopologyDatabaseIO interface {
 	Migrate() error
 	Create(host Host) (*Host, error)
 	All() ([]Host, error)
+	GetByNetwork(network string) ([]Host, error)
 	GetByIP(ip string) (*Host, error)
 	Update(id int64, updated Host) (*Host, error)
 	Delete(id int64) error
@@ -74,7 +75,8 @@ func (r *SQLiteRepo) Migrate() error {
         id INTEGER PRIMARY KEY AUTOINCREMENT,
         fqdn TEXT NOT NULL,
         ipv4_address TEXT NOT NULL UNIQUE,
-        listening_port TEXT NOT NULL
+        listening_port TEXT NOT NULL,
+		network TEXT NOT NULL
     );
     `
 
@@ -88,7 +90,7 @@ Create an entry in the hosts table
 	:param host: a Host entry from a port scan
 */
 func (r *SQLiteRepo) Create(host Host) (*Host, error) {
-	res, err := r.db.Exec("INSERT INTO hosts(fqdn, ipv4_address, listening_port) values(?,?,?)", host.Fqdn, host.IpAddress, host.PortString)
+	res, err := r.db.Exec("INSERT INTO hosts(fqdn, ipv4_address, listening_port, network) values(?,?,?,?)", host.Fqdn, host.IpAddress, host.PortString, host.Network)
 	if err != nil {
 		var sqliteErr sqlite3.Error
 		if errors.As(err, &sqliteErr) {
@@ -119,7 +121,7 @@ func (r *SQLiteRepo) All() ([]Host, error) {
 	var all []Host
 	for rows.Next() {
 		var host Host
-		if err := rows.Scan(&host.Id, &host.Fqdn, &host.IpAddress, &host.PortString); err != nil {
+		if err := rows.Scan(&host.Id, &host.Fqdn, &host.IpAddress, &host.PortString, &host.Network); err != nil {
 			return nil, err
 		}
 		all = append(all, host)
@@ -132,7 +134,7 @@ func (r *SQLiteRepo) GetByIP(ip string) (*Host, error) {
 	row := r.db.QueryRow("SELECT * FROM hosts WHERE ipv4_address = ?", ip)
 
 	var host Host
-	if err := row.Scan(&host.Id, &host.Fqdn, &host.IpAddress, &host.PortString); err != nil {
+	if err := row.Scan(&host.Id, &host.Fqdn, &host.IpAddress, &host.PortString, &host.Network); err != nil {
 		if errors.Is(err, sql.ErrNoRows) {
 			return nil, ErrNotExists
 		}
@@ -146,7 +148,7 @@ func (r *SQLiteRepo) Update(id int64, updated Host) (*Host, error) {
 	if id == 0 {
 		return nil, errors.New("invalid updated ID")
 	}
-	res, err := r.db.Exec("UPDATE hosts SET fqdn = ?, ipv4_address = ?, listening_port = ? WHERE id = ?", updated.Fqdn, updated.IpAddress, updated.PortString, id)
+	res, err := r.db.Exec("UPDATE hosts SET fqdn = ?, ipv4_address = ?, listening_port = ?, network = ? WHERE id = ?", updated.Fqdn, updated.IpAddress, updated.PortString, updated.Network, id)
 	if err != nil {
 		return nil, err
 	}
@@ -181,3 +183,21 @@ func (r *SQLiteRepo) Delete(id int64) error {
 
 	return err
 }
+
+func (r *SQLiteRepo) GetByNetwork(network string) ([]Host, error) {
+	rows, err := r.db.Query("SELECT * FROM hosts WHERE network = ?", network)
+	if err != nil {
+		return nil, err
+	}
+	var hosts []Host
+	defer rows.Close()
+
+	for rows.Next() {
+		var host Host
+		if err := rows.Scan(&host.Id, &host.Fqdn, &host.IpAddress, &host.PortString, &host.Network); err != nil {
+			return nil, err
+		}
+		hosts = append(hosts, host)
+	}
+	return hosts, nil
+}

+ 41 - 10
pkg/webserver.go

@@ -36,10 +36,11 @@ func RunHttpServer(port int, dbhook TopologyDatabaseIO, portmap []int) {
 	if err != nil {
 		log.Fatal(err)
 	}
-	htmlHndl := &HtmlHandler{Home: tmpl, DbHook: dbhook}
+	htmlHndl := &HtmlHandler{Home: tmpl, TableEntry: iptable, DbHook: dbhook}
 	execHndl := &ExecutionHandler{DbHook: dbhook, PortMap: portmap, TableEntry: iptable}
 	http.Handle("/static/", assets)
 	http.Handle("/home", htmlHndl)
+	http.Handle("/subnets", htmlHndl)
 	http.Handle("/refresh", execHndl)
 
 	log.Fatal(http.ListenAndServe(fmt.Sprintf(":%v", port), nil))
@@ -76,8 +77,6 @@ func (e *ExecutionHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 			if len(x.ListeningPorts) > 0 {
 				templ.Execute(wr, x)
 
-				fmt.Print(" |-|-|-| :::: HOST FOUND :::: |-|-|-|\n==================||==================\n")
-				fmt.Printf("IPv4 Address: %s\nListening Ports: %v\n=====================================\n", x.IpAddress, x.ListeningPorts)
 				host, err := e.DbHook.GetByIP(x.IpAddress)
 				if err != nil {
 					if err != ErrNotExists {
@@ -97,14 +96,15 @@ func (e *ExecutionHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 			}
 		}
 	}(w, e.TableEntry)
-	NetSweep(subnetMap.Ipv4s, RetrieveScanDirectives(), scanned)
+	NetSweep(subnetMap.Ipv4s, subnetMap.Mask, RetrieveScanDirectives(), scanned)
 }
 
 // handlers //
 
 type HtmlHandler struct {
-	Home   *template.Template // pointer to the HTML homepage
-	DbHook TopologyDatabaseIO
+	Home       *template.Template // pointer to the HTML homepage
+	TableEntry *template.Template // pointer to the table entry html template
+	DbHook     TopologyDatabaseIO
 }
 
 /*
@@ -114,11 +114,42 @@ Handler function for HTML serving
 	:param r: pointer to the http.Request coming in
 */
 func (h *HtmlHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-	data, err := h.DbHook.All()
-	if err != nil {
-		fmt.Fprintf(w, "You have made it to the kyoketsu web server!\nThere was an error getting the db table, though.\n%s", err)
+	if r.RequestURI == "/home" {
+		data, err := h.DbHook.All()
+		if err != nil {
+			fmt.Fprintf(w, "You have made it to the kyoketsu web server!\nThere was an error getting the db table, though.\n%s", err)
+		}
+		h.Home.Execute(w, data)
+		return
+	}
+	splitpath := strings.Split(r.RequestURI, "/")
+	if len(splitpath) <= 1 {
+		w.Header().Add("Location", "/home")
+		return
+	}
+	if r.RequestURI == "/subnets" {
+		fmt.Println("request recv")
+		var req ScanRequest
+		b, err := io.ReadAll(r.Body)
+		defer r.Body.Close()
+		if err != nil {
+			fmt.Fprintf(w, "There was an error reading the input: %s", err)
+			return
+		}
+		err = json.Unmarshal(b, &req)
+		if err != nil {
+			fmt.Fprintf(w, "There was an error reading the input: %s", err)
+			return
+		}
+		data, err := h.DbHook.GetByNetwork(req.IpAddress)
+		if err != nil {
+			fmt.Fprintf(w, "There was an error reading from the database: %s", err)
+			return
+		}
+		for _, host := range data {
+			h.TableEntry.Execute(w, host)
+		}
 	}
-	h.Home.Execute(w, data)
 }
 
 type AssetHandler struct {