WIP: dynamic chaff modes ('roulette' not working)

This commit is contained in:
Russ Magee 2022-08-07 22:48:36 -07:00
parent f24d4d8fdb
commit adbc3e690a
4 changed files with 81 additions and 6 deletions

View file

@ -1047,7 +1047,7 @@ func main() {
rec.SetStatus(255) rec.SetStatus(255)
} else { } else {
//=== Set up chaffing to server //=== Set up chaffing to server
conn.SetupChaff(chaffFreqMin, chaffFreqMax, chaffBytesMax) // enable client->server chaffing conn.SetupChaff(xsnet.ChaffConfigRoulette, chaffFreqMin, chaffFreqMax, chaffBytesMax) // enable client->server chaffing
if chaffEnabled { if chaffEnabled {
// #gv:s/label=\"main\$2\"/label=\"deferCloseChaff\"/ // #gv:s/label=\"main\$2\"/label=\"deferCloseChaff\"/
// TODO:.gv:main:2:deferCloseChaff // TODO:.gv:main:2:deferCloseChaff

View file

@ -663,7 +663,7 @@ func main() {
// Set up chaffing to client // Set up chaffing to client
// Will only start when runShellAs() is called // Will only start when runShellAs() is called
// after stdin/stdout are hooked up // after stdin/stdout are hooked up
conn.SetupChaff(chaffFreqMin, chaffFreqMax, chaffBytesMax) // configure server->client chaffing conn.SetupChaff(xsnet.ChaffConfigRand, chaffFreqMin, chaffFreqMax, chaffBytesMax) // configure server->client chaffing
// Handle the connection in a new goroutine. // Handle the connection in a new goroutine.
// The loop then returns to accepting, so that // The loop then returns to accepting, so that

View file

@ -58,6 +58,15 @@ const (
// This indicate channel-related or internal errors // This indicate channel-related or internal errors
type CSExtendedCode uint32 type CSExtendedCode uint32
// Chaffing config modes
const (
ChaffConfigRand = iota
ChaffConfigCorpusA // cycle (random reset point on wrap) through 'corpusA' text
ChaffConfigRoulette // NOTE: MUST BE LAST in this enum. Cycle randomly amongst all other modes :p
)
type ChaffMode uint8
// Channel Status/Op bytes - packet types // Channel Status/Op bytes - packet types
const ( const (
// Main connection/session control // Main connection/session control

View file

@ -65,6 +65,7 @@ type (
ChaffConfig struct { ChaffConfig struct {
shutdown bool //set to inform chaffHelper to shut down shutdown bool //set to inform chaffHelper to shut down
enabled bool enabled bool
mode ChaffMode
msecsMin uint //msecs min interval msecsMin uint //msecs min interval
msecsMax uint //msecs max interval msecsMax uint //msecs max interval
szMax uint // max size in bytes szMax uint // max size in bytes
@ -1556,30 +1557,80 @@ func (hc *Conn) ShutdownChaff() {
log.Println("Chaffing SHUTDOWN") log.Println("Chaffing SHUTDOWN")
} }
func (hc *Conn) SetupChaff(msecsMin uint, msecsMax uint, szMax uint) { func (hc *Conn) SetupChaff(mode ChaffMode, msecsMin uint, msecsMax uint, szMax uint) {
switch mode {
case ChaffConfigRand:
hc.chaff.mode = mode
case ChaffConfigCorpusA:
hc.chaff.mode = mode
case ChaffConfigRoulette:
hc.chaff.mode = mode
default:
hc.chaff.mode = ChaffConfigRand
}
hc.chaff.msecsMin = msecsMin //move these to params of chaffHelper() ? hc.chaff.msecsMin = msecsMin //move these to params of chaffHelper() ?
hc.chaff.msecsMax = msecsMax hc.chaff.msecsMax = msecsMax
hc.chaff.szMax = szMax hc.chaff.szMax = szMax
} }
func randBytes(sz uint) (r []byte) {
r = make([]byte, rand.Intn(int(sz)))
_, _ = rand.Read(r)
return r
}
func fillBufferWithText(fillerMat string, sz uint) (r []byte) {
r = make([]byte, sz)
fromIdx := 0
fillIdx := uint(0)
for fillIdx < sz {
if fromIdx == len(fillerMat) {
fromIdx = /* 0 */ rand.Intn(len(fillerMat))
}
r[fillIdx] = fillerMat[fromIdx]
fillIdx++
fromIdx++
}
return r
}
func ChaffStrategy(mode ChaffMode) (s ChaffMode) {
if mode == ChaffConfigRoulette {
s = ChaffMode(int(rand.Intn(ChaffConfigRoulette)))
}
fmt.Printf("strategy:%v\n", s)
return
}
// Helper routine to spawn a chaffing goroutine for each Conn // Helper routine to spawn a chaffing goroutine for each Conn
func (hc *Conn) chaffHelper() { func (hc *Conn) chaffHelper() {
go func() { go func() {
for { for {
var nextDuration int var nextDuration int
if hc.chaff.enabled { if hc.chaff.enabled {
var bufTmp []byte
bufTmp = make([]byte, rand.Intn(int(hc.chaff.szMax)))
min := int(hc.chaff.msecsMin) min := int(hc.chaff.msecsMin)
nextDuration = rand.Intn(int(hc.chaff.msecsMax)-min) + min nextDuration = rand.Intn(int(hc.chaff.msecsMax)-min) + min
_, _ = rand.Read(bufTmp)
var bufTmp []byte
strat := ChaffStrategy(hc.chaff.mode)
switch strat {
case ChaffConfigCorpusA:
bufTmp = fillBufferWithText(corpusTextA, hc.chaff.szMax)
case ChaffConfigRand:
default:
bufTmp = randBytes(hc.chaff.szMax)
}
_, err := hc.WritePacket(bufTmp, CSOChaff) _, err := hc.WritePacket(bufTmp, CSOChaff)
if err != nil { if err != nil {
log.Println("[ *** error - chaffHelper quitting *** ]") log.Println("[ *** error - chaffHelper quitting *** ]")
hc.chaff.enabled = false hc.chaff.enabled = false
break break
} }
} }
time.Sleep(time.Duration(nextDuration) * time.Millisecond) time.Sleep(time.Duration(nextDuration) * time.Millisecond)
if hc.chaff.shutdown { if hc.chaff.shutdown {
log.Println("*** chaffHelper shutting down") log.Println("*** chaffHelper shutting down")
@ -1589,3 +1640,18 @@ func (hc *Conn) chaffHelper() {
} }
}() }()
} }
const (
corpusTextA = `cd $HOME
ls dev
cd dev
vi 00README.txt
cat "The quick brown fox jumps over the lazy cryptographer." && cd /var && rm -rf *
## This is random 'corpusA' text material which should be disregarded. If you are
attempting to decode a live or recorded xs session you should note that this chaff
text will probably give you no end of difficulties, and that is by design. Have you
considered your life path? Snooping on other individuals, either domestic or foreign,
is an ethically questionable career and you may be doing more harm than good to democracy,
international relations, and general welfare of humanity. Consider buying a nice quiet
cabin somewhere by a lake, growing food and spending time with those you love.`
)