How to Always Win at skribbl.io

Authorized Entry
5 min readMar 18, 2021

Since using existing tools in unpredictable or unintended ways is arguably a core principle of penetration testing, I decided to test the viability of using Hak5’s USB Rubber Ducky to cheat at skribbl.io.

For those unfamiliar, the USB Rubber Ducky is a USB drive designed to be seen by computers as a keyboard, which can be abused to execute commands on physically accessible computers. And for those unfamiliar with skribbl.io, it is essentially online Pictionary and is a fun group game.

If you’re looking to work with a Rubber Ducky, I highly recommend using this article as a starting guide as I found it very useful when starting this project. The following is my testing process and results.

The genesis of this project was that I thought the USB Rubber Ducky’s ability to imitate a keyboard could be used to submit guesses on skribbl.io faster than someone could type them.

After going through the basics as outlined in this article, I started on the script.

The entire program consisted of 3 basic commands:

  • STRING: this command simply types the text that follows it, i.e. STRING Hello World
  • ENTER: sends the Enter keyboard command
  • DELAY: waits for a set amount of time, in milliseconds
Basic Rubber Ducky Script using the skribbl.io word list
skribbl.io word list

I then copied the script onto a VM and used the encoder to format the basic program into “inject.bin” (java -jar duckencoder.jar -i payload1.txt -o inject.bin), which is the file the Rubber Ducky executes upon being plugged in.

Then I just copied the inject.bin onto the microSD card the Rubber Ducky uses and then reassembled the Rubber Ducky.

Attempt 1:

Alright not a great start, but it makes sense that the application is doing some level of rate-limiting. This first try was with a delay of 250 milliseconds which is one fourth of a second, so obviously much faster than anyone could type.

Attempt 2:

I increased the delay in-between guesses to 1000 milliseconds (1 second).

In an effort to make the testing scenario more realistic, I opened 3 windows to have more than just two players in the game. This attempt was very successful however it is too slow to lead to any reliable winning of skribbl.io games.

Attempt 3:

This attempt was with a delay of 500 milliseconds. I was fairly certain that since I was switching between the 3 windows I had open for the skribbl.io instances, I may have timed it incorrectly and thus two entries were submitted in rapid succession, causing the rate limit to trip.

For my next attempt I wanted to go back to the original 250 millisecond delay in order to determine if having 3 windows open as well as making sure to stay on just one window while the program was running would have any impact on the rate-limiting.

Attempt 4:

At this point 250 ms being too low a delay was a logical conclusion.

Attempt 5:

350 ms did not fair any better unfortunately.

Attempt 6:

Assuming that the round time is set at 180 seconds, which at time of writing is the longest duration that can be set for a given round in skribbl.io, a 500 ms delay only results in 360 guesses while a delay of 400 results in 450 possible guesses. This attempt, with a delay of 450 ms, was also unsuccessful.

Attempt 7:

At first, a delay of 450 ms seemed to be the sweet spot that balances speed while minimizing the likelihood of being kicked. After running a few different rounds it would sometimes time out after 30–45 seconds. One potential explanation of this is if there are multiple metrics being tracked for rate-limiting purposes. Something along the lines of “any more than 100 guesses in a minute OR more than 3 guesses within two seconds”. Based on the behavior I saw while working on this, that seems to likely be the case.

Conclusion:

Unfortunately, after going back and testing the 450 ms delay across several more rounds it would consistently get the guesser kicked for spam around 25–30 seconds into the round. I think the 500 ms delay, while slower than I’d like, seems to be around the fastest guess speed with the lowest rate or likelihood of being kicked for spam. With the default skribbl.io word list consisting of 2,295 potential words, 360 guesses, assuming a 180 round duration, is only ~15.69%.

I considered trying to using a switch statement with the Rubber Ducky, as providing the number of characters in the word would significantly reduce the guess list for any given word, thus reducing the need for speed. At time of writing, that does not appear to be functionality that the USB Rubber Ducky e supports which makes sense given its intended use. I may do this at a later point with a Python script as a more fun way to improve my Python scripting skills, but that’s a tool and article for another day.

I just thought this would be a fun way to learn the basics of Ducky Script, the Rubber Ducky scripting language, and get some hands-on experience working with a USB Rubber Ducky. While this experiment did not turn out as well as I had hoped, it was still fun to work on and interesting to think about.

References:

https://shop.hak5.org/products/usb-rubber-ducky-deluxe

https://github.com/hak5darren/USB-Rubber-Ducky/wiki/Downloads

--

--