Help Center
< All Topics
Print

ArcSight ESM API

Here is an example on how to get a API token

https://esm:8443/www/core-service/rest/LoginService/login?login=admin&password=password

Here is the URL to ESM Swagger

https://esm:8443/detect-api

Here is two example

curl -X GET ”https://esm:8443/detect-api/rest/rules/allIds” -H ”accept: /” -H ”Authorization: Bearer EKMQEX_kyH-S34tD0tX3ic6CyVnDZ92NZCrPXkqSa5s=”

curl -X GET ”https://esm:8443/detect-api/rest/activelists/H%2BIrcfm4BABD239ty-mSKog%3D%3D/entries” -H ”accept: /” -H ”Authorization: Bearer QWWj0-MuK8D31ETL2mZPKFrGJgTN-hzoV__oS02rl_U=”

Here is a script that fetches all Connectors and cases in ESM

import json
import os
import sys
import requests
import urllib3

urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

CRED_FILE = "cred.json"


def load_credentials(filepath):
    with open(filepath, "r", encoding="utf-8") as f:
        config = json.load(f)
    return config.get("url"), config.get("username"), config.get("password")


class ArcSightDetectClient:
    def __init__(self, base_url, username, password):
        self.base_url = base_url.rstrip("/")
        self.username = username
        self.password = password
        self.token = None
        self.headers = {"Accept": "application/json"}

    def login(self):
        login_url = f"{self.base_url}/www/core-service/rest/LoginService/login"
        payload = {"login": self.username, "password": self.password}
        headers = {"Content-Type": "application/x-www-form-urlencoded", "Accept": "application/json"}

        res = requests.post(login_url, data=payload, headers=headers, verify=False)
        res.raise_for_status()
        data = res.json()
        self.token = (
            data.get("log.loginResponse", {}).get("log.return")
            or data.get("logonResponse", {}).get("return")
            or data.get("loginResponse", {}).get("return")
            or data.get("return")
        )
        self.headers["Authorization"] = f"Bearer {self.token}"

    def logout(self):
        if not self.token:
            return
        logout_url = f"{self.base_url}/www/core-service/rest/LoginService/logout"
        try:
            requests.post(logout_url, data={"authToken": self.token}, headers={"Content-Type": "application/x-www-form-urlencoded"}, verify=False)
        except Exception:
            pass

    def get_all_activelist_ids(self):
        url = f"{self.base_url}/detect-api/rest/v1/activelists/allIds"
        res = requests.get(url, headers=self.headers, verify=False)
        res.raise_for_status()
        return res.json()

    def get_activelist_details(self, list_id):
        url = f"{self.base_url}/detect-api/rest/v1/activelists/{list_id}"
        res = requests.get(url, headers=self.headers, verify=False)
        if res.status_code == 200:
            return res.json()
        return None

    def get_activelist_entries(self, list_id):
        """Hämtar rader/poster i en Active List."""
        url = f"{self.base_url}/detect-api/rest/v1/activelists/{list_id}/entries"
        res = requests.get(url, headers=self.headers, verify=False)
        if res.status_code == 200:
            return res.json()
        return None


def main():
    client = None
    try:
        url, username, password = load_credentials(CRED_FILE)
        client = ArcSightDetectClient(url, username, password)
        client.login()

        print("Hämtar Active Lists...")
        al_ids = client.get_all_activelist_ids()

        # Slår upp de första 5 listorna
        print(f"\nVisar de 5 första av totalt {len(al_ids)} Active Lists:")
        for list_id in al_ids[:5]:
            details = client.get_activelist_details(list_id)
            if details:
                name = details.get("name", "Namnlös")
                uri = details.get("reference", {}).get("uri", "")
                
                # Hämtar rader
                entries = client.get_activelist_entries(list_id)
                num_entries = len(entries) if isinstance(entries, list) else "N/A"
                print(f"  - [{name}] (Poster: {num_entries}) | Sökväg: {uri}")

    except Exception as e:
        print(f"Fel: {e}", file=sys.stderr)
    finally:
        if client:
            client.logout()


if __name__ == "__main__":
    main()

The credentials is stored outside of the script like this

