Keysar v2(Writeup)

## 問題
https://2021.angstromctf.com/challenges

```python:source
import string

with open("key.txt", "r") as f:
    shift = int(f.readline())
    key = f.readline()

with open("flag.txt", "r") as f:
    flag = f.read()


stdalph = string.ascii_lowercase
rkey = ""

for i in key:
    if i not in rkey:
        rkey += i
for i in stdalph:
    if i not in rkey:
        rkey += i
rkey = rkey[-shift:] + rkey[:-shift]

enc = ""
for a in flag:
    if a in stdalph:
        enc += rkey[stdalph.index(a)]
    else:
        enc += a

print(enc)
```
```txt:output
quutcvbmy ft qii amtkm iqkd tx qjbqfbtm, fzwcw bd mt kqo q sww dztgiv sw qsiw ft xio. bfd kbmyd qcw ftt drqii ft ywf bfd xqf ibffiw stvo txx fzw yctgmv. fzw sww, tx utgcdw, xibwd qmokqo swuqgdw swwd vtm'f uqcw kzqf zgrqmd fzbma bd brhtddbsiw. owiitk, siqua. owiitk, siqua. owiitk, siqua. owiitk, siqua. ttz, siqua qmv owiitk! iwf'd dzqaw bf gh q ibffiw. sqcco! scwqaxqdf bd cwqvo! utrbmy! zqmy tm q dwutmv. zwiit? sqcco? qvqr? uqm otg swibwjw fzbd bd zqhhwmbmy? b uqm'f. b'ii hbua otg gh. ittabmy dzqch. gdw fzw dfqbcd. otgc xqfzwc hqbv yttv rtmwo xtc fztdw. dtcco. b'r wnubfwv. zwcw'd fzw ycqvgqfw. kw'cw jwco hctgv tx otg, dtm. q hwcxwuf cwhtcf uqcv, qii s'd. jwco hctgv. rq! b ytf q fzbmy ytbmy zwcw. otg ytf ibmf tm otgc xgpp. tk! fzqf'd rw! kqjw ft gd! kw'ii sw bm ctk 118,000. sow! sqcco, b ftiv otg, dfth xiobmy bm fzw ztgdw! zwo, qvqr. zwo, sqcco. bd fzqf xgpp ywi? q ibffiw. dhwubqi vqo, ycqvgqfbtm. mwjwc fztgyzf b'v rqaw bf. fzcww vqod ycqvw duztti, fzcww vqod zbyz duztti. fztdw kwcw qkakqcv. fzcww vqod utiiwyw. b'r yiqv b ftta q vqo qmv zbfuzzbawv qctgmv fzw zbjw. otg vbv utrw squa vbxxwcwmf. zb, sqcco. qcfbw, yctkbmy q rgdfquzw? ittad yttv. zwqc qstgf xcqmabw? owqz. otg ytbmy ft fzw xgmwcqi? mt, b'r mtf ytbmy. wjwcostvo amtkd, dfbmy dtrwtmw, otg vbw. vtm'f kqdfw bf tm q degbccwi. dguz q ztfzwqv. b ygwdd zw utgiv zqjw lgdf ytffwm tgf tx fzw kqo. b itjw fzbd bmutchtcqfbmy qm qrgdwrwmf hqca bmft tgc vqo. fzqf'd kzo kw vtm'f mwwv jquqfbtmd. sto, egbfw q sbf tx htrh... gmvwc fzw ubcugrdfqmuwd. kwii, qvqr, ftvqo kw qcw rwm. kw qcw! sww-rwm. qrwm! zqiiwiglqz! dfgvwmfd, xqugifo, vbdfbmygbdzwv swwd, hiwqdw kwiutrw vwqm sgppkwii. kwiutrw, mwk zbjw ubfo ycqvgqfbmy uiqdd tx... ...9:15. fzqf utmuigvwd tgc uwcwrtmbwd. qmv swybmd otgc uqcwwc qf ztmwn bmvgdfcbwd! kbii kw hbua tgclts ftvqo? b zwqcv bf'd lgdf tcbwmfqfbtm. zwqvd gh! zwcw kw yt. awwh otgc zqmvd qmv qmfwmmqd bmdbvw fzw fcqr qf qii fbrwd. ktmvwc kzqf bf'ii sw ibaw? q ibffiw duqco. kwiutrw ft ztmwn, q vbjbdbtm tx ztmwdut qmv q hqcf tx fzw zwnqytm yctgh. fzbd bd bf! ktk. ktk. kw amtk fzqf otg, qd q sww, zqjw ktcawv otgc kztiw ibxw ft ywf ft fzw htbmf kzwcw otg uqm ktca xtc otgc kztiw ibxw. ztmwo swybmd kzwm tgc jqibqmf htiiwm ltuad scbmy fzw mwufqc ft fzw zbjw. tgc fth-dwucwf xtcrgiq bd qgftrqfbuqiio utitc-utccwufwv, duwmf-qvlgdfwv qmv sgssiw-utmftgcwv bmft fzbd dttfzbmy dkwwf docgh kbfz bfd vbdfbmufbjw ytivwm yitk otg amtk qd... ztmwo! fzqf ybci kqd ztf. dzw'd ro utgdbm! dzw bd? owd, kw'cw qii utgdbmd. cbyzf. otg'cw cbyzf. qf ztmwn, kw utmdfqmfio dfcbjw ft brhctjw wjwco qdhwuf tx sww wnbdfwmuw. fzwdw swwd qcw dfcwdd-fwdfbmy q mwk zwirwf fwuzmtityo. kzqf vt otg fzbma zw rqawd? mtf wmtgyz. zwcw kw zqjw tgc iqfwdf qvjqmuwrwmf, fzw acwirqm. qufx{awowvuqwdqcrtcwibawdgsdfbfgfbtm}
```

