Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug] tcpreplay-edit —— heap-buffer-overflow in do_checksum at Checksum.c:132 #577

Closed
14isnot40 opened this issue May 19, 2020 · 1 comment
Assignees
Labels
Projects
Milestone

Comments

@14isnot40
Copy link

Describe the bug
A heap-based buffer overflow was discovered in tcpreplay-edit binary, during the do_checksum operation. The issue is being triggered in the function do_checksum at Checksum.c:132.

To Reproduce
Steps to reproduce the behavior:

  1. Compile tcpreplay according to the default configuration
./configure CFLAGS="-g -O0 -fsanitize=address"
  1. execute command
tcpreplay-edit -r 80:84 -s 20 -b -C -m 1500 -P --oneatatime -i lo $poc

poc can be found here.

Expected behavior
An attacker can exploit this vulnerability by submitting a malicious pcap that exploits this issue. This will result in a Denial of Service (DoS) and potentially Information Exposure when the application attempts to process the file.

Screenshots
ASAN Reports

==64466==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60600000ec3c at pc 0x000000428924 bp 0x7fffffffd570 sp 0x7fffffffd560
WRITE of size 2 at 0x60600000ec3c thread T0
    #0 0x428923 in do_checksum /home/test/Desktop/evaulation/tcpreplay/src/tcpedit/checksum.c:132
    #1 0x42033a in fix_ipv4_checksums /home/test/Desktop/evaulation/tcpreplay/src/tcpedit/edit_packet.c:82
    #2 0x41c8f9 in tcpedit_packet /home/test/Desktop/evaulation/tcpreplay/src/tcpedit/tcpedit.c:354
    #3 0x40963b in send_packets /home/test/Desktop/evaulation/tcpreplay/src/send_packets.c:552
    #4 0x418e9a in replay_file /home/test/Desktop/evaulation/tcpreplay/src/replay.c:182
    #5 0x417e73 in tcpr_replay_index /home/test/Desktop/evaulation/tcpreplay/src/replay.c:59
    #6 0x416de4 in tcpreplay_replay /home/test/Desktop/evaulation/tcpreplay/src/tcpreplay_api.c:1136
    #7 0x40fb4f in main /home/test/Desktop/evaulation/tcpreplay/src/tcpreplay.c:139
    #8 0x7ffff687f82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #9 0x403508 in _start (/usr/local/bin/tcpreplay-edit+0x403508)

0x60600000ec3c is located 10 bytes to the right of 50-byte region [0x60600000ec00,0x60600000ec32)
allocated by thread T0 here:
    #0 0x7ffff6f02602 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x98602)
    #1 0x7ffff6c484fe  (/usr/lib/x86_64-linux-gnu/libpcap.so.0.8+0x1f4fe)

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/test/Desktop/evaulation/tcpreplay/src/tcpedit/checksum.c:132 do_checksum
Shadow bytes around the buggy address:
  0x0c0c7fff9d30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0c7fff9d40: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0c7fff9d50: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0c7fff9d60: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0c7fff9d70: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c0c7fff9d80: 00 00 00 00 00 00 02[fa]fa fa fa fa 00 00 00 00
  0x0c0c7fff9d90: 00 00 00 05 fa fa fa fa fd fd fd fd fd fd fd fd
  0x0c0c7fff9da0: fa fa fa fa fd fd fd fd fd fd fd fd fa fa fa fa
  0x0c0c7fff9db0: 00 00 00 00 00 00 00 fa fa fa fa fa fd fd fd fd
  0x0c0c7fff9dc0: fd fd fd fd fa fa fa fa fd fd fd fd fd fd fd fd
  0x0c0c7fff9dd0: fa fa fa fa fd fd fd fd fd fd fd fd fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
==64466==ABORTING
[Inferior 1 (process 64466) exited with code 01]

Debug

