dCTF 2021: Discord PingPong
Investigating a Go Discord bot binary and recovering the path to the challenge flag.
Original challenge writeup: Discord PingPong.md
This one was annoying to set up.
Running the executable printed:
Successfully connected to Discord API
Last message in #general is: Welcome to our secret server! Only trusted bots and users have access to the secret channels. Our secret plans have been moved from here to a secret channel.
Bot is now running. Press CTRL-C to exit.
Sending anything through stdin did not seem to do anything.
Running file on the binary showed:
discordbot: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, Go BuildID=_ZEAdEO-wvSQGBQYhkGM/xFUNbqa5yDNs4HrN4WQF/IfIgpWbUNMnt11lPcn7W/sNa0sC3hsaXC9dymZEeD, not stripped
So, Go.
A quick search for a Go Discord bot led me to discordgo:
https://github.com/bwmarrin/discordgo
That repository has a ping-pong example:
https://github.com/bwmarrin/discordgo/blob/master/examples/pingpong/main.go
It also matched this string from the binary:
Bot is now running. Press CTRL-C to exit.
That was useful for identifying what I was looking at, but not much else. Arguments passed to the bot were ignored.
Intended solution
The intended solve was apparently much simpler: run strings on the discordbot file, extract the Discord API token, join or query the secret Discord server, and get the flag from the secret channel.
How I worked it out
I had already tried strings, but the output was huge and manually sifting through it would have been painful.
I knew that Go's net/http library respects proxy environment variables by default. So I launched Burp, set the HTTP and HTTPS proxy environment variables in my terminal to 127.0.0.1:8080, and added the Burp Suite CA certificate to /usr/local/share/ca-certificates.
Helpful links:
- How do you add a certificate authority CA to Ubuntu?
- How to program Go to use a proxy when using a custom transport
After that, the bot's requests showed up in Burp. From there, I could run the discordbot, grab the token, and retrieve the flag from one of the channels using the Discord API.
I did not take screenshots, and setting it all up again was enough of a pain that I am leaving it there.