Skip to content

Commit

Permalink
testing the jar patcher by loading findings file and then looking at
Browse files Browse the repository at this point in the history
discovered files
  • Loading branch information
breadchris committed Dec 19, 2021
1 parent 5bd43d1 commit 258281c
Show file tree
Hide file tree
Showing 4 changed files with 146 additions and 38 deletions.
113 changes: 113 additions & 0 deletions tools/log4shell/commands/patch.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
// Copyright 2021 by LunaSec (owned by Refinery Labs, Inc)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package commands

import (
"archive/zip"
"encoding/json"
"github.com/lunasec-io/lunasec/tools/log4shell/types"
"github.com/lunasec-io/lunasec/tools/log4shell/util"
"github.com/rs/zerolog/log"
"github.com/urfave/cli/v2"
"io/fs"
"io/ioutil"
"os"
)

func JavaArchivePatchCommand(c *cli.Context, globalBoolFlags map[string]bool) error {
enableGlobalFlags(c, globalBoolFlags)

findingsFile := c.String("findings")

findingsContent, err := ioutil.ReadFile(findingsFile)
if err != nil {
log.Error().
Err(err).
Str("findings", findingsFile).
Msg("Unable to open and read findings file")
return err
}

var findings types.FindingsOutput
err = json.Unmarshal(findingsContent, &findings)
if err != nil {
log.Error().
Err(err).
Str("findings", findingsFile).
Msg("Unable to unmarshal findings file")
return err
}

for _, finding := range findings.VulnerableLibraries {
var file *os.File

file, err = os.Open(finding.Path)
if err != nil {
log.Warn().
Str("path", finding.Path).
Err(err).
Msg("unable to open findings archive")
return err
}
defer file.Close()

info, _ := os.Stat(finding.Path)

var zipReader *zip.Reader

zipReader, err = zip.NewReader(file, info.Size())
if err != nil {
log.Warn().
Str("path", finding.Path).
Err(err).
Msg("unable to open archive for patching")
return err
}

var zipFile fs.File

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

var zipFileHash string

zipFileHash, err = util.HexEncodedSha256FromReader(zipFile)
if err != nil {
log.Warn().
Str("path", finding.Path).
Str("p", finding.Path).
Err(err).
Msg("unable to hash zip file")
return err
}

if zipFileHash != finding.Hash {
log.Warn().
Str("path", finding.Path).
Str("p", finding.Path).
Err(err).
Msg("hashes do not match, not deleting")
return nil
}
}

return nil
}
44 changes: 7 additions & 37 deletions tools/log4shell/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,38 +43,6 @@ func enableGlobalFlags(c *cli.Context) {
}
}

func jarPatchCommand(c *cli.Context) error {
enableGlobalFlags(c)

fileName := c.String("file-name")

if fileName == "" {
log.Info().Msg("Public IP not provided. Binding to the local network interface.")
panic("must specify a valid file name to patch")
}

file, err := os.Open(path)
if err != nil {
log.Warn().
Str("path", path).
Err(err).
Msg("unable to open archive")
panic("unable to open specified file")
}

fileInfo, err := file.Stat()

if err != nil {
panic("unable to read file info")
}

findings := scan.SearchArchiveForVulnerableFiles(fileName, file, fileInfo.Size(), false)

// TODO: Do something with these findings to actually patch them in-place. Either that or add the patching to `SearchArchiveForVulnerableFiles` above.

return nil
}

func main() {
zerolog.TimeFieldFormat = zerolog.TimeFormatUnix

Expand Down Expand Up @@ -213,16 +181,18 @@ func main() {
},
},
{
Name: "patch-local-jar",
Name: "patch",
Aliases: []string{"s"},
Usage: "Patches a specified JAR or WAR file against log4shell by injecting a fixed version of the vulnerable code into vulnerable log4j instances found within it.",
Usage: "Patches findings of libraries vulnerable toLog4Shell by removing the JndiLookup.class file from each.",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "file-name",
Usage: "Patches the specified file (must be a valid JAR or WAR file).",
Name: "findings",
Usage: "Patches all vulnerable Java archives which have been identified.",
},
},
Action: jarPatchCommand,
Action: func(c *cli.Context) error {
return commands.JavaArchivePatchCommand(c, globalBoolFlags)
},
},
},
}
Expand Down
15 changes: 15 additions & 0 deletions tools/log4shell/patch/archivepatch.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright 2021 by LunaSec (owned by Refinery Labs, Inc)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package patch
12 changes: 11 additions & 1 deletion tools/log4shell/scan/scanfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"github.com/lunasec-io/lunasec/tools/log4shell/util"
"github.com/rs/zerolog/log"
"io"
"path/filepath"
"strings"
)

Expand Down Expand Up @@ -66,8 +67,17 @@ func identifyPotentiallyVulnerableFile(reader io.Reader, path, fileName string,
Str("cve", vulnerableFile.CVE).
Msg("Identified vulnerable path")

absolutePath, err := filepath.Abs(path)
if err != nil {
log.Warn().
Str("fileName", fileName).
Str("path", path).
Err(err).
Msg("Unable to resolve absolute path to file")
}

finding = &types.Finding{
Path: path,
Path: absolutePath,
FileName: fileName,
Hash: fileHash,
Version: vulnerableFile.Version,
Expand Down

0 comments on commit 258281c

Please sign in to comment.