Lucene search
+L

FTP Delete File

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

KittySploit FTP File Deletion module deletes files or directories from an FTP server.

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

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

class Module(Post, FTPClientMixin):
    """FTP File Deletion Module"""
    
    __info__ = {
        "name": "FTP Delete File",
        "description": "Deletes files or directories from the FTP server",
        "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': [],
         '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': []},
    },
    }
    
    remote_path = OptString("", "Remote file or directory path to delete", True)
    recursive = OptBool(False, "Recursively delete directories", False)
    confirm = OptBool(False, "Skip confirmation prompt", 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 _delete_directory(self, remote_path: str) -> tuple:
        """
        Recursively delete directory and its contents
        
        Returns:
            tuple: (files_deleted, directories_deleted)
        """
        files_deleted = 0
        directories_deleted = 0
        
        try:
            # List files in directory
            files = self.list_files(remote_path)
            
            for file_info in files:
                name = file_info.get('name', '')
                file_type = file_info.get('type', 'unknown')
                
                # Skip . and ..
                if name in ['.', '..']:
                    continue
                
                file_path = f"{remote_path}/{name}".replace("//", "/")
                if remote_path == ".":
                    file_path = name
                
                if file_type == 'directory':
                    if self.recursive:
                        # Recursively delete subdirectory
                        sub_files, sub_dirs = self._delete_directory(file_path)
                        files_deleted += sub_files
                        directories_deleted += sub_dirs
                        
                        # Delete the directory itself
                        try:
                            connection = self.open_ftp()
                            connection.rmd(file_path)
                            directories_deleted += 1
                            print_success(f"  ✓ Deleted directory: {file_path}")
                        except Exception as e:
                            print_warning(f"  ✗ Failed to delete directory {file_path}: {e}")
                    else:
                        print_warning(f"  ⏭️  Skipping directory (use recursive=True): {file_path}")
                else:
                    # Delete file
                    try:
                        connection = self.open_ftp()
                        connection.delete(file_path)
                        files_deleted += 1
                        print_success(f"  ✓ Deleted file: {file_path}")
                    except Exception as e:
                        print_warning(f"  ✗ Failed to delete file {file_path}: {e}")
            
            return (files_deleted, directories_deleted)
            
        except Exception as e:
            print_warning(f"Error deleting directory {remote_path}: {e}")
            return (files_deleted, directories_deleted)
    
    def _check_path_exists(self, remote_path: str) -> tuple:
        """
        Check if path exists and return its type
        
        Returns:
            tuple: (exists, is_directory)
        """
        try:
            connection = self.open_ftp()
            
            # Try to get file size (for files)
            try:
                size = connection.size(remote_path)
                if size is not None:
                    return (True, False)
            except:
                pass
            
            # Try to change to directory (for directories)
            try:
                original_dir = connection.pwd()
                connection.cwd(remote_path)
                connection.cwd(original_dir)
                return (True, True)
            except:
                pass
            
            # Try listing parent directory
            if '/' in remote_path:
                parent_dir = '/'.join(remote_path.split('/')[:-1])
                filename = remote_path.split('/')[-1]
            else:
                parent_dir = '.'
                filename = remote_path
            
            files = self.list_files(parent_dir)
            for file_info in files:
                if file_info.get('name') == filename:
                    is_dir = file_info.get('type') == 'directory'
                    return (True, is_dir)
            
            return (False, False)
            
        except:
            return (False, False)
    
    def run(self):
        """Run the file deletion"""
        try:
            print_info("=" * 70)
            print_info("FTP File Deletion")
            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"Target Path: {self.remote_path}")
            print_info(f"Recursive: {self.recursive}")
            print_info("")
            
            # Check if path exists
            exists, is_directory = self._check_path_exists(self.remote_path)
            
            if not exists:
                print_error(f"Path not found: {self.remote_path}")
                return False
            
            path_type = "directory" if is_directory else "file"
            print_info(f"Path type: {path_type}")
            
            # Confirmation
            if not self.confirm:
                print_warning("⚠️  WARNING: This will permanently delete the target!")
                print_info(f"Target: {self.remote_path}")
                print_info(f"Type: {path_type}")
                if is_directory and self.recursive:
                    print_warning("Recursive deletion is enabled - all contents will be deleted!")
                print_info("")
                response = input("Continue? (yes/no): ").strip().lower()
                if response not in ['yes', 'y']:
                    print_info("Deletion cancelled")
                    return False
                print_info("")
            
            # Delete
            print_status("Deleting...")
            print_info("-" * 70)
            
            connection = self.open_ftp()
            
            if is_directory:
                if self.recursive:
                    # Recursively delete directory contents
                    files_deleted, dirs_deleted = self._delete_directory(self.remote_path)
                    
                    # Delete the directory itself
                    try:
                        connection.rmd(self.remote_path)
                        dirs_deleted += 1
                        print_success(f"✓ Deleted directory: {self.remote_path}")
                    except Exception as e:
                        print_warning(f"✗ Failed to delete directory {self.remote_path}: {e}")
                    
                    print_info("")
                    print_info("-" * 70)
                    print_success(f"Deletion complete!")
                    print_info(f"Files deleted: {files_deleted}")
                    print_info(f"Directories deleted: {dirs_deleted}")
                else:
                    # Try to delete empty directory
                    try:
                        connection.rmd(self.remote_path)
                        print_success(f"✓ Deleted directory: {self.remote_path}")
                    except Exception as e:
                        print_error(f"Failed to delete directory: {e}")
                        print_info("Directory may not be empty. Use recursive=True to delete contents.")
            else:
                # Delete file
                try:
                    connection.delete(self.remote_path)
                    print_success(f"✓ Deleted file: {self.remote_path}")
                except Exception as e:
                    print_error(f"Failed to delete file: {e}")
                    raise ProcedureError(FailureType.Unknown, f"Error deleting file: {e}")
            
            return True
            
        except ProcedureError:
            raise
        except Exception as e:
            raise ProcedureError(FailureType.Unknown, f"Error deleting file: {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

10 Jul 2026 11:31Current
5.9Medium risk
Vulners AI Score5.9
4