Level 5 - PALINDROME'S Invitation
Domain(s): OSINT, Misc
Last updated
Domain(s): OSINT, Misc
Last updated
Valuable intel suggests that PALINDROME has established a secret online chat room for their members to discuss on plans to invade Singapore's cyber space. One of their junior developers accidentally left a repository public, but he was quick enough to remove all the commit history, only leaving some non-classified files behind. One might be able to just dig out some secrets of PALINDROME and get invited to their secret chat room...who knows? Start here: https://github.com/palindrome-wow/PALINDROME-PORTAL
We are given a link to a public GitHub repository that only contains a GitHub Actions workflow file.
The workflow file is shown below.
The workflow runs when an issue is closed, and it uses the wget
command to make a request to the PORTAL_URL with the PORTAL_PASSWORD secrets.
Let's take a look at the Actions workflows that have already been run to see if we could find these variables in the logs.
From the logs, we can see that the Portal URL is http://chals.tisc23.ctf.sg:45938 and the Portal Password is :dIcH:..uU9gp1%3C@%3C3Q%22DBM5F%3C)64S%3C(01tF(Jj%25ATV@$Gl
.
URL decode the password (:dIcH:..uU9gp1<@<3Q"DBM5F<)64S<(01tF(Jj%ATV@$Gl
)and submit it on the web application. The application generates a Discord server invite URL and what seems to be a Base64-encoded string.
First, join the Discord server.
However, we seem to lack all privileges in this server.
The Base64 string (MTEyNTk4MjE2NjM3MTc5NDk5NQ.GVBKnK.QlrWaL9QAaz1QlnIfrv1-y28eTWblHCBh72oT4
) included with the invite URL seems to be a Discord bot token. This could mean we are expected to perform some kind of Privilege Escalation on the server.
Let's write a Python script to enumerate our Bot's permissions on the server. The server ID is 1130166064710426674. We create an on_ready()
handler that runs when the bot instance is initialized, querying all roles in the server and their corresponding permission values.
We can see that our permission value is 66688. This means that the bot can View Channels, View Audit Log, and Read Message History.
Let's try reading messages in the server. We first retrieve all channels and loop through them to retrieve their message history.
Here, we can see 3 text channels, general, meeting-records and flag. The only channel we are able to read from is meeting-records, where we see a message or thread meeting 05072023
.
Let's try enumerating all threads in the server, we find 1 that matches from before.
Now, we can try joining the thread and reading the messages. This code will write all messages to the file meeting 05072023.txt
.
The messages read:
There is a reference to the client_id 1076936873106231447 which refers to the BetterInvites Discord bot that allows users to attach Roles to Invite URLs, and to the permission number "66688".
From this list, we have already used our "View Channels" and "Read Message History" permissions, but not the "View Audit Log" one. This permission allows users to view a log of administrative operations carried out on the server.
With this information, we can list the audit logs with the Discord API, filtering logs with the action_type
value of 40 for "create invite link".
We can use the first invite code in the log entries to craft a discord invite URL.
And joining the server again with this URL gives us access to the flag channel.
Flag: TISC{H4ppY_B1rThD4y_4nY4!}