Project Ideas

1. Playlist maker based on music's emotion

Perform Emotional Analysis on music in a playlist and create a new playlist based on the emotions of the songs. or reorder the songs in the playlist based on the emotions of the songs.

Relevant Paper

Have not even started work on it

2. Ascii Doc lexer and writer which is compatible with the Asciidoctor

Self Explanatory

Currently working on it

Rascii

3. Music Player Daemon, with integrated support for Notifications

Self Explanatory

Haven't even started

4. Operating System for risc V architecture

Self Explanatory

Basically on hold

Rascii

5. A concise proc macro for generating everything a CRUD App might need

It must have permissions, import, export, frontend component generation

Working on it locally, not in a state to be built

Software

General pieces of advice for me

  • Exercising regularly really does help.
  • Use bash for scripts when the script will run less than 10 times in a lifetime.
  • Use python for scripts when you want to be able to edit them.
  • Use PlatformIO for embedded development, unless there is no mature rust HAL for a MCU.
  • Prefer wgpu over platform specific APIs for graphics programming.
  • Always benchmark stuff when optimizing, no exception.
  • Try to avoid web development if you can, its hell incarnate.
  • After some testing, Music actually slows you down, unless you are doing something that requires no thinking.
  • For downloading music,
yt-dlp -x --embed-subs --embed-metadata --embed-thumbnail --add-metadata "https://youtube.com/playlist?list=PLNPkZsUXzlEjvQemMGAnBifR4yNFO4dpb" -N 8 -I -1:-10:-1 --parse-metadata ":(?P<meta_synopsis>)"

More detailed info

2D Rendering

  • Denote an image with a single array and a pixel's index can be found by width * y + x.
  • The x coordinate is i % width, y is i / width.
  • To get a point at a distance r and angle t, relative to point (x0, y0)
  • For drawing a simple primitive, use its derivative to get the next pixel, usually the derivative is simpler
  • Ok, Fk, This stuff is sub optimal, since it kinda encourages drawing vertically, which is not optimal for the cache.

Line

  • A line's equation is

or, where

  • When drawing line, a simple for (x in x0..x1) usually leaves gaps if , and for (y in y0..y1) leaves gaps when , use both with if cases.
  • Use when when drawing lines to avoid division.

Circle

  • A circle's equation is

or,

  • Its not worth doing the derivative for a circle, just use the equation.
  • A circle can be drawn by only finding 1/8th of it, and mirroring it to the other 7 parts.

Ellipse

  • An ellipse's equation is

or,

  • Its not worth doing the derivative for a circle, just use the equation.
  • An ellipse can be drawn by only finding 1/4th of it, and mirroring it to the other 3 parts.

Rotated Rectangle

  • Find the points of upper line and the corresponding point at the bottom part at the same x coordinate.
  • Draw a vertical line between these two points.
  • Bam, you have a rotated rectangle.

Electronics chapter

General words of caution

  • Isolate the grounds of power and signal circuitry
  • Prototype a PCB before ordering it.
  • Make soldered connections before changing anything else.
  • Check code before changing circuitry.

Component sellers

PCB Manufacturing

Quirks of devices

Quirks

NodeMCU

DATASHEET PINOUT

  • NodeMCU is a development board that uses the ESP8266 chip, packaged as a ESP-12E module.
  • The NodeMCU Board maps the ESP 12E's pins to custom pins named as DX pins.

To Program

  • Using the Arduino IDE.

    1. Install the ESP8266 board package.
    2. Select the board as NodeMCU 1.0 (ESP-12E Module).
    3. Code like you would for an Arduino.

    NOTE: The pin numbers in the code are the DX pin numbers, not the GPIO numbers. So, D8 GPIO8.

  • Using platformio.

    • PlatformIO has native support for it, go look at the website.

Quirks

  • Most boards use CP2102 Serial to USB converter, so if on windows, download it's driver, and if on linux, gentoo in particular, compile that in.
  • One may think that the NodeMCU shouldn't be powered by more than 3.3V, but it can be powered by 5V.
  • However, you can't have the signal be 5V, as the ESP8266 is a 3.3V device. You can fry GPIOs like this.
  • It also has an upper current limit of 12mA per GPIO pin, that's not much.
  • Don't connect it directly to relays, have an optocoupler.
  • Sudden current demand spikes can also crash it.
  • Remember to regularly yield() when taking up a core for too long, otherwise it will crash.
  • Default Baud rate for errors is 76800.
  • D3 is mapped to GPIO0, D4 is mapped to GPIO2, D8 is mapped to GPIO15
  • GPIO0, GPIO2 and GPIO15 determine the boot mode, so if you are unable to upload code to it, check whether the states of these pins is in the correct state at early boot.
  • GPIO15 also acts as chip select for SPI.
