Library
TB comes with 20 libraries, built into the app. Bring one in with import, then use its functions with a dot.
import ioc
let note = "Beacon to hxxp://evil[.]example[.]com from 203.0.113.9"
let found = ioc.extract(note)
say(found.urls, found.ips)
Core
Everyday building blocks: numbers, text, dates, randomness, patterns and the computer you're on.
-
mathNumbers beyond + - * /: square roots, powers, rounding, trigonometry. -
textText helpers: padding, wrapping, number formatting and random ids. -
timeClocks and dates: the time now, timestamps, formatting, parsing and waiting. -
randomRandom numbers, picks and shuffles (use seed(n) to repeat them). -
reRegular expressions: search text with patterns like "\d+" (digits) or "\w+@\w+". -
osThe computer TB runs on: your program's arguments, environment variables, running other programs, and exiting.
Files and data
Read and write files, JSON and CSV.
Security (SOC)
Parse logs, detect attacks, pull out and defang indicators, hash and decode, and report.
-
logsRead log files into records (maps) you can search and count: syslog, Linux auth.log (SSH and sudo), Apache/nginx access logs, JSON lines, CSV and Windows Security event exports. -
detectDetection rules for logs: describe what suspicious looks like as a map (or load a Sigma rule), run it over records from the logs library, and get alerts back. -
iocIndicators of compromise (IOCs): pull IPs, domains, URLs, emails, file hashes and CVE IDs out of any text, check what something is, and defang them (1.2.3[.]4, hxxp://) so nobody clicks a bad link by accident. -
hashHashes (fingerprints) of text and files: MD5, SHA-1, SHA-256 and SHA-512, HMAC signatures, and a safe way to compare secrets. -
encodeEncodings attackers (and the web) use: base64, hex, URL encoding and ROT13, plus entropy to spot random-looking text such as packed code or generated domains. -
reportTurn records and alerts into something to read or share: aligned text tables, Markdown, CSV, a self-contained HTML page, and a timeline.
Network and intel
IP and CIDR maths, port checks, web requests and threat-intelligence lookups.
Desktop GUI
Windows, buttons, tables, menus and dialogs.
Testing
Checks for your own programs, run with tb test.
Built in, no import needed
These functions are always there, and every text, list, map and number has methods you call with a dot, like "hi".upper() or names.sort().
say(...) | Show values on the screen, with spaces between them. |
ask(prompt?) -> text | Show prompt, wait for the person to type, and give back what they typed. |
len(value) -> number | How many letters (text), items (list) or keys (map). |
str(value) -> text | The value as text. |
num(text) -> number | The text as a number, like num("42"). |
range(end) / range(start, end, step?) -> list | A list of whole numbers from start up to (not including) end. |
push(list, value) -> list | Add value to the end of the list. |
care(name?) | Show a kind message. |
type(value) -> text | One of: number, text, bool, nil, list, map, function, module. |
keys(map) -> list | The map's keys, in order. |
int(value) -> number | The whole-number part (3.9 gives 3). Text is turned into a number first. |
round(number, digits?) -> number | Rounded to digits after the dot (default 0). 2.5 rounds to 3. |
min(list) / min(a, b, ...) -> value | The smallest value. |
max(list) / max(a, b, ...) -> value | The biggest value. |
sum(list) -> number | All the numbers in the list added up. |
sorted(list) -> list | A new sorted list (all numbers or all text). |
exit(code?) | Stop the program now. 0 (the default) means all went well. |
Methods on text
.chars() -> list | A list of the text's letters. |
.contains(part) -> bool | True if part appears in the text. |
.ends_with(part) -> bool | True if the text ends with part. |
.find(part) -> number | Where part first appears (0 is the start), or -1. |
.is_number() -> bool | True if num() could turn this text into a number. |
.len() -> number | How many letters the text has. |
.lines() -> list | The text cut into its lines. |
.lower() -> text | The text in small letters. |
.repeat(n) -> text | The text n times in a row. |
.replace(old, new) -> text | The text with every old swapped for new. |
.slice(start, end?) -> text | The letters from start up to (not including) end. Negative counts from the end. |
.split(sep?) -> list | Cut the text at every sep. With no sep, cut at spaces. |
.starts_with(part) -> bool | True if the text begins with part. |
.to_number() -> number | The text as a number (like num()). |
.trim() -> text | The text without spaces, tabs or newlines at the start and end. |
.upper() -> text | The text in CAPITAL letters. |
Methods on lists
.contains(value) -> bool | True if the list has value in it. |
.copy() -> list | A new list with the same items. |
.each(fn) -> nil | Call fn(item) for every item. |
.filter(fn) -> list | A new list of the items where fn(item) is true. |
.first() -> value | The first item, or nil if the list is empty. |
.index_of(value) -> number | The position of value in the list, or -1. |
.insert(position, value) -> list | Put value at position, moving the rest along (changes the list). |
.is_empty() -> bool | True if the list has no items. |
.join(sep?) -> text | All the items as one text, with sep between them. |
.last() -> value | The last item, or nil if the list is empty. |
.len() -> number | How many items the list has. |
.map(fn) -> list | A new list of fn(item) for every item. |
.max() -> value | The biggest item. |
.min() -> value | The smallest item. |
.pop() -> value | Take the last item off the list (changes it) and give it back. |
.push(value) -> list | Add value to the end (changes the list) and give the list back. |
.reduce(fn, start) -> value | Combine the items: fn(fn(start, first), second) and so on. |
.remove_at(position) -> value | Take out the item at position (changes the list) and give it back. |
.reverse() -> list | A new list in the opposite order. |
.slice(start, end?) -> list | A new list of the items from start up to (not including) end. |
.sort() -> list | A new sorted list (all numbers or all text). |
.sort_by(fn) -> list | A new list sorted by what fn(item) gives back. |
.sum() -> number | All the numbers added up. |
.unique() -> list | A new list without repeats (first ones kept). |
Methods on maps
.copy() -> map | A new map with the same keys and values. |
.get(key, default?) -> value | The value for key, or default (nil) if it's missing. |
.has(key) -> bool | True if the map has this key. |
.is_empty() -> bool | True if the map has no keys. |
.items() -> list | A list of [key, value] pairs. |
.keys() -> list | The map's keys, in order. |
.len() -> number | How many keys the map has. |
.merge(other) -> map | A new map with both maps' keys (other wins). |
.remove(key) -> value | Take key out of the map (changes it); gives back its value, or nil. |
.set(key, value) -> map | Put value under key (changes the map) and give the map back. |
.values() -> list | The map's values, in order. |
Methods on numbers
.abs() -> number | The number without its minus sign. |
.ceil() -> number | The whole number at or above it. |
.floor() -> number | The whole number at or below it. |
.round(digits?) -> number | Rounded to digits after the dot (default 0). 2.5 rounds to 3. |
.to_text() -> text | The number as text (like str()). |