No output from Runtime.getRuntime().exec("ls") - java

ping and date returned output, but it's not returning anything from "ls" or "pwd". What I want to do ultimately is run an SSH command. Any idea what I am missing below?
//Works and shows the output
executeCommand("ping -c 3 " + "google.com");
//Works and shows the output
executeCommand("date");
//Does not work. No output
executeCommand("sudo ls");
//Does not work. No output
executeCommand("ls");
private void executeCommand(String command) {
StringBuffer output = new StringBuffer();
Process p;
try {
p = Runtime.getRuntime().exec(command);
p.waitFor();
BufferedReader reader =
new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = "";
while ((line = reader.readLine())!= null) {
output.append(line + "\n");
}
} catch (Exception e) {
e.printStackTrace();
}
Log.d("Output", "Output: " + output.toString());
}

I have two solutions
first solution (you need Java 7):
...
ProcessBuilder pb = new ProcessBuilder("ls");
pb.redirectOutput(Redirect.INHERIT);
Process p = pb.start();
second solution:
Process p=Runtime.getRuntime().exec("ls");
InputStream is = p.getInputStream();
int c;
StringBuilder commandResponse = new StringBuilder();
while( (c = is.read()) != -1) {
commandResponse.append((char)c);
}
System.out.println(commandResponse);
is.close();

Related

Command injection attack: tempered input value with &&

Controller:
#PostMapping("/output/")
#ResponseBody
public Object command_injected(#RequestParam String command) {
Map<String, String> response_data = new HashMap<String, String>();
try {
String output = "";
Process p = Runtime.getRuntime().exec("ping -c 3 " + command) ;
String line = "";
BufferedReader inputStream = new BufferedReader(new InputStreamReader(p.getInputStream()));
BufferedReader errorStream = new BufferedReader(new InputStreamReader(p.getErrorStream()));
while ((line = inputStream.readLine()) != null) {
output += line + "<br/>";
}
inputStream.close();
while ((line = errorStream.readLine()) != null) {
output += line + "<br/>";
}
errorStream.close();
p.waitFor();
response_data.put("status", "success");
response_data.put("msg", output);
return response_data;
} catch (Exception e) {
e.printStackTrace();
response_data.put("status", "error");
response_data.put("msg", "No output found");
return response_data;
}
}
example input (Linux):
8.8.8.8 && ls && whoami
To show a command injection attack, I want to temper my input using &&. If I enter only IP address, this thing works. If I enter the above example, things are not ok and giving me the following:
ping: whoami: Temporary failure in name resolution
Please help!!

How to read first five character from buffered reader?

I have this code
Process p =Runtime.getRuntime().exec("busybox");
InputStream a = p.getInputStream();
InputStreamReader read = new InputStreamReader(a);
BufferedReader in = new BufferedReader(read);
Running it from the terminal the first lines of oupout return the version of Busybox. If I wanted to take for example the first 5 characters as I do?
While the other answers should work well too, the following will exit and close the stream after reading five characters:
Process p = Runtime.getRuntime().exec("busybox");
InputStream a = p.getInputStream();
InputStreamReader read = new InputStreamReader(a);
StringBuilder firstFiveChars = new StringBuilder();
int ch = read.read();
while (ch != -1 && firstFiveChars.length() < 5) {
firstFiveChars.append((char)ch);
ch = read.read();
}
read.close();
a.close();
System.out.println(firstFiveChars);
try
String line = in.readLine();
if(line!=null && line.length() >5)
line = line.substring(0, 5);
Do this way
Process p;
try {
p = Runtime.getRuntime().exec("busybox");
InputStream a = p.getInputStream();
InputStreamReader read = new InputStreamReader(a);
BufferedReader in = new BufferedReader(read);
StringBuilder buffer = new StringBuilder();
String line = null;
try {
while ((line = in.readLine()) != null) {
buffer.append(line);
}
} finally {
read.close();
in.close();
}
String result = buffer.toString().substring(0, 15);
System.out.println("Result : " + result);
} catch (Exception e) {
e.printStackTrace();
}
Output
Result : BusyBox v1.13.3

java write netstat in cmd

