saotake’s blog

-竿竹-

(TUCTF2016)The Neverending Crypto Level1(Crypto10)

ncでつないで問題を何回も解くタイプの問題。
お題は、以下の感じ。

xxx@ubuntu:~/py$ nc 146.148.102.236 24069
Welcome to The Neverending Crypto!
Quick, find Falkor and get through this!
This is level 1, the Bookstore
Round 1. Give me some text:abc
abc encrypted is .- -... -.-.
What is .-. . .- -.. .. -. --. .. ... -.. .- -. --. . .-. --- ..- .-. ... decrypted?
:XXXXXXXX
No... I am leaving.

平文と暗号文の対応関係が毎回変わると厄介なんだけど、
プログラムを何回起動しても同じ。
一回正解すると、まったく同じ内容で[Round2]が開始されるんだけど、
平文と暗号文の対応関係は変わらず。
なので、あらかじめ英数字がどのように暗号化されるかの対応表を作っておいて、
ハードコーディングしておきました。
Level2以降はこの辺が動的になるのかな?

ちなみに、時間制限ありで、50問連続正解が必要なので、
手動は無理でした。

import socket

def doattack():
chrstring = "0123456789abcdefghijklmnopqrstuvwxyz "
enclist = ["-----",".----","..---","...--","....-",".....","-....","--...","---..","----.",".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--..","SP"]

while True:
data = s.recv(2048)
print data
if(" Give me some text:" in data):
break

s.sendall("abc\n")

while True:
data = s.recv(2048)
print data
if(" encrypted is " in data):
break

qstring = data.split("\n")[1]
qstring = qstring.replace(" "," SP ")
print qstring
print qstring[8:len(qstring)-12]
qlist = qstring[8:len(qstring)-12].split(" ")
print qlist
ans = ""
for q in qlist:
ans += chrstring[enclist.index(q)]
print ans
print ans

s.sendall(ans + "\n")

#main
hostname = "146.148.102.236"
port = 24069
s = socket.socket( socket.AF_INET, socket.SOCK_STREAM)
s.connect*1

while True:
doattack()

※スペースだけは変換されずにスペースのままで、セパレータをスペースにするとめちゃくちゃになるので、
軽くエスケープしています。

*1:hostname,port