## 解法
タイトル的にシーザー暗号の派生っぽい。
シーザー暗号はA-Z順のリストを元に鍵分シフトするが、
与えられたソースを見ると、key.txtからリストを生成している。
よって、単一換字式暗号とみなして地道に解いていく。

## コード

```python:solution
text="quutcvbmy ft qii amtkm iqkd tx qjbqfbtm, fzwcw bd mt kqo q sww dztgiv sw qsiw ft xio. bfd kbmyd qcw ftt drqii ft ywf bfd xqf ibffiw stvo txx fzw yctgmv. fzw sww, tx utgcdw, xibwd qmokqo swuqgdw swwd vtm'f uqcw kzqf zgrqmd fzbma bd brhtddbsiw. owiitk, siqua. owiitk, siqua. owiitk, siqua. owiitk, siqua. ttz, siqua qmv owiitk! iwf'd dzqaw bf gh q ibffiw. sqcco! scwqaxqdf bd cwqvo! utrbmy! zqmy tm q dwutmv. zwiit? sqcco? qvqr? uqm otg swibwjw fzbd bd zqhhwmbmy? b uqm'f. b'ii hbua otg gh. ittabmy dzqch. gdw fzw dfqbcd. otgc xqfzwc hqbv yttv rtmwo xtc fztdw. dtcco. b'r wnubfwv. zwcw'd fzw ycqvgqfw. kw'cw jwco hctgv tx otg, dtm. q hwcxwuf cwhtcf uqcv, qii s'd. jwco hctgv. rq! b ytf q fzbmy ytbmy zwcw. otg ytf ibmf tm otgc xgpp. tk! fzqf'd rw! kqjw ft gd! kw'ii sw bm ctk 118,000. sow! sqcco, b ftiv otg, dfth xiobmy bm fzw ztgdw! zwo, qvqr. zwo, sqcco. bd fzqf xgpp ywi? q ibffiw. dhwubqi vqo, ycqvgqfbtm. mwjwc fztgyzf b'v rqaw bf. fzcww vqod ycqvw duztti, fzcww vqod zbyz duztti. fztdw kwcw qkakqcv. fzcww vqod utiiwyw. b'r yiqv b ftta q vqo qmv zbfuzzbawv qctgmv fzw zbjw. otg vbv utrw squa vbxxwcwmf. zb, sqcco. qcfbw, yctkbmy q rgdfquzw? ittad yttv. zwqc qstgf xcqmabw? owqz. otg ytbmy ft fzw xgmwcqi? mt, b'r mtf ytbmy. wjwcostvo amtkd, dfbmy dtrwtmw, otg vbw. vtm'f kqdfw bf tm q degbccwi. dguz q ztfzwqv. b ygwdd zw utgiv zqjw lgdf ytffwm tgf tx fzw kqo. b itjw fzbd bmutchtcqfbmy qm qrgdwrwmf hqca bmft tgc vqo. fzqf'd kzo kw vtm'f mwwv jquqfbtmd. sto, egbfw q sbf tx htrh... gmvwc fzw ubcugrdfqmuwd. kwii, qvqr, ftvqo kw qcw rwm. kw qcw! sww-rwm. qrwm! zqiiwiglqz! dfgvwmfd, xqugifo, vbdfbmygbdzwv swwd, hiwqdw kwiutrw vwqm sgppkwii. kwiutrw, mwk zbjw ubfo ycqvgqfbmy uiqdd tx... ...9:15. fzqf utmuigvwd tgc uwcwrtmbwd. qmv swybmd otgc uqcwwc qf ztmwn bmvgdfcbwd! kbii kw hbua tgclts ftvqo? b zwqcv bf'd lgdf tcbwmfqfbtm. zwqvd gh! zwcw kw yt. awwh otgc zqmvd qmv qmfwmmqd bmdbvw fzw fcqr qf qii fbrwd. ktmvwc kzqf bf'ii sw ibaw? q ibffiw duqco. kwiutrw ft ztmwn, q vbjbdbtm tx ztmwdut qmv q hqcf tx fzw zwnqytm yctgh. fzbd bd bf! ktk. ktk. kw amtk fzqf otg, qd q sww, zqjw ktcawv otgc kztiw ibxw ft ywf ft fzw htbmf kzwcw otg uqm ktca xtc otgc kztiw ibxw. ztmwo swybmd kzwm tgc jqibqmf htiiwm ltuad scbmy fzw mwufqc ft fzw zbjw. tgc fth-dwucwf xtcrgiq bd qgftrqfbuqiio utitc-utccwufwv, duwmf-qvlgdfwv qmv sgssiw-utmftgcwv bmft fzbd dttfzbmy dkwwf docgh kbfz bfd vbdfbmufbjw ytivwm yitk otg amtk qd... ztmwo! fzqf ybci kqd ztf. dzw'd ro utgdbm! dzw bd? owd, kw'cw qii utgdbmd. cbyzf. otg'cw cbyzf. qf ztmwn, kw utmdfqmfio dfcbjw ft brhctjw wjwco qdhwuf tx sww wnbdfwmuw. fzwdw swwd qcw dfcwdd-fwdfbmy q mwk zwirwf fwuzmtityo. kzqf vt otg fzbma zw rqawd? mtf wmtgyz. zwcw kw zqjw tgc iqfwdf qvjqmuwrwmf, fzw acwirqm. qufx#awowvuqwdqcrtcwibawdgsdfbfgfbtm#"

str_list = list(text)
eigo = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']
col = []
for i in eigo:
    col.append((i, str_list.count(i.lower())))
col.sort(key=lambda x:x[1])
for l in col:
    print(l)
ans = text
u_dict ={
"a":"k",
"b":"i",
"c":"r",
"d":"s",
"e":"q",
"f":"t",
"g":"u",
"h":"p",
"i":"l",
"j":"v",
"k":"w",
"l":"L",
"m":"n",
"n":"x",
"o":"y",
"p":"l",
"q":"a",
"r":"m",
"s":"b",
"t":"o",
"u":"c",
"v":"d",
"w":"e",
"x":"f",
"y":"g",
"z":"h"}

read_list = [] 
for i, one_dic in enumerate(u_dict.items()): 
    text = text.replace(one_dic[0], '{'+str(i)+'}')
    read_list.append(one_dic[1]) 

text = text.format(*read_list) 
print(text)
```
辞書には頻度や単語から分かったものを埋めていく。
例えば、問題文の後半に明らかフラグっぽいところがあるのでqufx->actfである。

