Close
picoCTF 2019 – General Skills WriteUp

picoCTF 2019 – General Skills WriteUp

Contents

The Factory’s Secret (1)

While the challenge was only worth one point, I consider it one of the most fun challenges this contest had. Let’s gt started:

Fragment 1

The first fragment is just lying on the General Skills Room floor.

Fragment 2

The second fragment lies within the Web Exploitation Room. I was able to see it as I walked to the computer that hosts the challenges:

However, we are not able to directly walk there and take it. I first made our way to the computer:

Once I got there, I entered the cave, which took me to another corner of the map:

There is another cave entrance at the bottom of the screen. To be able to enter it, I first needed to move the stone:

The cave took me to the small ‘island’ that held the glyph fragment:

Fragment 3

This fragment was located in the Cryptography Room. It was buried under the 5th grave on the 7th row, right matrix.

Fragment 4

This fragment is located in the Binary Exploitation room. I saw that if I go through one door, say, the red one, the background music & animations would speed up. If I went again through the red door, everything would ‘reset’, but if I went through the blue one, everything would speed up even more. I kept alternating the doors I entered and a third door appeared, which led me in hidden room that contained the glyph fragment. I believe the authors wanted to showcase the idea of an overflow – if the speed gets too high, it might cause an overflow and theoretically crash the app.

Fragment 5

Next, I went searching in the Forensics Room. As fragment 4 hinted, there is a glyph hidden inside the lake in the upper right corner:

Fragment 6

Unlike most players in the Discord group, I liked the background music of the game. I heard something in the General Skills Room and I found two beeping blocks in the upper right direction (I can’t call it a corner):

I found the following sequence to be repeated:

It looked like morse code, so I used this tool to decode it:

At first, the message made no sense. I understood it after entering the Reversing Room, which had 4 pillars, numbered from 1 to 4, each having a lever that the player had the ability to pull:

I activated the 2nd, 4th, 1st, and 3rd levers, in that order, as the message hinted. After that, a message stating that the levers reset appeared, along with a glyph fragment:

The flag

After collecting all the fragments, the following text appears:

In addition to those prompts, a new item appears in the player’s inventory:

I used this tool to convert it to text:

password: xmfv53uqkf621gakvh502gxfu1g78glds

After decoding the text, I had the password for the computer located in the spawn room. I used this password to unlock it:

Flag: picoCTF{zerozerozerozero}

2Warm (50)

Just use python ^-^

>>> bin(42)
'0b101010'
>>>

Flag: picoCTF{101010}

Lets Warm Up (50)

Just use python ^-^

>>> chr(0x70)
'p'
>>>

Flag: picoCTF{p}

Warmed Up (50)

Just use python ^-^

>>> 0x3D
61
>>>

Flag: picoCTF{61}

Bases (100)

In order to get the flag, we need to decode the given string using base64. We can achieve this using the Linux program named ‘base64’:

yakuhito@furry-catstation:~/blog/picoctf2019/crypto$ echo bDNhcm5fdGgzX3IwcDM1 | base64 -d; echo
l3arn_th3_r0p35
yakuhito@furry-catstation:~/blog/picoctf2019/crypto$

Flag: picoCTF{l3arn_th3_r0p35}

First Grep (100)

I don’t know what to write here 🙂

yakuhito@furry-catstation:~/blog/picoctf2019/general-skills$ grep picoCTF{ file --color=none
picoCTF{grep_is_good_to_find_things_cdb327ab}
yakuhito@furry-catstation:~/blog/picoctf2019/general-skills$

Flag: picoCTF{grep_is_good_to_find_things_cdb327ab}

Resources (100)

The flag is listed on the webpage -_-

Flag: picoCTF{r3source_pag3_f1ag}

strings it(100)

Use the ‘strings’ program along with grep:

yakuhito@furry-catstation:~/blog/picoctf2019/general-skills$ strings strings | grep picoCTF* --color=none
picoCTF{5tRIng5_1T_c611cac7}
yakuhito@furry-catstation:~/blog/picoctf2019/general-skills$

Flag: picoCTF{5tRIng5_1T_c611cac7}

what’s a net cat? (100)

It’s a very good thing that Linux comes with netcat pre-installed 😛

yakuhito@furry-catstation:~/blog/picoctf2019/general-skills$ nc 2019shell1.picoctf.com 47229
You're on your way to becoming the net cat master
picoCTF{nEtCat_Mast3ry_cc4ad2c7}
 
yakuhito@furry-catstation:~/blog/picoctf2019/general-skills$

Flag: picoCTF{nEtCat_Mast3ry_cc4ad2c7}

Based (200)

I’ll first paste the solution and then try to explain it step-by-step:

yakuhito@furry-catstation:~/blog/picoctf2019/general-skills$ nc 2019shell1.picoctf.com 7380
Let us see how data is stored
pear
Please give the 01110000 01100101 01100001 01110010 as a word.
...
you have 45 seconds.....
 
Input:
pear
Please give me the  143 150 141 151 162 as a word.
Input:
chair
Please give me the 636f6d7075746572 as a word.
Input:
computer
You've beaten the challenge
Flag: picoCTF{learning_about_converting_values_819ada06}
 
yakuhito@furry-catstation:~/blog/picoctf2019/general-skills$

The first word is encoded using binary. I used this tool to recover the word:

The second one is the octal representation of the word. I came to this conclusion because there is no digit greater than 7. I used this tool to recover the word:

The third and last encoding is hex/base16, as it has the alphabet 0-9a-f. I used this tool to get the final word:

Flag: picoCTF{learning_about_converting_values_819ada06}

First Grep: Part II (200)

We can just use grep along with its -R switch, which tells the program to search for all files in the specified directory and its sub-directories:

y4kuhito@pico-2019-shell1:~$ grep -R picoCTF* /problems/first-grep--part-ii_0_b68f6a4e9cb3a7aad4090dea9dd80ce1/files
/problems/first-grep--part-ii_0_b68f6a4e9cb3a7aad4090dea9dd80ce1/files/files9/file26:picoCTF{grep_r_to_find_this_e4fa3ba7}
y4kuhito@pico-2019-shell1:~$

Flag: picoCTF{grep_r_to_find_this_e4fa3ba7}

plumbing (200)

Just connecting to the given address won’t work, as there is a lot of garbage output. The challenge’s name is a reference to pipes, so I just piped the output to grep and I got the flag:

y4kuhito@pico-2019-shell1:~$ nc 2019shell1.picoctf.com 63345 | grep picoCTF* --color=none
picoCTF{digital_plumb3r_4e7a5813}
^C
y4kuhito@pico-2019-shell1:~$

If you have no idea how piping works, I recommend this article.

Flag: picoCTF{digital_plumb3r_4e7a5813}

whats-the-difference (200)

Two files, kitters.jpg and cattos.jpg, can be found attached. kitters.jpg looks normal, however, cattos.jpg looks corrupted:

The first image seems to be a corrupt copy of the second one. It turns out the flag was written at random locations in the cattos.jpg file. I used the following script to get the flag:

a = open("cattos.jpg", "rb").read()
b = open("kitters.jpg", "rb").read()
 
flag = ""
 
for i in range(len(a)):
	if a[i] != b[i]:
		flag += chr(a[i])
 
print(flag)

The script needs to be run in the same directory as the images and will output the flag:

yakuhito@furry-catstation:~/blog/picoctf2019/general-skills$ python hex.py 
picoCTF{th3yr3_a5_d1ff3r3nt_4s_bu773r_4nd_j311y_aslkjfdsalkfslkflkjdsfdszmz10548}
yakuhito@furry-catstation:~/blog/picoctf2019/general-skills$

Flag: picoCTF{th3yr3_a5_d1ff3r3nt_4s_bu773r_4nd_j311y_aslkjfdsalkfslkflkjdsfdszmz10548}

where-is-the-file (200)

Just trying to list the directory’s files will return an empty result:

y4kuhito@pico-2019-shell1:~$ ls /problems/where-is-the-file_0_cc140a3ba634658b98122a1954c1316a
y4kuhito@pico-2019-shell1:~$

However, ls does NOT show us all files. By default, all files beginning with a . are considered hidden on Linux and are not listed by default. We can tell ls to show all files by using the -a switch:

y4kuhito@pico-2019-shell1:~$ ls -a /problems/where-is-the-file_0_cc140a3ba634658b98122a1954c1316a
.  ..  .cant_see_me
y4kuhito@pico-2019-shell1:~$ cat /problems/where-is-the-file_0_cc140a3ba634658b98122a1954c1316a/.cant_see_me 
picoCTF{w3ll_that_d1dnt_w0RK_b2dab472}
y4kuhito@pico-2019-shell1:~$

The flag was located in the hidden file.

Flag: picoCTF{w3ll_that_d1dnt_w0RK_b2dab472}

flag_shop (300)

#include <stdio.h>
#include <stdlib.h>
int main()
{
    setbuf(stdout, NULL);
    int con;
    con = 0;
    int account_balance = 1100;
    while(con == 0){
 
        printf("Welcome to the flag exchange\n");
        printf("We sell flags\n");
 
        printf("\n1. Check Account Balance\n");
        printf("\n2. Buy Flags\n");
        printf("\n3. Exit\n");
        int menu;
        printf("\n Enter a menu selection\n");
        fflush(stdin);
        scanf("%d", &menu);
        if(menu == 1){
            printf("\n\n\n Balance: %d \n\n\n", account_balance);
        }
        else if(menu == 2){
            printf("Currently for sale\n");
            printf("1. Defintely not the flag Flag\n");
            printf("2. 1337 Flag\n");
            int auction_choice;
            fflush(stdin);
            scanf("%d", &auction_choice);
            if(auction_choice == 1){
                printf("These knockoff Flags cost 900 each, enter desired quantity\n");
 
                int number_flags = 0;
                fflush(stdin);
                scanf("%d", &number_flags);
                if(number_flags > 0){
                    int total_cost = 0;
                    total_cost = 900*number_flags;
                    printf("\nThe final cost is: %d\n", total_cost);
                    if(total_cost <= account_balance){
                        account_balance = account_balance - total_cost;
                        printf("\nYour current balance after transaction: %d\n\n", account_balance);
                    }
                    else{
                        printf("Not enough funds to complete purchase\n");
                    }
 
 
                }
 
 
 
 
            }
            else if(auction_choice == 2){
                printf("1337 flags cost 100000 dollars, and we only have 1 in stock\n");
                printf("Enter 1 to buy one");
                int bid = 0;
                fflush(stdin);
                scanf("%d", &bid);
 
                if(bid == 1){
 
                    if(account_balance > 100000){
                        FILE *f = fopen("flag.txt", "r");
                        if(f == NULL){
 
                            printf("flag not found: please run this on the server\n");
                            exit(0);
                        }
                        char buf[64];
                        fgets(buf, 63, f);
                        printf("YOUR FLAG IS: %s\n", buf);
                        }
 
                    else{
                        printf("\nNot enough funds for transaction\n\n\n");
                    }}
 
            }
        }
        else{
            con = 1;
        }
 
    }
    return 0;
}

This challenge was about integer overflows. In C/C++, when an integer variable is set to INT_MAX (+2147483647) and someone adds 1 to it, then the variable will ‘reset’ to INT_MIN (-2147483648). If we do things right, we may be able to make total_cost be negative, meaning that we will gain money after we buy the flags.

I’ll paste a working solution below and let you figure out how I got to it 😉

Enter a menu selection
2
Currently for sale
1. Defintely not the flag Flag
2. 1337 Flag
1
These knockoff Flags cost 900 each, enter desired quantity
2386122
 
The final cost is: -2147457496
 
Your current balance after transaction: 2147460292
 
Welcome to the flag exchange
We sell flags
 
1. Check Account Balance
 
2. Buy Flags
 
3. Exit
 
 Enter a menu selection
2
Currently for sale
1. Defintely not the flag Flag
2. 1337 Flag
2
1337 flags cost 100000 dollars, and we only have 1 in stock
Enter 1 to buy one1
YOUR FLAG IS: picoCTF{m0n3y_bag5_cd0ead78}
Welcome to the flag exchange
We sell flags
 
1. Check Account Balance
 
2. Buy Flags
 
3. Exit
 
 Enter a menu selection
3

Flag: picoCTF{m0n3y_bag5_cd0ead78}

2 thoughts on “picoCTF 2019 – General Skills WriteUp

  1. Hi!
    I was going through eh CTF challenge myself and actually got stuck on the “flag_shop” challenge. Seeing the competition was already over, I figured I’d look online for the answer and saw this, among others. I was just curious, how did you come to the solution that you did? I tried many random numbers, none took. After seeing the answer and realizing the need to overflow the integer, even using a larger number like “214783647” didn’t give me what I expected.

    How and why did you do it the way you did? Just looking to learn different approaches to problems. I know that not everything can only be solved one way, there are many ways to solve the same problem.

    When trying “214783647”, I get an increase but not enough to cover the full cost, so I have to re-enter that value multiple time. However, your solution gives me enough money in a single go. How did you arrive to this solution?

    1. Hi, ctfGoer!
      Keep in mind that the final price is the number you entered times 900, as the program asks you for the number of flags you want to buy.
      If you still have problems, just post another comment.

      yakuhito

Leave a Reply

Your email address will not be published. Required fields are marked *