Introduction
Highlights
Project
Write-ups
Certificates
Other Activities

Summary Practice

Practice Writeups

These are just the writeups of about 25 challenges I’ve tried at MetaCTF.

/** TJ: 75 **/

BYU CTF 2026 / Weight: 79.0

Incontinent

Intro 2

Description:

I think there was an intro 1 at some point, idk. Is it even an intro if it's second? Note: byuctf{welcome_to_rev_fellas} is a relic of the intro 1 challenge and intro 2 is solvable by pwning the remote binary.

Solve:

Hex To Int

Description:

Okay, I vibe coded a hex converter... but I ran out of tokens after 0xff, so you can just add the correct conversions as you find them and I'll fill the rest in after my token limit refreshes tomorrow. And best part, it'll only be $20/month for the subscription after it's out of beta!!

Solve:

Angr_management

Description:

I built a maze using goto statements! Navigate through it successfully to get the flag.Note: the provided file contains a dummy flag.

Solve:

scriptCTF 2025 / Weight: 24.70

Summary Writeups

BDSec CTF 2025 / Weight: 16.63

Summary Writeups

MetaCTF July 2025 Flash

Working For Peanuts

Description:

I wanted to make a CTF challenge based on one of my favorite comic strips, but there wasn't much to go off of. I ended up making a kinda dusty looking crypto challenge, can you figure out what it's saying?

Information provided:

Image: here

Solve:

Easy recognize this is Pigpen cipher which can solve by draft on paper or use a simple tool on Internet

Flag: MetaCTF{COMICALLYDECODED}

Magical Meta

Description:

All the wizards keep one upping each other, now they're talking to each other about "Magic Bytes" whatever that means.... Anyway, they cast a spell on this image, and now I can't view it, can you cure this curse to recover the original image?

Download the corrupted image here.

You may want to use a hex editor tool. For example, check out HexEd.it. Try comparing this file to any other .jpg image.

Information provided:

Image: magical_meta.jpg

Solve:

Download the image, I got a jpg file and I could not open it by Photo on Windows

I used Hex.it for see what happened in this file and I found that the header of this file was replaced. This can be the reason why this file cannot read bu Windows

The header of a .jpg file is FF D8 FF E0 but in this file is 4D 45 54 41

There are 2 ways to change header of this file

First, I can use this command with WSL:

printf '\xFF\xD8\xFF\xE0' | dd of=magical_meta.jpg bs=1 seek=0 count=4 conv=notrunc

Second, I can use hexedit with WSL for easier

hexdedit magical_meta.jpg

After that I can use keyboard to change bytes what I want

Both ways give to me a image have a flag string on it

Flag: MetaCTF{solv1ng_th3_m4gical_m3ta}

Port Authority

Description:

Help! I was exploring a harbor and got lost. Can you help me figure out what's here?

Try scanning it to discover what's open. There's a common tool used for this that starts with "n."

Information provided:

Sever: here

Solve:

Base on recommend of question about port and starts with "n" → Use Nmap for find flag in open port

Use Nmap Zenmap GUI, I got this:


PORT     STATE SERVICE
80/tcp   open  http
443/tcp  open  https
8888/tcp open  sun-answerbook
                    

The suspicious port is 8888 so I connect to this port and easy to get flag

Flag: MetaCTF{harbor_clearance_granted}

Nothing To C Here

Description:

Move along, NOThing to see here, no flags in sight...

Information provided:

File: NothingToC

Solve:

Use Ghidra with Decompiler Explorer

This have a lot of lines but I found a function which the most valuable


undefined8 FUN_001010c0(void)

