Table of Contents
Crypto
Boot2Root
Misc
DDC admin bot
TLDR
- User kaj sends
!verifyme
- Bot sends message in
verification_channel
:f"{user.mention} has requested verification. Moderators with {mod_role.mention}, please verify."
msg = f"{user.mention} has requested verification. Moderators with {mod_role.mention}, please verify."
- User with moderator role reacts with ✅ on message
- Do Exploit
- send spoof message in own discord server
- react to it while having the the role
moderator
- User kaj is assigned role
member
- Read flag in new channel
Writeup
In this challenge we have to exploit a Discord bot. There is an instance of the bot running on the challenge Discord server.
When a user types !verifyme
then the bot sends the message:
msg = f"{user.mention} has requested verification. Moderators with {mod_role.mention}, please verify."
to the "verification channel".
Our goal is to have a user, with the mod_role
, react with to the message sent by the bot.
However we do not have access to this channel nor do we have the mod_role
However, the bot has a vulnerability!
The important part is the check
function in:
try:
# Wait for a moderator to react with the correct emoji
reaction, moderator = await bot.wait_for('reaction_add', check=check)
# Assign the "member" role to the user after verification
member_role = discord.utils.get(guild.roles, name=MEMBER_ROLE_NAME)
if member_role is None:
await ctx.send("Member role not found in the server.")
else:
await user.add_roles(member_role)
await verification_channel.send(
f"{user.mention} has been verified by {moderator.mention} and given the {member_role.name} role."
)
<...>
Notice the conditions:
def check(reaction, reactor):
return (
str(reaction.emoji) == "✅"
and reaction.message.content == msg
and reaction.message.channel.name == VERIFICATION_CHANNEL_NAME
and any([r.name == MODERATOR_ROLE_NAME for r in reactor.roles])
)
Since the constants just are strings:
MODERATOR_ROLE_NAME = "moderator"
MEMBER_ROLE_NAME = "member"
VERIFICATION_CHANNEL_NAME = "verification"
My setup:
- Create a second Discord server (let me denote with
fake server
) - Invite the same "instance" of the Discord bot to the
fake server
using this method: https://ctftime.org/writeup/33674
We want to spoof a message and react to it in our own server.
But first you need some IDs (enable developer mode in Discord)
- Your User ID. (right-click yourself or something)
- Find user with the
moderator
role and get the Role ID (right-click)1293636473291014184
To construct the message:
Send !verifyme
in the fake server to get:
<@USER_ID> has requested verification. Moderators with <@&FAKE_MODERATOR_ROLE_ID>, please verify.
Then replace role id and send in fake server:
<@SMAVL_ID> has requested verification. Moderators with <@&1293636473291014184>, please verify.
then react to the message with ✅, and you should get the member
role in the challenge server
Source code:
#!/bin/python3
import discord
from discord.ext import commands
import os
# Intents setup
intents = discord.Intents.default()
intents.message_content = True
intents.members = True # Required to access member updates and role management
# Bot prefix and intents
bot = commands.Bot(command_prefix="!", intents=intents)
# IDs for roles and channel names
TOKEN = os.getenv('DISCORD_TOKEN')
MODERATOR_ROLE_NAME = "moderator"
MEMBER_ROLE_NAME = "member"
VERIFICATION_CHANNEL_NAME = "verification"
@bot.event
async def on_ready():
print(f'Bot {bot.user.name} has connected to Discord!')
async def get_or_create_verification_channel(guild):
# Look for the verification channel by name
verification_channel = discord.utils.get(guild.text_channels, name=VERIFICATION_CHANNEL_NAME)
# If the channel doesn't exist, create it
if verification_channel is None:
print(f"Verification channel not found. Creating a new one...")
verification_channel = await guild.create_text_channel(
VERIFICATION_CHANNEL_NAME,
topic="Channel for moderator to verify users",
reason="Create verification channel for user verification",
)
print(f"Created verification channel: {verification_channel.name}")
return verification_channel
# Command to request verification
@bot.command(name='verifyme')
async def request_verification(ctx):
user = ctx.author
guild = ctx.guild
# Get the moderator and member roles
mod_role = discord.utils.get(guild.roles, name=MODERATOR_ROLE_NAME)
if mod_role is None:
await ctx.send("Moderator role not found in the server.")
return
# Get or create the verification channel
verification_channel = await get_or_create_verification_channel(guild)
# Notify the user their request has been sent
await ctx.send(f"{user.mention}, your verification request has been sent to the moderators.")
# Send the verification request to the verification channel
msg = f"{user.mention} has requested verification. Moderators with {mod_role.mention}, please verify."
verification_msg = await verification_channel.send(msg)
# Ask moderators to react to verify the user
await verification_msg.add_reaction("✅")
# Create a check function to confirm it's the correct reaction from a moderator
def check(reaction, reactor):
return (
str(reaction.emoji) == "✅"
and reaction.message.content == msg
and reaction.message.channel.name == VERIFICATION_CHANNEL_NAME
and any([r.name == MODERATOR_ROLE_NAME for r in reactor.roles])
)
try:
# Wait for a moderator to react with the correct emoji
reaction, moderator = await bot.wait_for('reaction_add', check=check)
# Assign the "member" role to the user after verification
member_role = discord.utils.get(guild.roles, name=MEMBER_ROLE_NAME)
if member_role is None:
await ctx.send("Member role not found in the server.")
else:
await user.add_roles(member_role)
await verification_channel.send(
f"{user.mention} has been verified by {moderator.mention} and given the {member_role.name} role."
)
except Exception as e:
await verification_channel.send(f"An error occurred during the verification process: {str(e)}")
# Run the bot
bot.run(TOKEN)
To exploit the
smavl id: 103595801464295424 veri msg: <@103595801464295424> has requested verification. Moderators with <@&>, please verify.
true ddc: mod: 1293636473291014184
first !verifyme in ddc_server
then copy the mod id:
1293636473291014184
then add bot to own server and send msg:
<@103595801464295424> has requested verification. Moderators with <@&1293636473291014184>, please verify. then react to it