Closed rmenessec closed 8 years ago
Is the Steam authenticator based on OATH? Is there a specification for it?
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. :(
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:
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.
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.
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!
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).
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.
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.
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
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.
Works with any Yubikey? Even the cheapest?
@ekaris A newer (NEO or 4) key is required to use this feature.
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.
@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.
@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"
@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.
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.
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.
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 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.
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.
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.
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.
@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,
@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.
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:
<Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>../../Newtonsoft.Json/Bin/net45/Newtonsoft.Json.dll</HintPath>
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
Amazing, thanks for detailed instructions. I'll try to reproduce your results as soon as I can.
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.
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?
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 ...
@lixo-6c69786f This will be added to the next release.
Support Steam authenticator codes.
A Windows .NET desktop app with open code is available here.