n00bzCTF 2024 Writeup

この大会は2024/8/3 10:00(JST)~2024/8/5 10:00(JST)に開催されました。
今回もチームで参戦。結果は5717点で967チーム中144位でした。
自分で解けた問題をWriteupとして書いておきます。

Sanity Check (Misc)

Discordに入り、#announcementチャネルのメッセージを見ると、フラグが書いてあった。

n00bz{w3lc0m3_t0_n00bzCTF2024!}

Addition (Misc)

サーバの処理概要は以下の通り。

・questions: 数値入力
・0以上questions未満の値iに対して以下を実行
 ・a: 0以上10以下のランダム整数
 ・b: 0以上10以下のランダム整数
 ・yourans: 数値入力
 ・totaltime = pow(2, i)
 ・合計でtotaltimeの時間だけスリープ
 ・yourans が a + b と一致しない場合、終了
・flagをquestionsの文字数だけ表示

普通に計算に答えていくと、時間がかかりすぎる。questionsに-1を指定すれば、flagの最終の文字以外を取得できる。

$ nc 24.199.110.35 42189
how many questions do you want to answer? -1
n00bz{m4th_15nt_4ll_4b0ut_3qu4t10n5}
n00bz{m4th_15nt_4ll_4b0ut_3qu4t10n5}

EVM - The Basics (Blockchain)

https://app.dedaub.com/decompileデコンパイルする。

    0x0: PUSH0     
    0x1: CALLVALUE 
    0x2: PUSH2     0x1337
    0x5: MUL       
    0x6: PUSH6     0xfdc29ff358a3
    0xd: EQ        
    0xe: PUSH1     0x12
   0x10: JUMPI     
   0x11: SELFDESTRUCT
   0x12: STOP  

0x1337をかけて0xfdc29ff358a3になる値を求める。

>>> a = 0x1337
>>> b = 0xfdc29ff358a3
>>> b % a
0
>>> hex(b // a)
'0xd34db33f5'
n00bz{0xd34db33f5}

Sillygoose (Programming)

ランダムな0以上pow(10, 100)以下の値を当てる問題。ただし、時間は60秒以下に対応する必要がある。最速と思われる二分探索法で探し当てる。

#!/usr/bin/env python3
import socket

def recvuntil(s, tail):
    data = b''
    while True:
        if tail in data:
            return data.decode()
        data += s.recv(1)

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('24.199.110.35', 41199))

ans = [0, pow(10, 100)]

while True:
    inp = (ans[0] + ans[1]) // 2
    print(inp)
    s.sendall(str(inp).encode() + b'\n')
    data = recvuntil(s, b'\n').rstrip()
    print(data)
    if data == 'your answer is too large you silly goose':
        ans[1] = inp
    elif data == 'your answer is too small you silly goose':
        ans[0] = inp
    else:
        break

data = recvuntil(s, b'\n').rstrip()
print(data)

実行結果は以下の通り。

5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
your answer is too large you silly goose
2500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
your answer is too large you silly goose
1250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
your answer is too small you silly goose
1875000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
your answer is too large you silly goose
1562500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
your answer is too small you silly goose
1718750000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
your answer is too small you silly goose
                :
1806248900837509389389223986621313895058191308210212045285156862871201722676478271626632639416820242
your answer is too small you silly goose
1806248900837509389389223986621313895058191308210212045285156862871201722676478271626632639416820388
your answer is too small you silly goose
1806248900837509389389223986621313895058191308210212045285156862871201722676478271626632639416820461
your answer is too small you silly goose
1806248900837509389389223986621313895058191308210212045285156862871201722676478271626632639416820498
your answer is too large you silly goose
1806248900837509389389223986621313895058191308210212045285156862871201722676478271626632639416820479
your answer is too small you silly goose
1806248900837509389389223986621313895058191308210212045285156862871201722676478271626632639416820488
congratulations you silly goose
n00bz{y0u_4r3_4_sm4rt_51l1y_g0053}
n00bz{y0u_4r3_4_sm4rt_51l1y_g0053}

Numbers 2 (Programming)

