Exporting MSV Actions using Python API

 

This post will cover how to bulk-export MSV Action details. The actions info could be useful in building a different categorization or understanding the actions coverage.

A possible use case is to pass the actions descriptions to an LLM to generate a different fine-tuned categorization, for example this is a snippet of categorizing Cloud Actions into finer categories by an LLM  ;

AbdElHafez_0-1735587811828.png

Another use case is to use "verodin_tags" column to generate statistics about the different actions Vs MITRE tags (e.g. ATT&CK:T1082). This column has multiple tags categories like like Malware, APT, ..etc that could be leverage to build visualization matrices per threats.

The code snippet provided is expands the library descried in a previous post by adding the getActions() function to msvlib_simple.py snippet. The few extra lines provided will just parse the data into Pandas dataframe. The actions info will be fetched by ;

actions = getActions() : GET : manage_sims/actions : Empty Body

 

 

###main.py
from msvlib_simple import *
import pandas as pd

folderName='.'
configFileName='credentials.txt'

headers_msv=readConfig(configFileName = configFileName
                       , folderName = folderName
                      )

url_base = headers_msv['url_base']
payload=json.dumps("")

actionsList = getActions(headers_msv, url_base)
actionsPd = pd.DataFrame(actionsList)

 

###credentials.txt --Remove this line
[hdr]
Content-Type = application/json 
Accept = application/json 
Authorization =  Bearer xxx=
Mandiant-Organization = UUID xxxx
url_base = https://app.validation.mandiant.com/

 

###msvlib_simple.py
import requests
import json
import configparser
import os
import urllib3
import time

def readConfig(configFileName='cre.txt',folderName='.'):
    configFileName=os.path.join(folderName, configFileName)
    config = configparser.ConfigParser()
    config.read(configFileName)
    keys=[key for key in config[config.sections()[0]]]
    values=[config[config.sections()[0]][key] for key in keys]
    headers={k:v for (k,v) in zip(keys,values)}
    return (headers)


def runAPI(endpoint='topology/nodes', verb='GET'
           , payload=json.dumps({}), headers_msv=json.dumps({})
           ,url_base = 'https://app.validation.mandiant.com/'
           ,params=None
           , printing=False ):
    url_msv=f"{url_base}{endpoint}"
    successful = False
    while not successful:
        try:
            res = requests.request(
                        method=verb
                        , url=url_msv
                        , params=params
                        , headers=headers_msv
                        , data=payload
                        , verify=False
                        , timeout=600
                    )
            successful = True
        except requests.exceptions.RequestException as e:
            print (f"Error : {e}")
            time.sleep(60)            
    if printing==True : print (res.url)
    if printing==True : print (res.request)
    if printing==True : print (res.text[:100])
    if res.text!='':
        return json.loads(res.text)
    else :
        return res.text



def getActions( headers_msv, url_base , filterPayload = {}):

#Returns a hash of sim_actions filtered by user provided tags
    payload=json.dumps(filterPayload)
    if filterPayload == {}:
    ##List actions
        returnActionsList=runAPI(endpoint=f"manage_sims/actions"
              , verb='GET'
              , payload=payload
              , headers_msv=headers_msv
              , url_base=url_base
             )

    else:
        returnActionsList=runAPI(endpoint=f"manage_sims/actions/filtered_actions"
                      , verb='GET'
                      , payload=payload
                      , headers_msv=headers_msv
                      , url_base=url_base
                     )
    return returnActionsList

 

 

 

0 0 150
0 REPLIES 0