Utilice el mecanismo de retransmisión TCP para reproducir el servicio de golpe de puerto

TCP no puede autenticarse antes de que se establezca la conexión, o no será posible para UDP sin conexión.

TCP tiene un mecanismo fastopen, pero no es fácil de usar. La idea de este artículo se basa en fastopen. Deje que el primer paquete SYN lleve datos, pero no puede llegar a la capa TCP. La autenticación debe completarse en la capa IP.

Así que existe el llamado servicio de respuesta.

El significado de llamar a la puerta es evitar la interferencia de conexiones ilegales. Incluso si no constituye un DoS, el servidor debe responder a los clientes conectados ilegalmente. Esto no solo es inseguro, expone la información del puerto abierto, sino que también desperdicia recursos de ancho de banda.

Internet es un entorno abierto, ¡no hables con extraños! Es mucho mejor eliminar silenciosamente las conexiones ilegales que responder con un RST.

En este artículo, jugaremos un servicio de golpe implementado a través del mecanismo de retransmisión TCP:
Inserte la descripción de la imagen aquí

Supongamos que queremos proteger el puerto 22 de SSH, primero realizamos la siguiente configuración en el lado del servidor:

# 以下配置部署在 192.168.56.101 这台Ubuntu上。
ipset create knockset hash:ip,port timeout 60 # 一分钟无活动即断开
iptables -t mangle -F
# 加入set的二元组允许建立连接
iptables -t mangle -A PREROUTING -p tcp --dport 22 -m set --match-set knockset src,src -j ACCEPT
# 过滤敲门包,将成功敲门的二元组加入ipset
iptables -t mangle -A PREROUTING -p tcp --dport 22 -m string --string "skinshoe" --algo bm --to 65535 -j SET --add-set knockset src,src
# 丢弃敲门包,因为正式包(也就是客户端重传的SYN包)马上就会到来
iptables -t mangle -A PREROUTING -p tcp --dport 22 -m string --string "skinshoe" --algo bm --to 65535 -j DROP
# 静默丢弃
iptables -t mangle -A PREROUTING -p tcp --dport 22 ! -s 192.168.56.1/32  -j DROP

El siguiente es un módulo del lado del cliente basado en Netfilter:

// padding.c 部署在192.168.56.110上
#include <linux/module.h>
#include <net/netfilter/nf_conntrack.h>
#include <linux/netfilter/nf_conntrack_common.h>
#include <net/tcp.h>

int port = 22;
module_param(port, int, 0644);

char *templ = NULL;
module_param(templ, charp, 0);

unsigned int knock_out_hook(const struct nf_hook_ops *ops, struct sk_buff *skb,
                             const struct net_device *in, const struct net_device *out,
                             const struct nf_hook_state *state)
{
    
    
	struct iphdr *iph = ip_hdr(skb);
	struct tcphdr *th = NULL;
	enum ip_conntrack_info ctinfo;
	struct nf_conn *ct;
	unsigned int extra, len;
	char *cookie;

	if (templ == NULL)
		return NF_ACCEPT;

	ct = nf_ct_get(skb, &ctinfo);
	// 过滤一个连接的第一个SYN包。
	if (!ct || (ct->status & IPS_CONFIRMED))
		return NF_ACCEPT;

	if (iph->version != 4 || iph->protocol != IPPROTO_TCP)
		return NF_ACCEPT;

	iph = ip_hdr(skb);
	th = (struct tcphdr *)((unsigned char *)iph + (iph->ihl * 4));

	if (ntohs(th->dest) != port)
		return NF_ACCEPT;

	// 在一个连接的第一个SYN包后面padding我们的认证魔术字。
	cookie = kmalloc(32, GFP_ATOMIC);
	memcpy(cookie, templ, strlen(templ));
	extra = strlen(templ);
	skb_put(skb, extra);
	memcpy((char *)th + sizeof(struct tcphdr), cookie, extra);
	len = ntohs(iph->tot_len) + extra;
	iph->tot_len = htons(len);
	iph->check = 0;
	ip_send_check(iph);

	return NF_ACCEPT;
}

static struct nf_hook_ops knock_out_ops = {
    
    
	.hook     = knock_out_hook,
	.owner    = THIS_MODULE,
	.pf       = AF_INET,
	.hooknum  = NF_INET_LOCAL_OUT,
	.priority = NF_IP_PRI_LAST,
};

static int __init knock_init(void)
{
    
    
	if (nf_register_hook(&knock_out_ops) < 0) {
    
    
		return -1;
	}

	return 0;
}

static void __exit knock_exit(void)
{
    
    
	nf_unregister_hook(&knock_out_ops);
}

module_init(knock_init);
module_exit(knock_exit);
MODULE_LICENSE("GPL");

Ven y mira el efecto:

# 不加载padding hook的时候:
[root@localhost ~]# ssh [email protected]
... # 无响应,抓包无内容,无回复,无RST

[root@localhost ~]# insmod ./padding.ko port=22 templ="skinshoe"
[root@localhost ~]# ssh [email protected]
[email protected]'s password:
Welcome to Ubuntu 19.10 (GNU/Linux 5.3.0-62-generic x86_64)
... # 成功连接

Cabe resaltar que:

  • Este artículo es solo un POC, de hecho, se puede completar una autenticación muy complicada.
  • El gancho de relleno no tiene que implementarse localmente en el cliente, también puede ser un agente de detonación independiente.
  • Esta solución es independiente de la protección DDoS, que es solo una idea.
  • El gancho de relleno usa conntrack, no levante la barra, conntrack no es tan insoportable, y mucho menos se implementa en el cliente.
  • Si usa esta idea de POC en una página web, puede darse cuenta de la anti-sanguijuela, pero no entiendo la tecnología front-end y solo puedo rendirme.
  • Dando un paso atrás, ¿no puedes usar el mecanismo del kernel? La respuesta es sí, también puedes usar UDP fuera de banda para completar el golpe.

Originalmente quería usar systemtap para escribir una bomba de horquilla dirigida para divertir la operación y el mantenimiento, el gerente y sus subordinados, pero no esperaba hacer esto, oye ...


Los zapatos de cuero en Wenzhou, Zhejiang están mojados, por lo que no engordan con la lluvia.

Supongo que te gusta

Origin blog.csdn.net/dog250/article/details/108479651
Recomendado
Clasificación