cURL command won't work in python TCP shell script - python

I was writing a TCP shell script to run some CMD commands on a server (laptop). I got some basic commands working like ipconfig and whoami and got the output sent back to the client terminal.
when I tried to run this command: curl https://media.wired.co.uk/photos/607d91994d40fbb952b6ad64/4:3/w_2664,h_1998,c_limit/wired-meme-nft-brian.jpg --output yo.jpg it would show this on the server terminal:
output of server terminal after running command
I tried running this command manually on the server and it worked fine, anyone knows why is this happening?
Client Code:
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, PORT))
s.settimeout(1.0) # waiting 1 second for data to be sent back before continuing from s.recv
while True:
command = input("Enter command:\n")
s.sendall(command.encode())
try:
data = s.recv(2048) # Waiting for data to be sent back
except socket.error: # Checking if there is data
print("NO DATA")
else:
print(data.decode()) # Decode the data
Server Code:
import socket
import os
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
PORT = 5000
sock.bind(('', PORT))
sock.listen(5)
try:
while True:
newSocket, address = sock.accept()
print("Connected from", address)
while True:
receivedData = newSocket.recv(2048)
receivedData = receivedData.decode()
print(str(receivedData))
output = os.popen(receivedData).read()
output = str(output)
newSocket.sendall(output.encode())
newSocket.close()
print("Disconnected from", address)
finally:
sock.close()

CD command was overwritten by the curl command after it, in order to curl to a specified directory both cd and curl command need to be inputted at the same time with the '&' operator.
cd C:\Users\User\Desktop && curl https://media.wired.co.uk/photos/607d91994d40fbb952b6ad64/4:3/w_2664,h_1998,c_limit/wired-meme-nft-brian.jpg --output yo.jpg

Related

Bidirectional socket between host and docker container

I have seen some similar questions but there don't seem to be answers but if one exists please point me to it. I have boiled down my issue to a self contained example. So all the stuff below is my exact env. I have a docker container that has a python script that listens on a socket and echoes back anything it receives (basically an echo server). The client is running on the host system. I seem to be able to send from the client to the server but the response is never received. I tried some fudging to send the response back to host.docker.internal but it doesn't work. So is this even possible to do? Anyways the details below:
Basically my docker container runs a python script, the Dockerfile looks like this:
FROM python:3.9
ADD main.py .
CMD ["python", "./main.py"]
Then I have docker-compose.yml to create a service with ports forwarding:
version: '3'
services:
web:
image: py-app
ports:
- "8010:8010"
My server (which runs inside the docker container) looks like this:
import socket
DOCKER_HOST = 'host.docker.internal'
HOST = '127.0.0.1'
PORT = 8010
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind((HOST, PORT))
s.listen()
conn, addr = s.accept()
with conn:
while True:
data = conn.recv(1024)
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as ds:
ds.connect((DOCKER_HOST, PORT))
ds.sendall(data)
My client that takes input from the keyboard and sends the data to the server running in docker looks like:
import socket
HOST = '127.0.0.1'
DOCKER_PORT = 8010
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, DOCKER_PORT))
print("Connected")
while True:
print("Sending data")
x = input()
x = bytes(x, 'utf-8')
s.sendall(x)
print("Recieving data")
data = s.recv(1024)
print('Received echo: ', repr(data))
There is no error when sending the data into the container but nothing comes out from it. Any thoughts on how I can accomplish what I want to do?

can't write to socket from cmd using sock.recv on windows

I'm trying to make basic synchronous hello world with sockets
(server is supposed to send some message as answer for any message from client).
I bind localhost:5000 to socket
I'm trying to receive console input with sock.recv(4096)
I try to connect to socket from the console using curl localhost:5000, but I can't write to the console. Also, server sends message when i connect to it, but nothing more
here is the code:
import socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind(("localhost", 5000))
server_socket.listen()
def accept_connection(server_socket):
while True:
client_socket, addr = server_socket.accept()
print("connection from", addr)
send_message(client_socket)
def send_message(client_socket):
while True:
request = client_socket.recv(4096)
if request:
response = "request recieved\n".encode()
client_socket.send(response)
else:
break
print("done with sending stuff")
client_socket.close()
if __name__ == "__main__":
print("stuff_started")
accept_connection(server_socket)
server output:
C:\Users\USER\Desktop\stuff\pth>python testing.py
stuff_started
connection from ('127.0.0.1', 53053)
client output:
C:\Users\USER\Desktop\stuff\pth>curl localhost:5000
request recieved
As written in the comments, curl is used to HTTP servers and not for generic sockets.
You can use netcat for that:
nc 127.0.0.1 5000
or just plain old Python in your favorite shell like so:
> py -c "import socket; s = socket.create_connection(('localhost', 5000)); s.sendall(b'data'); print(s.recv(1024))"
b'request recieved\n'

How to encode traffic socket?

