Defeating authuld protection on CI+ devices

Here is information about customize your B series firmware..:!:This forum is NOT FOR USER questions or problems but DEVELOPER.
Post Reply

cyberdemon79
Official SamyGO Developer
Posts: 37
Joined: Tue May 04, 2010 10:43 am

Defeating authuld protection on CI+ devices

Post by cyberdemon79 »

Hi there,

I might have found a possibility to circumvent the authuld protection on CI+ devices.

The checking procedure:

- the T2P kernel first ensures the integrity of authuld by calculating it's checksum and comparing
it to a checksum stored on the uboot partition (the easiest way would be to modify authuld and
chance this checksum by i don't know if there are any other checks so I think this would be too
risky).

- after making sure that authuld is authentic, a 4-byte nonce (random number) is generated
by polling Register 0x00090408 by invoking a function named lldSe_ReadReg (doesn't matter).

- the kernel removes the file /dtv/.uk

- this nonce is written to /dtv/.ku and the kernel executes authuld to check the integrity of
the other files (especially exeDSP). It is important to understand that this check takes
some time (this is the delay experienced until authuld reboots the system if it detects
modifications, should be approx 1 minute).

- authuld checks the files and build a string consisting of the nonce+an integer containing
the value 23, then it encrypts this 8-byte-block with something called the mkey.
The resulting 16 byte-block is then written to /dtv/.uk

- after the kernel has launched authuld for checking, it constantly checks for the existance of
/dtv/.uk (which it deleted before starting authuld). The idea here is that authuld writes
the 16-byte-value (as specified above) after it is done checking the files. The kernel
reads this value and compares it to it's own mkey-encrypted nonce+number_23.
If it matches, nothing happens (besides an authuld completed successfully message),
if it doesn't match the kernel tells Micom to shutdown the system (Micom cmd 18).



There is at least one possible flaw in this checking routine:

Remember that it takes authuld quite some time to check the files and respond to the kernel ?
During this period exeDSP gets launched and some other stuff happens (maybe you can even
reach the gamemenu to execute own code, at least the samygo expert autostart script gets
launched within this timeframe).
All we have to do is to create the /dtv/.uk file with the correct contents before authuld does.
Then the kernel will find our file, check it and won't reboot (authuld later overwrites this
file, but that happens after the kernel is satisfied and shouldn't matter).
A program that writes to this file could be launched from exeDSP (modify an early called function
to execute a process) or from an installed samygo autostart script.

A small problem is to create the correct contents of the file. We need to know the current nonce
and the mkey that encrypts data.
The nonce can be read directly from /dtv/.ku (after all this is the way the kernel tells the nonce
to authuld).
The mkey is a little trickier. We have to write a small programm which reads this from the
MackeyPartition:

The main function should look something like this:

Code: Select all

int main(void)
{
        UInt32 outLength;
        unsigned char mkey[16] ;
        char strMackeyPartition[20];
        cmacKey_t cmackey;
        int i=0;
        unsigned char __attribute__ ((aligned(4))) ckey2[32];
        unsigned char __attribute__ ((aligned(4))) mkey2[32];

        switch (getPartSize())
        {
                case 128:
                        printf("kernel flash type : 128 MB\n");
                        strncpy(strMackeyPartition, CMACKEY_PARTITION_128,19);
                        break;
                case 2000:
                        printf("kernel flash type : 2000 MB\n");
                        strncpy(strMackeyPartition, CMACKEY_PARTITION_2000,19);
                        break;
                case 1000:
                        printf("kernel flash type : 1000 MB\n");
                        strncpy(strMackeyPartition, CMACKEY_PARTITION_1000,19);
                        break;
                default:
                        printf("kernel flash type : unknown. default = 1000 MB\n");
                        strncpy(strMackeyPartition, CMACKEY_PARTITION_1000,19);
                        break;
        }

        getcmackey(strMackeyPartition, &cmackey);

        if (0x19790727 == cmackey.magic)
        {
                memcpy(ckey2, cmackey.key,16);
                memcpy(ckey2+16, cmackey.key,16);
                memset(mkey, 0, 16);
                secure_dec((UInt32)ckey2, 32, (UInt32)mkey2, &outLength);
                memcpy(mkey, mkey2+16,16);
        }
        else
        {
                secure_enc((UInt32)cmackey.key, 16, (UInt32)mkey, &outLength);
        }

	printf("your mkey is: ");
	for (int i=0;i<16;i++) printf("%2x ", mkey[i]);
	printf("\n");
}
The missing functions can be found in the kernel sources in the init directory.
The mkey should be relatively constant, so you only need to read it once.

Then put the nonce in an integer, write its 4 bytes in the beginning of a 8 byte buffer,
write the number 23 in an interger and append its 4 bytes to this buffer.
Then call
AES_CMAC(mkey, input_buf, 8, mac);
or
HMAC_Sha1_buf(mkey, input_buf, 8, mac);
(I don't currently know which one gets used (default is AES_CMAC if W_HMAC isn't defined
in the kernel-configuration). Both are defined in the kernel sources, grab them from there.

The resulting 16 byte "mac" is exactly the content of the /dtv/.uk file.

So to break it down, we need to
- read the mkey (once)
- tell samygo autostart script to launch our fake_authuld process (at every boot)
- let the fake_authuld read /dtv/.ku to get the nonce, append the number 23 (as 4-byte integer)
after that, encrypt the resulting 8 bytes with the mkey (using AES or HMAC) and write the
resulting 16 bytes to /dtv/.uk

If see a relatively low risk of bricking the TV.
The reading of the mkey doesn't modify any data, just reads and displays it.
If our fake_authuld writes the wrong value to /dtv/.uk the TV reboots, this could lead to a
rebootloop. But if we tell the samygo script to launch fake_authuld from an attached usb drive,
we could just remove the drive so the fake_authuld won't be started and couldn't write the
wrong value to /dtv/.uk (note that the real authuld will reboot the system anyhow if we
modified exeDSP to launch an autostart script).

A very failproof way would be to manually launch fake_authuld from the game menu if there is
enough time (should be).

Anyone wanna try ;) ?
Last edited by erdem_ua on Fri May 21, 2010 11:07 am, edited 1 time in total.
Reason: Added code tags
User avatar
erdem_ua
SamyGO Admin
Posts: 3126
Joined: Thu Oct 01, 2009 6:02 am
Location: Istanbul, Turkey
Contact:

