SECCON 2023 Capsule CTF Writeup
SECCON 2023 Capsule CTF
SECCON 2023 Finalsおよび電脳会議の併設イベントとしてCapsule CTFを実施しました。結構盛況で嬉しかったです。
参加者同士で問題を交換しあって増やしていくトレーディングシステムが結構機能していたのも非常に良い。
Writeup
ここでは自分が作問した以下の問題のWriteupを書きます
とにかく簡単な問題を大量に作る必要があったので、結構簡単だと思います。
Pwn
int
-1
src.c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
char buf[31] = {0};
int main() {
char *flag = buf;
char *text[4] = {
"Life is but a fleeting dream, Slippery as a mountain stream.",
"Time ticks away, silent and stern, Teaching us we must learn.",
"Wisdom's voice is often low, But in its echo, truths will grow.",
"A single act of kindness throws Out roots in all directions, and the roots spring up and make new trees."
};
int selection = 0;
puts("Welcome to the fortune teller!");
printf("Index(0~3): ");
scanf("%d", &selection);
if (selection > 3) {
puts("Invalid index!");
return 1;
}
puts("Here is your fortune:");
puts(text[selection]);
}
__attribute__((constructor))
void init() {
FILE *f = fopen("flag.txt", "r");
if (!f) {
puts("Missing flag.txt. Contact an admin if you see this on remote.");
exit(1);
}
fgets(buf, sizeof(buf), f);
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
alarm(60);
}
見ての通りtext
とflag
が連続しているので、いい感じにselection
を合わせればいいだけです。-1
で行けます。
SECCON{L0ng_D5t4nc3_Run4r0und}
Yes
Reversing
just_read
簡単です。読むだけなので
main
を見てみると
┌ 2987: int main (int argc, char **argv, char **envp);
│ ; var signed int var_4h @ rbp-0x4
│ ; var uint32_t var_5h @ rbp-0x5
│ ; var char *s @ rbp-0x70
│ 0x00001179 55 push rbp
│ 0x0000117a 4889e5 mov rbp, rsp
│ 0x0000117d 4883ec70 sub rsp, 0x70
│ 0x00001181 488d057c0e00. lea rax, str.Enter_the_FLAG:_ ; 0x2004 ; "Enter the FLAG: "
│ 0x00001188 4889c7 mov rdi, rax ; const char *format
│ 0x0000118b b800000000 mov eax, 0
│ 0x00001190 e8bbfeffff call sym.imp.printf ; int printf(const char *format)
│ 0x00001195 488d4590 lea rax, [s]
│ 0x00001199 4889c6 mov rsi, rax
│ 0x0000119c 488d05720e00. lea rax, str._99s___n_ ; 0x2015 ; "%99s%*[^\n]"
│ 0x000011a3 4889c7 mov rdi, rax ; const char *format
│ 0x000011a6 b800000000 mov eax, 0
│ 0x000011ab e8b0feffff call sym.imp.__isoc99_scanf ; int scanf(const char *format)
│ 0x000011b0 488d4590 lea rax, [s]
│ 0x000011b4 4889c7 mov rdi, rax ; const char *s
│ 0x000011b7 e884feffff call sym.imp.strlen ; size_t strlen(const char *s)
│ 0x000011bc 4883f843 cmp rax, 0x43 ; 'C'
│ ┌─< 0x000011c0 7419 je 0x11db
│ │ 0x000011c2 488d05570e00. lea rax, str.Incorrect ; 0x2020 ; "Incorrect"
│ │ 0x000011c9 4889c7 mov rdi, rax ; const char *s
│ │ 0x000011cc e85ffeffff call sym.imp.puts ; int puts(const char *s)
│ │ 0x000011d1 b801000000 mov eax, 1
│ ┌──< 0x000011d6 e9470b0000 jmp 0x1d22
│ ││ ; CODE XREF from main @ 0x11c0(x)
│ │└─> 0x000011db c745fc000000. mov dword [var_4h], 0
│ │┌─< 0x000011e2 e91d0b0000 jmp 0x1d04
│ ││ ; CODE XREF from main @ 0x1d08(x)
│ ┌───> 0x000011e7 8b45fc mov eax, dword [var_4h]
│ ╎││ 0x000011ea 4898 cdqe
│ ╎││ 0x000011ec 0fb6440590 movzx eax, byte [rbp + rax - 0x70]
│ ╎││ 0x000011f1 3c60 cmp al, 0x60 ; '`'
│ ┌────< 0x000011f3 7e47 jle 0x123c
│ │╎││ 0x000011f5 8b45fc mov eax, dword [var_4h]
│ │╎││ 0x000011f8 4898 cdqe
│ │╎││ 0x000011fa 0fb6440590 movzx eax, byte [rbp + rax - 0x70]
│ │╎││ 0x000011ff 3c7a cmp al, 0x7a ; 'z'
│ ┌─────< 0x00001201 7f39 jg 0x123c
│ ││╎││ 0x00001203 8b45fc mov eax, dword [var_4h]
│ ││╎││ 0x00001206 4898 cdqe
│ ││╎││ 0x00001208 0fb6440590 movzx eax, byte [rbp + rax - 0x70]
│ ││╎││ 0x0000120d 0fbec0 movsx eax, al
│ ││╎││ 0x00001210 83e854 sub eax, 0x54
│ ││╎││ 0x00001213 4863d0 movsxd rdx, eax
│ ││╎││ 0x00001216 4869d24fecc4. imul rdx, rdx, 0x4ec4ec4f
│ ││╎││ 0x0000121d 48c1ea20 shr rdx, 0x20
│ ││╎││ 0x00001221 c1fa03 sar edx, 3
│ ││╎││ 0x00001224 89c1 mov ecx, eax
│ ││╎││ 0x00001226 c1f91f sar ecx, 0x1f
│ ││╎││ 0x00001229 29ca sub edx, ecx
│ ││╎││ 0x0000122b 6bca1a imul ecx, edx, 0x1a
│ ││╎││ 0x0000122e 29c8 sub eax, ecx
│ ││╎││ 0x00001230 89c2 mov edx, eax
│ ││╎││ 0x00001232 89d0 mov eax, edx
│ ││╎││ 0x00001234 83c061 add eax, 0x61
│ ││╎││ 0x00001237 8845fb mov byte [var_5h], al
│ ┌──────< 0x0000123a eb62 jmp 0x129e
│ │││╎││ ; CODE XREFS from main @ 0x11f3(x), 0x1201(x)
│ │└└────> 0x0000123c 8b45fc mov eax, dword [var_4h]
│ │ ╎││ 0x0000123f 4898 cdqe
│ │ ╎││ 0x00001241 0fb6440590 movzx eax, byte [rbp + rax - 0x70]
│ │ ╎││ 0x00001246 3c40 cmp al, 0x40 ; elf_phdr
│ │ ┌────< 0x00001248 7e47 jle 0x1291
│ │ │╎││ 0x0000124a 8b45fc mov eax, dword [var_4h]
│ │ │╎││ 0x0000124d 4898 cdqe
│ │ │╎││ 0x0000124f 0fb6440590 movzx eax, byte [rbp + rax - 0x70]
│ │ │╎││ 0x00001254 3c5a cmp al, 0x5a ; 'Z'
│ │┌─────< 0x00001256 7f39 jg 0x1291
│ │││╎││ 0x00001258 8b45fc mov eax, dword [var_4h]
│ │││╎││ 0x0000125b 4898 cdqe
│ │││╎││ 0x0000125d 0fb6440590 movzx eax, byte [rbp + rax - 0x70]
│ │││╎││ 0x00001262 0fbec0 movsx eax, al
│ │││╎││ 0x00001265 83e834 sub eax, 0x34
│ │││╎││ 0x00001268 4863d0 movsxd rdx, eax
│ │││╎││ 0x0000126b 4869d24fecc4. imul rdx, rdx, 0x4ec4ec4f
│ │││╎││ 0x00001272 48c1ea20 shr rdx, 0x20
│ │││╎││ 0x00001276 c1fa03 sar edx, 3
│ │││╎││ 0x00001279 89c1 mov ecx, eax
│ │││╎││ 0x0000127b c1f91f sar ecx, 0x1f
│ │││╎││ 0x0000127e 29ca sub edx, ecx
│ │││╎││ 0x00001280 6bca1a imul ecx, edx, 0x1a
│ │││╎││ 0x00001283 29c8 sub eax, ecx
│ │││╎││ 0x00001285 89c2 mov edx, eax
│ │││╎││ 0x00001287 89d0 mov eax, edx
│ │││╎││ 0x00001289 83c041 add eax, 0x41
│ │││╎││ 0x0000128c 8845fb mov byte [var_5h], al
│ ┌───────< 0x0000128f eb0d jmp 0x129e
│ ││││╎││ ; CODE XREFS from main @ 0x1248(x), 0x1256(x)
│ ││└└────> 0x00001291 8b45fc mov eax, dword [var_4h]
│ ││ ╎││ 0x00001294 4898 cdqe
│ ││ ╎││ 0x00001296 0fb6440590 movzx eax, byte [rbp + rax - 0x70]
│ ││ ╎││ 0x0000129b 8845fb mov byte [var_5h], al
│ ││ ╎││ ; CODE XREFS from main @ 0x123a(x), 0x128f(x)
│ └└──────> 0x0000129e 837dfc42 cmp dword [var_4h], 0x42 ; 'B'
│ ┌────< 0x000012a2 0f87580a0000 ja case.default.0x12c9
│ │╎││ 0x000012a8 8b45fc mov eax, dword [var_4h]
│ │╎││ 0x000012ab 488d14850000. lea rdx, [rax*4]
│ │╎││ 0x000012b3 488d057a0d00. lea rax, [0x00002034]
│ │╎││ 0x000012ba 8b0402 mov eax, dword [rdx + rax]
│ │╎││ 0x000012bd 4898 cdqe
│ │╎││ 0x000012bf 488d156e0d00. lea rdx, [0x00002034]
│ │╎││ 0x000012c6 4801d0 add rax, rdx
│ │╎││ ;-- switch
│ │╎││ 0x000012c9 ffe0 jmp rax ; switch table (67 cases) at 0x2034
│ │╎││ ;-- case 0: ; from 0x000012c9
│ │╎││ ; CODE XREF from main @ 0x12c9(x)
│ │╎││ 0x000012cb 807dfb46 cmp byte [var_5h], 0x46 ; 'F'
│ ┌─────< 0x000012cf 0f841f090000 je 0x1bf4
│ ││╎││ 0x000012d5 488d05440d00. lea rax, str.Incorrect ; 0x2020 ; "Incorrect"
│ ││╎││ 0x000012dc 4889c7 mov rdi, rax ; const char *s
│ ││╎││ 0x000012df e84cfdffff call sym.imp.puts ; int puts(const char *s)
│ ││╎││ 0x000012e4 bf01000000 mov edi, 1 ; int status
│ ││╎││ 0x000012e9 e882fdffff call sym.imp.exit ; void exit(int status)
│ ││╎││ ;-- case 1: ; from 0x000012c9
│ ││╎││ ; CODE XREF from main @ 0x12c9(x)
│ ││╎││ 0x000012ee 807dfb52 cmp byte [var_5h], 0x52 ; 'R'
│ ┌──────< 0x000012f2 0f8402090000 je 0x1bfa
│ │││╎││ 0x000012f8 488d05210d00. lea rax, str.Incorrect ; 0x2020 ; "Incorrect"
│ │││╎││ 0x000012ff 4889c7 mov rdi, rax ; const char *s
│ │││╎││ 0x00001302 e829fdffff call sym.imp.puts ; int puts(const char *s)
│ │││╎││ 0x00001307 bf01000000 mov edi, 1 ; int status
│ │││╎││ 0x0000130c e85ffdffff call sym.imp.exit ; void exit(int status)
│ │││╎││ ;-- case 2: ; from 0x000012c9
│ │││╎││ ; CODE XREF from main @ 0x12c9(x)
│ │││╎││ 0x00001311 807dfb50 cmp byte [var_5h], 0x50 ; 'P'
│ ┌───────< 0x00001315 0f84e5080000 je 0x1c00
│ ││││╎││ 0x0000131b 488d05fe0c00. lea rax, str.Incorrect ; 0x2020 ; "Incorrect"
│ ││││╎││ 0x00001322 4889c7 mov rdi, rax ; const char *s
│ ││││╎││ 0x00001325 e806fdffff call sym.imp.puts ; int puts(const char *s)
│ ││││╎││ 0x0000132a bf01000000 mov edi, 1 ; int status
│ ││││╎││ 0x0000132f e83cfdffff call sym.imp.exit ; void exit(int status)
│ ││││╎││ ;-- case 3: ; from 0x000012c9
│ ││││╎││ ; CODE XREF from main @ 0x12c9(x)
│ ││││╎││ 0x00001334 807dfb50 cmp byte [var_5h], 0x50 ; 'P'
│ ────────< 0x00001338 0f84c8080000 je 0x1c06
│ ││││╎││ 0x0000133e 488d05db0c00. lea rax, str.Incorrect ; 0x2020 ; "Incorrect"
│ ││││╎││ 0x00001345 4889c7 mov rdi, rax ; const char *s
│ ││││╎││ 0x00001348 e8e3fcffff call sym.imp.puts ; int puts(const char *s)
│ ││││╎││ 0x0000134d bf01000000 mov edi, 1 ; int status
│ ││││╎││ 0x00001352 e819fdffff call sym.imp.exit ; void exit(int status)
│ ││││╎││ ;-- case 4: ; from 0x000012c9
│ ││││╎││ ; CODE XREF from main @ 0x12c9(x)
│ ││││╎││ 0x00001357 807dfb42 cmp byte [var_5h], 0x42 ; 'B'
│ ────────< 0x0000135b 0f84ab080000 je 0x1c0c
│ ││││╎││ 0x00001361 488d05b80c00. lea rax, str.Incorrect ; 0x2020 ; "Incorrect"
│ ││││╎││ 0x00001368 4889c7 mov rdi, rax ; const char *s
│ ││││╎││ 0x0000136b e8c0fcffff call sym.imp.puts ; int puts(const char *s)
│ ││││╎││ 0x00001370 bf01000000 mov edi, 1 ; int status
│ ││││╎││ 0x00001375 e8f6fcffff call sym.imp.exit ; void exit(int status)
│ ││││╎││ ;-- case 5: ; from 0x000012c9
│ ││││╎││ ; CODE XREF from main @ 0x12c9(x)
│ ││││╎││ 0x0000137a 807dfb41 cmp byte [var_5h], 0x41 ; 'A'
│ ────────< 0x0000137e 0f848e080000 je 0x1c12
│ ││││╎││ 0x00001384 488d05950c00. lea rax, str.Incorrect ; 0x2020 ; "Incorrect"
│ ││││╎││ 0x0000138b 4889c7 mov rdi, rax ; const char *s
│ ││││╎││ 0x0000138e e89dfcffff call sym.imp.puts ; int puts(const char *s)
│ ││││╎││ 0x00001393 bf01000000 mov edi, 1 ; int status
│ ││││╎││ 0x00001398 e8d3fcffff call sym.imp.exit ; void exit(int status)
│ ││││╎││ ;-- case 6: ; from 0x000012c9
│ ││││╎││ ; CODE XREF from main @ 0x12c9(x)
│ ││││╎││ 0x0000139d 807dfb7b cmp byte [var_5h], 0x7b ; '{'
│ ────────< 0x000013a1 0f8471080000 je 0x1c18
│ ││││╎││ 0x000013a7 488d05720c00. lea rax, str.Incorrect ; 0x2020 ; "Incorrect"
│ ││││╎││ 0x000013ae 4889c7 mov rdi, rax ; const char *s
│ ││││╎││ 0x000013b1 e87afcffff call sym.imp.puts ; int puts(const char *s)
│ ││││╎││ 0x000013b6 bf01000000 mov edi, 1 ; int status
│ ││││╎││ 0x000013bb e8b0fcffff call sym.imp.exit ; void exit(int status)
│ ││││╎││ ;-- case 7: ; from 0x000012c9
│ ││││╎││ ; CODE XREF from main @ 0x12c9(x)
│ ││││╎││ 0x000013c0 807dfb30 cmp byte [var_5h], 0x30 ; '0'
│ ────────< 0x000013c4 0f8454080000 je 0x1c1e
│ ││││╎││ 0x000013ca 488d054f0c00. lea rax, str.Incorrect ; 0x2020 ; "Incorrect"
│ ││││╎││ 0x000013d1 4889c7 mov rdi, rax ; const char *s
│ ││││╎││ 0x000013d4 e857fcffff call sym.imp.puts ; int puts(const char *s)
│ ││││╎││ 0x000013d9 bf01000000 mov edi, 1 ; int status
│ ││││╎││ 0x000013de e88dfcffff call sym.imp.exit ; void exit(int status)
│ ││││╎││ ;-- case 8: ; from 0x000012c9
│ ││││╎││ ; CODE XREF from main @ 0x12c9(x)
│ ││││╎││ 0x000013e3 807dfb61 cmp byte [var_5h], 0x61 ; 'a'
│ ────────< 0x000013e7 0f8437080000 je 0x1c24
│ ││││╎││ 0x000013ed 488d052c0c00. lea rax, str.Incorrect ; 0x2020 ; "Incorrect"
│ ││││╎││ 0x000013f4 4889c7 mov rdi, rax ; const char *s
│ ││││╎││ 0x000013f7 e834fcffff call sym.imp.puts ; int puts(const char *s)
│ ││││╎││ 0x000013fc bf01000000 mov edi, 1 ; int status
│ ││││╎││ 0x00001401 e86afcffff call sym.imp.exit ; void exit(int status)
~~ snip ~~
│ ╎│└─> 0x00001d04 837dfc42 cmp dword [var_4h], 0x42 ; 'B'
│ └───< 0x00001d08 0f8ed9f4ffff jle 0x11e7
│ │ 0x00001d0e 488d05150300. lea rax, str.Correct ; 0x202a ; "Correct"
│ │ 0x00001d15 4889c7 mov rdi, rax ; const char *s
│ │ 0x00001d18 e813f3ffff call sym.imp.puts ; int puts(const char *s)
│ │ 0x00001d1d b800000000 mov eax, 0
│ │ ; CODE XREF from main @ 0x11d6(x)
│ └──> 0x00001d22 c9 leave
└ 0x00001d23 c3 ret
こんな感じで一文字ずつ比較しています。
気合で読んだり、ツールで抽出するとrot13っぽいことがわかります。
>>> import r2pipe
>>> pipe = r2pipe.open('just_read', flags=['-2'])
>>> _=pipe.cmd('aaa')
>>> disas = pipe.cmd('pdf @main')
>>> cmps = [x for x in disas.split('\n') if 'cmp byte' in x]
>>> print(''.join([c[-2] for c in cmps]))
FRPPBA{0a3_a33q_a0g_u4i3_o33a_Pnrfne_1a_0eq3e_g0_haq3e5g4aq_Pnrfne}
というわけで、全体のSolverはこう
#!/usr/bin/env python3
import r2pipe
import codecs
pipe = r2pipe.open("just_read", flags=["-2"])
_ = pipe.cmd("aaa")
disas = pipe.cmd("pdf @main")
cmps = [x for x in disas.split("\n") if "cmp byte" in x]
encoded_flag = ''.join([c[-2] for c in cmps])
print(codecs.decode(encoded_flag, 'rot_13'))
SECCON{0n3_n33d_n0t_h4v3_b33n_Caesar_1n_0rd3r_t0_und3r5t4nd_Caesar}
snake
pythonを読んで逆をする系の問題です。
#!/use/bin/env python3
# -*- coding: utf-8 -*-
flag = open('FLAG', 'r').read()
open('output', 'wb').write(bytes([(ord(c) ^ 0x42) + 10 for c in flag]))
output
00000000: 1b11 0b0b 1716 4310 8042 7b30 2780 3630 ......C..B{0'.60
00000010: 272b 7c36 2e41 817b 3049 52 '+|6.A.{0IR
やります
>>> output = open('output', 'rb').read()
>>> ''.join([chr((c-10)^0x42) for c in output])
'SECCON{D4z3d_4nd_c0nfu53d}\n'
Zeppelinですね
pl
Pythonはみんな読めるやろ。ということで今度はPerlにしました。
use MIME::Base64;eval(decode_base64('c3ViIHIgewogIG15KCRkLCAkaykgPSBAXzsKICBteSBAcyA9IDAuLjI1NTsKICBteSAoJGksICRqLCAkYykgPSAoMCwgMCwgJycpOwogIG15ICRsID0gQCRrOwogIGZvciAoJGkgPSAwOyAkaSA8IDI1NjsgJGkrKykgewogICAgJGogPSAoJGogKyAkc1skaV0gKyAkay0+WyRpJSRsXSkgJSAyNTY7CiAgICBAc1skaSwgJGpdID0gQHNbJGosICRpXTsKICB9CiAgJGkgPSAkaiA9IDA7CiAgZm9yZWFjaCBteSAkY2hhciAoc3BsaXQgLy8sICRkKSB7CiAgICAkaSA9ICgkaSArIDEpICUgMjU2OwogICAgJGogPSAoJGogKyAkc1skaV0pICUgMjU2OwogICAgQHNbJGksICRqXSA9IEBzWyRqLCAkaV07CiAgICAkYyAuPSBjaHIob3JkKCRjaGFyKSBeICRzWygkc1skaV0gKyAkc1skal0pICUgMjU2XSk7CiAgfQogIHJldHVybiAkYzsKfQpteSAkayA9IFs1NSwgNDksIDUwLCAxMDAsIDk5LCA5NywgMTAyLCA1NiwgMTAxLCA1NiwgNTAsIDUxLCA1NywgNTAsIDUyLCAxMDIsIDEwMCwgNTcsIDk3LCAxMDAsIDEwMiwgNTcsIDk3LCA1NSwgMTAxLCA5NywgOTksIDUzLCA5OSwgNTYsIDU2LCAxMDJdOwpteSAkZT0gJzg3ZDg1Y2Y1MDM3NWY3M2NhMDY2ZGEzNjQ1NjQwYWVmYjBkYzc4NTFjMzIzNGE2NDVkY2FjYjVmMjInOwpteSAkeCA9IHIoJGUsICRrKTsKcHJpbnQgImZsYWc6ICI7Cm15ICRwID0gPFNURElOPjsKY2hvbXAgJHA7Cm15ICRpID0gcigkcCwgJGspOwpwcmludCB1bnBhY2soJ0gqJywgJGkpIGVxICRlPyJDb3JyZWN0IVxuIjoiV3JvbmchXG4iOwo='));
まぁこういうのはeval
をprint
とかにしましょう。というかbase64って書いてあるのでデコードしてみましょう。
sub r {
my($d, $k) = @_;
my @s = 0..255;
my ($i, $j, $c) = (0, 0, '');
my $l = @$k;
for ($i = 0; $i < 256; $i++) {
$j = ($j + $s[$i] + $k->[$i%$l]) % 256;
@s[$i, $j] = @s[$j, $i];
}
$i = $j = 0;
foreach my $char (split //, $d) {
$i = ($i + 1) % 256;
$j = ($j + $s[$i]) % 256;
@s[$i, $j] = @s[$j, $i];
$c .= chr(ord($char) ^ $s[($s[$i] + $s[$j]) % 256]);
}
return $c;
}
my $k = [55, 49, 50, 100, 99, 97, 102, 56, 101, 56, 50, 51, 57, 50, 52, 102, 100, 57, 97, 100, 102, 57, 97, 55, 101, 97, 99, 53, 99, 56, 56, 102];
my $e= '87d85cf50375f73ca066da3645640aefb0dc7851c3234a645dcacb5f22';
my $x = r($e, $k);
print "flag: ";
my $p = <STDIN>;
chomp $p;
my $i = r($p, $k);
print unpack('H*', $i) eq $e?"Correct!\n":"Wrong!\n";
なんだろうこのmy $x = r($e, $k)
の行。正直自分でも覚えてないです。
まぁ見ての通りRC4ですね。ChatGPTもそう言っています。
$ fask '以下のPerlで書かれた暗号化処理を説明してください
∙ sub r {
my($d, $k) = @_;
my @s = 0..255;
my ($i, $j, $c) = (0, 0, '');
my $l = @$k;
for ($i = 0; $i < 256; $i++) {
$j = ($j + $s[$i] + $k->[$i%$l]) % 256;
@s[$i, $j] = @s[$j, $i];
}
$i = $j = 0;
foreach my $char (split //, $d) {
$i = ($i + 1) % 256;
$j = ($j + $s[$i]) % 256;
@s[$i, $j] = @s[$j, $i];
$c .= chr(ord($char) ^ $s[($s[$i] + $s[$j]) % 256]);
}
return $c;
}'
このPerlサブルーチン`r`は、RC4ストリーム暗号アルゴリズムに基づいた暗号化(および復号化)処理を実行するためのコードです。RC4は鍵ストリームを生成して平文(または暗号文)と排他的論理和(XOR)を取るアルゴリズムです。このコードはそのための初期化とデータ処理を行っています。
サブルーチンの引数:
- `$d`は暗号化または復号化するデータ(文字列)
- `$k`は暗号化(または復号化)の鍵を表す配列のリファレンス
手順の説明:
1. 配列`@s`を初期化し、0から255までの数値で埋めます。これは、RC4のS-box(順列ボックス)です。
2. インデックス`$i`と`$j`を0に初期化します。これらはアルゴリズム内で使用される変数です。
3. 鍵の長さ`$l`を取得します(スカラー配列リファレンスをデリファレンスして配列サイズを取得している)。
4. 鍵の初期化ステップ: 0から255の各値`$i`について、S-boxを鍵に基づいて初期化します。`$j`はS-boxと鍵の値を使用して更新され、S-boxの位置`$i`と`$j`の値を交換します。
5. 変数`$i`と`$j`を再び0にリセットします。
6. 暗号化(または復号化)のメインループ: データ`$d`を1文字ずつ処理します。
a. S-boxを使用して鍵ストリームを生成します。`$i`と`$j`は更新され、S-boxの当該位置も交換されます。
b. 生成した鍵ストリームの値(S-boxの値を使用)とデータ文字のASCII値のXORを取り、暗号化(または復号化)された文字を生成します。
c. 処理された文字を結果文字列`$c`に追加します。
7. 処理が完了した後、暗号化(または復号化)されたデータを含む文字列`$c`を返します。
この処理により、平文と鍵を使用して暗号文を生成することができます。また、同じ鍵を使って暗号文に対してこのサブルーチンを実 行することで、元の平文を復号化することができます。これは、XOR操作が反転可能なためです(同じ鍵ストリームを使用して二度XOR を行うと、元のデータに戻ります)。
まずは$k
がasciiっぽいのでいい感じにします
>>> ''.join([chr(c) for c in [55, 49, 50, 100, 99, 97, 102, 56, 101, 56, 50, 51, 57, 50, 52, 102, 100, 57, 97, 100, 102, 57, 97, 55, 101, 97, 99, 53, 99, 56, 56, 102]])
'712dcaf8e823924fd9adf9a7eac5c88f'
あとはCyberChefにでも投げればdecryptoできます
SECCON{R1d3_0n_5h00t1ng_5t4r}
flcl
Web
poem
Web問が最初なさすぎたので作ったんですが、path
と結構被ってます。
require 'sinatra'
get '/' do
"""
<html>
<body>
<h1>My Poems</h1>
<ul>
<li><a href='/read?poem=poem1.html'>Poem 1</a></li>
<li><a href='/read?poem=poem2.html'>Poem 2</a></li>
<li><a href='/read?poem=poem3.html'>Poem 3</a></li>
</ul>
</body>
</html>
"""
end
get '/read' do
file = params[:poem]
begin
File.open(file, 'r') do |f|
f.read
end
rescue
"Can't read"
end
end
get '/flag.txt' do
"Do not look at me!"
end
ポエムはChatGPTに作らせました。こういうので便利。
/read?poem=flag.txt
だけです。
SECCON{Und3r_Th3_Br1dg3}
Blood Sugar Sex Magik
総括
CTF会場の入り口で主にやっていたんですが、一般参加者が結構集まって交流もしてくれたので非常に嬉しかったです。
気合と機会があれば来年もやりたいですね。
おわりに
この記事はn01e0 Advent Calendar 2023の24日目の記事です。
明日でやっと解放されますが、明日のネタはありません。
また、IPFactory OB Advent Calendar 2023の24日目の記事も兼ねています。
Comments