Skip to content

Commit

Permalink
include jndilookup.class file when analyzing so that it can be removed
Browse files Browse the repository at this point in the history
when patching
  • Loading branch information
breadchris committed Dec 21, 2021
1 parent 258281c commit 56c6375
Show file tree
Hide file tree
Showing 8 changed files with 457 additions and 149 deletions.
53 changes: 45 additions & 8 deletions tools/log4shell/analyze/analyze.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package analyze

import (
"archive/zip"
"github.com/blang/semver/v4"
"github.com/lunasec-io/lunasec/tools/log4shell/constants"
"github.com/lunasec-io/lunasec/tools/log4shell/types"
Expand Down Expand Up @@ -96,7 +97,33 @@ func fileNameToSemver(fileNameNoExt string) string {
return semverVersion
}

func ProcessArchiveFile(reader io.Reader, filePath, fileName string) (finding *types.Finding) {
func getJndiLookupHash(zipReader *zip.Reader, filePath string) (fileName, fileHash string, err error) {
fileName = "org/apache/logging/log4j/core/lookup/JndiLookup.class"

reader, err := zipReader.Open(fileName)
if err != nil {
log.Warn().
Str("fieName", fileName).
Str("path", filePath).
Err(err).
Msg("cannot find file in zip")
return
}
defer reader.Close()

fileHash, err = util.HexEncodedSha256FromReader(reader)
if err != nil {
log.Warn().
Str("fieName", fileName).
Str("path", filePath).
Err(err).
Msg("unable to hash JndiLookup.class file")
return
}
return
}

func ProcessArchiveFile(zipReader *zip.Reader, reader io.Reader, filePath, fileName string) (finding *types.Finding) {
_, file := path.Split(filePath)
fileNameNoExt := strings.TrimSuffix(file, path.Ext(file))

Expand Down Expand Up @@ -128,24 +155,34 @@ func ProcessArchiveFile(reader io.Reader, filePath, fileName string) (finding *t
return
}

log.Log().
Str("path", filePath).
Str("fileName", fileName).
Str("fileHash", fileHash).
Msg("identified library version")

if versionCve == "" {
log.Debug().
Str("hash", fileHash).
Str("version", semverVersion).
Msg("Skipping version as it is not vulnerable to any known CVE")
return nil
return
}

jndiLookupFileName, jndiLookupFileHash, err := getJndiLookupHash(zipReader, filePath)
if err != nil {
jndiLookupFileName = ""
jndiLookupFileHash = ""
}

log.Log().
Str("path", filePath).
Str("fileName", fileName).
Str("fileHash", fileHash).
Str("jndiLookupFileName", jndiLookupFileName).
Str("jndiLookupFileHash", jndiLookupFileHash).
Msg("identified library version")

finding = &types.Finding{
Path: filePath,
FileName: fileName,
Hash: fileHash,
JndiLookupFileName: jndiLookupFileName,
JndiLookupHash: jndiLookupFileHash,
Version: semverVersion,
CVE: versionCve,
}
Expand Down
30 changes: 21 additions & 9 deletions tools/log4shell/commands/patch.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func JavaArchivePatchCommand(c *cli.Context, globalBoolFlags map[string]bool) er
log.Warn().
Str("path", finding.Path).
Err(err).
Msg("unable to open findings archive")
Msg("Unable to open findings archive")
return err
}
defer file.Close()
Expand All @@ -72,18 +72,27 @@ func JavaArchivePatchCommand(c *cli.Context, globalBoolFlags map[string]bool) er
log.Warn().
Str("path", finding.Path).
Err(err).
Msg("unable to open archive for patching")
Msg("Unable to open archive for patching")
return err
}

var zipFile fs.File

zipFile, err = zipReader.Open(finding.FileName)
if finding.JndiLookupFileName == "" {
log.Warn().
Str("path", finding.Path).
Err(err).
Msg("Finding does not have JndiLookup.class file to patch")
continue
}

zipFile, err = zipReader.Open(finding.JndiLookupFileName)
if err != nil {
log.Warn().
Str("path", finding.Path).
Str("jndiLookupFileName", finding.JndiLookupFileName).
Err(err).
Msg("unable to open file from zip")
Msg("Unable to open file from zip")
return err
}

Expand All @@ -93,20 +102,23 @@ func JavaArchivePatchCommand(c *cli.Context, globalBoolFlags map[string]bool) er
if err != nil {
log.Warn().
Str("path", finding.Path).
Str("p", finding.Path).
Err(err).
Msg("unable to hash zip file")
Msg("Unable to hash zip file")
return err
}

if zipFileHash != finding.Hash {
if zipFileHash != finding.JndiLookupHash {
log.Warn().
Str("path", finding.Path).
Str("p", finding.Path).
Str("hash", finding.JndiLookupHash).
Err(err).
Msg("hashes do not match, not deleting")
Msg("Hashes do not match, not deleting")
return nil
}
log.Debug().
Str("path", finding.Path).
Str("path", finding.Path).
Msg("Found file to remove")
}

return nil
Expand Down
24 changes: 18 additions & 6 deletions tools/log4shell/commands/scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,11 @@ func loadHashLookup(
return
}

func ScanCommand(c *cli.Context, globalBoolFlags map[string]bool, log4jLibraryHashes []byte) (err error) {
enableGlobalFlags(c, globalBoolFlags)

searchDirs := c.Args().Slice()
func scanDirectoriesForVulnerableLibraries(
c *cli.Context,
searchDirs []string,
log4jLibraryHashes []byte,
) (scannerFindings []types.Finding, err error) {
log.Debug().
Strs("directories", searchDirs).
Msg("scanning directories")
Expand All @@ -67,15 +68,26 @@ func ScanCommand(c *cli.Context, globalBoolFlags map[string]bool, log4jLibraryHa

hashLookup, err := loadHashLookup(log4jLibraryHashes, versionHashes, onlyScanArchives)
if err != nil {
return err
return
}

processArchiveFile := scan.IdentifyPotentiallyVulnerableFiles(scanLog4j1, hashLookup)

scanner := scan.NewLog4jDirectoryScanner(
excludeDirs, onlyScanArchives, noFollowSymlinks, processArchiveFile)

scannerFindings := scanner.Scan(searchDirs)
scannerFindings = scanner.Scan(searchDirs)
return
}

func ScanCommand(c *cli.Context, globalBoolFlags map[string]bool, log4jLibraryHashes []byte) (err error) {
enableGlobalFlags(c, globalBoolFlags)

searchDirs := c.Args().Slice()
scannerFindings, err := scanDirectoriesForVulnerableLibraries(c, searchDirs, log4jLibraryHashes)
if err != nil {
return
}

output := c.String("output")
if output != "" {
Expand Down
Loading

0 comments on commit 56c6375

Please sign in to comment.