lani@fedora:~/arcsight$ cat cred.json 
{
  "url": "https://esm:8443",
  "username": "admin",
  "password": "password"
}
lani@fedora:~/arcsight$ 

Here is the output of the script

lani@fedora:~/arcsight$ python3 gemini6.py 
[+] Inloggad! Token: jUIPOgwBmeWt1I6...

=== CONNECTOR STATUS ===
Status: 2 UP | 6 DOWN

[+] Aktiva connectors:
  - [UP]   testalerts           (ID: 3X1yMtpMBABCEMxJEZ+IVjw==)
  - [UP]   Manager Internal Agent (ID: 3qpZDtpMBABCAZsKho9kV5A==)

[-] Nere connectors:
  - [DOWN] threatintel          (ID: 3-VMm0JQBABCGPDSb5L9QMw==)
  - [DOWN] hana-db              (ID: 30R6DQ5YBABCHb2OjWx9gDA==)
  - [DOWN] testalertvialani     (ID: 322n-uZMBABCEHhj1fzbJpQ==)
  - [DOWN] syslog2              (ID: 3fttb4ZkBABC1AJ3ObGTlWQ==)
  - [DOWN] lab                  (ID: 3iIX9epYBABCDN+7LifJltQ==)
  - [DOWN] audit                (ID: 3kFRW4ZkBABC0BoB8FgB5Pg==)

=== CASES ===
Totalt antal ärenden: 1
  - Case: 'Ozzy' | Sökväg: /All Cases/All Cases/Public/Ozzy (ID: 77l3CPqABABCEAsHQl0ZmPA==)

=== ACTIVE LISTS ===
Totalt antal Active Lists i systemet: 113
[+] Sessionen avslutades korrekt.
lani@fedora:~/arcsight$ 

Here is another script which fetch all entries in

import json
import os
import sys
import requests
import urllib3

urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

CRED_FILE = "cred.json"
TARGET_LIST_NAME = "Suspicious Addresses List"


def load_credentials(filepath):
    """Läser in inloggningsuppgifter från cred.json."""
    if not os.path.exists(filepath):
        raise FileNotFoundError(f"Filen '{filepath}' hittades inte.")

    with open(filepath, "r", encoding="utf-8") as f:
        config = json.load(f)

    return config.get("url"), config.get("username"), config.get("password")


class ArcSightDetectClient:
    def __init__(self, base_url, username, password):
        self.base_url = base_url.rstrip("/")
        self.username = username
        self.password = password
        self.token = None
        self.headers = {"Accept": "application/json"}

    def login(self):
        """Autentiserar och sparar Bearer-token."""
        login_url = f"{self.base_url}/www/core-service/rest/LoginService/login"
        payload = {"login": self.username, "password": self.password}
        headers = {
            "Content-Type": "application/x-www-form-urlencoded",
            "Accept": "application/json",
        }

        response = requests.post(
            login_url, data=payload, headers=headers, verify=False
        )
        response.raise_for_status()

        data = response.json()
        self.token = (
            data.get("log.loginResponse", {}).get("log.return")
            or data.get("logonResponse", {}).get("return")
            or data.get("loginResponse", {}).get("return")
            or data.get("return")
        )

        if not self.token:
            raise ValueError("Kunde inte hämta token ur inloggningssvaret.")

        self.headers["Authorization"] = f"Bearer {self.token}"
        print(f"[+] Inloggad! Token: {self.token[:15]}...")

    def logout(self):
        """Avslutar sessionen i ESM."""
        if not self.token:
            return
        logout_url = f"{self.base_url}/www/core-service/rest/LoginService/logout"
        payload = {"authToken": self.token}
        headers = {"Content-Type": "application/x-www-form-urlencoded"}
        try:
            requests.post(
                logout_url, data=payload, headers=headers, verify=False
            )
            print("[+] Sessionen avslutades korrekt.")
        except Exception as e:
            print(f"[-] Fel vid utloggning: {e}")

    def find_activelist_id_by_name(self, list_name):
        """Söker upp ID för en Active List baserat på dess namn."""
        # 1. Testa direkt namnsökning via API:et
        url_by_name = f"{self.base_url}/detect-api/rest/v1/activelists/name/{list_name}"
        res = requests.get(url_by_name, headers=self.headers, verify=False)
        if res.status_code == 200:
            data = res.json()
            if isinstance(data, dict) and "resourceId" in data:
                return data["resourceId"]

        # 2. Fallback: Hämta alla ID:n och leta efter rätt namn
        print(f"[!] Direkt namnsökning misslyckades, söker bland alla Active Lists...")
        all_ids_url = f"{self.base_url}/detect-api/rest/v1/activelists/allIds"
        all_ids_res = requests.get(all_ids_url, headers=self.headers, verify=False)
        all_ids_res.raise_for_status()
        
        for list_id in all_ids_res.json():
            details_url = f"{self.base_url}/detect-api/rest/v1/activelists/{list_id}"
            details_res = requests.get(details_url, headers=self.headers, verify=False)
            if details_res.status_code == 200:
                info = details_res.json()
                if info.get("name") == list_name:
                    return list_id

        return None

    def get_activelist_entries(self, list_id):
        """Hämtar alla rader (entries) ur en specifik Active List."""
        url = f"{self.base_url}/detect-api/rest/v1/activelists/{list_id}/entries"
        res = requests.get(url, headers=self.headers, verify=False)
        res.raise_for_status()
        return res.json()


