Ugra CTF Quals 2021 Writeup

この大会は2021/2/27 16:00(JST)~2021/3/1 4:00(JST)に開催されました。
今回もチームで参戦。結果は450点で139チーム中53位でした。
自分で解けた問題をWriteupとして書いておきます。

nothingtosee (WEB 100)

証明書が無効になっているので、証明書を見てみる。
Netscape コメントにフラグがあった。
f:id:satou-y:20210316064844p:plain

ugra_v1_p0sm0tr3l1_5b566c0581c4

developers (FORENSICS 200)

$ cat .git/ORIG_HEAD 
86d7e5988f56123960fe5755a4f22a91acd00b56

$ python -c 'import zlib; print zlib.decompress(open(".git/objects/86/d7e5988f56123960fe5755a4f22a91acd00b56").read())'
commit 230tree d36c2293f57eca1cfd8f147c243202bd34eb4e71
parent 7116f28ab8d9b017e237f8529cfa074c0a5f2501
author Validian <validian@validian.name> 1576012530 +0845
committer Validian <validian@validian.name> 1576012530 +0845

added info.txt.

$ python -c 'import zlib; print zlib.decompress(open(".git/objects/d3/6c2293f57eca1cfd8f147c243202bd34eb4e71").read())' | xxd -g 1
00000000: 74 72 65 65 20 36 33 33 00 31 30 30 36 34 34 20  tree 633.100644 
00000010: 2e 64 69 72 2d 6c 6f 63 61 6c 73 2e 65 6c 00 49  .dir-locals.el.I
00000020: 02 7d ab 5d 0d d4 82 66 83 a6 f8 28 6e 5f 9e 39  .}.]...f...(n_.9
00000030: 55 fa c2 31 30 30 36 34 34 20 2e 67 69 74 69 67  U..100644 .gitig
00000040: 6e 6f 72 65 00 be 8a 43 4d c1 f1 3e 94 52 19 3e  nore...CM..>.R.>
00000050: 64 47 2e e3 16 47 fa 3c 60 31 30 30 36 34 34 20  dG...G.<`100644 
00000060: 2e 74 72 61 76 69 73 2e 79 6d 6c 00 19 de 5d ff  .travis.yml...].
00000070: a7 45 f1 12 2d 65 7d 9c c1 71 b9 6e 63 fc de 14  .E..-e}..q.nc...
00000080: 31 30 30 36 34 34 20 4c 49 43 45 4e 53 45 00 ba  100644 LICENSE..
00000090: 78 cc 23 7c ff 9e 7d 0a e0 94 e9 78 c0 aa 27 d6  x.#|..}....x..'.
000000a0: 20 1f 2c 31 30 30 37 35 35 20 4d 61 6b 65 66 69   .,100755 Makefi
000000b0: 6c 65 00 56 74 91 f4 b1 89 b6 d9 9e 46 5d 84 a8  le.Vt.......F]..
000000c0: 8e 73 a4 c7 73 ff c8 31 30 30 36 34 34 20 52 45  .s..s..100644 RE
000000d0: 41 44 4d 45 2e 6d 64 00 a0 3c 4e 2f 7e 86 45 fa  ADME.md..<N/~.E.
000000e0: 82 b0 32 98 d6 6d 7a 92 6b e3 51 f1 31 30 30 37  ..2..mz.k.Q.1007
000000f0: 35 35 20 62 6f 6f 74 73 74 72 61 70 2e 73 68 00  55 bootstrap.sh.
00000100: 50 6b 16 0f 7b 02 07 33 b5 35 c7 cd ac 31 9f 2c  Pk..{..3.5...1.,
00000110: 1e 64 60 25 31 30 30 37 35 35 20 63 6f 6e 66 69  .d`%100755 confi
00000120: 67 75 72 65 00 db 1a 12 8d f7 d8 7f cd a8 66 54  gure..........fT
00000130: 32 57 1c 36 59 50 f0 fa 3f 31 30 30 36 34 34 20  2W.6YP..?100644 
00000140: 63 6f 6e 66 69 67 75 72 65 2e 6b 61 66 6b 61 63  configure.kafkac
00000150: 61 74 00 05 d2 bb 5a 4c 67 eb 69 09 13 a8 1d 5b  at....ZLg.i....[
00000160: ee fc 5b 80 4c af 43 31 30 30 36 34 34 20 66 6f  ..[.L.C100644 fo
00000170: 72 6d 61 74 2e 63 00 25 ba 84 47 6a 5b f3 39 cc  rmat.c.%..Gj[.9.
00000180: db d4 1e 25 e6 1a 41 e6 13 f3 eb 31 30 30 36 34  ...%..A....10064
00000190: 34 20 69 6e 66 6f 2e 74 78 74 00 f0 80 0f f8 40  4 info.txt.....@
000001a0: 7d 8b ce 0b 30 87 97 2a 4e 8e ec 52 c0 28 66 31  }...0..*N..R.(f1
000001b0: 30 30 36 34 34 20 6a 73 6f 6e 2e 63 00 41 64 8d  00644 json.c.Ad.
000001c0: b3 b9 af 07 f7 87 83 3b 0e f3 b7 6f c4 48 fb 15  .......;...o.H..
000001d0: 6f 31 30 30 36 34 34 20 6b 61 66 6b 61 63 61 74  o100644 kafkacat
000001e0: 2e 31 00 ea 7c e5 40 3a 9a c1 64 fe 59 6b ac 2a  .1..|.@:..d.Yk.*
000001f0: b6 3d 5d 9f 3d 86 d2 31 30 30 36 34 34 20 6b 61  .=].=..100644 ka
00000200: 66 6b 61 63 61 74 2e 63 00 36 c6 98 4b 33 ee 7e  fkacat.c.6..K3.~
00000210: 68 5d 6c 68 a0 ad 2b 75 f6 33 89 f6 b3 31 30 30  h]lh..+u.3...100
00000220: 36 34 34 20 6b 61 66 6b 61 63 61 74 2e 68 00 3d  644 kafkacat.h.=
00000230: 35 4e e5 33 27 c2 4a 41 49 8c 05 d2 68 9a 4f e7  5N.3'.JAI...h.O.
00000240: 86 cf 2b 34 30 30 30 30 20 6d 6b 6c 6f 76 65 00  ..+40000 mklove.
00000250: 96 2c 50 5e 77 ce 27 89 0e a6 13 40 1e 43 9f 23  .,P^w.'....@.C.#
00000260: 3c 72 21 b2 34 30 30 30 30 20 72 70 6d 00 db 39  <r!.40000 rpm..9
00000270: f1 0d 69 16 dd 4c da e3 34 24 64 16 8f ae c7 80  ..i..L..4$d.....
00000280: 0d 11 0a                                         ...

info.txtの情報を見てみる。

$ python -c 'import zlib; print zlib.decompress(open(".git/objects/f0/800ff8407d8bce0b3087972a4e8eec52c02866").read())'
blob 282If you are reading this, I am definitely dead by now.

I also know that by reaching this file, you have demonstrated
the best of your ability and courage. Here is the key to my
lifetime secret: ugra_the_yellow_purse_c79f005f1610f86a

You will understand what to do next. Good luck!

info.txtにフラグが書いてあった。

ugra_the_yellow_purse_c79f005f1610f86a

apl (CRYPTO 150)

APL言語。https://en.wikipedia.org/wiki/APL_syntax_and_symbolsを参考に読み解く。

A ← 'abcdefghijklmnopqrstuvwxy_1234567890'

I ← (6 6 ⍴ 1 + ⍳6)+⍉(10 × 6 6 ⍴ 1 + ⍳6)

11 12 13 14 15 16
21 22 23 24 25 26
31 32 33 34 35 36
41 42 43 44 45 46
51 52 53 54 55 56
61 62 63 64 65 66

S ← 6 6 ⍴ A
abcdef
ghijkl
mnopqr
stuvwx
y_1234
567890

E ← {⌈/⌈/ (~⍵ ⍳ S) × I}
E¨flag

以下のように暗号化している数字で対応する文字に置き換えて復号する。

11 -> a
12 -> b
   :
61 -> 5
   :
66 -> 0
def get_index(code):
    c1 = int(code[0]) - 1
    c2 = int(code[1]) - 1
    return c1 * 6 + c2

A = 'abcdefghijklmnopqrstuvwxy_1234567890'
enc = '43 21 36 11 52 42 22 15 52 32 15 46 42 52 41 42 11 42 23 33 32 52 23 41 52 15 41 33 42 15 36 23 13 52 34 36 33 21 36 11 31 31 23 32 21 52 54 12 53 64 65 66 55 63 66 62 65 65 56 11 63 13 13 54 12 62 63 12 14 53 62 13 54 53 64 56 13 11 62 62 62 62 63 64 13 16 15 54 65 54 62 15 63 15 12 54 13 15 63 62 13 63 54 11'
codes = enc.split(' ')

flag = ''
for c in codes:
    index = get_index(c)
    flag += A[index]
print flag
ugra_the_next_station_is_esoteric_programming_2b18903706994a7cc2b67bd16c2184ca666678cfe2926e7eb2ce76c72a

Tenable CTF 2021 Writeup

この大会は2021/2/18 21:00(JST)~2021/2/22 21:00(JST)に開催されました。
今回もチームで参戦。結果は3925点で1762チーム中53位でした。
自分で解けた問題をWriteupとして書いておきます。

Intro 1 (_Introduction 25)

問題にフラグが書いてあった。

flag{some_clever_text}

Intro 2 (_Introduction 25)

Doscordに入ると、#generalチャネルのトピックにフラグが書いてあった。

flag{you_f0und_m3}

Esoteric (Misc 25)

Brainf*ck言語。https://sange.fi/esoteric/brainfuck/impl/interp/i.htmlで実行する。

flag{wtf_is_brainfuck}

Quit messing with my flags (Misc 25)

161EBD7D45089B3446EE4E0D86DBCF92をmd5の逆変換として検索する。

https://md5.gromweb.com/?md5=161ebd7d45089b3446ee4e0d86dbcf92
⇒P@ssw0rd
flag{P@ssw0rd}

One Byte at a Time (Misc 50)

$ nc challenges.ctfd.io 30468

Show me how much of the flag you know and I'll help you with the rest.'

[flag]>f

You seem to know the first 1 characters of the flag!
XORing the next flag character with a random octet taken from some unknown IPv4 address I have...

0x1b


$ nc challenges.ctfd.io 30468

Show me how much of the flag you know and I'll help you with the rest.'

[flag]>fl

You seem to know the first 2 characters of the flag!
XORing the next flag character with a random octet taken from some unknown IPv4 address I have...

0x16

>>> 0x1b ^ ord('l')
119
>>> 0x16 ^ ord('a')
119

$ nc challenges.ctfd.io 30468

Show me how much of the flag you know and I'll help you with the rest.'

[flag]> 

You seem to know the first 0 characters of the flag!
XORing the next flag character with a random octet taken from some unknown IPv4 address I have...

0x76

>>> 0x76 ^ ord('f')
16

$ nc challenges.ctfd.io 30468

Show me how much of the flag you know and I'll help you with the rest.'

[flag]>

You seem to know the first 0 characters of the flag!
XORing the next flag character with a random octet taken from some unknown IPv4 address I have...

0x64

>>> 0x64 ^ ord('f')
2

$ nc challenges.ctfd.io 30468

Show me how much of the flag you know and I'll help you with the rest.'

[flag]>    

You seem to know the first 0 characters of the flag!
XORing the next flag character with a random octet taken from some unknown IPv4 address I have...

0x11

>>> 0x11 ^ ord('f')
119

とりあえずXOR鍵は、16, 2, 119のどれか。プログラムで119の1点張りで復号する。

import socket

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

key = 119

flag = ''
c = ''
while True:
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect(('challenges.ctfd.io', 30468))

    data = recvuntil(s, '>')
    print data + flag + c
    s.sendall(flag + c + '\n')

    data = recvuntil(s, '\n').rstrip()
    print data
    data = recvuntil(s, '\n').rstrip()
    print data
    if data.startswith('You seem'):
        flag += c
        if 'character' not in data:
            break
        data = recvuntil(s, '\n').rstrip()
        print data
        data = recvuntil(s, '\n').rstrip()
        print data
        data = recvuntil(s, '\n').rstrip()
        print data
        code = eval(data)
        c = chr(code ^ key)
    else:
        data = recvuntil(s, '\n').rstrip()
        print data
        c = ''

print flag

実行結果は以下の通り。

        :
Show me how much of the flag you know and I'll help you with the rest.'

[flag]>flag{f0ll0w_th3_whit3_r@bb1t

You seem to know the first 28 characters of the flag!
XORing the next flag character with a random octet taken from some unknown IPv4 address I have...

0x0a

Show me how much of the flag you know and I'll help you with the rest.'

[flag]>flag{f0ll0w_th3_whit3_r@bb1t}

You seem to know it all. Can't help you anymore
flag{f0ll0w_th3_whit3_r@bb1t}
flag{f0ll0w_th3_whit3_r@bb1t}

Forwards from Grandma (Misc 100)

メールのSubjectにこう書いてある。

FWD: FWD: RE: FWD:  FWD: RE: FWD: FWD:  FWD: RE:  RE: RE: FWD: { FWD:
 FWD:  FWD: FWD: RE: RE: FWD: RE:  RE: RE:  FWD: FWD:  FWD: FWD: FWD:  FWD:
 FWD: FWD:  FWD: FWD: RE: RE: FWD: RE:  FWD: RE:  RE: RE: RE:  FWD: RE: FWD:
 FWD: } THIS IS HILARIOUS AND SO TRUE

FWD: を "."、RE: を"-"にすると、" "区切りでモールス信号になっているので、デコードする。

..-. .-.. .- --. {.. ..--.- -- .. ... ... ..--.- .- --- .-..}
flag{i_miss_aol}

Parsey Mcparser (Code 50)

指定したグループ名のユーザ名をリストで返すようスクリプトを組む。以下のスクリプトで通った。

def ParseNamesByGroup(blob, group_name):
    uname = []
    arr = blob.split('+++,')[1:]
    for a in arr:
        data = a.split(',', 1)[1]
        info = data[1:-1].split(',[')
        for i in info:
            info = eval('{' + i.rstrip(']') + '}')
            group = info['Group']
            if group == group_name:
                uname.append(info['user_name'])
    return uname
   
data = raw_input()
group_name = data.split('|')[0]
blob = data.split('|')[1]
result_names_list = ParseNamesByGroup(blob, group_name)
print result_names_list

Random Encryption (Code 100)

コードの中に記載されているフラグで通った。

flag{n0t_that_r4ndom}

Random Encryption Fixed (Code 100)

seedを使った乱数なので、XOR鍵を割り出せる。XOR鍵を割り出したら、その鍵で復号する。

#!/usr/bin/python3
import random

rand_list = [[249, 182, 79], [136, 198, 95], [159, 167, 6], [223, 136, 101], [66, 27, 77], [213, 234, 239], [25, 36, 53], [89, 113, 149], [65, 127, 119], [50, 63, 147], [204, 189, 228], [228, 229, 4], [64, 12, 191], [65, 176, 96], [185, 52, 207], [37, 24, 110], [62, 213, 244], [141, 59, 81], [166, 50, 189], [228, 5, 16], [59, 42, 251], [180, 239, 144], [13, 209, 132]]
res = [184, 161, 235, 97, 140, 111, 84, 182, 162, 135, 76, 10, 69, 246, 195, 152, 133, 88, 229, 104, 111, 22, 39]
seeds = [9925, 8861, 5738, 1649, 2696, 6926, 1839, 7825, 6434, 9699, 227, 7379, 9024, 817, 4022, 7129, 1096, 4149, 6147, 2966, 1027, 4350, 4272]

flag = ''
for i in range(len(res)):
    random.seed(seeds[i])
    rands = []
    for j in range(4):
        rands.append(random.randint(0, 255))
    key = rands[i % 4]
    del rands[i % 4]
    assert rands == rand_list[i]
    flag += chr(res[i] ^ key)

print(flag)
flag{Oppsie_LULZ_fixed}

Find Largest Triangle (Code 125)

三角形の面積は以下の式で求められる。

S = |(B - A) × (C - A)| /  2
※"×"は外積

これを使って、全組合せで面積の最大値を返すようスクリプトを組む。以下のスクリプトで通った。

import math
import itertools

def ext_prod(a, b):
    v_aa = a + a[0:2]
    v_bb = b + b[0:2]
    v_o =[]
    for i in range(len(a)):
        v_o.append(v_aa[i+1] * v_bb[i+2] - v_aa[i+2] * v_bb[i+1])
    return v_o

def calc_area(p1, p2, p3):
    pt1 = [e2 - e1 for e1, e2 in zip(p1, p2)]
    pt2 = [e3 - e1 for e1, e3 in zip(p1, p3)]
    prod = ext_prod(pt1, pt2)
    size = math.sqrt(sum([pow(x, 2) for x in prod]))
    area = size / 2
    return area

def FindLargestTriangleArea(points):
    max_area = 0
    for p in itertools.combinations(points, 3):
        area = calc_area(p[0], p[1], p[2])
        if max_area < area:
            max_area = area
    return max_area

# Reading space delimited points from stdin
# and building list of 3D points
points_data = raw_input()
points = []
for point in points_data.split(' '):
  point_xyz = point.split(',')
  points.append([int(point_xyz[0]), int(point_xyz[1]), int(point_xyz[2])])

# Compute Largest Triangle and Print Area rounded to nearest whole number
area = FindLargestTriangleArea(points)
print int(round(area))

We Need an Emulator (Code 150)

XOR, MOV, REVERSEのオペランドレジスタもTRX, DRXしかないので、全パターンをプログラムで作成する。

def xor(a, b):
    if len(a) > len(b):
        s1 = a
        s2 = b + '\x00' * (len(a) - len(b))
    else:
        s1 = a + '\x00' * (len(b) - len(a))
        s2 = b
    return ''.join(chr(ord(x) ^ ord(y)) for x, y in zip(s1, s2))

with open('Crypto.asm', 'r') as f:
    lines = [line.rstrip() for line in f.readlines()]

trx = 'GED\x03hG\x15&Ka =;\x0c\x1a31o*5M'
drx = ''

for line in lines:
    op = line.split(' ')[0]
    if op == 'XOR':
        arg1 = line.split(' ')[1]
        arg2 = line.split(' ')[2]
        if arg2 == 'TRX':
            arg2 = trx
        else:
            arg2 = drx
        if arg1 == 'TRX':
            trx = xor(trx, arg2)
        else:
            drx = xor(drx, arg2)
    elif op == 'MOV':
        arg1 = line.split(' ')[1]
        arg2 = line.split(' ')[2]
        if arg2 == 'TRX':
            arg2 = trx
        elif arg2 == 'DRX':
            arg2 = drx
        else:
            arg2 = eval(arg2)
        if arg1 == 'TRX':
            trx = arg2
        else:
            drx = arg2
    else:
        arg1 = line.split(' ')[1]
        if arg1 == 'TRX':
            trx = trx[::-1]
        else:
            drx = drx[::-1]

print trx
flag{N1ce_Emul8tor!1}

The only tool you'll ever need (Reverse Engineering 25)

$ strings a.out | grep flag
flag{str1ngs_FTW}
Enter the password to get the flag:
flag{str1ngs_FTW}

Stay Away Creepy Crawlers (Web App 25)

http://167.71.246.232/robots.txtにアクセスすると、フラグが書いてあった。

User-agent: *
Disallow: /admin/
# flag{mr_roboto}
flag{mr_roboto}

Source of All Evil (Web App 25)

HTMLソースを見ると、フラグが書いてあった。

flag{best_implants_ever}

Can't find it (Web App 25)

適当なパス(例:http://167.71.246.232/a)にアクセスすると、エラーページが表示され、フラグが書いてある。

flag{404_oh_no}

Show me what you got (Web App 25)

http://167.71.246.232/imagesにアクセスすると、indexが見えている。
http://167.71.246.232/images/aljdi3sd.txtにアクセスするとフラグが書いてあった。

flag{disable_directory_indexes}

Certificate of Authenticity (Web App 25)

httpsでアクセスし、証明書を見ると、フラグが書いてあった。
f:id:satou-y:20210227093330p:plain

flag{selfsignedcert}

Headers for you inspiration (Web App 25)

レスポンスヘッダにフラグがあった。

flag{headersftw}

Spring MVC 1 (Web App 25)

src/main/java/com/tenable/ctf/mvc/MainController.javaを見る。

	@GetMapping("/main")
        public ModelAndView getMain() {
		ModelAndView modelAndView = new ModelAndView("flag");
                modelAndView.addObject("flag", flags.getFlag("spring_mvc_1"));	// get main
                return modelAndView;
        }

GETメソッドで/mainにアクセスすればよい。http://challenges.ctfd.io:30542/mainにアクセスすると、フラグが表示された。

flag{flag1_517d74}

Spring MVC 2 (Web App 25)

src/main/java/com/tenable/ctf/mvc/MainController.javaを見る。

	@PostMapping("/main")
        public String postMain(@RequestParam(name="magicWord", required=false, defaultValue="") String magicWord, Model model) {
		if (magicWord.equals("please"))
			model.addAttribute("flag", flags.getFlag("spring_mvc_3"));	// post main param 
		else
                	model.addAttribute("flag", flags.getFlag("spring_mvc_2"));	// post main
                return "flag";
        }

POSTメソッドでmagicWordに"please"以外の値をセットして/mainにアクセスすればよい。

$ curl http://challenges.ctfd.io:30542/main -d 'magicWord=a'
<!DOCTYPE HTML>
<html>
<head>
    <title>Tenable CTF: Spring MVC</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
	<p >flag{flag2_de3981}</p>
</body>
</html>
flag{flag2_de3981}

Spring MVC 3 (Web App 25)

src/main/java/com/tenable/ctf/mvc/MainController.javaを見る。

	@PostMapping("/main")
        public String postMain(@RequestParam(name="magicWord", required=false, defaultValue="") String magicWord, Model model) {
		if (magicWord.equals("please"))
			model.addAttribute("flag", flags.getFlag("spring_mvc_3"));	// post main param 
		else
                	model.addAttribute("flag", flags.getFlag("spring_mvc_2"));	// post main
                return "flag";
        }

POSTメソッドでmagicWordに"please"をセットして/mainにアクセスすればよい。

$ curl http://challenges.ctfd.io:30542/main -d 'magicWord=please'
<!DOCTYPE HTML>
<html>
<head>
    <title>Tenable CTF: Spring MVC</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
	<p >flag{flag3_0d431e}</p>
</body>
</html>
flag{flag3_0d431e}

Spring MVC 4 (Web App 25)

src/main/java/com/tenable/ctf/mvc/MainController.javaを見る。

	@PostMapping(path = "/main", consumes = "application/json")
	public String postMainJson(Model model) {
                model.addAttribute("flag", flags.getFlag("spring_mvc_4"));	// post main flag json
                return "flag";
        }

POSTメソッドでapplication/jsonのコンテンツタイプを指定して/mainにアクセスすればよい。

$ curl http://challenges.ctfd.io:30542/main -H "Content-Type: application/json" -X POST
<!DOCTYPE HTML>
<html>
<head>
    <title>Tenable CTF: Spring MVC</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
	<p >flag{flag4_695954}</p>
</body>
</html>
flag{flag4_695954}

Spring MVC 5 (Web App 25)

src/main/java/com/tenable/ctf/mvc/MainController.javaを見る。

	@RequestMapping(path = "/main", method = RequestMethod.OPTIONS)
        public String optionsMain(Model model) {
                model.addAttribute("flag", flags.getFlag("spring_mvc_5"));	// options main
                return "flag";
        }

OPTIONSメソッドで/mainにアクセスすればよい。

$ curl http://challenges.ctfd.io:30542/main -X OPTIONS
<!DOCTYPE HTML>
<html>
<head>
    <title>Tenable CTF: Spring MVC</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
	<p >flag{flag5_70102b}</p>
</body>
</html>
flag{flag5_70102b}

Spring MVC 6 (Web App 25)

src/main/java/com/tenable/ctf/mvc/MainController.javaを見る。

	@RequestMapping(path = "/main", method = RequestMethod.GET, headers = "Magic-Word=please")
        public String headersMain(Model model) {
                model.addAttribute("flag", flags.getFlag("spring_mvc_6"));	// headers main
                return "flag";
        }

GETメソッドでHTTPヘッダに"Magic-Word: please"をセットして/mainにアクセスすればよい。

$ curl http://challenges.ctfd.io:30542/main -H 'Magic-Word: please'
<!DOCTYPE HTML>
<html>
<head>
    <title>Tenable CTF: Spring MVC</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
	<p >flag{flag6_ca1ddf}</p>
</body>
</html>
flag{flag6_ca1ddf}

Ripper Doc (Web App 50)

Cookieのauthenticatedの値をfalseからtrueに変更して、http://167.71.246.232/certified_rippers.phpにアクセスすると、フラグが表示された。

flag{messing_with_cookies}

Protected Directory (Web App 50)

http://167.71.246.232/.htpasswdにアクセスする。

admin:$apr1$1U8G15kK$tr9xPqBn68moYoH4atbg20

パスワードクラックする。

$ john .htpasswd           
Warning: detected hash type "md5crypt", but the string is also recognized as "md5crypt-long"
Use the "--format=md5crypt-long" option to force loading these as that type instead
Using default input encoding: UTF-8
Loaded 1 password hash (md5crypt, crypt(3) $1$ (and variants) [MD5 256/256 AVX2 8x3])
Proceeding with single, rules:Single
Press 'q' or Ctrl-C to abort, almost any other key for status
Warning: Only 2 candidates buffered for the current salt, minimum 24 needed for performance.
Warning: Only 20 candidates buffered for the current salt, minimum 24 needed for performance.
Warning: Only 23 candidates buffered for the current salt, minimum 24 needed for performance.
Warning: Only 21 candidates buffered for the current salt, minimum 24 needed for performance.
Warning: Only 13 candidates buffered for the current salt, minimum 24 needed for performance.
Almost done: Processing the remaining buffered candidate passwords, if any.
Warning: Only 15 candidates buffered for the current salt, minimum 24 needed for performance.
Proceeding with wordlist:/usr/share/john/password.lst, rules:Wordlist
Warning: Only 4 candidates left, minimum 24 needed for performance.
Proceeding with incremental:ASCII
alesh16          (admin)
1g 0:00:00:11 DONE 3/3 (2021-02-19 11:29) 0.08532g/s 88568p/s 88568c/s 88568C/s alesio2..alemeis
Use the "--show" option to display all of the cracked passwords reliably
Session completed

http://167.71.246.232/adminにアクセスし、以下の認証情報で認証すると、フラグが表示された。

admin / alesh16
flag{cracked_the_password}

Hackerman (Stego 25)

$ strings silly_hacker.svg | grep flag
       style="font-size:1.25px;fill:#808080">flag{m1cr0dot}</tspan></text>
flag{m1cr0dot}

Secret Images (Stego 125)

各RGBのXORを取ってみると、フラグが現れた。

from PIL import Image

o_img = Image.open('crypted1.png').convert('RGB')
e_img = Image.open('crypted2.png').convert('RGB')

w, h = o_img.size

output_img = Image.new('RGB', (w, h), (255, 255, 255))

for y in range(h):
    for x in range(w):
        r1, g1, b1 = o_img.getpixel((x, y))
        r2, g2, b2 = e_img.getpixel((x, y))
        output_img.putpixel((x, y), (r1 ^ r2, g1 ^ g2, b1 ^ b2))

output_img.save('flag.png')

f:id:satou-y:20210227095320p:plain

flag{otp_reuse_fail}

A3S Turtles (Stego 250)

$ fcrackzip -u -D -p dict/rockyou.txt turtles128.zip 


PASSWORD FOUND!!!!: pw == 0
$ unzip -P 0 turtles128.zip
Archive:  turtles128.zip
  inflating: turtles127.zip
$ fcrackzip -u -D -p dict/rockyou.txt turtles127.zip 


PASSWORD FOUND!!!!: pw == 0
$ unzip -P 0 turtles127.zip
Archive:  turtles127.zip
  inflating: turtles126.zip
$ fcrackzip -u -D -p dict/rockyou.txt turtles126.zip 


PASSWORD FOUND!!!!: pw == 1

パスワードは1桁の数字に決まっていそう。スクリプトを組んで試した結果はパスワードは0か1。turtle1.zipを解凍すると、key.pngが展開された。そこにはこう書いてある。

ed 57 0e 22 d4 58 e2 57 34 fc 08 d8 49 96 1d a9

問題のタイトルから考えると、AES暗号が関係しているのかもしれない。0, 1の128ビットのデータを暗号データとして、上記の鍵でAES-ECBの復号をしてみる。

import zipfile
from Crypto.Cipher import AES

def unzip_with_pwd(filename, path='.', pwd=''):
    with zipfile.ZipFile(filename, 'r') as zf:
        try:
            zf.extractall(path=path, pwd=pwd)
            return True
        except RuntimeError:
            return False

def unpad(s):
    return s[:-ord(s[-1])]

b_ct = ''
for i in range(128, 0, -1):
    fname = 'turtles%d.zip' % i
    for j in [0, 1]:
        pwd = str(j)
        res = unzip_with_pwd(fname, pwd=pwd)
        if res:
            b_ct += str(j)
            break

ct = ''.join([chr(int(b_ct[i:i+8], 2)) for i in range(0, len(b_ct), 8)])
key = 'ed570e22d458e25734fc08d849961da9'.decode('hex')

cipher = AES.new(key, AES.MODE_ECB)
flag = unpad(cipher.decrypt(ct))
print flag
flag{steg0_a3s}

Classic Crypto (Crypto 50)

Vigenere暗号。https://www.guballa.de/vigenere-solverで復号する。

There are many theories about us. That we’re anarchists, kids, crazy film-buffs that saw one too many superhero movies. The truth is, we are all these things. Anonymous is a symbol, like the flag a country flies. The flag is the symbol of the country. Our masks are our national identity. We are not Anonymous – we represent the ideals of Anonymous. Truth, freedom and the removal of censorship. Like any symbol, we affix it wherever we go, as you have seen from street protests.

We have no leaders, civilians or soldiers. We are all one. We run operations because that is what the group decides to do. We choose targets because that is what the people who represent the ideals of Anonymous want to fight for. The world is in trouble. We see it every day – war, poverty, murder. Every day we are bombarded with news and images, as we sit at home safe in the knowledge that we are powerless, that “better” minds are dealing with the situation.

But what if you could be the change you want to see? I’m twenty five years old. I went to school and college. I fought for my country then got a job and paid my taxes. If you met me on the street I wouldn’t even register on your radar. I am just another person in a sea of faces.

But in cyberspace we are different. We helped free the people of Egypt. We helped fight against Israel as it attempted genocide. We exposed more than fifty thousand paedophiles around the world. We fought the drug cartels. We have taken to the streets to fight for the rights you are letting slip through your fingers.

We are Anonymous.

The flag is "flag{classicvigenere}"

In today’s world we are seen as terrorists or at best dangerous anarchists. We’re called “cowards” and “posers” for hiding behind masks, but who is the real poser? We take away the face and leave only the message. Behind the mask we could be anyone, which is why we are judged by what we say and do, not who we are or what we have.

We exist without nationality, skin colour or religious bias.

復号した文中にフラグがあった。

flag{classicvigenere}

Easy Peasy (Crypto 50)

base64デコード、hexデコード、rot13で復号すると、フラグになった。

enc = 'NzMgNzkgNmUgNzQgN2IgNzAgNjIgNjEgNzQgNjUgNmUgNjcgNjYgNWYgNmMgNjIgNjggNWYgNzQgNjIgNjcgNWYgN2EgNzIgN2Q='
dec = enc.decode('base64')
print dec

dec = dec.replace(' ', '').decode('hex')
print dec

flag = dec.decode('rot13')
print flag

実行結果は以下の通り。

73 79 6e 74 7b 70 62 61 74 65 6e 67 66 5f 6c 62 68 5f 74 62 67 5f 7a 72 7d
synt{pbatengf_lbh_tbg_zr}
flag{congrats_you_got_me}
flag{congrats_you_got_me}

Netrunner Encryption (Crypto 200)

Source Codeをクリックすると、以下のようになっている。

<html>
<body>
  <h1>Netrunner Encryption Tool</h1>
  <a href="netrun.txt">Source Code</a>
  <form method=post action="crypto.php">
  <input type=text name="text_to_encrypt">
  <input type="submit" name="do_encrypt" value="Encrypt">
  </form>

<?php

function pad_data($data)
{
  $flag = "flag{wouldnt_y0u_lik3_to_know}"; 

  $pad_len = (16 - (strlen($data.$flag) % 16));
  return $data . $flag . str_repeat(chr($pad_len), $pad_len);
}

if(isset($_POST["do_encrypt"]))
{
  $cipher = "aes-128-ecb";
  $iv  = hex2bin('00000000000000000000000000000000');
  $key = hex2bin('74657374696E676B6579313233343536');
  echo "</br><br><h2>Encrypted Data:</h2>";
  $ciphertext = openssl_encrypt(pad_data($_POST['text_to_encrypt']), $cipher, $key, 0, $iv); 

  echo "<br/>";
  echo "<b>$ciphertext</b>";
}
?>
</body>
</html>

<入力文字列><フラグ>をAES-ECBで暗号化している。ソースコード中のflagやiv, keyは正しくないので、フラグを1文字ずつはみ出させながら、暗号を比較し平文を求める。

a
7ii97QpMPBNhknGD3igg4aKhzWdroplDGd0QSc/8pG5I/EjJ6OXYKXOVQPIDkUpB

aa
lCODIH4f3+rCvpYde8/oaAW0B7t/tMwBOtJadxcOFcZI/EjJ6OXYKXOVQPIDkUpB

aaa
HsoEuhN3CpdMSxbOv0MRcYHQ4lxtL157fCDm+Bq0zX5I/EjJ6OXYKXOVQPIDkUpB

aaaa
CdvUd/SwH2a6O4lgnmq5BeVLvLtBezfPf0Il0LGIZ+NI/EjJ6OXYKXOVQPIDkUpB

aaaaa
guFCH9dTJ1fBIZLA5iLGXZX8HlrVjaA+bkMjwPdrXXFI/EjJ6OXYKXOVQPIDkUpB

aaaaaa
zKMyyy5eAwCWk/Ui/PIlnmE0aprqGzDI8Ap/JyX8VY9I/EjJ6OXYKXOVQPIDkUpBSPxIyejl2ClzlUDyA5FKQQ==
0123456789abcdef
aaaaaaFFFFFFFFFF
FFFFFFFFFFFFFFFF
PPPPPPPPPPPPPPPP

0123456789abcdef
aaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaF
FFFFFFFFFFFFFFFF
FFFFFFFFFPPPPPPP
import requests
import re

url = 'http://167.71.246.232:8080/crypto.php'

flag = ''
for i in range(26):
    for code in range(32, 127):
        print '[+] try flag:', flag + chr(code)
        if i < 16:
            text = 'a' * (15 - i) + flag + chr(code) + 'a' * (63 - i)
        else:
            text = flag[-15:] + chr(code) + 'a' * (63 - i)
        payload = {'text_to_encrypt': text, 'do_encrypt': 'Encrypt'}
        r = requests.post(url, data=payload)
        body = r.text

        pattern = '<b>(.+)</b>'
        m = re.search(pattern, body)
        enc = m.group(1).decode('base64')
        ct0 = enc[16*0:16*1]
        ct4 = enc[16*4:16*5]
        if ct0 == ct4:
            flag += chr(code)
            break

print '[*] flag:', flag

実行結果は以下の通り。

        :
[+] try flag: flag{b4d_bl0cks_for_g0nksv
[+] try flag: flag{b4d_bl0cks_for_g0nksw
[+] try flag: flag{b4d_bl0cks_for_g0nksx
[+] try flag: flag{b4d_bl0cks_for_g0nksy
[+] try flag: flag{b4d_bl0cks_for_g0nksz
[+] try flag: flag{b4d_bl0cks_for_g0nks{
[+] try flag: flag{b4d_bl0cks_for_g0nks|
[+] try flag: flag{b4d_bl0cks_for_g0nks}
[*] flag: flag{b4d_bl0cks_for_g0nks}
flag{b4d_bl0cks_for_g0nks}

ECDSA Implementation Review (Crypto 225)

ECDSAのrが同じ場合の脆弱性の問題。kを計算できるので、それからsecretを計算できる。あとはそれを元にAESの復号をすればフラグになる。

#!/usr/bin/python3
from Crypto.Cipher import AES
from Crypto.Util.number import *
import binascii

def unpad(s):
    return s[:-s[-1]]

r = 50394691958404671760038142322836584427075094292966481588111912351250929073849
s1 = 26685296872928422980209331126861228951100823826633336689685109679472227918891
s2 = 40762052781056121604891649645502377037837029273276315084687606790921202237960

hash1 = 777971358777664237997807487843929900983351335441289679035928005996851307115
hash2 = 91840683637030200077344423945857298017410109326488651848157059631440788354195
order = 115792089210356248762697446949407573529996955224135760342422259061068512044369

k = int(((hash1 - hash2) % order) * inverse(((s1 - s2) % order), order))
secret = int((((((s1 * k) % order) - hash1) % order) * inverse(r, order)) % order)
print('[+] secret =', secret)

ct = b'f3ccfd5877ec7eb886d5f9372e97224c43f4412ca8eaeb567f9b20dd5e0aabd5'
ctxt = binascii.unhexlify(ct)

aes_key = secret.to_bytes(64, byteorder='little')[0:16]
IV = b'\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0'
cipher = AES.new(aes_key, AES.MODE_CBC, IV)
flag = unpad(cipher.decrypt(ctxt))
print('[*] flag =', flag)

実行結果は以下の通り。

[+] secret = 26924620604793025490002124762205825722410676804960639851404176074662508843402
[*] flag = b'flag{cRypt0_c4r3fully}'
flag{cRypt0_c4r3fully}

Union CTF 2021 Writeup

この大会は2021/2/20 4:00(JST)~2021/2/22 4:00(JST)に開催されました。
今回もチームで参戦。結果は110点で466チーム中213位でした。
自分で解けた問題をWriteupとして書いておきます。

Welcome (Misc)

ルールのページにサンプルとしてフラグが記載されていた。

union{r0p_s4v3_the_que3n}

Where in the World? (5) (GEOINT)

画像検索すると、中国の福州市の地図だとわかる。

Fuzhou, China

darkCON CTF Writeup

この大会は2021/2/20 19:30(JST)~2021/2/21 19:30(JST)に開催されました。
今回もチームで参戦。結果は1467点で663チーム中134位でした。
自分で解けた問題をWriteupとして書いておきます。

Sanity Check (Misc)

問題にフラグが書いてあった。

darkCON{free_Fl4g_4_every0ne_G00d_Luck}

Take It Easy (Crypto)

添付のzipファイルにはgetkey.txtとパスワード付きzipが入っている。getkey.txtにはこう書いてある。

p = 147310848610710067833452759772211595299756697892124273309283511558003008852730467644332450478086759935097628336530735607168904129699752266056721879451840506481443745340509935333411835837548485362030793140972434873394072578851922470507387225635362369992377666988296887264210876834248525673247346510754984183551
ct = 43472086389850415096247084780348896011812363316852707174406536413629129
e = 3

RSA暗号として、復号してみる。

from Crypto.Util.number import *

p = 147310848610710067833452759772211595299756697892124273309283511558003008852730467644332450478086759935097628336530735607168904129699752266056721879451840506481443745340509935333411835837548485362030793140972434873394072578851922470507387225635362369992377666988296887264210876834248525673247346510754984183551
ct = 43472086389850415096247084780348896011812363316852707174406536413629129
e = 3

phi = p - 1
d = inverse(e, phi)
m = pow(ct, d, p)
pw = long_to_bytes(m)
print pw

RSA暗号を復号した結果は以下の通り。

Ju5t_@_K3Y

これでパスワード付きzipを解凍すると、chall.pyとcipher.txtが展開された。この暗号処理の概要は以下の通り。

・chunks: フラグを4バイトブロックに分割
・2ブロック先とのXORを出している。

"darkCON{"から始まることを前提に復号する。

#!/usr/bin/env python3
from struct import pack, unpack

def Tup_Int(chunk):
    return unpack('I', chunk)[0]

ct = [b'\nQ&4', b"\x17'\x0e\x0f", b'1X5\r', b'072E', b'\x18\x00\x15/']

flag = b'darkCON{'
for i in range(5):
    block = pack("I", Tup_Int(flag[i*4:i*4+4]) ^ Tup_Int(ct[i]))
    flag += block

print(flag)
darkCON{n0T_Th@t_haRd_r1Ght}

Tony And James (Crypto)

暗号化処理は以下の通り。

・l: フラグの長さ
・raw, seed = get_seed(l)
 ・rand: lビットランダム整数
 ・以下、randが0より大きい場合に繰り返し実行
  ・rand: 1ビット右にシフト
  ・seed: randをプラス
  ・rawのリストにrandを追加
 ・rawとseedを返却
・random.seed(seed)
・以下フラグの各文字に対して実行
 ・r: 1~2**512のランダム整数
 ・i=0の場合のみ、rを表示
 ・encoded = hex(r ^ m[i] ^ raw[i])[2:]
   ⇒表示

r0はわかている。フラグが"darkCON{"で始まることからm[0]はわかる。r0、m[0]とF0からraw[0]を算出でき、rand(末尾1ビットは動作に関係ない)はraw[0]から左シフトすればよい。そこまで絞れば、seedを算出でき、各フラグに対するrを計算でき、フラグを求めることができる。

#!/usr/bin/env python3
import random

def get_seed(r):
    seed = 0
    rand = r
    raw = list()

    while rand > 0:
        rand = rand >> 1
        seed += rand
        raw.append(rand)

    return raw, seed

r0 = 1251602129774106047963344349716052246200810608622833524786816688818258541877890956410282953590226589114551287285264273581561051261152783001366229253687592

pre_flag = b'darkCON{'

with open('encrypted.txt', 'r') as f:
    encs = [line.rstrip().split(' ')[-1] for line in f.readlines()]

raw0 = r0 ^ pre_flag[0] ^ int(encs[0], 16)
rand = raw0 << 1

raw, seed = get_seed(rand)
random.seed(seed)

flag = ''
for i in range(len(encs)):
    r = random.randint(1, 2**512)
    m = r ^ raw[i] ^ int(encs[i], 16)
    flag += chr(m)

print(flag)
darkCON{user_W4rm4ch1ne68_pass_W4RM4CH1N3R0X_t0ny_h4cked_4g41n!}

Rookie's_Choice_4_you (Crypto)

RC4で同じKEYでの平文、暗号文のペアが複数あり、フラグより長い暗号文があるので、XORで復号できる。

from Crypto.Util.strxor import strxor

pt = 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz'
ct = '3d5d841c4df203758189060d7ba5ef0460c90faeae890dc621dfb563a03cc5f728d42794ae8a08102f2766acece427f3c6514fc7'.decode('hex')
enc_flag = '385e95136bdb2a66baa0593e27b8df03228f1785ea9925c768d08b74b06bffe27bd17da1aed51c21342026bdacb173f8'.decode('hex')

key = strxor(pt, ct)
flag = strxor(enc_flag, key[:len(enc_flag)])
print flag
darkCON{RC4_1s_w34k_1f_y0u_us3_s4m3_k3y_tw1c3!!}

DiceCTF 2021 Writeup

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

Cuckoo's Nest (misc)

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

dice{gang}

babymix (rev)

Ghidraでデコンパイルする。

undefined8 main(void)

{
  int iVar1;
  undefined8 uVar2;
  long in_FS_OFFSET;
  char local_48 [56];
  long local_10;
  
  local_10 = *(long *)(in_FS_OFFSET + 0x28);
  puts(&DAT_00103008);
  printf("Please enter your admin password: ");
  fgets(local_48,0x30,stdin);
  iVar1 = check815546(local_48);
  if (iVar1 == 0) {
    puts("\nIncorrect :(");
    uVar2 = 0xffffffff;
  }
  else {
    puts("Correct! Wrap password in dice{} for the flag :)");
    uVar2 = 0;
  }
  if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) {
                    /* WARNING: Subroutine does not return */
    __stack_chk_fail();
  }
  return uVar2;
}

undefined8 check815546(long param_1)

{
  undefined8 uVar1;
  
  if ((int)*(char *)(param_1 + 8) + (int)*(char *)(param_1 + 0xc) +
      ((int)*(char *)(param_1 + 0xc) - (int)*(char *)(param_1 + 0x11)) == 0x99) {
    uVar1 = check921708(param_1);
  }
  else {
    uVar1 = 0;
  }
  return uVar1;
}

undefined8 check921708(long param_1)

{
  undefined8 uVar1;
  
  if ((int)(char)(*(byte *)(param_1 + 2) ^ *(byte *)(param_1 + 0x13)) +
      (int)*(char *)(param_1 + 0x15) + (int)*(char *)(param_1 + 10) == 0xd9) {
    uVar1 = check306697(param_1);
  }
  else {
    uVar1 = 0;
  }
  return uVar1;
}

undefined8 check306697(byte *param_1)

{
  undefined8 uVar1;
  
  if ((int)(char)(param_1[0x10] ^ *param_1) +
      (int)(char)param_1[3] + (int)(char)param_1[0x10] + (int)(char)(param_1[0x10] ^ param_1[5]) ==
      0xe8) {
    uVar1 = check358616(param_1);
  }
  else {
    uVar1 = 0;
  }
  return uVar1;
}

undefined8 check358616(byte *param_1)

{
  undefined8 uVar1;
  
  if ((int)(char)(*param_1 ^ param_1[0x13]) +
      (int)(char)param_1[10] + (int)(char)param_1[3] +
      ((int)(char)param_1[3] - (int)(char)param_1[0x13]) == 0x148) {
    uVar1 = check914884(param_1);
  }
  else {
    uVar1 = 0;
  }
  return uVar1;
}

undefined8 check914884(long param_1)

{
  undefined8 uVar1;
  
  if (((int)*(char *)(param_1 + 2) - (int)*(char *)(param_1 + 0x13)) +
      ((int)*(char *)(param_1 + 10) - (int)*(char *)(param_1 + 8)) == 0x4a) {
    uVar1 = check125197(param_1);
  }
  else {
    uVar1 = 0;
  }
  return uVar1;
}

undefined8 check125197(long param_1)

{
  undefined8 uVar1;
  
  if (((int)*(char *)(param_1 + 0x11) - (int)*(char *)(param_1 + 9)) +
      (int)*(char *)(param_1 + 4) + (int)*(char *)(param_1 + 0xb) +
      ((int)*(char *)(param_1 + 0x11) - (int)*(char *)(param_1 + 1)) == 0xa6) {
    uVar1 = check410842(param_1);
  }
  else {
    uVar1 = 0;
  }
  return uVar1;
}

undefined8 check410842(long param_1)

{
  undefined8 uVar1;
  
  if ((int)*(char *)(param_1 + 10) + (int)*(char *)(param_1 + 5) +
      ((int)*(char *)(param_1 + 0x12) - (int)*(char *)(param_1 + 9)) +
      (int)*(char *)(param_1 + 10) + (int)*(char *)(param_1 + 0xe) == 0x19d) {
    uVar1 = check123562(param_1);
  }
  else {
    uVar1 = 0;
  }
  return uVar1;
}

undefined8 check123562(long param_1)

{
  undefined8 uVar1;
  
  if ((int)*(char *)(param_1 + 0x15) + (int)*(char *)(param_1 + 1) +
      ((int)*(char *)(param_1 + 0xb) - (int)*(char *)(param_1 + 2)) +
      ((int)*(char *)(param_1 + 0x11) - (int)*(char *)(param_1 + 0xd)) +
      ((int)*(char *)(param_1 + 8) - (int)*(char *)(param_1 + 0xc)) +
      ((int)*(char *)(param_1 + 5) - (int)*(char *)(param_1 + 0x10)) == 0x62) {
    uVar1 = check56511(param_1);
  }
  else {
    uVar1 = 0;
  }
  return uVar1;
}

undefined8 check56511(long param_1)

{
  undefined8 uVar1;
  
  if ((int)(char)(*(byte *)(param_1 + 0xc) ^ *(byte *)(param_1 + 0x10)) +
      ((int)*(char *)(param_1 + 6) - (int)*(char *)(param_1 + 0xd)) +
      ((int)*(char *)(param_1 + 0x11) - (int)*(char *)(param_1 + 0xb)) +
      (int)(char)(*(byte *)(param_1 + 0xd) ^ *(byte *)(param_1 + 0x13)) == 0x55) {
    uVar1 = check561255(param_1);
  }
  else {
    uVar1 = 0;
  }
  return uVar1;
}

undefined8 check561255(long param_1)

{
  undefined8 uVar1;
  
  if ((int)(char)(*(byte *)(param_1 + 7) ^ *(byte *)(param_1 + 2)) +
      ((int)*(char *)(param_1 + 4) - (int)*(char *)(param_1 + 0x10)) == 0x4d) {
    uVar1 = check874387(param_1);
  }
  else {
    uVar1 = 0;
  }
  return uVar1;
}

undefined8 check874387(long param_1)

{
  undefined8 uVar1;
  
  if ((int)*(char *)(param_1 + 10) + (int)*(char *)(param_1 + 7) +
      (int)(char)(*(byte *)(param_1 + 0xe) ^ *(byte *)(param_1 + 8)) +
      (int)*(char *)(param_1 + 1) + (int)*(char *)(param_1 + 5) +
      ((int)*(char *)(param_1 + 0xe) - (int)*(char *)(param_1 + 3)) +
      ((int)*(char *)(param_1 + 8) - (int)*(char *)(param_1 + 0x11)) == 0x180) {
    uVar1 = check929976(param_1);
  }
  else {
    uVar1 = 0;
  }
  return uVar1;
}

undefined8 check929976(char *param_1)

{
  undefined8 uVar1;
  
  if ((int)param_1[2] + (int)param_1[0x11] +
      ((int)param_1[0xf] - (int)param_1[0x15]) + ((int)param_1[2] - (int)param_1[4]) +
      ((int)param_1[4] - (int)*param_1) == 0x109) {
    uVar1 = check421149(param_1);
  }
  else {
    uVar1 = 0;
  }
  return uVar1;
}

undefined8 check421149(long param_1)

{
  undefined8 uVar1;
  
  if ((int)*(char *)(param_1 + 6) + (int)*(char *)(param_1 + 7) +
      ((int)*(char *)(param_1 + 0x15) - (int)*(char *)(param_1 + 0x12)) +
      (int)*(char *)(param_1 + 2) + (int)*(char *)(param_1 + 0xf) +
      ((int)*(char *)(param_1 + 0x11) - (int)*(char *)(param_1 + 4)) +
      ((int)*(char *)(param_1 + 5) - (int)*(char *)(param_1 + 0x12)) == 0xfa) {
    uVar1 = check136292(param_1);
  }
  else {
    uVar1 = 0;
  }
  return uVar1;
}

undefined8 check136292(long param_1)

{
  undefined8 uVar1;
  
  if ((int)(char)(*(byte *)(param_1 + 0x12) ^ *(byte *)(param_1 + 0xc)) +
      ((int)*(char *)(param_1 + 7) - (int)*(char *)(param_1 + 0x12)) +
      ((int)*(char *)(param_1 + 0x15) - (int)*(char *)(param_1 + 0x13)) +
      ((int)*(char *)(param_1 + 0x10) - (int)*(char *)(param_1 + 0x15)) == 0x4b) {
    uVar1 = check29354(param_1);
  }
  else {
    uVar1 = 0;
  }
  return uVar1;
}

undefined8 check29354(long param_1)

{
  undefined8 uVar1;
  
  if ((int)*(char *)(param_1 + 6) + (int)*(char *)(param_1 + 9) +
      (int)(char)(*(byte *)(param_1 + 2) ^ *(byte *)(param_1 + 10)) +
      (int)*(char *)(param_1 + 7) + (int)*(char *)(param_1 + 2) +
      (int)*(char *)(param_1 + 0xd) + (int)*(char *)(param_1 + 0x14) +
      (int)(char)(*(byte *)(param_1 + 0x10) ^ *(byte *)(param_1 + 3)) == 0x26d) {
    uVar1 = check389170(param_1);
  }
  else {
    uVar1 = 0;
  }
  return uVar1;
}

undefined8 check389170(char *param_1)

{
  undefined8 uVar1;
  
  if (((int)param_1[1] - (int)param_1[0x13]) +
      (int)(char)(param_1[2] ^ param_1[0xe]) + (int)*param_1 + (int)param_1[0xb] +
      ((int)param_1[8] - (int)param_1[3]) == 0x11b) {
    uVar1 = check200582(param_1);
  }
  else {
    uVar1 = 0;
  }
  return uVar1;
}

undefined8 check200582(byte *param_1)

{
  undefined8 uVar1;
  
  if (((int)(char)param_1[0xd] - (int)(char)param_1[0x13]) +
      (int)(char)(param_1[0xb] ^ *param_1) + (int)(char)(param_1[0xe] ^ *param_1) +
      ((int)(char)param_1[0x10] - (int)(char)param_1[0xe]) == 0x6a) {
    uVar1 = check494505(param_1);
  }
  else {
    uVar1 = 0;
  }
  return uVar1;
}

undefined8 check494505(char *param_1)

{
  undefined8 uVar1;
  
  if (((int)param_1[3] - (int)param_1[0x12]) +
      ((int)*param_1 - (int)param_1[0x14]) + (int)param_1[0x13] + (int)param_1[10] +
      (int)param_1[10] + (int)param_1[0x13] == 0x129) {
    uVar1 = check225302(param_1);
  }
  else {
    uVar1 = 0;
  }
  return uVar1;
}

undefined8 check225302(char *param_1)

{
  undefined8 uVar1;
  
  if ((int)param_1[0x12] + (int)param_1[0x14] + ((int)*param_1 - (int)param_1[0xf]) == 0x9c) {
    uVar1 = check208407(param_1);
  }
  else {
    uVar1 = 0;
  }
  return uVar1;
}

undefined8 check208407(long param_1)

{
  undefined8 uVar1;
  
  if (((int)*(char *)(param_1 + 3) - (int)*(char *)(param_1 + 0x11)) +
      ((int)*(char *)(param_1 + 10) - (int)*(char *)(param_1 + 0x14)) +
      ((int)*(char *)(param_1 + 0xd) - (int)*(char *)(param_1 + 8)) == 0x55) {
    uVar1 = check966250(param_1);
  }
  else {
    uVar1 = 0;
  }
  return uVar1;
}

undefined8 check966250(long param_1)

{
  undefined8 uVar1;
  
  if (((int)*(char *)(param_1 + 10) - (int)*(char *)(param_1 + 2)) +
      (int)*(char *)(param_1 + 4) + (int)*(char *)(param_1 + 0x13) +
      (int)(char)(*(byte *)(param_1 + 0x11) ^ *(byte *)(param_1 + 0xc)) +
      ((int)*(char *)(param_1 + 3) - (int)*(char *)(param_1 + 0x11)) == 0xa0) {
    uVar1 = check2476(param_1);
  }
  else {
    uVar1 = 0;
  }
  return uVar1;
}

undefined8 check2476(long param_1)

{
  undefined8 uVar1;
  
  if (((int)*(char *)(param_1 + 0xc) - (int)*(char *)(param_1 + 10)) +
      ((int)*(char *)(param_1 + 0xb) - (int)*(char *)(param_1 + 0x15)) == 0x24) {
    uVar1 = check554366(param_1);
  }
  else {
    uVar1 = 0;
  }
  return uVar1;
}

undefined8 check554366(long param_1)

{
  undefined8 uVar1;
  
  if ((int)(char)(*(byte *)(param_1 + 0x10) ^ *(byte *)(param_1 + 5)) +
      ((int)*(char *)(param_1 + 6) - (int)*(char *)(param_1 + 0x10)) +
      (int)(char)(*(byte *)(param_1 + 0x13) ^ *(byte *)(param_1 + 0x12)) == 0x66) {
    uVar1 = check471672(param_1);
  }
  else {
    uVar1 = 0;
  }
  return uVar1;
}

undefined8 check471672(long param_1)

{
  undefined8 uVar1;
  
  if (((int)*(char *)(param_1 + 0x15) - (int)*(char *)(param_1 + 5)) +
      ((int)*(char *)(param_1 + 6) - (int)*(char *)(param_1 + 0xd)) +
      (int)(char)(*(byte *)(param_1 + 0xf) ^ *(byte *)(param_1 + 10)) == -0x30) {
    uVar1 = check656702(param_1);
  }
  else {
    uVar1 = 0;
  }
  return uVar1;
}

undefined8 check656702(long param_1)

{
  undefined8 uVar1;
  
  if ((int)(char)(*(byte *)(param_1 + 4) ^ *(byte *)(param_1 + 6)) +
      ((int)*(char *)(param_1 + 0xc) - (int)*(char *)(param_1 + 0xb)) +
      (int)(char)(*(byte *)(param_1 + 3) ^ *(byte *)(param_1 + 5)) == 0x1d) {
    uVar1 = check244553(param_1);
  }
  else {
    uVar1 = 0;
  }
  return uVar1;
}

undefined8 check244553(long param_1)

{
  undefined8 uVar1;
  
  if (((int)*(char *)(param_1 + 0x15) - (int)*(char *)(param_1 + 0xb)) +
      ((int)*(char *)(param_1 + 8) - (int)*(char *)(param_1 + 0xf)) +
      ((int)*(char *)(param_1 + 9) - (int)*(char *)(param_1 + 2)) +
      ((int)*(char *)(param_1 + 6) - (int)*(char *)(param_1 + 0xe)) == -0x6d) {
    uVar1 = check594146(param_1);
  }
  else {
    uVar1 = 0;
  }
  return uVar1;
}

undefined8 check594146(char *param_1)

{
  undefined8 uVar1;
  
  if ((int)param_1[0x11] + (int)param_1[0xb] +
      (int)*param_1 + (int)param_1[0x10] + ((int)param_1[0x13] - (int)param_1[7]) == 0x169) {
    uVar1 = check916070(param_1);
  }
  else {
    uVar1 = 0;
  }
  return uVar1;
}

bool check916070(long param_1)

{
  return (int)(char)(*(byte *)(param_1 + 0x13) ^ *(byte *)(param_1 + 0xf)) +
         (int)*(char *)(param_1 + 0xf) + (int)*(char *)(param_1 + 3) == 0x128;
}

以上から、z3で条件を羅列して解く。

from z3 import *

x = [BitVec('x%d' % i, 8) for i in range(22)]
s = Solver()

s.add(x[8] + x[12] + x[12] - x[17] == 0x99)
s.add((x[2] ^ x[19]) + x[21] + x[10] == 0xd9)
s.add((x[16] ^ x[0]) + x[3] + x[16] + (x[16] ^ x[5]) == 0xe8)
s.add((x[0] ^ x[19]) + x[10] + x[3] + x[3] - x[19] == 0x148)
s.add(x[2] - x[19] + x[10] - x[8] == 0x4a)
s.add(x[17] - x[9] + x[4] + x[11] + x[17] - x[1] == 0xa6)
s.add(x[10] + x[5] + x[18] - x[9] + x[10] + x[14] == 0x19d)
s.add(x[21] + x[1] + x[11] - x[2] + x[17] - x[13] + x[8] - x[12] + x[5] - x[16] == 0x62)
s.add((x[12] ^ x[16]) + x[6] - x[13] + x[17] - x[11] + (x[13] ^ x[19]) == 0x55)
s.add((x[7] ^ x[2]) + x[4] - x[16] == 0x4d)
s.add(x[10] + x[7] + (x[14] ^ x[8]) + x[1] + x[5] + x[14] - x[3] + x[8] - x[17] == 0x180)
s.add(x[2] + x[17] + x[15] - x[21] + x[2] - x[4] + x[4] - x[0] == 0x109)
s.add(x[6] + x[7] + x[21] - x[18] + x[2] + x[15] + x[17] - x[4] + x[5] - x[18] == 0xfa)
s.add((x[18] ^ x[12]) + x[7] - x[18] + x[21] - x[19] + x[16] - x[21] == 0x4b)
s.add(x[6] + x[9] + (x[2] ^ x[10]) + x[7] + x[2] + x[13] + x[20] + (x[16] ^ x[3]) == 0x26d)
s.add(x[1] - x[19] + (x[2] ^ x[14]) + x[0] + x[11] + x[8] - x[3] == 0x11b)
s.add(x[13] - x[19] + (x[11] ^ x[0]) + (x[14] ^ x[0]) + x[16] - x[14] == 0x6a)
s.add(x[3] - x[18] + x[0] - x[20] + x[19] + x[10] + x[10] + x[19] == 0x129)
s.add(x[18] + x[20] + x[0] - x[15] == 0x9c)
s.add(x[3] - x[17] + x[10] - x[20] + x[13] - x[8] == 0x55)
s.add(x[10] - x[2] + x[4] + x[19] + (x[17] ^ x[12]) + x[3] - x[17] == 0xa0)
s.add(x[12] - x[10] + x[11] - x[21] == 0x24)
s.add((x[16] ^ x[5]) + x[6] - x[16] + (x[19] ^ x[18]) == 0x66)
s.add(x[21] - x[5] + x[6] - x[13] + (x[15] ^ x[10]) == -0x30)
s.add((x[4] ^ x[6]) + x[12] - x[11] + (x[3] ^ x[5]) == 0x1d)
s.add(x[21] - x[11] + x[8] - x[15] + x[9] - x[2] + x[6] - x[14] == -0x6d)
s.add(x[17] + x[11] + x[0] + x[16] + x[19] - x[7] == 0x169)
s.add((x[19] ^ x[15]) + x[15] + x[3] == 0x128)

r = s.check()
if r == sat:
    m = s.model()
    password = ''
    for i in range(22):
        password += chr(m[x[i]].as_long())
    flag = 'dice{%s}' % password
    print flag
dice{m1x_it_4ll_t0geth3r!1!}

TrollCAT CTF 2021 Writeup

この大会は2021/2/6 13:30(JST)~2021/2/7 1:30(JST)に開催されました。
今回もチームで参戦。結果は4156点で355チーム中16位でした。
自分で解けた問題をWriteupとして書いておきます。

Sanity Check (Misc)

問題にフラグが書いてあった。

Trollcat{Y0u_ar3_s4ne}

Discord (Misc)

Discordに入り、#miscチャネルのトピックを見ると、フラグが書いてあった。

Trollcat{L3t's_B3g1n_Th3_G4m3}

Social Challenge (Misc)

いろんなチャネルのトピックにこう書いてある。

search @cscodershub on Youtube, Twitter, Instagram and Linkedin to follow us

Youtubeで検索してみると以下のページが見つかった。

https://www.youtube.com/channel/UCboUwuCmX4d313yhtxfgBjQ

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

Trollcat{c5c0d3rshub_y0utub3_Ch4nn3l}

Rich Orphan (Misc)

passwdとshadowの情報が入っているので、クラックする。

$ awk 'NR==3' RichOrphan.txt > passwd
$ awk 'NR==2' RichOrphan.txt > shadow
$ unshadow passwd shadow > passwd_shadow
$ john --wordlist=dict/rockyou.txt passwd_shadow
Warning: detected hash type "md5crypt", but the string is also recognized as "md5crypt-long"
Use the "--format=md5crypt-long" option to force loading these as that type instead
Warning: detected hash type "md5crypt", but the string is also recognized as "md5crypt-opencl"
Use the "--format=md5crypt-opencl" option to force loading these as that type instead
Using default input encoding: UTF-8
Loaded 1 password hash (md5crypt, crypt(3) $1$ (and variants) [MD5 128/128 AVX 4x3])
Will run 2 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
batman           (sys)
1g 0:00:00:00 DONE (2021-02-06 21:07) 2.941g/s 847.0p/s 847.0c/s 847.0C/s alyssa..brenda
Use the "--show" option to display all of the cracked passwords reliably
Session completed
Trollcat{batman}

Forbidden (FORENSICS)

$ binwalk trollcats.car 

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
50            0x32            bzip2 compressed data, block size = 900k

$ dd if=trollcats.car of=trollcats.bz2 bs=1 skip=50
255+0 レコード入力
255+0 レコード出力
255 bytes copied, 0.214606 s, 1.2 kB/s
$ bzip2 -d trollcats.bz2 

bzip2: trollcats.bz2: trailing garbage after EOF ignored
$ cat trollcats
Trollcat{M0zilla_Archive_maaaarls}
Trollcat{M0zilla_Archive_maaaarls}

the_sus_agent (FORENSICS)

No.1613のパケットでsecret.jpgをPOSTしているので、エクスポートする。

$ file secret.jpg 
secret.jpg: ASCII text
$ cat secret.jpg

aWhvcGV5b3VkaWRub3R0cmllZHRvYnJ1dGVmb3JjZWl0
$ cat secret.jpg | base64 -d
ihopeyoudidnottriedtobruteforceit

これをパスワードとして、No.447のパケットでPOSTしているwelcome.jpgをエクスポートして、steghideで隠した情報を抽出する。

$ steghide extract -sf welcome.jpg -p ihopeyoudidnottriedtobruteforceit
wrote extracted data to "foryou".
$ cat foryou
Trollcat{this_challenge_was_easy_right???}
Trollcat{this_challenge_was_easy_right???}

Mr_evilpepo_1 (FORENSICS)

$ volatility -f evilpepo.vmem imageinfo
Volatility Foundation Volatility Framework 2.6
INFO    : volatility.debug    : Determining profile based on KDBG search...
          Suggested Profile(s) : Win7SP1x64, Win7SP0x64, Win2008R2SP0x64, Win2008R2SP1x64_23418, Win2008R2SP1x64, Win7SP1x64_23418
                     AS Layer1 : WindowsAMD64PagedMemory (Kernel AS)
                     AS Layer2 : FileAddressSpace (C:\CTF\work\evilpepo.vmem)
                      PAE type : No PAE
                           DTB : 0x187000L
                          KDBG : 0xf80002a3f0a0L
          Number of Processors : 1
     Image Type (Service Pack) : 1
                KPCR for CPU 0 : 0xfffff80002a40d00L
             KUSER_SHARED_DATA : 0xfffff78000000000L
           Image date and time : 2021-01-12 13:22:41 UTC+0000
     Image local date and time : 2021-01-12 18:52:41 +0530

$ volatility -f evilpepo.vmem --profile=Win7SP1x64 consoles
Volatility Foundation Volatility Framework 2.6
**************************************************
ConsoleProcess: conhost.exe Pid: 992
Console: 0xff346200 CommandHistorySize: 50
HistoryBufferCount: 1 HistoryBufferMax: 4
OriginalTitle: Command Prompt
Title: Command Prompt
AttachedProcess: cmd.exe Pid: 1492 Handle: 0x60
----
CommandHistory: 0x39eb60 Application: cmd.exe Flags: Allocated, Reset
CommandCount: 37 LastAdded: 36 LastDisplayed: 36
FirstCommand: 0 CommandCountMax: 50
ProcessHandle: 0x60
Cmd #0 at 0x37e550: helo
Cmd #1 at 0x37e570: troollll
Cmd #2 at 0x37e590: caaat
Cmd #3 at 0x37e5b0: yooooo
Cmd #4 at 0x39de90: T
Cmd #5 at 0x39dcd0: r
Cmd #6 at 0x3a2f00: o
Cmd #7 at 0x3a2f20: l
Cmd #8 at 0x3a2f40: c
Cmd #9 at 0x3a2f60: a
Cmd #10 at 0x3a2fb0: t
Cmd #11 at 0x3a2fc0: {
Cmd #12 at 0x3a2fd0: c
Cmd #13 at 0x3a2fe0: o
Cmd #14 at 0x3a2ff0: m
Cmd #15 at 0x3a3000: a
Cmd #16 at 0x3a3010: n
Cmd #17 at 0x3a3020: d
Cmd #18 at 0x3a3030: s
Cmd #19 at 0x3a3040: _
Cmd #20 at 0x3a3050: 4
Cmd #21 at 0x3a3060: r
Cmd #22 at 0x3a3070: 3
Cmd #23 at 0x3a3080: _
Cmd #24 at 0x3a3090: i
Cmd #25 at 0x3a30a0: m
Cmd #26 at 0x3a30b0: p
Cmd #27 at 0x3a30c0: o
Cmd #28 at 0x3a30d0: r
Cmd #29 at 0x3a30e0: t
Cmd #30 at 0x3a30f0: a
Cmd #31 at 0x3a3100: n
Cmd #32 at 0x3a3110: t
Cmd #33 at 0x3a3120: }
Cmd #34 at 0x3a33b0: hope you got it 
Cmd #35 at 0x377860: "are you trying to run strings?"
Cmd #36 at 0x3a33e0: lolololololol
----
Screen 0x381120 X:80 Y:300
Dump:
Microsoft Windows [Version 6.1.7601]                                            
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.                 
                                                                                
C:\Users\WhiteWolf>helo                                                         
'helo' is not recognized as an internal or external command,                    
operable program or batch file.                                                 
                                                                                
C:\Users\WhiteWolf>troollll                                                     
'troollll' is not recognized as an internal or external command,                
operable program or batch file.                                                 
                                                                                
C:\Users\WhiteWolf>caaat                                                        
'caaat' is not recognized as an internal or external command,                   
operable program or batch file.                                                 
                                                                                
C:\Users\WhiteWolf>yooooo                                                       
'yooooo' is not recognized as an internal or external command,                  
operable program or batch file.                                                 
                                                                                
C:\Users\WhiteWolf>T                                                            
'T' is not recognized as an internal or external command,                       
operable program or batch file.                                                 
                                                                                
C:\Users\WhiteWolf>r                                                            
'r' is not recognized as an internal or external command,                       
operable program or batch file.                                                 
                                                                                
C:\Users\WhiteWolf>o                                                            
'o' is not recognized as an internal or external command,                       
operable program or batch file.                                                 
                                                                                
C:\Users\WhiteWolf>l                                                            
'l' is not recognized as an internal or external command,                       
operable program or batch file.                                                 
                                                                                
C:\Users\WhiteWolf>l                                                            
'l' is not recognized as an internal or external command,                       
operable program or batch file.                                                 
                                                                                
C:\Users\WhiteWolf>c                                                            
'c' is not recognized as an internal or external command,                       
operable program or batch file.                                                 
                                                                                
C:\Users\WhiteWolf>a                                                            
'a' is not recognized as an internal or external command,                       
operable program or batch file.                                                 
                                                                                
C:\Users\WhiteWolf>t                                                            
't' is not recognized as an internal or external command,                       
operable program or batch file.                                                 
                                                                                
C:\Users\WhiteWolf>{                                                            
'{' is not recognized as an internal or external command,                       
operable program or batch file.                                                 
                                                                                
C:\Users\WhiteWolf>c                                                            
'c' is not recognized as an internal or external command,                       
operable program or batch file.                                                 
                                                                                
C:\Users\WhiteWolf>o                                                            
'o' is not recognized as an internal or external command,                       
operable program or batch file.                                                 
                                                                                
C:\Users\WhiteWolf>m                                                            
'm' is not recognized as an internal or external command,                       
operable program or batch file.                                                 
                                                                                
C:\Users\WhiteWolf>m                                                            
'm' is not recognized as an internal or external command,                       
operable program or batch file.                                                 
                                                                                
C:\Users\WhiteWolf>a                                                            
'a' is not recognized as an internal or external command,                       
operable program or batch file.                                                 
                                                                                
C:\Users\WhiteWolf>n                                                            
'n' is not recognized as an internal or external command,                       
operable program or batch file.                                                 
                                                                                
C:\Users\WhiteWolf>d                                                            
'd' is not recognized as an internal or external command,                       
operable program or batch file.                                                 
                                                                                
C:\Users\WhiteWolf>s                                                            
's' is not recognized as an internal or external command,                       
operable program or batch file.                                                 
                                                                                
C:\Users\WhiteWolf>_                                                            
'_' is not recognized as an internal or external command,                       
operable program or batch file.                                                 
                                                                                
C:\Users\WhiteWolf>4                                                            
'4' is not recognized as an internal or external command,                       
operable program or batch file.                                                 
                                                                                
C:\Users\WhiteWolf>r                                                            
'r' is not recognized as an internal or external command,                       
operable program or batch file.                                                 
                                                                                
C:\Users\WhiteWolf>3                                                            
'3' is not recognized as an internal or external command,                       
operable program or batch file.                                                 
                                                                                
C:\Users\WhiteWolf>_                                                            
'_' is not recognized as an internal or external command,                       
operable program or batch file.                                                 
                                                                                
C:\Users\WhiteWolf>i                                                            
'i' is not recognized as an internal or external command,                       
operable program or batch file.                                                 
                                                                                
C:\Users\WhiteWolf>m                                                            
'm' is not recognized as an internal or external command,                       
operable program or batch file.                                                 
                                                                                
C:\Users\WhiteWolf>p                                                            
'p' is not recognized as an internal or external command,                       
operable program or batch file.                                                 
                                                                                
C:\Users\WhiteWolf>o                                                            
'o' is not recognized as an internal or external command,                       
operable program or batch file.                                                 
                                                                                
C:\Users\WhiteWolf>r                                                            
'r' is not recognized as an internal or external command,                       
operable program or batch file.                                                 
                                                                                
C:\Users\WhiteWolf>t                                                            
't' is not recognized as an internal or external command,                       
operable program or batch file.                                                 
                                                                                
C:\Users\WhiteWolf>a                                                            
'a' is not recognized as an internal or external command,                       
operable program or batch file.                                                 
                                                                                
C:\Users\WhiteWolf>n                                                            
'n' is not recognized as an internal or external command,                       
operable program or batch file.                                                 
                                                                                
C:\Users\WhiteWolf>t                                                            
't' is not recognized as an internal or external command,                       
operable program or batch file.                                                 
                                                                                
C:\Users\WhiteWolf>}                                                            
'}' is not recognized as an internal or external command,                       
operable program or batch file.                                                 
                                                                                
C:\Users\WhiteWolf>hope you got it                                              
'hope' is not recognized as an internal or external command,                    
operable program or batch file.                                                 
                                                                                
C:\Users\WhiteWolf>"are you trying to run strings?"                             
'"are you trying to run strings?"' is not recognized as an internal or external 
command,                                                                        
operable program or batch file.                                                 
                                                                                
C:\Users\WhiteWolf>lolololololol                                                
'lolololololol' is not recognized as an internal or external command,           
operable program or batch file.                                                 
                                                                                
C:\Users\WhiteWolf>

コマンドとして認識しなくてもフラグをコマンド入力している。

Trolcat{comands_4r3_important}

FREE WIFI (NETWORKING)

$ aircrack-ng -w dict/rockyou.txt hack1-01.cap 
Opening hack1-01.cap
Read 23892 packets.

   #  BSSID              ESSID                     Encryption

   1  3A:22:DC:05:71:6B  OnePlus 7 Pro             WPA (1 handshake)

Choosing first network as target.

Opening hack1-01.cap
Reading packets, please wait...

                                 Aircrack-ng 1.2 rc4

      [00:12:07] 714692/9822769 keys tested (1109.22 k/s) 

      Time left: 2 hours, 16 minutes, 52 seconds                 7.28%

                    KEY FOUND! [ no1caredformelikejesus ]


      Master Key     : 4B F5 BE 98 7B B1 67 23 A9 CB 68 1C 88 50 76 9D 
                       7D CB 07 21 23 3F 2A 86 AD 26 D9 17 76 D2 16 E0 

      Transient Key  : 2C A2 38 92 7D 8C 6F 53 41 22 80 C8 5D A6 7B 23 
                       AC 05 EF 82 4D 59 79 53 6A 2D 93 E9 DC 3B 56 BC 
                       24 A5 E8 2F 29 27 1A FE E0 42 57 A4 FB C4 56 65 
                       63 79 22 B8 8B 22 FF 18 E8 24 EB 86 BC D3 45 10 

      EAPOL HMAC     : C2 19 FE 8E 23 EA 7C 58 31 AE 90 B6 6A 33 D4 99
Trollcat{no1caredformelikejesus}

Change my mind (Steganography)

$ zsteg trolllll.png 
b1,rgb,lsb,xy       .. text: "Trollcat{I_L0v3_Tr011C4t}"
b2,g,msb,xy         .. text: "PQDTAEDP"
b3,abgr,msb,xy      .. text: "h_pL_piW"
b4,r,msb,xy         .. text: "gf'sr`P531Ue"
b4,g,msb,xy         .. text: " e5EcBCw6@uarP3da"
b4,b,msb,xy         .. text: "wW32 RWd"
b4,rgb,msb,xy       .. text: "sv bqG@f"
b4,bgr,msb,xy       .. text: "&v#paBwF"
b4,abgr,msb,xy      .. text: "_xOaof/f?w"
Trollcat{I_L0v3_Tr011C4t}

Aliens Message (Steganography)

Audacityで開くと、真ん中あたりにモールス信号らしきものがある。

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

デコードする。

TROLLCATCTFBROUGHTTOYOUBYCSCODERSHUB
Trollcat{TROLLCATCTFBROUGHTTOYOUBYCSCODERSHUB}

Deal Breaking (Cryptography)

シーザー暗号。https://www.geocachingtoolbox.com/index.php?lang=en&page=caesarCipherで復号する。

Rotation 13:
paracetamolforheadache
Trollcat{paracetamolforheadache}

Lost In Forest (Cryptography)

$ echo TWVyY3VyeVZlbnVzRWFydGhNYXJzSnVwaXRlclNhdHVyblVyYW51c05lcHR1bmU= | base64 -d
MercuryVenusEarthMarsJupiterSaturnUranusNeptune
Trollcat{MercuryVenusEarthMarsJupiterSaturnUranusNeptune}

Show your Dedication (Cryptography)

Vigenere暗号。鍵をRACEにして、https://www.dcode.fr/vigenere-cipherで復号する。

your flag is HELLOwORLD
Trollcat{HELLOwORLD}

Radio Station Apocalypse (Cryptography)

p - q = A -> q = p - A
n = p * q = p * (p - A)
p**2 - A*p - n = 0

この二次方程式を解けば、pがわかる。あとはそのまま復号すればよい。

from sympy import *
from Crypto.Util.number import *

ct = 15927954374690152068700390298074593196253864077169207071831999310211243220084198633824761313226756137217716813832139827281860280786151119392571330914043785795154126460993477079312886238477507766509831010644388998659565303441719615131661670116956449101956505931748018171190878765731317846254607404813297135537090043417404895660853320127812799010027005785901634939020872408881201149711968120809368691413105318444873712717786940780346214959475833457688794871749017822337860503424073668090333543027469770960756536095503271163592383252371337847620140632398753943463160733918860277382675572411402618882039992721158705125550
e = 65537
n = 25368447768323504911600571988774494107818159082103458909402378375896888147122503938518591402940401613482043710928629612450119548224453500663121617535722112844472859040198762641907836363229969155712075958868854330020410559684508712810222293531147857306199021834554435068975911739307607540505629883798642466233546635096780559373979170475222394473493457660803818950607714830510840577490628849303933022437114380092662378432401109413796410640006146844170094240232072224662551989418393330140325743682017287713705780111627575953826016488999945470058220771848171583260999599619753854835899967952821690531655365651736970047327
A = 13850705243110859039354321081017038361100285164728565071420492338985283998938739255457649493117185659009054998475484599174052182163568940357425209817392780314915968465598416149706099257132486744034100104272832634714470968608095808094711578599330447351992808756520378741868674695777659183569180981300608614286

p = Symbol('p')
eq = Eq(p**2 - A*p - n)
ans = solve(eq)
if ans[0] < 0:
    p = int(ans[1])
else:
    p = int(ans[0])

q = n // p
assert p * q == n

phi = (p - 1) * (q - 1)
d = inverse(e, phi)
m = pow(ct, d, n)
flag = long_to_bytes(m)
print flag
Trollcat{R5A_1s_n0t_Th4t_ezzz!}