penn5 / miunlock

Test code to talk to unlock.update.miui.com
https://unlock.update.miui.com
52 stars 56 forks source link

Fix missing ssecurity #4

Closed GiorgioUghini closed 3 years ago

GiorgioUghini commented 4 years ago

Feel free to beautify my code, I was in a hurry to write it in a good way :)

xaiki commented 3 years ago

this still gets the ssecurity error. also, it makes it harder to debug why as we now have all the login dance in between.

penn5 commented 3 years ago

this still gets the ssecurity error. also, it makes it harder to debug why as we now have all the login dance in between.

Anyone who gets it working again can make a fork and I'll link it in the readme.

pcfighter commented 3 years ago

Hi, there's possible to get ssecurity and nonce, you need to download MiUnlock 3.5.1030.37 (i've got one from mi-globe website). They have some quirky debugging there. just open miunlock, and in explorer go to %appdata%\Roaming\Xiaomi\miflash_unlock\Log\miflash_unlock.log on miunlock, login using your mi account, and immediately close it when it says "Checking if your mi account have permissions..." You will find data needed to put into main.py when prompted on 1 req response logline. It contains ssecurity and nonce arguments here. I was able to proceed with passing fastboot getvars, but well still have to wait for unlocking my device :) you should be quick, because delaying may result with "nonce used" error

notmarek commented 3 years ago

Hello after reading @pcfighter i got curious and "reverse engineered" the login process

