#CTFとは
Capture The Flagの略で、フラグという文字列を問題から発見し、それに応じた得点を得て、競いあう競技です。セキュリティの勉強になります。
WikiPedia
#常設CTF
今回挑戦するksnctfは常設CTFというものの一種で、いつでも挑戦できるCTFです。CTFの中にはリアルタイムのものもあるそうです。
#環境
WSL Ubuntu20.04 LTSです。
#やってみる
とりあえず解いてみます。解法が出るので答えを見たくないかたは注意してください。
##1. Test Ploblem
テストです。ただ表示されたフラグを入力するだけです。
##2. Easy Cipher
EBG KVVV vf n fvzcyr yrggre fhofgvghgvba pvcure gung ercynprf n yrggre jvgu gur yrggre KVVV yrggref nsgre vg va gur nycunorg. EBG KVVV vf na rknzcyr bs gur Pnrfne pvcure, qrirybcrq va napvrag Ebzr. Synt vf SYNTFjmtkOWFNZdjkkNH. Vafreg na haqrefpber vzzrqvngryl nsgre SYNT.
これが暗号文のようです。よく見るとEBGやKVVVという言い回しが何度か出てきていますね。スペースもありますし、シーザー暗号の可能性が高そうです。とりあえずfvzcvrという単語で、何文字ずらしているか確かめてみます。ツールを使ってもいいのですが、せっかくなので自分でスクリプト(githubにあげた)を書いてみます。
; String to ascii list.
(defun str-code (str)
(mapcar #'char-code
(coerce str 'list)))
; Ascii list to string.
(defun dec-code (asc)
(coerce (mapcar #'code-char
asc)
'string))
; String shift function.
(defun ascii-shift (lst val)
(mapcar
(lambda (chr)
(setq plused-ascii (+ chr val))
(cond ((<= 65 chr 90)
(cond ((< plused-ascii 65) (incf plused-ascii 26)
plused-ascii)
((> plused-ascii 90) (decf plused-ascii 26)
plused-ascii)
(t plused-ascii)))
((<= 97 chr 122)
(cond ((< plused-ascii 97) (incf plused-ascii 26)
plused-ascii)
((> plused-ascii 122) (decf plused-ascii 26)
plused-ascii)
(t plused-ascii)))
(t chr)))
lst))
; Shift str for val.
(defun solve (str val)
(princ (dec-code (ascii-shift (str-code str) val))))
; Shift str from 1 to 26.
(defun solve-all (str)
(let ((ascii (str-code str)))
(loop for i
from 1
below 26
do(progn;
(princ i)
(princ ">> ")
(princ (dec-code (ascii-shift ascii i)))
(fresh-line)))))
clispを起動し、
(solve-all "fvzcvr")
を入力します。
###実行結果
1>> gwadws
2>> hxbext
3>> iycfyu
4>> jzdgzv
5>> kaehaw
6>> lbfibx
7>> mcgjcy
8>> ndhkdz
9>> oeilea
10>> pfjmfb
11>> qgkngc
12>> rhlohd
13>> simpie
14>> tjnqjf
15>> ukorkg
16>> vlpslh
17>> wmqtmi
18>> xnrunj
19>> yosvok
20>> zptwpl
21>> aquxqm
22>> brvyrn
23>> cswzso
24>> dtxatp
25>> euybuq
13文字ずらしたところでsimpleという単語があります。なので、13文字ずらした文章と推測できます。文章全体を13文字ずらしてみましょう。
(solve "EBG KVVV vf n fvzcyr yrggre fhofgvghgvba pvcure gung ercynprf n yrggre jvgu gur yrggre KVVV yrggref nsgre vg va gur nycunorg. EBG KVVV vf na rknzcyr bs gur Pnrfne pvcure, qrirybcrq va napvrag Ebzr. Synt vf SYNTFjmtkOWFNZdjkkNH. Vafreg na haqrefpber vzzrqvngryl nsgre SYNT." 13)
; 結果:
"ROT XIII is a simple letter substitution cipher that replaces a letter with the letter XIII letters after it in the alphabet. ROT XIII is an example of the Caesar cipher, developed in ancient Rome. Flag is FLAG(自主規制). Insert an underscore immediately after FLAG."
出ました。FLAG_(自主規制)の形がフラグだと書いてありますね。
#個人的な発見
lambdaの中にletをぶち込める。
Lispってリストに問題を落とし込めば勝ち。
#追記
(mapcar (lambda (x) (char-code x)) lst)とかやってたけど
(mapcar #'char-code lst)で良かったことに気づいた
8/8
コードにあったバグを修正。