GPIO0 (D3)GPIO2 (D4)GPIO15 (D8)
UART (aka. When you can upload code to it)LOWHIGHLOW
Flash Boot (aka. When code runs)HIGHHIGHLOW
  • You can pull down a pin by attaching a high value resistor to a ground.
  • You can pull up a pin by attaching a high value resistor to a VCC.
  • If there is literally no response from the nodeMCU, check the EN pin and the RST Pin, both of these should be high and not fluctuating.
  • Serial.print sends data to both USB and the RX, TX pins on board, if using them for something, make sure you are printing only relevant stuff.
  • The antenna sucks a little, may dire wiring the antenna manually, some people have reported success, haven't verified personally.
  • SPI can be finicky, when a connection is broken, it needs to be reset. My current solution is to just reset SPI and begin a new connection everytime data needs to be sent.
  • In particular, MFRC522 module fks with it, sending it to a different boot mode if you connect it's pins to the ones specified above without care.

RC522 RFID Reader

I am referring to the complete module, not just the chip.

If you have metal behind the reader OR the tag, it won't be able to read it.

To mitigate, get a piece of dielectric material, like ferrite and put that between the tag and metal, that is actually how the commercial solution is made.

The better solution is to just buy the metal tags, they are more expensive, but they work better with metal.

Just know this before starting your project.

It fking SUCKS, but is the cheapest, you can get it as low as 50 rupees.

Actually, MFRC522 is the name of the chip, but also commonly refers to the cheap board it is commonly found on.

Somehow the IRQ pin is not supported by the most popular library for reading rfid tags using it for arduino, idk how, that is just how it is.

It alternates between having a tag and not having a tag when sending the command to read a tag, Ping multiple times to get the actual result.

If the boot mode of NodeMCU is wrong, this fker is probably the culprit.

Also, buy in bulk, these things are fragile AF, and can randomly stop working if voltage is not to their liking. Could be dirty DC, could be slightly more voltage, could be slightly less voltage.

These don't have any VRMs or filtering caps, so make sure power is good.

Sometimes you may need to do a SPI Reset, in my experience, even when i had soldered the connections, at this point, i can't figure out why, may be the mfrc522 chip crashes for some reason. Just do a SPI reset regularly.

CTF Section

This section will contain the writeups for the CTF I have participated in.

ACECTF Writeups

ACECTF was a CTF hosted at acectf.tech in 2025. I participated with team name Cat4Ever

Broken Secrets

You’ve found a suspicious file, but it seems broken and cannot be opened normally. Your goal is to uncover its secrets.

Submit your answer in the following format: ACECTF{3x4mpl3_fl4g}

Attachments: file named brokenfr

Solution

The obvious first step, ran file on it and got the following output:

brokenfr: 7-zip archive data, version 0.4

So, it's a 7z archive. Renamed it to brokenfr.7z and extracted it, out came the following file tree:

.
├── Brokenfr.7z
└── _
    ├── [Content_Types].xml
    ├── _rels
    ├── docProps
    │   ├── app.xml
    │   └── core.xml
    └── word
        ├── _rels
        │   └── document.xml.rels
        ├── document.xml
        ├── fontTable.xml
        ├── media
        │   └── not_so_suspicious_file
        ├── settings.xml
        ├── styles.xml
        ├── theme
        │   └── theme1.xml
        └── webSettings.xml

8 directories, 13 files

Ran straight to the not_so_suspicious_file, and ran file on it:

not_so_suspicious_file: data

So it needed a little more digging, opened it in nvim, just for checking it.

not_so_sus_neovim

Saw the IHDR and IDAT, figured it was some form of corrupted PNG

ran :%!xxd to convert it to hex, and saw the following:

on the top of the file, it seems to be missing the PNG magic bytes

00000000: 122e d4a7 0d0a 1a0a 0000 000d 4948 4452  ............IHDR
00000010: 0000 015e 0000 00c8 0800 0000 0085 08d6  ...^............
00000020: 2c00 0000 0467 414d 4100 00b1 8f0b fc61  ,....gAMA......a
00000030: 0500 0000 2063 4852 4d00 007a 2600 0080  .... cHRM..z&...

Copied the section from a working png to here, as follows:

00000000: 8950 4e47 0d0a 1a0a 0000 000d 4948 4452  .PNG........IHDR
00000010: 0000 015e 0000 00c8 0800 0000 0085 08d6  ...^............
00000020: 2c00 0000 0467 414d 4100 00b1 8f0b fc61  ,....gAMA......a
00000030: 0500 0000 2063 4852 4d00 007a 2600 0080  .... cHRM..z&...

renamed the file to not_so_suspicious_file.png and opened it:

not_so_suspicious_file.png

ACECTF{h34dr_15_k3y}

Another Reading between the Lines?

Question: Is this another one of those hidden in plain sight typical normie challenges? Answer: No.

This challenge is very simple, here you have a file named hidden and all you need to do is get the flag. My focus for this year's CTF is not just the beginning but also ending on a high note, I won't rely on overused "read between the line" challenges and would rather have you guys do some research.

Good Luck!

Attachment: hidden

Solution

Ran file on the attachment

hidden: ASCII text, with CRLF, LF line terminators

Seems to be an ASCII file with mixed line terminators.

Luckily, neovim immediately gave away what this was

Neovim reveals all

Those ^M are what we were looking for, DOS Line endings in a Unix file.

00000000: 0a0d 0a0a 0a0a 0a0a 0d0a 0a0d 0a0a 0a0a  ................
00000010: 0a0d 0a0d 0a0a 0d0a 0a0a 0a0d 0a0a 0d0a  ................
00000020: 0a0d 0a0a 0a0a 0a0d 0a0d 0a0a 0d0a 0a0d  ................
00000030: 0a0a 0d0a 0a0a 0a0d 0a0a 0a0a 0d0a 0d0a  ................
00000040: 0a0a 0d0a 0d0a 0d0a 0d0a 0a0d 0a0d 0a0a  ................
00000050: 0d0a 0d0a 0a0d 0a0d 0a0d 0a0a 0a0a 0d0a  ................
00000060: 0d0a 0a0a 0a0a 0a0d 0a0a 0d0a 0d0a 0d0a  ................
00000070: 0d0a 0d0a 0a0d 0a0d 0a0d 0a0a 0a0d 0a0a  ................
00000080: 0a0a 0d0a 0d0a 0a0a 0d0a 0d0a 0a0a 0d0a  ................
00000090: 0d0a 0a0d 0a0a 0a0a 0d0a 0d0a 0a0a 0d0a  ................

A simple script to treat 0a as 0 and 0a0d as 1

#!/usr/bin/env python3

file = open("hidden", "rb")

output = open("line.bin", "wb")

content = file.read()

content = content.replace(b"\r\n", (1).to_bytes(1, byteorder="big"))
content = content.replace(b"\n", (0).to_bytes(1, byteorder="big"))
chunk_size = 8
content = [content[i:i+chunk_size] for i in range(0, len(content), chunk_size)]

for byte_str in content:
    current_byte = 0

    for byte_char in byte_str:
        current_byte = current_byte << 1
        current_byte = current_byte | byte_char

    output.write(current_byte.to_bytes(1, byteorder="big"))

this gave the output:

ACECTF{n0_r34d1n6_be7w33n_7h3_l1n35}

Significance of Reversing

Over the years, we hackers have been reversing stuff, thinking we understand how everything works and feel good about it. But, sometimes it feels like do we really understand what reversing means in mordern days? Anyways, here's a PNG, let's see if you can reverse your way out of this one.

Attachment: Reverseme.png

Solution

Downloaded the image and tried to open it, but imv came up with nothing, So as standard procedure, i opened it in neovim and found the following:

Start Middle-ish End

Reversed strings which looked like dynamically linked library paths, and the FLE at the end which was ELF reversed gave it away

This was a reversed ELF executable

A simple script for reversing it and we were golden

file = open("Reverseme.png", "rb")

data = file.read()

data = data[::-1]

data = data[1:]

file.close()

bin = open("Forward.elf", "wb")

bin.write(data)

bin.close()

Running the Forward.elf gave us:

Decrypted string: ACECTF{w3_74lk_4b0u7_r3v3r53}

The Chemistry Of Code

