Skip to content

[Bug] Heap Address Leak in src/common/xX.c #928

@momo-trip

Description

@momo-trip

Hi, I have found a heap address leak and would like to report this issue.
Could you confirm if this is a bug? I am happy to provide any additional information needed.

Summary

Heap address leak due to lack of validation of argument length following the -x option.

Details

  • Vulnerability Type: Out-of-bounds Read (Heap Address Leak)
  • Version: 4.5.1

Reproduction

Tested Environment

  • Operating System: Ubuntu 22.04 LTS
  • Architecture: x86_64
  • Compiler: clang (clang version: 14.0.0)

Reproduction Steps

# Setup
wget https://github.com/appneta/tcpreplay/releases/download/v4.5.1/tcpreplay-4.5.1.tar.xz
tar -xf tcpreplay-4.5.1.tar.xz
cd tcpreplay-4.5.1

cat > build_tcpreplay.sh << 'EOF'
#!/bin/bash

./configure CC=clang CXX=clang++

make
EOF

chmod +x build_tcpreplay.sh
./build_tcpreplay.sh

# Execute 
./src/tcpprep -x D

Output

Fatal Error: Unable to parse as a valid CIDR: b�

Root Cause Analysis

Insufficient validation of argument length.

Affected Code

src/common/xX.c:39
The code performs str + 2 without validating the length of the str string argument, causing out-of-bounds access.

int
parse_xX_str(tcpr_xX_t *xX, char *str, tcpr_bpf_t *bpf)
{
    int out;

    dbgx(1, "Parsing string: %s", str);
    dbgx(1, "Switching on: %c", str[0]);

    switch (str[0]) {
    case 'B': /* both ip's */
        str = str + 2;
        out = xXBoth;
        if (!parse_cidr(&(xX->cidr), str, ","))
            return xXError;
        break;

    case 'D': /* dst ip */
        str = str + 2;
        out = xXDest;
        if (!parse_cidr(&(xX->cidr), str, ","))
            return xXError;
        break;

    case 'E': /* either ip */
        str = str + 2;
        out = xXEither;
        if (!parse_cidr(&(xX->cidr), str, ","))
            return xXError;
        break;

    case 'F': /* bpf filter */
        str = str + 2;
        out = xXBPF;
        bpf->filter = safe_strdup(str);
        /*
         * note: it's temping to compile the BPF here, but we don't
         * yet know what the link type is for the file, so we have
         * to compile the BPF once we open the pcap file
         */
        break;

    case 'P': /* packet id */
        str = str + 2;
        out = xXPacket;
        if (!parse_list(&(xX->list), str))
            return xXError;
        break;

    case 'S': /* source ip */
        str = str + 2;
        out = xXSource;
        if (!parse_cidr(&(xX->cidr), str, ","))
            return xXError;
        break;

    default:
        errx(-1, "Invalid -%c option: %c", xX->mode, *str);
    }

    if (xX->mode == 'X') { /* run in exclude mode */
        out += xXExclude;
        if (bpf->filter != NULL)
            err(-1,
                "Using a BPF filter with -X doesn't work.\n"
                "Try using -xF:\"not <filter>\" instead");
    }

    xX->mode = out;
    return xX->mode;
}

Impact Assessment

CWE-125: Out-of-bounds Read
This vulnerability allows bypassing security mechanisms such as ASLR and can serve as a stepping stone for arbitrary code execution when combined with other memory corruption vulnerabilities.

Proposed Fix

diff --git a/src/common/xX.c b/src/common/xX.c
index be98943e..76df7540 100644
--- a/src/common/xX.c
+++ b/src/common/xX.c
@@ -43,6 +43,10 @@ parse_xX_str(tcpr_xX_t *xX, char *str, tcpr_bpf_t *bpf)
     dbgx(1, "Parsing string: %s", str);
     dbgx(1, "Switching on: %c", str[0]);
 
+    if (strlen(str) <= 2){
+        return xXError;
+    }
+
     switch (str[0]) {
     case 'B': /* both ip's */
         str = str + 2;

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions