Java can't run cmd-command's properly - java

I am attempting to generate a list of all installed Programs on my Windows machine.
This is the command I am using:
WMIC /output:D:\miep product get name && type D:\miep > D:\miep_
You might have realized that I'm also trying to make a type-Command as I need the output in UTF-8.
I made a Whitelist for this with a simple loop where I will look later where in my file certain Names will appear and keep them while I remove everything else.
The command works in the command prompt, but when I try to do the same inside my Java Program it keeps telling me I've got an Invalid GET-Expression ...
Here is my function:
void createLists() throws IOException {
//String cmd = "WMIC /output:D:\\miep.csv product get name /format:\"%WINDIR%\\System32\\wbem\\de-DE\\csv.xsl\"";
String cmd = "WMIC /output:D:\\miep product get name && type D:\\miep > D:\\miep_";
System.out.println(cmd);
Process p;
p = Runtime.getRuntime().exec(cmd);
p.getOutputStream().close();
String line;
BufferedReader stdout = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((line = stdout.readLine()) != null) {
System.out.println(line);
}
stdout.close();
BufferedReader stderr = new BufferedReader(new InputStreamReader(p.getErrorStream()));
while ((line = stderr.readLine()) != null) {
System.out.println(line);
}
stderr.close();
System.out.println("Done");
}
I also tried the converting stuff with the .csv files as you might have seen in the second line of my code and the same:
Works in CMD, but not in my Java-Program..!
Here it keeps telling me that it's an Invalid XSL-Format
Can someone help?

Related

Why does the output of my shell script doesn't print in console?

I am trying to print the output of a shell script on the console using java. When I manually run the script, I get
C:/Users/user1/Desktop/shell.sh: line 78: /usr/ucb/ps: No such file or directory
<STATUS>: Probe [ devicename ] is not running!
But, when I try to run it on my Java program, the output is not being printed on the console.
My code is:
ProcessBuilder processBuilder = new ProcessBuilder("C:/Program Files/Git/git-bash.exe","C:/Users/user1/Desktop/shell.sh");
try {
Process process = processBuilder.start();
StringBuilder output = new StringBuilder();
BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
output.append(line + "\n");
System.out.println(line);
}
int exitVal = process.waitFor();
if (exitVal == 0) {
System.out.println("Success!");
System.out.println(output);
System.exit(0);
} else {
//abnormal...
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
The only output I am getting is "Success". When I debugged my code, I found that the code never enters the condition
while ((line = reader.readLine()) != null)
even though, in the bash terminal, there are lines of output. Why is this happening?
I am stuck at this point and I couldn't find any other explanations for this problem. Kindly help.
You are running git-bash.exe which opens as a windows application. Although Java has access to the stdout/stderr streams of git-bash.exe, these are not necessarily the same as the stdout/err of the internal launch of your shell script within git-bash.exe.
One way to see the stdout/err of your command would be to make a java friendly version of the .sh script which launches your original sh and redirects output to a specific files which you can then access within java afterwards.
ProcessBuilder pb = new ProcessBuilder("C:/Program Files/Git/GIT-BASH.EXE","/c/Users/blah/somescript.sh");
somescript.sh:
#!/bin/sh
runtheoriginalcommand > ~/somepath.out 2> ~/somepath.err
You could also add extra args to wrapper to pass the out/err files to be used so there is no contention with any other launches or hardcoded output files.

How does java Runtime.getRuntime().exec(...) search for executables on windows?

I'm trying to do a proof of concept exploit to show how changing the path variable can replace standard programs for malicious ends. I put a dummy program called "cmd.exe" in a directory "C:\path\to\fake_exe\" and changed the path to have that at the front.
Below is the function I'm using to demonstrate, but it runs normally (i.e., it passes the arguments to the correct cmd.exe instead of my fake one). I even passed "cmd" to the function, and it opened my dummy program! So the path variable is definitely set to find my fake cmd.exe correctly, but the exec(..) function is finding the proper cmd.exe regardless.
How does the exec(...) function find executables? Where is this documented?
static void unsafeExec(String cmd) throws IOException, InterruptedException {
String[] run = new String[3];
run[0] = "cmd.exe";
run[1] = "/C";
run[2] = cmd;
Process p = Runtime.getRuntime().exec(run);
BufferedReader stdIN = new BufferedReader(new InputStreamReader(p.getInputStream()));
BufferedReader stdER = new BufferedReader(new InputStreamReader(p.getErrorStream()));
p.waitFor();
String s;
while ((s = stdIN.readLine()) != null) {
System.out.println(s);
}
while ((s = stdER.readLine()) != null) {
System.out.print(s);
}
}

Java function to toggle socket state via raspberry pi

I have a function in java which is being executet on my raspberry pi and should send a signal to toggle the targeted sockets state to on / off.
Thats my current function:
public static void rcswitch(int housecode,int unitcode, int onoff) throws InterruptedException, IOException {
String housestring = Integer.toString(housecode);
String unitstring = Integer.toString(unitcode);
String onoffstring = Integer.toString(onoff);
ProcessBuilder builder = new ProcessBuilder("/bin/bash", "-c", "sudo /home/pi/rcswitch-pi/send", housestring, unitstring, onoffstring);
Process proc = builder.start();
BufferedReader reader =
new BufferedReader(new InputStreamReader(proc.getInputStream()));
String line = "";
while((line = reader.readLine()) != null) {
System.out.print(line + "\n");
}
}
However, it doesn't seem like the terminal is receiving the command as it does not output anything. It should show something like "command received" and execute it then. When I normally execute the /send command in the terminal it works just fine. In eclipse it just works fine and throws the expected error.
Thanks for your answers :)
It is most likely that an error has occured while executing the command. Keep in mind that Process#getInputStream() does not include standard error stream of the process. You should use Process#getErrorStream(). Something like:
BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getErrorStream()));
String line = null;
while((line = reader.readLine()) != null) {
System.out.print(line + "\n");
}