During a discussion with hackers, one idea stuck: every hacker must be able to understand code, no matter how cryptic.

Hidden within obfuscated Rust code is a function that holds the flag. But it only unlocks when you reverse its logic and uncover the correct username and password.

Do you have what it takes to decode this tangled masterpiece? Dive into the chemistry of code and prove your skills.

Hint: Some secrets are worth their salt.

use base64::{engine::general_purpose::STANDARD, Engine};
use hex::encode as hex_encode;
use num_bigint::BigUint;
use std::io::{self, Write};

const FERROUS_OXIDE_USERNAME: &str = "AdminFeroxide";
const ANIONIC_PASSWORD: &str = "NjQzMzcyNzUzNTM3MzE2Njc5MzE2ZTM2";
const ALKALINE_SECRET: &str = "4143454354467B34707072336E373163335F3634322C28010D3461302C392E";

fn ionic_bond(cation_input: &str, anion_input: &str) {
    let cation_hex = hex_encode(cation_input);
    let anion_hex = hex_encode(anion_input);

    let cation_value = BigUint::parse_bytes(cation_hex.as_bytes(), 16).unwrap();
    let anion_value = BigUint::parse_bytes(anion_hex.as_bytes(), 16).unwrap();

    let covalent_link = &cation_value ^ &anion_value;

    let alkaline_secret_value = BigUint::parse_bytes(ALKALINE_SECRET.as_bytes(), 16).unwrap();
    let metallic_alloy = &covalent_link ^ &alkaline_secret_value;

    let precipitate = format!("{:x}", metallic_alloy);

    let alloy_compound = (0..precipitate.len())
        .step_by(2)
        .map(|i| u8::from_str_radix(&precipitate[i..i + 2], 16).unwrap() as char)
        .collect::<String>();

    println!("Crystallized Flag (ASCII): {}", alloy_compound);
}

fn reaction_chamber() {
    let mut username = String::new();
    print!("Introduce the Catalyst: ");
    io::stdout().flush().unwrap();
    io::stdin().read_line(&mut username).unwrap();
    let username = username.trim();

    let mut password = String::new();
    print!("Introduce the Reagent: ");
    io::stdout().flush().unwrap();
    io::stdin().read_line(&mut password).unwrap();
    let password = password.trim();
    
    if username != FERROUS_OXIDE_USERNAME {
        println!("Reaction denied: Unstable molecule detected.");
        return;
    }
    
    let reagent_ion = STANDARD.encode(hex_encode(password).as_bytes());
    if reagent_ion != ANIONIC_PASSWORD {
        println!("Reaction denied: Unstable molecule detected.");
        return;
    }

    ionic_bond(username, password);
}

fn main() {
    reaction_chamber();
}

Solution

Overall, one of the easier ones, reaction_chamber acts as the main function.

The program does the following:

  • Read the username from stdin as a line
  • Read the password from stdin as a line
  • Early returns if username is not equal to AdminFeroxide
  • Encodes the password as follows:
    • Consider the password as raw bytes and encode that as hex
    • Encode the result of previous step as base64
  • Early returns if the encoded password is not equal to the constant ANIONIC_PASSWORD
  • Proceeds to print the flag

So, to get the correct password, we need to reverse the encoding process.

We decode the ANIONIC_PASSWORD from base64 and get

643372753537316679316e36

Decoding this as hex, we get

d3ru571fy1n6

Inputting this as the password, we get:

Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.01s
Running `target/debug/chemistryofcode`

Introduce the Catalyst: AdminFeroxide
Introduce the Reagent: d3ru571fy1n6
Crystallized Flag (ASCII): ACECTF{4ppr3n71c3_w4l73r_wh1t3}

ACECTF{4ppr3n71c3_w4l73r_wh1t3}

DONOTOPEN

A suspicious script file seems to be hiding something important, but it refuses to cooperate. It's obfuscated, tampered with, and demands a password. Unravel the mystery to uncover the hidden flag.

Attachment: DONTOPEN

Solution

The top of the script looks something like this:


#!/bin/bash

TMP_DIR=$(mktemp -d)
PYTHON_SCRIPT="$TMP_DIR/embedded_script.py"
CHECKSUM_FILE="$TMP_DIR/checksum.txt"

EXPECTED_CHECKSUM="g5c533c0e5e1dd82051e9ee6109144b6" 

