I want to connect to 2018shell.picoctf.com by netcat using python. I need to read output(which I accomplished) and later write "210.205.230.140" and send it to the server.
import subprocess
proces = subprocess.Popen(["nc", "2018shell.picoctf.com", "14079"],
stdout=subprocess.PIPE,
stdin=subprocess.PIPE)
data = proces.communicate(input=b'210.205.230.140')
I don't know why program gets stuck in proces.communicate(input=b'210.205.230.140') and I can't send it to subproces and get next messages sent by server or execute next commands.
Related
First, thank for fixing my post. I'm still not sure how to include a sketch. I've been reading posts here for many months, but never posted one before.
My headless RasPi is running two sketches of mine, one reads data from a pm2.5 sensor (PMS7003) and the other is the program listed above that sends information to another Pi, the client, that turns on a pm2.5 capable air filter. (I live in California) The program that reads the PMS7003 sorts the data, called max_index, into one of six categories, 0 thru 5 and saves the current category to a text file. I'm using the 'w' mode during the write operation, so there is only one character in the text file at any time. The server program listed above reads the text file and sends it to a client that turns on the air filter for categories above 2. The client sends the word "done" back to the server to end the transaction.
Until you mentioned it, I didn't realize my mistake, clientsocket.recv(2). I'll fix that and try again.
So, the listener socket should go outside the while loop, leaving the send and receive inside???
Troubleshooting: I start the two programs using nice nohup python3 xxx.py & nice nohup python3 yyy.py. The program that reads the PMS7003 continues running and updating the text file with current category, but the server program falls out of existence after a few days. top -c -u pi reveals only the PMS7003 program running, while the server program is missing. Also, there's nothing in nohup.out or in socketexceptions.txt and I tried looking through system logs in /var/log but was overwhelmed by information and found nothing that made any sense to me.
Since writing to the socketexceptions.txt file is not in a try/except block, the crash might be happening there.
import socket
import time
index = " "
clientsocket = ""
def getmaxindex():
try:
with open('/home/pi/pm25/fan.txt','r')as f:
stat = f.read() #gets max_index from pm25b.py
return(stat)
except:
with open("/home/pi/pm25/socketexceptions.txt",'a')as f:
f.write("Failed to read max index")
def setup(index):
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,1)
s.bind(("192.168.1.70", 5050))
except:
with open("/home/pi/pm25/socketexceptions.txt",'a')as f:
f.write("Failed to bind")
try:
s.listen(1)
clientsocket, address = s.accept()
clientsocket.send(index)
rx = clientsocket.recv(2)
if rx == "done":
clientsocket.close()
except:
with open("/home/pi/pm25/socketexceptions.txt",'a')as f:
f.write("Failed to communicate with flient")
while True:
index = getmaxindex().encode('utf-8')
setup(index)
time.sleep(5)
enter code here
It is unknown what program is supposed to do and where exactly you run into problems, since there is only a code dump and no useful error description (what does "stop" mean - hang or exit, where exactly does it stop). But the following condition can never be met:
rx = clientsocket.recv(2)
if rx == "done":
The will receive at most 2 bytes (recv(2)) which is definitely not enough to store the value "done".
Apart from that it makes not real sense to recreate the same listener socket again and again, just to accept a single client and exchange some data. Instead the listener should only be created once and multiple accept should be called on the same listener socket, where each will result in a new client connection.
I'm developing a Python code that can run two applications and exchange information between them during their run time.
The basic scheme is something like:
start a subprocess with the 1st application
start a subprocess with the 2nd application
1st application performs some calculation, writes a file A, and waits for input
2nd application reads file A, performs some calculation, writes a file B, and waits for input
1st application reads file B, performs some calculation, writes a file C, and waits for input
...and so on until some condition is met
I know how to start one Python subprocess, and now I'm learning how to pass/receive information during run time.
I'm testing my Python code using a super-simple application that just reads a file, makes a plot, closes the plot, and returns 0.
I was able to pass an input to a subprocess using subprocess.communicate() and I could tell that the subprocess used that information (plot opens and closes), but here the problems started.
I can only send an input string once. After the first subprocess.communicate() in my code below, the subprocess hangs there. I suspect I might have to use subprocess.stdin.write() instead, since I read subprocess.communicate() will wait for the end of the file and I wish to send multiple times different inputs during the application run instead. But I also read that the use of stdin.write() and stdout.read() is discouraged. I tried this second alteranative (see #alternative in the code below), but in this case the application doesn't seem to receive the inputs, i.e. it doesn't do anything and the code ends.
Debugging is complicated because I haven't found a neat way to output what the subprocess is receiving as input and giving as output. (I tried to implement the solutions described here, but I must have done something wrong: Python: How to read stdout of subprocess in a nonblocking way, A non-blocking read on a subprocess.PIPE in Python)
Here is my working example. Any help is appreciated!
import os
import subprocess
from subprocess import PIPE
# Set application name
app_folder = 'my_folder_path'
full_name_app = os.path.join(app_folder, 'test_subprocess.exe')
# Start process
out_app = subprocess.Popen([full_name_app], stdin=PIPE, stdout=PIPE)
# Pass argument to process
N = 5
for n in range(N):
str_to_communicate = f'{{\'test_{n+1}.mat\', {{\'t\', \'y\'}}}}' # funny looking string - but this how it needs to be passed
bytes_to_communicate = str_to_communicate.encode()
output_communication = out_app.communicate(bytes_to_communicate)
# output_communication = out_app.stdin.write(bytes_to_communicate) # alternative
print(f'Communication command #{n+1} sent')
# Terminate process
out_app.terminate()
I have a command-line program which when triggered provides a list of options and prompts the user to select an option to continue.
Now I have launched the command line program using subprocess call, now the command line program prompts for the value, how do I pass the value from user to the command line program via subprocess call?
subprocess.call just waits for the process to finish and gives return code, no way to interact with it. if you instead use subprocess.Popen that gives you the ability to communicate with the subprocess while it is running via stdin and stdout
import subprocess, sys
program = subprocess.Popen("python3",
# give us a pipes to coommunicate
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
data = input("input to subprocess")
[out,err] = program.communicate((data+"\n").encode())
print(out.decode())
print(err.decode(), file=sys.stderr)
Doing a bit of input then some output then more input can get messy though since there reading from stdout is blocking so determining when the output has stopped for more input is tricky.
I was reading << Black Hat Python >> and trying the first bhnet.py program.
On one terminal, I run script
./bhnet.py -l -p 9999 -c
And on another terminal, run script
./bhnet.py -t localhost -p 9999
then type
<ctrl-D>
or
ls -alt
<ctrl-D>
The first terminal would return
File "bhnet.py", line 186, in client_handler
cmd_buffer += client_socket.recv(1024).decode('utf-8')
ConnectionResetError: [Errno 54] Connection reset by peer
Below are the codes for the program
def client_handler(client_socket):
global upload
global execute
global command
# check for upload
if len(upload_destination):
# read all the buffer and write to destination
file_buffer = ""
# keep reading til none is available
while True:
data = client_socket.recv(1024)
if not data:
break
else:
file_buffer += data
# take the bytes and write them out
try:
file_descriptor = open(upload_destination,'wb')
file_descriptor.write(file_buffer)
file_descriptor.close()
# acknowledge that file being wrote out
client_socket.send(f"Successfully save file to {upload_destination}.\r \n")
except:
client_socket.send(f"Failed to save file to {upload_destination}.\r \n")
# check for command execution
if command:
while True:
#pop up a window
client_socket.send(b"<BHP:#> ")
# keep receiving data until \n
cmd_buffer = ""
while "\n" not in cmd_buffer:
cmd_buffer += client_socket.recv(1024).decode('utf-8')
response = run_command(cmd_buffer)
client_socket.send(response)
I googled and even tried to upgrade openssl and none of these work...
Thanks in advance!
It's hard to be certain since you don't provide the client side code. However, I'm fairly confident this is happening:
When you type Ctrl-D, you're giving an end of file to the client's input. That is causing the client to close the socket it had previously connected to the server. Doing this causes the client's operating system to send a TCP FIN packet to the server. The FIN only tells the server that the client is finished sending data; there is no way in the normal TCP session termination of telling a peer that the peer may not send any more data.
But then the server is trying to send to the client, after the client has closed its socket. When you try to send further data on a closed socket, then the destination peer's operating system sends a TCP RST packet. That isn't actually reported to the server on the send because the send function call is complete when the data is copied into the kernel -- whereas the RST is probably received by the kernel a few milliseconds later after it actually sent a data packet to the peer.
Hence that condition will be reported on the next operation on the socket which, here, is recv. Hence your program gets back an ECONNRESET error, which python translates into ConnectionResetError exception.
In other words:
Client Server
------ ------
close()
FIN => <OS receives FIN>
send(data)
<= "data"
RST =>
recv
<ECONNRESET>
One more thing: Depending on the exact timing, it's possible that your first call to recv in that loop is actually getting an end-of-file indicator (i.e. zero bytes). However, you're not checking for that, you just keep calling recv as long as there is no newline in the buffer. You really should be checking whether you got a zero byte string back from recv and terminate your loop in that case.
Once you've gotten the end-of-file indicator on the socket, you'll never get a newline added to the buffer. If the client had actually managed to receive the data you sent it before it closed the socket, then no RST would have been sent. In that case, your recv loop would run potentially forever, getting back zero bytes continuously but never finding the newline.
I am beginner in Python, ZMQ,networking or even coding in general, so please pardon my mistakes.
I am trying to send instructions to open notepad.exe from my desktop to my laptop like this:
MAIN SERVER
import zmq
import subprocess
try:
raw_input
except NameError:
raw_input = input #for python 3
#This will handle all the sockets we will open on the mainServer
context = zmq.Context()
#Socket 1 - Using for instructions
instructions = context.socket(zmq.PUSH)
instructions.bind("tcp://*:5555")
#Socket 2 - Using for end of finished instructions
#doneWork = context.socket(zmq.PULL)
#instructions.bind("tcp://*:5556")
#Now we will press enter when the workers are ready
print("Press Enter when you want to send the instructions. Make sure test devices are ready")
_=raw_input()
print ("Sending tasks to test device. . .")
instruction_One= "subprocess.call(['C:\notepad.exe'])"
instructions.send_string('%s' %instruction_One)
and
CLIENT
import zmq
import sys
context = zmq.Context()
instructions = context.socket(zmq.PULL)
instructions.connect("tcp://192.168.0.12:5555")
while True:
instruction_One=instructions.recv()
string_of_instruction = instruction_One.decode("utf-8")
sys.std.out.write(string_of_instruction)
sys.std.out.flush()
I am sending the instructions in terms of string which encoded into binary through the socket. But on the client side (laptop), whatever I am fetching cannot be executed through command line. What is the stupid mistake I am making?
I found out the fix.
instead of sys, I have used subprocess.
subprocess(command, shell=True)
Thanks