My goal is to print all the internet connections on my computer. When i type netstat on cmd i get the internet connections list. I wanted to do the same in java, automatically.
My code:
Runtime runtime = Runtime.getRuntime();
process = runtime.exec(pathToCmd);
byte[] command1array = command1.getBytes();//writing netstat in an array of bytes
OutputStream out = process.getOutputStream();
out.write(command1array);
out.flush();
out.close();
readCmd(); //read and print cmd
But with this code i get C:\eclipse\workspace\Tracker>Mais? instead of the list of connections. Obviously i'm working with eclipse, in windows 7. What am I doing wrong? I've looked in similar topics but i cound't find whats wrong. Thank you for the answers.
EDIT:
public static void readCmd() throws IOException {
is = process.getInputStream();
isr = new InputStreamReader(is);
br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
}
Try this : I was able to create a file in my default temporary directory with all the connections
final String cmd = "netstat -ano";
try {
Process process = Runtime.getRuntime().exec(cmd);
InputStream in = process.getInputStream();
File tmp = File.createTempFile("allConnections","txt");
byte[] buf = new byte[256];
OutputStream outputConnectionsToFile = new FileOutputStream(tmp);
int numbytes = 0;
while ((numbytes = in.read(buf, 0, 256)) != -1) {
outputConnectionsToFile.write(buf, 0, numbytes);
}
System.out.println("File is present at "+tmp.getAbsolutePath());
} catch (Exception e) {
e.printStackTrace(System.err);
}
You can also use an instance of java.util.Scanner to read the output of the command.
public static void main(String[] args) throws Exception {
String[] cmdarray = { "netstat", "-o" };
Process process = Runtime.getRuntime().exec(cmdarray);
Scanner sc = new Scanner(process.getInputStream(), "IBM850");
sc.useDelimiter("\\A");
System.out.println(sc.next());
sc.close();
}
final String cmd = "netstat -ano";
try {
Process process = Runtime.getRuntime().exec(cmd);
InputStream in = process.getInputStream();
InputStreamReader isr = new InputStreamReader(in);
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (Exception e) {
e.printStackTrace(System.err);
} finally{
in = null;
isr = null;
br = null;
}

Runtime.getRuntime().exec(cmd) hanging

I am executing a command which returns me the Revision number of a file; 'fileName'. But if there is some problem executing the command, then the application hangs up. What can I do to avoid that condition? Please find below my code.
String cmd= "cmd /C si viewhistory --fields=revision --project="+fileName;
Process p = Runtime.getRuntime().exec(cmd) ;
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = null;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
} catch (Exception e) {
e.printStackTrace();
}
I guess the issue is that you are only reading InputStream and not reading ErrorStream. You also have to take care that both the streams are read in parallel. It may so happen that currently the data piped from the output stream fills up the OS buffer, your exec command will be automatically be suspended to give your reader a chance to empty the buffer. But the program will still be waiting for the output to process. Hence, the hang occurs.
You can create a separate class to handle both the Input and Error Stream as follows,
public class ReadStream implements Runnable {
String name;
InputStream is;
Thread thread;
public ReadStream(String name, InputStream is) {
this.name = name;
this.is = is;
}
public void start () {
thread = new Thread (this);
thread.start ();
}
public void run () {
try {
InputStreamReader isr = new InputStreamReader (is);
BufferedReader br = new BufferedReader (isr);
while (true) {
String s = br.readLine ();
if (s == null) break;
System.out.println ("[" + name + "] " + s);
}
is.close ();
} catch (Exception ex) {
System.out.println ("Problem reading stream " + name + "... :" + ex);
ex.printStackTrace ();
}
}
}
The way you use it is as follows,
String cmd= "cmd /C si viewhistory --fields=revision --project="+fileName;
Process p = Runtime.getRuntime().exec(cmd) ;
s1 = new ReadStream("stdin", p.getInputStream ());
s2 = new ReadStream("stderr", p.getErrorStream ());
s1.start ();
s2.start ();
p.waitFor();
} catch (Exception e) {
e.printStackTrace();
} finally {
if(p != null)
p.destroy();
}
This code is based on the same idea Arham's answer, but is implemented using a java 8 parallel stream, which makes it a little more concise.
public static String getOutputFromProgram(String program) throws IOException {
Process proc = Runtime.getRuntime().exec(program);
return Stream.of(proc.getErrorStream(), proc.getInputStream()).parallel().map((InputStream isForOutput) -> {
StringBuilder output = new StringBuilder();
try (BufferedReader br = new BufferedReader(new InputStreamReader(isForOutput))) {
String line;
while ((line = br.readLine()) != null) {
output.append(line);
output.append("\n");
}
} catch (IOException e) {
throw new RuntimeException(e);
}
return output;
}).collect(Collectors.joining());
}
You can call the method like this
getOutputFromProgram("cmd /C si viewhistory --fields=revision --project="+fileName);
Note that this method will hang if the program you are calling hangs, which will happen if it requires input.

Fetch and store output from a subprocess in Java

