AiTM API (Beta) Documentation

In order to access the API you will need to have a valid API key. To request an API key fill out the form here.

The beta API exists here:

https://aitm-beta.lab539.dev

Authentication

Requests to the API require a bearer token (i.e. your API key) to be passed as an Authorization header. If you were making a request with curl or powershell this would look as follows:

curl

curl -s -H "Authorization: Bearer <YOUR_API_KEY>" https://aitm-beta.lab539.dev/list

Powershell

Invoke-RestMethod -Uri "https://aitm-beta.lab539.dev/list" -Method Get -Headers @{Authorization = 'Bearer <YOUR_API_KEY>'}

You will receive a HTTP 401 response if your API key is invalid. A HTTP 200 indicates success and should also return data.

Your API key is a 64 character string, e.g. f2ca1bb6c7e907d06dafe4687e579fce76b37e4e93b7605022da52e6ccc26fd2. This is different to the 12 character access code which you need to register for the service. You can convert your access code into a registration code be registering here.

API Calls

The following API calls are available:

  • search - provides search capabilities across the entire dataset

  • list - this returns a detailed list of all AiTM infrastructure within the last 7 days

  • last-event - this returns the eventID of the last record added to the list (handy if you want to check if there is any new data without pulling down a full list each time)

/search

Info

Provides functionality to search within the following fields across the entire dataset:

  • hostname - search for any hostnames matching supplied string

  • ip - search for any records matching the supplied IP address

Requests use the following format:

  • /search/<field>/<value>

For example, the following will search for all entries with the text “microsoft” in the hostname:

  • /search/hostname/microsoft

The following will search for all entries corresponding to the IP “10.11.12.13”:

  • /search/ip/10.11.12.13

/search/hostname/<value>

Example Request

You can query this endpoint with either a GET/POST request. Examples:

curl

curl -s -H "Authorization: Bearer <YOUR_API_KEY>" https://aitm-beta.lab539.dev/search/hostname/linkedin | jq

Powershell

Invoke-RestMethod -Uri "https://aitm-beta.lab539.dev/search/hostname/linkedin" -Method Get -Headers @{Authorization = 'Bearer <YOUR_API_KEY>'}

Hostname searches must be a minimum of 5 characters. If you will receive a HTTP 400 response with a “Search string too short” message. Powershell strips

Example Response

[
  {
    "hostname": "www.linkedin.edinarealty-teams.com",
    "ip": "20.221.216.97",
    "timestamp": 1706663391,
    "confidence": "high"
  },
  {
    "hostname": "platform.linkedin.com.relaysecure.com",
    "ip": "64.23.183.153",
    "timestamp": 1710264914,
    "confidence": "high"
  },
  {
    "hostname": "linkedin-api.ss.fluxnews.site",
    "ip": "20.46.55.136",
    "timestamp": 1716386022,
    "confidence": "high"
  },
  {
    "hostname": "www.linkedin.paede.xyz",
    "ip": "65.109.181.7",
    "timestamp": 1716724199,
    "confidence": "high"
  }
]

The structure of the response is:

hostname : string

ip : string

timestamp : int

confidence : string

/search/ip/<value>

Example Request

You can query this endpoint with either a GET/POST request. Examples:

curl

curl -s -H "Authorization: Bearer <YOUR_API_KEY>" https://aitm-beta.lab539.dev/search/ip/165.232.77.140 | jq

Powershell

Invoke-RestMethod -Uri "https://aitm-beta.lab539.dev/search/ip/165.232.77.140" -Method Get -Headers @{Authorization = 'Bearer <YOUR_API_KEY>'}

Searches must include a valid IP address (IPv4 or IPv6). If you send an invalid IP address you will receive a HTTP 400 response with a “Invalid IP address” message.

Example Response

[
  {"hostname":"microsoft.join.meets-google.com","timestamp":1709931573,"confidence":"high"},
  {"hostname":"youtube.join.meets-google.com","timestamp":1709939491,"confidence":"high"},
  {"hostname":"appleid.icloud.meets-google.com","timestamp":1709940811,"confidence":"high"}
]

The structure of the response is:

hostname : string

timestamp : int

confidence : string

If the response is empty (i.e. content-length: 0) then there are no results for that IP address.

/list

Info

Provides a JSON list of AiTM infrastructure from the last 7 days as well as some rich information about it.

Example Request

You can query this endpoint with either a GET/POST request. An example curl command is as follows:

curl

curl -H "Authorization: Bearer <YOUR_API_KEY>" https://aitm-beta.lab539.dev/list

Powershell

Invoke-RestMethod -Uri "https://aitm-beta.lab539.dev/list" -Method Get -Headers @{Authorization = 'Bearer <YOUR_API_KEY>'}

Example Response

