Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

posts/2023-01-18/ #45

Open
utterances-bot opened this issue Jan 18, 2023 · 7 comments
Open

posts/2023-01-18/ #45

utterances-bot opened this issue Jan 18, 2023 · 7 comments

Comments

@utterances-bot
Copy link

Breaking EA Desktop's pathetic Encryption | erri120's random Blog

EA made a sad attempt to prevent me from reading their files. I’ll explain how I went about breaking their encryption.

https://erri120.github.io/posts/2023-01-18/

Copy link

Awesome write-up, very interesting learning material (on how to not encrypt stuff), thanks!

One question remains, though: Why bother encrypt this information in the first place?

Most likely to keep third-party tools like yours away from it to lock up the system I guess 🤣

Copy link

mdulin2 commented Jan 19, 2023

Hey! Good write up! Really enjoyed the technical details of this. Always love good reverse engineering stories.

To me, the encryption is more about obfuscation than anything else. If you have full control of the machine and do the decryption on the file locally, then of course it can be decrypted; this is what the code is designed to do. You said this took 4 days to do, right? This would stop a lot of people in their tracks, which is probably the goal of EA.

What would you suggest EA did instead to make this secure? I don't have a good suggestion, since the data needs to be decrypted locally anyway. Even if you pushed this operation to the EA server, you could collect the data used to make the request and simply make it from your application.

Copy link

@mdulin2 But considering the data stored in the file there is nothing that would need obfuscation. And the fact that it breaks when you install new hardware is a big red flag and shows no QA process before the update to the EA APP was pushed.

Copy link
Owner

erri120 commented Jan 20, 2023

@daniel-kun

One question remains, though: Why bother encrypt this information in the first place?

@mdulin2

To me, the encryption is more about obfuscation than anything else. If you have full control of the machine and do the decryption on the file locally, then of course it can be decrypted; this is what the code is designed to do. You said this took 4 days to do, right? This would stop a lot of people in their tracks, which is probably the goal of EA.

What would you suggest EA did instead to make this secure? I don't have a good suggestion, since the data needs to be decrypted locally anyway. Even if you pushed this operation to the EA server, you could collect the data used to make the request and simply make it from your application.

As someone who maintains a library that needs the file, I'm obviously very biased and say that this should not be encrypted or even obfuscated. The plaintext I posted is unaltered, I did not remove any sensitive information or redacted anything because it doesn't contain anything outside some installation information.

What baffles me is the fact that they chose to encrypt this file on purpose. As I've mentioned in the post, an earlier version of EA Desktop saved the plaintext version of this as IS.json. Someone had to change the code.

Although I hate EA with a passion, I want to give the devs the benefit of the doubt and say that they likely just used a utility function for cleaner code:

unknown1.SaveToFile("CATS");
unknown2.SaveToFile("IQ");
installState.SaveToFile("IS");

I didn't talk about the CATS and IQ files, because they are irrelevant. However, they might contain sensitive data. While debugging, I found out that all of these files go through the same generic functions. This suggests that they have some common wrapper function for saving these files. This leads me to believe, that the devs encrypted IS.json as IS because every other file in the same folder was also encrypted.

To summarize: every other file in the same folder is encrypted and might contain sensitive information. Even if the IS file doesn't contain anything special, the devs likely just used the same function to encrypt this file, as they have with the other files. Even if this post reaches them somehow, and they find out someone broke their encryption, I doubt they will change anything. At best, they will just write the plaintext version of this one file, and leave the others encrypted. Once again, I don't know what is in the other files.

Update: yeah, so I decrypted the other files, and they also just contain installation related information. Nothing special whatsoever. I've updated the post to reflect my new findings.

Repository owner deleted a comment from klove010705 Mar 17, 2023
Copy link

