iNoob
iNoob

Reputation: 1395

I am having problems with Pythons `subprocess.popen` hanging

I have a simple function that calls the same subprocess.popen command on multiple items from a list. It executes the first 2 items in the list no problem, however the action on the third hangs.

It seems that the process_null.communicate() never executes or doesnt finish at least as I never get the output from the 3rd item in the list. I have tried changing the list, but get the same results. Any ideas to whats going on here?

def check_list(server_list):
    null_list = []

    for target in server_list:
        command_null="rpcclient -N -U '' {}". format (str(target))
        process_null = subprocess.Popen(command_null, shell=True, stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
        output_null = process_null.communicate()[0].replace('\n','')

        if "NT_STATUS_ACCESS_DENIED" in output_null or "NT_STATUS_CONNECTION_REFUSED" in output_null or "NT_STATUS_UNSUCCESSFUL" in output_null:
            print '[-]  ' + target + '\tDenied NULL Session'
        else:
            print '[+]  ' + target + '\tAccepted NULL Session'
            null_list.append(target)


    return null_list

Output

[-]  192.168.1.3    Denied NULL Session
[-]  192.168.1.65   Denied NULL Session

Upvotes: 0

Views: 113

Answers (1)

mata
mata

Reputation: 69012

When rpcclient successfully establishes a connection it starts a shell and waits for commands to be entered on stdin if none are given using the -c flag, which is what happens here. You don't see the prompt because you redirect all output (stdout + stderr) to a pipe, but you don't do the same for stdin, which means the input will be read from the same tty the python interpreter is running on.

Also, you shouldn't use shell=True with a string argument if not absolutely necessary, use a list of arguments instead:

command_null = ['rpcclient', '-N', '-U', '', str(target)]

To fix your problem you have two options:

  • supply a command to execute when successfully connected:

    command_null = ['rpcclient', '-N', '-U', '', '-c', 'exit', str(target)]
    
  • use stdin=PIPE when opening the process, which causes rcpclient to exit when stdin is closed by communicate():

    process_null = subprocess.Popen(command_null, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=subprocess.PIPE)
    

Upvotes: 2

Related Questions