Yubico / yubioath-flutter

Yubico Authenticator for Desktop (Windows, macOS and Linux) and Android
https://developers.yubico.com/yubioath-flutter/
Apache License 2.0
1.01k stars 137 forks source link

Support Steam authenticator codes #72

Closed rmenessec closed 8 years ago

rmenessec commented 8 years ago

Support Steam authenticator codes.

A Windows .NET desktop app with open code is available here.

dainnilsson commented 8 years ago

Is the Steam authenticator based on OATH? Is there a specification for it?

rmenessec commented 8 years ago

It appears to be OATH with nonstandard (alphanum instead of num) output. Several other TOTP generators have been adding support for generating the codes. Here's a much more mature one, also open source: https://github.com/winauth/winauth

There is no specification that I'm aware of. Valve have been receiving requests to add proper 2FA (YubiKey, OATH, U2F, Grid, other), support for some time, and ignoring them. Their Android application finally added the ability to generate 2FA codes some months ago. Unfortunately, the Android application is both the "second factor" and also capable of modifying the user's account, making purchases, etc., so it's worse than useless.

The only way I'm aware of to make TOTP generation on phones properly secure is to move the underlying secret onto a YubiKey NEO (which I have).

IOW, I'm asking for help turning Valve's security theatre into real security. I realize this would be easier with proper documentation, but it seems safe to assume that Valve will never provide it. :(

dainnilsson commented 8 years ago

Thanks for providing a bit more background. I took a very quick look at one of those projects, and it does indeed look like a scheme that is based on TOTP, with the only difference being in the end to produce an alphanumeric code. There are two parts required to implement this:

  1. The application needs to know when to use the Steam scheme instead of the standard. This can be solved by using a specific name for the credential, such as "Steam".
  2. There needs to be a way to store a Steam credential in the YubiKey. This requires access to the credential secret which is provided by Steam. Ordinarily this is provided in the form of a QR code or as a base32 encoded string, but the Steam app seems to do the provisioning automatically in the background, and the secret is never shown to the user.

The first point would be a pretty simple addition, but the second one is much more invasive. The process used by the projects you linked to seem to perform a login to Steam via the web interface by scraping the HTML. The user has to solve a captcha as well. This looks quite frail to me and may break if Steam changes their webpage. I'm not very keen on adding support for this into the tool itself.

An alternative would be to implement 1 in the tool, and solve 2 in a different manner. This could be by using one of the other authenticator tools which already support this (assuming you can easily extract the secret from them) or by providing an additional script which performs the "hacky" stuff. As long as you can get the secret, you can manually add the credential using the existing interface.

dainnilsson commented 8 years ago

Correction: It's not scraping the normal web site, it's an actual web API. That makes it a whole lot cleaner, but as it's not a public API it might still not be stable.

rmenessec commented 8 years ago

If you can provide a brief description of the process required, I'm fine with doing the secret extraction by hand, with cURL or similar, if it becomes necessary. ;)

FWIW, (most of) the Valve APIs are probably at least relatively stable; Valve are aware that there are many third-party sites depending on them, of which I use several. For instance, https://isthereanydeal.com/

Thanks so much for looking into this!

dainnilsson commented 8 years ago

I did a quick test using winauth, and it's not that difficult to do (assuming you have access to a Windows computer). Winauth implements all the functionality needed for getting the secret. You simply use the program to add the credential. Once it's added in Winauth, you can export it to a text file, where you'll get a URL containing the secret. This otpauth:// url can be imported into your YubiKey by running the command line program:

yubioath-cli put "otpauth://..."

The URL itself looks something like this:

otpauth://totp/Steam:Steam?secret=REDACTED&digits=5&issuer=Steam&...

The "Steam:Steam" part will be the credential name, so I would suggest changing it to "Steam:myusername" instead. This will give you a credential on your YubiKey which will act as any other TOTP credential, producing a numeric code. Once we've added support for handing Steam credentials (this will probably be based on the name starting with "Steam:"), the application will instead start showing the correct alphanumeric code.

Note: This process also works for the Battle.net authenticator, which uses a standard 8 digit TOTP credential, but with special provisioning (also supported by winauth).

rmenessec commented 8 years ago

I'll see if I can get WinAuth running with WINE.

Failing that--is the Steam API work sufficiently complicated that trying to kludge something together with cURL and shellcode would be a bit of a nightmare? I can always try to get a trial copy of Windows going in a VM if I have to, but something I can reuse from *NIX (or Android) would be great; Valve may decide to re-provision everyone's secrets after their seemingly inevitable next screwup.

If it can be done in shellcode in a couple hours or less, I'd be happy to contribute the code back.

I think I'm also going to go install the Steam app and trawl it to see if they've made the mistake of storing the secret in something easy to parse, like XML or SQLite3, without proper hashing. Nothing in mobile "security" surprises me any more...

Once again, I really want to thank you for looking into this. This will be a huge help.

uberushaximus commented 8 years ago

The keys generated via this OATH string don't seem to match the ones generated by Winauth, and they also fail on the server side, "Steam Guard" tokens have alphabetical characters in addition to numbers.

ghost commented 8 years ago

WinAuth devs are a piece of shit, I created a ticked to add support for Linux since .net is opensource now and they removed it

dagheyman commented 8 years ago

Steam codes are now supported since the 3.0.1 release. They have to be added manually to the key. Please try it out and report any issues you may find.

ghost commented 8 years ago

Works with any Yubikey? Even the cheapest?

dagheyman commented 8 years ago

@ekaris A newer (NEO or 4) key is required to use this feature.

geripgeri commented 8 years ago

Hi! I successfully did it :)

