These are just the writeups of about 25 challenges I’ve tried at MetaCTF.
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:
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:
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:
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}
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}
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}
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}