mirror of
https://github.com/rapid7/metasploit-payloads
synced 2025-01-02 11:36:22 +01:00
fix ProcessChannel thread closing
This commit is contained in:
parent
91acbc8f2e
commit
6c54c2ce76
@ -12,7 +12,7 @@ import java.io.OutputStream;
|
||||
public class Channel {
|
||||
|
||||
public final Meterpreter meterpreter;
|
||||
protected final InputStream in;
|
||||
private final InputStream in;
|
||||
private final OutputStream out;
|
||||
private final int id;
|
||||
protected boolean active = false, closed = false, waiting = false;
|
||||
@ -26,24 +26,12 @@ public class Channel {
|
||||
* @param out Output stream of the channel, if any
|
||||
*/
|
||||
public Channel(Meterpreter meterpreter, InputStream in, OutputStream out) {
|
||||
this(meterpreter, in, out, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new "generic" channel.
|
||||
*
|
||||
* @param meterpreter The meterpreter this channel should be assigned to.
|
||||
* @param in Input stream of the channel
|
||||
* @param out Output stream of the channel, if any
|
||||
* @param hasStderr True if the channel has stderr output
|
||||
*/
|
||||
public Channel(Meterpreter meterpreter, InputStream in, OutputStream out, boolean hasStderr) {
|
||||
this.meterpreter = meterpreter;
|
||||
this.id = meterpreter.registerChannel(this);
|
||||
this.in = in;
|
||||
this.out = out;
|
||||
if (!hasStderr) {
|
||||
new InteractThread(in).start();
|
||||
if (in != null) {
|
||||
new InteractThread(in, true).start();
|
||||
}
|
||||
}
|
||||
|
||||
@ -51,9 +39,12 @@ public class Channel {
|
||||
* Close this channel and deregister it from the meterpreter.
|
||||
*/
|
||||
public synchronized void close() throws IOException {
|
||||
in.close();
|
||||
if (out != null)
|
||||
if (in != null) {
|
||||
in.close();
|
||||
}
|
||||
if (out != null) {
|
||||
out.close();
|
||||
}
|
||||
meterpreter.channelClosed(id);
|
||||
active = false;
|
||||
closed = true;
|
||||
@ -172,9 +163,11 @@ public class Channel {
|
||||
*/
|
||||
protected class InteractThread extends Thread {
|
||||
private final InputStream stream;
|
||||
private final boolean handleClose;
|
||||
|
||||
public InteractThread(InputStream stream) {
|
||||
public InteractThread(InputStream stream, boolean handleClose) {
|
||||
this.stream = stream;
|
||||
this.handleClose = handleClose;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
@ -188,7 +181,9 @@ public class Channel {
|
||||
System.arraycopy(buffer, 0, data, 0, len);
|
||||
handleInteract(data);
|
||||
}
|
||||
handleInteract(null);
|
||||
if (handleClose) {
|
||||
handleInteract(null);
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace(meterpreter.getErrorStream());
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import java.io.InputStream;
|
||||
public class ProcessChannel extends Channel {
|
||||
|
||||
private final Process process;
|
||||
private final InputStream inputStream;
|
||||
private final InputStream err;
|
||||
|
||||
/**
|
||||
@ -20,10 +21,13 @@ public class ProcessChannel extends Channel {
|
||||
* @param process Process of the channel
|
||||
*/
|
||||
public ProcessChannel(Meterpreter meterpreter, Process process) {
|
||||
super(meterpreter, process.getInputStream(), process.getOutputStream(), true);
|
||||
super(meterpreter, null, process.getOutputStream());
|
||||
this.inputStream = process.getInputStream();
|
||||
this.err = process.getErrorStream();
|
||||
this.process = process;
|
||||
new StdoutStderrThread(this.in, this.err).start();
|
||||
Thread stdinThread = new InteractThread(this.inputStream, false);
|
||||
Thread stderrThread = new InteractThread(this.err, false);
|
||||
new CloseThread(stdinThread, stderrThread).start();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -47,48 +51,31 @@ public class ProcessChannel extends Channel {
|
||||
|
||||
public void close() throws IOException {
|
||||
process.destroy();
|
||||
inputStream.close();
|
||||
err.close();
|
||||
super.close();
|
||||
}
|
||||
|
||||
class StdoutStderrThread extends Thread {
|
||||
private final InputStream in;
|
||||
private final InputStream err;
|
||||
class CloseThread extends Thread {
|
||||
private final Thread stdinThread;
|
||||
private final Thread stderrThread;
|
||||
|
||||
public StdoutStderrThread(InputStream in, InputStream err) {
|
||||
this.in = in;
|
||||
this.err = err;
|
||||
public CloseThread(Thread stdinThread, Thread stderrThread) {
|
||||
this.stdinThread = stdinThread;
|
||||
this.stderrThread = stderrThread;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
try {
|
||||
byte[] buffer = new byte[1024*1024];
|
||||
int inlen;
|
||||
int errlen;
|
||||
while (true) {
|
||||
if ((inlen = in.read(buffer)) != -1) {
|
||||
if (inlen > 0)
|
||||
writeBuf(buffer, inlen);
|
||||
}
|
||||
if ((errlen = err.read(buffer)) != -1) {
|
||||
if (errlen > 0)
|
||||
writeBuf(buffer, errlen);
|
||||
}
|
||||
if (inlen == -1 && errlen == -1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
stdinThread.start();
|
||||
stderrThread.start();
|
||||
stdinThread.join();
|
||||
stderrThread.join();
|
||||
handleInteract(null);
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace(meterpreter.getErrorStream());
|
||||
}
|
||||
}
|
||||
|
||||
private void writeBuf(byte[] buffer, int len) throws IOException, InterruptedException {
|
||||
byte[] data = new byte[len];
|
||||
System.arraycopy(buffer, 0, data, 0, len);
|
||||
handleInteract(data);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user