If successful this will return a response which will include a number of JSON records, one for each entry. Below is a snippet from a real response:

[
  {"hostname":"microsoft.i.illve.com","domain":"illve.com.","ip":"95.164.2.214","rdns":"","asn":"AS44477 STARK INDUSTRIES SOLUTIONS LTD","frontend":true,"backend":true,"active":true,"timestamp":1716627895,"confidence":"high","country":"NL","eventid":"38183c94-1483-4a2b-9c8c-9da33312f24c"},
  {"hostname":"www.secured.onefiles.space","domain":"onefiles.space.","ip":"139.59.241.61","rdns":"","asn":"AS14061 DigitalOcean, LLC","frontend":true,"backend":true,"active":true,"timestamp":1716656443,"confidence":"high","country":"SG","eventid":"c2982415-21fa-450c-843c-7ff04cd1aa5a"},
  {"hostname":"r2kt3s7m.secured.onefiles.space","domain":"onefiles.space.","ip":"139.59.241.61","rdns":"","asn":"AS14061 DigitalOcean, LLC","frontend":true,"backend":true,"active":true,"timestamp":1716657635,"confidence":"high","country":"SG","eventid":"6de16c63-8924-469f-a548-02bef0d67842"}
]  

If you want the response as a list of JSON objects rather than an array then add the ?format=list parameter to your request.

The objects and their types are:

  • hostname : string

  • domain : string

  • ip : string

  • rdns : string

  • asn : string

  • frontend : bool

  • backend : bool

  • active : bool

  • timestamp : int

  • confidence : string

  • country : string

  • eventid : string

You should expect duplication of some object data in your feed, so please ensure that you handle that sensibly - the only unique field should be the eventID but it is entirely possible to get identical events with only the time and eventID field differing. We do not remove events from the feed and the feed only includes records from the last 7 days.

Frontend, Backend, Active

There are three boolean values in the results:

  • frontend - this is set to “true” if the infrastructure in the record is operating as frontend infrastructure - i.e. it is infrastructure to which users are likely to authenticate, typically this is infrastructure hosting phishing websites or content. We recommend restricting access to this infrastructure (e.g. blocking at proxies or DNS)

  • backend - this is set to “true” if the infrastructure in the record is operating as backend infrastructure - i.e. it is infrastructure from which you are likely to see AiTM proxied authentication attempts. We recommend blocking authentication attempts from AiTM backend infrastructure

In a lot of cases there is overlap and some infrastructure may operate both backend and frontend functions, so both flags may be set to true. The dataset we are providing in the beta will mostly fall into this category.

  • active - this is set to “true” if the infrastructure appears to be active (i.e. alive) at the point we identify it (of course it may go offline at any point). We have mechanisms that allow us to identify offline infrastructure but this data is not being provided in the beta data feed. Offline infrastructure would have its active flag set to false.

Confidence Levels

  • confidence - rather than a score we decided to set the confidence level to one of “high”, “medium” or “low”. This is to help you decide whether certain actions are appropriate or not. You may chose to be more robust with your actions for high confidence infrastructure than you would be for low confidence infrastructure.

We should highlight that this confidence level relates to our confidence this being AiTM infrastructure - we make no assessment as to whether this AiTM infrastructure is being used for nefarious purposes. You will likely see some infrastructure that is clearly part of educational phishing related campaigns as you will also see infrastructure which is clearly involved in concerning activities.

/last-event

Info

Provides a JSON response containing the eventID of the most recent AiTM infrastructure record.

Example Request

You can query this endpoint with either a GET/POST request. An example curl command is as follows:

curl

curl https://aitm-beta.lab539.dev/last-event

Powershell

Invoke-RestMethod -Uri "https://aitm-beta.lab539.dev/last-event" -Method Get -Headers @{Authorization = 'Bearer <YOUR_API_KEY>'}

Calls to /last-event do not require authentication and do not count against any quota you may have.

Example Response

If successful this will return a response which will include the eventID of the newest recird. Below is an example response:

{"eventid":"6de16c63-8924-469f-a548-02bef0d67842"}

Checking this eventid against your existing data will allow you to identify whether there are any additional records since your last request.

API Quotas

Once the beta testing has completed it is possible that the number of API calls to get-detailed per day will be capped at the number of new records by default (i.e. if there are 50 new records in a day then you can call the API 50 times). Therefore checking if there has been an update by calling “/last-event” is advisable. There will always be a lower limit of 24 (i.e. you can call “/list” once per hour even on quiet days when there are not 24 updates).

The reason for this is primarily to ensure that we can offer the service at a very affordable price. If a quota presents you a problem then you may wish to pay a premium to have this cap removed (or you may wish to simply set up a webhook and not be met with such limits). We have yet to determine sensible quotas for the “/search” function - but the more registered users we have the cheaper we will be able to set search quotas.