The Unwanted Traffic API supports both simple and complex filtering for the /sessions
, /attempts
, and /malware
endpoints. This page explains how to use these filters to query specific data.
Simple filters are applied using query parameters in the URL. Each parameter corresponds to a field in the data model, and multiple parameters are combined with an implicit AND operation. Simple filters are supported for the following endpoints:
/sessions
: Filter by session attributes, attempt details, or malware properties./attempts
: Filter by attempt attributes or associated session details./malware
: Filter by malware attributes or associated session details.The table below lists the supported simple filter fields for each endpoint:
Endpoint | Filter Field | Data Type | Description |
---|---|---|---|
/sessions | session-id | Integer | Unique session ID |
/sessions | session | String | Session identifier (e.g., "2a58f17a436b") |
/sessions | commands | String | Commands executed in the session |
/sessions | dst-ip | String | Destination IP (e.g., "192.168.0.96") |
/sessions | dst-port | Integer | Destination port (e.g., 2723) |
/sessions | dst-asn | Integer | Destination ASN (e.g., 7922) |
/sessions | dst-country | String | Destination country with URL-encoded spaces (e.g., "United%20States") |
/sessions | duration | Float | Session duration in seconds (e.g., 1.23172) |
/sessions | protocol | String | Protocol (e.g., "telnet", "ssh") |
/sessions | sensor | String | Sensor name (e.g., "raspberrypi") |
/sessions | src-ip | String | Source IP (e.g., "192.168.1.100") |
/sessions | src-port | Integer | Source port (e.g., 61248) |
/sessions | src-asn | Integer | Source ASN (e.g., 4766) |
/sessions | src-country | String | Source country with URL-encoded spaces (e.g., "South%20Korea") |
/sessions | timestamp | String | Session timestamp (e.g., "2025-02-23T00:00:00Z") |
/sessions | traffic-type | String | Traffic type (e.g., "attack", "scan") |
/sessions | start | String | Start timestamp for range (e.g., "2025-02-23T00:00:00Z") |
/sessions | end | String | End timestamp for range (e.g., "2025-02-23T23:59:59Z") |
/attempts | attempt-id | Integer | Unique attempt ID |
/attempts | attempt-session | String | Session identifier (e.g., "2a58f17a436b") |
/attempts | attempt-login | String | Login success ("true" or "false") |
/attempts | attempt-credentials | String | Credentials with URL-encoded "||" separating username and password (format: "username%7c%7cpassword") |
/attempts | attempt-username | String | Username used in attempt |
/attempts | attempt-password | String | Password used in attempt |
/attempts | start, end | String | Timestamp range via session |
/malware | malware-id | Integer | Unique malware ID |
/malware | malware-session | String | Session identifier (e.g., "82e4335b3bb3") |
/malware | malware-hash | String | Malware hash (e.g., "a8460f446be540410004b1a8db4083773fa46f7fe76fa84219c93daa1669f8f2") |
/malware | malware-site | String | Malware site URL with doubly URL-encoded forward slashes (e.g., "http:%252f%252f37.44.238.88") |
/malware | malware-type | String | Malware type (e.g., "redir", "download", "upload") |
/malware | start, end | String | Timestamp range via session |
Example Request (Simple Filter):
Retrieve sessions where the destination IP is "192.168.0.96" and the protocol is "telnet":
curl -H "X-API-Key: YOUR_API_KEY" -H "Accept: application/json" "https://defrancisco.us/unwanted-traffic/sessions?dst-ip=192.168.0.96&protocol=telnet&limit=1"
Example Response:
{
"status": "success",
"data": [
{
"attempts": [
{
"attempt_credentials": "root||xc3511",
"attempt_id": 1,
"attempt_login": "true",
"attempt_password": "xc3511",
"attempt_session": "2a58f17a436b",
"attempt_username": "root"
}
],
"commands": "sh; shell; enable; system; ping ;sh; >/usr/.a && cd /usr/; rm -rf .a; >/mnt/.a && cd /mnt/; rm -rf .a; >/var/run/.a && cd /var/run/; rm -rf .a; >/dev/shm/.a && cd /dev/shm/; rm -rf .a; >/etc/.a && cd /etc/; rm -rf .a; >/var/.a && cd /var/; rm -rf .a; >/tmp/.a && cd /tmp/; rm -rf .a; >/dev/.a && cd /dev/; rm -rf .a; >/var/home/user/fw/.a && cd /var/home/user/fw/; rm -rf .a; for i in `cat /proc/mounts|grep tmpfs|grep -v noexec|cut -d ' ' -f 2`; do >$i/.a && cd $i;done; cat /proc/mounts | grep tmpfs | grep -v noexec | cut -d -f 2; /bin/busybox wget --help; /bin/busybox ftpget --help; /bin/busybox echo -e '\\\\x67\\\\x61\\\\x79\\\\x66\\\\x67\\\\x74';",
"dst_asn": 7922,
"dst_country": "United States",
"dst_ip": "192.168.0.96",
"dst_port": 2723,
"duration": 1.23172,
"malware": [],
"protocol": "telnet",
"sensor": "raspberrypi",
"session": "2a58f17a436b",
"session_id": 1,
"src_asn": 4766,
"src_country": "South Korea",
"src_ip": "192.168.1.100",
"src_port": 61248,
"timestamp": "Sun, 23 Feb 2025 00:00:01 GMT",
"traffic_type": "attack"
}
],
"pagination": {
"limit": 1,
"offset": 0,
"totalRecords": 6850
}
}
Complex filters are applied using a single filter
query parameter, which accepts a JSON-encoded object. Complex filters support advanced operators and logical combinations, allowing for more precise queries. Supported operators include:
eq
: Equalsne
: Not equalsgt
: Greater thanlt
: Less thange
: Greater than or equal tole
: Less than or equal toin
: In a list of valuescontains
: String contains substringand
: Logical AND of conditionsor
: Logical OR of conditionsThe filter JSON object has the following structure:
field
: The field to filter on (e.g., "dst_ip", "protocol").operator
: The operator to apply (e.g., "eq", "contains").value
: The value to compare against (string, number, or array for "in").conditions
: Array of sub-filters for "and" or "or" operators.Complex filters must be URL-encoded when included in the query string.
Example Request (Complex Filter):
Retrieve sessions where the source IP is "192.168.1.100" AND the protocol is either "telnet" OR "ssh":
curl -H "X-API-Key: YOUR_API_KEY" -H "Accept: application/json" "https://defrancisco.us/unwanted-traffic/sessions?filter=%7B%22and%22:%5B%7B%22field%22:%22src_ip%22,%22operator%22:%22eq%22,%22value%22:%22192.168.1.100%22%7D,%7B%22or%22:%5B%7B%22field%22:%22protocol%22,%22operator%22:%22eq%22,%22value%22:%22telnet%22%7D,%7B%22field%22:%22protocol%22,%22operator%22:%22eq%22,%22value%22:%22ssh%22%7D%5D%7D%5D%7D&limit=1"
Decoded Filter JSON:
{
"and": [
{
"field": "src_ip",
"operator": "eq",
"value": "192.168.1.100"
},
{
"or": [
{
"field": "protocol",
"operator": "eq",
"value": "telnet"
},
{
"field": "protocol",
"operator": "eq",
"value": "ssh"
}
]
}
]
}
Example Response:
{
"status": "success",
"data": [
{
"attempts": [
{
"attempt_credentials": "root||xc3511",
"attempt_id": 1,
"attempt_login": "true",
"attempt_password": "xc3511",
"attempt_session": "2a58f17a436b",
"attempt_username": "root"
}
],
"commands": "sh; shell; enable; system; ping ;sh; >/usr/.a && cd /usr/; rm -rf .a; >/mnt/.a && cd /mnt/; rm -rf .a; >/var/run/.a && cd /var/run/; rm -rf .a; >/dev/shm/.a && cd /dev/shm/; rm -rf .a; >/etc/.a && cd /etc/; rm -rf .a; >/var/.a && cd /var/; rm -rf .a; >/tmp/.a && cd /tmp/; rm -rf .a; >/dev/.a && cd /dev/; rm -rf .a; >/var/home/user/fw/.a && cd /var/home/user/fw/; rm -rf .a; for i in `cat /proc/mounts|grep tmpfs|grep -v noexec|cut -d ' ' -f 2`; do >$i/.a && cd $i;done; cat /proc/mounts | grep tmpfs | grep -v noexec | cut -d -f 2; /bin/busybox wget --help; /bin/busybox ftpget --help; /bin/busybox echo -e '\\\\x67\\\\x61\\\\x79\\\\x66\\\\x67\\\\x74';",
"dst_asn": 7922,
"dst_country": "United States",
"dst_ip": "192.168.0.96",
"dst_port": 2723,
"duration": 1.23172,
"malware": [],
"protocol": "telnet",
"sensor": "raspberrypi",
"session": "2a58f17a436b",
"session_id": 1,
"src_asn": 4766,
"src_country": "South Korea",
"src_ip": "192.168.1.100",
"src_port": 61248,
"timestamp": "Sun, 23 Feb 2025 00:00:01 GMT",
"traffic_type": "attack"
}
],
"pagination": {
"limit": 1,
"offset": 0,
"totalRecords": 7604
}
}
To effectively use filters:
in
or contains
.400 Bad Request
errors.limit
, offset
) to manage large result sets (see Pagination).commands
or malware-site
, use the contains
operator in complex filters to search for substrings.limit
values to verify results before querying large datasets.