Skip to content

Commit b9deab6

Browse files
feature: Added text, csv, json ouput capability
1 parent 9c34082 commit b9deab6

File tree

1 file changed

+40
-3
lines changed

1 file changed

+40
-3
lines changed

log4j-finder.py

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
# Exclude files or directories:
1919
# $ python3 log4j-finder.py / --exclude "/*/.dontgohere" --exclude "/home/user/*.war"
2020
#
21+
import json
2122
import os
2223
import io
2324
import sys
@@ -243,7 +244,15 @@ def check_vulnerable(fobj, path_chain, stats, has_jndilookup=True):
243244
status = bold(color(status.upper()))
244245
md5sum = color(md5sum)
245246
comment = bold(color(comment))
246-
print(f"[{now}] {hostname} {status}: {path_chain} [{md5sum}: {comment}]")
247+
248+
return {
249+
'timestamp': now,
250+
'hostname': hostname,
251+
'status': status,
252+
'path_chain': path_chain,
253+
'md5sum': md5sum,
254+
'comment': comment
255+
}
247256

248257

249258
def print_summary(stats):
@@ -300,6 +309,13 @@ def main():
300309
help="exclude files/directories by pattern (can be used multiple times)",
301310
metavar='PATTERN'
302311
)
312+
parser.add_argument(
313+
"-o",
314+
"--output",
315+
choices=['text', 'csv', 'json'],
316+
default='text',
317+
help="choose output format"
318+
)
303319
args = parser.parse_args()
304320
logging.basicConfig(
305321
format="%(asctime)s %(levelname)s %(message)s",
@@ -316,6 +332,12 @@ def main():
316332
global NO_COLOR
317333
NO_COLOR = True
318334

335+
if 'text' not in args.output:
336+
NO_COLOR = True
337+
args.quiet = True
338+
args.no_banner = True
339+
340+
summary = []
319341
stats = collections.Counter()
320342
start_time = time.monotonic()
321343
hostname = magenta(HOSTNAME)
@@ -336,7 +358,7 @@ def main():
336358
if p.name.lower().endswith("JndiManager.class".lower()):
337359
lookup_path = p.parent.parent / "lookup/JndiLookup.class"
338360
has_lookup = lookup_path.exists()
339-
check_vulnerable(fobj, [p], stats, has_lookup)
361+
summary.append(check_vulnerable(fobj, [p], stats, has_lookup))
340362
if p.suffix.lower() in JAR_EXTENSIONS:
341363
try:
342364
log.info(f"Found jar file: {p}")
@@ -354,10 +376,25 @@ def main():
354376
has_lookup = zfile.open(lookup_path.as_posix())
355377
except KeyError:
356378
has_lookup = False
357-
check_vulnerable(zf, parents + [zpath], stats, has_lookup)
379+
summary.append(check_vulnerable(zf, parents + [zpath], stats, has_lookup))
358380
except IOError as e:
359381
log.debug(f"{p}: {e}")
360382

383+
if 'text' in args.output:
384+
for line in summary:
385+
print(
386+
f"[{line['timestamp']}] {line['hostname']} {line['status']}: {line['path_chain']} [{line['md5sum']}: {line['comment']}]"
387+
)
388+
elif 'csv' in args.output:
389+
for line in summary:
390+
print(
391+
f"{line['timestamp']};{line['hostname']};{line['status']};{line['path_chain']};{line['md5sum']};{line['comment']}"
392+
)
393+
elif 'json' in args.output:
394+
print(json.dumps(summary, default=str))
395+
else:
396+
raise NameError('Unknown output parameter')
397+
361398
elapsed = time.monotonic() - start_time
362399
now = datetime.datetime.utcnow().replace(microsecond=0)
363400
if not args.quiet:

0 commit comments

Comments
 (0)