I'm working on something that requires me to start to subprocess(command prompt) and execute some commands on it. I need to fetch the output from the subprocess and store it in a file or String.
here's what I have done so far, and it doesn't work:
public static void main(String args[])
{
try
{
Runtime RT = Runtime.getRuntime();
String command = "cmd /c start javap java.lang.String";
File file = new File("write.txt");
Writer output = new BufferedWriter(new FileWriter(file));
BufferedReader br = new(BufferedReader(newInputStreamReader(RT.exec(command).getInputStream()));
String temp = br.readLine();
while(!temp.equals(null))
{
output.write(temp);
temp = br.readLine();
}
output.close();
RT.exec("exit");
}
catch(Exception e)
{
System.out.println(e);
}
}
Start changing this:
new(BufferedReader(newInputStreamReader(
To:
new BufferedReader(new InputStreamReader(
Compile and see if you still have the problem
edit
Also, there is a good reason why you shouldn't catch Exception, you also catch programming errors like a NullPointerException
while( !temp.equals(null)) { //Throws NullPointerExceptin when temp is null
Change it with:
while( temp != null ) { //!temp.equals(null)) {
Finally you don't have to "exit" since you're not inside the cmd really.
Corrected version
This version runs as you intend:
import java.io.*;
class Rt {
public static void main(String args[]) throws Exception {
Runtime RT = Runtime.getRuntime();
String command = "javap java.lang.String" ;
File file = new File("write.txt");
Writer output = new BufferedWriter(new FileWriter(file));
BufferedReader br = new BufferedReader(new InputStreamReader(RT.exec(command).getInputStream()));
String temp = br.readLine();
while( temp != null ) { //!temp.equals(null)) {
output.write(temp);
temp = br.readLine();
}
output.close();
//RT.exec("exit");
}
}
edit
Final remarks:
Since Java 1.5 the preferred way to invoke a command is using ProcessBuilder and it is better if you use an array of strings instead of a single string ( or varargs ).
When you're building your output you can get rid of the file object and pass the file name directly to the filewriter.
While reading the line you can assign and evaluate in the condition.
Java's coding conventions suggest to use the opening brace in the same like.
This would be my version of your code:
class Rt {
public static void main(String args[]) throws Exception {
Writer output = new BufferedWriter(new FileWriter ( "write.txt"));
InputStream in = new ProcessBuilder("javap", "java.lang.String").start().getInputStream();
BufferedReader br = new BufferedReader( new InputStreamReader(in));
String line = null;
while( ( line = br.readLine() ) != null ) {
output.write( line );
}
output.close();
}
}
It might need still some work, but I hope it helps you.
Here is an example which should work:
StringBuffer outStream = new StringBuffer();
StringBuffer errStream = new StringBuffer();
Runtime runtime = Runtime.getRuntime();
Process process = null;
try {
process = runtime.exec(command);
} catch (IOException ex) {
ex.printStackTrace();
return;
}
InputStream outIs = process.getInputStream();
MonitorOutputThread sout = new MonitorOutputThread(outIs, outStream);
sout.run();
InputStream errIs = process.getErrorStream();
MonitorOutputThread serr = new MonitorOutputThread(errIs, errStream);
serr.run();
while (sout.isAlive() || serr.isAlive()) {
try {
sleep(100);
} catch (InterruptedException ex) {
ex.printStackTrace();
// ignore
}
}
And the code for MonitorOutputThread
private class MonitorOutputThread extends Thread {
private final InputStream is;
private final StringBuffer output;
public MonitorOutputThread(InputStream is, StringBuffer output) {
this.is = is;
this.output = output;
}
#Override
public void run() {
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line = null;
try {
while ((line = br.readLine()) != null) {
output.append(line);
output.append(LINE_SEPARATOR);
}
if (output.length() >= 1) {
char lastChar = output.charAt(output.length() - 1);
if (lastChar == '\n') {
output.deleteCharAt(output.length() - 1);
}
}
} catch (IOException ex) {
ex.printStackTrace();
return;
}
}
}
This should catch both the standard output and standard error of the command.
DevDaily has a simple example of how to work with Process class.
See the snippet:
import java.io.*;
public class JavaRunCommand {
public static void main(String args[]) {
String s = null;
try {
// run the Unix "ps -ef" command
// using the Runtime exec method:
Process p = Runtime.getRuntime().exec("ps -ef");
BufferedReader stdInput = new BufferedReader(new
InputStreamReader(p.getInputStream()));
BufferedReader stdError = new BufferedReader(new
InputStreamReader(p.getErrorStream()));
// read the output from the command
System.out.println("Here is the standard output of the command:\n");
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
// read any errors from the attempted command
System.out.println("Here is the standard error of the command (if any):\n");
while ((s = stdError.readLine()) != null) {
System.out.println(s);
}
System.exit(0);
}
catch (IOException e) {
System.out.println("exception happened - here's what I know: ");
e.printStackTrace();
System.exit(-1);
}
}
}
or even check this code I've writen some time ago

Categories

Resources