Re: Defeating authuld protection on CI+ devices

Post by erdem_ua »

This is very detailed analysis and beginning the death of authld (r.i.p.).
Clapping :)
aquadran
Posts: 264
Joined: Fri Oct 16, 2009 9:35 pm
Location: Poland

Re: Defeating authuld protection on CI+ devices

Post by aquadran »

cyberdemon79 wrote:Hi there,

A small problem is to create the correct contents of the file. We need to know the current nonce
and the mkey that encrypts data.
The nonce can be read directly from /dtv/.ku (after all this is the way the kernel tells the nonce
to authuld).
The mkey is a little trickier. We have to write a small programm which reads this from the
MackeyPartition:

The main function should look something like this:

Code: Select all

int main(void)
{
        UInt32 outLength;
        unsigned char mkey[16] ;
        char strMackeyPartition[20];
        cmacKey_t cmackey;
        int i=0;
        unsigned char __attribute__ ((aligned(4))) ckey2[32];
        unsigned char __attribute__ ((aligned(4))) mkey2[32];

        switch (getPartSize())
        {
                case 128:
                        printf("kernel flash type : 128 MB\n");
                        strncpy(strMackeyPartition, CMACKEY_PARTITION_128,19);
                        break;
                case 2000:
                        printf("kernel flash type : 2000 MB\n");
                        strncpy(strMackeyPartition, CMACKEY_PARTITION_2000,19);
                        break;
                case 1000:
                        printf("kernel flash type : 1000 MB\n");
                        strncpy(strMackeyPartition, CMACKEY_PARTITION_1000,19);
                        break;
                default:
                        printf("kernel flash type : unknown. default = 1000 MB\n");
                        strncpy(strMackeyPartition, CMACKEY_PARTITION_1000,19);
                        break;
        }

        getcmackey(strMackeyPartition, &cmackey);

        if (0x19790727 == cmackey.magic)
        {
                memcpy(ckey2, cmackey.key,16);
                memcpy(ckey2+16, cmackey.key,16);
                memset(mkey, 0, 16);
                secure_dec((UInt32)ckey2, 32, (UInt32)mkey2, &outLength);
                memcpy(mkey, mkey2+16,16);
        }
        else
        {
                secure_enc((UInt32)cmackey.key, 16, (UInt32)mkey, &outLength);
        }

	printf("your mkey is: ");
	for (int i=0;i<16;i++) printf("%2x ", mkey[i]);
	printf("\n");
}
?
sure, i can help you in this matter.
aquadran
Posts: 264
Joined: Fri Oct 16, 2009 9:35 pm
Location: Poland

