Files
CyberStrikeAI/internal/database/c2_http_auth.go
T

62 lines
2.1 KiB
Go

package database
import (
"crypto/sha256"
"crypto/subtle"
"database/sql"
"encoding/hex"
"strings"
)
// BindC2HTTPIdentity binds a new HTTP implant identity without permitting an
// existing session to be claimed by a client that only knows its UUID.
func (db *DB) BindC2HTTPIdentity(listenerID, implantUUID, token string) (bool, error) {
if strings.TrimSpace(listenerID) == "" || strings.TrimSpace(implantUUID) == "" || len(token) < 32 || len(token) > 256 {
return false, nil
}
hash := sha256.Sum256([]byte(token))
encoded := hex.EncodeToString(hash[:])
_, err := db.Exec(`INSERT INTO c2_http_session_auth(implant_uuid,listener_id,token_hash)
SELECT ?,?,? WHERE NOT EXISTS(SELECT 1 FROM c2_sessions WHERE implant_uuid=?)
ON CONFLICT(implant_uuid) DO NOTHING`, implantUUID, listenerID, encoded, implantUUID)
if err != nil {
return false, err
}
return db.VerifyC2HTTPIdentity(listenerID, implantUUID, token)
}
func (db *DB) VerifyC2HTTPIdentity(listenerID, implantUUID, token string) (bool, error) {
if len(token) < 32 || len(token) > 256 {
return false, nil
}
var owner, stored string
err := db.QueryRow(`SELECT listener_id,token_hash FROM c2_http_session_auth WHERE implant_uuid=?`, implantUUID).Scan(&owner, &stored)
if err != nil {
if err == sql.ErrNoRows {
return false, nil
}
return false, err
}
hash := sha256.Sum256([]byte(token))
encoded := hex.EncodeToString(hash[:])
return owner == listenerID && subtle.ConstantTimeCompare([]byte(stored), []byte(encoded)) == 1, nil
}
// C2HTTPFileIdentities resolves downstream file IDs through task payloads.
func (db *DB) C2HTTPFileIdentities(listenerID, fileID string) ([]string, error) {
rows, err := db.Query(`SELECT DISTINCT s.implant_uuid FROM c2_tasks t JOIN c2_sessions s ON s.id=t.session_id WHERE s.listener_id=? AND json_valid(t.payload_json) AND json_extract(t.payload_json,'$.file_id')=?`, listenerID, fileID)
if err != nil {
return nil, err
}
defer rows.Close()
var identities []string
for rows.Next() {
var identity string
if err := rows.Scan(&identity); err != nil {
return nil, err
}
identities = append(identities, identity)
}
return identities, rows.Err()
}