TALOS-2022-1512 memory corruption vulnerability

Hello,
The Cisco Talos team found a security vulnerability affecting ArduPilot APWeb master commit 50b6b7ac - master commit 46177cb9.
As this is a sensitive security issue, this message is to request a PGP key for further communication via email. If a key is not received or is unavailable, this issue via Github should be marked as private and a security report of findings will be added. two business days. Please acknowledge receipt oso we can confirm we have the correct method for reporting security issues.
For further information about the Cisco Vendor Vulnerability Reporting and Disclosure Policy please refer to this document which also links to our public PGP key. https://tools.cisco.com/security/center/resources/vendor_vulnerability_policy.html Please CC vulndiscovery@external.cisco.com on all correspondence related to this issue.

hello,
Thanks for the report, no need to PGP security here.
Please make the issue on Github open so everybody can learn from the issue. Thanks

TALOS-2022-1512
CVE-2022-28711

ArduPilot APWeb cgi.c unescape memory corruption vulnerability

Summary

A memory corruption vulnerability exists in the cgi.c unescape functionality of ArduPilot APWeb master branch 50b6b7ac - master branch 46177cb9. A specially-crafted HTTP request can lead to memory corruption. An attacker can send a network request to trigger this vulnerability.

Tested Versions

ArduPilot APWeb master commit 50b6b7ac - master commit 46177cb9

Product URLs

APWeb - https://github.com/ArduPilot/APWeb

CVSSv3 Score

5.3 - CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N

CWE

CWE-20 - Improper Input Validation

Details

APWeb is the web server for ArduPilot.

The ArduPilot’s APWeb component, has a file named cgi.c that contains CGI helper functions. One of these functions is unescape:

void unescape(char *p)
{
    unsigned v;

    while (*p) {                                                                                        [1]
        if (*p == '+') *p = ' ';
        if (*p == '%' && sscanf(p+1, "%02x", &v) == 1) {                                                [2]
            *p = (char)v;                                                                               [3]
            memcpy(p+1, p+3, strlen(p+3)+1);                                                            [4]
        }
        p++;
    }
}

This function takes as argument a string. If the string is URL encoded, this function will decode it. The while loop, starting at [1], will traverse the input searching for the characters % or +. When the % character is found then, at [2], the following two characters are converted from hex value to a single character. At [3] the converted character replaces the % character. At [4], the string after the just parsed URL encoded character is moved left by two position, this will replace the parsed characters.
A string like “A…B%41%42” would go through the following steps:

|A|...|B|%|4|1|%|4|2|NULL|           at    [1]/[2]
|A|...|B|A|4|1|%|4|2|NULL|           after [3]
|A|...|B|A|%|4|2|NULL|2|NULL|        after [4]

Eventually, after a second iteration of the loop we would end up like this:

|A|...|B|A|B|NULL|2|NULL|2|NULL|     after [4]

The unescape function assumes, wrongly, that after a % there are always at least two characters. If this is not the case the instruction at [4] would cause a out-of-bounds read, and could cause an out-of-bounds and write.

Credit

Discovered by Francesco Benvenuto of Cisco Talos.

Timeline

2022-04-11 - Vendor Disclosure
None - Public Release

nice one. Thanks !
considering the usage of APWeb, this is armless, but we will still make a patch as it can still serve as example

@CiscoTalos thanks for reporting! I’ve pushed a fix:

please let me know if you see any issues with the fix