shadowbrokers-exploits/windows/fuzzbunch/edfexecution.py
2017-04-14 11:45:07 +02:00

268 lines
8.4 KiB
Python

"""
Platform dependent plugin execution helper functions.
"""
import os
import sys
import uuid
__all__ = ["generate_pipename",
"create_pipe",
"validate_plugin",
"launch_plugin",
"connect_pipe",
"write_outconfig",
"close_pipe",
"PipeError"]
CONNECT_TIMEOUT_SECS = 45
class PipeError(Exception):
pass
mswindows = (sys.platform == "win32")
if mswindows:
import win32pipe
import win32file
import pywintypes
import win32event
import subprocess
ERROR_PIPE_CONNECTED = 535
ERROR_IO_PENDING = 997
PIPE_PREFIX = "\\\\.\\pipe\\fb-pipe"
else:
import signal
import subprocess
PIPE_PREFIX = "/tmp/fb-pipe-"
#
# Cross platform functions
#
def generate_pipename():
return PIPE_PREFIX + str(uuid.uuid4())
#
# MS Windows
#
if mswindows:
def create_pipe(pipeName):
# XXX - We should validate here and return None on fail
pipe = win32pipe.CreateNamedPipe(pipeName,
win32pipe.PIPE_ACCESS_INBOUND | win32file.FILE_FLAG_OVERLAPPED,
0x0,
1,
1024,
1024,
0,
None)
return pipe
def validate_plugin(binName, inName, io):
cmdLine = []
if binName.endswith(".py"):
cmdLine.append("python.exe")
cmdLine.append("\"%s\"" % binName)
cmdLine.append("--InConfig \"%s\"" % inName)
cmdLine.append("--ValidateOnly true")
try:
retcode = subprocess.call(" ".join(cmdLine),
stdout=io.stdout,
stderr=io.stdout,
stdin=io.stdin,
env=os.environ)
except OSError, e:
io.print_error("Failed to execute: %s" % str(e))
retcode = 1
return retcode
def launch_plugin(binName, inName, pipeName, logFile, io, newconsole):
"""Execute the process with the passed in parameters. Note that the
output parameter is not a file name, but rather a named pipe!"""
if newconsole:
cmdLine = []
cmdLine.append("start \"%s\" cmd /T:9F /K " % binName)
if binName.endswith(".py"):
cmdLine.append("\"python.exe \"%s\"" % binName)
else:
cmdLine.append("\"\"%s\"" % binName)
cmdLine.append("--InConfig \"%s\"" % inName)
cmdLine.append("--OutConfig \"%s\"" % pipeName)
cmdLine.append("--LogFile \"%s\"\"" % logFile)
p = subprocess.Popen(" ".join(cmdLine), shell=True, env=os.environ)
else:
cmdLine = []
if binName.endswith(".py"):
cmdLine.append("python.exe")
cmdLine.append("\"%s\"" % binName)
cmdLine.append("--InConfig \"%s\"" % inName)
cmdLine.append("--OutConfig \"%s\"" % pipeName)
cmdLine.append("--LogFile \"%s\"" % logFile)
p = subprocess.Popen(" ".join(cmdLine),
shell=False,
stdout=io.stdout,
stderr=io.stderr,
stdin=io.stdin,
env=os.environ)
return p
def connect_pipe(pipe, pipeName):
overLap = pywintypes.OVERLAPPED()
overLap.hEvent = win32event.CreateEvent(None, 1, 0, None)
if overLap.hEvent == 0:
raise PipeError('Could not create hEvent')
try:
# Wait for a pipe client connection
ret = win32pipe.ConnectNamedPipe(pipe, overLap)
if not ret in (0, ERROR_PIPE_CONNECTED):
if ret == ERROR_IO_PENDING:
ret = win32event.WaitForSingleObject(overLap.hEvent,
1000 * CONNECT_TIMEOUT_SECS)
if ret != win32event.WAIT_OBJECT_0:
# Timeout error
raise PipeError('Timeout error')
else:
# API error
raise PipeError('API error')
ret = win32pipe.GetOverlappedResult(pipe, overLap, True)
if not ret in (0, ERROR_PIPE_CONNECTED):
# API Error
raise PipeError('API error 2')
except PipeError:
# Named pipe exception
win32file.CancelIo(pipe)
pipe.close()
raise
except BaseException, err:
win32file.CancelIo(pipe)
pipe.close()
pipe = None
raise PipeError('BaseException : ' + str(err))
return pipe
def write_outconfig(fileName, pipe):
tmpFile = open(fileName, "w")
while 1:
try:
(ret, line) = win32file.ReadFile(pipe, 4096, None)
if ret != 0 or line == "":
break
else:
tmpFile.write(line)
except:
break
tmpFile.close()
def close_pipe(pipe):
win32file.CancelIo(pipe)
pipe.close()
#
# Linux
#
else:
def SIGALRM_handler(sigNum, frame):
return
def create_pipe(pipename):
os.mkfifo(pipename, 0666)
return None
def launch_plugin(binName, inName, pipeName, logFile, io, newconsole):
"""Execute the process with the passed in parameters. Note that the
output parameter is not a file name, but rather a named pipe!"""
if newconsole:
cmdLine = []
cmdLine.append("/usr/bin/xterm -hold -T \"%s\" -e " % binName)
cmdLine.append("\"%s\"" % binName)
cmdLine.append("--InConfig \"%s\"" % inName) # Contains the input parameters
cmdLine.append("--OutConfig \"%s\"" % pipeName)
cmdLine.append("--LogFile \"%s\"" % logFile)
p = subprocess.Popen(" ".join(cmdLine), shell=True, env=os.environ)
else:
cmdLine = []
if binName.endswith(".py"):
cmdLine.append("/usr/bin/python2.6")
cmdLine.append("\"%s\"" % binName)
cmdLine.append("--InConfig \"%s\"" % inName) # Contains the input parameters
cmdLine.append("--OutConfig \"%s\"" % pipeName)
cmdLine.append("--LogFile \"%s\"" % logFile)
p = subprocess.Popen(" ".join(cmdLine), shell=True,
stdout=io.stdout,
stderr=io.stderr,
stdin=io.stdin,
env=os.environ)
return p
def validate_plugin(binName, inName, io):
cmdLine = []
if binName.endswith(".py"):
cmdLine.append("/usr/bin/python2.6")
cmdLine.append("\"%s\"" % binName)
cmdLine.append("--InConfig \"%s\"" % inName)
cmdLine.append("--ValidateOnly true")
try:
retcode = subprocess.call(" ".join(cmdLine),
stdout=io.stdout,
stderr=io.stdout,
stdin=io.stdin,
shell=True,
env=os.environ)
except OSError, e:
io.print_error("Failed to execute: %s" % str(e))
retcode = 1
return retcode
def connect_pipe(pipe, pipeName):
"""
"""
oldHandler = signal.getsignal(signal.SIGALRM)
try:
signal.signal(signal.SIGALRM, SIGALRM_handler)
signal.alarm(CONNECT_TIMEOUT_SECS + 1)
retval = os.open(pipeName, os.O_RDONLY)
signal.alarm(0)
except OSError:
# Alarm Timeout
retval = None
except BaseException:
# Keyboard interrupt
retval = None
# cancel the alarm and restore prev handler
signal.signal(signal.SIGALRM, oldHandler)
return retval
def write_outconfig(fileName, pipe):
tmpFile = open(fileName, "w")
while 1:
line = os.read(pipe, 4096)
if len(line) == 0:
break
else:
tmpFile.write(line)
tmpFile.close()
def close_pipe(pipe):
os.close(pipe)