How to install the Linux kernel not to send RST_ACK so that I can give SYN_ACK in the raw socket

I want to ask a classic question about socket software and Linux TCP processing. I did the research in the same threads as the linux raw socket programming question . How to reproduce the TCP protocol 3-way handshake with raw sockets correctly? and TCP ACK spoofing , but still can't get a solution.

I am trying to make a server that does not listen on any port, but sniff SYN packets from remote hosts. After the server has completed some calculations, it will send back the SYN_ACK packet to the corresponding SYN packet so that I can create a TCP connection manually, without turning on the kernel. I created a raw socket and sent SYN_ACK on top of it, but the packet cannot go to the remote host. When I tcpdump on the server (Ubuntu Server 10.04) and wirehark on the client (Windows 7), the server returns RST_ACK instead of my SYN_ACK package. After some research, I got information that we cannot preempt TCP file processing.

Are there any other ways to hack or install the kernel so as not to respond to RST_ACK on these packages? I added a firewall to the local IP server to tell the kernel that there might be something behind the firewall that is waiting for the packet, but still no luck

+4
source share
2 answers

Have you tried removing RST using iptables?

iptables -A OUTPUT -p tcp --tcp-flags RST RST -j DROP 

should do the job for you.

+4
source

I recommend using ip tables, but since you are also asking how to hack the kernel, here is an explanation of how you could do this (I use the 4.1.20 kernel as a reference):

When a packet is received (sk_buff), the IP protocol handler will send it to the registered network protocol:

 static int ip_local_deliver_finish(struct sock *sk, struct sk_buff *skb) { ... ipprot = rcu_dereference(inet_protos[protocol]); if (ipprot) { ... ret = ipprot->handler(skb); 

Assuming TCP protocol, handler: tcp_v4_rcv:

 static const struct net_protocol tcp_protocol = { .early_demux = tcp_v4_early_demux, .handler = tcp_v4_rcv, .err_handler = tcp_v4_err, .no_policy = 1, .netns_ok = 1, .icmp_strict_tag_validation = 1, }; 

This is how tcp_v4_cv is called. It will try to find the socket for the resulting skb, and if not, it will send a reset:

 int tcp_v4_rcv(struct sk_buff *skb) { sk = __inet_lookup_skb(&tcp_hashinfo, skb, th->source, th->dest); if (!sk) goto no_tcp_socket; no_tcp_socket: if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) goto discard_it; tcp_v4_send_reset(NULL, skb); ... 

There are many different ways to hack this. You can go to the xfrm4_policy_check function and hack / modify the policy for AF_INET. Either you can simply comment on the line that calls xfrm4_policy_check, so the code will always go to discard_it, or you can just comment on the line that calls tcp_v4_send_reset (which will have more consequences, though).

Hope this helps.

0
source

Source: https://habr.com/ru/post/1380132/


All Articles