Hi i have my server client model i need to encode the traffic which is HTTP1.1 how should i do this this is my server code
server:
import socket
from base64 import b64encode
SERVER_HOST = "0.0.0.0"
SERVER_PORT = 5003
BUFFER_SIZE = 1024
# create a 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
# when you run the server multiple times in Linux, Address already in use error will raise
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.listen(5)
print(f"Listening as {SERVER_HOST}:{SERVER_PORT} ...")
# accept any connections attempted
client_socket, client_address = s.accept()
print(f"{client_address[0]}:{client_address[1]} Connected!")
# just sending a message, for demonstration purposes
message = "Hello and Welcome".encode()
client_socket.send(message)
while True:
# get the command from prompt
command = input("Enter the command you wanna execute:")
# send the command to the client
if command == "3":
command2 = "arp -a"
client_socket.send(command2.encode())
else:
client_socket.send(command.encode())
if command.lower() == "exit":
# if the command is exit, just break out of the loop
break
# retrieve command results
results = client_socket.recv(BUFFER_SIZE).decode()
# print them
print(results)
# close connection to the client
client_socket.close()
# close server connection
s.close()
and this is what i am trying to do:
How should i achive this thanku.
First you should have encryption and decryption mechanism both on
server side and client side depending on your needs.
The next thing is to use Web Socket Secure Protocol (WSS) Configured
in your web server.

Python client hanging when sending empty message to server

I have a python reverse shell that I am working on that utilizes a client-server connection using TCP. I am testing them both right now on my localhost windows machine and I am utilizing the subprocess library to handle commands. The client is supposed to send a command to the server and the server will reply back with the output.
Server:
import socket
import subprocess
import os
# Server
# creates TCP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# port and server ip(localhost)
LOCAL_HOST = '127.0.0.1'
PORT = 5565
BUFFER_SIZE = 5000 # size of message
no_char_message = "-1: Please enter a command"
# test connection
print("Server starting up on %s with port number %s" % (LOCAL_HOST, PORT))
# bind socket to ip and port
sock.bind((LOCAL_HOST, PORT))
# listen to socket
sock.listen(1)
# socket will accept connection and client address
print("Waiting for connection") # waiting for connection
connection, address = sock.accept() # accept connection with client address
print("Connected to", address) # connected by address
while True:
command = connection.recv(BUFFER_SIZE) # receive message from client
if not command:
break
if len(command) == 0:
connection.send(str.encode(no_char_message))
if len(command) > 0:
terminal = subprocess.Popen(command[:].decode("utf-8"), shell=True, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, stdin=subprocess.PIPE)
output = terminal.stdout.read() + terminal.stderr.read()
output_as_string = str(output, "utf-8")
connection.send(str.encode(output_as_string))
print(output_as_string)
print("Closing Server")
sock.close()
connection.close()
Client
import socket
# Client
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # creates TCP Socket
# local host and port
LOCAL_HOST = '127.0.0.1'
PORT = 5565
BUFFER_SIZE = 5000 # size of message
# connect socket to ip and port
sock.connect((LOCAL_HOST, PORT))
print("Connected to server\n")
while True:
message = input("Please enter a command:\n") # ask user to input message
if message == 'quit':
break
print("Sending %s" % message)
sock.send(str.encode(message)) # send message
command = str(sock.recv(BUFFER_SIZE), "utf-8") # receive message
print("received %s" % command)
print("closing connection with server")
sock.close()
The issue is when I send an empty message to the server it hangs and just says sending in the terminal and the server never receives anything. I am not sure what is causing this but I am assuming the pipes are being blocked or that I am not handling this correctly.
I want the server to return an error message to the client rather than handle the message error in the client itself.
I tried checking the condition if the length of the command is 0 and handling it with an error message but it did not work and still hangs.
The program also seems to hang when I try for example the date command.
In general, how do I handle the condition if a command is not recognized, empty or doesn't execute successfully?
TCP has no concept of an empty message. TCP has no concept of a message at all, it knows only bytes. Thus, if you call send with an empty string it will simply send nothing (not an empty packet but no packet at all) to the server which means that there is nothing for the server to receive - it will still block while waiting for data. In other words: there is no empty command, there is simply no comment at all.
if len(command) == 0:
This will not check for an empty message (which again does not exist) but will trigger if the client closes the connection. Any check for an empty command had to be done at the client already.

Remote Command Execution Python

For educational purposes, I set up a server that allows remote command execution on Windows - or rather, I tried to. For some reason, the command line refuses to recognize some of the commands I send, but others work fine. For instance, sending the command echo "Hello World!!!" causes, as it should, a cmd window to pop up reading "Hello World!!!". Fine. But when I send the command shutdown /s /t 30 it gives me the improper syntax / help screen for the shutdown command. When I send the command msg * "Hello World" it tells me that 'msg' is not a recognized internal or external command, operable program, or batch file. Here is my server code:
import socket
import sys
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_address = ('', 4242)
sock.bind(server_address)
sock.listen(1)
connection, client_address = sock.accept()
print("Connection established with %s " % str(client_address))
while True:
command = input("Enter a command: ")
connection.send(bytes(command, 'UTF-8'))
confirm = connection.recv(128)
if confirm == "yes":
print("[+] Command executed successfully.")
else:
print("[-] Command failed to execute!!!")
And here is my client code:
import socket
import sys
import os
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_address = ('', 42042)
sock.bind(server_address)
sock.connect(('192.168.1.5', 4242))
while True:
command = str(sock.recv(1024))
try:
os.system(command[2:]) # an odd thing, the commands somehow came out prefaced with "b'". Ideas?
sock.send(bytes("yes", 'UTF-8'))
except:
sock.send(bytes("no", 'UTF-8'))
So yeah, that's that. The fact that only SOME commands are getting screwed up is really confusing me. Anybody have any ideas? Also, what's up with that "b'"?
str(sock.recv(1024)) is not the way to convert a bytes object into a string, you should be using the sock.recv(1024).decode('UTF-8') method
You can look at the documentation for bytes.decode https://docs.python.org/3.4/library/stdtypes.html#bytes.decode
Or this related question Best way to convert string to bytes in Python 3?

Categories