{
  int iVar1;
  time_t tVar2;
  char *pcVar3;
  size_t sVar4;
  undefined8 uVar5;
  byte *pbVar6;
  byte *pbVar7;
  long in_FS_OFFSET;
  byte local_138 [32];
  byte local_118 [28];
  byte local_fc [236];
  long local_10;
  
  pbVar6 = local_138;
  local_10 = *(long *)(in_FS_OFFSET + 0x28);
  local_138[0] = 0xb2;
  local_138[1] = 0x9a;
  local_138[2] = 0x8b;
  local_138[3] = 0x9e;
  local_138[4] = 0xbc;
  local_138[5] = 0xab;
  local_138[6] = 0xb9;
  local_138[7] = 0x84;
  local_138[8] = 200;
  local_138[9] = 0x97;
  local_138[10] = 0x96;
  local_138[0xb] = 0xca;
  local_138[0xc] = 0xa0;
  local_138[0xd] = 0x96;
  local_138[0xe] = 0xca;
  local_138[0xf] = 0xa0;
  local_138[0x10] = 0x91;
  local_138[0x11] = 0xcf;
  local_138[0x12] = 0x8b;
  local_138[0x13] = 0xa0;
  local_138[0x14] = 0x8b;
  local_138[0x15] = 0x97;
  local_138[0x16] = 0xcc;
  local_138[0x17] = 0xa0;
  local_138[0x18] = 0x88;
  local_138[0x19] = 0xcb;
  local_138[0x1a] = 0x86;
  local_138[0x1b] = 0x82;
  tVar2 = time((time_t *)0x0);
  srand((uint)tVar2);
  puts(" === NOTing To C Flag Checker === ");
  puts("Ready to check your flag? Let\'s see what you\'ve got!\n");
  printf("Enter the flag to check: ");
  pcVar3 = fgets((char *)local_118,0x100,stdin);
  if (pcVar3 == (char *)0x0) {
    puts("Hmm, seems like you\'re having trouble typing...");
    uVar5 = 1;
  }
  else {
    sVar4 = strcspn((char *)local_118,"\n");
    local_118[sVar4] = 0;
    sVar4 = strlen((char *)local_118);
    if (sVar4 == 0x1c) {
      pbVar7 = local_118;
      do {
        if (*pbVar6 != (byte)~*pbVar7) goto LAB_001011ba;
        pbVar7 = pbVar7 + 1;
        pbVar6 = pbVar6 + 1;
      } while (pbVar7 != local_fc);
      puts("\nCONGRATULATIONS!");
      printf("The flag is: %s\n",local_118);
    }
    else {
      printf("Oops! Your flag is %zu characters long, but I\'m looking for exactly %d characters.\n"
             ,sVar4,0x1c);
      puts("Maybe count your characters next time?");
LAB_001011ba:
      iVar1 = rand();
      switch(iVar1 % 6) {
      case 0:
        puts("Nice try, but that\'s NOT it!");
        break;
      case 1:
        puts("Hmm... that does NOT look right...");
        break;
      case 2:
        puts("NOT quite it! Keep trying!");
        break;
      case 3:
        puts("Incorrect! But do NOT give up!");
        break;
      case 4:
        puts("That\'s NOT the flag I\'m looking for!");
        break;
      case 5:
        puts("NOPE! This flag is NOT what I expected.");
      }
    }
    uVar5 = 0;
  }
  if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) {
                    // WARNING: Subroutine does not return
    __stack_chk_fail();
  }
  return uVar5;
}
                    

Read the code I found it use NOT bitwise to decode the flag

At first, it require user put a string 28 characters

After that, compare flag and user input with NOT bitwise

Flag save at local_138 and input save at local_118

The main compare part:


...
else {
    sVar4 = strcspn((char *)local_118,"\n");
    local_118[sVar4] = 0;
    sVar4 = strlen((char *)local_118);
    if (sVar4 == 0x1c) {
      pbVar7 = local_118;
      do {
        if (*pbVar6 != (byte)~*pbVar7) goto LAB_001011ba;   ->start compare
        pbVar7 = pbVar7 + 1;
        pbVar6 = pbVar6 + 1;
      } while (pbVar7 != local_fc);
      puts("\nCONGRATULATIONS!");
      printf("The flag is: %s\n",local_118);
    }
    else {
      printf("Oops! Your flag is %zu characters long, but I\'m looking for exactly %d characters.\n"
             ,sVar4,0x1c);
      puts("Maybe count your characters next time?");
                    

Each value of ~local_138 = local_118 → ~flag[i] = input[i] with i is "0x.."

So I can use a simple Python script to decode


local_138 = [
    0xb2, 0x9a, 0x8b, 0x9e, 0xbc, 0xab, 0xb9, 0x84,
    0xc8, 0x97, 0x96, 0xca, 0xa0, 0x96, 0xca, 0xa0,
    0x91, 0xcf, 0x8b, 0xa0, 0x8b, 0x97, 0xcc, 0xa0,
    0x88, 0xcb, 0x86, 0x82
]
#~b and 0xFF for ensure the negative numbers can change to positive numbers
flag = ''.join([chr(~b & 0xFF) for b in local_138])

print(flag)
                    

Flag: MetaCTF{7hi5_i5_n0t_th3_w4y}