Canary

import { Client, Intents } from 'discord.js'
import axios from 'axios'
import { wrapper } from 'axios-cookiejar-support'
import { Cookie, CookieJar, MemoryCookieStore } from 'tough-cookie'

const APP_HOSTNAME = process.env.APP_HOSTNAME || 'localhost'
const ADMIN_SECRET = process.env.ADMIN_SECRET || 'superSecretCookie'
const DISCORD_TOKEN = process.env.ADMIN_DISCORD_TOKEN!

const client = new Client({
  intents: [Intents.FLAGS.DIRECT_MESSAGES],
  partials: ['CHANNEL']
})

client.on('ready', () => {
  console.log(`Logged in as ${client.user!.tag}!`)
  client.user!.setPresence({
    activities: [{ name: 'DM me' }]
  })
})

client.on('messageCreate', async (message) => {
  if (message.author.bot) return

  if (
    !(
      message.content.startsWith('http://') ||
      message.content.startsWith('https://')
    )
  ) {
    message.channel.send("I'm just a bot. Maybe send me a URL and I'll open it")
    return
  }

  try {
    if (
      message.content.startsWith(`http://${APP_HOSTNAME}`) ||
      message.content.startsWith(`https://${APP_HOSTNAME}`)
    ) {
      message.channel.send("I see you're trying to steal my cookie :rage:")
      return
    }

    message.channel.sendTyping()

    const jar = new CookieJar(
      new MemoryCookieStore(),
      { allowSpecialUseDomain: true }
    )
    const cookie = new Cookie({
      key: 'auth',
      value: ADMIN_SECRET,
      domain: APP_HOSTNAME
    })

    jar.setCookieSync(cookie, `https://${APP_HOSTNAME}`)

    const client = wrapper(axios.create({ jar }))
    const response = await client.get(message.content, { maxRedirects: 0 })

    await message.channel.send(
      `I fetched your URL and got a ${response.status} status code`
    )
  } catch (e) {
    message.channel.send(`:x: \`${e}\``)
  }
})

client.login(DISCORD_TOKEN)

We need to bypass the URL filter:

  try {
    if (
      message.content.startsWith(`http://${APP_HOSTNAME}`) ||
      message.content.startsWith(`https://${APP_HOSTNAME}`)
    ) {
      message.channel.send("I see you're trying to steal my cookie :rage:")
      return
    }

To get the admin cookie:

   jar.setCookieSync(cookie, `https://${APP_HOSTNAME}`)

    const client = wrapper(axios.create({ jar }))
    const response = await client.get(message.content, { maxRedirects: 0 })

    await message.channel.send(
      `I fetched your URL and got a ${response.status} status code`
    )
  } catch (e) {
    message.channel.send(`:x: \`${e}\``)

And Enter to the /flag and take the flag.

server.get(
  '/flag',
  async (request, reply) => {
    if (request.headers.cookie !== undefined) {
      const cookies = parseCookies(request.headers.cookie)
      if (cookies.auth === ADMIN_SECRET) {
        await reply.send(FLAG)
        return
      }
    }

Create a Canary with Canary Bot.

We can add user@ before the URL to simulate user:password to the request and bypass the filter.

We didn´t receive any warnings, so we can verifiy if the auth cookie was sent.

auth:d5692713322d63c8627ce39151943b82

After create the cookie, we can access to /flag!

buckeye{d0ma1n_m4tch1ng_1s_c4s5_1ns3nsit1v3}

Last updated