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

Heap overflow in get_ipv6_next() #576

Closed
14isnot40 opened this issue May 8, 2020 · 4 comments
Closed

Heap overflow in get_ipv6_next() #576

14isnot40 opened this issue May 8, 2020 · 4 comments
Assignees
Milestone

Comments

@14isnot40
Copy link

Describe the bug
A heap-based buffer overflow was discovered in tcprewrite binary, during the get_c operation. The issue is being triggered in the function get_ipv6_next() at common/get.c.

To Reproduce
Steps to reproduce the behavior:

  1. Compile tcpreplay according to the default configuration
  2. execute command
tcprewrite -i $poc -o /dev/null --fuzz-seed=42

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

/usr/local/bin/tcprewrite -i id\:000000\,sig\:11\,src\:000280\,op\:fa-havoc\,rep\:2 -o /dev/null --fuzz-seed=42
=================================================================
==34195==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x63100001080e at pc 0x00000042bd74 bp 0x7ffd8b9eada0 sp 0x7ffd8b9ead90
READ of size 4 at 0x63100001080e thread T0
    #0 0x42bd73 in get_ipv6_next /home/test/Desktop/evaulation/tcpreplay/src/common/get.c:454
    #1 0x42bfcc in get_ipv6_l4proto /home/test/Desktop/evaulation/tcpreplay/src/common/get.c:540
    #2 0x42bfb9 in get_ipv6_l4proto /home/test/Desktop/evaulation/tcpreplay/src/common/get.c:531
    #3 0x4134c2 in do_checksum /home/test/Desktop/evaulation/tcpreplay/src/tcpedit/checksum.c:63
    #4 0x40b383 in fix_ipv4_checksums /home/test/Desktop/evaulation/tcpreplay/src/tcpedit/edit_packet.c:74
    #5 0x4079c2 in tcpedit_packet /home/test/Desktop/evaulation/tcpreplay/src/tcpedit/tcpedit.c:354
    #6 0x40569b in rewrite_packets /home/test/Desktop/evaulation/tcpreplay/src/tcprewrite.c:291
    #7 0x404e13 in main /home/test/Desktop/evaulation/tcpreplay/src/tcprewrite.c:130
    #8 0x7f9fd6a0e82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #9 0x402688 in _start (/usr/local/bin/tcprewrite+0x402688)

0x63100001080e is located 1 bytes to the right of 65549-byte region [0x631000000800,0x63100001080d)
allocated by thread T0 here:
    #0 0x7f9fd72b2602 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x98602)
    #1 0x42c8e9 in _our_safe_malloc /home/test/Desktop/evaulation/tcpreplay/src/common/utils.c:50
    #2 0x40551e in rewrite_packets /home/test/Desktop/evaulation/tcpreplay/src/tcprewrite.c:249
    #3 0x404e13 in main /home/test/Desktop/evaulation/tcpreplay/src/tcprewrite.c:130
    #4 0x7f9fd6a0e82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/test/Desktop/evaulation/tcpreplay/src/common/get.c:454 get_ipv6_next
Shadow bytes around the buggy address:
  0x0c627fffa0b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c627fffa0c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c627fffa0d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c627fffa0e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c627fffa0f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c627fffa100: 00[05]fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c627fffa110: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c627fffa120: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c627fffa130: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c627fffa140: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c627fffa150: fa fa fa fa fa fa fa fa fa fa fa fa 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
==34195==ABORTING

Debug

