Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Detailed Analysis of Integer overflow vulnerabilities in TCP Protocol Stack in Linux Kernel

2025-02-24 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Network Security >

Share

Shulou(Shulou.com)05/31 Report--

How to make a detailed analysis of the integer overflow vulnerability of the TCP protocol stack in the Linux kernel? aiming at this problem, this article introduces the corresponding analysis and solution in detail, hoping to help more partners who want to solve this problem to find a more simple and feasible method.

Overview of vulnerabilities

On June 18, 2019, the official website of RedHat released a vulnerability named CVE CVE-2019-11477, which is an integer overflow vulnerability in the underlying protocol stack, which affects Linux kernel version 2.6.29 and above, and can theoretically cause a remote denial of service vulnerability. After the analysis and verification of our team, it is difficult to trigger this vulnerability in the real environment, so it is not so harmful in the real environment.

Loophole principle

The vulnerability is an integer overflow vulnerability of a tcp_gso_segs member on the skb_buff structure. Linux kernel packet messages are expressed in skb_buff structure. The kernel provides NETIF_F_SG (default enabled), NETIF_F_ UFO and other functions to improve packet sending efficiency. When sending messages, tabloid messages will be accumulated in a similar slicing form, and will be uniformly sent as large messages, and will be sliced by Nic hardware. At this time, the maximum cumulative length of the message is 32k (x86) or 64k (powerpc). In the code, the member of the tabloid accumulation queue is the tcp_skb_cb object of the skb_buff structure, where the tcp_gso_segs member is a member of short unsight int type, representing the number of tabloids.

\ linux\ net\ ipv4\ tcp.c

If (can_coalesce) {skb_frag_size_add (& skb_shinfo (skb)-> frags [i1], copy);} else {get_page (page); skb_fill_page_desc (skb, iMagazine page, offset, copy);}

Linux/include/linux/skbuff.h

Struct tcp_skb_cb {

_ _ U32 seq; / * Starting sequence number*/

_ _ U32 end_seq; / * SEQ + FIN + SYN + datalen * /

_ _ u32 tcp_tw_isn

Struct {

U16 tcp_gso_segs

U16 tcp_gso_size

}

_ U8 tcp_flags; / 2* TCP headerflags. (tcp [13]) * /

...

}

In general, TCP protocol provides mss negotiation mechanism to avoid the performance loss caused by slicing. By providing the Mtu value of both parties during the handshake, negotiating the maximum message length of both parties, and providing their own mss length, both parties choose the minimum MSS value as the maximum message length. After that, the maximum message length of both parties will not exceed the negotiated MSS value. If a vulnerability is required, the sender forces the mss value to 8 when shaking hands (the minimum mss negotiation value is 48-the maximum tcp header length = 8). That is, when the receiver shakes hands with the handshake, the mss value can be set to 8.

TCP-MSS, full name is TCP maximum segment size. It translates to the maximum message size of TCP. Its value represents the maximum size of a single TCP message expected by the TCP transport layer to send itself a single TCP message.

In the TCP protocol, when the two ends of the TCP protocol negotiate the TCP three-way handshake protocol, the two ends of the host will inform each other of the MSS value of their current link. When one host receives the MSS value of the other end, it will evaluate its MSS value and compare it with its own MSS value, and take the minimum value to determine the maximum message size sent by TCP.

How do I calculate the local MSS value? Local MSS=MTU-20 byte standard IP header-20 byte standard TCP header (from another point of view, it is actually TCP payload)

Another relevant is linux's sack mechanism. In the description of RFC, when the TCP message arrives out of order, the TCP receiver will require the sender to resend the message that has not been sent in order. In order to improve the packet sending efficiency of the TCP protocol, TCP provides the sack mechanism (the implementation of the sack mechanism has been provided since linux kernel 2.6.29). When the receiver requests retransmission from the sender, the retransmission message will enter the tcp_gso_segs mechanism of the tcp_sendmsg function. Accumulate message fragments in the form of fragments, and accept up to 17 fragmentation queues in the skb_buff structure. In the process of receiving malicious sessions, the receiver can constantly require the sender to retransmit, that is, the receiver continues to send sack messages to the sender. After receiving the sack message, the sender will resend the message.

Linux/include/linux/skbuff.h

DefineMAX_SKB_FRAGS (65536/PAGE_SIZE + 1) = > 17

In this case, a skb_buff structure can be accumulated by a maximum of 17" 32" 1024% 8" 69632 message fragments, while 69632 exceeds the maximum value of 65535 for tcp_gso_segs members (unsigned short integers), which will cause integer overflows and eventually trigger a crash in the tcp_shifted_skb function.

Linux\ net\ ipv4\ tcp_input.c

Static bool tcp_shifted_skb (struct sock * sk, … , unsigned int pcount,...)