Re: Defeating authuld protection on CI+ devices

Post by aquadran »

there is not CMACKEY_PARTITION partition on CI device
langerhans
Posts: 54
Joined: Sun Jan 10, 2010 3:22 pm

Re: Defeating authuld protection on CI+ devices

Post by langerhans »

Count me in for that project. Got a B550 CI+ device here waiting for modifications :D
Luckily now we have console access on these devices through ex-link. I did some research today and found that the firmware has the wifi-modules inside, maybe it will be possible to get an wifi-stick working on those non-network devices too. That would be great.

If i should test anything please contact me!
cyberdemon79
Official SamyGO Developer
Posts: 37
Joined: Tue May 04, 2010 10:43 am

Re: Defeating authuld protection on CI+ devices

Post by cyberdemon79 »

Hi,

you need the mkey (masterkey) to calculate the correct hash.
The mkey is derived from the cmackey. If the cmackey.magic
is 0x1979... is seems to be a normal boot, if it's not it uses
another function(secure_dec or secure_enc), I think the value
is not equal to 0x1979... if it is the first boot after a firmware
upgrade or something.
The calculation of the mkey is done via secure_enc or secure_dec
(depending on the cmackey.magic), both functions are declared
in the kernel source but call the kernel functions consistent_sync
and virt_to_phys.
As far as I know (could be very well wrong here) I have to call these
functions from kernelspace, so I'm currently trying to compile
a module which will get the cmackey, call secure_dec or
secure_enc and then print the resulting mkey (last 16 bytes of
mkey2 if cmackey.magic is 0x1979...).
If someone could tell me how to cross-compile modules that
would be a great help

cu Cyberdemon
cyberdemon79
Official SamyGO Developer
Posts: 37
Joined: Tue May 04, 2010 10:43 am

Re: Defeating authuld protection on CI+ devices

Post by cyberdemon79 »

Hi,

browsing through the authuld disassembly I found out that it references some key
called the "semaphore key" or "semaphore keyset", as far as I know, semaphores
are used to control concurrent hardware accesses (by blocking them if this resource
is already in use). I think it is possible that authuld somehow locks resources needed
by secure_enc and secure_dec so that only itself could calculate the correct responses.
If this is true, there are several ways around this problem
1) (the risky way) : One could patch authuld directly to dump the used mkey
(dangerous because then the check of authuld fails and we may very well get a reboot loop,
so I'm strongly against it)
2) (the long way) : We can assume that the used mkey is still in memory after authuld
terminated or (better) while it is still running, so trying to dump the whole ram should
give us the key (512*1024*1024 bytes take some time to check but would be possible)
3) patching the kernel in memory (via a module or like the ci+-serial-exlink-enable-way you
found) so that the memcmp which checks the response from authuld compares 0 bytes
instead of 16 (which would yield a positive response and keeps the tv running)
4) figuring out how the semaphorekey is created, try to mimic the commandflow to get
access to the possibly blocked resource and calculate the mkey like we tried in the
first place

2) is the easiest way but may fail due to memory access checks or maybe too time consuming
I think 3) would be the way to go but have no idea for now on how to calculate the correct
address to poke (the command there should be "mov r2, 10", which tells memcmp to check
16 bytes in length).

cu Cyberdemon

Post Reply

Return to “[B] Firmware”