```txt:out
('E', 2)
('L', 6)
('N', 6)
('P', 6)
('J', 22)
('H', 30)
('X', 31)
('A', 33)
('R', 39)
('S', 43)
('Y', 53)
('K', 60)
('U', 66)
('O', 70)
('V', 74)
('G', 78)
('I', 103)
('Z', 106)
('C', 114)
('M', 121)
('D', 123)
('B', 131)
('Q', 168)
('F', 174)
('T', 188)
('W', 257)
according to all known laws of aviation, there is no way a bee should be able to fly. its wings are too small to get its fat little body off the ground. the bee, of course, flies anyway because bees don't care what humans think is impossible. yellow, black. yellow, black. yellow, black. yellow, black. ooh, black and yellow! let's shake it up a little. barry! breakfast is ready! coming! hang on a second. hello? barry? adam? can you believe this is happening? i can't. i'll pick you up. looking sharp. use the stairs. your father paid good money for those. sorry. i'm excited. here's the graduate. we're very proud of you, son. a perfect report card, all b's. very proud. ma! i got a thing going here. you got lint on your full. ow! that's me! wave to us! we'll be in row 118,000. bye! barry, i told you, stop flying in the house! hey, adam. hey, barry. is that full gel? a little. special day, graduation. never thought i'd make it. three days grade school, three days high school. those were awkward. three days college. i'm glad i took a day and hitchhiked around the hive. you did come back different. hi, barry. artie, growing a mustache? looks good. hear about frankie? yeah. you going to the funeral? no, i'm not going. everybody knows, sting someone, you die. don't waste it on a squirrel. such a hothead. i guess he could have Lust gotten out of the way. i love this incorporating an amusement park into our day. that's why we don't need vacations. boy, quite a bit of pomp... under the circumstances. well, adam, today we are men. we are! bee-men. amen! halleluLah! students, faculty, distinguished bees, please welcome dean bullwell. welcome, new hive city graduating class of... ...9:15. that concludes our ceremonies. and begins your career at honex industries! will we pick ourLob today? i heard it's Lust orientation. heads up! here we go. keep your hands and antennas inside the tram at all times. wonder what it'll be like? a little scary. welcome to honex, a division of honesco and a part of the hexagon group. this is it! wow. wow. we know that you, as a bee, have worked your whole life to get to the point where you can work for your whole life. honey begins when our valiant pollen Locks bring the nectar to the hive. our top-secret formula is automatically color-corrected, scent-adLusted and bubble-contoured into this soothing sweet syrup with its distinctive golden glow you know as... honey! that girl was hot. she's my cousin! she is? yes, we're all cousins. right. you're right. at honex, we constantly strive to improve every aspect of bee existence. these bees are stress-testing a new helmet technology. what do you think he makes? not enough. here we have our latest advancement, the krelman. actf#keyedcaesarmorelikesubstitution#
```