ARCHIVE_START=$(awk '/^__ARCHIVE_BELOW__/ {print NR + 1; exit 0; }' "$0")
tail -n +$ARCHIVE_START "$0" | gzip -d > "$PYTHON_SCRIPT"


CALCULATED_CHECKSUM=$(md5sum "$PYTHON_SCRIPT" | awk '{ print $1 }')


if [ "$CALCULATED_CHECKSUM" != "$EXPECTED_CHECKSUM" ]; then
  echo "Checksum mismatch! The embedded script may have been corrupted."
  echo "Doesnt match with the MD5 checksum - a3c533c0e5e1dd82051e9ee6109144b6"
  rm -rf "$TMP_DIR"
  exit 1
fi


python3 "$PYTHON_SCRIPT"


rm -rf "$TMP_DIR"
exit 0

__ARCHIVE_BELOW__
# Apparently bytes for an archive

Apparently, this script does the following:

  • Create a temporary dir
  • Extract the archive at the end of this script into the temporary file
  • Check if the checksum of the python script inside of the archive is as the expected checksum
    • if not, wipe the temp directory and exit
    • else, run the python file

When we first ran this script, we got the following:

Checksum mismatch! The embedded script may have been corrupted.
Doesnt match with the MD5 checksum - a3c533c0e5e1dd82051e9ee6109144b6

