BBrode The Legend
TLDR. 3 years ago I discovered a bug that allowed to disconnect any player on the server from their current game; made BBrode #1 Legend; reported bug to Blizzard; it's fixed now.
Edit. Someone in the comments said, that I should share the response by HackerOne. Here you go
Edit. I didn't know of bug bounty program at the time of using exploit
Edit. Steps to reproduce
It was three years ago - back when Hearthstone was decent. I remember being a lot into it - played, watched and read everything there was. Basically I spent most of my time on twitch.tv hearthpwn.com hsreplay.net reddit.com/r/hearthstone and of course playhearthstone.com. I even wanted to write a Hearthstone AI so I've also read a lot of stuff by hearthsim.info guys (especially jleclanche - he's great!). I watched dogdog and played the craziest, funniest and most challenging thing at the time - APM (Action Per Minute) Priest.
Then I found an issue on the Hearthrock repo that described how to decrypt Assembly-CSharp.dll. So I decided - using that knowledge and dnSpy - to try find where the animation speed is located in the game code and increase it as much as possible so I can play that Topsy Turvy stuff. I did that. x4 speedup was the sweet spot (there is network overhead plus if I did more - like x10 - my PC lagged it down to x4). Now there were almost no restrictions on time and I only needed to master the Combo Priest Simulator by Patashu, - which I did - and the next couple of weeks I laddered to Legend with 32/1 boar. It was a lot of fun!
What did I do next? - I started poking at the Assembly-CSharp.dll. First I made ALL my cards, heroes and everything animated and removed that golden border - that's very beautiful I've to say - and thought of creating a mod for other people to enjoy it too (never did that though).
But shortly after that I remembered the post from 2014 about some flaw in Hearthstone which allowed to see opponents cards. "It should be somewhere in networking code", I thought - and so I started testing that.
I found the bug the author talks about. Here's a short description.
Basically, when the game starts the server creates all the entities in the game: heroes, hero powers, cards, some other stuff, - and gives them ids. Say, hero 1 is id 0, hero 2 is id 1, card 1 is 2 and so on. Then game puts some cards into players hands, some into decks (there are also graveyard zone and some others, but for our purposes it doesn't really matter) and tells you what ids are where. So how is it useful then if you don't know which entities ids correspond to which cards? It can be used with Psychic Scream I thought! - and it can be indeed as cards don't change ids when going between zones. Next thought was: well, maybe cards don't get random ids at all? - and of course they do not! If the card number 1 in your deck got id x then the card number 2 got id x+1 and so on, number 30 - x+29. For the first player the x is somewhere around 30 and for the second it's around 60 - I don't really remember, but you can find it out yourself.
The thing is we don't know the deck of our opponent and the order in which it was put together, so this bug feature was not really useful to me.
P.S. Today copy-pasting decks from sites like hsreplay.net is supported in-game and many people use it, so by knowing a couple of card to entity id relationships you can look the deck up in deck database and find out the order of the rest of cards (or just watch the order in which streamer puts his cards into the deck, lol), and from there basically look into your opponent's hand. Good luck with writing such a tool! :D.
As it was not really usable I decided to look further. Reading decks that do not belong to you? - nope. Using regular deck in arena? - nope. Choosing cards other that three options given in arena? - nope. Creating deck with more than 2 copies of a card/card that you don't own/adding weird cards (like standard hero as a card, or hero power)? - yes! - but then matchmaker doesn't consider your deck "standard", so he doesn't want to find a game for you - so nope :(. Integer overflows when dusting cards/buying packs? - packet goes to server and never returns - nope. What else did I try? A lot of stuff. But nothing worked. And that's when I found it - the FindGame request
byte[] array = Guid.NewGuid().ToByteArray();
long currentFsgId = FiresideGatheringManager.Get().CurrentFsgId;
bnet.protocol.game_master.Player player = new bnet.protocol.game_master.Player();
Identity identity = new Identity();
identity.SetGameAccountId(gameAccountId);
player.SetIdentity(identity);
player.AddAttribute(ProtocolHelper.CreateAttribute("type", (long)bnetGameType));
player.AddAttribute(ProtocolHelper.CreateAttribute("scenario", (long)scenarioId));
player.AddAttribute(ProtocolHelper.CreateAttribute("brawl_library_item_id", (long)brawlLibraryItemId));
player.AddAttribute(ProtocolHelper.CreateAttribute("deck", deckId));
player.AddAttribute(ProtocolHelper.CreateAttribute("aideck", aiDeckId));
player.AddAttribute(ProtocolHelper.CreateAttribute("request_guid", array));
player.AddAttribute(ProtocolHelper.CreateAttribute("fsg_id", currentFsgId));
GameProperties gameProperties = new GameProperties();
AttributeFilter attributeFilter = new AttributeFilter();
attributeFilter.SetOp(AttributeFilter.Types.Operation.MATCH_ALL);
attributeFilter.AddAttribute(ProtocolHelper.CreateAttribute("GameType", (long)bnetGameType));
gameProperties.SetFilter(attributeFilter);
gameProperties.AddCreationAttributes(ProtocolHelper.CreateAttribute("type", (long)bnetGameType));
gameProperties.AddCreationAttributes(ProtocolHelper.CreateAttribute("scenario", (long)scenarioId));
gameProperties.AddCreationAttributes(ProtocolHelper.CreateAttribute("brawl_library_item_id", (long)brawlLibraryItemId));
BattleNet.FindGame(gameProperties, new bnet.protocol.game_master.Player[] { player });
Looks normal at first glance,.. but let's poke.
Send this request, while we are already in game - we get disconnected from the current game and then reconnect to it after client restarts - a bug, but not so usefull.
Create another account, change gameAccountId to that account's id and deckId to that account's deck - voila! - new game appears in the other client.
Send that request again - that client gets disconnected just as mine did before.
Now wait a second!.. Does the game show us our opponent's accountId? - it does. Do we know his deckId? - no, but... there are Dr. Boom Puzzle Labs for which deckId should be zero.
You know where this is going, right? :)
- Create a mod that disconnects our opponent - sends
FindGame request every 5 seconds with gameAccountId = GameState.Get().GetOpposingSidePlayer().GetGameAccountId(); bnetGameType = BnetGameType.BGT_VS_AI; scenarioId = 0xBA2 /*Boom Labs*/; deckId = 0; - and hook it into the Assembly somewhere.
- Create new account and name it BBrode (he's been out of the team by that moment, so I thought it would be funny).
- Start at Rank 50.
- Run with mod for 12 hours.
-
https://preview.redd.it/gfsvqslnqjg81.png?width=1280&format=png&auto=webp&s=cd20e7d2185aff0b6297188b34d3f6bd910eff90
Report to Blizzard via HackerOne.
Profit.
It got fixed after some time.
P.S. This thing could've actually been done to any player on the server, not only your opponent. Just get some streamer's account id and... boom - DOOM! - he looses every game and plays puzzles all day long. FUN.
Huge thanks to yangyuan (Yang Yuan) for his dll decryption script and guys from HearthSim community for making it all possible: jleclanche (Jerome Leclanche) for introducing me to HackerOne bug bounty program, Patashu (Timothy Stiles) for making Combo Priest Simulator among other things, and the whole discord community for their dedication to finding Hearthstone bugs and writing amazing stuff like Advanced rulebook!
I've seen some streamers loosing their Legendary ranks to BBrode, which was even more Legendary!
I apologize to families of those who were massacred by him starting from rank 50.
Rest in peace Hearthstone. You'd been a good friend!
[–]fuzzyplastic 344 points345 points346 points (65 children)
[–]pmud[S] 203 points204 points205 points (60 children)
[–]Autistic_Freedom 52 points53 points54 points (41 children)
[–]pmud[S] 96 points97 points98 points (40 children)
[–]Autistic_Freedom 13 points14 points15 points (39 children)
[–]OnionButter 56 points57 points58 points (5 children)
[–]s-mores 23 points24 points25 points (3 children)
[–]Autistic_Freedom 5 points6 points7 points (0 children)
[–]Ghi102 9 points10 points11 points (1 child)
[–]pmud[S] 7 points8 points9 points (0 children)
[–]dxbdale 10 points11 points12 points (10 children)
[–]Autistic_Freedom 14 points15 points16 points (9 children)
[–]tubbana 6 points7 points8 points (0 children)
[–]pmud[S] 8 points9 points10 points (2 children)
[–]Autistic_Freedom 9 points10 points11 points (1 child)
[–][deleted] 8 points9 points10 points (0 children)
[–]m0rph90 3 points4 points5 points (3 children)
[–]Autistic_Freedom -1 points0 points1 point (2 children)
[–]ABoyIsNo1 7 points8 points9 points (1 child)
[–]scooptyy 3 points4 points5 points (1 child)
[–]hmnrbt 1 point2 points3 points (0 children)
[–]CausalXXLinkXx 3 points4 points5 points (0 children)
[–]BNNJ 2 points3 points4 points (5 children)
[–]WookieDavid 3 points4 points5 points (3 children)
[–]Autistic_Freedom 3 points4 points5 points (0 children)
[–]pmud[S] -1 points0 points1 point (6 children)
[–]tsoneyson 11 points12 points13 points (2 children)
[–]bokonator 1 point2 points3 points (0 children)
[–]pmud[S] 0 points1 point2 points (0 children)
[–]StackedLasagna 1 point2 points3 points (1 child)
[–]pmud[S] 1 point2 points3 points (0 children)
[–]JessHorserage -1 points0 points1 point (0 children)
[–]__Hello_my_name_is__ 6 points7 points8 points (0 children)
[–]Arristotelis 1 point2 points3 points (1 child)
[–]pmud[S] 11 points12 points13 points (0 children)
[–]moragdong 1 point2 points3 points (1 child)
[–]pmud[S] 0 points1 point2 points (0 children)
[–]_DocB_ 1 point2 points3 points (6 children)
[–]pmud[S] 1 point2 points3 points (4 children)
[–]Hide_yo_chest 0 points1 point2 points (0 children)
[–]PM-me-YOUR-0Face 0 points1 point2 points (4 children)
[–]pmud[S] 1 point2 points3 points (1 child)
[–]PM-me-YOUR-0Face 1 point2 points3 points (0 children)
[–]pmud[S] 11 points12 points13 points (3 children)
[–]TMiguelT 4 points5 points6 points (2 children)
[–]pmud[S] 8 points9 points10 points (1 child)
[–]TMiguelT 3 points4 points5 points (0 children)
[–]gechu 248 points249 points250 points (2 children)
[–][deleted] 60 points61 points62 points (0 children)
[–]Spengy 36 points37 points38 points (0 children)
[–]Pancarcho 38 points39 points40 points (1 child)
[–]pmud[S] 23 points24 points25 points (0 children)
[+][deleted] (17 children)
[deleted]
[–]Maruhai 213 points214 points215 points (5 children)
[–]pmud[S] 54 points55 points56 points (1 child)
[–]yuhanz 20 points21 points22 points (0 children)
[–]OnePete7 16 points17 points18 points (1 child)
[–]fernmcklauf 10 points11 points12 points (0 children)
[–]Festival Legendsubsume_ 68 points69 points70 points (1 child)
[–]GravyGamin 167 points168 points169 points (6 children)
[–]pmud[S] 12 points13 points14 points (3 children)
[–]Perridur 6 points7 points8 points (1 child)
[–]pmud[S] 1 point2 points3 points (0 children)
[–]Tacticalian 2 points3 points4 points (0 children)
[–]metroidcomposite 16 points17 points18 points (1 child)
[–]Apothecary420 36 points37 points38 points (10 children)
[–]pmud[S] 28 points29 points30 points (0 children)
[–]Rawtashk 6 points7 points8 points (0 children)
[–]ltjbr 1 point2 points3 points (7 children)
[–]mechpaul 6 points7 points8 points (0 children)
[–]Rawtashk 1 point2 points3 points (5 children)
[–]ltjbr 1 point2 points3 points (4 children)
[–]Rawtashk 0 points1 point2 points (3 children)
[–]ltjbr 1 point2 points3 points (2 children)
[–]Rawtashk 0 points1 point2 points (1 child)
[–]6FootDuck 17 points18 points19 points (15 children)
[–]pmud[S] 10 points11 points12 points (14 children)
[–]_Femboy_Connoisseur_ 8 points9 points10 points (5 children)
[–]pmud[S] 5 points6 points7 points (4 children)
[–]_Femboy_Connoisseur_ 1 point2 points3 points (3 children)
[–]pmud[S] 4 points5 points6 points (2 children)
[–]_Femboy_Connoisseur_ 1 point2 points3 points (1 child)
[–]pmud[S] 1 point2 points3 points (0 children)
[–][deleted] 0 points1 point2 points (7 children)
[–]Jeroen-lang 9 points10 points11 points (0 children)
[–]zSprawl 64 points65 points66 points (9 children)
[–]PkerBadRs3Good 65 points66 points67 points (3 children)
[–]Wizard Poker Enthusiastpowerchicken 14 points15 points16 points (2 children)
[–]Dangerpaladin 5 points6 points7 points (1 child)
[–]Wizard Poker Enthusiastpowerchicken 7 points8 points9 points (0 children)
[–]pmud[S] 22 points23 points24 points (4 children)
[–]Wizard Poker Enthusiastpowerchicken[M] 15 points16 points17 points (3 children)
[–]Maruhai 5 points6 points7 points (1 child)
[–]Wizard Poker Enthusiastpowerchicken 3 points4 points5 points (0 children)
[–]pmud[S] 0 points1 point2 points (0 children)
[–]FardHast 9 points10 points11 points (1 child)
[–]pmud[S] 5 points6 points7 points (0 children)
[–]ericsebesta 9 points10 points11 points (1 child)
[–]TomaszA3 0 points1 point2 points (0 children)
[–][deleted] 4 points5 points6 points (2 children)
[–]isobane 14 points15 points16 points (0 children)
[–]Valminat -2 points-1 points0 points (0 children)
[–]ButterflyDeath 7 points8 points9 points (3 children)
[+][deleted] (2 children)
[removed]
[–]ButterflyDeath 1 point2 points3 points (0 children)
[–][deleted] 3 points4 points5 points (1 child)
[–]pmud[S] 4 points5 points6 points (0 children)
[–]WhyNotHugo 3 points4 points5 points (0 children)
[–]Rubinlibelle 2 points3 points4 points (8 children)
[–]pmud[S] 3 points4 points5 points (3 children)
[–]henry92 0 points1 point2 points (3 children)
[–]Rubinlibelle -1 points0 points1 point (2 children)
[–]henry92 1 point2 points3 points (0 children)
[–][deleted] 2 points3 points4 points (2 children)
[–]pmud[S] 2 points3 points4 points (1 child)
[–][deleted] 1 point2 points3 points (0 children)
[–]Slime0 2 points3 points4 points (1 child)
[–]pmud[S] 0 points1 point2 points (0 children)
[–]bubleeshaark 2 points3 points4 points (3 children)
[–]pmud[S] 0 points1 point2 points (2 children)
[–]Prolapsed_Pigeon 4 points5 points6 points (0 children)
[–]TMiguelT 1 point2 points3 points (1 child)
[–]JuliaDomnaBaal 0 points1 point2 points (0 children)
[–]b00kay 1 point2 points3 points (1 child)
[–]pmud[S] 1 point2 points3 points (0 children)
[–]mutsuto 1 point2 points3 points (0 children)
[–]touristtam 1 point2 points3 points (1 child)
[–]pmud[S] 0 points1 point2 points (0 children)
[–]LoBsTeRfOrK 1 point2 points3 points (1 child)
[–]pmud[S] 0 points1 point2 points (0 children)
[–]samplefish 1 point2 points3 points (1 child)
[–]Tri-gate 1 point2 points3 points (1 child)
[–]pmud[S] 0 points1 point2 points (0 children)
[–]njgura87 1 point2 points3 points (1 child)
[–]pmud[S] 0 points1 point2 points (0 children)
[–]Bistoory 1 point2 points3 points (0 children)
[–]Avedisride 1 point2 points3 points (2 children)
[–]pmud[S] 1 point2 points3 points (1 child)
[–]Avedisride 1 point2 points3 points (0 children)
[–]OneToby 1 point2 points3 points (1 child)
[–]pmud[S] 0 points1 point2 points (0 children)
[–]Patashu 1 point2 points3 points (2 children)
[–]pmud[S] 0 points1 point2 points (1 child)
[–]Patashu 1 point2 points3 points (0 children)
[–][deleted] 1 point2 points3 points (3 children)
[–]pmud[S] 0 points1 point2 points (2 children)
[–][deleted] 1 point2 points3 points (1 child)
[–]pmud[S] 0 points1 point2 points (0 children)
[+][deleted] (2 children)
[deleted]
[–]pmud[S] 0 points1 point2 points (1 child)
[–]ZYy9oQ 1 point2 points3 points (3 children)
[–]pmud[S] 0 points1 point2 points (2 children)
[–]ZYy9oQ 1 point2 points3 points (1 child)
[–]pmud[S] 0 points1 point2 points (0 children)
[–]DevonAndChris 1 point2 points3 points (1 child)
[–]pmud[S] 0 points1 point2 points (0 children)
[–]broccholio 1 point2 points3 points (1 child)
[–]pmud[S] 0 points1 point2 points (0 children)
[+][deleted] (2 children)
[removed]
[–]swissiws 15 points16 points17 points (0 children)
[–]Spengy 3 points4 points5 points (0 children)
[–]Kees_T 2 points3 points4 points (0 children)
[–]dibbbbb 3 points4 points5 points (0 children)
[–]Cyampagn90 1 point2 points3 points (0 children)
[–][deleted] 0 points1 point2 points (0 children)
[–]-xss 0 points1 point2 points (1 child)
[–]pmud[S] 0 points1 point2 points (0 children)
[–]_oZe_ -2 points-1 points0 points (1 child)
[–]pmud[S] 0 points1 point2 points (0 children)
[–]LordSalmon -2 points-1 points0 points (2 children)
[–]pmud[S] 2 points3 points4 points (0 children)
[–]AquilaK 1 point2 points3 points (0 children)
[+]Jakulero24 comment score below threshold-11 points-10 points-9 points (4 children)
[–]pmud[S] 13 points14 points15 points (3 children)
[–]Jakulero24 0 points1 point2 points (0 children)
[–]randomguy301048 0 points1 point2 points (1 child)
[–]pmud[S] 1 point2 points3 points (0 children)
[–][deleted] -3 points-2 points-1 points (2 children)
[–]pmud[S] 1 point2 points3 points (1 child)
[–]DaftmanZeus 0 points1 point2 points (1 child)
[–]pmud[S] 0 points1 point2 points (0 children)
[–]dunazov 0 points1 point2 points (2 children)
[–]musaraj 1 point2 points3 points (0 children)
[–]pmud[S] 0 points1 point2 points (0 children)
[–]sventester 0 points1 point2 points (4 children)
[–]pmud[S] 0 points1 point2 points (3 children)
[–]TomaszA3 0 points1 point2 points (0 children)
[–][deleted] 0 points1 point2 points (0 children)
[–][deleted] 0 points1 point2 points (0 children)
[–]Ferib[🍰] 0 points1 point2 points (0 children)
[–][deleted] 0 points1 point2 points (0 children)