So I have a vulnerable program which is to be exploited using buffer overflow. After analysis I have all the relevant values(buffer size, the address to be injected ,etc )
The issue is that I need to automate the inputs given to it.
Precisely here's what happens :
the program asks for a normal input -- (No vulnerability present here)
It asks for a second input -- this is to be injected with the shellcode
I have tried sending the input from the file (by writing it with the payload say python -c 'print '.. blah blah), but the file somehow sends the ascii representation and messes up with the desired input
Things I have tried : Wrote a shell script like this :
echo -e "<first input>\r";
python -c 'print "A"*100 + "<shell code>"+"<ret>";
after this I send this file as an input : $ ./vuln < File
Is there anyway that I send the output from python when the program is prompting for the second input ?
You can use expect, a program used to automate interactions with programs that expose text terminal interfaces.
The script should look like this:
#!/usr/bin/expect
spawn programUnderTest
expect firstPrompt
send firstInput
expect secondPrompt
send secondInput
Related
I am trying to trigger the python script or shell script whenever a desktop notification has arrived using dbus-monitor
I am using the command in this way
dbus-monitor "interface='org.freedesktop.Notifications'" | grep --line-buffered "string" | xargs -I '{}' python3 ./test.py {}
after that, I am trying to send the desktop notification from another terminal using
-> notify-send "hello" "world"
the output for the above custom notification is
string "notify-send"
string ""
string "hello"
string "world "
string "urgency"
string "notify-send"
string ""
string "hello"
string "world "
string "urgency"
but if my output of this command is 10 lines, then the python script is getting called for every line.
but my expectation is to call the python script once for every notification and then get all the output in a single line as a param for the python script.
It is wise to take advantage of systemd integration with dbus.
Using systemd integration the programmer has better controls/sensors over the dbus integration. Also can take advantage on systemd loging/monitors mechanisms.
There is a good article here about systemd dbus with python..
Also there is very related answer to your question in this answer. as well.
I'm trying to make some functions in python so that I can connect to a linux terminal and do stuff (like in this case, create a file). The code I have, works partially. The only thing that doesn't work is if you want to do something after you have entered the code. Like for instance you create the file and then want to navigate somewhere else (cd /tmp) for instance. Instead of doing the next command, it will just add to the file created.
def create_file(self, name, contents, location):
try:
log.info("Creating a file...")
self.device.execute("mkdir -p {}".format(location))
self.cd_path(location)
self.device.sendline("cat > {}".format(name))
self.device.sendline("{}".format(contents))
self.device.sendline("EOF") # send the CTRL + D command to save and exit I tried here with ^D as well
except:
log.info("Failed to create the file!")
The contents of the file is:
cat test.txt
#!/bin/bash
echo "Fail Method Requested"
exit 1
EOF
ls -d /tmp/asdasd
The order of commands executed is:
execute.create_file(test.txt, the_message, the_location)
execute.check_path("/tmp/adsasd") #this function just checks with ls -d if the directory exists.
I have tried with sendline the following combinations:
^D, EOF, <<EOF
I don't really understand how I could make this happen. I just want to create a file with a specific message. (When researching on how to do this with VI I got the same problem, but there the command I needed was the one for ESC)
If anyone could help with some input that would be great!!
Edit: As Rob mentioned below, sending the character "\x04" actually works. For anyone else having this issue, you can also consult this chart for other combinations if needed:
http://donsnotes.com/tech/charsets/ascii.html
You probably need to send the EOF character, which is typically CONTROL-D, not the three characters E, O, and F.
self.device.sendline("\x04")
http://wiki.bash-hackers.org/syntax/redirection#here_documents
Here docs allow you to use any file input termination string you like to represent end of file ( such as the literal EOF you're attempting to use now). Quoting that string tells the shell not to interpret expansions inside the heredoc content, ensuring that said content is treated as literal.
Using pipes.quote() here ensures that filenames with literal quotes, $s, spaces, or other surprising characters won't break your script. (Of course, you'll need to import pipes; on Python 3, by contrast, this has moved to shlex.quote()).
self.device.sendline("cat > {} <<'EOF'".format(pipes.quote(name)))
Then you can write the EOF as is, having told bash to interpret it as the end of file input.
Background
I'm working on a bash script to pull serial numbers and part numbers from all the devices in a server rack, my goal is to be able to run a single script (inventory.sh) and walk away while it generates text files containing the information I need. I'm using bash for maximum compatibility, the RHEL 6.7 systems do have Perl and Python installed, however they have minimal libraries. So far I haven't had to use anything other than bash, but I'm not against calling a Perl or Python script from my bash script.
My Problem
I need to retrieve the Serial Numbers and Part numbers from the drives in a Dot Hill Systems AssuredSAN 3824, as well as the Serial numbers from the equipment inside. The only way I have found to get all the information I need is to connect over SSH and run the following three commands dumping the output to a local file:
show controllers
show frus
show disks
Limitations:
I don't have "sshpass" installed, and would prefer not to install it.
The Controller is not capable of storing SSH keys ( no option in custom shell).
The Controller also cannot write or transfer local files.
The Rack does NOT have access to the Internet.
I looked at paramiko, but while Python is installed I do not have pip.
I also cannot use CPAN.
For what its worth, the output comes back in XML format. (I've already written the code to parse it in bash)
Right now I think my best option would be to have a library for Python or Perl in the folder with my other scripts, and write a script to dump the commands' output to files that I can parse with my bash script. Which language is easier to just provide a library in a file? I'm looking for a library that is as small and simple as possible to use. I just need a way to get the output of those commands to XML files. Right now I am just using ssh 3 times in my script and having to enter the password each time.
Have a look at SNMP. There is a reasonable chance that you can use SNMP tools to remotely extract the information you need. The manufacturer should be able to provide you with the MIBs.
I ended up contacting the Manufacturer and asking my question. They said that the system isn't setup for connecting without a password, and their SNMP is very basic and won't provide the information I need. They said to connect to the system with FTP and use "get logs " to download an archive of the configuration and logs. Not exactly ideal as it takes 4 minutes just to run that one command but it seems to be my only option. Below is the script I wrote to retrieve the file automatically by adding the login credentials to the .netrc file. This works on RHEL 6.7:
#!/bin/bash
#Retrieve the logs and configuration from a Dot Hill Systems AssuredSAN 3824 automatically.
#Modify "LINE" and "HOST" to fit your configuration.
LINE='machine <IP> login manage password <password>'
HOST='<IP>'
AUTOLOGIN="/root/.netrc"
FILE='logfiles.zip'
#Check for and verify the autologin file
if [ -f $AUTOLOGIN ]; then
printf "Found auto-login file, checking for proper entry... \r"
READLINE=`cat $AUTOLOGIN | grep "$LINE"`
#Append the line to the end of .netrc if file exists but not the line.
if [ "$LINE" != "$READLINE" ]; then
printf "Proper entry not found, creating it... \r"
echo "$LINE" >> "$AUTOLOGIN"
else
printf "Proper entry found... \r"
fi
#Create the Autologin file if it doesn't exist
else
printf "Auto-Login file does not exist, creating it and setting permissions...\r"
echo "$LINE" > "$AUTOLOGIN"
chmod 600 "$AUTOLOGIN"
fi
#Start getting the information from the controller. (This takes a VERY long time)
printf "Retrieving Storage Controller data, this will take awhile... \r"
ftp $HOST << SCRIPT
get logs $FILE
SCRIPT
exit 0
This gave me a bunch of files in the zip, but all I needed was the "store_....logs" file. It was about 500,000 lines long, the first portion is the entire configuration in XML format, then the configuration in text format, followed by the logs from the system. I parsed the file and stripped off the logs at the end which cut the file down to 15,000 lines. From there I divided it into two files (config.xml and config.txt). I then pulled the XML output of the 3 commands that I needed and it to the 3 files my previously written script searches for. Now my inventory script pulls in everything it needs, albeit pretty slow due to waiting 4 minutes for the system to generate the zip file. I hope this helps someone in the future.
Edit:
Waiting 4 minutes for the system to compile was taking too long. So I ended up using paramiko and python scripts to dump output from the commands to files that my other code can parse. It accepts the IP of the Controller as a parameter. Here is the script for those interested. Thank you again for all the help.
#!/usr/bin/env python
#Saves output of "show disks" from the storage Controller to an XML file.
import paramiko
import sys
import re
import xmltodict
IP = sys.argv[1]
USERNAME = "manage"
PASSWORD = "password"
FILENAME = "./logfiles/disks.xml"
cmd = "show disks"
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
client.connect(IP,username=USERNAME,password=PASSWORD)
stdin, stdout, stderr = client.exec_command(cmd)
except Exception as e:
sys.exit(1)
data = ""
for line in stdout:
if re.search('#', line):
pass
else:
data += line
client.close()
f = open(FILENAME, 'w+')
f.write(data)
f.close()
sys.exit(0)
Is there any easy way to handle multiple lines user input in command-line Python application?
I was looking for an answer without any result, because I don't want to:
read data from a file (I know, it's the easiest way);
create any GUI (let's stay with just a command line, OK?);
load text line by line (it should pasted at once, not typed and not pasted line by line);
work with each of lines separately (I'd like to have whole text as a string).
What I would like to achieve is to allow user pasting whole text (containing multiple lines) and capture the input as one string in entirely command-line tool. Is it possible in Python?
It would be great, if the solution worked both in Linux and Windows environments (I've heard that e.g. some solutions may cause problems due to the way cmd.exe works).
import sys
text = sys.stdin.read()
After pasting, you have to tell python that there is no more input by sending an end-of-file control character (ctrl+D in Linux, ctrl+Z followed by enter in Windows).
This method also works with pipes. If the above script is called paste.py, you can do
$ echo "hello" | python paste.py
and text will be equal to "hello\n". It's the same in windows:
C:\Python27>dir | python paste.py
The above command will save the output of dir to the text variable. There is no need to manually type an end-of-file character when the input is provided using pipes -- python will be notified automatically when the program creating the input has completed.
You could get the text from clipboard without any additional actions which raw_input() requires from a user to paste the multiline text:
import Tkinter
root = Tkinter.Tk()
root.withdraw()
text = root.clipboard_get()
root.destroy()
See also How do I copy a string to the clipboard on Windows using Python?
Use :
input = raw_input("Enter text")
These gets in input as a string all the input. So if you paste a whole text, all of it will be in the input variable.
EDIT: Apparently, this works only with Python Shell on Windows.
I am using pexpect with python to create a program that allows a user to interact with a FORTRAN program through a website. From the FORTRAN program I am receive the error:
open: Permission denied apparent state: unit 4 named subsat.out.55 last format: list io lately writing sequential formatted external IO 55
when I attempt to:
p = pexpect.spawn(myFortranProgram,[],5)
p.logfile_read = sys.stdout
p.expect("(.*)")
p.sendline("55")
From what I understand, I am likely sending the 55 to the wrong input unit. How do I correctly send input to a FORTRAN program using pexpect in Python?
Thank You.
Edit: When p.sendline's parameter is empty (e.g. p.sendline()) or only contains spaces, the program proceeds as expected. In sending non-space values to a FORTRAN program, do I need to specify the input format somehow?
The pexpect module is something I'd not used before, but could be useful to me, so I tried this.
Edit:
I've not been able to duplicate the error you're reporting. Looking at this error leads me to believe that it has something to do with reading from a file, which may be a result of other issues. From what I've seen, this isn't what pexpect is designed to handle directly; however, you may be able to make it work with a pipe, like the example in my original answer, below.
I'm having no problem sending data to Fortran's I/O stream 5 (stdin). I created a Fortran program called regurgitate which issues a " Your entry? " prompt, then gets a line of input from the user on I/O stream 5, then prints it back out. The following code works with that program:
import pexpect
child = pexpect.spawn('./regurgitate')
child.setecho(False)
ndx = child.expect('.*Your entry?.*')
child.sendline('42')
child.expect([pexpect.EOF])
print child.before
child.close()
The output is simply:
42
Exactly what I expected. However, if my Fortran program says something different (such as "Your input?"), the pexpect just hangs or times out.
Original suggestion:
Maybe this pexpect.run() sample will help you. At least it seems to run my regurgitate program (a simple Fortran program that accepts an input and then prints it out):
import pexpect
out = pexpect.run('/bin/bash -c "/bin/cat forty-two | ./regurgitate"')
print out
The output was:
Your entry?
42
Where regurgitate prints out a "Your entry?" prompt and the forty-two file contains "42" (without quotes in both cases).