Here is how I did it:

otpauth:\/\/totp\/Steam:Username?secret=SECRET

  • Add a new entry via yubioath-gui, add a nice name for it & paste your secret.
rmenessec commented 8 years ago

@geripgeri : I've never been able to get the Steam support to work before now. I'll try this out later today. Thanks!

EDIT: Confirmed working.

supernovajm commented 7 years ago

@geripgeri Thanks, your instructions were great for finding the secret key. In the end this worked but I used the cli since the (linux) gui doesn't allow me to select a 5-digit code. This is what worked for me

yubioath put "otpauth://totp/Steam:USERNAME?secret=UNIQUE_ID&issuer=Steam&digits=5"

dagheyman commented 7 years ago

@geripgeri

gui doesn't allow me to select a 5-digit code.

Actually a code from a credential prefixed with Steam: will always be 5 characters, but the Add credential view doesn't really inform you about that.

nukeop commented 7 years ago

Is there a way to extract the shared secret without using google infrastructure? I would like to add steam to my yubikey in CCID mode.

rmenessec commented 7 years ago

Is there a way to extract the shared secret without using google infrastructure? I would like to add steam to my yubikey in CCID mode.

Please explain what you mean by "without using Google infrastructure". If you mean "Is there another place to download the Android Steam app?" then sure, but that's seriously offtopic here. However, the answer is: "Yes, there are APK mirrors and APK downloading tools of variable reputation all over the Internet". One of the more trusted mirror sites has a dedicated entry for the app right here.

Instructions for installing Android PacKage files are even more offtopic, and can be found in even more places, all over the Internet.

If that's not what you meant, please explain.

PS: If you meant "can I do it with Apple devices?" I have no idea, but I can tell you that you'll almost certainly have to jailbreak your device, then do a fair amount of other work after that, and that's kind of all over the Internet as well. However, I do know that Apple HATE it when you jailbreak "their" (your) devices, so I can't recommend this. Maybe try using Bluestacks or Genymotion to emulate Android on a real computer, and use that to install the Steam app. Also waaaaaay offtopic.

nukeop commented 7 years ago

I don't want to use either Google or Apple devices, just a regular GNU/Linux system and a web browser. I find the idea of using a device you don't control for anything important baffling, and "jailbreaking" or "rooting" is loathsome.

rmenessec commented 7 years ago

I don't want to use either Google or Apple devices, just a regular GNU/Linux system and a web browser. I find the idea of using a device you don't control for anything important baffling, and "jailbreaking" or "rooting" is loathsome.

I take it you're not aware that there's a native build of Steam for Linux, from Valve.

Let us know how it goes.

EDIT: Or are you asking if there's a build of the Steam mobile client for devices that don't run Android or iOS? First: never heard of one. Second: this was a question for Valve support or a Linux user group. This is a resource for tracking bugs in Yubico's software.

nukeop commented 7 years ago

Yeah, and I want to know what's the procedure for adding the secret key to my Yubikey, since support for it was added explicitly at some point, but there are no official instructions as to how to use it.

rmenessec commented 7 years ago

Yeah, and I want to know what's the procedure for adding the secret key to my Yubikey, since support for it was added explicitly at some point, but there are no official instructions as to how to use it.

Everything you need to know about the Yubico side is explained above. I'll re-summarize:

It's not officially supported. Note the total lack of mentions on the Yubico store, the Yubico product pages, and all the presales and support information I've ever read. (If someone promised you support for Steam: it wasn't me; I don't work for Yubico; and I have no control over what you were told.) Steam is (probably) alone in generating 5-character alphanum OTPs, which I'm reasonably sure isn't part of the OATH standards. If not: okay, they're a tiny minority.

Find some way to get the TOTP secret from one of the Steam mobile apps or from the Steam API referred to above. Once you have the secret, add it the usual way, taking care to call the account "Steam"—optionally "Steam:username", as explained earlier in the bug

Retrieving the TOTP secret depends on fragile Valve APIs... or extracting the secret from a plaintext file on a rooted/jailbroken device running the proprietary Steam mobile app... which is why "how to get the secret" isn't documented, and probably never will be. If they ever start storing the TOTP secret securely, the second option breaks.