var w2b=r=>{for(var n=[],t=0;t<32*r.length;t+=8)n.push(r[t>>>5]>>>24-t%32&255);return n},b2h=r=>Array.from(r,function(r){return("0"+(255&r).toString(16)).slice(-2)}).join(""),b2s=r=>{for(var n=[],t=0;t<r.length;t++)n.push(String.fromCharCode(r[t]));return n.join("")},b2w=r=>{for(var n=[],t=0,e=0;t<r.length;t++,e+=8)n[e>>>5]|=r[t]<<24-e%32;return n},rotl=(r,n)=>r<<n|r>>>32-n,endian=r=>{if(r.constructor==Number)return 16711935&rotl(r,8)|4278255360&rotl(r,24);for(var n=0;n<r.length;n++)r[n]=endian(r[n]);return r},s2b=r=>{for(var n=[],t=0;t<r.length;t++)n.push(255&r.charCodeAt(t));return n},a=function n(t,e){t.constructor==String?(e&&e.encoding,t=s2b(t)):r(t)?t=Array.prototype.slice.call(t,0):Array.isArray(t)||t.constructor===Uint8Array||(t=t.toString());for(var o=b2w(t),t=8*t.length,a=1732584193,i=-271733879,u=-1732584194,h=271733878,s=0;s<o.length;s++)o[s]=16711935&(o[s]<<8|o[s]>>>24)|4278255360&(o[s]<<24|o[s]>>>8);o[t>>>5]|=128<<t%32,o[14+(64+t>>>9<<4)]=t;for(var f=n._ff,g=n._gg,c=n._hh,l=n._ii,s=0;s<o.length;s+=16){var b=a,v=i,_=u,d=h,a=f(a,i,u,h,o[s+0],7,-680876936),h=f(h,a,i,u,o[s+1],12,-389564586),u=f(u,h,a,i,o[s+2],17,606105819),i=f(i,u,h,a,o[s+3],22,-1044525330);a=f(a,i,u,h,o[s+4],7,-176418897),h=f(h,a,i,u,o[s+5],12,1200080426),u=f(u,h,a,i,o[s+6],17,-1473231341),i=f(i,u,h,a,o[s+7],22,-45705983),a=f(a,i,u,h,o[s+8],7,1770035416),h=f(h,a,i,u,o[s+9],12,-1958414417),u=f(u,h,a,i,o[s+10],17,-42063),i=f(i,u,h,a,o[s+11],22,-1990404162),a=f(a,i,u,h,o[s+12],7,1804603682),h=f(h,a,i,u,o[s+13],12,-40341101),u=f(u,h,a,i,o[s+14],17,-1502002290),a=g(a,i=f(i,u,h,a,o[s+15],22,1236535329),u,h,o[s+1],5,-165796510),h=g(h,a,i,u,o[s+6],9,-1069501632),u=g(u,h,a,i,o[s+11],14,643717713),i=g(i,u,h,a,o[s+0],20,-373897302),a=g(a,i,u,h,o[s+5],5,-701558691),h=g(h,a,i,u,o[s+10],9,38016083),u=g(u,h,a,i,o[s+15],14,-660478335),i=g(i,u,h,a,o[s+4],20,-405537848),a=g(a,i,u,h,o[s+9],5,568446438),h=g(h,a,i,u,o[s+14],9,-1019803690),u=g(u,h,a,i,o[s+3],14,-187363961),i=g(i,u,h,a,o[s+8],20,1163531501),a=g(a,i,u,h,o[s+13],5,-1444681467),h=g(h,a,i,u,o[s+2],9,-51403784),u=g(u,h,a,i,o[s+7],14,1735328473),a=c(a,i=g(i,u,h,a,o[s+12],20,-1926607734),u,h,o[s+5],4,-378558),h=c(h,a,i,u,o[s+8],11,-2022574463),u=c(u,h,a,i,o[s+11],16,1839030562),i=c(i,u,h,a,o[s+14],23,-35309556),a=c(a,i,u,h,o[s+1],4,-1530992060),h=c(h,a,i,u,o[s+4],11,1272893353),u=c(u,h,a,i,o[s+7],16,-155497632),i=c(i,u,h,a,o[s+10],23,-1094730640),a=c(a,i,u,h,o[s+13],4,681279174),h=c(h,a,i,u,o[s+0],11,-358537222),u=c(u,h,a,i,o[s+3],16,-722521979),i=c(i,u,h,a,o[s+6],23,76029189),a=c(a,i,u,h,o[s+9],4,-640364487),h=c(h,a,i,u,o[s+12],11,-421815835),u=c(u,h,a,i,o[s+15],16,530742520),a=l(a,i=c(i,u,h,a,o[s+2],23,-995338651),u,h,o[s+0],6,-198630844),h=l(h,a,i,u,o[s+7],10,1126891415),u=l(u,h,a,i,o[s+14],15,-1416354905),i=l(i,u,h,a,o[s+5],21,-57434055),a=l(a,i,u,h,o[s+12],6,1700485571),h=l(h,a,i,u,o[s+3],10,-1894986606),u=l(u,h,a,i,o[s+10],15,-1051523),i=l(i,u,h,a,o[s+1],21,-2054922799),a=l(a,i,u,h,o[s+8],6,1873313359),h=l(h,a,i,u,o[s+15],10,-30611744),u=l(u,h,a,i,o[s+6],15,-1560198380),i=l(i,u,h,a,o[s+13],21,1309151649),a=l(a,i,u,h,o[s+4],6,-145523070),h=l(h,a,i,u,o[s+11],10,-1120210379),u=l(u,h,a,i,o[s+2],15,718787259),i=l(i,u,h,a,o[s+9],21,-343485551),a=a+b>>>0,i=i+v>>>0,u=u+_>>>0,h=h+d>>>0}return endian([a,i,u,h])};a._ff=function(r,n,t,e,o,a,i){i=r+(n&t|~n&e)+(o>>>0)+i;return(i<<a|i>>>32-a)+n},a._gg=function(r,n,t,e,o,a,i){i=r+(n&e|t&~e)+(o>>>0)+i;return(i<<a|i>>>32-a)+n},a._hh=function(r,n,t,e,o,a,i){i=r+(n^t^e)+(o>>>0)+i;return(i<<a|i>>>32-a)+n},a._ii=function(r,n,t,e,o,a,i){i=r+(t^(n|~e))+(o>>>0)+i;return(i<<a|i>>>32-a)+n},a._blocksize=16,a._digestsize=16;var hash=r=>{var n=w2b(a(r,r));return(r&&r.asBytes?n:(r&&r.asString?b2s:b2h)(n)).toUpperCase()}; 
// the long shit above this is whats used by xiaomi to create the password hash, if you don't believe me don't run it
var username = encodeURIComponent("username (usually your number or email, not your id)");
var password = hash("password"); // hash is the function from above

fetch("https://account.xiaomi.com/pass/serviceLoginAuth2", {
    method: "POST",
    body: `https%3A%2F%2Faccount.xiaomi.com&sid=passport&qs=%253Fsid%253Dpassport%2526json%253Dfalse%2526passive%253Dtrue%2526hidden%253Dfalse%2526_snsDefault%253Dfacebook%2526_locale%253Den%2526checkSafePhone%253Dtrue&serviceParam=%7B%22checkSafePhone%22%3Atrue%2C%22checkSafeAddress%22%3Afalse%2C%22lsrp_score%22%3A0.0%7D&_sign=2&V1_passport&user=${username}&cc=%2B1&hash=${password}&_json=true`,
   headers: { "content-type": "application/x-www-form-urlencoded; charset=UTF-8" }
}).then(async(r)=>{console.log(await r.text())})