$ nc challs.n00bzunit3d.xyz 10224
Welcome to Numbers 2! Time to step up the game...
Current round: 1 of 100
Give me the least common multiple of 190 and 43: 8170
Correct!
You took too long!

$ nc challs.n00bzunit3d.xyz 10224
Welcome to Numbers 2! Time to step up the game...
Current round: 1 of 100
Give me the greatest common divisor of 34 and 124: 2
Correct!
You took too long!

$ nc challs.n00bzunit3d.xyz 10224
Welcome to Numbers 2! Time to step up the game...
Current round: 1 of 100
Give me the greatest prime factor of 74: 37
Correct!
You took too long!

LCM, GCD, 素因数分解したときの因数の最大値を答えるパターンがあるので、識別して答えていく。

#!/usr/bin/env python3
import socket
from Crypto.Util.number import *
from sympy import factorint

def recvuntil(s, tail):
    data = b''
    while True:
        if tail in data:
            return data.decode()
        data += s.recv(1)

def LCM(a, b):
    return a * b // GCD(a, b)

def GPF(n):
    f = factorint(n)
    f = sorted(f.items(), reverse=True)
    return f[0][0]

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('challs.n00bzunit3d.xyz', 10224))

data = recvuntil(s, b'\n').rstrip()
print(data)

for i in range(100):
    data = recvuntil(s, b'\n').rstrip()
    print(data)
    data = recvuntil(s, b': ')
    print(data, end='')
    if 'least common multiple' in data:
        a = int(data.split(' ')[7])
        b = int(data.split(' ')[9][:-1])
        ans = LCM(a, b)
    elif 'greatest common divisor' in data:
        a = int(data.split(' ')[7])
        b = int(data.split(' ')[9][:-1])
        ans = GCD(a, b)
    else:
        n = int(data.split(' ')[7][:-1])
        ans = GPF(n)
    print(ans)
    s.sendall(str(ans).encode() + b'\n')
    data = recvuntil(s, b'\n').rstrip()
    print(data)

data = recvuntil(s, b'\n').rstrip()
print(data)

実行結果は以下の通り。

Welcome to Numbers 2! Time to step up the game...
Current round: 1 of 100
Give me the greatest common divisor of 162 and 174: 6
Correct!
Current round: 2 of 100
Give me the greatest prime factor of 146: 73
Correct!
Current round: 3 of 100
Give me the least common multiple of 262 and 172: 22532
Correct!
Current round: 4 of 100
Give me the greatest prime factor of 47: 47
Correct!
Current round: 5 of 100
Give me the least common multiple of 177 and 78: 4602
Correct!
                :
                :
Current round: 96 of 100
Give me the least common multiple of 2398 and 740: 887260
Correct!
Current round: 97 of 100
Give me the greatest common divisor of 8228 and 5806: 2
Correct!
Current round: 98 of 100
Give me the least common multiple of 4408 and 3176: 1749976
Correct!
Current round: 99 of 100
Give me the greatest common divisor of 8527 and 9805: 1
Correct!
Current round: 100 of 100
Give me the least common multiple of 8331 and 9207: 25567839
Correct!
Good job! Here's your flag: n00bz{numb3r5_4r3_fun_7f3d4a_ed47522cf007}
n00bz{numb3r5_4r3_fun_7f3d4a_ed47522cf007}

The Gang (OSINT)

John Doeが最近チーム「n00bzUnit3d」に加わったかどうかを調べる問題。
"n00bzUnit3d"で検索すると、以下のWebサイトが見つかる。

https://n00bzunit3d.xyz/

Membersのリンクをクリックし、メンバー一覧を確認する。この中にjohndoeのリンクがあったので、アクセスする。

https://n00bzunit3d.xyz/authors/johndoe

このページにフラグが書いてあった。

n00bz{1ts_051N7_71m3_3e4a7d6f}

Pastebin (OSINT)

かなり前に作成したユーザabhinav654321のpastebinを調べる問題。
https://pastebin.com/u/abhinav654321を見てみる。そこには掲示板のスレットが1つあるので、中を見てみる。URLは以下の通り。

https://pastebin.com/j1UnKA7m

コメントがたくさんあるが、特に何も見つからない。Internet Archiveで以下のURLを見てみる。

https://pastebin.com/j1UnKA7m

