A MAAT/rulescan crash-debugging log shows the engine's getCfgId() lookup called with domain=".twitter.com", table_id=12, type="SNI", confirming MAAT performs SNI-field domain matching against a configured blocklist table (table_id 12 = SSL/SNI domain tables DF_SSL_REGION/DJ_SSL_REGION; table_id 22 = HTTP URL tables DF_HTTP_URL/DJ_HTTP_URL seen in the same crash series), and that the underlying librulescan.so string-scan library is prone to native crashes (SIGABRT) under real traffic.
上图可看到调用getCfgId()函数输入参数domain=".twitter.com",table_id=12,type="SNI"。根据table_id=12查询table_info.conf可查看到对应域配置表信息如下...经4次测试,有3次table_id=12,对应连接表DF_SSL_REGION和DJ_SSL_REGION;有1次table_id=22,对应连接表DF_HTTP_URL和DJ_HTTP_URL。
Defense implications
- Confirms MAAT's blocking decision for at least this class of rule is keyed off the literal SNI hostname string per-connection; SNI encryption (ECH) or domain fronting defeats this exact matching path, not just generic 'encryption'.
Related findings
The Fujian (domestic China) deployment uses a punycode/IDN-aware keyword-filtering policy object named '中文涉诈域名' (Chinese fraud-related domains) with wildcard item matching; a bug ticket shows the policy engine failing to match an IDN punycode domain correctly against this object, revealing the underlying components: a 'verify-policy' microservice, and libraries 'libmaatframe' and 'librulescan' handling rule evaluation.
The internal 'MAAT网络流处理配置统一描述框架' engineering manual (v3.1.20, author 郑超, 2021) documents MAAT's Redis-synced rule-compilation framework and its RuleScan/Hyperscan-based pattern-matching engine (libmaatframe.so / librulescan), and records that RuleScan's fast-scan feature caused a production outage on 2019-03-19 and has been disabled ever since.
An internal 'MAAT Configuration Description Manual (String)' fully documents MAAT's rule-compilation model: per-field string matches (substring/prefix/suffix/exact/regex/AND-of-substrings/offset-anchored substrings) grouped into up to 8 AND/NOT clauses per compiled rule (conjunctive normal form), each carrying an action code (0=block, 1=monitor-only, 2=whitelist), blacklist and logging flags, and a floating-point execution-order field for safe rule reordering, plus the C scanning API (Maat_full_scan_string) and the file/JSON formats used to push rule updates to production.
Internal MAAT engineering Q&A notes detail the rule engine's filter hierarchy: a 'region' config matches on keyword / regex / IP / extended-IP(CIDR) / numeric / file-digest / text-similarity / FQDN fields; regions roll up via AND/OR into 'group' configs; groups roll up into an 8-clause-max 'compile' config in conjunctive normal form. Rule config is pushed via a Redis single-primary/multi-replica tree, and MAAT itself is not distributed — each production front-end box runs its own single MAAT instance that receives pushed config and calls the shared rulescan library to execute the actual scan.
The AppSketch/MAAT signature system contains a systematically dated, patch-versioned catalog of FQDN-based detection signatures for dozens of individually named commercial VPN apps (e.g. V2VPN, V2Netvpn, Turbo VPN, LetsVPN, AdGuard VPN, Avira Phantom VPN, TouchVPN, FinchVPN, Opera VPN, Ultrasurf VPN, GoFly VPN), each modeled as an 'app' object in category 'networking' / subcategory 'tunnels' whose default deny_action drops the flow while sending both an ICMP-unreachable and a TCP RST to the client. At least 35 such distinct VPN-app signature objects appear in this batch alone, dated July-November 2024, with repeated 'Patch0N' revisions to the same app as its domains rotate.
A production TSG maat.conf shows the MAAT rule-matching engine running four parallel instances (STATIC, DYNAMIC, APP_SIGNATURE_MAAT, CAPTURE); the APP_SIGNATURE_MAAT instance is explicitly configured against app_sketch_tableinfo.conf / app_sketch_maat.json -- directly confirming MAAT is the execution engine underlying the AppSketch signature system -- and is tagged with an ACCEPT_TAGS datacenter value 'xjlhs', indicating this specific instance is scoped to a Xinjiang deployment.