mirror of
https://github.com/bol-van/zapret2.git
synced 2026-03-14 06:13:09 +00:00
nfqws2: add mtproto detection
This commit is contained in:
38
nfq2/crypto/aes-ctr.c
Normal file
38
nfq2/crypto/aes-ctr.c
Normal file
@@ -0,0 +1,38 @@
|
||||
#include "aes-ctr.h"
|
||||
#include <string.h>
|
||||
|
||||
#define AES_BLOCKLEN 16
|
||||
|
||||
void aes_ctr_xcrypt_buffer(aes_context *ctx, const uint8_t *iv, uint8_t *buf, size_t length)
|
||||
{
|
||||
uint8_t bi, buffer[AES_BLOCKLEN], ivc[AES_BLOCKLEN];
|
||||
size_t i;
|
||||
|
||||
memcpy(ivc,iv,AES_BLOCKLEN);
|
||||
|
||||
for (i = 0, bi = AES_BLOCKLEN; i < length; ++i, ++bi)
|
||||
{
|
||||
if (bi == AES_BLOCKLEN) /* we need to regen xor compliment in buffer */
|
||||
{
|
||||
memcpy(buffer, ivc, AES_BLOCKLEN);
|
||||
aes_cipher(ctx, buffer, buffer);
|
||||
|
||||
/* Increment ivc and handle overflow */
|
||||
for (bi = (AES_BLOCKLEN - 1); bi >= 0; --bi)
|
||||
{
|
||||
/* inc will owerflow */
|
||||
if (ivc[bi] == 255)
|
||||
{
|
||||
ivc[bi] = 0;
|
||||
continue;
|
||||
}
|
||||
ivc[bi] += 1;
|
||||
break;
|
||||
}
|
||||
bi = 0;
|
||||
}
|
||||
buf[i] = (buf[i] ^ buffer[bi]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
7
nfq2/crypto/aes-ctr.h
Normal file
7
nfq2/crypto/aes-ctr.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "aes.h"
|
||||
|
||||
// this function rewrites buf
|
||||
void aes_ctr_xcrypt_buffer(aes_context *ctx, const uint8_t *iv, uint8_t *buf, size_t length);
|
||||
@@ -1162,7 +1162,6 @@ static uint8_t dpi_desync_tcp_packet_play(unsigned int replay_piece, unsigned in
|
||||
}
|
||||
|
||||
process_retrans_fail(ctrack, IPPROTO_TCP, (struct sockaddr*)&src);
|
||||
|
||||
if (IsHttp(rdata_payload, rlen_payload))
|
||||
{
|
||||
DLOG("packet contains HTTP request\n");
|
||||
@@ -1253,6 +1252,16 @@ static uint8_t dpi_desync_tcp_packet_play(unsigned int replay_piece, unsigned in
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ctrack && (ctrack->seq_last - ctrack->seq0)==1 && IsMTProto(dis->data_payload, dis->len_payload))
|
||||
{
|
||||
// mtproto detection requires aes. react only on the first tcp data packet. do not detect if ctrack unavailable.
|
||||
l7payload = L7P_MTPROTO_INITIAL;
|
||||
if (l7proto == L7_UNKNOWN)
|
||||
{
|
||||
l7proto = L7_MTPROTO;
|
||||
if (ctrack->l7proto == L7_UNKNOWN) ctrack->l7proto = l7proto;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
t_protocol_probe testers[] = {
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
#include "lua.h"
|
||||
#include "params.h"
|
||||
#include "helpers.h"
|
||||
#include "crypto/sha.h"
|
||||
#include "crypto/aes-gcm.h"
|
||||
#include "crypto/aes-ctr.h"
|
||||
|
||||
|
||||
static void lua_check_argc(lua_State *L, const char *where, int argc)
|
||||
{
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
#include "protocol.h"
|
||||
#include "helpers.h"
|
||||
#include "params.h"
|
||||
#include "crypto/sha.h"
|
||||
#include "crypto/aes-gcm.h"
|
||||
#include "crypto/aes-ctr.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
@@ -26,7 +29,7 @@ static bool FindNLD(const uint8_t *dom, size_t dlen, int level, const uint8_t **
|
||||
return true;
|
||||
}
|
||||
|
||||
static const char *l7proto_name[] = {"all","unknown","http","tls","quic","wireguard","dht","discord","stun","xmpp","dns"};
|
||||
static const char *l7proto_name[] = {"all","unknown","http","tls","quic","wireguard","dht","discord","stun","xmpp","dns","mtproto"};
|
||||
const char *l7proto_str(t_l7proto l7)
|
||||
{
|
||||
if (l7>=L7_LAST) return NULL;
|
||||
@@ -46,7 +49,9 @@ static const char *l7payload_name[] = {
|
||||
"all","unknown","empty","http_req","http_reply","tls_client_hello","tls_server_hello","quic_initial",
|
||||
"wireguard_initiation","wireguard_response","wireguard_cookie","wireguard_keepalive","wireguard_data",
|
||||
"dht","discord_ip_discovery","stun_binding_req",
|
||||
"xmpp_stream", "xmpp_starttls", "xmpp_proceed", "xmpp_features", "dns_query", "dns_response"};
|
||||
"xmpp_stream", "xmpp_starttls", "xmpp_proceed", "xmpp_features",
|
||||
"dns_query", "dns_response",
|
||||
"mtproto_initial"};
|
||||
t_l7payload l7payload_from_name(const char *name)
|
||||
{
|
||||
int idx = str_index(l7payload_name,sizeof(l7payload_name)/sizeof(*l7payload_name),name);
|
||||
@@ -1385,3 +1390,17 @@ bool IsStunBindingRequest(const uint8_t *data, size_t len)
|
||||
ntohl(*(uint32_t*)(&data[4]))==0x2112A442 && // magic cookie
|
||||
ntohs(*(uint16_t*)(&data[2]))==len-20;
|
||||
}
|
||||
bool IsMTProto(const uint8_t *data, size_t len)
|
||||
{
|
||||
if (len>=64)
|
||||
{
|
||||
aes_context ctx;
|
||||
uint8_t dcopy[64];
|
||||
|
||||
aes_init_keygen_tables();
|
||||
memcpy(dcopy,data,sizeof(dcopy));
|
||||
aes_setkey(&ctx, true, data+8, 32);
|
||||
aes_ctr_xcrypt_buffer(&ctx, data+40, dcopy, sizeof(dcopy));
|
||||
return !memcmp(dcopy+56,"\xEF\xEF\xEF\xEF",4);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "crypto/sha.h"
|
||||
#include "crypto/aes-gcm.h"
|
||||
#include "helpers.h"
|
||||
|
||||
typedef enum {
|
||||
@@ -19,6 +17,7 @@ typedef enum {
|
||||
L7_STUN,
|
||||
L7_XMPP,
|
||||
L7_DNS,
|
||||
L7_MTPROTO,
|
||||
L7_LAST, L7_INVALID=L7_LAST
|
||||
} t_l7proto;
|
||||
const char *l7proto_str(t_l7proto l7);
|
||||
@@ -48,6 +47,7 @@ typedef enum {
|
||||
L7P_XMPP_FEATURES,
|
||||
L7P_DNS_QUERY,
|
||||
L7P_DNS_RESPONSE,
|
||||
L7P_MTPROTO_INITIAL,
|
||||
L7P_LAST, L7P_INVALID=L7P_LAST
|
||||
} t_l7payload;
|
||||
t_l7payload l7payload_from_name(const char *name);
|
||||
@@ -151,6 +151,7 @@ bool IsWireguardData(const uint8_t *data, size_t len);
|
||||
bool IsDht(const uint8_t *data, size_t len);
|
||||
bool IsDiscordIpDiscoveryRequest(const uint8_t *data, size_t len);
|
||||
bool IsStunBindingRequest(const uint8_t *data, size_t len);
|
||||
bool IsMTProto(const uint8_t *data, size_t len);
|
||||
|
||||
#define QUIC_MAX_CID_LENGTH 20
|
||||
typedef struct quic_cid {
|
||||
|
||||
Reference in New Issue
Block a user