Running Python scripts in Java

I'm trying to run a python script during the execution of my java code, because it will depend on the output received from the python script. So far I've tried using jythonc, unfortunately to no success, and now im trying to use the java Runtime and java Process to execute the python script.
Now I've run into a problem when trying to call the python script. I feel as though it doesn't even call the script because it takes less than a couple seconds to get to the next page....
Could the problem be how I am calling the python script?? I am trying to run this through a web application...
Here is some of my code:
String run = "cmd /c python duplicatetestingoriginal.py" ;
boolean isCreated = fwr.writeFile(BugFile, GD, 500, true, 5, "LET");
if(isCreated){
try{
r = Runtime.getRuntime();
p = r.exec(run);
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));
String line = "";
while ((line = stdInput.readLine()) != null) {
System.out.println(line);
}
while ((line = stdError.readLine()) != null) {
errorW.write(line);
}
int exitVal = p.waitFor();
arrayList = fwr.readResults();
}catch(Exception e){
}
}
else{
// troubleshoot....
}
Instead of String for the command, split it to chunks and make a String[]. No need to state cmd /c, I think.
This is a sample code from my application:
//Running on windows
command = new String[4];
command[0]=directory.getCanonicalPath()+"/data/ExtenalApp.exe"; //extenal commandline app, not placed in path, but in subfolder
command[1]=directory.getCanonicalPath()+"/data/SomeFile.txt"; //file needed for the external app, sent as an argument
command[2]=arg1; //argument for the app
command[3]=arg2; //argument for the app
//Running on Mac
command = new String[6];
command[0]="python";
command[1]=directory.getCanonicalPath()+"/data/wp.py"; //path to the script
command[2]="-F"; //argument/Flag/option
command[3]="--dir="+path; //argument/option
command[4]="--filename="+filename; //argument/option
command[5]=argument; //argument/option
Process process = Runtime.getRuntime().exec(command);
process.waitFor();
process.destroy();
I don't handle the Input/Output streams because the script/app doesn't require input, and outputs only when finished, nothing important. Which might not be the case for you.

ProcessBuilder to execute custom executable

Okay, I have tried a dozen different ways and no success. I want to execute a custom exe and grab the output. It runs fine from the command prompt. I get the "dir" to work fine, but not custom.exe. Here is the code:
List<String> command = new ArrayList<String>();
command.add("cmd"); // Even removed these two lines
command.add("/c"); // aka hail mary coding.
//command.add("dir");
command.add("custom.exe"); // even tried "c://custom.exe"
String line;
Process p = new ProcessBuilder(command).start();
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((line = input.readLine()) != null) {
System.out.println(line);
}
I get no output at all. If I place it in a batch file, i get output. I have a feeling it has something to do with %PATH%. Back at it...
EDIT--> So turns out that the output from this custom exe goes to error, so to see what is happening i have the code:
List<String> command = new ArrayList<String>();
command.add(System.getenv("ProgramFiles(x86)") + "\\mydir\\custom.exe";
String line;
ProcessBuilder pb = new ProcessBuilder(command);
pb.redirectErrorStream(true);
Process p = pb.start();
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((line = input.readLine()) != null) {
System.out.println(line);
}
And it works like a hot damn. :)
You don't need the lines
command.add("cmd");
command.add("/c");
That would only be required for a batch file. I would rather specify the full path to the executable.
Maybe the output is on stderr? Try replacing p.getInputStream() with p.getErrorStream().

Categories

Resources