-
Notifications
You must be signed in to change notification settings - Fork 20
/
checksum8-accesslogs.py
86 lines (74 loc) · 2.9 KB
/
checksum8-accesslogs.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#!/usr/bin/env python3
#
# Simple script to check the checksum8 of accesslogs
#
import argparse
import collections
import datetime
import re
import sys
from dissect.cobaltstrike import utils
RE_ACCESS_LOG = re.compile(
r"""
[^\d]* # ignore front matter (eg: filename from grep out or logger name)
(?P<ip>\d+\.\d+\.\d+\.\d+) # the IP address
.* # Ignore other stuff (could be a space, or username in case of nginx or apache)
\[(?P<time>.+)\] # the date and time
\s+ # ignore spaces
"(?P<request>.*)" # the request
\s+ # ignore spaces
(?P<status>[0-9]+) # the status
\s+ # ignore spaces
(?P<size>\S+) # the size
\s+ # ignore spaces
"(?P<referrer>.*)" # the referrer
\s+ # ignore spaces
"(?P<agent>.*)" # the user agent
""",
re.VERBOSE,
)
def build_parser():
parser = argparse.ArgumentParser(description="checksum8 accesslogs")
parser.add_argument("--stats", action="store_true", help="show monthly stats")
parser.add_argument("-l", "--length", type=int, help="truncate output to this length")
parser.add_argument("-b", "--brief", action="store_true", help="brief output (no user agent)")
parser.add_argument("-d", "--datefmt", default=None, help="date format")
return parser
@utils.catch_sigpipe
def main():
parser = build_parser()
args = parser.parse_args()
stats = collections.Counter()
print("[reading from stdin..]", file=sys.stderr)
for line in sys.stdin:
match = RE_ACCESS_LOG.match(line)
if not match:
continue
ip = match.group("ip")
apache_stamp = match.group("time")
request = match.group("request")
agent = match.group("agent")
dt = datetime.datetime.strptime(apache_stamp, "%d/%b/%Y:%H:%M:%S %z")
method, _, uri = request.partition(" ")
uri, _, version = uri.partition(" ")
if utils.is_stager_x86(uri) or utils.is_stager_x64(uri):
beacon = "x64" if utils.is_stager_x64(uri) else "x86"
if args.stats:
fmt = args.datefmt or "%Y-%m"
stats[dt.strftime(fmt)] += 1
continue
if args.datefmt:
dt = dt.strftime(args.datefmt)
if args.brief:
out = f"{dt} - beacon {beacon} - {method} {uri}"
else:
out = f"{dt} - beacon {beacon} - {method} {ip} {uri} - {agent}"
if args.length and len(out) > args.length:
out = out[: args.length] + "..."
print(out)
if args.stats:
print("date,requests")
for month, value in sorted(stats.items()):
print(f"{month},{value}")
if __name__ == "__main__":
sys.exit(main())