Program received signal SIGSEGV, Segmentation fault.
0x0000000000410025 in get_ipv6_next (exthdr=0x663ff6, len=0x8) at get.c:454
454        maxlen = *((int*)((u_char *)exthdr + len));
[ Legend: Modified register | Code | Heap | Stack | String ]
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ────
$rax   : 0x0000000000663ff6  →  0x0000000000000000
$rbx   : 0x0               
$rcx   : 0x10080a0000000001
$rdx   : 0x1               
$rsp   : 0x00007fffffffd8a8  →  0x0000000000410207  →  <get_ipv6_l4proto+87> test rax, rax
$rbp   : 0x8               
$rsi   : 0x8               
$rdi   : 0x0000000000663ff6  →  0x0000000000000000
$rip   : 0x0000000000410025  →  <get_ipv6_next+37> mov esi, DWORD PTR [rdi+rsi*1]
$r8    : 0xe               
$r9    : 0x34              
$r10   : 0x8               
$r11   : 0x1               
$r12   : 0x1008080000000001
$r13   : 0x1               
$r14   : 0x20000000000     
$r15   : 0x1               
$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 ────
0x00007fffffffd8a8│+0x0000: 0x0000000000410207  →  <get_ipv6_l4proto+87> test rax, rax     ← $rsp
0x00007fffffffd8b0│+0x0008: 0x0000000000633c4e  →  0x29294fab8000a062 ("b"?)
0x00007fffffffd8b8│+0x0010: 0x0000000000631550  →  0x0000000000000001
0x00007fffffffd8c0│+0x0018: 0x0000000000631550  →  0x0000000000000001
0x00007fffffffd8c8│+0x0020: 0x000000000000000e
0x00007fffffffd8d0│+0x0028: 0x0000000000631550  →  0x0000000000000001
0x00007fffffffd8d8│+0x0030: 0x0000000000406d56  →  <do_checksum+438> mov ecx, DWORD PTR [rsp+0xc]
0x00007fffffffd8e0│+0x0038: 0x0000000000631e10  →  0x0000000000631550  →  0x0000000000000001
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ────
     0x410014 <get_ipv6_next+20> add    BYTE PTR [rax+0x63], cl
     0x410017 <get_ipv6_next+23> test   BYTE PTR [rax-0x2d], 0xe2
     0x41001b <get_ipv6_next+27> movabs rcx, 0x10080a0000000001
 →   0x410025 <get_ipv6_next+37> mov    esi, DWORD PTR [rdi+rsi*1]
     0x410028 <get_ipv6_next+40> test   rdx, rcx
     0x41002b <get_ipv6_next+43> jne    0x410050 <get_ipv6_next+80>
     0x41002d <get_ipv6_next+45> movabs rcx, 0x804000000000000
     0x410037 <get_ipv6_next+55> and    rcx, rdx
     0x41003a <get_ipv6_next+58> jne    0x410080 <get_ipv6_next+128>
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── source:get.c+454 ────
    449         int extlen = 0;
    450         int maxlen;
    451         void *ptr;
    452         assert(exthdr);
    453     
 →  454         maxlen = *((int*)((u_char *)exthdr + len));
    455     
    456         dbgx(3, "Jumping to next IPv6 header.  Processing 0x%02x", exthdr->ip_nh);
    457         switch (exthdr->ip_nh) {
    458         /* no further processing */
    459         case TCPR_IPV6_NH_NO_NEXT:
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "tcprewrite", stopped, reason: SIGSEGV
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ────
[#0] 0x410025 → get_ipv6_next(exthdr=0x663ff6, len=0x8)
[#1] 0x410207 → get_ipv6_l4proto(ip6_hdr=0x633c4e, len=<optimized out>)
[#2] 0x406d56 → do_checksum(tcpedit=0x631550, data=0x633c4e "b\240", proto=0x0, len=0x80)
[#3] 0x404988 → fix_ipv4_checksums(tcpedit=0x631550, pkthdr=<optimized out>, ip_hdr=0x633c4e)
[#4] 0x403407 → tcpedit_packet(tcpedit=0x631550, pkthdr=0x7fffffffd9b8, pktdata=0x61fc78 <pktdata_buff>, direction=TCPR_DIR_C2S)
[#5] 0x402d06 → rewrite_packets(tcpedit=0x631550, pin=0x621290, pout=0x632a00)
[#6] 0x402151 → main(argc=<optimized out>, argv=<optimized out>)

System (please complete the following information):

  • OS version : Ubuntu 16.04
  • Tcpreplay Version : 4.3.2/master branch
@fklassen fklassen self-assigned this May 8, 2020
@carnil
Copy link

carnil commented May 8, 2020

This issue appears to have been assigned CVE-2020-12740

@bsmojver
Copy link

@fklassen Is there a patch to fix this?

@fklassen
Copy link
Member

@fklassen Is there a patch to fix this?

Expect a patch within 2 weeks.

@fklassen fklassen added this to the 4.3.3 milestone Jun 2, 2020
fklassen added a commit that referenced this issue Jun 2, 2020
…t_ipv6_next

Bug #576 heap buffer overflow get ipv6 next
@fklassen
Copy link
Member

fklassen commented Jun 2, 2020

Fixed in #578

$ sudo src/tcprewrite -i ../tcpreplay-pcaps/id\^%000000,sig\^%11,src\^%000280,op\^%fa-havoc,rep\^%2 -o /dev/null --fuzz-seed=42
Fatal Error in tcprewrite.c:main() line 131:
 Error rewriting packets: From edit_packet.c:fix_ipv4_checksums() line 73:
Invalid packet: Expected IPv4 packet: got 6

@fklassen fklassen closed this as completed Jun 2, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants