mirror of
https://github.com/evilsocket/opensnitch.git
synced 2025-03-04 00:24:40 +01:00
allow to use lists of md5s to block connections
Besides domains, net ranges and IPs, now it's possible to filter connections by the MD5 of a binary, if it's enabled.
This commit is contained in:
parent
5184c45086
commit
ced8410d43
2 changed files with 76 additions and 47 deletions
|
@ -15,6 +15,7 @@ import (
|
|||
"github.com/evilsocket/opensnitch/daemon/conman"
|
||||
"github.com/evilsocket/opensnitch/daemon/core"
|
||||
"github.com/evilsocket/opensnitch/daemon/log"
|
||||
"github.com/evilsocket/opensnitch/daemon/procmon"
|
||||
)
|
||||
|
||||
// Type is the type of rule.
|
||||
|
@ -64,8 +65,9 @@ const (
|
|||
OpDomainsRegexpLists = Operand("lists.domains_regexp")
|
||||
OpIPLists = Operand("lists.ips")
|
||||
OpNetLists = Operand("lists.nets")
|
||||
OpHashMD5Lists = Operand("lists.hash.md5")
|
||||
|
||||
// TODO
|
||||
//OpHashMD5Lists = Operand("lists.hash.md5")
|
||||
//OpQuota = Operand("quota")
|
||||
//OpQuotaTxOver = Operand("quota.sent.over") // 1000b, 1kb, 1mb, 1gb, ...
|
||||
//OpQuotaRxOver = Operand("quota.recv.over") // 1000b, 1kb, 1mb, 1gb, ...
|
||||
|
@ -225,7 +227,7 @@ func (o *Operator) Compile() error {
|
|||
return fmt.Errorf("Operand lists is empty, nothing to load: %s", o)
|
||||
}
|
||||
o.loadLists()
|
||||
o.cb = o.domainsListCmp
|
||||
o.cb = o.domainsListsCmp
|
||||
} else if o.Operand == OpDomainsRegexpLists {
|
||||
if o.Data == "" {
|
||||
return fmt.Errorf("Operand regexp lists is empty, nothing to load: %s", o)
|
||||
|
@ -237,13 +239,19 @@ func (o *Operator) Compile() error {
|
|||
return fmt.Errorf("Operand ip lists is empty, nothing to load: %s", o)
|
||||
}
|
||||
o.loadLists()
|
||||
o.cb = o.ipListCmp
|
||||
o.cb = o.simpleListsCmp
|
||||
} else if o.Operand == OpNetLists {
|
||||
if o.Data == "" {
|
||||
return fmt.Errorf("Operand net lists is empty, nothing to load: %s", o)
|
||||
}
|
||||
o.loadLists()
|
||||
o.cb = o.ipNetCmp
|
||||
} else if o.Operand == OpHashMD5Lists {
|
||||
if o.Data == "" {
|
||||
return fmt.Errorf("Operand lists.hash.md5 is empty, nothing to load: %s", o)
|
||||
}
|
||||
o.loadLists()
|
||||
o.cb = o.simpleListsCmp
|
||||
} else if o.Operand == OpProcessHashMD5 || o.Operand == OpProcessHashSHA1 {
|
||||
o.cb = o.hashCmp
|
||||
}
|
||||
|
@ -288,7 +296,15 @@ func (o *Operator) cmpNetwork(destIP interface{}) bool {
|
|||
return o.netMask.Contains(destIP.(net.IP))
|
||||
}
|
||||
|
||||
func (o *Operator) domainsListCmp(v interface{}) bool {
|
||||
func (o *Operator) matchListsCmp(msg, what string) bool {
|
||||
if item, found := o.lists[what]; found {
|
||||
log.Debug("%s: %s, %s", log.Red(msg), what, item)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (o *Operator) domainsListsCmp(v interface{}) bool {
|
||||
dstHost := v.(string)
|
||||
if dstHost == "" {
|
||||
return false
|
||||
|
@ -299,26 +315,18 @@ func (o *Operator) domainsListCmp(v interface{}) bool {
|
|||
o.RLock()
|
||||
defer o.RUnlock()
|
||||
|
||||
if _, found := o.lists[dstHost]; found {
|
||||
log.Debug("%s: %s, %s", log.Red("domain list match"), dstHost, o.lists[dstHost])
|
||||
return true
|
||||
}
|
||||
return false
|
||||
return o.matchListsCmp("domains list match", dstHost)
|
||||
}
|
||||
|
||||
func (o *Operator) ipListCmp(v interface{}) bool {
|
||||
dstIP := v.(string)
|
||||
if dstIP == "" {
|
||||
func (o *Operator) simpleListsCmp(v interface{}) bool {
|
||||
what := v.(string)
|
||||
if what == "" {
|
||||
return false
|
||||
}
|
||||
o.RLock()
|
||||
defer o.RUnlock()
|
||||
|
||||
if _, found := o.lists[dstIP]; found {
|
||||
log.Debug("%s: %s, %s", log.Red("IP list match"), dstIP, o.lists[dstIP].(string))
|
||||
return true
|
||||
}
|
||||
return false
|
||||
return o.matchListsCmp("simple list match", what)
|
||||
}
|
||||
|
||||
func (o *Operator) ipNetCmp(dstIP interface{}) bool {
|
||||
|
@ -393,6 +401,8 @@ func (o *Operator) Match(con *conman.Connection, hasChecksums bool) bool {
|
|||
return o.cb(con.DstHost)
|
||||
} else if o.Operand == OpIPLists {
|
||||
return o.cb(con.DstIP.String())
|
||||
} else if o.Operand == OpHashMD5Lists {
|
||||
return o.cb(con.Process.Checksums[procmon.HashMD5])
|
||||
} else if o.Operand == OpUserID || o.Operand == OpUserName {
|
||||
return o.cb(strconv.Itoa(con.Entry.UserId))
|
||||
} else if o.Operand == OpDstNetwork {
|
||||
|
|
|
@ -104,32 +104,46 @@ func (o *Operator) StopMonitoringLists() {
|
|||
}
|
||||
}
|
||||
|
||||
func (o *Operator) readDomainsList(raw, fileName string) (dups uint64) {
|
||||
log.Debug("Loading domains list: %s, size: %d", fileName, len(raw))
|
||||
lines := strings.Split(string(raw), "\n")
|
||||
for _, domain := range lines {
|
||||
if len(domain) < 9 {
|
||||
continue
|
||||
func filterDomains(line, defValue string) (bool, string, string) {
|
||||
if len(line) < 9 {
|
||||
return true, line, defValue
|
||||
}
|
||||
// exclude not valid lines
|
||||
if domain[:7] != "0.0.0.0" && domain[:9] != "127.0.0.1" {
|
||||
continue
|
||||
if line[:7] != "0.0.0.0" && line[:9] != "127.0.0.1" {
|
||||
return true, line, defValue
|
||||
}
|
||||
host := domain[8:]
|
||||
host := line[8:]
|
||||
// exclude localhost entries
|
||||
if domain[:9] == "127.0.0.1" {
|
||||
host = domain[10:]
|
||||
if line[:9] == "127.0.0.1" {
|
||||
host = line[10:]
|
||||
}
|
||||
if host == "local" || host == "localhost" || host == "localhost.localdomain" || host == "broadcasthost" {
|
||||
continue
|
||||
return true, line, defValue
|
||||
}
|
||||
|
||||
host = core.Trim(host)
|
||||
if _, found := o.lists[host]; found {
|
||||
return false, host, defValue
|
||||
}
|
||||
|
||||
func filterSimple(line, hashPath string) (bool, string, string) {
|
||||
// XXX: some lists may use TABs as separator
|
||||
hash := strings.SplitN(line, " ", 2)
|
||||
return false, hash[0], hash[1]
|
||||
}
|
||||
|
||||
func (o *Operator) readTupleList(raw, fileName string, filter func(line, defValue string) (bool, string, string)) (dups uint64) {
|
||||
log.Debug("Loading list: %s, size: %d", fileName, len(raw))
|
||||
lines := strings.Split(string(raw), "\n")
|
||||
for _, line := range lines {
|
||||
skip, key, value := filter(line, fileName)
|
||||
if skip || len(line) < 9 {
|
||||
continue
|
||||
}
|
||||
key = core.Trim(key)
|
||||
if _, found := o.lists[key]; found {
|
||||
dups++
|
||||
continue
|
||||
}
|
||||
o.lists[host] = fileName
|
||||
o.lists[key] = value
|
||||
}
|
||||
lines = nil
|
||||
log.Info("%d domains loaded, %s", len(o.lists), fileName)
|
||||
|
@ -187,22 +201,25 @@ func (o *Operator) readRegexpList(raw, fileName string) (dups uint64) {
|
|||
return dups
|
||||
}
|
||||
|
||||
func (o *Operator) readIPList(raw, fileName string) (dups uint64) {
|
||||
log.Debug("Loading IPs list: %s, size: %d", fileName, len(raw))
|
||||
// A simple list is a list composed of one column with several entries, that
|
||||
// don't require manipulation.
|
||||
// It can be a list of IPs, domains, etc.
|
||||
func (o *Operator) readSimpleList(raw, fileName string) (dups uint64) {
|
||||
log.Debug("Loading simple list: %s, size: %d", fileName, len(raw))
|
||||
lines := strings.Split(string(raw), "\n")
|
||||
for _, line := range lines {
|
||||
if line == "" || line[0] == '#' {
|
||||
continue
|
||||
}
|
||||
ip := core.Trim(line)
|
||||
if _, found := o.lists[ip]; found {
|
||||
what := core.Trim(line)
|
||||
if _, found := o.lists[what]; found {
|
||||
dups++
|
||||
continue
|
||||
}
|
||||
o.lists[ip] = fileName
|
||||
o.lists[what] = fileName
|
||||
}
|
||||
lines = nil
|
||||
log.Info("%d IPs loaded, %s", len(o.lists), fileName)
|
||||
log.Info("%d entries loaded, %s", len(o.lists), fileName)
|
||||
|
||||
return dups
|
||||
}
|
||||
|
@ -236,13 +253,15 @@ func (o *Operator) readLists() error {
|
|||
}
|
||||
|
||||
if o.Operand == OpDomainsLists {
|
||||
dups += o.readDomainsList(string(raw), fileName)
|
||||
dups += o.readTupleList(string(raw), fileName, filterDomains)
|
||||
} else if o.Operand == OpDomainsRegexpLists {
|
||||
dups += o.readRegexpList(string(raw), fileName)
|
||||
} else if o.Operand == OpNetLists {
|
||||
dups += o.readNetList(string(raw), fileName)
|
||||
} else if o.Operand == OpIPLists {
|
||||
dups += o.readIPList(string(raw), fileName)
|
||||
dups += o.readSimpleList(string(raw), fileName)
|
||||
} else if o.Operand == OpHashMD5Lists {
|
||||
dups += o.readSimpleList(string(raw), fileName)
|
||||
} else {
|
||||
log.Warning("Unknown lists operand type: %s", o.Operand)
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue