Edit File by line
/home/barbar84/www/wp-conte.../plugins/sujqvwi/ShExBy/smshex_r.../opt/sharedra...
File: forensic.py
#!/opt/imh-python/bin/python3
[0] Fix | Delete
"""Forensic Attack Tool -- This program will dump forensic data from ss,
[1] Fix | Delete
tcpdump, netstat, and ps for use in analyzing attack vectors, surfaces,
[2] Fix | Delete
and impact as part of the post-mortem process."""
[3] Fix | Delete
# Forensic Attack Tool
[4] Fix | Delete
# Copyright 2012 -- InMotion Hosting Inc.
[5] Fix | Delete
# Author: Kevin D (kevind@inmotionhosting.com, ext 1116)
[6] Fix | Delete
# Version: 2012061803
[7] Fix | Delete
# Dependencies: Python 2.4
[8] Fix | Delete
# Changelog:
[9] Fix | Delete
# 2012071201 -- updated to fix binary paths for subprocesses
[10] Fix | Delete
# 2012061803 -- updated to give more feedback to the user
[11] Fix | Delete
# 2012061802 -- misc syntax and header info updates
[12] Fix | Delete
# -- added in venet and CE6 interface input validation
[13] Fix | Delete
# 2012061801 -- fixed log init time (moved later to prevent blank logs)
[14] Fix | Delete
# -- added input sanity checking
[15] Fix | Delete
# -- removed log tagging. may be added back in later release
[16] Fix | Delete
# 2012061501 -- Initial release
[17] Fix | Delete
[18] Fix | Delete
# Reference for backgrounding:
[19] Fix | Delete
# https://www.oreilly.com/library/view/python-cookbook/0596001673/ch06s08.html
[20] Fix | Delete
[21] Fix | Delete
[22] Fix | Delete
import os
[23] Fix | Delete
import subprocess
[24] Fix | Delete
from datetime import datetime
[25] Fix | Delete
import re
[26] Fix | Delete
import sys
[27] Fix | Delete
from argparse import ArgumentParser
[28] Fix | Delete
from concurrent.futures import ThreadPoolExecutor
[29] Fix | Delete
[30] Fix | Delete
NOW = datetime.now()
[31] Fix | Delete
DATESTAMP = NOW.strftime("%Y%m%d_%H%M%S")
[32] Fix | Delete
[33] Fix | Delete
[34] Fix | Delete
def parse_args():
[35] Fix | Delete
parser = ArgumentParser(description=__doc__)
[36] Fix | Delete
# fmt: off
[37] Fix | Delete
parser.add_argument(
[38] Fix | Delete
"-i", "--interface", dest="eth_interface", metavar="INTERFACE",
[39] Fix | Delete
help="Define a capture interface for tcpdump",
[40] Fix | Delete
)
[41] Fix | Delete
parser.add_argument(
[42] Fix | Delete
"-s", "--sip", "--source-ip", dest="sip", metavar="SIP",
[43] Fix | Delete
help="Define a source IP for tcpdump",
[44] Fix | Delete
)
[45] Fix | Delete
parser.add_argument(
[46] Fix | Delete
"-d", "--dip", "--destination-ip", dest="dip", metavar="DIP",
[47] Fix | Delete
help="Define a destination IP for tcpdump",
[48] Fix | Delete
)
[49] Fix | Delete
# fmt: on
[50] Fix | Delete
args = parser.parse_args()
[51] Fix | Delete
valid_interface = re.compile(
[52] Fix | Delete
r"^(eth|venet|em)[0-9]{1,3}(\:(cp)?[0-9]{1,3})?$"
[53] Fix | Delete
)
[54] Fix | Delete
valid_ip = re.compile(r"^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$")
[55] Fix | Delete
if args.eth_interface is not None:
[56] Fix | Delete
if not valid_interface.match(args.eth_interface):
[57] Fix | Delete
sys.exit("Invalid ethernet interface! Exiting")
[58] Fix | Delete
if args.sip is not None:
[59] Fix | Delete
if not valid_ip.match(args.sip):
[60] Fix | Delete
sys.exit("Invalid source IP! Exiting")
[61] Fix | Delete
if args.dip is not None:
[62] Fix | Delete
if not valid_ip.match(args.dip):
[63] Fix | Delete
sys.exit("Invalid destination IP! Exiting")
[64] Fix | Delete
return args
[65] Fix | Delete
[66] Fix | Delete
[67] Fix | Delete
def main():
[68] Fix | Delete
args = parse_args()
[69] Fix | Delete
print(
[70] Fix | Delete
"Backgrounding forensic proccesses.",
[71] Fix | Delete
"Please include the following line in your post-mortem report.",
[72] Fix | Delete
"FAT logs: /var/log/attack.{DATESTAMP}.*.log",
[73] Fix | Delete
sep='\n',
[74] Fix | Delete
)
[75] Fix | Delete
background()
[76] Fix | Delete
collect_data(args)
[77] Fix | Delete
[78] Fix | Delete
[79] Fix | Delete
def background():
[80] Fix | Delete
try:
[81] Fix | Delete
pid = os.fork()
[82] Fix | Delete
if pid > 0:
[83] Fix | Delete
# Exit first parent
[84] Fix | Delete
sys.exit(0)
[85] Fix | Delete
except OSError as exc:
[86] Fix | Delete
sys.exit(f"fork #1 failed: {exc}")
[87] Fix | Delete
# Decouple from parent environment
[88] Fix | Delete
os.chdir("/root")
[89] Fix | Delete
os.setsid()
[90] Fix | Delete
os.umask(0)
[91] Fix | Delete
try:
[92] Fix | Delete
pid = os.fork()
[93] Fix | Delete
if pid > 0:
[94] Fix | Delete
sys.exit(0)
[95] Fix | Delete
except OSError as exc:
[96] Fix | Delete
sys.exit(f"fork #2 failed: {exc}")
[97] Fix | Delete
[98] Fix | Delete
[99] Fix | Delete
def collect_data(args):
[100] Fix | Delete
# fmt: off
[101] Fix | Delete
tcpdump = [
[102] Fix | Delete
'/usr/sbin/tcpdump', '-Un', '-c', '5000', '-Z', 'root',
[103] Fix | Delete
'-w', f'/var/log/attack.{DATESTAMP}.tcpdump.cap',
[104] Fix | Delete
]
[105] Fix | Delete
# fmt: on
[106] Fix | Delete
netstat = ['/bin/netstat', '-pnee', '-a']
[107] Fix | Delete
ss_cmd = ['/usr/sbin/ss', '-pain']
[108] Fix | Delete
ps_cmd = ['/bin/ps', 'aufx']
[109] Fix | Delete
[110] Fix | Delete
# If an ethernet interface is defined, add it to the command.
[111] Fix | Delete
if args.eth_interface is not None:
[112] Fix | Delete
tcpdump.extend(['-i', args.eth_interface])
[113] Fix | Delete
# If a source IP is defined, add it to the command.
[114] Fix | Delete
if args.sip is not None:
[115] Fix | Delete
tcpdump.extend(['src', args.sip])
[116] Fix | Delete
# If source AND destination IPs are defined, add them both to tcpdump.
[117] Fix | Delete
if args.dip is not None:
[118] Fix | Delete
tcpdump.extend(['and', 'dst', args.dip])
[119] Fix | Delete
# If a only destination IP is defined, add it to the command.
[120] Fix | Delete
elif args.dip is not None:
[121] Fix | Delete
tcpdump.extend(['dst', args.dip])
[122] Fix | Delete
log = f'/var/log/attack.{DATESTAMP}.%s.log'
[123] Fix | Delete
with ThreadPoolExecutor(max_workers=4) as pool:
[124] Fix | Delete
pool.submit(run_cmd, tcpdump, log % 'tcpdump')
[125] Fix | Delete
pool.submit(run_cmd, netstat, log % 'netstat')
[126] Fix | Delete
pool.submit(run_cmd, ss_cmd, log % 'ss')
[127] Fix | Delete
pool.submit(run_cmd, ps_cmd, log % 'psaufx')
[128] Fix | Delete
[129] Fix | Delete
[130] Fix | Delete
def run_cmd(cmd, log_path):
[131] Fix | Delete
with open(log_path, 'wb') as log_file:
[132] Fix | Delete
try:
[133] Fix | Delete
subprocess.run(cmd, stdout=log_file, stderr=log_file, check=False)
[134] Fix | Delete
except OSError as exc:
[135] Fix | Delete
log_file.write(bytes(str(exc), 'utf-8', 'replace'))
[136] Fix | Delete
[137] Fix | Delete
[138] Fix | Delete
if __name__ == '__main__':
[139] Fix | Delete
main()
[140] Fix | Delete
[141] Fix | Delete
It is recommended that you Edit text format, this type of Fix handles quite a lot in one request
Function