If you're not satisfied with the lack of documentation for the Valve-specific knowhow: re-read the entire bug, including links (esp. links to the WinAuth project), experiment, test, and re-test, write the documentation, and feel free to offer it here or anywhere else you think a lot of people would be able to get to it.

nukeop commented 7 years ago

I don't have a Windows computer so I'll have to find out if using WinAuth is possible for me to extract the secret key.

I was under the impression that Steam support is official, since it is included in the tool and it is mentioned in the changelog. If I figure out how to add the secret to yubioath, I will try to open a pull request with an update to the docs.

rmenessec commented 7 years ago

@nukeop, If you'd take the time to read the bug or my summary of it, you'd have seen that there is or was a Steam API (probably HTTP/HTTPS-accessible) for getting the secret. I pointed you at the WinAuth source for a reason.

I don't have infinite time to [re-]clarify and [re-]guide, so I'm muting this thread,

dagheyman commented 7 years ago

@nukeop Just to answer your original question, I'm not aware of any other ways to extract the shared secret from Steam in addition to the methods presented in this thread. Until some more official method appears, the Steam support in this application will probably remain as a "hidden" feature.

rkjnsn commented 6 years ago

It sounds like SteamDesktopAuthenticator might build on Linux, which provides a graphical interface. However, because I'm a glutton for punishment (and happened to be connected to my machine with Mono installed via SSH at the time), I decided to try to use the SteamAuth library directly from the command line. Here are the steps I used:

The first task was to build SteamAuth using Mono:

  1. Download a compiled version of Newtonsoft.Json (needed by SteamAuth) and extract it somewhere. I downloaded Json100r3.zip from https://github.com/JamesNK/Newtonsoft.Json/releases.
  2. Clone https://github.com/geel9/SteamAuth
  3. cd into SteamAuth/SteamAuth
  4. Edit SteamAuth.csproj and change the Newtonsoft.Json reference to point to the one you downloaded. For me it looked like this:
       <Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
         <HintPath>../../Newtonsoft.Json/Bin/net45/Newtonsoft.Json.dll</HintPath>
  5. Build SteamAuth using xbuild SteamAuth.csproj

Then the fun part: getting the shared secret.

First, add and verify a phone number on your steam account if you haven't already. This is required to activate the authenticator.

I used the interactive csharp interface to interact with the library:

$ csharp /r:obj/Debug/SteamAuth.dll /r:../../Newtonsoft.Json/Bin/net45/Newtonsoft.Json.dll
Mono C# Shell, type "help;" for help

Enter statements below.
csharp> var login = new SteamAuth.UserLogin("username","password")
csharp> login.DoLogin()
NeedEmail
csharp> login.EmailCode = "XYZZY" /* Check your e-mail for the code to use. */
csharp> login.DoLogin()
LoginOkay
csharp> var linker = new SteamAuth.AuthenticatorLinker(login.Session)
csharp> linker.AddAuthenticator() /* You should get a text with a confirmation code after this step. */
AwaitingFinalization
csharp> Newtonsoft.Json.JsonConvert.SerializeObject(linker.LinkedAccount)
"JSON string containing secrets, device ids, etc. Store this somewhere safe."
csharp> linker.FinalizeAddAuthenticator("12345") /* Use the SMS code you received above */
Success

Finally, we need to write the code to the Yubikey. In the generated JSON, "shared_secret" holds the necessary key. (The rest contains values needed for other functionality, such as trading confirmation.) shared_secret is in base64, so the first step is to convert it to base32, for which I used python:

$ python
>>> import base64
>>> base64.b32encode(base64.b64decode("base64 encoded secret"))
'base32 encoded secret'

And to write it:

ykman oath uri "otpauth://totp/Steam:my_account?secret=MYBASE32SECRET&issuer=Steam&digits=5
nukeop commented 6 years ago

Amazing, thanks for detailed instructions. I'll try to reproduce your results as soon as I can.

Aymendje commented 6 years ago

Thank you so much @rkjnsn I wasn't feeling like compiling stuff, so I just installed the exe of SteamDesktopAuthenticator, connected and activated the 2FA Then I grabbed the oath url from the maFile (you must install SDA unencrypted) Then weird enough, could not install it with a generated QRcode, but the ykman command works perfectly.

lixo-6c69786f commented 3 years ago

Am i doing something wrong or is the conversion to an alphanumeric 5-digit key currently only working in the cli-version? If not why am i getting the right keys in cli but not in gui? If yes, is this going to be added to the gui version since it would be really useful?

lixo-6c69786f commented 3 years ago

Am i doing something wrong or is the conversion to an alphanumeric 5-digit key currently only working in the cli-version? If not why am i getting the right keys in cli but not in gui? If yes, is this going to be added to the gui version since it would be really useful?

sorry, just found issue #703 ...

fdennis commented 3 years ago

@lixo-6c69786f This will be added to the next release.