Add recon form fingerprint library and SSRF canary mode.
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
Score crawl inputs by SSRF-prone field names and register ping-back canaries for operator paste confirmation.
This commit is contained in:
50
server/internal/db/recon_canary.go
Normal file
50
server/internal/db/recon_canary.go
Normal file
@@ -0,0 +1,50 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"time"
|
||||
|
||||
"crypto-miner-server/internal/recon"
|
||||
)
|
||||
|
||||
func (d *Database) ensureReconSSRfCanaryTable() error {
|
||||
_, err := d.Exec(`CREATE TABLE IF NOT EXISTS recon_ssrf_canary (
|
||||
scan_id TEXT PRIMARY KEY, host TEXT NOT NULL, canary_url TEXT NOT NULL,
|
||||
status TEXT NOT NULL DEFAULT 'pending', paste_field_name TEXT NOT NULL DEFAULT '',
|
||||
paste_field_id TEXT NOT NULL DEFAULT '', hit_at DATETIME, created_at DATETIME NOT NULL)`)
|
||||
return err
|
||||
}
|
||||
|
||||
func (d *Database) InsertReconSSRfCanary(scanID, host, canaryURL, pasteName, pasteID string) error {
|
||||
if err := d.ensureReconSSRfCanaryTable(); err != nil { return err }
|
||||
_, err := d.Exec(`INSERT INTO recon_ssrf_canary (scan_id, host, canary_url, status, paste_field_name, paste_field_id, created_at) VALUES (?, ?, ?, 'pending', ?, ?, ?)`,
|
||||
scanID, host, canaryURL, pasteName, pasteID, time.Now().UTC().Format(time.RFC3339Nano))
|
||||
return err
|
||||
}
|
||||
|
||||
func (d *Database) GetReconSSRfCanary(scanID string) (*recon.SSRFCanaryInfo, error) {
|
||||
if err := d.ensureReconSSRfCanaryTable(); err != nil { return nil, err }
|
||||
var host, canaryURL, status, pasteName, pasteID string
|
||||
var hitAt sql.NullString
|
||||
err := d.QueryRow(`SELECT host, canary_url, status, paste_field_name, paste_field_id, hit_at FROM recon_ssrf_canary WHERE scan_id = ?`, scanID).Scan(&host, &canaryURL, &status, &pasteName, &pasteID, &hitAt)
|
||||
if err != nil { return nil, err }
|
||||
info := &recon.SSRFCanaryInfo{ScanID: scanID, URL: canaryURL, Status: status, PasteTarget: canaryURL, PasteFieldName: pasteName, PasteFieldID: pasteID}
|
||||
if hitAt.Valid { if ts, err := time.Parse(time.RFC3339Nano, hitAt.String); err == nil { info.HitAt = &ts } }
|
||||
return info, nil
|
||||
}
|
||||
|
||||
func (d *Database) UpdateReconSSRfCanaryPasteField(scanID, pasteName, pasteID string) error {
|
||||
if err := d.ensureReconSSRfCanaryTable(); err != nil { return err }
|
||||
_, err := d.Exec(`UPDATE recon_ssrf_canary SET paste_field_name = ?, paste_field_id = ? WHERE scan_id = ?`, pasteName, pasteID, scanID)
|
||||
return err
|
||||
}
|
||||
|
||||
func (d *Database) MarkReconSSRfCanaryHit(scanID string) (bool, error) {
|
||||
if err := d.ensureReconSSRfCanaryTable(); err != nil { return false, err }
|
||||
res, err := d.Exec(`UPDATE recon_ssrf_canary SET status = 'confirmed', hit_at = ? WHERE scan_id = ? AND status != 'confirmed'`, time.Now().UTC().Format(time.RFC3339Nano), scanID)
|
||||
if err != nil { return false, err }
|
||||
if n, _ := res.RowsAffected(); n > 0 { return true, nil }
|
||||
var status string
|
||||
err = d.QueryRow(`SELECT status FROM recon_ssrf_canary WHERE scan_id = ?`, scanID).Scan(&status)
|
||||
return status == "confirmed", err
|
||||
}
|
||||
Reference in New Issue
Block a user