CVE-2018-18408: Use-after-free in post_args() – tcpreplay 4.3.0-beta1

Use-after-free in post_args() – tcpreplay 4.3.0 beta1

Loginsoft-2018-18408
October 30, 2018

CVE Number

CVE-2018-18408

CWE

CWE-416: Use After Free

Product Details

tcpflow is an open source program which is used to capture the data transmitted as part of TCP connections, it also stores the data for the protocol analysis and for debugging issue
URL: https://github.com/simsong/tcpflow/wiki

Vulnerable Versions

4.3.0-beta1 branch

Vulnerability Details

A use-after-free was discovered in the tcpbridge binary of Tcpreplay 4.3.0 beta1. The issue gets triggered in the function post_args() at tcpbridge.c, causing a denial of service or possibly unspecified other impact.

Synopsis

In condition if (memcmp(options.intf1_mac, "\00\00\00\00\00\00", ETHER_ADDR_LEN) == 0).The options.intf1_mac has the value of {0,0,0,0,0,0} and ETHER_ADDR_LEN is ‘0’, which satisfies the condition and checks for the interface accessibility by comparing the packet value (sp) with NULL , if the packet value is NULL then there is problem with the interface and gives out the error. The same it checks for the MAC in the packet, if eth_buff value is NULL then it gives out an error. If the above two conditions are satisfied then the packet is sent to the function sendpacket_close() where it closes the packet by freeing the memory where the packet is been stored by using the function safe_free() from program “send_packets.c” which itself call the other function _our_safe_free() from “utils.c”. In section memcpy(options.intf1_mac, eth_buff, ETHER_ADDR_LEN) the value of “eth_buff” is copied to “options.intf1_mac”. Eth_buff is used to get mac from the packet using function sendpacket_get_hwaddr(). When a packet is sent to the binary tcpbinary which doesnt contain a valid MAC, the function memcpy(options.intf1_mac, eth_buff, ETHER_ADDR_LEN) memcpy tries to access “eth_buff” which in turn calls the function sendpacket_get_hwaddr() which uses “sp” where the memory was freed, and tries to access it which resulted in a heap use-after-free vulnerability.

Analysis

 

219            memcpy(options.intf1_mac, eth_buff, ETHER_ADDR_LEN); 
[ Legend: Modified register | Code | Heap | Stack | String ] 
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- registers ---- 
$eax   : 0x0        
$ebx   : 0xbffff700 -> 0x00000000 
$ecx   : 0x3d       
$edx   : 0x3c       
$esp   : 0xbffff1f0 -> 0x080aa480 -> 0xb50001f0 -> 0x316f6e65 -> 0x00000000 
$ebp   : 0xbffff6a8 -> 0xbffff6e8 -> 0x00000000 
$esi   : 0x0809fc20 -> 0x004d0028 ("("?) 
$edi   : 0xbffff690 -> 0xbffff6e8 -> 0x00000000 
$eip   : 0x0804e67b ->  mov ebx, DWORD PTR [ebp-0x47c] 
$eflags: [carry PARITY adjust zero SIGN trap INTERRUPT direction overflow resume virtualx86 identification] 
$cs: 0x0073 $ss: 0x007b $ds: 0x007b $es: 0x007b $fs: 0x0000 $gs: 0x0033  
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ stack ---- 
0xbffff1f0|+0x0000: 0x080aa480 -> 0xb50001f0 -> 0x316f6e65 -> 0x00000000     0x41b58ab3 
0xbffff204|+0x0014: 0xbffff230 -> 0x41b58ab3 
0xbffff208|+0x0018: 0xbffff690 -> 0xbffff6e8 -> 0x00000000 
0xbffff20c|+0x001c: 0xbffff79c -> 0x00000000 
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ code:x86:32 ---- 
    0x804e66d  push   DWORD PTR [ebp-0x480] 
    0x804e673  call   0x807f0a3  
    0x804e678  add    esp, 0x10 
-> 0x804e67b  mov    ebx, DWORD PTR [ebp-0x47c] 
    0x804e681  mov    eax, ebx 
    0x804e683  shr    eax, 0x3 
    0x804e686  add    eax, 0x20000000 
    0x804e68b  movzx  edx, BYTE PTR [eax] 
    0x804e68e  test   dl, dl 
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- source:tcpbridge.c+219 ---- 
    214             if ((eth_buff = sendpacket_get_hwaddr(sp)) == NULL) { 
    215                 warnx("Unable to get MAC address: %s", sendpacket_geterr(sp)); 
    216                 err(-1, "Please consult the man page for using the -M option."); 
    217             } 
    218             sendpacket_close(sp); 
        // eth_buff=0xbffff22c -> [...] -> 0x6d3acab8 