I must be one of the few people out there who share the exact same problem with you so I can't thank you enough for putting the research to solve all of this mess.
I write a game manager called Lutris that is exclusively for Linux. We've had an Origin integration for a while but time has come to replace it with an EA App one...
With the manifests gone, I was wondering if there was a way to detect installed games from the contents of ProgramData/EA Desktop/InstallData. I couldn't find a way to match "base-Origin.SFT.50.0000189" with Battlefield Hardline but while searching for the string, I did find your post!
Now, it seems that EABackgroundService.exe has changed quite a bit since the writing of this post but I was still able to find the functions I wanted using Ghidra.
I think the last piece I'm missing is a way to verify the hardware information string I'm generating. While I have figured out where the function calling sha1 is, I haven't managed to trigger it by downloading games on EA... Maybe I should try with a fresh install of EA App to force the regeneration of the ID file...
I also noticed that the code in "HashSomething" function was more complex than the one presented here so I'm hoping didn't change anything related to the encryption.
I feel very close to having a working implementation for Lutris but this whole thing is also a bit outside of my domain so any pointers would be helpful!

@erri120
Copy link
Owner

erri120 commented Jun 17, 2023

I must be one of the few people out there who share the exact same problem with you so I can't thank you enough for putting the research to solve all of this mess. I write a game manager called Lutris that is exclusively for Linux. We've had an Origin integration for a while but time has come to replace it with an EA App one... With the manifests gone, I was wondering if there was a way to detect installed games from the contents of ProgramData/EA Desktop/InstallData. I couldn't find a way to match "base-Origin.SFT.50.0000189" with Battlefield Hardline but while searching for the string, I did find your post! Now, it seems that EABackgroundService.exe has changed quite a bit since the writing of this post but I was still able to find the functions I wanted using Ghidra. I think the last piece I'm missing is a way to verify the hardware information string I'm generating. While I have figured out where the function calling sha1 is, I haven't managed to trigger it by downloading games on EA... Maybe I should try with a fresh install of EA App to force the regeneration of the ID file... I also noticed that the code in "HashSomething" function was more complex than the one presented here so I'm hoping didn't change anything related to the encryption. I feel very close to having a working implementation for Lutris but this whole thing is also a bit outside of my domain so any pointers would be helpful!

I've been trying to figure out how to generate the hardware hash on Linux for a while. You can find my progress at erri120/GameFinder#71, and I believe it's not really feasible to generate the hash by reading normal Linux system files. The easiest and most reliable solution appears to be running a command inside the Wine prefix that contains the EA Desktop installation.

I'm not sure if they updated their encryption algorithm, erri120/GameFinder#74 is about the only issue reported so far regarding this.

Anyways, I've been running Linux for about 4 months at this point, so I don't really have access to all my debugging and reverse engineering tools anymore (aside from Ghidra) and debugging inside a Wine prefix is just a pain.

@strycore
Copy link

That's great to hear and I think we can share our progress at this point and get this to work.

I was finally able to double check the hardware info generated key, but it turns out result doesn't decrypt my IS file...

Screenshot from 2023-06-17 13-35-39

I was able to use x64dbg in Wine without issue, and attaching the EABackgroundService process before the IS file was generated is the solution I was looking for.

As for the hardware info, I found that wmic was working without issue, with the only component left being the drive C: serial.

This can be accessed manually by opening winecfg, in the drives tab opening the advanced property of the C: drive. To access it programmatically, it's possible to use a program like this:

#include <windows.h>
#include <iostream>

int main()
{
    DWORD serial=0;
    GetVolumeInformation(
        "C:\\",nullptr,0,&serial,nullptr,nullptr,nullptr,0
    );
    std::cout << std::hex << serial << '\n';
    return 0;
}

Which can be built on Linux with i686-w64-mingw32-c++ -o GetFSSerial.exe -O3 win_fs_id.cpp -mconsole and can be executed once the dlls from /usr/i686-w64-mingw32/sys-root/mingw/bin are copied to the Wine prefix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants