Close

CTF Results & Walkthrough

A project log for AND!XOR DC28 Badge

DEF CON may be canceled but we are still doing a badge

Hyr0nHyr0n 08/14/2020 at 01:440 Comments

DC28 AND!XOR BENDERPISS CTF Stats

132 Players on the Scoreboard / 5 Fake Hacked Players / 60 Flags Possible

21 Main Challenges

3 Bonus Challenges 

36 Easter Eggs

Concept

Our CTF has never been about cutthroat competition, its about exploration, learning, and being a hacker. You can take whatever route you want, if you are just trying to bag points, and that makes you happy, then you do you. The BENDER CTF (BENDERPISS variant this year), is multidisciplinary in approach. We always want people out of their comfort zone and having to learn something new, which hopefully drives them to visit villages and learn. Beating a dead horse, its not a demonstration of skill sets you have, but rather giving you an opportunity to acquire some new ones and frendz along the way. That being said, the scoreboard can be misleading, seeing someone in first place and thinking "they won." We've never flat out said the person in first "won" the CTF, rather we take time to watch what people are doing, hide some land mines to detect those who take the easy path of point gathering, but also watch how the participants react to those land mines, as well as socialize withing their new community. We also take this approach, because participants have the badge in hand. What are land mines? Flags hidden in the firmware which could only be obtained by dumping it from the MCU or extracting from the patch. If you entered any of these (which we mix with the actual challenge flags), we know that's what you were doing because there's no other way to get them. Some were negative (-1000) some were positive (+10). We know what u did last summer. You can mitigate this at times with additional hardware security, but its hardware. If you have physical access to hardware there is NOTHING you can do to protect it, firmware can be dumped or even GDB used to step through in real time. Additionally we had to post a necessary patch during the CTF, which some instantly went straight to reversing and string dumps to find flags. Doing this doesn't disqualify one from the CTF, in fact it makes it harder because each land mind awards you -1000 points. 

That being said, there are a few categories which we will give shout outs to those who stood out, based on the types of flags they submitted and generally how their discovery went in chat. 

Category Champions

TLDR: These few will receive DC29 AND!XOR badges and a beverage in Vegas (if DEF CON isn't canceled).

S@g@n++: Based on discovery, learning, and not taking the easy path. The 3 persons with the most correct flags submitted, without any land mines, and completing the challenges as designed.

S@g@n--Based on discovery, learning, and not taking the easy path. The 3 persons with the most correct flags submitted, without any negative land mines, and dabbled in some firmware RE.

H@x0r: Based on learning the CTF system, exploiting it, and overcoming the negative score. The person with ALL flags submitted (i.e. including the positive and negative land mines & reset), highest score in the positive.

JTAG@5AurA5R3X: Based on actual hardware hacking of the badge to achieve greatness.

1337: Their only goal was to make their final score 1337

Walk-through

The walkthrough will expand across a few logs, because Hyr0n managed to exploit the same bug in Hackaday.io that he did last year, where a combination of REDACTED, REDACTED, REDACTED, & REDACTED results in REDACTED... Im responsible and won't publicly disclose. Just know that given the type of information I provide and type, and the length of it, requires 3 logs. Also you may wonder, whats up with the SMS speak? We thought it would be lulzy and an additional challenge to understand what was going on, unless you're a millennial. But we put a blackberry keyboard on there to nerf the millennials. So its fair. Also with such limited screen space, it allowed us to put more context in. Big thanks to whoever made the transl8tit SMS TXT Lingo converter.

While the game outline is in the RTFM log, the basics are this: There is an overworld map, where all challenges and tools are randomly hidden. One must discover them all by walking and looking. Each challenge has an initial lock, where one must hack the appropriate target with a tool; i.e. "hack lock wit lockpick", at that point further information is released and one can continue with the challenge.

Master Challenge Unlock (incase you didnt make enough frendz):

> hack flag wit NEVERGONNAGIVEYOUUPNEVERGONNALETYOUDOWN

Challenge 0 - OSINT Twitter

Wut? Itz MrBill. Hes trying 2 coLec OSINT on Hs net of hard hat SD haXor fam.StA classy & giv him wot he wants.

Description: This is a passive OSINT challenge. Many thought it was social engineering and actively kept trying to get a hold of poor MrBill. Lulz. Anyway if you searched through Twitter you would eventually come across hints, such as MrBill has SD (San Diego) hax0r fam. Stay Classy is a hint of Ron Burgundy (the official mascot of DC858/619). More importantly a Mr Bill tweet during BSides San Diego of people calling the payphone to leave their social security number, overwhelmingly resulted in 420-69-1337.

Tool unlock: hack OSINT wit MALTEGO

Answer: hack flag wit 420-69-1337

What Did You Learn Today: That Twitter is a good source of OSINT and the most common SSN is 420-69-1337

Challenge 1 - CRYPTO/ENCODING Keyboard Walk

U find a locked Q10 w tiny ENGRAVING. itz asking 4 a PW.A BIRB flies overhead, you l%k ^ & 2 d L

Description: This is somewhat of a riddle for solving an encoded keyboard walk. Once you hack the target with tool, you can read that "on d bak d following iz inscribed: tzizcz." Combine "tzizcz" with the initial information, you look up "^" and to "2" the "d" left "L." Doing a blackberry keyboard shift cipher of up and to the left for "tzizcz" results in "canada" (that weird place full of EvilMog's and white walkers).

Tool unlock: hack ENGRAVING wit AMSCOPE

Flag: hack flag wit canada

What Did You Learn Today: Ensure your cracking wordlist contains keyboard walks enumerated with shift cyphers, they are more common than you think.

Challenge 2 REVERSE ENGINEERING Derbycon Trevor Firmware

Theres an elctrnk bug. ! d NSA kind bt d ROACH frm con kind. PrograMn INTRFAC exposed. f only U c%d hack dis HW.

Description: This is a re-hash of one of our Trevor 2.0 badge challenges from the last Derby Con. It was fair to re-hash because we only made 40 of those ;) Essentially you get a dump of the firmware and are looking for the secret word, this is a novice RE challenge as all you do is dump strings on the binary to find the password ROUNDERS. But the hints? After completing the initial tool/target hack you see "D mny bug badge blings raw whIl itz binary dumps.Itz az f frm warez iz jst hidden n pln cite" Well its hidden in plain site and talks about bling... looking in the badge SPI storage for bling you'll notice DERBY.RAW, which if you do a long listing you notice its executable (or you could have deduced there was never any DERBYCON bling on the badge, so WTF is this? Executing the program asks for a password and simply checks the input for a string comparison, which is an easy $strings DERBY.RAW dump.

Tool unlock: hack INTRFAC wit ICEDEBUGGER

Flag: hack flag with ROUNDERS

What Did You Learn Today: Dumping strings on firmware is always a good first step.

Challenge 3 REVERSE ENGINEERING Find The E-mail Address

U cUm ax a supa secure medical LAPPY covered n stickers. It hz a TACO_CORP_PROMPT on itz scrEn.

Description: Yet another bullshit RE challenge, the best kind. This is not super difficult, we would place it as medium, but its above a novice attempt (so don't feel bad if it gave you trouble). So the laptop is locked, what better way to backdoor in than with a rubber ducky? Execute the tool/target hack combo to unlock further details. You can now see "D credz auth binary wz XtractD. wot acownt iz Usd 2 login? Saved undRyouZer binz..."" So, once again look under your SPI flash "BIN" directory and behold there's a binary. You should reverse that shit. If you need a basic intro to Ghidra (I like Cutter as well) you can find many resources online, but we wrote one up last year as well. Follow the general process, look at the control flow graph of the binary to see how it works and where its decision branch points are in the logic. Then systematically rename the variables to things which make sense to you (or dont, I'm not the boss of you). Keep in mind, we may have put lots of extra shit (i.e. red herrings) in the binary which have absolutely nothing to do with its operation. Its just more fun that way. So the best way to go through this is generally figure out what is going on and iteratively decompose...

undefined8 main(uint32_t argc, char **argv)
{
    int64_t iVar1;
    char cVar2;
    int32_t iVar3;
    undefined8 uVar4;
    int64_t in_FS_OFFSET;
    char **s2;
    uint32_t var_74h;
    int32_t c;
    int32_t var_64h;
    int32_t var_60h;
    int32_t var_5ch;
    int32_t var_58h;
    uint32_t var_54h;
    uint32_t var_50h;
    uint32_t var_4ch;
    int32_t var_48h;
    uint32_t var_44h;
    char *filename;
    undefined8 stream;
    int32_t var_2ch;
    int32_t var_28h;
    char *s1;
    int32_t var_15h;
    char var_11h;
    char var_10h;
    int32_t canary;
    
    iVar1 = *(int64_t *)(in_FS_OFFSET + 0x28);
    if (argc == 2) {
        uVar4 = sym.imp.fopen(".temp", 0x2035);
        sym.imp.fputc(0x47, uVar4, uVar4);
        sym.imp.fclose(uVar4);
        s1._0_1_ = '\0';
        sym.imp.strcat(&s1, argv[1], argv[1]);
        if (((int32_t)(char)s1 - 0x30U & 0x3fffffff) == 8) {
            _obj.x00 = 1;
        }
        if (((s1._1_1_ == 'G') && (s1._2_1_ == 'A')) && (s1._3_1_ == 'T')) {
            _obj.x01 = 1;
            _obj.x02 = 1;
            _obj.x03 = 1;
        }
        iVar3 = sym.imp.atoi();
        if ((iVar3 + 1) % 0x24 == 0) {
            _obj.x04 = 1;
            _obj.x05 = 1;
        }
        if (s1._6_1_ == '@') {
            _obj.x06 = 1;
        }
        var_64h = 7;
        while (var_64h < 0xb) {
    // switch table (26 cases) at 0x204c
            switch(*(undefined *)((int64_t)&s1 + (int64_t)var_64h)) {
            case 0x41:
                if (var_64h == 8) {
                    _obj.x08 = 1;
                }
                break;
            case 0x42:
                if (var_64h == 8) {
                    _obj.a02 = 1;
                }
                break;
            case 0x43:
                if (var_64h == 9) {
                    _obj.a03 = 1;
                } else {
                    if (var_64h == 10) {
                        _obj.a03 = 1;
                    }
                }
                break;
            case 0x44:
                if (var_64h == 7) {
                    _obj.a04 = 1;
                }
                break;
            case 0x45:
                if (var_64h == 8) {
                    _obj.a05 = 1;
                }
                break;
            case 0x46:
                if (var_64h == 9) {
                    _obj.a06 = 1;
                } else {
                    if (var_64h == 10) {
                        _obj.a06 = 1;
                    }
                }
                break;
            case 0x47:
                if (var_64h == 7) {
                    _obj.a07 = 1;
                }
                break;
            case 0x48:
                if (var_64h == 8) {
                    _obj.a08 = 1;
                }
                break;
            case 0x49:
                if (var_64h == 9) {
                    _obj.a09 = 1;
                } else {
                    if (var_64h == 10) {
                        _obj.a09 = 1;
                    }
                }
                break;
            case 0x4a:
                if (var_64h == 7) {
                    _obj.a10 = 1;
                }
                break;
            case 0x4b:
                if (var_64h == 8) {
                    _obj.a11 = 1;
                }
                break;
            case 0x4c:
                if (var_64h == 9) {
                    _obj.a12 = 1;
                } else {
                    if (var_64h == 10) {
                        _obj.a12 = 1;
                    }
                }
                break;
            case 0x4d:
                if (var_64h == 7) {
                    _obj.a13 = 1;
                }
                break;
            case 0x4e:
                if (var_64h == 8) {
                    _obj.a14 = 1;
                }
                break;
            case 0x4f:
                if (var_64h == 9) {
                    _obj.a15 = 1;
                } else {
                    if (var_64h == 10) {
                        _obj.a15 = 1;
                    }
                }
                break;
            case 0x50:
                if (var_64h == 7) {
                    _obj.a16 = 1;
                }
                break;
            case 0x51:
                if (var_64h == 8) {
                    _obj.a17 = 1;
                }
                break;
            case 0x52:
                if (var_64h == 9) {
                    _obj.a18 = 1;
                } else {
                    if (var_64h == 10) {
                        _obj.a18 = 1;
                    }
                }
                break;
            case 0x53:
                if (var_64h == 7) {
                    _obj.a19 = 1;
                }
                break;
            case 0x54:
                if (var_64h == 8) {
                    _obj.a20 = 1;
                }
                break;
            case 0x55:
                if (var_64h == 9) {
                    _obj.a21 = 1;
                } else {
                    if (var_64h == 10) {
                        _obj.a21 = 1;
                    }
                }
                break;
            case 0x56:
                if (var_64h == 7) {
                    _obj.x07 = 1;
                }
                break;
            case 0x57:
                if (var_64h == 8) {
                    _obj.a23 = 1;
                }
                break;
            case 0x58:
                if (var_64h == 9) {
                    _obj.x09 = 1;
                } else {
                    if (var_64h == 10) {
                        _obj.x10 = 1;
                    }
                }
                break;
            case 0x59:
                if (var_64h == 7) {
                    _obj.a25 = 1;
                }
                break;
            case 0x5a:
                if (var_64h == 8) {
                    _obj.a26 = 1;
                }
            }
            var_64h = var_64h + 1;
        }
        if (((_obj.x07 != 0) && (_obj.x08 != 0)) && ((_obj.x09 != 0 && (_obj.x10 != 0)))) {
            _obj.x06 = 1;
        }
        if (((int32_t)var_15h._1_1_ + (int32_t)(char)var_15h == 0x67) &&
           ((int32_t)var_15h._1_1_ - (int32_t)(char)var_15h == 1)) {
            _obj.x11 = 1;
            _obj.x12 = 1;
        }
        if (var_15h._2_1_ == '.') {
            _obj.x13 = 1;
        }
        iVar3 = sym.rot13((int32_t)var_15h._3_1_);
        if ((iVar3 == 0x3d) && (iVar3 = sym.rot13((int32_t)var_11h + 1), iVar3 == 0x60)) {
            _obj.x14 = 1;
            _obj.x15 = 1;
        }
        uVar4 = sym.imp.fopen(".temp", 0x2038);
        iVar3 = sym.imp.fgetc(uVar4);
        sym.imp.fclose(uVar4);
        sym.imp.remove(".temp");
        if (iVar3 == (int32_t)var_10h) {
            _obj.x16 = 1;
        }
        cVar2 = sym.getCRC((char *)&s1, 0x10);
        if (cVar2 == '\x0f') {
            _obj.crc = 1;
        }
        if ((((((_obj.x00 == 0) || (_obj.x01 == 0)) || (_obj.x02 == 0)) || ((_obj.x03 == 0 || (_obj.x04 == 0)))) ||
            ((((_obj.x05 == 0 || ((_obj.x06 == 0 || (_obj.x07 == 0)))) || (_obj.x08 == 0)) ||
             ((((_obj.x09 == 0 || (_obj.x10 == 0)) || (_obj.x11 == 0)) ||
              (((_obj.x12 == 0 || (_obj.x13 == 0)) || ((_obj.x14 == 0 || ((_obj.x15 == 0 || (_obj.x16 == 0))))))))))))
           || (_obj.crc == 0)) {
            sym.imp.puts("FAILZ!");
        } else {
            sym.imp.puts(0x203a);
        }
    } else {
        sym.imp.puts("DFIU OnRy 1 arg nEdd n allowD!");
    }
    uVar4 = 0;
    if (iVar1 != *(int64_t *)(in_FS_OFFSET + 0x28)) {
        uVar4 = sym.imp.__stack_chk_fail();
    }
    return uVar4;
}

 Yeah it looks cleaner in Ghidra or Cutter (which uses Ghidra as its decompiler BTW and doesn't require JAVA). So logically going through it, and you will see its evaluating every charachter of the input string to meet certain criteria. So figure out how you make each character meet such criteria. Easy enough right?

  1. Check if 2 args or fail (i.e. run the program with the expected input as an argument)
  2. Create a file pointer
  3. Create some strings (red herring)
  4. Lets call input x, check x[0] = 8 - Check if atoi(i) * 4 = (int) ' ' -> Does 8x4 = 32
  5. Check x[1] = G - Convert GAT to binary (01000111 01000001 01010100)
  6. Check x[2] = A - XOR wit (01000011 00000000 00000000)
  7. Check x[3] = T - Does it equal = (0)0000100 1000001 01010100)
  8. Check x[4] = 3 - STR cat x4 and x5 together, does atoi(x4x5) % 35 == 0
  9. Check x[5] = 5 - ----> Combine them, convert to integer, is that int a multiple of 35?
  10. Check x[6] = @ - Check if it is @ (DECIMAL VALUE 64)
  11. Check x[7] = V -> Lets do a loooong ass switch statement , set bools for 7..10
  12. Check x[8] = A
  13. Check x[9] = X
  14. Check x[10] = X
  15. Check x[11]= 3 -> is x11 + x12 (ASCII) = 51 + 52 ==> does it equal 103 && x12-x11 = 1
  16. Check x[12]= 4
  17. Check x[13]= . -> "." is 46, + = 43, - = 45 ----> 45(-) + 43(+) - 42(*) == x13(46 .)
  18. Check x[14]= 0 -> rot13 check is it 61
  19. Check x[15]= R -> rot13+1 check is it 96
  20. Check x[16]= G -> create a file at the begining, save a G...check it at the very end.
  21. Open that file we started with, double check x[16] == G
  22. Check x[17] for a CRC that matches 0xF, which is the CRC of 8GAT35@VAXX34.0RG

Why does the CRC matter? Because there are multiple ways to satisfy the criteria. So in a way you could have thought you were correct, get to the end and the CRC fails. LOLZ. Also for a cleaner look, here's the actual C code...

/*****************************************************************************
 * Made with beer and late nights in California.
 *
 * (C) Copyright 2017-2020 AND!XOR LLC (https://andnxor.com/).
 *
 * PROPRIETARY AND CONFIDENTIAL UNTIL AUGUST 11th, 2020 then,
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * ADDITIONALLY:
 * If you find this source code useful in anyway, use it in another electronic
 * conference badge, or just think it's neat. Consider buying us a beer
 * (or two) and/or a badge (or two). We are just as obsessed with collecting
 * badges as we are in making them.
 *
 * Contributors:
 *     @andnxor
 *     @zappbrandnxor
 *     @hyr0n1
 *     @bender_andnxor
 *     @lacosteaef
 *  @f4nci3
 *  @Cr4bf04m
 *****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef int bool;
#define true 1
#define false 0

bool x00 = false;bool x01 = false;bool x02 = false;bool x03 = false;bool x04 = false;bool x05 = false;bool x06 = false;bool x07 = false;bool x08 = false;
bool x09 = false;bool x10 = false;bool x11 = false;bool x12 = false;bool x13 = false;bool x14 = false;bool x15 = false;bool x16 = false;bool crc = false;

bool a01 = false;bool a02 = false;bool a03 = false;bool a04 = false;bool a05 = false;bool a06 = false;bool a07 = false;bool a08 = false;bool a09 = false;
bool a10 = false;bool a11 = false;bool a12 = false;bool a13 = false;bool a14 = false;bool a15 = false;bool a16 = false;bool a17 = false;bool a18 = false;
bool a19 = false;bool a20 = false;bool a21 = false;bool a22 = false;bool a23 = false;bool a24 = false;bool a25 = false;bool a26 = false;

const unsigned char CRC7_POLY = 0x91;
 
unsigned char getCRC(unsigned char message[], unsigned char length) //Borrowed from https://www.pololu.com/docs/0J44/6.7.6
{
  unsigned char i, j, crc = 0;
 
  for (i = 0; i < length; i++)
  {
    crc ^= message[i];
    for (j = 0; j < 8; j++)
    {
      if (crc & 1)
        crc ^= CRC7_POLY;
      crc >>= 1;
    }
  }
  return crc;
}

int rot13(int x){ //This really isn't ROT13, it just adds 13. I want the function name to fuck with people.
    return x+13;
}

int main(int argc, char *argv[]) {
    /*********************************************************************************************
     * @brief Initialization & Setup : Sekret flag = 8GAT35@VAXX34.0RG
    **********************************************************************************************/ 
    if (argc != 2) {
        printf("DFIU OnRy 1 arg nEdd n allowD!\n");
        return 0;
    }
    else{
        /*********************************************************************************************
         * @brief Initialize Variables
        **********************************************************************************************/ 
        //Create the file for the last step
        FILE *fp;
        char G = 71;
        char* filename = ".temp";
        fp = fopen(filename, "w+");
        fprintf(fp, "%c", (char)G);
        fclose(fp);

        //Red Herring
        char hint[] = "flag";
        char msg[17];
        strcpy(msg,"");
        strcat(msg,argv[1]);
        
        /*********************************************************************************************
         * @brief Step 00 : Sekret flag = 8GAT35@VAXX34.0RG
         * x[0] = 8 - Check if atoi(i) * 4 = (int) ' ' -> Does 8x4 = 32?
        **********************************************************************************************/ 
        if((msg[0] - 48) * 4 == 32){
            x00 = true; 
        } 

        /*********************************************************************************************
         * @brief Step 01 : Sekret flag = 8GAT35@VAXX34.0RG
         * x[1] = G - Convert GAT to binary (01000111 01000001 01010100)
         * x[2] = A - XOR wit (01000011 00000000 00000000) 
         * x[3] = T - Does it equal = (0)0000100 1000001 01010100)
        **********************************************************************************************/ 

        int s01bin00=0b01000011;
        int s01bin01=0b00000000;
        int s01bin02=0b00000000;
        int s01ans00=0b00000100;
        int s01ans01=0b01000001;
        int s01ans02=0b01010100;
        if(((msg[1]^s01bin00) == s01ans00)&&((msg[2]^s01bin01) == s01ans01)&&((msg[3]^s01bin02) == s01ans02)){
            x01 = true; x02 = true; x03 = true;
        }
        
        /*********************************************************************************************
         * @brief Step 02 : Sekret flag = 8GAT35@VAXX34.0RG
         * x[4] = 3 - STR cat x4 and x5 together, does atoi(x4x5) % 35 == 0?
        *  x[5] = 5 - ----> Combine them, convert to integer, is that int a multiple of 35?
        **********************************************************************************************/ 
        char step02_str[2];
        step02_str[0] = msg[4];
        step02_str[1] = msg[5];
        int step02_int = atoi(step02_str);
        if((step02_int + 1) % 36 == 0){
            x04 = true;
            x05 = true;
        }

        /*********************************************************************************************
         * @brief Step 03 : Sekret flag = 8GAT35@VAXX34.0RG
         * x[6] = @ - Check if it is @ (DECIMAL VALUE 64)
        **********************************************************************************************/ 
        if (msg[6] == 64){
            x06 = true;   
        }

        /*********************************************************************************************
         * @brief Step 04 : Sekret flag = 8GAT35@VAXX34.0RG
         * x[7] = V -> Lets do a loooong ass switch statement , set bools for 7..10
         * x[8] = A
         * x[9] = X
         * x[10]= X
        **********************************************************************************************/ 
        char sss[]="xxxxxx";
        for (int i=7; i<=10; i++){
            switch (msg[i]){
                case 'A' : if (i == 8) {x08 = true; strcpy(sss,"abacus");} break; //A
                case 'B' : if (i == 8) {a02 = true; strcpy(sss,"babies");} break;
                case 'C' : if (i == 9) {a03 = true; strcpy(sss,"cabala");} else if (i == 10) {a03 = true; strcpy(sss,"cabala");}break;
                case 'D' : if (i == 7) {a04 = true; strcpy(sss,"dabber");} break;
                case 'E' : if (i == 8) {a05 = true; strcpy(sss,"eagers");} break;
                case 'F' : if (i == 9) {a06 = true; strcpy(sss,"fables");} else if (i == 10) {a06 = true; strcpy(sss,"fables");}break;
                case 'G' : if (i == 7) {a07 = true; strcpy(sss,"gabion");} break;
                case 'H' : if (i == 8) {a08 = true; strcpy(sss,"habits");} break;
                case 'I' : if (i == 9) {a09 = true; strcpy(sss,"ibices");} else if (i == 10) {a09 = true; strcpy(sss,"ibices");}break;
                case 'J' : if (i == 7) {a10 = true; strcpy(sss,"jabber");} break;
                case 'K' : if (i == 8) {a11 = true; strcpy(sss,"kabala");} break;
                case 'L' : if (i == 9) {a12 = true; strcpy(sss,"laager");} else if (i == 10) {a12 = true; strcpy(sss,"laager");}break;
                case 'M' : if (i == 7) {a13 = true; strcpy(sss,"macaws");} break;
                case 'N' : if (i == 8) {a14 = true; strcpy(sss,"nachos");} break;
                case 'O' : if (i == 9) {a15 = true; strcpy(sss,"oakums");} else if (i == 10) {a15 = true; strcpy(sss,"oakums");}break;
                case 'P' : if (i == 7) {a16 = true; strcpy(sss,"packed");} break;
                case 'Q' : if (i == 8) {a17 = true; strcpy(sss,"qiblas");} break;
                case 'R' : if (i == 9) {a18 = true; strcpy(sss,"rabbin");} else if (i == 10) {a18 = true; strcpy(sss,"rabbin");}break;
                case 'S' : if (i == 7) {a19 = true; strcpy(sss,"sabora");} break;
                case 'T' : if (i == 8) {a20 = true; strcpy(sss,"tables");} break;
                case 'U' : if (i == 9) {a21 = true; strcpy(sss,"uglier");} else if (i == 10) {a21 = true; strcpy(sss,"uglier");}break;
                case 'V' : if (i == 7) {x07 = true; strcpy(sss,"vacuum");} break; //V
                case 'W' : if (i == 8) {a23 = true; strcpy(sss,"wabble");} break;
                case 'X' : if (i == 9) {x09 = true; strcpy(sss,"xenial");} else if (i == 10) {x10 = true; strcpy(sss,"xenial");}break; //X
                case 'Y' : if (i == 7) {a25 = true; strcpy(sss,"yabber");} break;
                case 'Z' : if (i == 8) {a26 = true; strcpy(sss,"zaffer");} break;
            }
        }
        if (x07 && x08 && x09 && x10){
            x06 = true;    
        }

        /*********************************************************************************************
         * @brief Step 05 : Sekret flag = 8GAT35@VAXX34.0RG
         * x[11]= 3 -> is x11 + x12 (ASCII) = 51 + 52 ==> does it equal 103 && x12-x11 = 1
         * x[12]= 4
        **********************************************************************************************/ 
        if((msg[11]+msg[12] == 103) && (msg[12]-msg[11]==1)){
            x11 = true; x12 = true;
        }

        /*********************************************************************************************
         * @brief Step 06 : Sekret flag = 8GAT35@VAXX34.0RG
         *  x[13]= . -> "." is 46, + = 43, - = 45 ----> 45(-) + 43(+) - 42(*) == x13(46 .)?
        **********************************************************************************************/ 
        char sub = 45;
        char add = 43;
        char mul = 42;
        if(sub + add - mul == msg[13]){
            x13 = true;
        }

        /*********************************************************************************************
         * @brief Step 07 : Sekret flag = 8GAT35@VAXX34.0RG
         * x[14]= 0 -> rot13 check is it 61
         * x[15]= R -> rot13+1 check is it 96
         * x[16]= G -> create a file at the begining, save a G...check it at the very end.
        **********************************************************************************************/ 
        if((rot13(msg[14])==61) && (rot13(msg[15]+1)==96)){
            x14 = true;
            x15 = true;
        }
        //Open that file from step 0...I hope they forgot about it.
        fp = fopen(filename, "r");
        int c = fgetc(fp);
        fclose(fp);
        remove(filename);
        if(c == msg[16]) x16 = true;

        /*********************************************************************************************
         * @brief Step 08 : FINAL CHECK OF TRUTH AND CRC (Hex: f / Decimal)
        **********************************************************************************************/ 
        msg[17] = getCRC(msg, 16);
        if(msg[17]==0xf) crc = true;

        if(x00 && x01 && x02 && x03 && x04 && x05 && x06 && x07 && x08 && x09 && x10 && x11 && x12 && x13 && x14 && x15 && x16 && crc){
            //TODO CRC
            printf("SUCCESS!\n");
        }
        else{
            printf("FAILZ!\n");
        }
        return 0;
    }
}

Oh an yes, do we take shots at the crazy conspiracy theory nuts about COVID19 throughout this entire CTF? OF COURSE. Because Bill Gates is trying to release vaccines in the world and implant you with tracking devices...don't forget tin foil hats provide RF shielding from the trackers.

Tool unlock: hack LAPPY wit RUBBER_DUCKY

Flag: hack flag wit 8GAT35@VAXX34.0RG

What Did You Learn Today: Reverseing compiled software is an extremely useful skillset, don't just live in the world of Python and Javascript, learn C and Assembly / how it works / how its built / and how to tear it apart.

Continue to Part 2...

Discussions