{

...

Tcp_skb_pcount_add (prev, pcount)

BUG_ON (tcp_skb_pcount (skb))

< pcount); 0) { struct sk_buff *skb = tcp_write_queue_tail(sk); int copy, i; bool can_coalesce; if (!tcp_send_head(sk) || (copy = size_goal - skb->

Len) sk_allocation, skb_queue_empty (& sk- > sk_write_queue); if (! skb) goto wait_for_memory; skb_entail (sk, skb); copy = size_goal;} if (copy > size) copy = size; I = skb_shinfo (skb)-> nr_frags; can_coalesce = skb_can_coalesce (skb, I, page, offset) If (! can_coalesce & & I > = sysctl_max_skb_frags) {tcp_mark_push (tp, skb); goto new_segment;} if (! sk_wmem_schedule (sk, copy)) goto wait_for_memory; if (can_coalesce) {skb_frag_size_add (& skb_shinfo (skb)-> frags [I-1], copy);} else {get_page (page) Skb_fill_page_desc (skb, I, page, offset, copy);}

Second, the actual load of the TCP message is set to 8 bytes (mss is set to a minimum value of 48). The TCP option header is set to 40 bytes, 48-40 bytes). The actual situation of this step is not default, normally it cannot be negotiated successfully. Mss negotiation initiated by the client will not be recognized by the server by default. TSO (TCP Segment Offload) technology is enabled in the default distribution linux system. In order to maximize the performance of the network card, the network card will continue to try to expand the value of mss. When we successfully negotiate the mss to 48, the TSO will soon restore the mss to 1460. So the actual attack chain has been broken at this time.

And in our test, the TCP option header of the TCP packet sent to us by the server is set to 40. By requiring the server packet with a timestamp option, the TCP option header can have a 12-byte option length. If you need a longer option header, you need some special TCP options, such as md5 option, but the md5 option of TCP needs to recompile the kernel, and the distribution does not have the md5 option:

By default, we only set the TCP option header length of 12 bytes of server messages through the client:

Third, send a sack message to the server and specify a specific message retransmission. When we retransmit a message with a specified byte sequence on the server, we find that we are unable to add up to the tiredness of the message. in the vulnerability analysis, we mentioned that we need to accumulate more than 65535 retransmitted messages to cause integer overflow, but in the actual test, we found that the retransmission of TCP is so fast that our packet sending speed is simply not fast enough for the server's gso mechanism to take effect and accumulate more than 65535 messages. My maximum accumulation at this time is more than 30 times. The server accumulates retransmission messages after receiving sack, and releases and accumulates after receiving ack or other mechanisms.

Please note the message sequence number in the figure below. The 27th message requests a designated retransmission, the 28th message retransmits the specified message, and the 29th message immediately sends the correct order message. The direct time of the 27th message and the 29th message is too short. It is possible to retransmit messages more than 65535 times through concurrent distributed attacks.

Other attempts:

Since the main flaw of this vulnerability is that the mss negotiation mechanism enables non-default, we have tried to bypass linux kernel's mss negotiation mechanism to attack the server. We have tried to use sack messages to tell the server that we only lack 8 bytes (if the original length of the message is 48 bytes). At this time, the reply message from the server does not only give us a message of 8 bytes in length. Instead, the message to which the missing message belongs (48 bytes long) is sent back to us, bypassing the failed attempt.

In the end, we decided that this loophole was actually not harmful.

Test code

We use python's scapy library to forge the client to communicate with the server.

Sack part of the test code:

From scapy.all import * import time i=IP () i.dst = "192.168.124.144" t=TCP () t.dport=8887 t.options= "S" t.options= [('MSS',18), (' SAckOK',')] # sr1 (iPAG) SYNACK=sr1 (iPAG) seq_num=int (SYNACK.seq) # ACK ACK=TCP (dport=8887) Flags='A',seq=SYNACK.ack, ack=SYNACK.seq + 1) send (i/ACK) printseq_num # SACK=TCP (dport=8887,flags='A',seq=SYNACK.ack, ack=SYNACK.seq + 1) time.sleep (1) SACK=TCP (dport=8887,flags='A',seq=SYNACK.ack, ack=SYNACK.seq + 1+0x30*2) # printSACK.seq num=3 SACK.options= [('SAck', (SYNACK.seq+1+0x30*3) SYNACK.seq+1+0x30*4)] send (i/SACK) # whilenum=4.14 requires a second patch:

Https://github.com/Netflix/security-bulletins/blob/master/advisories/third-party/2019-001/PATCH_net_1a.patch

(2) disable SACK processing echo0 > / proc/sys/net/ipv4/tcp_sack (3) use filters to block attacks

Https://github.com/Netflix/security-bulletins/blob/master/advisories/third-party/2019-001/block-low-mss/README.md

This mitigation is valid when you need to disable TCP probes (that is, set net.ipv4.tcp_mtu_probingsysctl to 0 in the / etc/sysctl.conf file)

(4) RedHat users can use the following script to check for vulnerabilities in the system.

Https://access.redhat.com/sites/default/files/cve-2019-11477--2019-06-17-1629.sh

This is the answer to the detailed analysis of integer overflow vulnerabilities in the TCP protocol stack in the Linux kernel. I hope the above content can be of some help to you. If you still have a lot of doubts to be solved, you can follow the industry information channel for more related knowledge.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Network Security

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report