Skip to content

Commit

Permalink
personal website done
Browse files Browse the repository at this point in the history
  • Loading branch information
nkalupahana committed May 7, 2024
1 parent 199ed67 commit 8de7c97
Show file tree
Hide file tree
Showing 5 changed files with 13 additions and 9 deletions.
2 changes: 1 addition & 1 deletion _posts/2023-09-09-sekai-scanner.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Here's what the scanner is doing internally:
```rb
post '/' do
input_service = escape_shell_input(params[:service])
hostname, port = input_service.split ':', 2
hostname, port = input_service.split ':', 2
begin
if valid_ip? hostname and valid_port? port
# Service up?
Expand Down
20 changes: 12 additions & 8 deletions _posts/2024-05-06-squ1rrel-personal-website.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
layout: post
current: post
cover: assets/squ1rrel/nisala/personal-website/cover.png
cover: assets/squ1rrel/nisala/personal-website/cover.webp
navigation: True
title: "Personal Website"
date: 2024-05-06 10:00:00
Expand All @@ -11,25 +11,27 @@ subclass: 'post'
author: nisala
---

challenge description
Check out my personal website! I have a blog!

This was the hardest web challenge in the CTF, with only two solves. My favorite part about this challenge is that it kinda "punishes" you for thinking like a CTF player. This challenge doesn't respond well to throwing tools at the problem. Instead, you have to really understand the technology and its shortcomings, and take a methodical approach that's specific to the challenge itself.

## Step 1: Getting our bearings

This challenge has no source, so all we have to go off of is the website, https://blog.squ1rrel.dev.

TODO INSERT PHOTO OF SITE
![Image of the challenge website](/assets/squ1rrel/nisala/personal-website/challenge-site.png)

Let's start by identifying its technologies. Using the chrome extension Wappalyzer, we can see that the site is hosted on Firebase. I'm not entirely sure how this extension is figuring this out, but there are a number of possibilities, from the IP it's connecting to (the primary Firebase load balancer), to the fact that blog.squ1rrel.dev has a CNAME record to a web.app URL (Firebase Hosting's subdomain).
Let's start by identifying its technologies. Using the Chrome extension Wappalyzer, we can see that the site is hosted on Firebase. I'm not entirely sure how the extension is figuring this out, but there are a number of possibilities, from the IP it's connecting to (an easily-identifiable Firebase load balancer), to the fact that blog.squ1rrel.dev has a CNAME record to a web.app URL (Firebase Hosting's subdomain).

We can also see that the challenge very clearly wants us to look at cloud storage. The blog post only has one image, and it's being loaded in from Firebase storage. The blog post also says they have "more in storage". So, let's do that.

TODO INSERT IMAGE
![Storage link in HTML](/assets/squ1rrel/nisala/personal-website/storage.png)

## Step 2: Authentication

There are two layers of authentication in this challenge -- authentication with Firebase as a web app, and authentication with Firebase as a user. Let's start with app authentication.

In order for Firebase to know what app we're referencing, we need to pass it a config, which contains an API key and various access URLs. Thankfully, because this site is hosted on Firebase, that's easy to get. It's always at https://blog.squ1rrel.dev/__/firebase/init.json (among other places in these reserved URLs).
In order for Firebase to know what app we're referencing, we need to pass it a config, which contains an API key and various access URLs. Thankfully, because this site is hosted on Firebase, that's easy to get. It's always at `https://blog.squ1rrel.dev/__/firebase/init.json` (among other places in these reserved URLs).

```js
const firebaseConfig = {
Expand All @@ -51,9 +53,11 @@ const auth = getAuth();
await createUserWithEmailAndPassword(auth, "[email protected]", "password");
```

And we're authenticated!

## Step 3: Storage

And we're fully authenticated! Now, it's time to get our files. Firebase Storage does technically have a way to stop users from enumerating the files in a storage bucket, but most people don't configure it. Instead, they just mark the bucket as "read-only", not realizing that "read" permissions also for some reason include "list" permissions. Thus, we can list the files in this bucket.
Now, it's time to get our files. Firebase Storage does technically have a way to stop users from enumerating the files in a storage bucket, but most people don't configure it. Instead, they just mark the bucket as "read-only", not realizing that "read" permissions also for some reason include "list" permissions. Thus, we can list the files in this bucket.

```js
const storage = getStorage(app);
Expand Down Expand Up @@ -95,4 +99,4 @@ for (let i = 0; i < flag.length; ++i) {

If the `set` fails, that means we guessed the wrong letter and need to try again. But if it succeeds, the letter is correct and we can move onto the next one.

And with that, we have the flag!
And with that, we have the flag! `squ1rrel{fIrebas3_hAs_s0me_interesting_qu1rks}`
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 8de7c97

Please sign in to comment.