def main():
    client = None
    try:
        url, username, password = load_credentials(CRED_FILE)
        client = ArcSightDetectClient(url, username, password)
        client.login()

        print(f"\nSöker efter Active List: '{TARGET_LIST_NAME}'...")
        list_id = client.find_activelist_id_by_name(TARGET_LIST_NAME)

        if not list_id:
            print(f"[-] Hittade ingen Active List med namnet '{TARGET_LIST_NAME}'.")
            return

        print(f"[+] Hittade listan! ID: {list_id}")
        print(f"Hämtar poster från '{TARGET_LIST_NAME}'...\n")

        entries = client.get_activelist_entries(list_id)

        print(f"=== INNEHÅLL I {TARGET_LIST_NAME.upper()} ({len(entries)} rader) ===")
        print(json.dumps(entries, indent=2))

    except Exception as e:
        print(f"Ett fel uppstod: {e}", file=sys.stderr)

    finally:
        if client:
            client.logout()


if __name__ == "__main__":
    main()

Here is the output from the script

lani@fedora:~/arcsight$ python3 gemini7.py 
[+] Inloggad! Token: bzDtbsJ7NmZEinD...

Söker efter Active List: 'Suspicious Addresses List'...
[+] Hittade listan! ID: H-pkUTmsBABCA5uAy8FUEvg==
Hämtar poster från 'Suspicious Addresses List'...

=== INNEHÅLL I SUSPICIOUS ADDRESSES LIST (2 rader) ===
{
  "fields": [
    "address",
    "indicatorType",
    "firstDetectTime",
    "lastDetectTime",
    "port",
    "sightings",
    "threatLevel",
    "actors",
    "campaign",
    "sector",
    "mitreAttack",
    "description",
    "reference",
    "mitigation",
    "extraInfo",
    "creatorOrg",
    "cve",
    "virusTotalCount",
    "malwareName",
    "confidence",
    "arcsightSearchTerm",
    "arcsightBulletinID",
    "avSignatureName",
    "tiEventID",
    "threatActorTypes",
    "threatOrigin",
    "threatOperations",
    "malwareTypes",
    "toolName",
    "toolTypes",
    "targetLocationRegion",
    "targetLocationCountry",
    "atapPlusCS1",
    "atapPlusCS2",
    "atapPlusCS3",
    "atapPlusCS4",
    "atapPlusCS5"
  ],
  "entries": [
    {
      "fields": [
        "8.8.8.8",
        "",
        "",
        "",
        "",
        "",
        "low",
        "",
        "",
        "",
        "",
        "test",
        "",
        "",
        "",
        "",
        "",
        "",
        "",
        "",
        "",
        "",
        "",
        "",
        "",
        "",
        "",
        "",
        "",
        "",
        "",
        "",
        "",
        "",
        "",
        "",
        ""
      ]
    }
  ]
}
[+] Sessionen avslutades korrekt.
lani@fedora:~/arcsight$ 

Table of Contents
sv_SESwedish