mirror of
https://github.com/bol-van/zapret2.git
synced 2026-03-21 08:45:48 +00:00
Compare commits
70 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2ecd34cbca | ||
|
|
b5b1f71fcc | ||
|
|
f5f7de4086 | ||
|
|
a331d59d33 | ||
|
|
0a6d066e92 | ||
|
|
1216ef0364 | ||
|
|
52e38ee687 | ||
|
|
fd53a54cf3 | ||
|
|
c6b7e1fc43 | ||
|
|
a7a1520b40 | ||
|
|
04881b10b1 | ||
|
|
561e5e2718 | ||
|
|
e83e127c15 | ||
|
|
3590861ffe | ||
|
|
a12307d7f9 | ||
|
|
25a9f9e426 | ||
|
|
f4644e2a47 | ||
|
|
b9a0d42815 | ||
|
|
f76beba434 | ||
|
|
60b6ec2f49 | ||
|
|
ce95210d1c | ||
|
|
953d92b177 | ||
|
|
4d9b4c9ad8 | ||
|
|
ee7b72dc66 | ||
|
|
8eb588d6a4 | ||
|
|
08e1f8fba1 | ||
|
|
454eedeb36 | ||
|
|
7e761b3f03 | ||
|
|
3dd51ee3b1 | ||
|
|
07b1356c6c | ||
|
|
23445785c9 | ||
|
|
f4a7fe3aaf | ||
|
|
6d31036ca1 | ||
|
|
5ceb3aa301 | ||
|
|
7fd602885f | ||
|
|
af75c3d63d | ||
|
|
cb9789668f | ||
|
|
c16508e2e4 | ||
|
|
912eb1217a | ||
|
|
3a328089a3 | ||
|
|
4c76444b2d | ||
|
|
403413bb26 | ||
|
|
8ea6a17942 | ||
|
|
15731d6135 | ||
|
|
8255481787 | ||
|
|
d2a919f71d | ||
|
|
915130aed9 | ||
|
|
901ffdfe5a | ||
|
|
8caaf85b36 | ||
|
|
1dc5e23a41 | ||
|
|
ee859db268 | ||
|
|
37f7fbbdec | ||
|
|
81f6937187 | ||
|
|
cbf5be50d1 | ||
|
|
1966ea2298 | ||
|
|
d96350d2c7 | ||
|
|
5cb96559d0 | ||
|
|
dffba7cd13 | ||
|
|
5ad122da40 | ||
|
|
54871f4ef8 | ||
|
|
d06e4f4c82 | ||
|
|
322b050e45 | ||
|
|
5cb9cfc820 | ||
|
|
ede260d4fa | ||
|
|
9a7de03830 | ||
|
|
b9b14f254a | ||
|
|
653ed92cf8 | ||
|
|
0d99c68b1b | ||
|
|
6c75dcc002 | ||
|
|
b76e1f65a3 |
@@ -105,3 +105,12 @@ v0.7.2
|
|||||||
* zapret-lib: fix broken is_retransmission()
|
* zapret-lib: fix broken is_retransmission()
|
||||||
* zapret-auto: add success detector logic
|
* zapret-auto: add success detector logic
|
||||||
* nfqws2: clean lua cutoff on profile change
|
* nfqws2: clean lua cutoff on profile change
|
||||||
|
* zapret-auto: separate hostkey function
|
||||||
|
|
||||||
|
v0.7.4
|
||||||
|
|
||||||
|
* nfqws2, zapret-lib : check tcp sequence range overflow
|
||||||
|
* 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
|
||||||
|
|||||||
1169
docs/manual.md
1169
docs/manual.md
File diff suppressed because it is too large
Load Diff
@@ -9,7 +9,7 @@
|
|||||||
function standard_hostkey(desync)
|
function standard_hostkey(desync)
|
||||||
local hostkey = desync.track and desync.track.hostname
|
local hostkey = desync.track and desync.track.hostname
|
||||||
if hostkey then
|
if hostkey then
|
||||||
if desync.arg.nld and tonumber(desync.arg.nld)>0 then
|
if desync.arg.nld and tonumber(desync.arg.nld)>0 and not (desync.track and desync.track.hostname_is_ip) then
|
||||||
-- dissect_nld returns nil if domain is invalid or does not have this NLD
|
-- dissect_nld returns nil if domain is invalid or does not have this NLD
|
||||||
-- fall back to original hostkey if it fails
|
-- fall back to original hostkey if it fails
|
||||||
local hktemp = dissect_nld(hostkey, tonumber(desync.arg.nld))
|
local hktemp = dissect_nld(hostkey, tonumber(desync.arg.nld))
|
||||||
@@ -20,7 +20,6 @@ function standard_hostkey(desync)
|
|||||||
elseif not desync.arg.reqhost then
|
elseif not desync.arg.reqhost then
|
||||||
hostkey = host_ip(desync)
|
hostkey = host_ip(desync)
|
||||||
end
|
end
|
||||||
-- prevent nld for ip addresses
|
|
||||||
return hostkey
|
return hostkey
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -284,11 +283,12 @@ end
|
|||||||
-- if 'final' arg is present in an orchestrated instance it stops rotation
|
-- if 'final' arg is present in an orchestrated instance it stops rotation
|
||||||
-- arg: fails=N - failture count threshold. default is 3
|
-- arg: fails=N - failture count threshold. default is 3
|
||||||
-- arg: time=<sec> - if last failure happened earlier than `maxtime` seconds ago - reset failure counter. default is 60.
|
-- arg: time=<sec> - if last failure happened earlier than `maxtime` seconds ago - reset failure counter. default is 60.
|
||||||
-- arg: reqhost - pass with no tampering if hostname is unavailable
|
|
||||||
-- arg: success_detector - success detector function name
|
-- arg: success_detector - success detector function name
|
||||||
-- arg: failure_detector - failure detector function name
|
-- arg: failure_detector - failure detector function name
|
||||||
|
-- arg: hostkey - hostkey generator function name
|
||||||
-- args for failure detector - see standard_failure_detector or your own detector
|
-- 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 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: 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
|
||||||
function circular(ctx, desync)
|
function circular(ctx, desync)
|
||||||
local function count_strategies(hrec)
|
local function count_strategies(hrec)
|
||||||
|
|||||||
@@ -234,6 +234,12 @@ function desync_orchestrator_example(ctx, desync)
|
|||||||
return replay_execution_plan(desync)
|
return replay_execution_plan(desync)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- if seq is over 2G s and p position comparision can be wrong
|
||||||
|
function pos_counter_overflow(desync, mode, reverse)
|
||||||
|
if not desync.track or not desync.track.tcp or (mode~='s' and mode~='p') then return false end
|
||||||
|
local track_pos = reverse and desync.track.pos.reverse or desync.track.pos.direct
|
||||||
|
return track_pos.tcp.rseq_over_2G
|
||||||
|
end
|
||||||
-- these functions duplicate range check logic from C code
|
-- these functions duplicate range check logic from C code
|
||||||
-- mode must be n,d,b,s,x,a
|
-- mode must be n,d,b,s,x,a
|
||||||
-- pos is {mode,pos}
|
-- pos is {mode,pos}
|
||||||
@@ -265,7 +271,7 @@ function pos_get(desync, mode, reverse)
|
|||||||
return 0
|
return 0
|
||||||
end
|
end
|
||||||
function pos_check_from(desync, range)
|
function pos_check_from(desync, range)
|
||||||
if range.from.mode == 'x' then return false end
|
if range.from.mode == 'x' or pos_counter_overflow(desync, range.from.mode) then return false end
|
||||||
if range.from.mode ~= 'a' then
|
if range.from.mode ~= 'a' then
|
||||||
if desync.track then
|
if desync.track then
|
||||||
return pos_get(desync, range.from.mode) >= range.from.pos
|
return pos_get(desync, range.from.mode) >= range.from.pos
|
||||||
@@ -277,7 +283,7 @@ function pos_check_from(desync, range)
|
|||||||
end
|
end
|
||||||
function pos_check_to(desync, range)
|
function pos_check_to(desync, range)
|
||||||
local ps
|
local ps
|
||||||
if range.to.mode == 'x' then return false end
|
if range.to.mode == 'x' or pos_counter_overflow(desync, range.to.mode) then return false end
|
||||||
if range.to.mode ~= 'a' then
|
if range.to.mode ~= 'a' then
|
||||||
if desync.track then
|
if desync.track then
|
||||||
ps = pos_get(desync, range.to.mode)
|
ps = pos_get(desync, range.to.mode)
|
||||||
@@ -297,8 +303,31 @@ end
|
|||||||
function pos_str(desync, pos)
|
function pos_str(desync, pos)
|
||||||
return pos.mode..pos_get(desync, pos.mode)
|
return pos.mode..pos_get(desync, pos.mode)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- sequence comparision functions. they work only within 2G interval
|
||||||
|
-- seq1>=seq2
|
||||||
|
function seq_ge(seq1, seq2)
|
||||||
|
return 0==bitand(u32add(seq1, -seq2), 0x80000000)
|
||||||
|
end
|
||||||
|
-- seq1>seq2
|
||||||
|
function seq_gt(seq1, seq2)
|
||||||
|
return seq1~=seq2 and seq_ge(seq1, seq2)
|
||||||
|
end
|
||||||
|
-- seq1<seq2
|
||||||
|
function seq_lt(seq1, seq2)
|
||||||
|
return 0~=bitand(u32add(seq1, -seq2), 0x80000000)
|
||||||
|
end
|
||||||
|
-- seq1<=seq2
|
||||||
|
function seq_le(seq1, seq2)
|
||||||
|
return seq1==seq2 or 0~=bitand(u32add(seq1, -seq2), 0x80000000)
|
||||||
|
end
|
||||||
|
-- seq_low<=seq<=seq_hi
|
||||||
|
function seq_within(seq, seq_low, seq_hi)
|
||||||
|
return seq_ge(seq, seq_low) and seq_le(seq, seq_hi)
|
||||||
|
end
|
||||||
|
|
||||||
function is_retransmission(desync)
|
function is_retransmission(desync)
|
||||||
return desync.track and desync.track.pos.direct.tcp and 0==bitand(u32add(desync.track.pos.direct.tcp.uppos_prev, -desync.track.pos.direct.tcp.pos), 0x80000000)
|
return desync.track and desync.track.pos.direct.tcp and seq_ge(desync.track.pos.direct.tcp.uppos_prev, desync.track.pos.direct.tcp.pos)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- prepare standard rawsend options from desync
|
-- prepare standard rawsend options from desync
|
||||||
@@ -801,6 +830,7 @@ end
|
|||||||
-- ip6_hopbyhop[=hex] - add hopbyhop ipv6 header with optional data. data size must be 6+N*8. all zero by default.
|
-- ip6_hopbyhop[=hex] - add hopbyhop ipv6 header with optional data. data size must be 6+N*8. all zero by default.
|
||||||
-- ip6_hopbyhop2[=hex] - add second hopbyhop ipv6 header with optional data. data size must be 6+N*8. all zero by default.
|
-- ip6_hopbyhop2[=hex] - add second hopbyhop ipv6 header with optional data. data size must be 6+N*8. all zero by default.
|
||||||
-- ip6_destopt[=hex] - add destopt ipv6 header with optional data. data size must be 6+N*8. all zero by default.
|
-- ip6_destopt[=hex] - add destopt ipv6 header with optional data. data size must be 6+N*8. all zero by default.
|
||||||
|
-- ip6_destopt2[=hex] - add second destopt ipv6 header with optional data. data size must be 6+N*8. all zero by default.
|
||||||
-- ip6_routing[=hex] - add routing ipv6 header with optional data. data size must be 6+N*8. all zero by default.
|
-- ip6_routing[=hex] - add routing ipv6 header with optional data. data size must be 6+N*8. all zero by default.
|
||||||
-- ip6_ah[=hex] - add authentication ipv6 header with optional data. data size must be 6+N*4. 0000 + 4 random bytes by default.
|
-- ip6_ah[=hex] - add authentication ipv6 header with optional data. data size must be 6+N*4. 0000 + 4 random bytes by default.
|
||||||
|
|
||||||
|
|||||||
@@ -155,6 +155,11 @@ static void ConntrackApplyPos(const struct tcphdr *tcp, t_ctrack *t, bool bRever
|
|||||||
if (direct->scale != SCALE_NONE) direct->winsize_calc <<= direct->scale;
|
if (direct->scale != SCALE_NONE) direct->winsize_calc <<= direct->scale;
|
||||||
if (mss && !direct->mss) direct->mss = mss;
|
if (mss && !direct->mss) direct->mss = mss;
|
||||||
if (scale != SCALE_NONE) direct->scale = scale;
|
if (scale != SCALE_NONE) direct->scale = scale;
|
||||||
|
|
||||||
|
if (!direct->rseq_over_2G && ((direct->seq_last - direct->seq0) & 0x80000000))
|
||||||
|
direct->rseq_over_2G = true;
|
||||||
|
if (!reverse->rseq_over_2G && ((reverse->seq_last - reverse->seq0) & 0x80000000))
|
||||||
|
reverse->rseq_over_2G = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// non-tcp packets are passed with tcphdr=NULL but len_payload filled
|
// non-tcp packets are passed with tcphdr=NULL but len_payload filled
|
||||||
@@ -208,19 +213,7 @@ static void ConntrackFeedPacket(t_ctrack *t, bool bReverse, const struct tcphdr
|
|||||||
|
|
||||||
ConntrackApplyPos(tcphdr, t, bReverse, len_payload);
|
ConntrackApplyPos(tcphdr, t, bReverse, len_payload);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
if (bReverse)
|
|
||||||
{
|
|
||||||
t->pos.server.seq_last = t->pos.server.pos;
|
|
||||||
t->pos.server.pos += len_payload;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
t->pos.client.seq_last = t->pos.client.pos;
|
|
||||||
t->pos.client.pos += len_payload;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
clock_gettime(CLOCK_REALTIME, &t->pos.t_last);
|
clock_gettime(CLOCK_REALTIME, &t->pos.t_last);
|
||||||
// make sure t_start gets exactly the same value as first t_last
|
// make sure t_start gets exactly the same value as first t_last
|
||||||
if (!t->t_start.tv_sec) t->t_start = t->pos.t_last;
|
if (!t->t_start.tv_sec) t->t_start = t->pos.t_last;
|
||||||
|
|||||||
@@ -17,17 +17,18 @@ typedef struct
|
|||||||
uint64_t pcounter; // packet counter
|
uint64_t pcounter; // packet counter
|
||||||
uint64_t pdcounter; // data packet counter (with payload)
|
uint64_t pdcounter; // data packet counter (with payload)
|
||||||
uint64_t pbcounter; // transferred byte counter. includes retransmissions. it's not the same as relative seq.
|
uint64_t pbcounter; // transferred byte counter. includes retransmissions. it's not the same as relative seq.
|
||||||
|
|
||||||
|
// tcp only state, not used in udp
|
||||||
uint32_t pos; // TCP: seq_last+payload, ack_last+payload UDP: sum of all seen payload lenghts including current
|
uint32_t pos; // TCP: seq_last+payload, ack_last+payload UDP: sum of all seen payload lenghts including current
|
||||||
uint32_t uppos; // max seen position. useful to detect retransmissions
|
uint32_t uppos; // max seen position. useful to detect retransmissions
|
||||||
uint32_t uppos_prev; // previous max seen position. useful to detect retransmissions
|
uint32_t uppos_prev; // previous max seen position. useful to detect retransmissions
|
||||||
uint32_t seq_last; // TCP: last seen seq and ack UDP: sum of all seen payload lenghts NOT including current
|
uint32_t seq_last; // TCP: last seen seq and ack UDP: sum of all seen payload lenghts NOT including current
|
||||||
|
|
||||||
// tcp only state, not used in udp
|
|
||||||
uint32_t seq0; // starting seq and ack
|
uint32_t seq0; // starting seq and ack
|
||||||
uint16_t winsize; // last seen window size
|
uint16_t winsize; // last seen window size
|
||||||
uint16_t mss;
|
uint16_t mss;
|
||||||
uint32_t winsize_calc; // calculated window size
|
uint32_t winsize_calc; // calculated window size
|
||||||
uint8_t scale; // last seen window scale factor. SCALE_NONE if none
|
uint8_t scale; // last seen window scale factor. SCALE_NONE if none
|
||||||
|
bool rseq_over_2G;
|
||||||
} t_ctrack_position;
|
} t_ctrack_position;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
|||||||
@@ -718,6 +718,29 @@ bool prepare_low_appdata()
|
|||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOL JobSandbox()
|
||||||
|
{
|
||||||
|
BOOL bRes = FALSE;
|
||||||
|
HANDLE hJob;
|
||||||
|
JOBOBJECT_BASIC_LIMIT_INFORMATION basic_limit;
|
||||||
|
JOBOBJECT_BASIC_UI_RESTRICTIONS basic_ui;
|
||||||
|
|
||||||
|
if (hJob = CreateJobObjectW(NULL, NULL))
|
||||||
|
{
|
||||||
|
basic_limit.LimitFlags = JOB_OBJECT_LIMIT_ACTIVE_PROCESS;
|
||||||
|
// prevent child process creation
|
||||||
|
basic_limit.ActiveProcessLimit = 1;
|
||||||
|
// prevent some UI interaction and settings change
|
||||||
|
basic_ui.UIRestrictionsClass = JOB_OBJECT_UILIMIT_DESKTOP | JOB_OBJECT_UILIMIT_DISPLAYSETTINGS | JOB_OBJECT_UILIMIT_EXITWINDOWS | JOB_OBJECT_UILIMIT_GLOBALATOMS | JOB_OBJECT_UILIMIT_HANDLES | JOB_OBJECT_UILIMIT_READCLIPBOARD | JOB_OBJECT_UILIMIT_SYSTEMPARAMETERS | JOB_OBJECT_UILIMIT_WRITECLIPBOARD;
|
||||||
|
bRes = SetInformationJobObject(hJob, JobObjectBasicLimitInformation, &basic_limit, sizeof(basic_limit)) &&
|
||||||
|
SetInformationJobObject(hJob, JobObjectBasicUIRestrictions, &basic_ui, sizeof(basic_ui)) &&
|
||||||
|
AssignProcessToJobObject(hJob, GetCurrentProcess());
|
||||||
|
w_win32_error = GetLastError();
|
||||||
|
CloseHandle(hJob);
|
||||||
|
}
|
||||||
|
return bRes;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#define WINDIVERT_DEVICE_NAME "WinDivert"
|
#define WINDIVERT_DEVICE_NAME "WinDivert"
|
||||||
static bool b_isandbox_set = false;
|
static bool b_isandbox_set = false;
|
||||||
@@ -734,6 +757,8 @@ bool win_sandbox(void)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
if (!LowMandatoryLevel())
|
if (!LowMandatoryLevel())
|
||||||
return false;
|
return false;
|
||||||
|
if (!JobSandbox())
|
||||||
|
return false;
|
||||||
// for LUA code to find where to store files
|
// for LUA code to find where to store files
|
||||||
b_isandbox_set = true;
|
b_isandbox_set = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -505,7 +505,10 @@ static uint8_t ct_new_postnat_fix(const t_ctrack *ctrack, const struct dissect *
|
|||||||
return VERDICT_DROP;
|
return VERDICT_DROP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool pos_overflow(const t_ctrack_position *pos, char mode)
|
||||||
|
{
|
||||||
|
return (mode=='s' || mode=='p') && pos && pos->rseq_over_2G;
|
||||||
|
}
|
||||||
static uint64_t pos_get(const t_ctrack_position *pos, char mode)
|
static uint64_t pos_get(const t_ctrack_position *pos, char mode)
|
||||||
{
|
{
|
||||||
if (pos)
|
if (pos)
|
||||||
@@ -524,7 +527,7 @@ static uint64_t pos_get(const t_ctrack_position *pos, char mode)
|
|||||||
static bool check_pos_from(const t_ctrack_position *pos, const struct packet_range *range)
|
static bool check_pos_from(const t_ctrack_position *pos, const struct packet_range *range)
|
||||||
{
|
{
|
||||||
uint64_t ps;
|
uint64_t ps;
|
||||||
if (range->from.mode == 'x') return false;
|
if ((range->from.mode == 'x') || pos_overflow(pos,range->from.mode)) return false;
|
||||||
if (range->from.mode != 'a')
|
if (range->from.mode != 'a')
|
||||||
{
|
{
|
||||||
if (pos)
|
if (pos)
|
||||||
@@ -540,7 +543,7 @@ static bool check_pos_from(const t_ctrack_position *pos, const struct packet_ran
|
|||||||
static bool check_pos_to(const t_ctrack_position *pos, const struct packet_range *range)
|
static bool check_pos_to(const t_ctrack_position *pos, const struct packet_range *range)
|
||||||
{
|
{
|
||||||
uint64_t ps;
|
uint64_t ps;
|
||||||
if (range->to.mode == 'x') return false;
|
if (range->to.mode == 'x' || pos_overflow(pos,range->to.mode)) return false;
|
||||||
if (range->to.mode != 'a')
|
if (range->to.mode != 'a')
|
||||||
{
|
{
|
||||||
if (pos)
|
if (pos)
|
||||||
@@ -707,7 +710,7 @@ static uint8_t desync(
|
|||||||
struct func_list *func;
|
struct func_list *func;
|
||||||
int ref_arg = LUA_NOREF, status;
|
int ref_arg = LUA_NOREF, status;
|
||||||
bool b, b_cutoff_all, b_unwanted_payload;
|
bool b, b_cutoff_all, b_unwanted_payload;
|
||||||
t_lua_desync_context ctx = { .dp = dp, .ctrack = ctrack, .dis = dis, .cancel = false, .incoming = bIncoming };
|
t_lua_desync_context ctx = { .magic = 0, .dp = dp, .ctrack = ctrack, .dis = dis, .cancel = false, .incoming = bIncoming };
|
||||||
const char *sDirection = bIncoming ? "in" : "out";
|
const char *sDirection = bIncoming ? "in" : "out";
|
||||||
struct packet_range *range;
|
struct packet_range *range;
|
||||||
size_t l;
|
size_t l;
|
||||||
@@ -754,10 +757,12 @@ static uint8_t desync(
|
|||||||
DLOG("* lua '%s' : voluntary cutoff\n", instance);
|
DLOG("* lua '%s' : voluntary cutoff\n", instance);
|
||||||
else if (check_pos_cutoff(pos, range))
|
else if (check_pos_cutoff(pos, range))
|
||||||
{
|
{
|
||||||
DLOG("* lua '%s' : %s pos %c%llu %c%llu is beyond range %c%u%c%c%u (ctrack %s)\n",
|
DLOG("* lua '%s' : %s pos %c%llu %c%llu overflow %u %u is beyond range %c%u%c%c%u (ctrack %s)\n",
|
||||||
instance, sDirection,
|
instance, sDirection,
|
||||||
range->from.mode, pos_get(pos, range->from.mode),
|
range->from.mode, pos_get(pos, range->from.mode),
|
||||||
range->to.mode, pos_get(pos, range->to.mode),
|
range->to.mode, pos_get(pos, range->to.mode),
|
||||||
|
pos_overflow(pos, range->from.mode),
|
||||||
|
pos_overflow(pos, range->to.mode),
|
||||||
range->from.mode, range->from.pos,
|
range->from.mode, range->from.pos,
|
||||||
range->upper_cutoff ? '<' : '-',
|
range->upper_cutoff ? '<' : '-',
|
||||||
range->to.mode, range->to.pos,
|
range->to.mode, range->to.pos,
|
||||||
@@ -855,8 +860,14 @@ static uint8_t desync(
|
|||||||
lua_pushf_str("func", func->func);
|
lua_pushf_str("func", func->func);
|
||||||
lua_pushf_int("func_n", ctx.func_n);
|
lua_pushf_int("func_n", ctx.func_n);
|
||||||
lua_pushf_str("func_instance", instance);
|
lua_pushf_str("func_instance", instance);
|
||||||
int initial_stack_top = lua_gettop(params.L);
|
|
||||||
|
// lua should not store and access ctx outside of this call
|
||||||
|
// if this happens make our best to prevent access to bad memory
|
||||||
|
// this is not crash-proof but better than nothing
|
||||||
|
ctx.magic = MAGIC_CTX; // mark struct as valid
|
||||||
status = lua_pcall(params.L, 2, LUA_MULTRET, 0);
|
status = lua_pcall(params.L, 2, LUA_MULTRET, 0);
|
||||||
|
ctx.magic = 0; // mark struct as invalid
|
||||||
|
|
||||||
if (status)
|
if (status)
|
||||||
{
|
{
|
||||||
lua_dlog_error();
|
lua_dlog_error();
|
||||||
@@ -1310,8 +1321,8 @@ static uint8_t dpi_desync_tcp_packet_play(
|
|||||||
bool bDiscoveredL7;
|
bool bDiscoveredL7;
|
||||||
if (ctrack_replay)
|
if (ctrack_replay)
|
||||||
{
|
{
|
||||||
bDiscoveredL7 = !ctrack_replay->l7proto_discovered && ctrack_replay->l7proto != L7_UNKNOWN;
|
if (bDiscoveredL7 = !ctrack_replay->l7proto_discovered && ctrack_replay->l7proto != L7_UNKNOWN)
|
||||||
ctrack_replay->l7proto_discovered = true;
|
ctrack_replay->l7proto_discovered = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
bDiscoveredL7 = l7proto != L7_UNKNOWN;
|
bDiscoveredL7 = l7proto != L7_UNKNOWN;
|
||||||
@@ -1755,8 +1766,8 @@ static uint8_t dpi_desync_udp_packet_play(
|
|||||||
bool bDiscoveredL7;
|
bool bDiscoveredL7;
|
||||||
if (ctrack_replay)
|
if (ctrack_replay)
|
||||||
{
|
{
|
||||||
bDiscoveredL7 = !ctrack_replay->l7proto_discovered && l7proto != L7_UNKNOWN;
|
if ((bDiscoveredL7 = !ctrack_replay->l7proto_discovered && l7proto != L7_UNKNOWN))
|
||||||
ctrack_replay->l7proto_discovered = true;
|
ctrack_replay->l7proto_discovered = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
bDiscoveredL7 = l7proto != L7_UNKNOWN;
|
bDiscoveredL7 = l7proto != L7_UNKNOWN;
|
||||||
|
|||||||
60
nfq2/lua.c
60
nfq2/lua.c
@@ -690,6 +690,22 @@ static int luacall_clock_gettime(lua_State *L)
|
|||||||
}
|
}
|
||||||
LUA_STACK_GUARD_RETURN(L,2)
|
LUA_STACK_GUARD_RETURN(L,2)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static t_lua_desync_context *lua_desync_ctx()
|
||||||
|
{
|
||||||
|
if (lua_isnil(params.L,1))
|
||||||
|
luaL_error(params.L, "missing ctx");
|
||||||
|
if (!lua_islightuserdata(params.L,1))
|
||||||
|
luaL_error(params.L, "bad ctx - invalid data type");
|
||||||
|
|
||||||
|
t_lua_desync_context *ctx = lua_touserdata(params.L,1);
|
||||||
|
// ensure it's really ctx. LUA could pass us any lightuserdata pointer
|
||||||
|
if (ctx->magic!=MAGIC_CTX)
|
||||||
|
luaL_error(params.L, "bad ctx - magic bytes invalid");
|
||||||
|
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
|
||||||
static int luacall_instance_cutoff(lua_State *L)
|
static int luacall_instance_cutoff(lua_State *L)
|
||||||
{
|
{
|
||||||
// out : instance_name.profile_number[0]
|
// out : instance_name.profile_number[0]
|
||||||
@@ -699,16 +715,12 @@ static int luacall_instance_cutoff(lua_State *L)
|
|||||||
|
|
||||||
LUA_STACK_GUARD_ENTER(L)
|
LUA_STACK_GUARD_ENTER(L)
|
||||||
|
|
||||||
const t_lua_desync_context *ctx;
|
|
||||||
|
|
||||||
if (lua_isnil(L,1))
|
if (lua_isnil(L,1))
|
||||||
// this can happen in orchestrated function. they do not have their own ctx and they cant cutoff
|
// this can happen in orchestrated function. they do not have their own ctx and they cant cutoff
|
||||||
DLOG("instance cutoff not possible because missing ctx\n");
|
DLOG("instance cutoff not possible because missing ctx\n");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!lua_islightuserdata(L,1))
|
const t_lua_desync_context *ctx = lua_desync_ctx();
|
||||||
luaL_error(L, "instance_cutoff expect desync context in the first argument");
|
|
||||||
ctx = lua_touserdata(L,1);
|
|
||||||
|
|
||||||
int argc=lua_gettop(L);
|
int argc=lua_gettop(L);
|
||||||
bool bIn,bOut;
|
bool bIn,bOut;
|
||||||
@@ -720,7 +732,6 @@ static int luacall_instance_cutoff(lua_State *L)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
bIn = bOut = true;
|
bIn = bOut = true;
|
||||||
|
|
||||||
if (ctx->ctrack)
|
if (ctx->ctrack)
|
||||||
{
|
{
|
||||||
DLOG("instance cutoff for '%s' in=%u out=%u\n",ctx->instance,bIn,bOut);
|
DLOG("instance cutoff for '%s' in=%u out=%u\n",ctx->instance,bIn,bOut);
|
||||||
@@ -785,11 +796,7 @@ static int luacall_lua_cutoff(lua_State *L)
|
|||||||
|
|
||||||
LUA_STACK_GUARD_ENTER(L)
|
LUA_STACK_GUARD_ENTER(L)
|
||||||
|
|
||||||
t_lua_desync_context *ctx;
|
t_lua_desync_context *ctx = lua_desync_ctx();
|
||||||
|
|
||||||
if (!lua_islightuserdata(L,1))
|
|
||||||
luaL_error(L, "lua_cutoff expect desync context in the first argument");
|
|
||||||
ctx = lua_touserdata(L,1);
|
|
||||||
|
|
||||||
int argc=lua_gettop(L);
|
int argc=lua_gettop(L);
|
||||||
bool bIn,bOut;
|
bool bIn,bOut;
|
||||||
@@ -821,11 +828,7 @@ static int luacall_execution_plan(lua_State *L)
|
|||||||
|
|
||||||
LUA_STACK_GUARD_ENTER(L)
|
LUA_STACK_GUARD_ENTER(L)
|
||||||
|
|
||||||
const t_lua_desync_context *ctx;
|
t_lua_desync_context *ctx = lua_desync_ctx();
|
||||||
|
|
||||||
if (!lua_islightuserdata(L,1))
|
|
||||||
luaL_error(L, "execution_plan expect desync context in the first argument");
|
|
||||||
ctx = lua_touserdata(L,1);
|
|
||||||
|
|
||||||
lua_newtable(L);
|
lua_newtable(L);
|
||||||
|
|
||||||
@@ -862,11 +865,7 @@ static int luacall_execution_plan_cancel(lua_State *L)
|
|||||||
{
|
{
|
||||||
lua_check_argc(L,"execution_plan_cancel",1);
|
lua_check_argc(L,"execution_plan_cancel",1);
|
||||||
|
|
||||||
t_lua_desync_context *ctx;
|
t_lua_desync_context *ctx = lua_desync_ctx();
|
||||||
|
|
||||||
if (!lua_islightuserdata(L,1))
|
|
||||||
luaL_error(L, "execution_plan_cancel expect desync context in the first argument");
|
|
||||||
ctx = lua_touserdata(L,1);
|
|
||||||
|
|
||||||
DLOG("execution plan cancel from '%s'\n",ctx->instance);
|
DLOG("execution plan cancel from '%s'\n",ctx->instance);
|
||||||
|
|
||||||
@@ -881,11 +880,7 @@ static int luacall_raw_packet(lua_State *L)
|
|||||||
|
|
||||||
LUA_STACK_GUARD_ENTER(L)
|
LUA_STACK_GUARD_ENTER(L)
|
||||||
|
|
||||||
const t_lua_desync_context *ctx;
|
const t_lua_desync_context *ctx = lua_desync_ctx();
|
||||||
|
|
||||||
if (!lua_islightuserdata(L,1))
|
|
||||||
luaL_error(L, "raw_packet expect desync context in the first argument");
|
|
||||||
ctx = lua_touserdata(L,1);
|
|
||||||
|
|
||||||
lua_pushlstring(L, (const char*)ctx->dis->data_pkt, ctx->dis->len_pkt);
|
lua_pushlstring(L, (const char*)ctx->dis->data_pkt, ctx->dis->len_pkt);
|
||||||
|
|
||||||
@@ -1251,13 +1246,15 @@ void lua_push_dissect(const struct dissect *dis)
|
|||||||
|
|
||||||
if (dis)
|
if (dis)
|
||||||
{
|
{
|
||||||
lua_createtable(params.L, 0, 7);
|
lua_createtable(params.L, 0, 9);
|
||||||
lua_pushf_iphdr(dis->ip, dis->len_l3);
|
lua_pushf_iphdr(dis->ip, dis->len_l3);
|
||||||
lua_pushf_ip6hdr(dis->ip6, dis->len_l3);
|
lua_pushf_ip6hdr(dis->ip6, dis->len_l3);
|
||||||
lua_pushf_tcphdr(dis->tcp, dis->len_l4);
|
lua_pushf_tcphdr(dis->tcp, dis->len_l4);
|
||||||
lua_pushf_udphdr(dis->udp, dis->len_l4);
|
lua_pushf_udphdr(dis->udp, dis->len_l4);
|
||||||
lua_pushf_int("l4proto",dis->proto);
|
lua_pushf_int("l4proto",dis->proto);
|
||||||
lua_pushf_int("transport_len",dis->transport_len);
|
lua_pushf_int("transport_len",dis->transport_len);
|
||||||
|
lua_pushf_int("l3_len",dis->len_l3);
|
||||||
|
lua_pushf_int("l4_len",dis->len_l4);
|
||||||
lua_pushf_raw("payload",dis->data_payload,dis->len_payload);
|
lua_pushf_raw("payload",dis->data_payload,dis->len_payload);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1282,10 +1279,11 @@ void lua_pushf_ctrack_pos(const t_ctrack *ctrack, const t_ctrack_position *pos)
|
|||||||
if (ctrack->ipproto == IPPROTO_TCP)
|
if (ctrack->ipproto == IPPROTO_TCP)
|
||||||
{
|
{
|
||||||
lua_pushliteral(params.L, "tcp");
|
lua_pushliteral(params.L, "tcp");
|
||||||
lua_createtable(params.L, 0, 10);
|
lua_createtable(params.L, 0, 11);
|
||||||
lua_pushf_lint("seq0", pos->seq0);
|
lua_pushf_lint("seq0", pos->seq0);
|
||||||
lua_pushf_lint("seq", pos->seq_last);
|
lua_pushf_lint("seq", pos->seq_last);
|
||||||
lua_pushf_lint("rseq", pos->seq_last - pos->seq0);
|
lua_pushf_lint("rseq", pos->seq_last - pos->seq0);
|
||||||
|
lua_pushf_bool("rseq_over_2G", pos->rseq_over_2G);
|
||||||
lua_pushf_int("pos", pos->pos - pos->seq0);
|
lua_pushf_int("pos", pos->pos - pos->seq0);
|
||||||
lua_pushf_int("uppos", pos->uppos - pos->seq0);
|
lua_pushf_int("uppos", pos->uppos - pos->seq0);
|
||||||
lua_pushf_int("uppos_prev", pos->uppos_prev - pos->seq0);
|
lua_pushf_int("uppos_prev", pos->uppos_prev - pos->seq0);
|
||||||
@@ -2135,7 +2133,7 @@ static int luacall_csum_ip4_fix(lua_State *L)
|
|||||||
}
|
}
|
||||||
static int luacall_csum_tcp_fix(lua_State *L)
|
static int luacall_csum_tcp_fix(lua_State *L)
|
||||||
{
|
{
|
||||||
// csum_ip4_fix(ip_header, tcp_header, payload) returns tcp_header
|
// csum_tcp_fix(ip_header, tcp_header, payload) returns tcp_header
|
||||||
lua_check_argc(L,"csum_tcp_fix",3);
|
lua_check_argc(L,"csum_tcp_fix",3);
|
||||||
|
|
||||||
LUA_STACK_GUARD_ENTER(L)
|
LUA_STACK_GUARD_ENTER(L)
|
||||||
@@ -2176,7 +2174,7 @@ static int luacall_csum_tcp_fix(lua_State *L)
|
|||||||
}
|
}
|
||||||
static int luacall_csum_udp_fix(lua_State *L)
|
static int luacall_csum_udp_fix(lua_State *L)
|
||||||
{
|
{
|
||||||
// csum_ip4_fix(ip_header, tcp_header, payload) returns tcp_header
|
// csum_udp_fix(ip_header, udp_header, payload) returns udp_header
|
||||||
lua_check_argc(L,"csum_udp_fix",3);
|
lua_check_argc(L,"csum_udp_fix",3);
|
||||||
|
|
||||||
LUA_STACK_GUARD_ENTER(L)
|
LUA_STACK_GUARD_ENTER(L)
|
||||||
@@ -3000,9 +2998,11 @@ static void lua_init_const(void)
|
|||||||
{"IP_OFFMASK",IP_OFFMASK},
|
{"IP_OFFMASK",IP_OFFMASK},
|
||||||
{"IP_FLAGMASK",IP_RF|IP_DF|IP_MF},
|
{"IP_FLAGMASK",IP_RF|IP_DF|IP_MF},
|
||||||
{"IPTOS_ECN_MASK",IPTOS_ECN_MASK},
|
{"IPTOS_ECN_MASK",IPTOS_ECN_MASK},
|
||||||
|
{"IPTOS_ECN_NOT_ECT",0},
|
||||||
{"IPTOS_ECN_ECT1",IPTOS_ECN_ECT1},
|
{"IPTOS_ECN_ECT1",IPTOS_ECN_ECT1},
|
||||||
{"IPTOS_ECN_ECT0",IPTOS_ECN_ECT0},
|
{"IPTOS_ECN_ECT0",IPTOS_ECN_ECT0},
|
||||||
{"IPTOS_ECN_CE",IPTOS_ECN_CE},
|
{"IPTOS_ECN_CE",IPTOS_ECN_CE},
|
||||||
|
{"IPTOS_DSCP_MASK",0xF0},
|
||||||
{"IP6F_MORE_FRAG",0x0001}, // in ip6.h it's defined depending of machine byte order
|
{"IP6F_MORE_FRAG",0x0001}, // in ip6.h it's defined depending of machine byte order
|
||||||
|
|
||||||
{"IPPROTO_IP",IPPROTO_IP},
|
{"IPPROTO_IP",IPPROTO_IP},
|
||||||
|
|||||||
@@ -101,7 +101,9 @@ bool lua_reconstruct_tcphdr(int idx, struct tcphdr *tcp, size_t *len);
|
|||||||
bool lua_reconstruct_udphdr(int idx, struct udphdr *udp);
|
bool lua_reconstruct_udphdr(int idx, struct udphdr *udp);
|
||||||
bool lua_reconstruct_dissect(int idx, uint8_t *buf, size_t *len, bool badsum, bool ip6_preserve_next);
|
bool lua_reconstruct_dissect(int idx, uint8_t *buf, size_t *len, bool badsum, bool ip6_preserve_next);
|
||||||
|
|
||||||
|
#define MAGIC_CTX 0xE73DC935
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
uint32_t magic;
|
||||||
unsigned int func_n;
|
unsigned int func_n;
|
||||||
const char *func, *instance;
|
const char *func, *instance;
|
||||||
const struct desync_profile *dp;
|
const struct desync_profile *dp;
|
||||||
|
|||||||
@@ -630,6 +630,7 @@ static int win_main()
|
|||||||
{
|
{
|
||||||
res=w_win32_error; goto ex;
|
res=w_win32_error; goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!win_sandbox())
|
if (!win_sandbox())
|
||||||
{
|
{
|
||||||
res=w_win32_error;
|
res=w_win32_error;
|
||||||
@@ -637,7 +638,6 @@ static int win_main()
|
|||||||
goto ex;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// init LUA only here because of possible sandbox. no LUA code with high privs
|
// init LUA only here because of possible sandbox. no LUA code with high privs
|
||||||
if (!params.L && !lua_init())
|
if (!params.L && !lua_init())
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user