2024/6/17にスナップショットがあるので、見てみると、フラグが書いてあった。

n00bz{l0ng_t1m3_ag0_m34ns_w4yb4ck}

The Gang 2 (OSINT)

問題「The Gang」で見つけた https://n00bzunit3d.xyz/authors/johndoe では、以下のページがリンクされている。

https://n00bzunit3d.xyz/blog/who-am-i/

行頭の文字をつなげると、以下のようになる。

USERNAME IS JOHN HACKER DOE

https://x.com/johnhackerdoeにアクセスすると、フラグがポストされているのを見つけた。

n00bz{5t0p_ch4s1ng_m3_4f2d1a7d}

Vacation (Rev)

ps1ファイルが添付されている。コードを見ると、flagの各文字のASCIIコードと3をXORして文字にして出力していることがわかる。出力文字列の各文字のASCIIコードと3をXORして文字にすればフラグになる。

>>> s = b'm33ayxeqln\\sbqjp\\twk\\{lq~'
>>> ''.join([chr(c ^ 3) for c in s])
'n00bz{from_paris_wth_xor}'
n00bz{from_paris_wth_xor}

FlagChecker (Rev)

xlsmファイルが添付されている。マクロコードを見てみる。

$ olevba FlagChecker.xlsm
olevba 0.60.2 on Python 3.11.9 - http://decalage.info/python/oletools
===============================================================================
FILE: FlagChecker.xlsm
Type: OpenXML
WARNING  For now, VBA stomping cannot be detected for files in memory
-------------------------------------------------------------------------------
VBA MACRO ThisWorkbook.cls 
in file: xl/vbaProject.bin - OLE stream: 'VBA/ThisWorkbook'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
(empty macro)
-------------------------------------------------------------------------------
VBA MACRO Sheet1.cls 
in file: xl/vbaProject.bin - OLE stream: 'VBA/Sheet1'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
(empty macro)
-------------------------------------------------------------------------------
VBA MACRO Module1.bas 
in file: xl/vbaProject.bin - OLE stream: 'VBA/Module1'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
Sub FlagChecker()

    Dim chars(1 To 24) As String
    guess = InputBox("Enter the flag:")
    If Len(guess) <> 24 Then
        MsgBox "Nope"
    End If
    char_1 = Mid(guess, 1, 1)
    char_2 = Mid(guess, 2, 1)
    char_3 = Mid(guess, 3, 1)
    char_4 = Mid(guess, 4, 1)
    char_5 = Mid(guess, 5, 1)
    char_6 = Mid(guess, 6, 1)
    char_7 = Mid(guess, 7, 1)
    char_8 = Mid(guess, 8, 1)
    char_9 = Mid(guess, 9, 1)
    char_10 = Mid(guess, 10, 1)
    char_11 = Mid(guess, 11, 1)
    char_12 = Mid(guess, 12, 1)
    char_13 = Mid(guess, 13, 1)
    char_14 = Mid(guess, 14, 1)
    char_15 = Mid(guess, 15, 1)
    char_16 = Mid(guess, 16, 1)
    char_17 = Mid(guess, 17, 1)
    char_18 = Mid(guess, 18, 1)
    char_19 = Mid(guess, 19, 1)
    char_20 = Mid(guess, 20, 1)
    char_21 = Mid(guess, 21, 1)
    char_22 = Mid(guess, 22, 1)
    char_23 = Mid(guess, 23, 1)
    char_24 = Mid(guess, 24, 1)
    If (Asc(char_1) Xor Asc(char_8)) = 22 Then
        If (Asc(char_10) + Asc(char_24)) = 176 Then
            If (Asc(char_9) - Asc(char_22)) = -9 Then
                If (Asc(char_22) Xor Asc(char_6)) = 23 Then
                    If ((Asc(char_12) / 5) ^ (Asc(char_3) / 12)) = 130321 Then
                        If (char_22 = char_11) Then
                            If (Asc(char_15) * Asc(char_8)) = 14040 Then
                                If (Asc(char_12) Xor (Asc(char_17) - 5)) = 5 Then
                                    If (Asc(char_18) = Asc(char_23)) Then
                                        If (Asc(char_13) Xor Asc(char_14) Xor Asc(char_2)) = 121 Then
                                            If (Asc(char_14) Xor Asc(char_24)) = 77 Then
                                                If 1365 = (Asc(char_22) Xor 1337) Then
                                                    If (Asc(char_10) = Asc(char_7)) Then
                                                        If (Asc(char_23) + Asc(char_8)) = 235 Then
                                                            If Asc(char_16) = (Asc(char_17) + 19) Then
                                                                If (Asc(char_19)) = 107 Then
                                                                    If (Asc(char_20) + 501) = (Asc(char_1) * 5) Then
                                                                        If (Asc(char_21) = Asc(char_22)) Then
                                                                            MsgBox "you got the flag!"
                                                                        End If
                                                                    End If
                                                                End If
                                                            End If
                                                        End If
                                                    End If
                                                End If
                                            End If
                                        End If
                                    End If
                                End If
                            End If
                        End If
                    End If
                End If
            End If
        End If
    End If
End Sub



+----------+--------------------+---------------------------------------------+
|Type      |Keyword             |Description                                  |
+----------+--------------------+---------------------------------------------+
|Suspicious|Xor                 |May attempt to obfuscate specific strings    |
|          |                    |(use option --deobf to deobfuscate)          |
|Suspicious|Hex Strings         |Hex-encoded strings were detected, may be    |
|          |                    |used to obfuscate strings (option --decode to|
|          |                    |see all)                                     |
|Suspicious|Base64 Strings      |Base64-encoded strings were detected, may be |
|          |                    |used to obfuscate strings (option --decode to|
|          |                    |see all)                                     |
+----------+--------------------+---------------------------------------------+

フラグの条件は以下のようになっている。

・x[0] ^ x[7] == 22
・x[9] + x[23] == 176
・x[8] - x[21] == -9
・x[21] ^ x[5] == 23
・(x[11] / 5) ^ (x[2] / 12) == 130321
 130321を素因数分解すると、19 ^ 4であることがわかる。
 → x[11] / 5 == 19 → x[11] == 95
 → x[2] / 12 == 4  → x[2] == 48
・x[21] == x[10]
・x[14] * x[7] == 14040
・x[11] ^ (x[16] - 5) == 5
・x[17] == x[22]
・x[12] ^ x[13] ^ x[1] == 121
・x[13] ^ x[23] == 77
・1365 == x[21] ^ 1337
・x[9] == x[6]
・x[22] + x[7] == 235
・x[15] == x[16] + 19
・x[18] == 107
・x[19] + 501 == x[0] * 5
・x[20] == x[21]

フラグの形式も条件に入れ、わかるものから割り出していく。

x[0] = ord('n') = 110
x[1] = ord('o') = 48
x[3] = ord('b') = 98
x[4] = ord('z') = 122
x[5] = ord('{') = 123
x[23] = ord('}') = 125

(x[11] / 5) ^ (x[2] / 12) == 130321から以下がわかる。

x[11] == 95
x[2] = 48

x[0] ^ x[7] == 22から以下がわかる。

x[7] = x[0] ^ 22 = 120

このようにして全部割り出していく。

#!/usr/bin/env python3
x = [0] * 24

flag_head = 'n00bz{'
flag_tail = '}'

for i in range(len(flag_head)):
    x[i] = ord(flag_head[i])

x[23] = ord(flag_tail)

x[11] = 95
x[7] = x[0] ^ 22
x[9] = 176 - x[23]
x[21] = x[5] ^ 23
x[8] = x[21] - 9
x[10] = x[21]
x[14] = 14040 // x[7]
x[16] = (x[11] ^ 5) + 5
x[13] = x[23] ^ 77
x[12] = x[13] ^ x[1] ^ 121
assert x[21] == 1365 ^ 1337
x[6] = x[9]
x[22] = 235 - x[7]
x[17] = x[22]
x[15] = x[16] + 19
x[18] = 107
x[19] = x[0] * 5 - 501
x[20] = x[21]

flag = ''.join([chr(c) for c in x])
print(flag)
n00bz{3xc3l_y0ur_sk1lls}

Plane (Forensics)