The easiest solution to this was just removing the checksum check, while doing that, i also ended up echo' the temp directory's location and removing the rm -rf "$TMP_DIR"` to simplify inspection

#!/bin/bash

TMP_DIR=$(mktemp -d)
PYTHON_SCRIPT="<span class="katex"><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10903em;">TM</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3283em;"><span style="top:-2.55em;margin-left:-0.1389em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.02778em;">D</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord mathnormal" style="margin-right:0.07847em;">I</span><span class="mord mathnormal" style="margin-right:0.00773em;">R</span><span class="mord">/</span><span class="mord mathnormal">e</span><span class="mord mathnormal">mb</span><span class="mord mathnormal">e</span><span class="mord mathnormal">dd</span><span class="mord mathnormal">e</span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.1514em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">s</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord mathnormal" style="margin-right:0.02778em;">cr</span><span class="mord mathnormal">i</span><span class="mord mathnormal">pt</span><span class="mord">.</span><span class="mord mathnormal">p</span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mord">&quot;</span><span class="mord mathnormal">A</span><span class="mord mathnormal" style="margin-right:0.07153em;">RC</span><span class="mord mathnormal" style="margin-right:0.08125em;">H</span><span class="mord mathnormal" style="margin-right:0.07847em;">I</span><span class="mord mathnormal" style="margin-right:0.22222em;">V</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.05764em;">E</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3283em;"><span style="top:-2.55em;margin-left:-0.0576em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord mathnormal" style="margin-right:0.13889em;">T</span><span class="mord mathnormal">A</span><span class="mord mathnormal" style="margin-right:0.13889em;">RT</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span></span></span></span>(awk '/^__ARCHIVE_BELOW__/ {print NR + 1; exit 0; }' "<span class="katex"><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">0&quot;</span><span class="mclose">)</span><span class="mord mathnormal">t</span><span class="mord mathnormal">ai</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6667em;vertical-align:-0.0833em;"></span><span class="mord mathnormal">n</span><span class="mord">+</span></span></span></span>ARCHIVE_START "<span class="katex"><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">0&quot;∣</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal" style="margin-right:0.04398em;">z</span><span class="mord mathnormal">i</span><span class="mord mathnormal">p</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.7335em;vertical-align:-0.0391em;"></span><span class="mord mathnormal">d</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">&gt;</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord">&quot;</span></span></span></span>PYTHON_SCRIPT"
echo <span class="katex"><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8889em;vertical-align:-0.1944em;"></span><span class="mord mathnormal" style="margin-right:0.10903em;">TM</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3283em;"><span style="top:-2.55em;margin-left:-0.1389em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.02778em;">D</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord mathnormal" style="margin-right:0.07847em;">I</span><span class="mord mathnormal">Rp</span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mord mathnormal">t</span><span class="mord mathnormal">h</span><span class="mord mathnormal">o</span><span class="mord mathnormal">n</span><span class="mord">3&quot;</span></span></span></span>PYTHON_SCRIPT"

exit 0

Running this script, we get the following output:

/tmp/tmp.1bSIP4aSd9
It looks like the box is locked with some kind of password, determine the pin to open the box!
What is the pin code?

It also opened https://vipsace.org/ for some reason

Going into the tmp directory, /tmp/tmp.1bSIP4aSd9 in this case, we find

.
└── embedded_script.py

1 directory, 1 file

A single python script, embedded_script.py.

import hashlib
import requests
import webbrowser  
NOT_THE_FLAG = "flag{this-is-not-the-droid-youre-looking-for}"
# Bunch of lines with flag0 - flag999
FLAG_PREFIX = "ACE{%s}"

print("It looks like the box is locked with some kind of password, determine the pin to open the box!")
req = requests.get("http://google.com")
req.raise_for_status()

pin = input("What is the pin code?")
if pin == "ACE@SE7EN":
    print("Looks good to me...")
    print("I guess I'll generate a flag")

    req = requests.get("http://example.com")
    req.raise_for_status()

    print(FLAG_PREFIX % hashlib.blake2b((pin + "Vansh").encode("utf-8")).hexdigest()[:32])
else:
    print("Bad pin!") 

After removing the network requests, and entering the pin ACE@SE7EN, we get:

It looks like the box is locked with some kind of password, determine the pin to open the box!
What is the pin code?ACE@SE7EN
Looks good to me...
I guess I'll generate a flag
ACE{e2e3619b630b3be9de762910fd58dba7}

ACE{e2e3619b630b3be9de762910fd58dba7}

For some reason this one doesn't follow the general flag pattern of the CTF

Pipher - Piano Cipher

Back in my school days, we were required to pick a "Leisure Time Activity" as part of the curriculum. Four days a week, we had to attend those classes and learn whatever we chose. I opted for the piano—or more specifically, the keyboard.

From junior school through high school, I gradually improved. Over time, I moved beyond simply memorizing notes and developed the ability to judge sounds and map notes instinctively, even when hearing a song for the first time. When I discovered this skill, it felt incredible.

But this joy was short-lived. My musical journey ended when I entered high school, as academics took precedence. Later, I pursued my bachelor's degree far from home, leaving my piano behind. It's a decision I've often regretted. Now, all I have are fond, fleeting memories of those starry-eyed days as a kid.

In honor of that time, I've created a cipher called the Pipher. There's a bug in it, though—every 6th character of the plaintext leaks. So, yeah, it’s still a work in progress.

Attachment: File named cipher.txt containing:

Ciphertext - DC# DD# DF DD# EC '70' G#B CE F#C FC# C#C# '104' C#A FC# F#A# C#A C#A '108' CF AF# C#C FC# CE '102' FC# C#A# FC# GA# CE '112' FC# C#B C#C# C#A# GC '125'

Solution

Having only rudimentary knowledge about music theory, I just assumed that notes represented numbers and started from there,

After a bit of googling around, i stumbled upon an image explaining piano scales

From here, i just wrote a script which mapped the above cipher text into integers based on this and then to chars, strung them together and that was that:

#!/usr/bin/env python3

input = "DC# DD# DF DD# EC '70' G#B CE F#C FC# C#C# '104' C#A FC# F#A# C#A C#A '108' CF AF# C#C FC# CE '102' FC# C#A# FC# GA# CE '112' FC# C#B C#C# C#A# GC '125'"

map = ["A", "A#", "B", "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#"]

output = []

print(len(input.split()))

for char in input.split():
    current = char
    if current.startswith("'"):
        current = current.strip("'")
        output.append(int(current))
        continue
    for i in range(len(map) - 1, -1, -1):
        if current.startswith(map[i]):
            output.append(i + 1)
            current = current[len(map[i]) :]
            break

    for i in range(len(map) - 1, -1, -1):
        if current.startswith(map[i]):
            output[len(output) - 1] = output[len(output) - 1] * 10 + i + 1
            break

print(len(output))

print("".join([chr(x) for x in output]))

Running this gave the output of:

36
36
ACECTF{0h_7h3_f33l16_0f_4_p0p_574r}

But there was a problem, the site didn't accept this flag, i ended up one of the organizer via discord, and he told me there was a typo.

I figured, that 0h_7h3_f33l16_0f_4_p0p_574r is probably oh the feelig of a pop star

i manually added an n in f33l1n6 and the site accepted it, idk if this was how it was supposed to be solved, but hey, it worked

ACECTF{0h_7h3_f33l1n6_0f_4_p0p_574r}