From 8f53a44f7e9e228ec473d2c1033b6d033017ad59 Mon Sep 17 00:00:00 2001 From: bol-van Date: Wed, 17 Dec 2025 22:54:22 +0300 Subject: [PATCH] zapret-lib: orchestrator 'repeater' --- docs/changes.txt | 6 +++++- lua/zapret-auto.lua | 37 +++++++++++++++++++++++++++++++++---- lua/zapret-lib.lua | 4 ++-- lua/zapret-pcap.lua | 2 +- lua/zapret-wgobfs.lua | 2 +- 5 files changed, 42 insertions(+), 9 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index edcb02b..872e73c 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -110,7 +110,11 @@ v0.7.2 v0.7.4 * nfqws2, zapret-lib : check tcp sequence range overflow -* zapret-lib : seq compare functions +* zapret-lib: seq compare functions * nfqws2: add l3_len, l4_len to dissect * nfqws2: fix broken l7proto profile rediscovery * winws2: harden sandbox. disable child process execution , some UI interaction and desktop settings change + +v0.7.5 + +* zapret-auto : orchestrator "repeater" diff --git a/lua/zapret-auto.lua b/lua/zapret-auto.lua index 34bfca7..7b650ce 100644 --- a/lua/zapret-auto.lua +++ b/lua/zapret-auto.lua @@ -289,7 +289,7 @@ end -- args for failure detector - see standard_failure_detector or your own detector -- args for success detector - see standard_success_detector or your own detector -- args for hostkey generator - see standard_hostkey or your own generator --- test case: nfqws2 --qnum 200 --debug --lua-init=@zapret-lib.lua --lua-init=@zapret-auto.lua --in-range=-s34228 --lua-desync=circular --lua-desync=argdebug:strategy=1 --lua-desync=argdebug:strategy=2 +-- test case: --in-range=-s34228 --lua-desync=circular --lua-desync=argdebug:strategy=1 --lua-desync=argdebug:strategy=2 function circular(ctx, desync) local function count_strategies(hrec) if not hrec.ctstrategy then @@ -377,7 +377,7 @@ function cond_random(desync) return math.random(0,99)<(tonumber(desync.arg.percent) or 50) end -- this iif function detects packets having 'arg.pattern' string in their payload --- test case : nfqws2 --qnum 200 --debug --lua-init=@zapret-lib.lua --lua-init=@zapret-auto.lua --lua-desync=condition:iff=cond_payload_str:pattern=1234 --lua-desync=argdebug:testarg=1 --lua-desync=argdebug:testarg=2:morearg=xyz +-- test case : --lua-desync=condition:iff=cond_payload_str:pattern=1234 --lua-desync=argdebug:testarg=1 --lua-desync=argdebug:testarg=2:morearg=xyz -- test case (true) : echo aaz1234zzz | ncat -4u 1.1.1.1 443 -- test case (false) : echo aaze124zzz | ncat -4u 1.1.1.1 443 function cond_payload_str(desync) @@ -399,7 +399,7 @@ end -- for example, this can be used by custom protocol detectors -- arg: iff - condition function. takes desync as arg and returns bool. (cant use 'if' because of reserved word) -- arg: neg - invert condition function result --- test case : nfqws2 --qnum 200 --debug --lua-init=@zapret-lib.lua --lua-init=@zapret-auto.lua --lua-desync=condition:iff=cond_random --lua-desync=argdebug:testarg=1 --lua-desync=argdebug:testarg=2:morearg=xyz +-- test case : --lua-desync=condition:iff=cond_random --lua-desync=argdebug:testarg=1 --lua-desync=argdebug:testarg=2:morearg=xyz function condition(ctx, desync) require_iff(desync, "condition") orchestrate(ctx, desync) @@ -415,7 +415,7 @@ end -- can be used with other orchestrators to stop execution conditionally -- arg: iff - condition function. takes desync as arg and returns bool. (cant use 'if' because of reserved word) -- arg: neg - invert condition function result --- test case : nfqws2 --qnum 200 --debug --lua-init=@zapret-lib.lua --lua-init=@zapret-auto.lua --in-range=-s1 --lua-desync=circular --lua-desync=stopif:iff=cond_random:strategy=1 --lua-desync=argdebug:strategy=1 --lua-desync=argdebug:strategy=2 +-- test case : --in-range=-s1 --lua-desync=circular --lua-desync=stopif:iff=cond_random:strategy=1 --lua-desync=argdebug:strategy=1 --lua-desync=argdebug:strategy=2 function stopif(ctx, desync) require_iff(desync, "stopif") orchestrate(ctx, desync) @@ -427,3 +427,32 @@ function stopif(ctx, desync) DLOG("stopif: false") end end + +-- repeat following 'instances` `repeats` times, execute others with no tampering +-- arg: instances - number of following instances to be repeated. 1 by default +-- arg: repeats - number of repeats +-- test case : --lua-desync=repeater:repeats=2:instances=2 --lua-desync=argdebug:v=1 --lua-desync=argdebug:v=2 --lua-desync=argdebug:v=3 +function repeater(ctx, desync) + local repeats = tonumber(desync.arg.repeats) + if not repeats then + error("repeat: missing 'repeats'") + end + local instances = tonumber(desync.arg.instances) or 1 + orchestrate(ctx, desync) + if instances > #desync.plan then + instances = #desync.plan + end + local verdict = VERDICT_PASS + for r=1,repeats do + DLOG("repeater: "..r.."/"..repeats) + for i=1,instances do + verdict = plan_instance_execute(desync, verdict, desync.plan[i]) + end + end + -- remove repeated instances + for i=1,instances do + table.remove(desync.plan, 1) + end + -- replay the rest + return verdict_aggregate(verdict, replay_execution_plan(desync)) +end diff --git a/lua/zapret-lib.lua b/lua/zapret-lib.lua index f128899..744c799 100644 --- a/lua/zapret-lib.lua +++ b/lua/zapret-lib.lua @@ -76,7 +76,7 @@ end -- arg: pattern - substring for search inside reasm_data or desync.dis.payload -- arg: payload - set desync.l7payload to this if detected -- arg: undetected - set desync.l7payload to this if not detected --- test case : nfqws2 --qnum 200 --debug --lua-init=@zapret-lib.lua --lua-init=@zapret-antidpi.lua --lua-init=@zapret-auto.lua --lua-desync=detect_payload_str:pattern=1234:payload=my --lua-desync=fake:blob=0x1234:payload=my +-- test case : --lua-desync=detect_payload_str:pattern=1234:payload=my --lua-desync=fake:blob=0x1234:payload=my function detect_payload_str(ctx, desync) if not desync.arg.pattern then error("detect_payload_str: missing 'pattern'") @@ -227,7 +227,7 @@ function replay_execution_plan(desync) end -- this function demonstrates how to stop execution of upcoming desync instances and take over their job -- this can be used, for example, for orchestrating conditional processing without modifying of desync functions code --- test case : nfqws2 --qnum 200 --debug --lua-init=@zapret-lib.lua --lua-desync=desync_orchestrator_example --lua-desync=pass --lua-desync=pass +-- test case : --lua-desync=desync_orchestrator_example --lua-desync=pass --lua-desync=pass function desync_orchestrator_example(ctx, desync) DLOG("orchestrator: taking over upcoming desync instances") orchestrate(ctx, desync) diff --git a/lua/zapret-pcap.lua b/lua/zapret-pcap.lua index d0f86c3..b934b86 100644 --- a/lua/zapret-pcap.lua +++ b/lua/zapret-pcap.lua @@ -16,7 +16,7 @@ function pcap_write(file, raw) pcap_write_packet(file, raw) end --- test case : nfqws2 --qnum 200 --debug --lua-init=@zapret-lib.lua --lua-init=@zapret-pcap.lua --writeable=zdir --in-range=a --lua-desync=pcap:file=test.pcap +-- test case : --writeable=zdir --in-range=a --lua-desync=pcap:file=test.pcap -- arg : file= - file for storing pcap data. if --writeable is specified and filename is relative - append filename to writeable path -- arg : keep - do not overwrite file, append packets to existing function pcap(ctx, desync) diff --git a/lua/zapret-wgobfs.lua b/lua/zapret-wgobfs.lua index e76ef29..1aa9f26 100644 --- a/lua/zapret-wgobfs.lua +++ b/lua/zapret-wgobfs.lua @@ -1,4 +1,4 @@ --- test case : nfqws2 --qnum 200 --debug --lua-init=@zapret-wgobfs.lua --in-range=a --out-range=a --lua-desync=wgobfs:secret=mycoolpassword +-- test case : --in-range=a --out-range=a --lua-desync=wgobfs:secret=mycoolpassword -- encrypt standard wireguard messages - initiation, response, cookie - and change udp packet size -- do not encrypt data messages and keepalives -- wgobfs adds maximum of 30+padmax bytes to udp size