Skip to content

Commit d96dcfc

Browse files
committed
add CVE-2021-45105 (v2.16.x) detection
1 parent d33e82e commit d96dcfc

File tree

3 files changed

+29
-14
lines changed

3 files changed

+29
-14
lines changed

README.md

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
11
# log4shelldetect
22

3-
Scans a file or folder recursively for Java programs that may be vulnerable to Log4Shell (CVE-2021-44228) and as of v0.0.5, the incomplete patch in Log4j v2.15.0 (CVE-2021-45046) as well, by inspecting the class paths inside files.
3+
Scans a file or folder recursively for Java programs that may be vulnerable to:
4+
5+
- CVE-2021-44228 (Log4Shell) (v2.0.x - v2.14.x)
6+
- CVE-2021-45046 (v2.15.x)
7+
- CVE-2021-45105 (v2.16.x)
8+
9+
by inspecting the class paths inside files.
410

511
If you only want possibly vulnerable files to be printed rather than all files, run with `-mode list`.
612

13+
![Demo of log4shelldetect](./demo.png)
14+
715
## Usage
816

917
```

demo.png

39.3 KB
Loading

main.go

+20-13
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,11 @@ func main() {
3131

3232
if flag.Arg(0) == "" {
3333
stderr.Println("Usage: log4shelldetect [options] <path>")
34-
stderr.Println("Scans a file or folder recursively for Java programs that may be")
35-
stderr.Println("vulnerable to Log4Shell (CVE-2021-44228) and the incomplete patch")
36-
stderr.Println("in Log4j 2.15.0 (CVE-2021-45046) by inspecting")
37-
stderr.Println("the class paths inside Java archives")
34+
stderr.Println("Scans a file or folder recursively for Java programs that may be vulnerable to:")
35+
stderr.Println("- CVE-2021-44228 (Log4Shell) (v2.0.x - v2.14.x)")
36+
stderr.Println("- CVE-2021-45046 (v2.15.x)")
37+
stderr.Println("- CVE-2021-45105 (v2.16.x)")
38+
stderr.Println("by inspecting the class paths inside Java archives")
3839
stderr.Println("")
3940
stderr.Println("Options:")
4041
flag.PrintDefaults()
@@ -74,12 +75,12 @@ func main() {
7475
status, desc := checkJar(osPathname, nil, 0, 0)
7576
if *mode == "list" {
7677
switch status {
77-
case StatusVulnerable, StatusMaybe, StatusOld:
78+
case StatusVulnerable, StatusMaybe, StatusOld, StatusSecondOld:
7879
atomic.StoreUint32(&hasNotableResults, 1)
7980
}
8081
} else {
8182
switch status {
82-
case StatusVulnerable, StatusMaybe, StatusOld, StatusPatched:
83+
case StatusVulnerable, StatusMaybe, StatusOld, StatusPatched, StatusSecondOld:
8384
atomic.StoreUint32(&hasNotableResults, 1)
8485
}
8586
}
@@ -172,8 +173,8 @@ func checkJar(pathToFile string, rd io.ReaderAt, size int64, depth int) (status
172173

173174
// Define some default variables.
174175
var vulnClassFound = false
176+
var secondPatchFound = false
175177
var oldPatchFound = false
176-
var patchedClassFound = false
177178
var maybeClassFound = ""
178179
var worstSubStatus Status = StatusOK
179180
var worstDesc string
@@ -226,10 +227,8 @@ func checkJar(pathToFile string, rd io.ReaderAt, size int64, depth int) (status
226227
oldPatchFound = true
227228
}
228229

229-
// And check if it contains the known patched code.
230230
if bytes.Contains(data, []byte("log4j2.enableJndi")) {
231-
// If so, indicate that the jar is patched.
232-
patchedClassFound = true
231+
secondPatchFound = true
233232
}
234233

235234
return nil
@@ -298,9 +297,12 @@ func checkJar(pathToFile string, rd io.ReaderAt, size int64, depth int) (status
298297
status = StatusOK
299298
desc = ""
300299
}
301-
} else if patchedClassFound {
300+
} else if secondPatchFound && !oldPatchFound {
302301
status = StatusPatched
303302
desc = ""
303+
} else if secondPatchFound {
304+
status = StatusSecondOld
305+
desc = ""
304306
} else if oldPatchFound {
305307
status = StatusOld
306308
desc = ""
@@ -330,8 +332,9 @@ const (
330332
StatusOK = iota
331333
StatusPatched
332334
StatusUnknown
333-
StatusMaybe
335+
StatusSecondOld
334336
StatusOld
337+
StatusMaybe
335338
StatusVulnerable
336339
)
337340

@@ -343,7 +346,8 @@ func printStatus(fileName string, status Status, desc string) {
343346

344347
// If we're running in -mode list, we only print likely vulnerable files.
345348
if *mode == "list" {
346-
if status == StatusVulnerable || status == StatusOld || status == StatusMaybe {
349+
if status == StatusVulnerable || status == StatusOld ||
350+
status == StatusMaybe || status == StatusSecondOld {
347351
fmt.Println(fileName)
348352
}
349353

@@ -362,6 +366,9 @@ func printStatus(fileName string, status Status, desc string) {
362366
case StatusOld:
363367
c = color.New(color.FgRed)
364368
c.Print("OLD2.15 ")
369+
case StatusSecondOld:
370+
c = color.New(color.FgRed)
371+
c.Print("OLD2.16 ")
365372
case StatusVulnerable:
366373
c = color.New(color.FgRed)
367374
c.Print("VULNRBL ")

0 commit comments

Comments
 (0)