# Copyright (c) 2003-2006 CORE Security Technologies # # This software is provided under under a slightly modified version # of the Apache Software License. See the accompanying LICENSE file # for more information. # # $Id: printer.py,v 1.2 2006/05/23 21:19:26 gera Exp $ # from impacket.structure import Structure def zeroize(s): return '\x00'.join(str(s)) + '\x00' class SpoolSS_DevModeContainer(Structure): alignment = 4 structure = ( ('cbBuf',' 4096: raise Exception, "Buffer is too big." # do the real request enumPrinters = SpoolSS_EnumPrinters() enumPrinters['level'] = level enumPrinters['flags'] = flags enumPrinters['Name'] = name enumPrinters['PrinterEnum'] = '\x00' * ans['cbNeeded'] ans = SpoolSS_EnumPrinters_answer(self.doRequest(enumPrinters, checkReturn = 0)) # ans.dump('answer') def openPrinter(self, printerName, dataType, devMode, accessRequired): openPrinter = SpoolSS_OpenPrinter() if printerName: openPrinter['PrinterName'] = zeroize(printerName+'\x00') if dataType: openPrinter['DataType'] = zeroize(dataType+'\x00') if devMode: devModeC = SpoolSS_DevModeContainer() # devModeC['DevMode'] = devModeC devModeC['cbBuf'] = 0 devModeC['pDevMode'] = 0 devModeC['DevMode'] = '' openPrinter['DevMode'] = '\x00\x00\x00\x00' openPrinter['pDevMode'] = 0 openPrinter['AccessRequired'] = accessRequired return self.doRequest(openPrinter, checkReturn = 0) def enumPorts(self, level = 1, noAnswer = 0): # this one calls ntdll_RtlAcquirePebLock and ntdll_RtlReleasePebLock # first get the number of bytes needed enumPorts = SpoolSS_EnumPorts() enumPorts['level'] = level enumPorts['Port'] = '' if noAnswer: self.doRequest(enumPorts, noAnswer = 1) else: ans = SpoolSS_EnumPorts_answer(self.doRequest(enumPorts, checkReturn = 0)) # do the real request enumPorts = SpoolSS_EnumPorts() # enumPorts['Name'] = '\\\x00\\\x00hola\x00\x00' enumPorts['level'] = level enumPorts['Port'] = '\x00'*ans['cbNeeded'] ans = SpoolSS_EnumPorts_answer(self.doRequest(enumPorts, checkReturn = 0)) # ans.dump('answer') def enumMonitors(self, level = 1): # first get the number of bytes needed enumMonitors = SpoolSS_EnumMonitors() enumMonitors['level'] = level enumMonitors['Monitor'] = '' ans = SpoolSS_EnumMonitors_answer(self.doRequest(enumMonitors, checkReturn = 0)) # do the real request enumMonitors = SpoolSS_EnumMonitors() # enumMonitors['Name'] = '\\\x00\\\x00hola\x00\x00' enumMonitors['level'] = level enumMonitors['Monitor'] = '\x00'*ans['cbNeeded'] ans = SpoolSS_EnumMonitors_answer(self.doRequest(enumMonitors, checkReturn = 0)) # ans.dump('answer') def addMonitor(self, name, monitorName, environment, dllName): addMonitor = SpoolSS_AddMonitor() addMonitor['level'] = 2 addMonitor['HostName'] = zeroize(name) addMonitor['Name'] = zeroize(monitorName) addMonitor['Environment'] = zeroize(environment) addMonitor['DLLName'] = zeroize(dllName) ans = self.doRequest(addMonitor, checkReturn = 0) print "%r" % ans def addPort(self): addPort = SpoolSS_AddPort() addPort['Name'] = zeroize('\\192.168.22.90\x00') addPort['hWnd'] = 0 addPort['MonitorName'] = zeroize('LanMan Print Services Port\x00') return self.doRequest(addPort) def addPortEx(self): port = SpoolSS_PortInfo1() port['Name'] = zeroize('Port Name\x00') addPortEx = SpoolSS_AddPortEx() addPortEx['Name'] = zeroize('\\\\192.168.22.90\x00') addPortEx['Port'] = port addPortEx['cbMonitorData'] = 0 addPortEx['MonitorData'] = '\x00'*4 addPortEx['MonitorName'] = zeroize('Monitor Name\x00') return self.doRequest(addPortEx) def addPrintProcessor(self): addPrintProcessor = SpoolSS_AddPrintProcessor() # addPrintProcessor['Name'] = zeroize('\\\\192.168.22.90\x00') addPrintProcessor['Environment'] = zeroize('Windows NT x86\x00') addPrintProcessor['PathName'] = zeroize('C:\\hola\\manola\x00') addPrintProcessor['PrintProcessorName'] = zeroize('chaucha\x00') return self.doRequest(addPrintProcessor) def deletePrinter(self, handle): deletePrinter = SpoolSS_DeletePrinter() deletePrinter['handle'] = handle self.doRequest(deletePrinter) def addPrinter(self, serverName, name, level = 1, flags = 0, comment = None, description = None): addPrinter = SpoolSS_AddPrinter() # length(Name)+length(PrinterName)+2+2 must be the size of the chunk following the overflown if serverName is not None: addPrinter['Name'] = serverName if level == 1: addPrinter['info'] = SpoolSS_PrinterInfo1() addPrinter['info']['Name'] = name addPrinter['info']['Description'] = description addPrinter['info']['flags'] = flags elif level == 2: addPrinter['info'] = SpoolSS_PrinterInfo2() addPrinter['info']['PrinterName'] = name else: raise Exception, "Unknown PRINTER_INFO level" addPrinter['info']['Comment'] = comment addPrinter['blob'] = ( # to be improved "\x00\x00\x00\x00"*4 ) # addPrinter.dump('addPrinter') # addPrinter['info'].dump('info') return self.doRequest(addPrinter, checkReturn = 0) def addPrinterEx(self, serverName, name, comment = None): addPrinterEx = SpoolSS_AddPrinterEx() # length(Name)+length(PrinterName)+2+2 must be the size of the chunk following the overflow in mem addPrinterEx['Name'] = serverName addPrinterEx['info'] = SpoolSS_PrinterInfo2() addPrinterEx['info']['PrinterName'] = name addPrinterEx['info']['Comment'] = comment addPrinterEx['blob'] = ( # to be improved "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x01\x00\x00\x00\x01\x00\x00\x00" "\xf8\xf3\x30\x00" "\x1c\x00\x00\x00" "\xf0\x62\xc9\x00" "\xe0\xf1\x30\x00" "\x93\x08\x00\x00" "\x03\x00\x00\x00" "\x00\x00\x00\x00" "\x00\x00\x00\x00" "\x08\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00" # \\ERATO "\x5c\x00\x5c\x00\x45\x00\x52\x00\x41\x00\x54\x00\x4f\x00\x00\x00" "\x0e\x00\x00\x00\x00\x00\x00\x00\x0e\x00\x00\x00" # Administrator "\x41\x00\x64\x00\x6d\x00\x69\x00\x6e\x00\x69\x00\x73\x00\x74\x00" "\x72\x00\x61\x00\x74\x00\x6f\x00\x72\x00\x00\x00" ) return self.doRequest(addPrinterEx)