How I Found a Bug in a Twitch Streamer’s Open-Source Overlay
At some of my free time, I usually go around Twitch to watch live streams, mainly proper IRL streams which abides to the Twitch ToS or programming streams, instead of gaming streams. One of my favourite streamers is JeffDev, who I’ve followed and have been watching since the 4th of May 2017. He’s a Unity C# indie game developer working on a Rust-like survival game. He’s a pretty friendly and chill guy so I’d totally recommend you to watch his stream if you’re into that sort of stuff.
Anyway, about the topic, he makes his own bots and overlays for the stream. The bots are named Bottweiler and BottweilerJr, in which you can tell which one is newer and which one is about to deprecate (spoiler: Jr is the newer version). He has released part of the source code that made up BottweilerJr in his GitHub respository for other streamers to implement and use, including scripts for a slot machine overlay (shown on the upper right corner of his stream).
There’s a pretty well-known privilege escalation vulnerability with his Bottweiler in his community. Some of us, being his loyal viewers, like to mess around with his commands to find bugs, sometimes as a joke. There’s a !challenge <username>
command in his Bottweiler which allows you to challenge another viewer in the chat. If the viewer you challenged !accept
the challenge, the bot will randomly pick one as the winner. The winner earns XP while the loser loses XP, simple. However, there isn’t any validation done on the <username> input, whether or not the username is in the proper format, have invalid symbols nor is the viewer online in the chat. What made this command exploitable is the fact that if the possibly-non-existent user didn’t !accept
the challenge within 3 minutes, the Bottweiler will print the following in chat:
<username> didn't accept the fight... Either because he didn't have enough currency or he declined.
Since the user-controlled input is at the front of the message, and both the Bottweiler and BottweilerJr are set to moderators, I can execute commands with it with a moderator privilege. However, there’s some drawbacks. Firstly, there will be a lot of additional ‘junk’ messages at the back of the command. Secondly, you can’t have a space in <username>
, or else it would just pick the first word. For example, if you wrote !challenge /ban NRockhouse
, the input will only be parsed as /ban
, and thus the command executed after three minutes would be /ban didn't accept the...
. What about other moderator commands which doesn’t need any parameters?
As you can see, when I tried executing a command along with the additional ‘junk’ text at the back, the command isn’t executed but instead the correct usage of the command along with the command’s function is being output. The /me
command works as intended, and while /disconnect
accepts the additional ‘junk’ text at the back, there’s no obvious permanent effect on the bot, it appears that it can reconnect back to the chat on it’s own.
Some time after Jeff, the streamer, released the partial source code of his BottweilerJr on GitHub publicly, I took a quick look to find anything fun that I can mess with on stream. I started looking for bugs in his slot machine overlay, but to no avail. Then, I looked outside the folder, and found a mysterious unused feature laying around then I have never seen being used on stream. The command was !caster and it was a command for giving shoutouts. I didn’t really dive deep to how it works at that time so I just went back onto the stream (I did the above while watching his stream) and wrote !caster
and then !caster @NRockhouse
. Nothing. Nothing happened. Except Jeff joked on stream that there won’t be any bugs with that command. I wonder if it’s disabled, since this command is a separate plugin that can be enabled and disabled in the bot. I looked in the source code again and found if(twitch.user.mod)
in line 61, which means only mods can use that command. Combining that with the privilege escalation bug above, !challenge !caster
is used. Three minutes later, …
Awesome! Looks like I am the first one to be able to find a bug in Jeff’s overlay. When Bottweiler sent out that message that contains the command, BottweilerJr thought that it’s a legitimate moderator that used the command, so the shoutout action is executed. Since the !caster
command takes only the first word as well and remove the first character (due to the ‘@’ in @username
when you tagged a user), the input from !caster didn't accept the fight...
would be idn't
, thus that is the “channel” that got the shoutout. You don’t always have to spend money to play racist jokes just to toy with a streamer, right? The next day, he streamed Destiny 2 and I stopped by his stream for a while as well and tried to use the same command again. But then, …
Oh well, it was fun while it lasted. He didn’t push the new updated code on his GitHub repository so I wouldn’t know how the patch was implemented, but then, we don’t always need the source code just to find bugs in a program, so we’re just gonna keep fuzzing his commands until we find something new again. 😛
Of course, this isn’t really a “vulnerability” that’s worth anything, but I’m just showing a fun way that you can use pentesting knowledge on other things besides typical web apps or computer softwares. Many thanks to JeffDev for being such a chill guy and letting us mess around with his hard work projects, be sure to stop by his channel if you’d like to give programming streams a try, I’d most probably be there.