diff --git a/pkg/action/diff.go b/pkg/action/diff.go index 22a2e2279..3daa893ab 100644 --- a/pkg/action/diff.go +++ b/pkg/action/diff.go @@ -12,7 +12,6 @@ import ( "path/filepath" "regexp" "strings" - "sync" "github.com/agext/levenshtein" "github.com/chainguard-dev/clog" @@ -21,23 +20,40 @@ import ( "golang.org/x/sync/errgroup" ) -func relPath(from string, fr *malcontent.FileReport, isArchive bool) (string, error) { +// displayPath mimics diff(1) output for relative paths. +func displayPath(base, path string) string { + if filepath.IsAbs(path) { + rel, err := filepath.Rel(base, path) + if err == nil { + return rel + } + } + return path +} + +// relPath returns the cleanest possible relative path between a source path and files within said path. +func relPath(from string, fr *malcontent.FileReport, isArchive bool) (string, string, error) { + var base string var err error var rel string switch { case isArchive: fromRoot := fr.ArchiveRoot - + base = fr.FullPath // trim archiveRoot from fullPath archiveFile := strings.TrimPrefix(fr.FullPath, fr.ArchiveRoot) rel, err = filepath.Rel(fromRoot, archiveFile) if err != nil { - return "", err + return "", "", err } default: + base, err = filepath.Abs(from) + if err != nil { + return "", "", err + } info, err := os.Stat(from) if err != nil { - return "", err + return "", "", err } dir := filepath.Dir(from) // Evaluate symlinks to cover edge cases like macOS' /private/tmp -> /tmp symlink @@ -50,28 +66,29 @@ func relPath(from string, fr *malcontent.FileReport, isArchive bool) (string, er fromRoot, err = filepath.EvalSymlinks(dir) } if err != nil { - return "", err + return "", "", err } if fromRoot == "." { fromRoot = from } rel, err = filepath.Rel(fromRoot, fr.Path) if err != nil { - return "", err + return "", "", err } } - return rel, nil + return rel, base, nil } -func relFileReport(ctx context.Context, c malcontent.Config, fromPath string) (map[string]*malcontent.FileReport, error) { +func relFileReport(ctx context.Context, c malcontent.Config, fromPath string) (map[string]*malcontent.FileReport, string, error) { fromConfig := c fromConfig.Renderer = nil fromConfig.ScanPaths = []string{fromPath} fromReport, err := recursiveScan(ctx, fromConfig) if err != nil { - return nil, err + return nil, "", err } fromRelPath := map[string]*malcontent.FileReport{} + var base, rel string fromReport.Files.Range(func(key, value any) bool { if key == nil || value == nil { return true @@ -81,7 +98,7 @@ func relFileReport(ctx context.Context, c malcontent.Config, fromPath string) (m if fr.Skipped != "" || fr.Error != "" { return true } - rel, err := relPath(fromPath, fr, isArchive) + rel, base, err = relPath(fromPath, fr, isArchive) if err != nil { return false } @@ -90,7 +107,35 @@ func relFileReport(ctx context.Context, c malcontent.Config, fromPath string) (m return true }) - return fromRelPath, nil + return fromRelPath, base, nil +} + +// scoreFile returns a boolean to determine how individual files are stored in a diff report. +func scoreFile(fr, tr *malcontent.FileReport) bool { + scoreSrc := false + scoreDest := false + + patterns := []string{ + `^[\w.-]+\.so$`, + `^.+-.*-r\d+\.spdx\.json$`, + } + + for _, pattern := range patterns { + re := regexp.MustCompile(pattern) + if re.MatchString(fr.Path) { + scoreSrc = true + } + if re.MatchString(tr.Path) { + scoreDest = true + } + } + + // If both files match patterns, reeturn true to indicate that `inferMoves` should be used + // Otherwise, indicate that `handleFile` should be used + if scoreSrc && scoreDest { + return true + } + return false } func Diff(ctx context.Context, c malcontent.Config) (*malcontent.Report, error) { @@ -98,13 +143,29 @@ func Diff(ctx context.Context, c malcontent.Config) (*malcontent.Report, error) return nil, fmt.Errorf("diff mode requires 2 paths, you passed in %d path(s)", len(c.ScanPaths)) } + srcPath := c.ScanPaths[0] + destPath := c.ScanPaths[1] + var g errgroup.Group var src, dest map[string]*malcontent.FileReport + var srcBase, destBase string srcCh := make(chan map[string]*malcontent.FileReport, 1) destCh := make(chan map[string]*malcontent.FileReport, 1) + srcIsArchive := isSupportedArchive(srcPath) + destIsArchive := isSupportedArchive(destPath) + + srcInfo, err := os.Stat(srcPath) + if err != nil { + return nil, err + } + + destInfo, err := os.Stat(destPath) + if err != nil { + return nil, err + } g.Go(func() error { - src, err := relFileReport(ctx, c, c.ScanPaths[0]) + src, srcBase, err = relFileReport(ctx, c, srcPath) if err != nil { return err } @@ -113,7 +174,7 @@ func Diff(ctx context.Context, c malcontent.Config) (*malcontent.Report, error) }) g.Go(func() error { - dest, err := relFileReport(ctx, c, c.ScanPaths[1]) + dest, destBase, err = relFileReport(ctx, c, destPath) if err != nil { return err } @@ -137,8 +198,35 @@ func Diff(ctx context.Context, c malcontent.Config) (*malcontent.Report, error) Modified: orderedmap.New[string, *malcontent.FileReport](), } - processSrc(ctx, c, src, dest, d) - processDest(ctx, c, src, dest, d) + // When scanning two directories, compare the files in each directory + // and employ add/delete for files that are not the same + // When scanning two files, do a 1:1 comparison and + // consider the source -> destination as a change rather than an add/delete + if (srcInfo.IsDir() && destInfo.IsDir()) || (srcIsArchive && destIsArchive) { + handleDir(ctx, c, src, dest, d) + } else { + var srcFile, destFile *malcontent.FileReport + for _, fr := range src { + srcFile = fr + break + } + for _, fr := range dest { + destFile = fr + break + } + if srcFile != nil && destFile != nil { + formatSrc := displayPath(srcBase, srcFile.Path) + formatDest := displayPath(destBase, destFile.Path) + if scoreFile(srcFile, destFile) { + d.Removed.Set(srcFile.Path, srcFile) + d.Added.Set(destFile.Path, destFile) + inferMoves(ctx, c, d) + } else { + handleFile(ctx, c, srcFile, destFile, fmt.Sprintf("%s -> %s", formatSrc, formatDest), d) + } + } + } + // skip inferring moves if added and removed are empty if d.Added != nil && d.Removed != nil { inferMoves(ctx, c, d) @@ -146,61 +234,51 @@ func Diff(ctx context.Context, c malcontent.Config) (*malcontent.Report, error) return &malcontent.Report{Diff: d}, nil } -func processSrc(ctx context.Context, c malcontent.Config, src, dest map[string]*malcontent.FileReport, d *malcontent.DiffReport) { - // things that appear in the source - for relPath, fr := range src { - tr, exists := dest[relPath] - if !exists { - d.Removed.Set(relPath, fr) - continue - } - handleFile(ctx, c, fr, tr, relPath, d) - } -} - -func processDest(ctx context.Context, c malcontent.Config, from, to map[string]*malcontent.FileReport, d *malcontent.DiffReport) { - // findings that exist only in the destination - for relPath, tr := range to { - fr, exists := from[relPath] - if !exists { - d.Added.Set(relPath, tr) - continue - } - - fileDestination(ctx, c, fr, tr, relPath, d) - } -} +func handleDir(ctx context.Context, c malcontent.Config, src, dest map[string]*malcontent.FileReport, d *malcontent.DiffReport) { + srcFiles := make(map[string]*malcontent.FileReport) + destFiles := make(map[string]*malcontent.FileReport) -func fileDestination(ctx context.Context, c malcontent.Config, fr, tr *malcontent.FileReport, relPath string, d *malcontent.DiffReport) { - // We've now established that this file exists in both source and destination - if fr.RiskScore < c.MinFileRisk && tr.RiskScore < c.MinFileRisk { - clog.FromContext(ctx).Info("diff does not meet min trigger level", slog.Any("path", tr.Path)) - return + for path, fr := range src { + base := filepath.Base(path) + srcFiles[base] = fr } - - // Filter files that are marked as added - if filterDiff(ctx, c, fr, tr) { - return + for path, fr := range dest { + base := filepath.Base(path) + destFiles[base] = fr } - abs := createFileReport(tr, fr) - - // if destination behavior is not in the source - for _, tb := range tr.Behaviors { - if !behaviorExists(tb, fr.Behaviors) { - tb.DiffAdded = true - abs.Behaviors = append(abs.Behaviors, tb) - continue + // Check for files that exist in both the source and destination + // Files that exist in both pass to handleFile which considers files as modifications + // Otherwise, treat the source file as existing only in the source directory + // These files are considered removals from the destination + for name, srcFr := range srcFiles { + if destFr, exists := destFiles[name]; exists { + if !filterDiff(ctx, c, srcFr, destFr) { + formatSrc := displayPath(name, srcFr.Path) + formatDest := displayPath(name, destFr.Path) + if scoreFile(srcFr, destFr) { + d.Removed.Set(srcFr.Path, srcFr) + d.Added.Set(destFr.Path, destFr) + inferMoves(ctx, c, d) + } else { + handleFile(ctx, c, srcFr, destFr, fmt.Sprintf("%s -> %s", formatSrc, formatDest), d) + } + } + } else { + formatSrc := displayPath(name, srcFr.Path) + dirPath := filepath.Dir(formatSrc) + d.Removed.Set(fmt.Sprintf("%s/%s", dirPath, name), srcFr) } } - // are there already modified behaviors for this file? - rel, exists := d.Modified.Get(relPath) - if !exists { - d.Modified.Set(relPath, abs) - } else { - rel.Behaviors = append(rel.Behaviors, abs.Behaviors...) - d.Modified.Set(relPath, rel) + // Check for files that exist only in the destination directory + // These files are considered additions to the destination + for name, destFr := range destFiles { + if _, exists := srcFiles[name]; !exists { + formatDest := displayPath(name, destFr.Path) + dirPath := filepath.Dir(formatDest) + d.Added.Set(fmt.Sprintf("%s/%s", dirPath, name), destFr) + } } } @@ -218,15 +296,29 @@ func handleFile(ctx context.Context, c malcontent.Config, fr, tr *malcontent.Fil rbs := createFileReport(tr, fr) + // Findings that exist only in the source + // If true, these are considered to be removed from the destination for _, fb := range fr.Behaviors { - // findings that exist only in the source if !behaviorExists(fb, tr.Behaviors) { fb.DiffRemoved = true rbs.Behaviors = append(rbs.Behaviors, fb) continue } - // findings that exist in both, for reference - rbs.Behaviors = append(rbs.Behaviors, fb) + } + + // Findings that exist only in the destination + // If true, these are considered to be added to the destination + // If findings exist in both files, then there is no diff for the given behavior + for _, tb := range tr.Behaviors { + if !behaviorExists(tb, fr.Behaviors) { + tb.DiffAdded = true + rbs.Behaviors = append(rbs.Behaviors, tb) + continue + } + if behaviorExists(tb, fr.Behaviors) { + rbs.Behaviors = append(rbs.Behaviors, tb) + continue + } } d.Modified.Set(relPath, rbs) @@ -254,23 +346,11 @@ func behaviorExists(b *malcontent.Behavior, behaviors []*malcontent.Behavior) bo return false } -// filterMap filters orderedmap pairs by checking for matches against a slice of compiled regular expression patterns. -func filterMap(om *orderedmap.OrderedMap[string, *malcontent.FileReport], ps []*regexp.Regexp, c chan<- *orderedmap.Pair[string, *malcontent.FileReport], wg *sync.WaitGroup) { - defer wg.Done() - for pair := om.Oldest(); pair != nil; pair = pair.Next() { - for _, pattern := range ps { - if match := pattern.FindString(filepath.Base(pair.Key)); match != "" { - c <- pair - } - } - } -} - // combine iterates over the removed and added channels to create a diff report to store in the combined channel. -func combine(removed, added <-chan *orderedmap.Pair[string, *malcontent.FileReport]) []malcontent.CombinedReport { - combined := make([]malcontent.CombinedReport, 0, len(removed)*len(added)) - for r := range removed { - for a := range added { +func combineReports(removed, added *orderedmap.OrderedMap[string, *malcontent.FileReport]) []malcontent.CombinedReport { + combined := make([]malcontent.CombinedReport, 0, removed.Len()*added.Len()) + for r := removed.Oldest(); r != nil; r = r.Next() { + for a := added.Oldest(); a != nil; a = a.Next() { score := levenshtein.Match(r.Key, a.Key, levenshtein.NewParams()) if score < 0.9 { continue @@ -287,44 +367,8 @@ func combine(removed, added <-chan *orderedmap.Pair[string, *malcontent.FileRepo return combined } -// combineReports orchestrates the population of the diffs channel with relevant diffReports. -func combineReports(d *malcontent.DiffReport) []malcontent.CombinedReport { - var wg sync.WaitGroup - - // Patterns we care about when handling diffs - patterns := []string{ - `^[\w.-]+\.so$`, - `^.+-.*-r\d+\.spdx\.json$`, - } - - ps := make([]*regexp.Regexp, len(patterns)) - for i, pattern := range patterns { - ps[i] = regexp.MustCompile(pattern) - } - - // Build two channels with filtered paths to iterate through in the worker pool - removed := make(chan *orderedmap.Pair[string, *malcontent.FileReport], d.Removed.Len()) - added := make(chan *orderedmap.Pair[string, *malcontent.FileReport], d.Added.Len()) - - wg.Add(1) - go func() { - filterMap(d.Removed, ps, removed, &wg) - close(removed) - }() - - wg.Add(1) - go func() { - filterMap(d.Added, ps, added, &wg) - close(added) - }() - - wg.Wait() - - return combine(removed, added) -} - func inferMoves(ctx context.Context, c malcontent.Config, d *malcontent.DiffReport) { - for _, cr := range combineReports(d) { + for _, cr := range combineReports(d.Removed, d.Added) { fileMove(ctx, c, cr.RemovedFR, cr.AddedFR, cr.Removed, cr.Added, d, cr.Score) } } @@ -371,6 +415,9 @@ func fileMove(ctx context.Context, c malcontent.Config, fr, tr *malcontent.FileR fb.DiffRemoved = true abs.Behaviors = append(abs.Behaviors, fb) } + if behaviorExists(fb, tr.Behaviors) { + abs.Behaviors = append(abs.Behaviors, fb) + } } d.Modified.Set(apath, abs) diff --git a/pkg/render/markdown.go b/pkg/render/markdown.go index 2de625db7..566a385ef 100644 --- a/pkg/render/markdown.go +++ b/pkg/render/markdown.go @@ -82,6 +82,7 @@ func (r Markdown) Full(ctx context.Context, rep *malcontent.Report) error { } added := 0 removed := 0 + noDiff := 0 for _, b := range modified.Value.Behaviors { if b.DiffAdded { added++ @@ -89,24 +90,57 @@ func (r Markdown) Full(ctx context.Context, rep *malcontent.Report) error { if b.DiffRemoved { removed++ } + if !b.DiffAdded && !b.DiffRemoved { + noDiff++ + } } // We split the added/removed up in Markdown to address readability feedback. Unfortunately, // this means we hide "existing" behaviors, which causes context to suffer. We should evaluate an // improved rendering, similar to the "terminal" refresh, that includes everything. + var count int + var qual string if added > 0 { + count = added + noun := "behavior" + qual = "new" + if count > 1 { + noun = "behaviors" + } markdownTable(ctx, modified.Value, r.w, tableConfig{ - Title: fmt.Sprintf("### %d new behaviors", added), + Title: fmt.Sprintf("### %d %s %s", count, qual, noun), SkipRemoved: true, SkipExisting: true, + SkipNoDiff: true, }) } if removed > 0 { + count = removed + noun := "behavior" + qual = "removed" + if count > 1 { + noun = "behaviors" + } markdownTable(ctx, modified.Value, r.w, tableConfig{ - Title: fmt.Sprintf("### %d removed behaviors", removed), + Title: fmt.Sprintf("### %d %s %s", count, qual, noun), SkipAdded: true, SkipExisting: true, + SkipNoDiff: true, + }) + } + + if noDiff > 0 { + count = noDiff + noun := "behavior" + qual = "consistent" + if count > 1 { + noun = "behaviors" + } + markdownTable(ctx, modified.Value, r.w, tableConfig{ + Title: fmt.Sprintf("### %d %s %s", count, qual, noun), + SkipAdded: true, + SkipRemoved: true, }) } } @@ -121,7 +155,6 @@ func markdownTable(_ context.Context, fr *malcontent.FileReport, w io.Writer, rc } if fr.Skipped != "" { - // fmt.Printf("%s - skipped: %s\n", path, fr.Skipped) return } @@ -195,6 +228,11 @@ func markdownTable(_ context.Context, fr *malcontent.FileReport, w io.Writer, rc } risk = fmt.Sprintf("-%s", risk) } + if (!k.Behavior.DiffRemoved && !k.Behavior.DiffAdded) || rc.NoDiff { + if rc.SkipNoDiff { + continue + } + } key := fmt.Sprintf("[%s](%s)", k.Key, k.Behavior.RuleURL) if strings.HasPrefix(risk, "+") { diff --git a/pkg/render/simple.go b/pkg/render/simple.go index b0f904a74..fe9f52814 100644 --- a/pkg/render/simple.go +++ b/pkg/render/simple.go @@ -104,6 +104,9 @@ func (r Simple) Full(_ context.Context, rep *malcontent.Report) error { if b.DiffAdded { fmt.Fprintf(r.w, "+%s\n", b.ID) } + if !b.DiffRemoved && !b.DiffAdded { + fmt.Fprintf(r.w, "%s\n", b.ID) + } } } diff --git a/pkg/render/terminal.go b/pkg/render/terminal.go index af3497bd9..714d5f5a0 100644 --- a/pkg/render/terminal.go +++ b/pkg/render/terminal.go @@ -26,7 +26,9 @@ type tableConfig struct { ShowTitle bool DiffRemoved bool DiffAdded bool + NoDiff bool SkipAdded bool + SkipNoDiff bool SkipRemoved bool SkipExisting bool } @@ -319,6 +321,13 @@ func renderFileSummary(_ context.Context, fr *malcontent.FileReport, w io.Writer content = fmt.Sprintf("%s%s%s %s %s", prefix, indent, bullet, rest, desc) e = "" } + + if !b.DiffAdded && !b.DiffRemoved { + prefix = " " + pc = color.New(color.FgHiCyan) + content = fmt.Sprintf("%s%s%s %s %s", prefix, indent, bullet, rest, desc) + e = "" + } } // no evidence to give diff --git a/tests/javascript/2024.lottie-player/lottie-player.min.js.mdiff b/tests/javascript/2024.lottie-player/lottie-player.min.js.mdiff index 50a5439c3..7d72bbedf 100644 --- a/tests/javascript/2024.lottie-player/lottie-player.min.js.mdiff +++ b/tests/javascript/2024.lottie-player/lottie-player.min.js.mdiff @@ -51,3 +51,14 @@ | -MEDIUM | [exec/remote_commands/code_eval](https://github.com/chainguard-dev/malcontent/blob/main/rules/exec/remote_commands/code_eval.yara#eval) | evaluate code dynamically using eval() | [eval("](https://github.com/search?q=eval%28%22&type=code) | | -MEDIUM | [os/time/clock_sleep](https://github.com/chainguard-dev/malcontent/blob/main/rules/os/time/clock-sleep.yara#setInterval) | uses setInterval to wait | [setInterval(](https://github.com/search?q=setInterval%28&type=code) | +### 6 consistent behaviors + +| RISK | KEY | DESCRIPTION | EVIDENCE | +|--------|-------------------------------------------------------------------------------------------------------------------------------------|------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| MEDIUM | [net/download](https://github.com/chainguard-dev/malcontent/blob/main/rules/net/download/download.yara#download) | download files | [Downloads](https://github.com/search?q=Downloads&type=code)
[downloads-view](https://github.com/search?q=downloads-view&type=code)
[mobile-download-links](https://github.com/search?q=mobile-download-links&type=code) | +| LOW | [data/encoding/json_decode](https://github.com/chainguard-dev/malcontent/blob/main/rules/data/encoding/json-decode.yara#jsondecode) | Decodes JSON messages | [JSON.parse](https://github.com/search?q=JSON.parse&type=code) | +| LOW | [data/encoding/json_encode](https://github.com/chainguard-dev/malcontent/blob/main/rules/data/encoding/json-encode.yara#JSONEncode) | encodes JSON | [JSON.stringify](https://github.com/search?q=JSON.stringify&type=code) | +| LOW | [exec/plugin](https://github.com/chainguard-dev/malcontent/blob/main/rules/exec/plugin/plugin.yara#plugin) | references a 'plugin' | [plugin_relativeTime](https://github.com/search?q=plugin_relativeTime&type=code)
[plugin_updateLocale](https://github.com/search?q=plugin_updateLocale&type=code)
[plugins](https://github.com/search?q=plugins&type=code) | +| LOW | [net/url/embedded](https://github.com/chainguard-dev/malcontent/blob/main/rules/net/url/embedded.yara#https_url) | contains embedded HTTPS URLs | [https://abitype.dev](https://abitype.dev)
[https://andromeda-explorer.metis.io/api](https://andromeda-explorer.metis.io/api)
[https://andromeda.metis.io/?owner=1088](https://andromeda.metis.io/?owner=1088)
[https://api-era.zksync.network/api](https://api-era.zksync.network/api)
[https://api-moonbeam.moonscan.io/api](https://api-moonbeam.moonscan.io/api)
[https://api-moonriver.moonscan.io/api](https://api-moonriver.moonscan.io/api)
[https://api-optimistic.etherscan.io/api](https://api-optimistic.etherscan.io/api)
[https://api-zkevm.polygonscan.com/api](https://api-zkevm.polygonscan.com/api)
[https://api.arbiscan.io/api](https://api.arbiscan.io/api)
[https://api.avax.network/ext/bc/C/rpc](https://api.avax.network/ext/bc/C/rpc)
[https://api.basescan.org/api](https://api.basescan.org/api)
[https://api.blastscan.io/api](https://api.blastscan.io/api)
[https://api.bscscan.com/api](https://api.bscscan.com/api)
[https://api.celoscan.io/api](https://api.celoscan.io/api)
[https://api.etherscan.io/api](https://api.etherscan.io/api)
[https://api.ftmscan.com/api](https://api.ftmscan.com/api)
[https://api.gnosisscan.io/api](https://api.gnosisscan.io/api)
[https://api.lineascan.build/api](https://api.lineascan.build/api)
[https://api.mantlescan.xyz/api](https://api.mantlescan.xyz/api)
[https://api.polygonscan.com/api](https://api.polygonscan.com/api)
[https://api.roninchain.com/rpc](https://api.roninchain.com/rpc)
[https://api.routescan.io/v2/network/mainnet/evm/43114/etherscan/api](https://api.routescan.io/v2/network/mainnet/evm/43114/etherscan/api)
[https://api.scan.pulsechain.com/api](https://api.scan.pulsechain.com/api)
[https://api.scrollscan.com/api](https://api.scrollscan.com/api)
[https://api.snowtrace.io](https://api.snowtrace.io)
[https://api.wallet.coinbase.com/rpc/v2/desktop/chrome](https://api.wallet.coinbase.com/rpc/v2/desktop/chrome)
[https://api.web3modal.org](https://api.web3modal.org)
[https://app.roninchain.com](https://app.roninchain.com)
[https://arb1.arbitrum.io/rpc](https://arb1.arbitrum.io/rpc)
[https://arbiscan.io](https://arbiscan.io)
[https://arweave.net](https://arweave.net)
[https://aurorascan.dev/api](https://aurorascan.dev/api)
[https://avatar.vercel.sh/andrew.svg?size=50](https://avatar.vercel.sh/andrew.svg?size=50)
[https://basescan.org](https://basescan.org)
[https://blastscan.io](https://blastscan.io)
[https://block-explorer-api.mainnet.zksync.io/api](https://block-explorer-api.mainnet.zksync.io/api)
[https://bobascan.com](https://bobascan.com)
[https://bscscan.com](https://bscscan.com)
[https://build.onbeam.com/rpc](https://build.onbeam.com/rpc)
[https://celoscan.io](https://celoscan.io)
[https://cloudflare-eth.com](https://cloudflare-eth.com)
[https://docs.cloud.coinbase.com/wallet-sdk/docs/errors](https://docs.cloud.coinbase.com/wallet-sdk/docs/errors)
[https://docs.soliditylang.org/en/latest/cheatsheet.html](https://docs.soliditylang.org/en/latest/cheatsheet.html)
[https://echo.walletconnect.com/](https://echo.walletconnect.com/)
[https://era.zksync.network/](https://era.zksync.network/)
[https://ethereum.org/en/developers/docs/networks/](https://ethereum.org/en/developers/docs/networks/)
[https://etherscan.io](https://etherscan.io)
[https://evm.cronos.org](https://evm.cronos.org)
[https://evm.kava.io](https://evm.kava.io)
[https://exchainrpc.okex.org](https://exchainrpc.okex.org)
[https://explorer-api.cronos.org/mainnet/api](https://explorer-api.cronos.org/mainnet/api)
[https://explorer-api.walletconnect.com](https://explorer-api.walletconnect.com)
[https://explorer.cronos.org](https://explorer.cronos.org)
[https://explorer.dogechain.dog/api](https://explorer.dogechain.dog/api)
[https://explorer.fuse.io/api](https://explorer.fuse.io/api)
[https://explorer.harmony.one](https://explorer.harmony.one)
[https://explorer.kcc.io](https://explorer.kcc.io)
[https://explorer.metis.io](https://explorer.metis.io)
[https://explorer.walletconnect.com/?type=wallet](https://explorer.walletconnect.com/?type=wallet)
[https://explorer.zksync.io/](https://explorer.zksync.io/)
[https://fonts.googleapis.com/css2?family=Inter](https://fonts.googleapis.com/css2?family=Inter)
[https://forno.celo.org](https://forno.celo.org)
[https://ftmscan.com](https://ftmscan.com)
[https://gnosisscan.io](https://gnosisscan.io)
[https://go.cb-w.com/dapp?cb_url=](https://go.cb-w.com/dapp?cb_url=)
[https://go.cb-w.com/walletlink](https://go.cb-w.com/walletlink)
[https://kavascan.com/api](https://kavascan.com/api)
[https://kcc-rpc.com](https://kcc-rpc.com)
[https://keys.coinbase.com/connect](https://keys.coinbase.com/connect)
[https://lineascan.build](https://lineascan.build)
[https://links.ethers.org/v5-errors-](https://links.ethers.org/v5-errors-)
[https://mainnet.aurora.dev](https://mainnet.aurora.dev)
[https://mainnet.base.org](https://mainnet.base.org)
[https://mainnet.boba.network](https://mainnet.boba.network)
[https://mainnet.era.zksync.io](https://mainnet.era.zksync.io)
[https://mainnet.optimism.io](https://mainnet.optimism.io)
[https://mantlescan.xyz/](https://mantlescan.xyz/)
[https://moonbeam.public.blastapi.io](https://moonbeam.public.blastapi.io)
[https://moonriver.moonscan.io](https://moonriver.moonscan.io)
[https://moonriver.public.blastapi.io](https://moonriver.public.blastapi.io)
[https://moonscan.io](https://moonscan.io)
[https://npms.io/search?q=ponyfill.](https://npms.io/search?q=ponyfill.)
[https://openchain.xyz/signatures?query=](https://openchain.xyz/signatures?query=)
[https://optimistic.etherscan.io](https://optimistic.etherscan.io)
[https://polygon-rpc.com](https://polygon-rpc.com)
[https://polygonscan.com](https://polygonscan.com)
[https://pulse.walletconnect.org](https://pulse.walletconnect.org)
[https://reactjs.org/docs/error-decoder.html?invariant=](https://reactjs.org/docs/error-decoder.html?invariant=)
[https://rpc.ankr.com/bsc](https://rpc.ankr.com/bsc)
[https://rpc.ankr.com/fantom](https://rpc.ankr.com/fantom)
[https://rpc.ankr.com/harmony](https://rpc.ankr.com/harmony)
[https://rpc.blast.io](https://rpc.blast.io)
[https://rpc.dogechain.dog](https://rpc.dogechain.dog)
[https://rpc.fuse.io](https://rpc.fuse.io)
[https://rpc.gnosischain.com](https://rpc.gnosischain.com)
[https://rpc.linea.build](https://rpc.linea.build)
[https://rpc.mantle.xyz](https://rpc.mantle.xyz)
[https://rpc.pulsechain.com](https://rpc.pulsechain.com)
[https://rpc.scroll.io](https://rpc.scroll.io)
[https://rpc.walletconnect.com/v1/?chainId=eip155](https://rpc.walletconnect.com/v1/?chainId=eip155)
[https://rpc.walletconnect.org](https://rpc.walletconnect.org)
[https://safe-client.safe.global](https://safe-client.safe.global)
[https://scan.pulsechain.com](https://scan.pulsechain.com)
[https://scrollscan.com](https://scrollscan.com)
[https://secure.walletconnect.org/sdk](https://secure.walletconnect.org/sdk)
[https://snowtrace.io](https://snowtrace.io)
[https://subnets.avax.network/beam](https://subnets.avax.network/beam)
[https://verify.walletconnect.com](https://verify.walletconnect.com)
[https://verify.walletconnect.org](https://verify.walletconnect.org)
[https://wagmi.sh/core](https://wagmi.sh/core)
[https://wagmi.sh/react](https://wagmi.sh/react)
[https://walletconnect.com/explorer?type=wallet](https://walletconnect.com/explorer?type=wallet)
[https://walletconnect.com/faq](https://walletconnect.com/faq)
[https://www.jsdelivr.com/using-sri-with-dynamic-files](https://www.jsdelivr.com/using-sri-with-dynamic-files)
[https://www.oklink.com/okc](https://www.oklink.com/okc)
[https://www.walletlink.org](https://www.walletlink.org)
[https://zkevm-rpc.com](https://zkevm-rpc.com)
[https://zkevm.polygonscan.com](https://zkevm.polygonscan.com) | +| LOW | [net/url/parse](https://github.com/chainguard-dev/malcontent/blob/main/rules/net/url/parse.yara#url_handle) | Handles URL strings | [new URL](https://github.com/search?q=new+URL&type=code) | + diff --git a/tests/linux/2023.FreeDownloadManager/freedownloadmanager.sdiff b/tests/linux/2023.FreeDownloadManager/freedownloadmanager.sdiff index cf673d234..e0327f1fd 100644 --- a/tests/linux/2023.FreeDownloadManager/freedownloadmanager.sdiff +++ b/tests/linux/2023.FreeDownloadManager/freedownloadmanager.sdiff @@ -1,12 +1,4 @@ ---- missing: freedownloadmanager_clear_postinst --data/embedded/pgp_key --exec/install_additional/add_apt_key --exec/shell/ignore_output --fs/path/etc --fs/path/usr_bin --net/download --net/url/embedded -++++ added: freedownloadmanager_infected_postinst +*** changed: linux/2023.FreeDownloadManager/freedownloadmanager_infected_postinst +3P/threat_hunting/touch +anti-static/base64/exec +anti-static/base64/http_agent @@ -14,24 +6,24 @@ +data/embedded/base64_elf +data/embedded/base64_terms +data/embedded/base64_url -+data/embedded/pgp_key +data/embedded/pgp_key +data/encoding/base64 +evasion/file/location/var_tmp -+exec/install_additional/add_apt_key +exec/install_additional/add_apt_key +exec/shell/exec -+exec/shell/ignore_output +exec/shell/ignore_output +fs/directory/create +fs/file/delete_forcibly +fs/file/make_executable +fs/file/times_set -+fs/path/etc +fs/path/etc +fs/path/tmp -+fs/path/usr_bin +fs/path/usr_bin +fs/path/var +fs/permission/modify +impact/remote_access/botnet -+net/download -+net/url/embedded +net/download +net/url/embedded +persist/cron/etc_d +persist/cron/tab +sus/geopolitics diff --git a/tests/linux/2024.sbcl.market/sbcl.sdiff b/tests/linux/2024.sbcl.market/sbcl.sdiff index 2ef508139..6a7704720 100644 --- a/tests/linux/2024.sbcl.market/sbcl.sdiff +++ b/tests/linux/2024.sbcl.market/sbcl.sdiff @@ -1,44 +1,24 @@ ---- missing: sbcl.clean --crypto/rc4 --data/compression/zstd --discover/user/HOME --discover/user/USER --evasion/file/location/var_tmp --exec/dylib/address_check --exec/dylib/symbol_address --exec/program --exec/program/background --exec/shell/echo --fs/file/delete --fs/file/truncate --fs/link_read --fs/path/dev --fs/path/tmp --fs/path/var --fs/permission/modify --fs/proc/self_exe --fs/symlink_resolve --net/url/embedded -++++ added: sbcl.dirty +*** changed: linux/2024.sbcl.market/sbcl.dirty +anti-static/elf/entropy -+data/compression/zstd +-crypto/rc4 +data/compression/zstd +data/embedded/zstd -+discover/user/HOME -+discover/user/USER -+evasion/file/location/var_tmp -+exec/dylib/address_check -+exec/dylib/symbol_address -+exec/program -+exec/program/background -+exec/shell/echo -+fs/file/delete -+fs/file/truncate -+fs/link_read -+fs/path/dev -+fs/path/tmp -+fs/path/var -+fs/permission/modify -+fs/proc/self_exe -+fs/symlink_resolve +discover/user/HOME +discover/user/USER +evasion/file/location/var_tmp +exec/dylib/address_check +exec/dylib/symbol_address +exec/program +exec/program/background +exec/shell/echo +fs/file/delete +fs/file/truncate +fs/link_read +fs/path/dev +fs/path/tmp +fs/path/var +fs/permission/modify +fs/proc/self_exe +fs/symlink_resolve +net/dns/txt -+net/url/embedded +net/url/embedded diff --git a/tests/linux/clean/aws-c-io/aws-c-io.sdiff b/tests/linux/clean/aws-c-io/aws-c-io.sdiff index 1a0be2922..b183c2eda 100644 --- a/tests/linux/clean/aws-c-io/aws-c-io.sdiff +++ b/tests/linux/clean/aws-c-io/aws-c-io.sdiff @@ -1 +1,3 @@ ->>> moved: linux/clean/aws-c-io/aws-c-io-0.14.10-r0.spdx.json -> linux/clean/aws-c-io/aws-c-io-0.14.11-r0.spdx.json (score: 0.979310) +>>> moved: linux/clean/aws-c-io/aws-c-io-0.14.10-r0.spdx.json -> linux/clean/aws-c-io/aws-c-io-0.14.11-r0.spdx.json (score: 0.988000) +net/download +net/url/embedded diff --git a/tests/macOS/2023.3CX/libffmpeg.change_decrease.mdiff b/tests/macOS/2023.3CX/libffmpeg.change_decrease.mdiff index bef727d5f..22f124ca8 100644 Binary files a/tests/macOS/2023.3CX/libffmpeg.change_decrease.mdiff and b/tests/macOS/2023.3CX/libffmpeg.change_decrease.mdiff differ diff --git a/tests/macOS/2023.3CX/libffmpeg.change_increase.mdiff b/tests/macOS/2023.3CX/libffmpeg.change_increase.mdiff index 8d90c3b3f..7329a7bd6 100644 Binary files a/tests/macOS/2023.3CX/libffmpeg.change_increase.mdiff and b/tests/macOS/2023.3CX/libffmpeg.change_increase.mdiff differ diff --git a/tests/macOS/2023.3CX/libffmpeg.change_unrelated.mdiff b/tests/macOS/2023.3CX/libffmpeg.change_unrelated.mdiff index fa19b7c49..24baa8424 100644 --- a/tests/macOS/2023.3CX/libffmpeg.change_unrelated.mdiff +++ b/tests/macOS/2023.3CX/libffmpeg.change_unrelated.mdiff @@ -1,24 +1,30 @@ -## Deleted: libffmpeg.dylib [🟡 MEDIUM] +## Changed: macOS/clean/ls [🟡 MEDIUM → 🔵 LOW] -| RISK | KEY | DESCRIPTION | EVIDENCE | -|---------|------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------| -| -MEDIUM | [data/base64/decode](https://github.com/chainguard-dev/malcontent/blob/main/rules/data/base64/base64-decode.yara#py_base64_decode) | decode base64 strings | [base64_decode](https://github.com/search?q=base64_decode&type=code) | -| -MEDIUM | [fs/path/tmp](https://github.com/chainguard-dev/malcontent/blob/main/rules/fs/path/tmp.yara#tmp_path) | path reference within /tmp | [/tmp/%sXXXXXX](https://github.com/search?q=%2Ftmp%2F%25sXXXXXX&type=code) | -| -MEDIUM | [impact/remote_access/agent](https://github.com/chainguard-dev/malcontent/blob/main/rules/impact/remote_access/agent.yara#agent) | references an 'agent' | [user_agent](https://github.com/search?q=user_agent&type=code) | -| -MEDIUM | [net/http/post](https://github.com/chainguard-dev/malcontent/blob/main/rules/net/http/post.yara#http_post) | submits content to websites | [HTTP](https://github.com/search?q=HTTP&type=code)
[POST](https://github.com/search?q=POST&type=code)
[http](https://github.com/search?q=http&type=code) | -| -LOW | [crypto/aes](https://github.com/chainguard-dev/malcontent/blob/main/rules/crypto/aes.yara#crypto_aes) | Supports AES (Advanced Encryption Standard) | [AES](https://github.com/search?q=AES&type=code) | -| -LOW | [crypto/rc4](https://github.com/chainguard-dev/malcontent/blob/main/rules/crypto/rc4.yara#rc4_ksa) | RC4 key scheduling algorithm, by Thomas Barabosch | $cmp_e_x_256
$cmp_r_x_256 | -| -LOW | [data/encoding/base64](https://github.com/chainguard-dev/malcontent/blob/main/rules/data/encoding/base64.yara#b64) | Supports base64 encoded strings | [base64](https://github.com/search?q=base64&type=code) | -| -LOW | [exec/shell/TERM](https://github.com/chainguard-dev/malcontent/blob/main/rules/exec/shell/TERM.yara#TERM) | [Look up or override terminal settings](https://www.gnu.org/software/gettext/manual/html_node/The-TERM-variable.html) | [TERM](https://github.com/search?q=TERM&type=code) | -| -LOW | [fs/directory/create](https://github.com/chainguard-dev/malcontent/blob/main/rules/fs/directory/directory-create.yara#mkdir) | [creates directories](https://man7.org/linux/man-pages/man2/mkdir.2.html) | [mkdir](https://github.com/search?q=mkdir&type=code) | -| -LOW | [net/url/parse](https://github.com/chainguard-dev/malcontent/blob/main/rules/net/url/parse.yara#url_handle) | Handles URL strings | [URLContext](https://github.com/search?q=URLContext&type=code) | -| -LOW | [process/multithreaded](https://github.com/chainguard-dev/malcontent/blob/main/rules/process/multithreaded.yara#pthread_create) | [creates pthreads](https://man7.org/linux/man-pages/man3/pthread_create.3.html) | [pthread_create](https://github.com/search?q=pthread_create&type=code) | +### 2 new behaviors -## Added: ls [🔵 LOW] +| RISK | KEY | DESCRIPTION | EVIDENCE | +|------|------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| +LOW | **[fs/directory/traverse](https://github.com/chainguard-dev/malcontent/blob/main/rules/fs/directory/directory-traverse.yara#fts)** | traverse filesystem hierarchy | [_fts_children](https://github.com/search?q=_fts_children&type=code)
[_fts_close](https://github.com/search?q=_fts_close&type=code)
[_fts_open](https://github.com/search?q=_fts_open&type=code)
[_fts_read](https://github.com/search?q=_fts_read&type=code)
[_fts_set](https://github.com/search?q=_fts_set&type=code) | +| +LOW | **[fs/link_read](https://github.com/chainguard-dev/malcontent/blob/main/rules/fs/link-read.yara#readlink)** | [read value of a symbolic link](https://man7.org/linux/man-pages/man2/readlink.2.html) | [readlink](https://github.com/search?q=readlink&type=code) | -| RISK | KEY | DESCRIPTION | EVIDENCE | -|------|------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| +LOW | **[exec/shell/TERM](https://github.com/chainguard-dev/malcontent/blob/main/rules/exec/shell/TERM.yara#TERM)** | [Look up or override terminal settings](https://www.gnu.org/software/gettext/manual/html_node/The-TERM-variable.html) | [TERM](https://github.com/search?q=TERM&type=code) | -| +LOW | **[fs/directory/traverse](https://github.com/chainguard-dev/malcontent/blob/main/rules/fs/directory/directory-traverse.yara#fts)** | traverse filesystem hierarchy | [_fts_children](https://github.com/search?q=_fts_children&type=code)
[_fts_close](https://github.com/search?q=_fts_close&type=code)
[_fts_open](https://github.com/search?q=_fts_open&type=code)
[_fts_read](https://github.com/search?q=_fts_read&type=code)
[_fts_set](https://github.com/search?q=_fts_set&type=code) | -| +LOW | **[fs/link_read](https://github.com/chainguard-dev/malcontent/blob/main/rules/fs/link-read.yara#readlink)** | [read value of a symbolic link](https://man7.org/linux/man-pages/man2/readlink.2.html) | [readlink](https://github.com/search?q=readlink&type=code) | +### 10 removed behaviors + +| RISK | KEY | DESCRIPTION | EVIDENCE | +|---------|------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------| +| -MEDIUM | [data/base64/decode](https://github.com/chainguard-dev/malcontent/blob/main/rules/data/base64/base64-decode.yara#py_base64_decode) | decode base64 strings | [base64_decode](https://github.com/search?q=base64_decode&type=code) | +| -MEDIUM | [fs/path/tmp](https://github.com/chainguard-dev/malcontent/blob/main/rules/fs/path/tmp.yara#tmp_path) | path reference within /tmp | [/tmp/%sXXXXXX](https://github.com/search?q=%2Ftmp%2F%25sXXXXXX&type=code) | +| -MEDIUM | [impact/remote_access/agent](https://github.com/chainguard-dev/malcontent/blob/main/rules/impact/remote_access/agent.yara#agent) | references an 'agent' | [user_agent](https://github.com/search?q=user_agent&type=code) | +| -MEDIUM | [net/http/post](https://github.com/chainguard-dev/malcontent/blob/main/rules/net/http/post.yara#http_post) | submits content to websites | [HTTP](https://github.com/search?q=HTTP&type=code)
[POST](https://github.com/search?q=POST&type=code)
[http](https://github.com/search?q=http&type=code) | +| -LOW | [crypto/aes](https://github.com/chainguard-dev/malcontent/blob/main/rules/crypto/aes.yara#crypto_aes) | Supports AES (Advanced Encryption Standard) | [AES](https://github.com/search?q=AES&type=code) | +| -LOW | [crypto/rc4](https://github.com/chainguard-dev/malcontent/blob/main/rules/crypto/rc4.yara#rc4_ksa) | RC4 key scheduling algorithm, by Thomas Barabosch | $cmp_e_x_256
$cmp_r_x_256 | +| -LOW | [data/encoding/base64](https://github.com/chainguard-dev/malcontent/blob/main/rules/data/encoding/base64.yara#b64) | Supports base64 encoded strings | [base64](https://github.com/search?q=base64&type=code) | +| -LOW | [fs/directory/create](https://github.com/chainguard-dev/malcontent/blob/main/rules/fs/directory/directory-create.yara#mkdir) | [creates directories](https://man7.org/linux/man-pages/man2/mkdir.2.html) | [mkdir](https://github.com/search?q=mkdir&type=code) | +| -LOW | [net/url/parse](https://github.com/chainguard-dev/malcontent/blob/main/rules/net/url/parse.yara#url_handle) | Handles URL strings | [URLContext](https://github.com/search?q=URLContext&type=code) | +| -LOW | [process/multithreaded](https://github.com/chainguard-dev/malcontent/blob/main/rules/process/multithreaded.yara#pthread_create) | [creates pthreads](https://man7.org/linux/man-pages/man3/pthread_create.3.html) | [pthread_create](https://github.com/search?q=pthread_create&type=code) | + +### 1 consistent behavior + +| RISK | KEY | DESCRIPTION | EVIDENCE | +|------|-----------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------|----------------------------------------------------| +| LOW | [exec/shell/TERM](https://github.com/chainguard-dev/malcontent/blob/main/rules/exec/shell/TERM.yara#TERM) | [Look up or override terminal settings](https://www.gnu.org/software/gettext/manual/html_node/The-TERM-variable.html) | [TERM](https://github.com/search?q=TERM&type=code) | diff --git a/tests/macOS/2023.3CX/libffmpeg.decrease.mdiff b/tests/macOS/2023.3CX/libffmpeg.decrease.mdiff index bef727d5f..e69de29bb 100644 Binary files a/tests/macOS/2023.3CX/libffmpeg.decrease.mdiff and b/tests/macOS/2023.3CX/libffmpeg.decrease.mdiff differ diff --git a/tests/macOS/2023.3CX/libffmpeg.dirty.mdiff b/tests/macOS/2023.3CX/libffmpeg.dirty.mdiff index 8d90c3b3f..7329a7bd6 100644 Binary files a/tests/macOS/2023.3CX/libffmpeg.dirty.mdiff and b/tests/macOS/2023.3CX/libffmpeg.dirty.mdiff differ diff --git a/tests/macOS/2023.3CX/libffmpeg.increase.mdiff b/tests/macOS/2023.3CX/libffmpeg.increase.mdiff index 8d90c3b3f..7329a7bd6 100644 Binary files a/tests/macOS/2023.3CX/libffmpeg.increase.mdiff and b/tests/macOS/2023.3CX/libffmpeg.increase.mdiff differ diff --git a/tests/macOS/2023.3CX/libffmpeg.increase_unrelated.mdiff b/tests/macOS/2023.3CX/libffmpeg.increase_unrelated.mdiff index c30dcb38e..2fac11c65 100644 --- a/tests/macOS/2023.3CX/libffmpeg.increase_unrelated.mdiff +++ b/tests/macOS/2023.3CX/libffmpeg.increase_unrelated.mdiff @@ -1,24 +1,30 @@ -## Deleted: ls [🔵 LOW] +## Changed: macOS/2023.3CX/libffmpeg.dylib [🔵 LOW → 🟡 MEDIUM] -| RISK | KEY | DESCRIPTION | EVIDENCE | -|------|--------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| -LOW | [exec/shell/TERM](https://github.com/chainguard-dev/malcontent/blob/main/rules/exec/shell/TERM.yara#TERM) | [Look up or override terminal settings](https://www.gnu.org/software/gettext/manual/html_node/The-TERM-variable.html) | [TERM](https://github.com/search?q=TERM&type=code) | -| -LOW | [fs/directory/traverse](https://github.com/chainguard-dev/malcontent/blob/main/rules/fs/directory/directory-traverse.yara#fts) | traverse filesystem hierarchy | [_fts_children](https://github.com/search?q=_fts_children&type=code)
[_fts_close](https://github.com/search?q=_fts_close&type=code)
[_fts_open](https://github.com/search?q=_fts_open&type=code)
[_fts_read](https://github.com/search?q=_fts_read&type=code)
[_fts_set](https://github.com/search?q=_fts_set&type=code) | -| -LOW | [fs/link_read](https://github.com/chainguard-dev/malcontent/blob/main/rules/fs/link-read.yara#readlink) | [read value of a symbolic link](https://man7.org/linux/man-pages/man2/readlink.2.html) | [readlink](https://github.com/search?q=readlink&type=code) | +### 10 new behaviors -## Added: libffmpeg.dylib [🟡 MEDIUM] +| RISK | KEY | DESCRIPTION | EVIDENCE | +|---------|----------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------| +| +MEDIUM | **[data/base64/decode](https://github.com/chainguard-dev/malcontent/blob/main/rules/data/base64/base64-decode.yara#py_base64_decode)** | decode base64 strings | [base64_decode](https://github.com/search?q=base64_decode&type=code) | +| +MEDIUM | **[fs/path/tmp](https://github.com/chainguard-dev/malcontent/blob/main/rules/fs/path/tmp.yara#tmp_path)** | path reference within /tmp | [/tmp/%sXXXXXX](https://github.com/search?q=%2Ftmp%2F%25sXXXXXX&type=code) | +| +MEDIUM | **[impact/remote_access/agent](https://github.com/chainguard-dev/malcontent/blob/main/rules/impact/remote_access/agent.yara#agent)** | references an 'agent' | [user_agent](https://github.com/search?q=user_agent&type=code) | +| +MEDIUM | **[net/http/post](https://github.com/chainguard-dev/malcontent/blob/main/rules/net/http/post.yara#http_post)** | submits content to websites | [HTTP](https://github.com/search?q=HTTP&type=code)
[POST](https://github.com/search?q=POST&type=code)
[http](https://github.com/search?q=http&type=code) | +| +LOW | **[crypto/aes](https://github.com/chainguard-dev/malcontent/blob/main/rules/crypto/aes.yara#crypto_aes)** | Supports AES (Advanced Encryption Standard) | [AES](https://github.com/search?q=AES&type=code) | +| +LOW | **[crypto/rc4](https://github.com/chainguard-dev/malcontent/blob/main/rules/crypto/rc4.yara#rc4_ksa)** | RC4 key scheduling algorithm, by Thomas Barabosch | $cmp_e_x_256
$cmp_r_x_256 | +| +LOW | **[data/encoding/base64](https://github.com/chainguard-dev/malcontent/blob/main/rules/data/encoding/base64.yara#b64)** | Supports base64 encoded strings | [base64](https://github.com/search?q=base64&type=code) | +| +LOW | **[fs/directory/create](https://github.com/chainguard-dev/malcontent/blob/main/rules/fs/directory/directory-create.yara#mkdir)** | [creates directories](https://man7.org/linux/man-pages/man2/mkdir.2.html) | [mkdir](https://github.com/search?q=mkdir&type=code) | +| +LOW | **[net/url/parse](https://github.com/chainguard-dev/malcontent/blob/main/rules/net/url/parse.yara#url_handle)** | Handles URL strings | [URLContext](https://github.com/search?q=URLContext&type=code) | +| +LOW | **[process/multithreaded](https://github.com/chainguard-dev/malcontent/blob/main/rules/process/multithreaded.yara#pthread_create)** | [creates pthreads](https://man7.org/linux/man-pages/man3/pthread_create.3.html) | [pthread_create](https://github.com/search?q=pthread_create&type=code) | -| RISK | KEY | DESCRIPTION | EVIDENCE | -|---------|----------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------| -| +MEDIUM | **[data/base64/decode](https://github.com/chainguard-dev/malcontent/blob/main/rules/data/base64/base64-decode.yara#py_base64_decode)** | decode base64 strings | [base64_decode](https://github.com/search?q=base64_decode&type=code) | -| +MEDIUM | **[fs/path/tmp](https://github.com/chainguard-dev/malcontent/blob/main/rules/fs/path/tmp.yara#tmp_path)** | path reference within /tmp | [/tmp/%sXXXXXX](https://github.com/search?q=%2Ftmp%2F%25sXXXXXX&type=code) | -| +MEDIUM | **[impact/remote_access/agent](https://github.com/chainguard-dev/malcontent/blob/main/rules/impact/remote_access/agent.yara#agent)** | references an 'agent' | [user_agent](https://github.com/search?q=user_agent&type=code) | -| +MEDIUM | **[net/http/post](https://github.com/chainguard-dev/malcontent/blob/main/rules/net/http/post.yara#http_post)** | submits content to websites | [HTTP](https://github.com/search?q=HTTP&type=code)
[POST](https://github.com/search?q=POST&type=code)
[http](https://github.com/search?q=http&type=code) | -| +LOW | **[crypto/aes](https://github.com/chainguard-dev/malcontent/blob/main/rules/crypto/aes.yara#crypto_aes)** | Supports AES (Advanced Encryption Standard) | [AES](https://github.com/search?q=AES&type=code) | -| +LOW | **[crypto/rc4](https://github.com/chainguard-dev/malcontent/blob/main/rules/crypto/rc4.yara#rc4_ksa)** | RC4 key scheduling algorithm, by Thomas Barabosch | $cmp_e_x_256
$cmp_r_x_256 | -| +LOW | **[data/encoding/base64](https://github.com/chainguard-dev/malcontent/blob/main/rules/data/encoding/base64.yara#b64)** | Supports base64 encoded strings | [base64](https://github.com/search?q=base64&type=code) | -| +LOW | **[exec/shell/TERM](https://github.com/chainguard-dev/malcontent/blob/main/rules/exec/shell/TERM.yara#TERM)** | [Look up or override terminal settings](https://www.gnu.org/software/gettext/manual/html_node/The-TERM-variable.html) | [TERM](https://github.com/search?q=TERM&type=code) | -| +LOW | **[fs/directory/create](https://github.com/chainguard-dev/malcontent/blob/main/rules/fs/directory/directory-create.yara#mkdir)** | [creates directories](https://man7.org/linux/man-pages/man2/mkdir.2.html) | [mkdir](https://github.com/search?q=mkdir&type=code) | -| +LOW | **[net/url/parse](https://github.com/chainguard-dev/malcontent/blob/main/rules/net/url/parse.yara#url_handle)** | Handles URL strings | [URLContext](https://github.com/search?q=URLContext&type=code) | -| +LOW | **[process/multithreaded](https://github.com/chainguard-dev/malcontent/blob/main/rules/process/multithreaded.yara#pthread_create)** | [creates pthreads](https://man7.org/linux/man-pages/man3/pthread_create.3.html) | [pthread_create](https://github.com/search?q=pthread_create&type=code) | +### 2 removed behaviors + +| RISK | KEY | DESCRIPTION | EVIDENCE | +|------|--------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| -LOW | [fs/directory/traverse](https://github.com/chainguard-dev/malcontent/blob/main/rules/fs/directory/directory-traverse.yara#fts) | traverse filesystem hierarchy | [_fts_children](https://github.com/search?q=_fts_children&type=code)
[_fts_close](https://github.com/search?q=_fts_close&type=code)
[_fts_open](https://github.com/search?q=_fts_open&type=code)
[_fts_read](https://github.com/search?q=_fts_read&type=code)
[_fts_set](https://github.com/search?q=_fts_set&type=code) | +| -LOW | [fs/link_read](https://github.com/chainguard-dev/malcontent/blob/main/rules/fs/link-read.yara#readlink) | [read value of a symbolic link](https://man7.org/linux/man-pages/man2/readlink.2.html) | [readlink](https://github.com/search?q=readlink&type=code) | + +### 1 consistent behavior + +| RISK | KEY | DESCRIPTION | EVIDENCE | +|------|-----------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------|----------------------------------------------------| +| LOW | [exec/shell/TERM](https://github.com/chainguard-dev/malcontent/blob/main/rules/exec/shell/TERM.yara#TERM) | [Look up or override terminal settings](https://www.gnu.org/software/gettext/manual/html_node/The-TERM-variable.html) | [TERM](https://github.com/search?q=TERM&type=code) | diff --git a/tests/macOS/clean/ls.mdiff b/tests/macOS/clean/ls.mdiff index 523345be4..fd6b24bc3 100644 --- a/tests/macOS/clean/ls.mdiff +++ b/tests/macOS/clean/ls.mdiff @@ -1,19 +1,24 @@ -## Deleted: ls.x86_64 [🟡 MEDIUM] +## Changed: macOS/clean/ls [🟡 MEDIUM → 🔵 LOW] -| RISK | KEY | DESCRIPTION | EVIDENCE | -|---------|------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| -MEDIUM | [process/name_set](https://github.com/chainguard-dev/malcontent/blob/main/rules/process/name-set.yara#__progname) | [get or set the current process name](https://stackoverflow.com/questions/273691/using-progname-instead-of-argv0) | [__progname](https://github.com/search?q=__progname&type=code) | -| -LOW | [data/compression/lzma](https://github.com/chainguard-dev/malcontent/blob/main/rules/data/compression/lzma.yara#gzip) | [works with lzma files](https://en.wikipedia.org/wiki/Lempel%E2%80%93Ziv%E2%80%93Markov_chain_algorithm) | [lzma](https://github.com/search?q=lzma&type=code) | -| -LOW | [discover/system/hostname](https://github.com/chainguard-dev/malcontent/blob/main/rules/discover/system/hostname.yara#gethostname) | [get computer host name](https://man7.org/linux/man-pages/man2/sethostname.2.html) | [gethostname](https://github.com/search?q=gethostname&type=code) | -| -LOW | [exec/shell/TERM](https://github.com/chainguard-dev/malcontent/blob/main/rules/exec/shell/TERM.yara#TERM) | [Look up or override terminal settings](https://www.gnu.org/software/gettext/manual/html_node/The-TERM-variable.html) | [TERM](https://github.com/search?q=TERM&type=code) | -| -LOW | [fs/link_read](https://github.com/chainguard-dev/malcontent/blob/main/rules/fs/link-read.yara#readlink) | [read value of a symbolic link](https://man7.org/linux/man-pages/man2/readlink.2.html) | [readlink](https://github.com/search?q=readlink&type=code) | -| -LOW | [net/url/embedded](https://github.com/chainguard-dev/malcontent/blob/main/rules/net/url/embedded.yara#https_url) | contains embedded HTTPS URLs | [https://gnu.org/licenses/gpl.html](https://gnu.org/licenses/gpl.html)
[https://translationproject.org/team/](https://translationproject.org/team/)
[https://wiki.xiph.org/MIME_Types_and_File_Extensions](https://wiki.xiph.org/MIME_Types_and_File_Extensions)
[https://www.gnu.org/software/coreutils/](https://www.gnu.org/software/coreutils/) | +### 1 new behavior -## Added: ls [🔵 LOW] +| RISK | KEY | DESCRIPTION | EVIDENCE | +|------|------------------------------------------------------------------------------------------------------------------------------------|-------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| +LOW | **[fs/directory/traverse](https://github.com/chainguard-dev/malcontent/blob/main/rules/fs/directory/directory-traverse.yara#fts)** | traverse filesystem hierarchy | [_fts_children](https://github.com/search?q=_fts_children&type=code)
[_fts_close](https://github.com/search?q=_fts_close&type=code)
[_fts_open](https://github.com/search?q=_fts_open&type=code)
[_fts_read](https://github.com/search?q=_fts_read&type=code)
[_fts_set](https://github.com/search?q=_fts_set&type=code) | -| RISK | KEY | DESCRIPTION | EVIDENCE | -|------|------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| +LOW | **[exec/shell/TERM](https://github.com/chainguard-dev/malcontent/blob/main/rules/exec/shell/TERM.yara#TERM)** | [Look up or override terminal settings](https://www.gnu.org/software/gettext/manual/html_node/The-TERM-variable.html) | [TERM](https://github.com/search?q=TERM&type=code) | -| +LOW | **[fs/directory/traverse](https://github.com/chainguard-dev/malcontent/blob/main/rules/fs/directory/directory-traverse.yara#fts)** | traverse filesystem hierarchy | [_fts_children](https://github.com/search?q=_fts_children&type=code)
[_fts_close](https://github.com/search?q=_fts_close&type=code)
[_fts_open](https://github.com/search?q=_fts_open&type=code)
[_fts_read](https://github.com/search?q=_fts_read&type=code)
[_fts_set](https://github.com/search?q=_fts_set&type=code) | -| +LOW | **[fs/link_read](https://github.com/chainguard-dev/malcontent/blob/main/rules/fs/link-read.yara#readlink)** | [read value of a symbolic link](https://man7.org/linux/man-pages/man2/readlink.2.html) | [readlink](https://github.com/search?q=readlink&type=code) | +### 4 removed behaviors + +| RISK | KEY | DESCRIPTION | EVIDENCE | +|---------|------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| -MEDIUM | [process/name_set](https://github.com/chainguard-dev/malcontent/blob/main/rules/process/name-set.yara#__progname) | [get or set the current process name](https://stackoverflow.com/questions/273691/using-progname-instead-of-argv0) | [__progname](https://github.com/search?q=__progname&type=code) | +| -LOW | [data/compression/lzma](https://github.com/chainguard-dev/malcontent/blob/main/rules/data/compression/lzma.yara#gzip) | [works with lzma files](https://en.wikipedia.org/wiki/Lempel%E2%80%93Ziv%E2%80%93Markov_chain_algorithm) | [lzma](https://github.com/search?q=lzma&type=code) | +| -LOW | [discover/system/hostname](https://github.com/chainguard-dev/malcontent/blob/main/rules/discover/system/hostname.yara#gethostname) | [get computer host name](https://man7.org/linux/man-pages/man2/sethostname.2.html) | [gethostname](https://github.com/search?q=gethostname&type=code) | +| -LOW | [net/url/embedded](https://github.com/chainguard-dev/malcontent/blob/main/rules/net/url/embedded.yara#https_url) | contains embedded HTTPS URLs | [https://gnu.org/licenses/gpl.html](https://gnu.org/licenses/gpl.html)
[https://translationproject.org/team/](https://translationproject.org/team/)
[https://wiki.xiph.org/MIME_Types_and_File_Extensions](https://wiki.xiph.org/MIME_Types_and_File_Extensions)
[https://www.gnu.org/software/coreutils/](https://www.gnu.org/software/coreutils/) | + +### 2 consistent behaviors + +| RISK | KEY | DESCRIPTION | EVIDENCE | +|------|-----------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------| +| LOW | [exec/shell/TERM](https://github.com/chainguard-dev/malcontent/blob/main/rules/exec/shell/TERM.yara#TERM) | [Look up or override terminal settings](https://www.gnu.org/software/gettext/manual/html_node/The-TERM-variable.html) | [TERM](https://github.com/search?q=TERM&type=code) | +| LOW | [fs/link_read](https://github.com/chainguard-dev/malcontent/blob/main/rules/fs/link-read.yara#readlink) | [read value of a symbolic link](https://man7.org/linux/man-pages/man2/readlink.2.html) | [readlink](https://github.com/search?q=readlink&type=code) | diff --git a/tests/macOS/clean/ls.sdiff.level_2 b/tests/macOS/clean/ls.sdiff.level_2 index fa0ab56fa..db7b91c5d 100644 --- a/tests/macOS/clean/ls.sdiff.level_2 +++ b/tests/macOS/clean/ls.sdiff.level_2 @@ -1,3 +1,2 @@ ---- missing: ls.x86_64 +*** changed: macOS/clean/ls -process/name_set -++++ added: ls diff --git a/tests/macOS/clean/ls.sdiff.trigger_2 b/tests/macOS/clean/ls.sdiff.trigger_2 index 902593b69..67fb0230f 100644 --- a/tests/macOS/clean/ls.sdiff.trigger_2 +++ b/tests/macOS/clean/ls.sdiff.trigger_2 @@ -1,11 +1,8 @@ ---- missing: ls.x86_64 +*** changed: macOS/clean/ls -data/compression/lzma -discover/system/hostname --exec/shell/TERM --fs/link_read +exec/shell/TERM ++fs/directory/traverse +fs/link_read -net/url/embedded -process/name_set -++++ added: ls -+exec/shell/TERM -+fs/directory/traverse -+fs/link_read diff --git a/tests/macOS/clean/ls.sdiff.trigger_3 b/tests/macOS/clean/ls.sdiff.trigger_3 index 902593b69..e69de29bb 100644 --- a/tests/macOS/clean/ls.sdiff.trigger_3 +++ b/tests/macOS/clean/ls.sdiff.trigger_3 @@ -1,11 +0,0 @@ ---- missing: ls.x86_64 --data/compression/lzma --discover/system/hostname --exec/shell/TERM --fs/link_read --net/url/embedded --process/name_set -++++ added: ls -+exec/shell/TERM -+fs/directory/traverse -+fs/link_read diff --git a/tests/samples_test.go b/tests/samples_test.go index 6d4a4c295..ac61dca16 100644 --- a/tests/samples_test.go +++ b/tests/samples_test.go @@ -306,7 +306,7 @@ func TestDiffFileChange(t *testing.T) { MinRisk: tc.minResultScore, Renderer: simple, RuleFS: []fs.FS{rules.FS, thirdparty.FS}, - ScanPaths: []string{strings.TrimPrefix(tc.src, "../out/samples/"), strings.TrimPrefix(tc.dest, "../out/samples/")}, + ScanPaths: []string{strings.TrimPrefix(tc.src, "../out/chainguard-dev/malcontent-samples/"), strings.TrimPrefix(tc.dest, "../out/chainguard-dev/malcontent-samples/")}, } logger := clog.New(slog.Default().Handler()).With("src", tc.src) @@ -373,7 +373,7 @@ func TestDiffFileIncrease(t *testing.T) { MinRisk: tc.minResultScore, Renderer: simple, RuleFS: []fs.FS{rules.FS, thirdparty.FS}, - ScanPaths: []string{strings.TrimPrefix(tc.src, "../out/samples/"), strings.TrimPrefix(tc.dest, "../out/samples/")}, + ScanPaths: []string{strings.TrimPrefix(tc.src, "../out/chainguard-dev/malcontent-samples/"), strings.TrimPrefix(tc.dest, "../out/chainguard-dev/malcontent-samples/")}, } logger := clog.New(slog.Default().Handler()).With("src", tc.src)