To use the code above just go to account.xiaomi.com (You don't have to login) open the console paste it edit the username, password press enter and the magic string appears here's a censored image of the script working

penn5 commented 3 years ago

The long shit is probably a NIST-approved SHA or a password hashing algo. Maybe run a bunch of algos and see which one works lol

notmarek commented 3 years ago

Turns out it was just MD5 and i somehow messed up the string i was comparing yesterday

var loadScript = (src, callback) => {
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = src;
    script.onload = () => { callback() };
    document.head.appendChild(script);
}

loadScript("https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/core.js", ()=>{});
loadScript("https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/md5.js", ()=>{
var username = encodeURIComponent("username (usually your number or email, not your id)");
var password = CryptoJS.MD5("password").toString().toUpperCase();

fetch("https://account.xiaomi.com/pass/serviceLoginAuth2", {
    method: "POST",
    body: `https%3A%2F%2Faccount.xiaomi.com&sid=passport&qs=%253Fsid%253Dpassport%2526json%253Dfalse%2526passive%253Dtrue%2526hidden%253Dfalse%2526_snsDefault%253Dfacebook%2526_locale%253Den%2526checkSafePhone%253Dtrue&serviceParam=%7B%22checkSafePhone%22%3Atrue%2C%22checkSafeAddress%22%3Afalse%2C%22lsrp_score%22%3A0.0%7D&_sign=2&V1_passport&user=${username}&cc=%2B1&hash=${password}&_json=true`,
   headers: { "content-type": "application/x-www-form-urlencoded; charset=UTF-8" }
}).then(async(r)=>{console.log(await r.text())})
});

here's the same thing but using the CryptoJS library

penn5 commented 3 years ago

And it works?

On Thu, 4 Feb 2021, 08:13 Marek Veselý, notifications@github.com wrote:

Turns out it was just MD5 and i somehow messed up the string i was comparing yesterday

var loadScript = (src, callback) => { var script = document.createElement('script'); script.type = 'text/javascript'; script.src = src; script.onload = () => { callback() }; document.head.appendChild(script);} loadScript("https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/core.js", ()=>{});loadScript("https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/md5.js", ()=>{var username = encodeURIComponent("username (usually your number or email, not your id)");var password = CryptoJS.MD5("password").toString().toUpperCase(); fetch("https://account.xiaomi.com/pass/serviceLoginAuth2", { method: "POST", body: https%3A%2F%2Faccount.xiaomi.com&sid=passport&qs=%253Fsid%253Dpassport%2526json%253Dfalse%2526passive%253Dtrue%2526hidden%253Dfalse%2526_snsDefault%253Dfacebook%2526_locale%253Den%2526checkSafePhone%253Dtrue&serviceParam=%7B%22checkSafePhone%22%3Atrue%2C%22checkSafeAddress%22%3Afalse%2C%22lsrp_score%22%3A0.0%7D&_sign=2&V1_passport&user=${username}&cc=%2B1&hash=${password}&_json=true, headers: { "content-type": "application/x-www-form-urlencoded; charset=UTF-8" }}).then(async(r)=>{console.log(await r.text())})});

here's the same thing but using the CryptoJS library

— You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub https://github.com/penn5/miunlock/pull/4#issuecomment-773118322, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABKXNQTDOJPVKUH3MA2LM3TS5JJJZANCNFSM4JP6NGJQ .

notmarek commented 3 years ago

Actually the previous one i posted didnt but after replacing passport with unlockApi https://i.kawaii.sh/mlm16SO.png i got my code!

var loadScript = (src, callback) => {
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = src;
    script.onload = () => { callback() };
    document.head.appendChild(script);
}

loadScript("https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/core.js", ()=>{
loadScript("https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/md5.js", ()=>{
var username = "username (usually your number or email, not your id)";
var password = "password";

fetch("https://account.xiaomi.com/pass/serviceLoginAuth2", {
    method: "POST",
    body: `https%3A%2F%2Faccount.xiaomi.com&sid=unlockApi&qs=%253Fsid%253DunlockApi%2526json%253Dfalse%2526passive%253Dtrue%2526hidden%253Dfalse%2526_snsDefault%253Dfacebook%2526_locale%253Den%2526checkSafePhone%253Dtrue&serviceParam=%7B%22checkSafePhone%22%3Atrue%2C%22checkSafeAddress%22%3Afalse%2C%22lsrp_score%22%3A0.0%7D&_sign=2&V1_passport&user=${encodeURIComponent(username)}&cc=%2B1&hash=${CryptoJS.MD5(password).toString().toUpperCase()}&_json=true`,
   headers: { "content-type": "application/x-www-form-urlencoded; charset=UTF-8" }
}).then(async(r)=>{console.log(await r.text())})
});
});

here's the script with an updated body. @penn5

penn5 commented 3 years ago

Why is there MD5?

notmarek commented 3 years ago

Why is there MD5?

Thats how xiaomi passes the password to their servers this function is used for login you can check it with dev tools when logging in

penn5 commented 3 years ago

Why is there MD5?

Thats how xiaomi passes the password to their servers this function is used for login you can check it with dev tools when logging in

Oh boi.

rien333 commented 3 years ago

So wait, since the roadblock was that there was no way of obtaining 'ssecurity' (https://github.com/penn5/miunlock/issues/3), could this tool work again?

Would it just be a manner of running the snippet provided by @notmarek (either manually, or by incorporating it into the existing codebase), and plugging the result into the rest of the process? Or are there further major roadblocks that hinder this unlocking tool?

penn5 commented 3 years ago

So wait, since the roadblock was that there was no way of obtaining 'ssecurity' (#3), could this tool work again?

Would it just be a manner of running the snippet provided by @notmarek (either manually, or by incorporating it into the existing codebase), and plugging the result into the rest of the process? Or are there further major roadblocks that hinder this unlocking tool?

No idea

Canny1913 commented 2 years ago

I got it working

image

i have no idea how to implement @notmarek's request code,i just pasted it inside a text file and added instructions

(ignore the commit below me please)

https://github.com/Canny1913/miunlock

cxOrz commented 2 years ago

image

Sadly it add more 168h to wait...

Canny1913 commented 2 years ago

image

Sadly it add more 168h to wait...

Oof, you got super unlucky.

villahed94 commented 2 years ago

I tried the script but I got a completely different output mentioning ssecurity and other variables...

And it also outputs this weird response when clicking the link:: image

Canny1913 commented 2 years ago

I tried the script but I got a completely different output mentioning ssecurity and other variables... image

And it also outputs this weird response when clicking the link:: image

You need to copy that response and paste it into the tool.

Also please remove that screenshot as it contains your login token (which can be used to hack your account)

villahed94 commented 2 years ago

image This is the tracelog of the crash after pasting a fresh token, something in the response changed that upsets the function.

Canny1913 commented 2 years ago

image This is the tracelog of the crash after pasting a fresh token, something in the response changed that upsets the function.

Huh, This doesn't happen to me. (just checked it) I'm trying to figure out why it's not working.

Edit:Try using Python 3.9 instead.

villahed94 commented 2 years ago

That seems to have done the trick, however it duped the time , same as with miaochenxi. It marks 337 hours. Something must have changed server-side on Xiaomi. However this is a mild annoyance compared to the stupid 2FA they're asking on the official tool now that never sends the required SMS.

penn5 commented 2 years ago

The hmac issue is a problem with the version of python you're using I guess.

On Tue, 15 Mar 2022, 20:23 Canny1913, @.***> wrote:

[image: image] https://user-images.githubusercontent.com/36257661/158463116-04261ca7-917b-4e22-842e-6ebd94f0d14e.png This is the tracelog of the crash after pasting a fresh token, something in the response changed that upsets the function.

Huh, This doesn't happen to me. (just checked it) I'm trying to figure out why it's not working.

— Reply to this email directly, view it on GitHub https://github.com/penn5/miunlock/pull/4#issuecomment-1068433241, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABKXNQU5H3CADSN7KK5EWALVADWTVANCNFSM4JP6NGJQ . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you were mentioned.Message ID: @.***>

villahed94 commented 2 years ago

Gotta comment that in my case (Redmi Note 10) the "fastboot oem get_token -s (your device serial number)" command kept failing, however I managed to get the token by using "fastboot getvar all" or by using "fastboot getvar token". Should be worth mentioning on the ReadMe about the python version requirement.

Canny1913 commented 2 years ago

Gotta comment that in my case (Redmi Note 10) the "fastboot oem get_token -s (your device serial number)" command kept failing, however I managed to get the token by using "fastboot getvar all" or by using "fastboot getvar token". Should be worth mentioning on the ReadMe about the python version requirement.

Token commands for MTK and Qualcomm are different. (just learned that now) Added it in the code using the worst way but it works now.

That seems to have done the trick, however it duped the time , same as with miaochenxi. It marks 337 hours. Something must have changed server-side on Xiaomi. However this is a mild annoyance compared to the stupid 2FA they're asking on the official tool now that never sends the required SMS.

That is not even the worst. Sometimes when logging in it takes you to the account settings page instead of actually logging in so you can't even use whatever you're using

villahed94 commented 2 years ago

They have noticed the use of python: image

And their stupid tool is still broken as always.

Canny1913 commented 2 years ago

They have noticed the use of python: image

And their stupid tool is still broken as always.

Some people are having this really annoying problem too and they seemed to solve it by using version 5.5.224.24.