Untying AirTies

It is well known that embedded devices' firmware are strewn with vulnerabilities. Whether it's the nature of the development process, apathy on part of the company, or shortcuts taken to appease the customer in some other way, the fact of the matter is it's basically candyland for newer researchers.

There will be no discussion of the why in this post though, only another example of poor security.

The target was the AirTies 4920 firmware version 2.49, retrieved by sniffing the update process of the device and browsing to that endpoint.

One of the first interesting features was remote debugging, which after setting up allowed me to get somewhat verbose output without having to deal with the SPI or JTAG.

Unfortunatley, there wasn't anything like the previous version I looked at (2.44), which was as simple as this:

http://192.168.1.81/cgi-bin/steer.sh?cmd=`whoami`

However, a simple survey script I wrote picked up on rampant use of strcpy in multiple binaries. One of those was the mngr binary, which takes care of logging and logic control for many of the services.

After doing a bit of static analysis in Ghidra, I found this vulnerable function:

int IOLogFunc(int iParm1,char *pcParm2,undefined4 uParm3,undefined4 uParm4)    
{
    int iVar1;
    char *local_2c;
    undefined4 *local_28;
    int local_24;
    char *local_c;
    undefined4 uStack8;
    undefined4 uStack4;
    
    local_c = pcParm2;
    uStack8 = uParm3;
    uStack4 = uParm4;
    __cyg_profile_func_enter(IOLogFunc);
    local_24 = 0;
    local_2c = (char *)0x0;
    local_28 = &uStack8;
    local_24 = vasprintf(&local_2c,local_c,local_28);
    if (iParm1 == 2) {
    strcpy(log_buf,local_2c);
    LogAdd(2,7,0x11,"GENERIC",log_buf,"io_mngr.c",0x431,"IOLogFunc");
    }
    else {
    strcpy(log_buf,local_2c);
    LogAdd(2,3,0x11,"GENERIC",log_buf,"io_mngr.c",0x433,"IOLogFunc");
    }
    if (local_24 != -1) {
    free(local_2c);
    }
    iVar1 = local_24;
    __cyg_profile_func_exit(IOLogFunc);
    return iVar1;
}

The LogAdd() function is easy to hit in the logic flow, and is a classic buffer overflow with one of the parameters.

if (iParm1 == 2)
{
    strcpy(log_buf,local_2c);
    LogAdd(2,7,0x11,"GENERIC",log_buf,"io_mngr.c",0x431,"IOLogFunc");
}

With this knowledge, I simply looked for the functionality of the IOLogFunc, and found it was controlled by the user... from the web interface! Unfortunately this does require authentication, but still is fun and likely a means for other avenues of approach.

I was able to build a PoC, but quickly bootlooped the device due to my lack of debugging skills in embedded devices at the time. As such, I am not officially releasing the PoC. Nor will I continue to work on this device, since there is very little benefit aside from learning.