Huawei Backup
#1
Hi I found:
https://www.researchgate.net/publication...martphones
and
https://github.com/RealityNet/kobackupdec

and I wonder if anyone here could implement a method simillar to -m 10900 that would crack password for the algorithm described in above article and then implemented in kobackupdec tool.

Basically there is info.xml file for huawei backup that has some hashes inside which then are parsed by kobackupdec (python script)
KEY_SALT in kobackupdec  is first 16 bytes of this pwkey_salt hash from info.xml
KEY NONCE in kobackupdec is last 16 bytes of pwkey_salt hash from info.xml
there is also e_perbackupkey hash in info.xml to get _bkey that is needed to calculate
KEY check expected that should be equal to first 32 bytes of checkMsg hash from info.xml
SALT in kobackupdec is last 32 bytes of checkMsg hash from info.xml

Here is the essential part of kobackupdec script slightly modified:

@staticmethod
    def prf(p, s):
        pdb.set_trace()
        return HMAC.new(p, s, SHA256).digest()

    def crypto_init(self):
        key_salt = self._pwkey_salt[:16]
        logging.debug('KEY_SALT[%s] = %s', len(key_salt),binascii.hexlify(key_salt))

        key = PBKDF2(self._upwd, key_salt, Decryptor.dklen, Decryptor.count, Decryptor.prf)
        logging.debug('KEY[%s] = %s', len(key), binascii.hexlify(key))

        nonce = self._pwkey_salt[16:]
        logging.debug('KEY NONCE[%s] = %s', len(nonce), binascii.hexlify(nonce))

        cipher = AES.new(key, mode=AES.MODE_GCM, nonce=nonce)
        self._bkey = cipher.decrypt(self._e_perbackupkey)[:32]
        logging.debug('self._e_perbackupkey[%s] =  %s', len(self._e_perbackupkey),binascii.hexlify(self._e_perbackupkey))

        logging.debug('[%s] =  %s', len(self._bkey), binascii.hexlify(self._bkey))

        salt = self._checkMsg[32:]
        logging.debug('SALT[%s] = %s', len(salt), binascii.hexlify(salt))

        res = PBKDF2(self._bkey, salt, Decryptor.dklen, Decryptor.count, Decryptor.prf, hmac_hash_module=None)
        logging.debug('KEY check expected = %s', binascii.hexlify(self._checkMsg[:32]))
        logging.debug('RESULT = %s', binascii.hexlify(res))

        if res == self._checkMsg[:32]:
            logging.info('OK, backup key is correct %s' % self._upwd)
            self._good = True
        else:
            logging.error('KO, backup key is wrong %s' % self._upwd)
            self._good = False


The script is covered by license:
# Huawei KoBackup backups decryptor.
#
# Version History
# - 20190729: first public release
#
# Released under MIT License
#
# Copyright (c) 2019 Francesco "dfirfpi" Picasso, Reality Net System Solutions
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
Reply
#2
interesting. is this something used even in modern smartphones (or is this old "encryption" ?). Do modern smartphones use this ? Is this an alternative to the standard android encryption.... can you give more background... would be nice to know how important and current this algorithm is
Reply
#3
This is used by current Huawei Backup application (kobackupdec project on github is quite new). As opposed to standard google backup Huawei Backup allows you to backup not only your apps but also their data. This backup can be created on external USB OTG or directly to PC using Huawei HiSuite program. The encryption method used by this app changes a bit between different versions of Huawei Backup application (called also kobackup). The algorithm mentioned above is the current one. There is a blog article at http://blog.digital-forensics.it/2019/07...yptor.html that can introduce some more details. I can provide you with some samples of info.xml files and modified kobackupdec python script that check if the password for the backup is correct. I was not testing this app on other android phones than Huawei's but it is available in play store and other apk mirror sites.
In current Huawei Backup app the minimum password lenght is 8 characters and has to include letters and digits. In previous versions of this app the user had the option not to provide backup password by that time also the minimum password lenght was 4 characters.
It is preinstalled on all modern Huawei smartphones.
In the latest version of this app it no longer appear as separate app and it is rechable via settings where standard android/google backup is.
Reply
#4
Sorry to push an old post to the front.
Recently I lost my Huawei Backup password and tons of valuable data were lost. The most frustrating thing is that both the phone and the backup data are at my hand but nothing could be done. I contacted Huawei customer support, they could do nothing about this, even though I can provide my huawei account, backup log, phone invoice etc.
After googling and researching, the blog article pawgol mentioned brought me here. Actually during the search, I found many people are suffering from this issue even in 2020, such as:

https://consumer.huawei.com/en/community...Id_124540/
https://consumer.huawei.com/en/community...cId_61112/
https://consumer.huawei.com/en/community...cId_95982/
I believe there's much more in Chinese community.

Really hope hashcat could implement a method for this issue, as for many people today, phone is their primary device for working and data storage.

If needed, I can provide several ecrypted backup files with a factory reseted phone.
Thanks
Reply
#5
if i remember right, (using kobackupdec for quite some time in the past)

the kobackupdec script tests whether your provided pw is valid or not, so you if you have an idea of your pw, you could use hashcat to build a pw-list and edit the script to do a dictionary like attack
Reply
#6
I cannot help much. I just modified the python script to the code provided below. To use it it is necessary to manually obtain:
pwkey_salt
e_perbackupkey
checkMsg

from backup xml file.

In example below the password is mate20pro
Usage example:
$ python3 ./test.py mate20pro
success OK b'mate20pro'

$python3 ./test.py notworkingpassword
error BAD b'notworkingpassword'

You may need to install python3 and some python libraries to run this script.
Using this script you can run through a list of previously generated passwords.
Unfortunately I wasn't able to retrieve my password yet.

Code:
#!/usr/local/opt/python3

import argparse
import binascii
import pdb

from Crypto.Cipher import AES
from Crypto.Hash import SHA256
from Crypto.Hash import HMAC
from Crypto.Protocol.KDF import PBKDF2

parser = argparse.ArgumentParser()
parser.add_argument('password', help='user password for the backup')
args = parser.parse_args()
password = args.password.encode('utf-8')

#mate20pro
pwkey_salt = binascii.unhexlify('efeea84ac48d147eca3a6631e56da4d6c932cf7d1765fea8defdbf1f2235c12b')
e_perbackupkey = binascii.unhexlify('cbf97ca427de57e714e14c6709de190af5acd87333fb2932dfcddbe40c3b91f2de8c366dcfd5843442f6efd288e8a52e')
checkMsg = binascii.unhexlify('ea5abd671a5df174e85b89dca6e69f797c3b381bc95e21d5242908c30d92517acc21e5553be3dc5a1bcc16141e229471cd600e60eaa5fdb483e85f92d1458ead')

count = 5000
dklen = 32

def prf(p, s):
    return HMAC.new(p, s, SHA256).digest()

key_salt = pwkey_salt[:16]
key = PBKDF2(password, key_salt, dklen, count, prf)
nonce = pwkey_salt[16:]
#pdb.set_trace()
bkey = AES.new(key, AES.MODE_GCM, nonce).decrypt(e_perbackupkey)[:32]
salt = checkMsg[32:]
res = PBKDF2(bkey, salt, dklen, count, prf)
if res==checkMsg[:32]:
    print('success OK', password)
else:
    print('error BAD', password)
Reply