Skip to content
DelspoN
Go back

LG webOS TV Zero-Click RCE

Edit page한국어

A zero-click vulnerability in LG webOS. According to Shodan, roughly 42,000 LG webOS devices are directly exposed on the internet.

Shodan: ~42,136 LG webOS devices exposed on the internet (Korea 23,704, Hong Kong 4,187, etc.)

Affected environment

Version: webOS 10.2.2-5901 (Build 33.31.23)

Vulnerability chain

  1. SSG R2R pairing bypass — the PIN sent to port 3001 is unconditionally accepted as the correct PIN. This bypasses authentication to establish pairing and obtain app-launch permission.
  2. Native-privilege acquisition (undisclosed — unpatched) — an attacker page is loaded while a privileged native context is retained, letting that page make native calls. Details are withheld as it is not yet fixed.
  3. Unsigned IPK installdev/install, gated only by a single on-disk devmode flag, skips signature verification. That flag can itself be turned on via a Luna call, so an unsigned IPK can be installed and arbitrary code executed.

Code-level analysis

1. SSG R2R pairing bypass

File: com.webos.service.secondscreen.gateway/helpers/system/pairing-manager.js

In R2R mode the server only checks the presence and length (PIN_LENGTH = 8) of the client-supplied r2rPin. There is no step that compares it against a correct PIN generated by the TV:

if (!!options.r2rMode) {
    if (!!options.r2rPin === false) {
        return Q.reject("r2rPin does not exist");
    } else if (options.r2rPin.length !== this.PIN_LENGTH) {
        return Q.reject("r2rPin.length is not PIN_LENGTH");
    }
}

That value is then stored as-is as the correct PIN, and the popup that would be shown to the user is short-circuited to an empty string in R2R mode:

if (!!this.pairingRequests[pairingRequestId].r2rMode) {
    pin = this.pairingRequests[pairingRequestId].r2rPin;   // attacker-controlled
} else {
    pin = this.generatePin();                              // normal: random 8 digits
}
this.pairingRequests[pairingRequestId].pin = pin;          // stored as the correct PIN

When the attacker submits the same PIN they sent at register time via ssap://pairing/setPin, pairing succeeds. An empty signatures[].signature in the manifest still passes, granting even the PROTECTED-tier LAUNCH permission.

2. Native-privilege acquisition (undisclosed)

This step is not yet patched, so its details are not disclosed.

Using the app-launch permission gained from vulnerability 1 as a foothold, this flaw loads an attacker-controlled external web page while retaining a privileged native IPC context. As a result, the attacker page’s script can make native calls directly, which leads into the setDevMode and dev/install calls of vulnerability 3. The specific affected component, permission, code, and reproduction steps are withheld until it is fixed.

3. Unsigned IPK install

File: usr/sbin/appinstalld

The privileged native context obtained from vulnerability 2 can turn on the devmode flag directly via setDevMode. The passphrase entry required in normal use exists only in the LG Developer UI, not at the LS2 method level:

luna://com.webos.service.devmode/setDevMode {"enabled": true}

Once the flag is on, dev/install — unlike the production path — does not call signature verification (pkgverifier/verifyIpk) and accepts an unsigned IPK as state:"installed". Launching the installed type:"native" IPK enables arbitrary code execution.

Root cause

Impact

Demo

A demo of an attacker on the same network achieving remote code execution with only the TV’s IP and no user interaction.

Disclosure timeline

Exploit code and detailed payloads are not disclosed. Please reach out separately if needed.


Edit page
Share this post:

Previous Post
Christmas CTF 2019 / Christmas Pocket