A difficult task in Nodejs
We have a very difficult task just for you.
There are Huawei b311 routers and they have:
- Software version 11.0.2.2
- Web page version WEBUI 11.0.2.1
Somewhere something may differ by several numbers, and the device model may be different; this firmware is installed on many devices from a given manufacturer.
This firmware has authorization that cannot be disabled and is quite tricky.
The task is to release this authorization on Nodejs.
What we already have:
- We know that the first GET request during authorization goes to the address "/api/webserver/token"
- It sets a cookie and returns a token, 32 characters of which which should be written in the header of the next request
- Next, a random hash 64 characters long is generated and sent to the address /api/user/challenge_login POST request.
- The response header overwrites the token received from this request
- In the response we receive the 3 parameters we need salt, iterations, servernonce
- Then, with some simple manipulations with CryptoJS.PBKDF2, CryptoJS.HmacSHA256 we get 2 new values
- Next, we send these values in a POST request to /api/user/authentication_login
- And that’s all.
What we currently have in terms of synchronous code:
const CryptoJS = require('crypto-js');
const request = require('co-request');
async function get_json_xml(a){
return JSON.parse(convert.xml2json(a, {compact: true, spaces: 4}));
}var tmp = await request('http://'+pl.phone_list_adm_ip+'/api/webserver/token');
var body=await get_json_xml(tmp.body);
var cook=tmp.headers['set-cookie'];
var header={'Cookie': cook[0], 'Referer': 'http://'+pl.phone_list_adm_ip+'/html/index.html', '_ResponseSource': 'Broswer', '__RequestVerificationToken': body.response.token._text.substr(32),'Content-Type':'application/x-www-form-urlencoded'};
var firstnonce=crypto.createHash('md5').digest("hex")+crypto.createHash('md5').digest("hex");
var obj={url:'http://'+pl.phone_list_adm_ip+'/api/user/challenge_login', body:'<?xml version: "1.0" encoding="UTF-8"?><request><username>admin</username><firstnonce>'+firstnonce+'</firstnonce><mode>1</mode></request>', headers: header};
var tmp= await request.post(obj);
header['__RequestVerificationToken']=tmp.headers['__requestverificationtoken'];
var data=await get_json_xml(tmp.body);
worklog(data);
var pass='admin12345';
var scarmSalt = CryptoJS.enc.Hex.parse(data.response.salt._text);
var iter = data.response.iterations._text;
var finalNonce = data.response.servernonce._text;
var authMsg = firstnonce + ',' + finalNonce + ',' + finalNonce;
var saltPassword = CryptoJS.PBKDF2(pass, scarmSalt, {keySize: 8,iterations:iter,hasher: CryptoJS.algo.SHA256});
saltPassword = saltPassword.toString();
var serverKey = CryptoJS.HmacSHA256(CryptoJS.enc.Hex.parse(saltPassword),"Server Key");
serverKey = serverKey.toString();
var spwd = CryptoJS.PBKDF2(pass, scarmSalt, {keySize: 8,iterations:iter,hasher: CryptoJS.algo.SHA256});
var ckey = CryptoJS.HmacSHA256(spwd,"Client Key");
var hasher = CryptoJS.algo.SHA256.create();
var skey = hasher.update(ckey).finalize();
var csig = CryptoJS.HmacSHA256(skey, authMsg);for (var i = 0; i < ckey.sigBytes/4; i += 1) {
ckey.words[i] = ckey.words[i] ^ csig.words[i]
}
clientProof = ckey.toString();
var obj={url:'http://'+pl.phone_list_adm_ip+'/api/user/authentication_login', body:'<?xml version: "1.0" encoding="UTF-8"?><request><clientproof>'+clientProof+'</clientproof><finalnonce>'+finalNonce+'</finalnonce></request>', headers: header};
We can’t do anything further, and we don’t understand what’s going on there and are looking for a person who can implement it. So if you know how and can, then welcome board.
If you know how or know the one who knows how to write to m@mobileproxy.space with the theme “The difficult task on nodejs” and we will cooperate.