Add browser deploy recon backend with port scan, web crawl, and deploy lane recommendations.
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
POST /api/v1/recon/scan probes fleet ports from the server host, crawls owned HTTP targets, maps findings to spread lanes, and records optional oath ledger rows.
This commit is contained in:
92
server/internal/api/recon_handler.go
Normal file
92
server/internal/api/recon_handler.go
Normal file
@@ -0,0 +1,92 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
dbpkg "crypto-miner-server/internal/db"
|
||||
"crypto-miner-server/internal/recon"
|
||||
)
|
||||
|
||||
// ReconHandler serves owned-target browser deploy recon.
|
||||
type ReconHandler struct {
|
||||
db *dbpkg.Database
|
||||
wsHub *WSHub
|
||||
}
|
||||
|
||||
func NewReconHandler(database *dbpkg.Database, hub *WSHub) *ReconHandler {
|
||||
return &ReconHandler{db: database, wsHub: hub}
|
||||
}
|
||||
|
||||
// POST /api/v1/recon/scan
|
||||
func (h *ReconHandler) Scan(w http.ResponseWriter, r *http.Request) {
|
||||
var req recon.ScanRequest
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
http.Error(w, "invalid JSON", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
req.Host = strings.TrimSpace(req.Host)
|
||||
if req.Host == "" {
|
||||
http.Error(w, "host required", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
report, err := recon.Scan(req)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
if h != nil && h.db != nil {
|
||||
payload := map[string]interface{}{
|
||||
"host": report.Host,
|
||||
"open_ports": openPortList(report.Ports),
|
||||
"ssrf_score": crawlSSRFScore(report.Crawl),
|
||||
"recommendations": len(report.Recommendations),
|
||||
"cms_fingerprints": crawlCMS(report.Crawl),
|
||||
}
|
||||
_ = (&OathLedgerBridge{DB: h.db, Hub: oathHub(h)}).Record(
|
||||
AuthUsername(r),
|
||||
dbpkg.OathReconScan,
|
||||
"",
|
||||
"",
|
||||
dbpkg.OathOutcomeSuccess,
|
||||
map[string]string{"host": report.Host},
|
||||
payload,
|
||||
)
|
||||
}
|
||||
|
||||
writeJSON(w, report)
|
||||
}
|
||||
|
||||
func oathHub(h *ReconHandler) *WSHub {
|
||||
if h == nil {
|
||||
return nil
|
||||
}
|
||||
return h.wsHub
|
||||
}
|
||||
|
||||
func openPortList(ports []recon.PortResult) []int {
|
||||
var out []int
|
||||
for _, p := range ports {
|
||||
if p.Open {
|
||||
out = append(out, p.Port)
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func crawlSSRFScore(c *recon.CrawlReport) int {
|
||||
if c == nil {
|
||||
return 0
|
||||
}
|
||||
return c.SSRFScore
|
||||
}
|
||||
|
||||
func crawlCMS(c *recon.CrawlReport) []string {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return c.CMSFingerprints
|
||||
}
|
||||
Reference in New Issue
Block a user