写真が撮影された場所の緯度、経度を答える問題。

$ exiftool plane.jpg                                            
ExifTool Version Number         : 12.76
File Name                       : plane.jpg
Directory                       : .
File Size                       : 208 kB
File Modification Date/Time     : 2024:08:03 11:06:09+09:00
File Access Date/Time           : 2024:08:03 11:06:20+09:00
File Inode Change Date/Time     : 2024:08:03 11:06:09+09:00
File Permissions                : -rwxrwxrwx
File Type                       : JPEG
File Type Extension             : jpg
MIME Type                       : image/jpeg
Exif Byte Order                 : Big-endian (Motorola, MM)
X Resolution                    : 72
Y Resolution                    : 72
Resolution Unit                 : inches
Y Cb Cr Positioning             : Centered
GPS Version ID                  : 2.3.0.0
GPS Latitude Ref                : North
GPS Longitude Ref               : West
Profile CMM Type                : 
Profile Version                 : 2.1.0
Profile Class                   : Display Device Profile
Color Space Data                : RGB
Profile Connection Space        : XYZ
Profile Date Time               : 0000:00:00 00:00:00
Profile File Signature          : acsp
Primary Platform                : Unknown ()
CMM Flags                       : Not Embedded, Independent
Device Manufacturer             : 
Device Model                    : 
Device Attributes               : Reflective, Glossy, Positive, Color
Rendering Intent                : Media-Relative Colorimetric
Connection Space Illuminant     : 0.9642 1 0.82491
Profile Creator                 : 
Profile ID                      : 0
Profile Description             : sRGB
Red Matrix Column               : 0.43607 0.22249 0.01392
Green Matrix Column             : 0.38515 0.71687 0.09708
Blue Matrix Column              : 0.14307 0.06061 0.7141
Red Tone Reproduction Curve     : (Binary data 40 bytes, use -b option to extract)
Green Tone Reproduction Curve   : (Binary data 40 bytes, use -b option to extract)
Blue Tone Reproduction Curve    : (Binary data 40 bytes, use -b option to extract)
Media White Point               : 0.9642 1 0.82491
Profile Copyright               : Google Inc. 2016
Image Width                     : 3000
Image Height                    : 4000
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                      : 3000x4000
Megapixels                      : 12.0
GPS Latitude                    : 13 deg 22' 12.00" N
GPS Longitude                   : 13 deg 22' 12.00" W
GPS Position                    : 13 deg 22' 12.00" N, 13 deg 22' 12.00" W

https://www.motohasi.net/GPS/PosConv.phpで小数の形式に変換する。

n00bz{13.37,-13.37}

Wave (Forensics)

バイナリエディタを見ると、先頭4バイトと9~15バイト目、37~40バイト目が"0"になっていることがわかる。それぞれ、"RIFF"、"WAVEfmt"、"data"に修正してみる。
Audacityで開くと、モールス信号になっていることがわかる。

-... . . .--. -... --- .--. -- --- .-. ... . -.-. --- -.. .

デコードすると、以下のようになる。

BEEPBOPMORSECODE
n00bz{beepbopmorsecode}

Disk Golf (Forensics)

Autopsyで開き、/home/johnhackerdoe/flag.txtをエクスポートする。flag.txtには以下のように書いてある。

156 60 60 142 172 173 67 150 63 137 154 60 156 147 137 64 167 64 61 164 63 144 137 144 61 65 153 137 146 60 162 63 156 163 61 143 65 175

8進数と推測しデコードする。

>>> s = '156 60 60 142 172 173 67 150 63 137 154 60 156 147 137 64 167 64 61 164 63 144 137 144 61 65 153 137 146 60 162 63 156 163 61 143 65 175'
>>> ''.join([chr(int(c, 8)) for c in s.split(' ')])
'n00bz{7h3_l0ng_4w41t3d_d15k_f0r3ns1c5}'
n00bz{7h3_l0ng_4w41t3d_d15k_f0r3ns1c5}

Vinegar (Crypto)

Vigenere暗号と推測し、https://www.dcode.fr/vigenere-cipherで復号する。

vigenerecipherisfun
n00bz{vigenerecipherisfun}

RSA (Crypto)

