mirror of
https://github.com/bol-van/zapret2.git
synced 2026-03-14 06:13:09 +00:00
nfqws2,zapret-lib: check tcp seq overflow
This commit is contained in:
@@ -106,3 +106,7 @@ v0.7.2
|
||||
* zapret-auto: add success detector logic
|
||||
* nfqws2: clean lua cutoff on profile change
|
||||
* zapret-auto: separate hostkey function
|
||||
|
||||
v0.7.2
|
||||
|
||||
* nfqws2, zapret-lib : check tcp sequence range overflow
|
||||
|
||||
@@ -234,6 +234,12 @@ function desync_orchestrator_example(ctx, desync)
|
||||
return replay_execution_plan(desync)
|
||||
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.seq_over_2G
|
||||
end
|
||||
-- these functions duplicate range check logic from C code
|
||||
-- mode must be n,d,b,s,x,a
|
||||
-- pos is {mode,pos}
|
||||
@@ -265,7 +271,7 @@ function pos_get(desync, mode, reverse)
|
||||
return 0
|
||||
end
|
||||
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 desync.track then
|
||||
return pos_get(desync, range.from.mode) >= range.from.pos
|
||||
@@ -277,7 +283,7 @@ function pos_check_from(desync, range)
|
||||
end
|
||||
function pos_check_to(desync, range)
|
||||
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 desync.track then
|
||||
ps = pos_get(desync, range.to.mode)
|
||||
|
||||
@@ -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 (mss && !direct->mss) direct->mss = mss;
|
||||
if (scale != SCALE_NONE) direct->scale = scale;
|
||||
|
||||
if (!direct->seq_over_2G && ((direct->seq_last - direct->seq0) & 0x80000000))
|
||||
direct->seq_over_2G = true;
|
||||
if (!reverse->seq_over_2G && ((reverse->seq_last - reverse->seq0) & 0x80000000))
|
||||
reverse->seq_over_2G = true;
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
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);
|
||||
// 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;
|
||||
|
||||
@@ -17,17 +17,18 @@ typedef struct
|
||||
uint64_t pcounter; // packet counter
|
||||
uint64_t pdcounter; // data packet counter (with payload)
|
||||
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 uppos; // 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
|
||||
|
||||
// tcp only state, not used in udp
|
||||
uint32_t seq0; // starting seq and ack
|
||||
uint16_t winsize; // last seen window size
|
||||
uint16_t mss;
|
||||
uint32_t winsize_calc; // calculated window size
|
||||
uint8_t scale; // last seen window scale factor. SCALE_NONE if none
|
||||
bool seq_over_2G;
|
||||
} t_ctrack_position;
|
||||
|
||||
typedef struct
|
||||
|
||||
@@ -505,7 +505,10 @@ static uint8_t ct_new_postnat_fix(const t_ctrack *ctrack, const struct dissect *
|
||||
return VERDICT_DROP;
|
||||
}
|
||||
|
||||
|
||||
static bool pos_overflow(const t_ctrack_position *pos, char mode)
|
||||
{
|
||||
return (mode=='s' || mode=='p') && pos && pos->seq_over_2G;
|
||||
}
|
||||
static uint64_t pos_get(const t_ctrack_position *pos, char mode)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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 (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)
|
||||
{
|
||||
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 (pos)
|
||||
@@ -754,10 +757,12 @@ static uint8_t desync(
|
||||
DLOG("* lua '%s' : voluntary cutoff\n", instance);
|
||||
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,
|
||||
range->from.mode, pos_get(pos, range->from.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->upper_cutoff ? '<' : '-',
|
||||
range->to.mode, range->to.pos,
|
||||
|
||||
@@ -13,10 +13,8 @@
|
||||
|
||||
#ifdef __linux__
|
||||
#define DPI_DESYNC_FWMARK_DEFAULT 0x40000000
|
||||
#elif defined(SO_USER_COOKIE)
|
||||
#define DPI_DESYNC_FWMARK_DEFAULT 512
|
||||
#else
|
||||
#define DPI_DESYNC_FWMARK_DEFAULT 0
|
||||
#define DPI_DESYNC_FWMARK_DEFAULT 512
|
||||
#endif
|
||||
|
||||
uint8_t dpi_desync_packet(uint32_t fwmark, const char *ifin, const char *ifout, const uint8_t *data_pkt, size_t len_pkt, uint8_t *mod_pkt, size_t *len_mod_pkt);
|
||||
|
||||
@@ -1282,7 +1282,7 @@ void lua_pushf_ctrack_pos(const t_ctrack *ctrack, const t_ctrack_position *pos)
|
||||
if (ctrack->ipproto == IPPROTO_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("seq", pos->seq_last);
|
||||
lua_pushf_lint("rseq", pos->seq_last - pos->seq0);
|
||||
@@ -1293,6 +1293,7 @@ void lua_pushf_ctrack_pos(const t_ctrack *ctrack, const t_ctrack_position *pos)
|
||||
lua_pushf_int("winsize_calc", pos->winsize_calc);
|
||||
lua_pushf_int("scale", pos->scale);
|
||||
lua_pushf_int("mss", pos->mss);
|
||||
lua_pushf_bool("seq_over_2G", pos->seq_over_2G);
|
||||
lua_rawset(params.L,-3);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user