def simple_upload_sample_file(sample_file): '''Upload a file to Deep Discovery Analyzer for analysis''' with open(demisto.getFilePath(sample_file)['path'], 'rb') as f: headers_simple_upload_sample_file = { 'X-DTAS-ProtocolVersion': PROTOCOL_VERSION, 'X-DTAS-ClientUUID': UUID, 'X-DTAS-SourceID': '1', 'X-DTAS-SourceName': 'DemistoIntegration', 'X-DTAS-SHA1': hash_file(demisto.getFilePath(sample_file)['path']), 'X-DTAS-Time': get_epoch_time(), 'X-DTAS-SampleType': '0', # 0 for file, 1 for URL 'X-DTAS-Challenge': str(uuid.uuid4()), 'X-DTAS-ChecksumCalculatingOrder': "X-DTAS-ProtocolVersion,X-DTAS-ClientUUID,X-DTAS-SourceID,X-DTAS-SourceName," \ + "X-DTAS-SHA1,X-DTAS-Time,X-DTAS-SampleType,X-DTAS-Challenge", } tmp_checksum = calculate_checksum(API_KEY, headers_simple_upload_sample_file) headers_simple_upload_sample_file[ 'X-DTAS-Checksum'] = tmp_checksum.hexdigest() cmd_url = 'web_service/sample_upload/simple_upload_sample' res = http_request(cmd_url, 'post', headers_simple_upload_sample_file, files={'uploadsample': f}) pretty_res = prettify_simple_upload_sample_file( headers_simple_upload_sample_file['X-DTAS-SHA1']) return res, pretty_res
def analyse_sample_file_request(file_entry, should_wait): data = {} # type:dict shutil.copy( demisto.getFilePath(file_entry)['path'], demisto.getFilePath(file_entry)['name']) with open(demisto.getFilePath(file_entry)['name'], 'rb') as f: res = http_cmd('/developers/files', data=data, files={'file': f}) if 'errors' in res: LOG('Error! in command sample file: file_entry=%s' % (file_entry, )) LOG('got the following errors:\n' + '\n'.join(e['msg'] for e in res['errors'])) raise Exception('command failed to run.') shutil.rmtree(demisto.getFilePath(file_entry)['name'], ignore_errors=True) if should_wait: return poll_analysis_id(res['id']) analysis_id = res['id'] result = info_request(analysis_id) return analysis_to_entry('Analysis #%s' % (analysis_id, ), result)
def wildfire_upload_file(upload): upload_file_uri = URL + URL_DICT["upload_file"] body = {'apikey': TOKEN} file_path = demisto.getFilePath(upload)['path'] file_name = demisto.getFilePath(upload)['name'] try: shutil.copy(file_path, file_name) except Exception: return_error('Failed to prepare file for upload.') try: with open(file_name, 'rb') as f: result = http_request( upload_file_uri, 'POST', body=body, files={'file': f} ) finally: shutil.rmtree(file_name, ignore_errors=True) upload_file_data = result["wildfire"]["upload-file-info"] return result, upload_file_data
def viper_upload_command(): """ Command to upload a file to Viper database """ # Get entry id, filename and filepath file_entry = demisto.args().get('EntryID') filename = demisto.getFilePath(file_entry)['name'] filepath = demisto.getFilePath(file_entry)['path'] # Send file to Viper response = viper_upload(filepath, filename, file_entry.lower()) # Update tags if necessary if response == 'add tags': curr_hash = demisto.context().get('File')[2]['SHA256'] url_fragment = "project/default/malware/{}/tag/".format(curr_hash) curr_tags = [ result['data']['tag'] for result in http_request( 'GET', url_fragment, None, None, None)['results'] ] if file_entry not in curr_tags: demisto.results("File already in Viper. Updating tags...") data = {'tag': file_entry} add_tags = http_post(url_fragment, None, data=data) else: demisto.results( "File already in Viper. Viper entry is up to date.")
def upload_file_on_demand(session, base_url): """File Processing""" upload = demisto.args().get('file_entry_id') file_path = demisto.getFilePath(upload)['path'] file_name = demisto.getFilePath(upload)['name'] file_sha256 = "" if 'sha256' in demisto.args(): file_sha256 = demisto.args().get('sha256') try: shutil.copy(file_path, file_name) except Exception: raise Exception('Failed to prepare file for upload.') try: file_handler = open(file_name, 'rb') fname = os.path.basename(file_handler.name) encoded_file_name = base64.b64encode(fname.encode()) file_data = file_handler.read() encoded_file_data = base64.encodebytes(file_data) file_handler.seek(0, os.SEEK_END) file_size = file_handler.tell() file_handler.close() finally: shutil.rmtree(file_name, ignore_errors=True) if int(file_size) >= 200000000: # Max File Size is 20M, hence the check. return_error("File too big to upload to the Sandbox, limit is 20MB") """File Upload""" url_suffix = "/alert/ondemand/submit-file" payload = { "method": "set", "params": [{ "file": encoded_file_data.decode('utf-8'), "filename": encoded_file_name.decode('utf-8'), "archive_password": demisto.args().get("archive_password"), "overwrite_vm_list": demisto.args().get("vm_csv_list"), # WIN7X86VM,WINXPVM "skip_steps": demisto.args().get("skip_steps"), # Do not use this parameter if no step to skip. 1 = Skip AV, 2= Skip Cloud, 4= Skip sandboxing, # 8= Skip Static Scan. "url": url_suffix, "type": "file", "timeout": "3600", # "malpkg":"0" # (Optional) set the value as "1" to require to add the sample to malware package if it satisfy the # malware critia. By default, the value is "0". }], "session": session, "ver": "2.5", "id": 11 } return _handle_post(base_url + "/jsonrpc", payload), file_name, file_sha256
def process_attachments(message, attachIDs="", attachNames=""): file_entries_for_attachments = [] # type: list attachments_names = [] # type: list if attachIDs: file_entries_for_attachments = attachIDs if isinstance(attachIDs, list) else attachIDs.split(",") if attachNames: attachments_names = attachNames if isinstance(attachNames, list) else attachNames.split(",") else: for att_id in file_entries_for_attachments: att_name = demisto.getFilePath(att_id)['name'] if isinstance(att_name, list): att_name = att_name[0] attachments_names.append(att_name) if len(file_entries_for_attachments) != len(attachments_names): raise Exception("attachIDs and attachNames lists should be the same length") for i in range(0, len(file_entries_for_attachments)): entry_id = file_entries_for_attachments[i] attachment_name = attachments_names[i] try: res = demisto.getFilePath(entry_id) except Exception as ex: raise Exception("entry {} does not contain a file: {}".format(entry_id, str(ex))) file_path = res["path"] with open(file_path, 'rb') as f: f_data = f.read() encoded_data = base64.b64encode(f_data).decode() file_type = mimetypes.guess_type(attachment_name)[0] message.attachment = Attachment(FileContent(encoded_data), # type: ignore[name-defined] FileName(attachment_name), # type: ignore[name-defined] FileType(file_type), # type: ignore[name-defined] Disposition('attachment')) # type: ignore[name-defined] return 'ok'
def upload_file( self, file: str, file_name: str, is_confidential: str = "true", comment: str = "" ) -> dict: """Creating the needed arguments for the http request :param file: content of the uploaded sample in binary format :param file_name: name of the file :param is_confidential: defines visibility of this file in Falcon MalQuery, either via the API or the Falcon console :param comment: a descriptive comment to identify the file for other users :return: http response """ name = demisto.getFilePath(file)['name'] try: shutil.copy(demisto.getFilePath(file)['path'], name) with open(name, 'rb') as f: url_suffix = f"/samples/entities/samples/v2?file_name={file_name}&is_confidential={is_confidential}" \ f"&comment={comment}" self._headers['Content-Type'] = 'application/octet-stream' shutil.rmtree(file_name, ignore_errors=True) return self._http_request("POST", url_suffix, files={'file': f}) except OSError: raise Exception('Failed to prepare file for upload.') finally: shutil.rmtree(file_name, ignore_errors=True)
def submit_file(client, args): """ Submit the URL """ file_entry_id = args.get('entry_id') file_path = demisto.getFilePath(file_entry_id)['path'] file_name = demisto.getFilePath(file_entry_id)['name'] priority = args.get('priority', 10) profile = args.get('profile') # validation for priority priority = validate_priority(priority) with open(file_path, 'rb') as file: result = client.submit_file(file_name=file_name, file_obj=file.read(), priority=priority, profile=profile) readable_output = '## Submitted File\n' readable_output += tableToMarkdown('Twinwave Submissions', result, headers=['JobID']) return CommandResults( readable_output=readable_output, outputs_prefix="Twinwave.Submissions", outputs_key_field='JobID', outputs=result, raw_response=result # raw response - the original response )
def analyse_sample_file_request(file_entry, should_wait, internet_access, comments='', systems=''): data = { 'accept-tac': 1, 'internet-access': 1 if internet_access else 0, } if comments != '': data['comments'] = comments if systems != '': data['systems[]'] = [s.strip() for s in systems.split(',')] # type: ignore shutil.copy(demisto.getFilePath(file_entry)['path'], demisto.getFilePath(file_entry)['name']) with open(demisto.getFilePath(file_entry)['name'], 'rb') as f: res = http_post('v2/analysis/submit', data=data, files={'sample': f}) if res == 'nothing_to_analyze': return nothing_to_analyze_output if 'errors' in res: LOG('Error! in command sample file: file_entry=%s' % (file_entry, )) LOG('got the following errors:\n' + '\n'.join(e['message'] for e in res['errors'])) raise Exception('command failed to run.') shutil.rmtree(demisto.getFilePath(file_entry)['name'], ignore_errors=True) if should_wait: return poll_webid(res['data']['webids'][0]) web_id = res['data']['webids'][0] result = info_request(web_id) return analysis_to_entry('Analysis #%s' % (web_id, ), result['data'])
def analyse_sample_file_request(file_entry, should_wait, internet_access, comments='', systems=''): data = { 'accept-tac': 1, 'internet-access': 1 if internet_access else 0, } if comments != '': data['comments'] = comments if systems != '': data['systems[]'] = [s.strip() for s in systems.split(',')] # type: ignore # removing backslashes from filename as the API does not like it # if given filename such as dir\file.xlsx - the sample will end with the name file.xlsx filename = demisto.getFilePath(file_entry)['name'].replace('\\', '/') with open(demisto.getFilePath(file_entry)['path'], 'rb') as f: res = http_post('v2/analysis/submit', data=data, files={'sample': (filename, f)}) if res == 'nothing_to_analyze': return nothing_to_analyze_output if 'errors' in res: LOG('Error! in command sample file: file_entry=%s' % (file_entry, )) LOG('got the following errors:\n' + '\n'.join(e['message'] for e in res['errors'])) raise Exception('command failed to run.') shutil.rmtree(demisto.getFilePath(file_entry)['name'], ignore_errors=True) if should_wait: return poll_webid(res['data']['webids'][0]) web_id = res['data']['webids'][0] result = info_request(web_id) return analysis_to_entry('Analysis #%s' % (web_id, ), result['data'])
def process_attachments(attachCIDs="", attachIDs="", attachNames="", manualAttachObj=None): if manualAttachObj is None: manualAttachObj = [] file_entries_for_attachments = [] # type: list attachments_names = [] # type: list if attachIDs: file_entries_for_attachments = attachIDs if isinstance( attachIDs, list) else attachIDs.split(",") if attachNames: attachments_names = attachNames if isinstance( attachNames, list) else attachNames.split(",") else: for att_id in file_entries_for_attachments: att_name = demisto.getFilePath(att_id)['name'] if isinstance(att_name, list): att_name = att_name[0] attachments_names.append(att_name) if len(file_entries_for_attachments) != len(attachments_names): raise Exception( "attachIDs and attachNames lists should be the same length") attachments = collect_manual_attachments(manualAttachObj) if attachCIDs: file_entries_for_attachments_inline = attachCIDs if isinstance( attachCIDs, list) else attachCIDs.split(",") for att_id_inline in file_entries_for_attachments_inline: try: file_info = demisto.getFilePath(att_id_inline) except Exception as ex: demisto.info("EWS error from getFilePath: {}".format(ex)) raise Exception("entry %s does not contain a file" % att_id_inline) att_name_inline = file_info["name"] with open(file_info["path"], 'rb') as f: attachments.append( FileAttachment(content=f.read(), name=att_name_inline, is_inline=True, content_id=att_name_inline)) for i in range(0, len(file_entries_for_attachments)): entry_id = file_entries_for_attachments[i] attachment_name = attachments_names[i] try: res = demisto.getFilePath(entry_id) except Exception as ex: raise Exception("entry {} does not contain a file: {}".format( entry_id, str(ex))) file_path = res["path"] with open(file_path, 'rb') as f: attachments.append( FileAttachment(content=f.read(), name=attachment_name)) return attachments, attachments_names
def send_email(to, subject, body="", bcc=None, cc=None, replyTo=None, htmlBody=None, attachIDs="", attachNames="", from_mailbox=None, manualAttachObj=None): account = get_account(from_mailbox or ACCOUNT_EMAIL) bcc = bcc.split(",") if bcc else None cc = cc.split(",") if cc else None to = to.split(",") if to else None manualAttachObj = manualAttachObj if manualAttachObj is not None else [] subject = subject[:252] + '...' if len(subject) > 255 else subject file_entries_for_attachments = [] # type: list attachments_names = [] # type: list if attachIDs: file_entries_for_attachments = attachIDs.split(",") if attachNames: attachments_names = attachNames.split(",") else: for att_id in file_entries_for_attachments: att_name = demisto.getFilePath(att_id)['name'] if isinstance(att_name, list): att_name = att_name[0] attachments_names.append(att_name) if len(file_entries_for_attachments) != len(attachments_names): raise Exception("attachIDs and attachNames lists should be the same length") attachments = collect_manual_attachments(manualAttachObj) for i in range(0, len(file_entries_for_attachments)): entry_id = file_entries_for_attachments[i] attachment_name = attachments_names[i] try: res = demisto.getFilePath(entry_id) except Exception as ex: raise Exception("entry {} does not contain a file: {}".format(entry_id, str(ex))) file_path = res["path"] with open(file_path, 'rb') as f: attachments.append(FileAttachment(content=f.read(), name=attachment_name)) send_email_to_mailbox(account, to, subject, body, bcc, cc, replyTo, htmlBody, attachments) result_object = { 'from': account.primary_smtp_address, 'to': to, 'subject': subject, 'attachments': attachments_names } return { 'Type': entryTypes['note'], 'Contents': result_object, 'ContentsFormat': formats['json'], 'ReadableContentsFormat': formats['markdown'], 'HumanReadable': tableToMarkdown('Sent email', result_object), }
def send_request(path, method='get', body=None, params=None, headers=None, file=None): body = body if body is not None else {} params = params if params is not None else {} url = '{}{}'.format(SERVER_URL, path) if not headers: headers = { 'Accept': 'application/json', 'Content-Type': 'application/json' } if file: # Not supported in v2 url = url.replace('v2', 'v1') try: file_entry = file['id'] file_name = file['name'] shutil.copy(demisto.getFilePath(file_entry)['path'], file_name) with open(file_name, 'rb') as f: files = {'file': f} res = requests.request(method, url, headers=headers, params=params, data=body, files=files, auth=(USERNAME, PASSWORD), verify=VERIFY_SSL) shutil.rmtree(demisto.getFilePath(file_entry)['name'], ignore_errors=True) except Exception as e: raise Exception('Failed to upload file - ' + e.message) else: res = requests.request(method, url, headers=headers, data=json.dumps(body), params=params, auth=(USERNAME, PASSWORD), verify=VERIFY_SSL) try: obj = res.json() except Exception as e: if not res.content: return '' raise Exception('Error parsing reply - {} - {}'.format(res.content, e.message)) if 'error' in obj: message = obj.get('error', {}).get('message') details = obj.get('error', {}).get('detail') if message == 'No Record found': return { # Return an empty results array 'result': [] } raise Exception('ServiceNow Error: {}, details: {}'.format(message, details)) if res.status_code < 200 or res.status_code >= 300: raise Exception('Got status code {} with url {} with body {} with headers {}' .format(str(res.status_code), url, str(res.content), str(res.headers))) return obj
def main(): args = demisto.args() entry_id = args.get('entry_id', '') file_path = demisto.getFilePath(entry_id).get('path') wpa_password = args.get('wpa_password', '') rsa_decrypt_key_entry_id = args.get('rsa_decrypt_key_entry_id', '') rsa_key_file_path = None if rsa_decrypt_key_entry_id: rsa_key_file_path = demisto.getFilePath(rsa_decrypt_key_entry_id).get( 'path') conversation_number_to_display = int(args.get('convs_to_display', '15')) extracted_protocols = argToList(args.get('protocol_output', '')) if 'All' in extracted_protocols: extracted_protocols = ALL_SUPPORTED_PROTOCOLS is_flows = True is_reg_extract = args.get('extract_strings', 'False') == 'True' pcap_filter = args.get('pcap_filter', '') homemade_regex = args.get('custom_regex', '') # 'Layer (.+):' pcap_filter_new_file_path = '' pcap_filter_new_file_name = args.get('filtered_file_name', '') unique_ips = args.get('extract_ips', 'False') == 'True' if pcap_filter_new_file_name: temp = demisto.uniqueFile() pcap_filter_new_file_path = demisto.investigation()['id'] + '_' + temp try: pcap = PCAP(is_reg_extract, extracted_protocols, homemade_regex, unique_ips, entry_id) pcap.mine(file_path, wpa_password, rsa_key_file_path, is_flows, is_reg_extract, pcap_filter, pcap_filter_new_file_path) hr, ec, raw = pcap.get_outputs(conversation_number_to_display, is_flows, is_reg_extract) return_outputs(hr, ec, raw) except Exception as e: return_error(f'Unexpected error: {str(e)}', error=traceback.format_exc()) if pcap_filter_new_file_name: demisto.results({ 'Contents': '', 'ContentsFormat': formats['text'], 'Type': 3, 'File': pcap_filter_new_file_name, 'FileID': temp })
def certificate_extract_command(args: Dict[str, Any]) -> CommandResults: pem: Optional[str] = args.get('pem') entry_id: Optional[str] = args.get('entry_id') if pem is None and entry_id is None: raise ValueError("You should specify pem or entry_id") if pem is not None and entry_id is not None: raise ValueError("Only one of pem and entry_id should be specified") certificate: x509.Certificate if entry_id is not None: res_path = demisto.getFilePath(entry_id) if not res_path: raise ValueError("Invalid entry_id - not found") entry_id_path = res_path['path'] certificate = load_certificate(entry_id_path) if pem is not None: certificate = x509.load_pem_x509_certificate( pem.encode('ascii'), backends.default_backend()) standard_context = certificate_to_context(certificate) readable_output = "Certificate decoded" return CommandResults(readable_output=readable_output, outputs=None, indicator=standard_context, ignore_auto_extract=True)
def get_file(entry_id): get_file_path_res = demisto.getFilePath(entry_id) file_path = get_file_path_res["path"] file_name = get_file_path_res["name"] with open(file_path, 'rb') as fopen: file_bytes = fopen.read() return file_name, file_bytes
def put_file_command(api_client: CBCloudAPI, device_id: str, destination_path: str, file_id: str): session = api_client.select(platform.Device, device_id).lr_session() path = demisto.getFilePath(file_id) session.put_file((path['name'], open(path['path'], 'rb')), destination_path) return f'File: {file_id} is successfully put to the remote destination {destination_path}'
def create_file_request(self, share_name: str, file_entry_id: str, file_name: str, directory_path: str = None) -> Response: """ Create a New empty file in Share from War room file Entry ID. Note that this operation only initializes the file. To add content to a file, we have to call the Put Range operation. Args: share_name (str): Share name. file_entry_id (str): File War room Entry ID. file_name (str): File name. Default is XSOAR file name. directory_path (str): The path to the directory where the file should be created. Returns: Response: API response from Azure. """ xsoar_file_data = demisto.getFilePath( file_entry_id ) # Retrieve XSOAR system file path and name, given file entry ID. xsoar_system_file_path = xsoar_file_data['path'] new_file_name = file_name if file_name else xsoar_file_data['name'] create_file_headers = { 'x-ms-type': 'file', 'x-ms-file-permission': 'Inherit', 'x-ms-file-attributes': 'None', 'x-ms-file-creation-time': 'now', 'x-ms-file-last-write-time': 'now' } create_file_url = f'{share_name}/{directory_path}/{new_file_name}' if directory_path else f'{share_name}/{new_file_name}' try: shutil.copy(xsoar_system_file_path, new_file_name) except FileNotFoundError: raise Exception( 'Failed to prepare file for upload. ' 'The process of importing and copying the file data from XSOAR failed.' ) try: with open(new_file_name, 'rb') as file: file.seek(0, 2) content_length = file.tell() create_file_headers['x-ms-content-length'] = str( content_length) create_file_response = self.ms_client.http_request( method='PUT', url_suffix=create_file_url, headers=create_file_headers, return_empty_response=True) finally: shutil.rmtree(new_file_name, ignore_errors=True) return create_file_response
def decrypt_email_body(client: Client, args: Dict, file_path=None): """ Decrypt the message Args: client: Client args: Dict file_path: relevant for the test module """ if file_path: encrypt_message = file_path else: encrypt_message = demisto.getFilePath(args.get('encrypt_message')) client.smime.load_key(client.private_key_file, client.public_key_file) try: p7, data = SMIME.smime_load_pkcs7(encrypt_message['path']) out = client.smime.decrypt(p7).decode('utf-8') except SMIME.SMIME_Error as e: if str( e ) == 'no content type': # If no content type; see if we can process as DER format with open(encrypt_message['path'], "rb") as message_file: p7data = message_file.read() p7bio = BIO.MemoryBuffer(p7data) p7 = SMIME.PKCS7(m2.pkcs7_read_bio_der(p7bio._ptr())) out = client.smime.decrypt( p7, flags=SMIME.PKCS7_NOVERIFY).decode('utf-8') entry_context = {'SMIME.Decrypted': {'Message': out}} human_readable = f'The decrypted message is: \n{out}' return human_readable, entry_context
def get_command_examples(entry_id): """ get command examples from command file @param entry_id: an entry ID of a command file or the content of such file @return: a list of command examples """ commands = [] # type: list errors = [] # type: list if entry_id is None: return commands, errors if re.match(r'[\d]+@[\d\w-]+', entry_id) is not None: examples_path = demisto.getFilePath(entry_id)['path'] with open(examples_path, 'r') as examples_file: commands = examples_file.read().split('\n') else: demisto.debug( 'failed to open command file, tried parsing as free text') commands = entry_id.split('\n') demisto.debug('found the following commands:\n{}'.format( '\n* '.join(commands))) return commands, errors
def fraud_watch_attachment_upload_command(client: Client, args: Dict): """ Adds a new file attachment to the incident which corresponds to the given incident ID. - Incident ID (Required): The ID of the incident to add additional urls to. - File Attachment: Entry id of the attachment to be added to the incident which corresponds to Incident ID. Known errors that causes error to be returned by FraudWatch service: - Unknown incident id. Args: client (Client): FraudWatch client to perform the API calls. args (Dict): Demisto arguments. Returns: CommandResults. """ incident_id: str = args.get('incident_id') # type: ignore entry_id = args.get('entry_id') try: # entry id of uploaded file to war room file_info = demisto.getFilePath(entry_id) file = open(file_info['path'], 'rb') except Exception: raise DemistoException(F"Entry {entry_id} does not contain a file.") files = [('incident_attachment', (file_info['name'], file))] raw_response = client.attachment_upload_command(incident_id, files) return CommandResults( raw_response=raw_response, # change to name and not entry ID readable_output= f'''### File {file_info['name']} was uploaded successfully to incident: {incident_id}''' )
def main(): LIST_NAME = demisto.args()['listName'] TO_ZIP = (demisto.args()['zipFile'] == 'true') entry_id = demisto.args()['entryId'] res = demisto.getFilePath(entry_id) if not res: return_error("Entry {} not found".format(entry_id)) file_path = res['path'] file_base64 = get_file_data(file_path, TO_ZIP) res = demisto.executeCommand("createList", {"listName": LIST_NAME, "listData": file_base64}) if isError(res): return res return { 'Contents': file_base64, 'ContentsFormat': formats['text'], 'HumanReadable': tableToMarkdown('Success store file in list', { 'File Entry ID': entry_id, 'List Name': LIST_NAME, 'Size': len(file_base64) }), 'HumanReadableFormat': formats['markdown'], }
def slack_send_file(): """ Sends a file to slack """ to = demisto.args().get('to') channel = demisto.args().get('channel') group = demisto.args().get('group') entry_id = demisto.args().get('file') thread_id = demisto.args().get('threadID') comment = demisto.args().get('comment', '') if not (to or channel or group): mirror = find_mirror_by_investigation() if mirror: channel = mirror.get('channel_name') if not (to or channel or group): return_error('Either a user, group or channel must be provided.') file_path = demisto.getFilePath(entry_id) with open(file_path['path'], 'rb') as file: data = file.read() file = {'data': data, 'name': file_path['name'], 'comment': comment} response = slack_send_request(to, channel, group, thread_id=thread_id, file=file) if response: demisto.results('File sent to Slack successfully.') else: demisto.results('Could not send the file to Slack.')
def rasterize_image(): global return_code, error_message res = demisto.getFilePath(demisto.args()['EntryID']) with open(res['path'], 'r') as f: data = f.read() b64 = base64.b64encode(data) html = '<img src="data:image/png;base64, ' + b64 + '">' return_code = 0 friendly_name = 'image.png' f = open('htmlImage.html', 'w') f.write('<html style="background:white;"><body>' + html + '</body></html>') f.close() command = ['phantomjs', '/usr/local/bin/rasterize.js', 'htmlImage.html', friendly_name] if demisto.get(demisto.args(), 'width') and demisto.get(demisto.args(), 'height'): command.append(demisto.get(demisto.args(), 'width') + '*' + demisto.get(demisto.args(), 'height')) try: error_message = subprocess.check_output(command) except Exception as e: return_code = -1 error_message = e.message if return_code == 0: file = file_result_existing_file(friendly_name) file['Type'] = entryTypes['image'] demisto.results(file) else: demisto.results({'ContentsFormat': 'text', 'Type': entryTypes['error'], 'Contents': 'PhantomJS returned - ' + error_message})
def detonate_file(self, entry_id: dict) -> object: title = 'PolySwarm File Detonation for Entry ID: %s' % entry_id demisto.debug(f'[detonate_file] {title}') try: file_info = demisto.getFilePath(entry_id) except Exception: return_error(f'File not found - EntryID: {entry_id}') try: demisto.debug(f'Submit file: {file_info}') instance = self.polyswarm_api.submit(file_info['path'], artifact_name=file_info['name']) result = self.polyswarm_api.wait_for(instance) except Exception as err: return_error('{ERROR_ENDPOINT}{err}'. format(ERROR_ENDPOINT=ERROR_ENDPOINT, err=err)) error_msg = 'Error submitting File.' return self.return_hash_results([result], title, error_msg)
def smb_upload(client: SMBClient, args: dict): hostname = args.get('hostname') path = handle_path(args.get('file_path')) path = os.path.join(hostname or client.hostname, path) username = args.get('username') password = args.get('password') entryID = args.get('entryID') content = args.get('content') if not entryID and not content: raise DemistoException( "You must provide a content to upload using one of the following arguments: content, entryID." ) client.create_session(hostname, username, password) # For the content argument - the input is text. writing_mode = 'w' if entryID: file = demisto.getFilePath(entryID) filePath = file['path'] writing_mode = 'wb' with open(filePath, mode='rb') as f: content = f.read() with open_file(fr'{path}', mode=writing_mode) as file_obj: file_obj.write(content) return f'File {get_file_name(path)} was uploaded successfully'
def read_file(input_data, input_type): data = [] # type: ignore if not input_data: return data if input_type.endswith("string"): if 'b64' in input_type: input_data = base64.b64decode(input_data) file_content = input_data.decode("utf-8") else: file_content = input_data else: res = demisto.getFilePath(input_data) if not res: return_error("Entry {} not found".format(input_data)) file_path = res['path'] if input_type.startswith('json'): with open(file_path, 'r') as f: file_content = f.read() if input_type.startswith('csv'): return pd.read_csv(file_path).fillna('').to_dict(orient='records') elif input_type.startswith('json'): return json.loads(file_content) elif input_type.startswith('pickle'): return pd.read_pickle(file_path, compression=None) else: return_error("Unsupported file type %s" % input_type)
def get_file(entry_id): get_file_path_res = demisto.getFilePath(entry_id) file_path = get_file_path_res["path"] file_name = get_file_path_res["name"] with open(file_path, 'rb') as f: file_bytes = f.read() return file_name, file_bytes
def wildfire_get_verdicts_command(): if ('EntryID' in demisto.args() and 'hash_list' in demisto.args()) or ( 'EntryID' not in demisto.args() and 'hash_list' not in demisto.args()): return_error('Specify exactly 1 of the following arguments: EntryID, hash_list.') if 'EntryID' in demisto.args(): inputs = argToList(demisto.args().get('EntryID')) paths = [demisto.getFilePath(element)['path'] for element in inputs] else: paths = hash_list_to_file(argToList(demisto.args().get('hash_list'))) for file_path in paths: result, verdicts_data = wildfire_get_verdicts(file_path) pretty_verdicts = prettify_verdicts(verdicts_data) md = tableToMarkdown('WildFire Verdicts', pretty_verdicts, removeNull=True) dbot_score = create_dbot_score_from_verdicts(pretty_verdicts) ec = { "WildFire.Verdicts(val.SHA256 == obj.SHA256 || val.MD5 == obj.MD5)": pretty_verdicts, "DBotScore(val.Indicator == obj.Indicator)": dbot_score } demisto.results({ 'Type': entryTypes['note'], 'Contents': result, 'ContentsFormat': formats['json'], 'HumanReadable': md, 'ReadableContentsFormat': formats['markdown'], 'EntryContext': ec })
def file_upload_raw(body, file_entry_id, filename_to_upload): uri = 'php/fileupload.php' if not filename_to_upload: # first priority for the file name is user's argument # second priority for the file name is the file name in the context filename_dq = demisto.dt( demisto.context(), 'File(val=val.EntryID=="' + file_entry_id + '")=val.Name') if filename_dq and filename_dq[0]: filename_to_upload = filename_dq else: # last priority for the file name is demisto's entryID filename_to_upload = file_entry_id with open(demisto.getFilePath(file_entry_id)['path'], 'rb') as file_to_upload: file_up = {'amas_filename': file_to_upload} result = http_request( uri, 'post', API_HEADERS, body, '', files=file_up, ) if not result['success']: return_error('Failed to upload sample due to: ' + result['errorMessage']) return result
def hunt_command(client: Client, args: dict) -> CommandResults: yara_rule = args.get('yara_rule') yar_file_entry_id = args.get('yar_file_entry_id') if not (yara_rule or yar_file_entry_id): raise DemistoException( "You must provide either a YARA rule or a YAR file in order to execute the HUNT command" ) if yar_file_entry_id: file_path = demisto.getFilePath(yar_file_entry_id).get("path") with open(file_path, "rb") as file: yara_rule = file.read().decode("utf-8") # dates format: YYYY/MM/DD query_filters = assign_params( limit=int(args.get('limit', '100')), filter_meta=argToList(args.get('filter_meta')), filter_filetypes=argToList(args.get('file_types')), max_size=args.get('max_size'), min_size=args.get('min_size'), max_date=args.get('max_date'), min_date=args.get('min_date')) body = {"options": query_filters, "yara_rule": yara_rule} raw_response = client.hunt(body) entry_context = {"Request_ID": raw_response.get('meta', {}).get('reqid')} human_readable = tableToMarkdown('Search Result', entry_context, removeNull=True) return CommandResults(readable_output=human_readable, outputs_prefix='Malquery', outputs_key_field='Request_ID', outputs=entry_context, raw_response=raw_response)
def upload_new_file(self, object_type, object_type_id, parent_id, file_name, entry_id): """ this function upload new file to a selected folder(parent_id) :param object_type: drive/ group/ me/ site/ users :param object_type_id: the selected object type id. :param parent_id: an ID of the folder to upload the file to. :param file_name: file name :param entry_id: demisto file entry ID :return: graph api raw response """ file_path = demisto.getFilePath(entry_id).get("path") if "drives" == object_type: uri = f"{object_type}/{object_type_id}/items/{parent_id}:/{file_name}:/content" elif object_type in ["groups", "users", "sites"]: uri = f"{object_type}/{object_type_id}/drive/items/{parent_id}:/{file_name}:/content" with open(file_path, "rb") as file: headers = {"Content-Type": "application/octet-stream"} return self.ms_client.http_request(method="PUT", headers=headers, url_suffix=uri, data=file)
def collect_manual_attachments(self): attachments = [] for attachment in demisto.getArg('manualAttachObj') or []: res = demisto.getFilePath( os.path.basename(attachment['RealFileName'])) path = res.get('path', '') content_type, encoding = mimetypes.guess_type(path) if content_type is None or encoding is not None: content_type = 'application/octet-stream' maintype, subtype = content_type.split('/', 1) if maintype == 'text': with open(path) as fp: data = fp.read() else: with open(path, 'rb') as fp: # type: ignore data = fp.read() attachments.append({ 'name': attachment['FileName'], 'maintype': maintype, 'subtype': subtype, 'data': data, 'cid': None }) return attachments
def replace_existing_file(self, object_type, object_type_id, item_id, entry_id): """ replace file context in MS Graph resource :param object_type: ms graph resource. :param object_type_id: ms graph resource id. :param item_id: item_id: ms graph item_id. :param entry_id: demisto file entry id :return: graph api raw response """ file_path = demisto.getFilePath(entry_id).get("path", None) if not file_path: raise DemistoException( f"Could not find file path to the next entry id: {entry_id}. \n" f"Please provide another one.") if object_type == "drives": uri = f"{object_type}/{object_type_id}/items/{item_id}/content" elif object_type in ["groups", "sites", "users"]: uri = f"{object_type}/{object_type_id}/drive/items/{item_id}/content" with open(file_path, "rb") as file: headers = {"Content-Type": "application/octet-stream"} return self.ms_client.http_request(method="PUT", data=file, headers=headers, url_suffix=uri)
def collect_inline_attachments(self, attach_cids): """ collects all attachments which are inline - only used in html bodied emails """ inline_attachment = [] if attach_cids is not None and len(attach_cids) > 0: for cid in attach_cids: file = demisto.getFilePath(cid) file_path = file['path'] content_type, encoding = mimetypes.guess_type(file_path) if content_type is None or encoding is not None: content_type = 'application/octet-stream' main_type, sub_type = content_type.split('/', 1) fp = open(file_path, 'rb') data = fp.read() fp.close() inline_attachment.append({ 'ID': cid, 'name': file['name'], 'maintype': main_type, 'subtype': sub_type, 'data': data, 'cid': cid }) return inline_attachment
def get_yaml_obj(entry_id): try: yml_file_path = demisto.getFilePath(entry_id)['path'] with open(yml_file_path, 'r') as yml_file: data = yaml.safe_load(yml_file) except (ValueError, yaml.YAMLError): return_error('Failed to open integration file') return data
def upload_pcap(component_ip, entry_id): file_info = demisto.getFilePath(entry_id) shutil.copy(file_info['path'], file_info['name']) try: with open(file_info['name'], 'rb') as f: http_request('POST', '/j/rest/policy/pcap/upload/{}/'.format(component_ip), files={'uploadFile': f}, is_json=False) finally: shutil.rmtree(file_info['name'], ignore_errors=True)
def upload_attachment(id_type, object_id, type_name, file_entry_id): file_data = demisto.getFilePath(file_entry_id) file_path = file_data.get('path') file_name = file_data.get('name') try: file_size = os.path.getsize(file_path) with open(file_path, 'rb') as f: file_content = f.read() attachment_id = upload_business_object_attachment(file_name, file_size, file_content, type_name, id_type, object_id) return attachment_id except Exception as err: return_error(f'unable to open file: {err}')
def run_analysis(args): """Make API call to ANYRUN to submit file or url for analysis Parameters ---------- args : dict The analysis specifications and data. Returns ------- dict Response JSON from ANYRUN API call. """ try: entry_id = args.pop('file', None) obj_url = args.get('obj_url') obj_type = args.get('obj_type') if obj_type == 'remote file': obj_type = 'download' args['obj_type'] = 'download' # In the case only a url was entered but the object type arg wasn't changed if not entry_id and obj_url and obj_type == 'file': args['obj_type'] = obj_type = 'url' files = None if obj_type == 'file': cmd_res = demisto.getFilePath(entry_id) file_path = cmd_res.get('path') name = cmd_res.get('name') files = { 'file': (name, open(file_path, 'rb')) } # Format command arguments to API's parameter expectations env_bitness = int(args.get('env_bitness', 32)) args['env_bitness'] = env_bitness env_version = args.get('env_version').lower() if env_version == 'windows vista': args['env_version'] = 'vista' elif env_version == 'windows 8.1': args['env_version'] = '8.1' elif env_version == 'windows 10': args['env_version'] = '10' else: args['env_version'] = '7' url_suffix = 'analysis' response = http_request('POST', url_suffix, data=args, files=files) return response except ValueError: err_msg = 'Invalid entryID - File not found for the given entryID' return_error(err_msg)
def get_command_examples(entry_id): commands = [] # type: list errors = [] # type: list if entry_id is None: return commands, errors if re.match(r'[\d]+@[0-9a-fA-F]+', entry_id) is not None: examples_path = demisto.getFilePath(entry_id)['path'] with open(examples_path, 'r') as examples_file: commands = examples_file.read().split('\n') else: demisto.debug('failed to open command file, tried parsing as free text') commands = entry_id.split('\n') return commands, errors
def extract_text_command() -> dict: langs = argToList(demisto.getArg('langs')) or argToList(demisto.getParam('langs')) demisto.debug("Using langs settings: {}".format(langs)) entry_id = demisto.args()['entryid'] file_path = demisto.getFilePath(entry_id) if not file_path: return_error("Couldn't find entry id: {}".format(entry_id)) demisto.debug('Extracting text from file: {}'.format(file_path)) res = extract_text(file_path['path'], langs) file_entry = {'EntryID': entry_id, 'Text': res} return { 'Type': entryTypes['note'], 'Contents': res, 'ContentsFormat': formats['text'], 'ReadableContentsFormat': formats['markdown'], 'HumanReadable': "## Image OCR Extracted Text\n\n" + res, "EntryContext": {"File(val.EntryID == obj.EntryID)": file_entry}, }