cがnよりビット数が少なく、eが小さいため、Low Public-Exponent Attackで復号する。

#!/usr/bin/env python3
from Crypto.Util.number import *
import gmpy2

with open('encryption.txt', 'r') as f:
    params = f.read().splitlines()

e = int(params[0].split(' ')[-1])
c = int(params[2].split(' ')[-1])

m, success = gmpy2.iroot(c, e)
assert success == True
flag = long_to_bytes(m).decode()
print(flag)
n00bz{crypt0_1s_1nc0mpl3t3_w1th0ut_rs4!!}

Vinegar 2 (Crypto)

以下の文字列を使ったVigenere暗号になっている。

'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*(){}_?'

鍵は以下であることがわかっているので、逆算して復号する。

'5up3r_s3cr3t_k3y_f0r_1337h4x0rs_r1gh7?'
#!/usr/bin/env python3
alphanumerical = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*(){}_?'
key = '5up3r_s3cr3t_k3y_f0r_1337h4x0rs_r1gh7?'

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

flag = ''
for i in range(len(enc)):
    idx1 = alphanumerical.index(enc[i])
    idx2 = alphanumerical.index(key[i])
    idx = (idx1 - idx2) % len(alphanumerical)
    flag += alphanumerical[idx]
print(flag)
n00bz{4lph4num3r1c4l_1s_n0t_4_pr0bl3m}

Random (Crypto)

サーバの処理概要は以下の通り。

・s: 入力
・sに同じ文字が含まれている場合、エラー
・sの長さが10より小さい場合、エラー
・sの長さが69の場合、エラー
・sの各文字の順序についてシャッフル
・ret = amazingcustomsortingalgorithm(s)
 ・n: sの長さ
 ・0以上69未満のiについて、以下を実行
  ・good = true
  ・文字の順序で小さい順から並んでいたら、good = true
  ・goodがtrueの場合、trueを返却
  ・sの各文字の順序についてシャッフル
 ・falseを返却
・retがtrueの場合、フラグを表示

適当な文字列で試してみる。

$ nc challs.n00bzunit3d.xyz 10161
abcdefghij
edhiafcbgj
afhiedjcbg
fhgdiecabj
egacibdjfh
eafbhjgcid
difgbhceaj
aegcjfidbh
bdgichfjae
fbhjiagecd
gfjebhaicd
caibdghfej
ifjcgeahdb
cdajfbhieg
fgdhciejba
fjcbdgahei
acebdjfhgi
acbgheijfd
ahfjicgedb
iceabjgfhd
hiegcfdbaj
igbchfeajd
hdbjacgief
jcebaifhgd
iegajhdcbf
gibjfadehc
igejcfhbad
eghacibfjd
cdfeiajghb
adbhgicfje
cdiaefjghb
acdbgifehj
djieabghfc
dbgaeicfjh
edicagjhfb
ifeahgcjdb
cdbeajigfh
hbigaedfjc
jbfhcaiegd
gidbehcjaf
ihafcbgejd
cjdegbfhia
hfdcgaiejb
fahcbegdij
gbdehajicf
idjhgbcafe
hfbgcajdei
jcaedfbhig
jhgdaibfce
cihgjfeadb
jgeaidfcbh
gdieafjchb
feadbhgcji
hcbjaidegf
hcdeibajgf
igfhejbadc
beadhgfcij
fdaicbgjeh
efidgbcahj
bghfadeijc
igjcdfehab
hebijadfcg
hfdgjcaibe
bjgfcdehia
cdbaefhjig
iahfbdegcj
bdcihfgaje
dhgfibaecj
dhjfbgceia
feihacgbjd
UNWORTHY USER DETECTED

最初に以下のようにシャッフルされている。

abcdefghij → edhiafcbgj

文字列の長さが変わらない場合、シャッフルのされ方は変わらないので、順番を考えて指定する。

ehgbaficdj
$ nc challs.n00bzunit3d.xyz 10161
ehgbaficdj
abcdefghij
n00bz{5up3r_dup3r_ultr4_54f3_p455w0rd_58dc49b79aa3}
n00bz{5up3r_dup3r_ultr4_54f3_p455w0rd_58dc49b79aa3}