Breakpoint 2, do_checksum (tcpedit=0x61d00001ea80, data=0x60600000ec12 "d", proto=0x3a, len=0xa072) at checksum.c:131
131	            icmp6 = (icmpv6_hdr_t *)(data + ip_hl);
[ Legend: Modified register | Code | Heap | Stack | String ]
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ────
$rax   : 0x3a              
$rbx   : 0x00007fffffffd800  →  0x00007fffffffdb80  →  0x00000ffffffffb7a  →  0x0000000000000000
$rcx   : 0xa000            
$rdx   : 0x28              
$rsp   : 0x00007fffffffd580  →  0x000060600000ec00  →  0x0080070000000004
$rbp   : 0x00007fffffffd5e0  →  0x00007fffffffd620  →  0x00007fffffffd820  →  0x00007fffffffdba0  →  0x00007fffffffdd60  →  0x00007fffffffdd90  →  0x00007fffffffde90  →  0x00007fffffffe340
$rsi   : 0x0               
$rdi   : 0x000060600000ec12  →  0x193a008172a00064 ("d"?)
$rip   : 0x00000000004288d8  →  <do_checksum+1498> mov eax, DWORD PTR [rbp-0x40]
$r8    : 0x20              
$r9    : 0x00000c0c7fff9d86  →  0x0000fafafafafa02
$r10   : 0x84              
$r11   : 0x00007ffff6978390  →  <ntohl+0> mov eax, edi
$r12   : 0x00000ffffffffad4  →  0x0000000000000000
$r13   : 0x00007fffffffd6a0  →  0x0000000041b58ab3
$r14   : 0x00007fffffffd6a0  →  0x0000000041b58ab3
$r15   : 0x00007fffffffdbd0  →  0x0000000041b58ab3
$eflags: [carry PARITY adjust ZERO sign trap INTERRUPT direction overflow resume virtualx86 identification]
$cs: 0x0033 $ss: 0x002b $ds: 0x0000 $es: 0x0000 $fs: 0x0000 $gs: 0x0000 
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ────
0x00007fffffffd580│+0x0000: 0x000060600000ec00  →  0x0080070000000004	 ← $rsp
0x00007fffffffd588│+0x0008: 0x0000003a0000a072  →  0x0000000000000000
0x00007fffffffd590│+0x0010: 0x000060600000ec12  →  0x193a008172a00064 ("d"?)
0x00007fffffffd598│+0x0018: 0x000061d00001ea80  →  0x0000000000000001
0x00007fffffffd5a0│+0x0020: 0x0000000000000028 ("("?)
0x00007fffffffd5a8│+0x0028: 0x0000000000000000
0x00007fffffffd5b0│+0x0030: 0x000060600000ec12  →  0x193a008172a00064 ("d"?)
0x00007fffffffd5b8│+0x0038: 0x000060600000ec3a  →  0x96b9000000000000
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ────
     0x4288cb <do_checksum+1485> mov    rax, QWORD PTR [rbp-0x10]
     0x4288cf <do_checksum+1489> mov    WORD PTR [rax+0x2], cx
     0x4288d3 <do_checksum+1493> jmp    0x428ad6 <do_checksum+2008>
 →   0x4288d8 <do_checksum+1498> mov    eax, DWORD PTR [rbp-0x40]
     0x4288db <do_checksum+1501> movsxd rdx, eax
     0x4288de <do_checksum+1504> mov    rax, QWORD PTR [rbp-0x50]
     0x4288e2 <do_checksum+1508> add    rax, rdx
     0x4288e5 <do_checksum+1511> mov    QWORD PTR [rbp-0x8], rax
     0x4288e9 <do_checksum+1515> mov    rax, QWORD PTR [rbp-0x8]
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────── source:checksum.c+131 ────
    126	             sum += do_checksum_math((uint16_t *)icmp, len);
    127	             icmp->icmp_sum = CHECKSUM_CARRY(sum);
    128	             break;
    129	 
    130	         case IPPROTO_ICMP6:
                     // data=0x00007fffffffd590  →  [...]  →  0x193a008172a00064 ("d"?), icmp6=0x00007fffffffd5d8  →  [...]  →  <randomize_ipv4+998> mov eax, 0x0, ip_hl=0x28
131	             icmp6 = (icmpv6_hdr_t *)(data + ip_hl);
    132	             icmp6->icmp_sum = 0;
    133	             if (ipv6 != NULL) {
    134	                 sum = do_checksum_math((u_int16_t *)&ipv6->ip_src, 32);
    135	             }
    136	             sum += ntohs(IPPROTO_ICMP6 + len);
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "tcpreplay-edit", stopped, reason: BREAKPOINT
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ────
[#0] 0x4288d8 → do_checksum(tcpedit=0x61d00001ea80, data=0x60600000ec12 "d", proto=0x3a, len=0xa072)
[#1] 0x42033b → fix_ipv4_checksums(tcpedit=0x61d00001ea80, pkthdr=0x7fffffffdac0, ip_hdr=0x60600000ec12)
[#2] 0x41c8fa → tcpedit_packet(tcpedit=0x61d00001ea80, pkthdr=0x7fffffffd940, pktdata=0x7fffffffd8c0, direction=TCPR_DIR_C2S)
[#3] 0x40963c → send_packets(ctx=0x61e00000f080, pcap=0x61600000f380, idx=0x0)
[#4] 0x418e9b → replay_file(ctx=0x61e00000f080, idx=0x0)
[#5] 0x417e74 → tcpr_replay_index(ctx=0x61e00000f080)
[#6] 0x416de5 → tcpreplay_replay(ctx=0x61e00000f080)
[#7] 0x40fb50 → main(argc=0x1, argv=0x7fffffffe490)

Possible cause of vulnerability
The lacking a check between IP and ICMP6 packet length, resulting in a header buffer overflow in (icmpv6_hdr_t *)(data + ip_hl)

        case IPPROTO_ICMP6:
            icmp6 = (icmpv6_hdr_t *)(data + ip_hl);
            icmp6->icmp_sum = 0;
            if (ipv6 != NULL) {
                sum = do_checksum_math((u_int16_t *)&ipv6->ip_src, 32);
            }
            sum += ntohs(IPPROTO_ICMP6 + len);
            sum += do_checksum_math((u_int16_t *)icmp6, len);
            icmp6->icmp_sum = CHECKSUM_CARRY(sum);
            break;

System (please complete the following information):

  • OS version : Ubuntu 16.04
  • Tcpreplay Version : 4.3.2/master branch

Additional context
The crash point of this vulnerability is different from issue 556. Although the specific causes of the vulnerabilities are different, they are similar. It is necessary to fully check the 80-142 lines of code in do_checksum.

@fklassen fklassen self-assigned this May 20, 2020
@fklassen fklassen added the bug label May 20, 2020
@fklassen fklassen added this to the 4.3.3 milestone May 20, 2020
@fklassen fklassen added this to To do in 4.3.3 via automation Jun 1, 2020
@fklassen fklassen moved this from To do to In progress in 4.3.3 Jun 1, 2020
@fklassen
Copy link
Member

fklassen commented Jun 2, 2020

Fixed in #589

@fklassen fklassen closed this as completed Jun 2, 2020
4.3.3 automation moved this from In progress to Done Jun 2, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
No open projects
4.3.3
  
Done
Development

No branches or pull requests

2 participants