kclejeune / TMobile-ISP-Client

mobile friendly, self hosted status dashboard for T-Mobile ISP routers
MIT License
33 stars 4 forks source link

Feature Request: Endpoint to do reboot through this client #1

Open leonowski opened 3 years ago

leonowski commented 3 years ago

Hi,

Thank you for making this. Very useful.

Is it possible to get an endpoint that will reboot the tmobile trashcan device? It is available through the t-mobile GUI but it needs auth. So, we need a way to store this auth in your client as well.

kclejeune commented 3 years ago

This is definitely on my to-do list! I've looked into it briefly and the auth mechanism is a little unclear, so it'll take some reverse engineering to figure out how to do it properly.

I'll try to do this when I have time, but would also welcome any pull requests that help advance this goal.

highvolt-dev commented 3 years ago

I found it helpful to do packet capture on my phone using the app when I first experimented with this some months ago - I used PCAPdroid. Amusingly, as I recall the mobile app seems to try endpoints for both the 4G Askey gateway as well as the Nokia when it starts and tries to auth. It does handle some things with the Nokia over websockets.

leonowski commented 3 years ago

This is definitely on my to-do list! I've looked into it briefly and the auth mechanism is a little unclear, so it'll take some reverse engineering to figure out how to do it properly.

I'll try to do this when I have time, but would also welcome any pull requests that help advance this goal.

I am definitely not an expert in this type of stuff. I did observe things to try and make sense of it:

  1. A GET request to http://192.168.12.1/login_web_app.cgi?nonce

returns a nonce, randomKey, and pubkey in json

  1. A POST to http://192.168.12.1/login_web_app.cgi occurs with this form data:

userhash: RandomKeyhash: response: nonce: enckey: enciv:

It then returns more json that looks similar to this:

{"result":0,"sid":"RbOJgmxqgdemkdia","token":"MHPPlwKrncvjsVKt","is_ctc_admin":0}

  1. Finally for a reboot, a POST to here: http://192.168.12.1/reboot_web_app.cgi

With the token from step 2 as form data named "csrf_token"

My ultimate goal is to have something that checks certain things about the signal and then reboot if it's not what I want. I noticed the json returned from your app that I could read easily for various things like signal strength.

kclejeune commented 3 years ago

I am definitely not an expert in this type of stuff. I did observe things to try and make sense of it:

  1. A GET request to http://192.168.12.1/login_web_app.cgi?nonce

returns a nonce, randomKey, and pubkey in json

  1. A POST to http://192.168.12.1/login_web_app.cgi occurs with this form data:

userhash:

RandomKeyhash:

response:

nonce:

enckey:

enciv:

For this step, it's unclear what the original client is using for hashing (it's either obfuscated or minified), so I can't generate those fields to post to this endpoint yet.

It then returns more json that looks similar to this:

{"result":0,"sid":"RbOJgmxqgdemkdia","token":"MHPPlwKrncvjsVKt","is_ctc_admin":0}

Once I'm able to get this response from it, the rest should be easy :)

  1. Finally for a reboot, a POST to here: http://192.168.12.1/reboot_web_app.cgi

With the token from step 2 as form data named "csrf_token"

My ultimate goal is to have something that checks certain things about the signal and then reboot if it's not what I want. I noticed the json returned from your app that I could read easily for various things like signal strength.

If I'm able to get auth working then I can look into implementing this - it shouldn't be too difficult with the current setup.

highvolt-dev commented 3 years ago

Here's the source the client is using to login:

const s = cryptoJS.sha256(t.username, t.password)
  , r = cryptoJS.sha256url(s, i.nonce);
let o = `userhash=${cryptoJS.sha256url(t.username, i.nonce)}&RandomKeyhash=${cryptoJS.sha256url(i.randomKey, i.
nonce)}&response=${r}&nonce=${cryptoJS.base64url_escape(i.nonce)}`;
const a = sjcl.codec.base64
  , l = a.fromBits(sjcl.random.randomWords(4, 0))
  , c = a.fromBits(sjcl.random.randomWords(4, 0));
o += `&enckey=${cryptoJS.base64url_escape(l)}`,
o += `&enciv=${cryptoJS.base64url_escape(c)}`,
kclejeune commented 3 years ago

Here's the source the client is using to login:


const s = cryptoJS.sha256(t.username, t.password)

  , r = cryptoJS.sha256url(s, i.nonce);

let o = `userhash=${cryptoJS.sha256url(t.username, i.nonce)}&RandomKeyhash=${cryptoJS.sha256url(i.randomKey, i.

nonce)}&response=${r}&nonce=${cryptoJS.base64url_escape(i.nonce)}`;

const a = sjcl.codec.base64

  , l = a.fromBits(sjcl.random.randomWords(4, 0))

  , c = a.fromBits(sjcl.random.randomWords(4, 0));

o += `&enckey=${cryptoJS.base64url_escape(l)}`,

o += `&enciv=${cryptoJS.base64url_escape(c)}`,

Thanks for this - I'll get started on implementing this when I have some more time.