Modified nxc/protocols/ftp/proto_args.py and added (--get and --put). Modified --ls

Modified nxc/protocols/ftp.py and added --get and --put functionality. Modified --ls functionality
main
romanrii 2023-09-24 12:36:14 +00:00
parent 87a2efac23
commit 9cbd847fd6
2 changed files with 81 additions and 8 deletions

View File

@ -1,5 +1,6 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
from nxc.config import process_secret
from nxc.connection import *
from nxc.logger import NXCAdapter
@ -80,16 +81,42 @@ class ftp(connection):
host_id = self.db.get_hosts(self.host)[0].id
self.db.add_loggedin_relation(cred_id, host_id)
if username in ["anonymous", ""] and password in ["", "-"]:
if username in ["anonymous", ""]:
self.logger.success(f"{username}:{process_secret(password)} {highlight('- Anonymous Login!')}")
else:
self.logger.success(f"{username}:{process_secret(password)}")
if self.args.ls:
files = self.list_directory_full()
self.logger.display(f"Directory Listing")
for file in files:
self.logger.highlight(file)
# If the default directory is specified, then we will list the current directory
if self.args.ls == ".":
files = self.list_directory_full()
# If files is false, then we encountered an exception
if not files:
return False
# If there are files, then we can list the files
self.logger.display(f"Directory Listing")
for file in files:
self.logger.highlight(file)
else:
# If the default directory is not specified, then we will list the specified directory
self.logger.display(f"Directory Listing for {self.args.ls}")
# Change to the specified directory
try:
self.conn.cwd(self.args.ls)
except error_perm as error_message:
self.logger.fail(f"Failed to change directory. Response: ({error_message})")
self.conn.close()
return False
# List the files in the specified directory
files = self.list_directory_full()
for file in files:
self.logger.highlight(file)
if self.args.get:
self.get_file(f"{self.args.get}")
if self.args.put:
self.put_file(self.args.put[0], self.args.put[1])
if not self.args.continue_on_success:
self.conn.close()
@ -101,9 +128,53 @@ class ftp(connection):
# in the future we can use mlsd/nlst if we want, but this gives a full output like `ls -la`
# ftplib's "dir" prints directly to stdout, and "nlst" only returns the folder name, not full details
files = []
self.conn.retrlines("LIST", callback=files.append)
try:
self.conn.retrlines("LIST", callback=files.append)
except error_perm as error_message:
self.logger.fail(f"Failed to list directory. Response: ({error_message})")
self.conn.close()
return False
return files
def get_file(self, filename):
# Extract the filename from the path
downloaded_file = filename.split("/")[-1]
try:
# Check if the current connection is ASCII (ASCII does not support .size())
if self.conn.encoding == "utf-8":
# Switch the connection to binary
self.conn.sendcmd("TYPE I")
# Check if the file exists
self.conn.size(filename)
# Attempt to download the file
self.conn.retrbinary(f"RETR {filename}", open(downloaded_file, "wb").write)
except error_perm as error_message:
self.logger.fail(f"Failed to download the file. Response: ({error_message})")
self.conn.close()
return False
except FileNotFoundError:
self.logger.fail(f"Failed to download the file. Response: (No such file or directory.)")
self.conn.close()
return False
# Check if the file was downloaded
if os.path.isfile(downloaded_file):
self.logger.success(f"Downloaded: {filename}")
else:
self.logger.fail(f"Failed to download: {filename}")
def put_file(self, local_file, remote_file):
try:
# Attempt to upload the file
self.conn.storbinary(f"STOR {remote_file}", open(local_file, "rb"))
except error_perm as error_message:
self.logger.fail(f"Failed to upload file. Response: ({error_message})")
return False
# Check if the file was uploaded
if self.conn.size(remote_file) > 0:
self.logger.success(f"Uploaded: {local_file} to {remote_file}")
else:
self.logger.fail(f"Failed to upload: {local_file} to {remote_file}")
def supported_commands(self):
raw_supported_commands = self.conn.sendcmd("HELP")
supported_commands = [item for sublist in (x.split() for x in raw_supported_commands.split("\n")[1:-1]) for item in sublist]

View File

@ -3,5 +3,7 @@ def proto_args(parser, std_parser, module_parser):
ftp_parser.add_argument("--port", type=int, default=21, help="FTP port (default: 21)")
cgroup = ftp_parser.add_argument_group("FTP Access", "Options for enumerating your access")
cgroup.add_argument("--ls", action="store_true", help="List files in the directory")
cgroup.add_argument("--ls", metavar="DIRECTORY", nargs="?", const=".", help="List files in the directory")
cgroup.add_argument("--get", metavar="FILE", help="Download a file")
cgroup.add_argument("--put", metavar=("LOCAL_FILE", "REMOTE_FILE"), nargs=2, help="Upload a file")
return parser