-> 219             memcpy(options.intf1_mac, eth_buff, ETHER_ADDR_LEN); 
    220         } 
    221      
    222         if (memcmp(options.intf2_mac, "\00\00\00\00\00\00", ETHER_ADDR_LEN) == 0) { 
    223             if ((sp = sendpacket_open(options.intf2, ebuf, TCPR_DIR_S2C, SP_TYPE_NONE, NULL)) == NULL) 
    224                 errx(-1, "Unable to open interface %s: %s", options.intf2, ebuf); 
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- threads ---- 
[#0] Id 1, Name: "tcpbridge", stopped, reason: SINGLE STEP 
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ trace ---- 
[#0] 0x804e67b->post_args(argc=0x0, argv=0xbffff79c) 
[#1] 0x804d48b->main(argc=0x0, argv=0xbffff79c) 
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
gef> p sp 
$6 = (sendpacket_t *) 0xb4203680 
gef> x sp 
0xb4203680:    2 
gef> p/d options.intf1_mac 
$7 = {0, 0, 0, 0, 0, 0} 
gef> ptype eth_buff 
type = struct tcpr_ether_addr { 
    uint8_t ether_addr_octet[6]; 
} * 
  
gef> x/9i $pc 
=> 0x804e67b :    mov    ebx,DWORD PTR [ebp-0x47c] 
   0x804e681 :    mov    eax,ebx 
   0x804e683 :    shr    eax,0x3 
   0x804e686 :    add    eax,0x20000000 
   0x804e68b :    movzx  edx,BYTE PTR [eax] 
   0x804e68e :    test   dl,dl 
   0x804e690 :    setne  cl 
   0x804e693 :    mov    eax,ebx 
   0x804e695 :    and    eax,0x7 
  
gef> i r 
eax            0x0                 0x0 
ecx            0x3d                0x3d 
edx            0x3c                0x3c 
ebx            0xbffff700          0xbffff700 
esp            0xbffff1f0          0xbffff1f0 
ebp            0xbffff6a8          0xbffff6a8 
esi            0x809fc20           0x809fc20 
edi            0xbffff690          0xbffff690 
eip            0x804e67b           0x804e67b  
eflags         0x286               [ PF SF IF ] 
cs             0x73                0x73 
ss             0x7b                0x7b 
ds             0x7b                0x7b 
es             0x7b                0x7b 
fs             0x0                 0x0 
gs             0x33                0x33 

}
ASAN Output
==11084==ERROR: AddressSanitizer: heap-use-after-free on address 0xb4203b38 at pc 0x0804e6e3 bp 0xbffff1d8 sp 0xbffff1c8 
READ of size 6 at 0xb4203b38 thread T0 
    #0 0x804e6e2 in post_args /home/ACETEAM/tcpreplay/src/tcpbridge.c:219 
    #1 0x804d48a in main /home/ACETEAM/tcpreplay/src/tcpbridge.c:72 
    #2 0xb7832636 in __libc_start_main (/lib/i386-linux-gnu/libc.so.6+0x18636) 
    #3 0x804a955  (/usr/local/bin/tcpbridge+0x804a955) 
  
0xb4203b38 is located 1208 bytes inside of 1240-byte region [0xb4203680,0xb4203b58) 
freed by thread T0 here: 
    #0 0xb7acda84 in free (/usr/lib/i386-linux-gnu/libasan.so.2+0x96a84) 
->    #1 0x807b714 in _our_safe_free /home/ACETEAM/tcpreplay/src/common/utils.c:118 
    #2 0x807f34e in sendpacket_close /home/ACETEAM/tcpreplay/src/common/sendpacket.c:636 
    #3 0x804e677 in post_args /home/ACETEAM/tcpreplay/src/tcpbridge.c:218 
    #4 0x804d48a in main /home/ACETEAM/tcpreplay/src/tcpbridge.c:72 
    #5 0xb7832636 in __libc_start_main (/lib/i386-linux-gnu/libc.so.6+0x18636) 
  
previously allocated by thread T0 here: 
    #0 0xb7acddee in malloc (/usr/lib/i386-linux-gnu/libasan.so.2+0x96dee) 
    #1 0x807b4b0 in _our_safe_malloc /home/ACETEAM/tcpreplay/src/common/utils.c:50 
    #2 0x807ff10 in sendpacket_open_pf /home/ACETEAM/tcpreplay/src/common/sendpacket.c:956 
    #3 0x807e932 in sendpacket_open /home/ACETEAM/tcpreplay/src/common/sendpacket.c:523 
    #4 0x804e4f3 in post_args /home/ACETEAM/tcpreplay/src/tcpbridge.c:211 
    #5 0x804d48a in main /home/ACETEAM/tcpreplay/src/tcpbridge.c:72 
    #6 0xb7832636 in __libc_start_main (/lib/i386-linux-gnu/libc.so.6+0x18636) 
  
SUMMARY: AddressSanitizer: heap-use-after-free /home/ACETEAM/tcpreplay/src/tcpbridge.c:219 post_args 
Shadow bytes around the buggy address: 
  0x36840710: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd 
  0x36840720: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd 
  0x36840730: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd 
  0x36840740: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd 
  0x36840750: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd 
=>0x36840760: fd fd fd fd fd fd fd[fd]fd fd fd fa fa fa fa fa 
  0x36840770: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 
  0x36840780: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 
  0x36840790: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 
  0x368407a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 
  0x368407b0: 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 
==11084==ABORTING
Proof of Concept

tcpbridge --intf1=NETWORKINTERFACE
–inft1 = Primary interface (listen in uni-directional mode). This option may appear up to 1 times.

Timeline

Vendor Disclosure: 2018-10-02
Public Disclosure: 2018-10-03

Credit

Discovered by ACE Team – Loginsoft