A closer look at the TCL Go Flip 4 5G and KaiOS 4.0

Posted by Tom Barrasso on

The TCL Go Flip 4 5G (commercial reference T440W-EATBUS1-V for T-Mobile) is the first device to ship with KaiOS 4.0. Given that CVE-2023-33294 and CVE-2023-27108 were discovered on the original Alcatel Go Flip 4 running KaiOS 3.0, it was worth checking whether these issues carried forward to new hardware.

The short answer: KaiOS 4.0 is architecturally indistinguishable from KaiOS 3.0. Many of the known vulnerabilities have been partially addressed, but the surface area remains broad.

ADB & Developer Mode Access

Unlike previous Go Flip models, developer mode is surprisingly easy to enable! This may be an accident, since the build my Flip 4 5G runs uses test-keys. Either way, I was able to use standard secret dialer codes:

  • *#*333284#*#* — developer mode
  • *#8378269# — launch Engmode app

Web2Dev (W2D) also works! WebActivity remains accessible from websites on the Browser app. See w2d.js.org for details.

1let w2d = new WebActivity("configure", {
2  target: "device",
3  section: "developer",
4});
5
6w2d.start()
7  .then(() => console.log("Developer Tools opened!"));

Making a surprising return is the secret Konami Code in the Settings app! Navigate to Settings > Device > Device Info > More Info, the following soft key sequence opens a hidden menu:

1SoftLeft SoftLeft SoftRight SoftLeft SoftRight SoftRight

Finally, another option from the Browser to launch the Engmode app (or any app for that matter) is to use the kind=app parameter passed to window.open using the Manifest URL of the target app.

1window.open(
2  "http://engmode.localhost/manifest.webmanifest",
3  "_blank",
4  "kind=app,noopener=yes"
5);

Limitations

Like previous KaiOS 3.0 devices, it’s not possible to access the device from Firefox’s Remote Debugger due to SELinux and permission issues accessing the debugger socket.

103-02 11:07:46.865  5108  5108 E adbd    : failed to connect to socket 'localfilesystem:/data/local/firefox-debugger-socket': could not connect to localfilesystem address 'localfilesystem:/data/local/firefox-debugger-socket'
203-02 11:07:46.860  5108  5108 W adbd    : type=1400 audit(0.0:61): avc:  denied  { write } for  name="firefox-debugger-socket" dev="dm-38" ino=5153 scontext=u:r:adbd:s0 tcontext=u:object_r:b2g_data_file:s0 tclass=sock_file permissive=0

The default Device Preference values match those from previous ROMs.

1pref("devtools.debugger.unix-domain-socket", "/data/local/firefox-debugger-socket");
2pref("devtools.debugger.remote-port", 6000);

CVE-2023-33294: tctweb_server Ensures

CVE-2023-33294 documented that the /system/bin/tctweb_server binary on KaiOS 3.0 exposed an unauthenticated HTTP server on port 2929 that would execute arbitrary commands as root. This binary disappeared in KaiOS 3.1, but possibly because it’s TCL-specific and the only KaiOS 3.1 devices were from other vendors like Nokia.

On the Go Flip 4 5G, tctweb_server is back, again listening on http://127.0.0.1:2929. It runs as root and is accessible to installed apps and websites via the browser. However, this time it’s significantly hardened. For starters, SE Linux prevents you from reading or copying the binary. It also implements an internal command and property whitelist. Attempts to issue arbitrary shell commands or read files like /system/build.prop are rejected.

103-02 13:14:12.550  1487 11862 E tctweb_server: [mweb] not in whitelist cat /sys/class/power_supply/battery/temp,

The server still responds to name=query&api=... style requests for a restricted set of system properties, and cmd=shell&... commands limited to diagnostic operations. The broad cmdshell passthrough that made the original vulnerability so dangerous appears to no longer be present.

A second daemon, EsimAfterSalesServer (run using mozTCPSocket inside the System app), runs on port 8612 and handles eSIM provisioning commands (clear-profile, esim-status-check) via a basic HTTP parser. This provides a specific vector for interacting with carrier eSIM profiles, and once again is globally accessible including from the browser, but lacks general system access.

Consistent with other TCL devices like the Android-based Go Flip 2, this phone ships with a few extra binaries including mfg_util and its daemon counterpart, mfg_utild, which reads special flags from /dev/block/by-name/oembin. This may be useful in a future exploit as it appears to control the ro.boot.inproductionflag.

CVE-2023-27108: getCallLogList Fixed

CVE-2023-27108 documented that the getCallLogList Web Activity on KaiOS 3.0 returned call log data to any caller without any origin check.

In KaiOS 4.0, the Communications app manifest now includes an allowedOrigins restriction:

 1"getCallLogList": {
 2  "filters": {
 3    "type": {
 4      "required": true,
 5      "value": [
 6        "calllog/tel"
 7      ]
 8    }
 9  },
10  "allowedOrigins": [
11    "system",
12    "http://system.localhost"
13  ],
14  "returnValue": true
15}

This is exactly the mitigation recommended in the original CVE write-up. Calls to this activity from third-party apps or websites will now be rejected with the error NO_PROVIDER.

Engmode: Possible Command Injection

The following has yet to be confirmed. Like nearly every previous KaiOS version, the Engmode API (navigator.b2g.engmodeManager) is limited to Core apps with the engmode permission. It also appears to perform complex input sanitization before passing commands off to EngmodeService.

On potential target for command injection is the updateAtmPressure method, which constructs a shell command by string concatenation:

 1updateAtmPressure(pressure) {
 2  return this.createPromiseWithId(aResolverId => {
 3    const floatRegex = /^[+-]?[0-9]+\.[0-9]+$/;
 4    if (
 5      parseFloat(pressure) > 259.0 &&
 6      parseFloat(pressure) < 1261.0 &&
 7      floatRegex.test(JSON.stringify(pressure))
 8    ) {
 9      var command =
10        "mkdir /mnt/testbox_log/;" +
11        "./vendor/bin/pressure_test -sensor=pressure -sample_rate=5 " +
12        "-duration=5 -limit1=3 -limit2=-3 -offset=" + pressure +
13        " > mnt/testbox_log/atmpressure.txt";
14
15      Services.cpmm.sendAsyncMessage("Engmode:EngmodeTestCommand", {
16        param: command,
17        useShell: true,
18        operation: "start",
19        requestID: aResolverId,
20      });
21    } else {
22      this.takePromiseResolver(aResolverId).reject("invalid parameter");
23    }
24  });
25}

The pressure value is passed directly into the shell command string. The validation — a range check and a regex applied to JSON.stringify(pressure) – intends to restrict input to a decimal number. However, the JSON.stringify call wraps string inputs in quotes, so the regex will reject string inputs that would otherwise pass the float check. If pressure is a Number rather than a String, the regex comparison behaves as intended.

Conclusion

KaiOS 4.0 on the TCL Go Flip 4 5G is pretty much identical to KaiOS 3.0 from a user perspective. From a security point-of-view, it appears prior vulnerabilities have been hardened. Yet, exposing HTTP services like the eSIM provisioning server circumvents permission and inter-process communication (IPC) safeguards, which is fundamentally poor design.