krypthon 5 通关过程
Krypton Level 5 -> 6 - OverTheWire 通关记录
任务:破译服务器目录下/krypthon/krtpthon5/包含的秘文
题目原文:FA can break a known key length as well. Lets try one last polyalphabetic cipher, but this time the key length is unknown. Note: the text is writen in American English
Enjoy.
此级别是 Vigenère 密码。您截获了两封较长的加密英语邮件 (美式英语)。密钥长度未知。
理论基础
1.维吉尼加密
如果我们使用密钥 (Key)= 'GOLD',并且 P ='PROCEEDMEETINGASAGREED' ,然后将 P “添加”到 Key,我们得到 C。加法时,如果我们超过 25,则滚动到 0(模数 26)。
P P R O C E E D M E E T I N G A S A G R E E D\
K G O L D G O L D G O L D G O L D G O L D G O\
转化为数字:
P 15 17 14 2 4 4 3 12 4 4 19 8 13 6 0 18 0 6 17 4 4 3\
K 6 14 11 3 6 14 11 3 6 14 11 3 6 14 11 3 6 14 11 3 6 14\
C 21 5 25 5 10 18 14 15 10 18 4 11 19 20 11 21 6 20 2 8 10 17\
然后,我们得到了密文:
VFZFK SOPKS ELTUL VGUCH KR
2.Kasiski测试法
两个相同的明文段要加密为相同的密文段,它们之间间距为 δ ,密钥的长度 m 一定是 δ 的约数,如果能在密文中观察到两个长度至少为 3 的密文段,它们很可能是由相同的明文段加密来的,并且密钥长度 m 是它们之间的距离 δ 的约数。
解决方案
我的想法
1.使用bash脚本统计出文中所有的出现大于等于5次的三字密文段,通过kasiski法计算出可能的密钥长度(keylength)。
2.以密钥长度划分数据对密文进行分析,把整体分为n=keylength份,理论上第1个字母和1+n*keylength个字母使用的密钥是一样的,所以可以进行统计学分析。
解决过程
登陆服务器:ssh krypton4@krypton.labs.overthewire.org -p 2231
检查其中一个密文
krypton5@bandit:~$ cat /krypton/krypton5/found1
SXULW GNXIO WRZJG OFLCM RHEFZ ALGSP DXBLM PWIQT XJGLA RIYRI BLPPC HMXMG CTZDL CLKRU YMYSJ TWUTX ZCMRH EFZAL OTMNL BLULV MCQMG CTZDL CPTBI AVPML NVRJN SSXWT XJGLA RIQPE FUGVP PGRLG OMDKW RSIFK TZYRM QHNXD UOWQT XJGLA RIQAV VTZVP LMAIV ZPHCX FPAVT MLBSD OIFVT PBACS EQKOL BCRSM AMULP SPPYF CXOKH LZXUO GNLID ZVRAL DOACC INREN YMLRH VXXJD XMSIN BXUGI UPVRG ESQSG YKQOK LMXRS IBZAL BAYJM AYAVB XRSIC KKPYH ULWFU YHBPG VIGNX WBIQP RGVXY SSBEL NZLVW IMQMG YGVSW GPWGG NARSP TXVKL PXWGD XRJHU SXQMI VTZYO GCTZR JYVBK MZHBX YVBIT TPVTM OOWSA IERTA SZCOI TXXLY JAZQC GKPCS LZRYE MOOVC HIEKT RSREH MGNTS KVEPN NCTUN EOFIR TPPDL YAPNO GMKGC ZRGNX ARVMY IBLXU QPYYH GNXYO ACCIN QBUQA GELNR TYQIH LANTW HAYCP RJOMO KJYTV SGVLY RRSIG NKVXI MQJEG GJOML MSGNV VERRC MRYBA GEQNP RGKLB XFLRP XRZDE JESGN XSYVB DSSZA LCXYE ICXXZ OVTPW BLEVK ZCDEA JYPCL CDXUG MARML RWVTZ LXIPL PJKKL CIREP RJYVB ITPVV ZPHCX FPCRG KVPSS CPBXW VXIRS SHYTU NWCGI ANNUN VCOEA JLLFI LECSO OLCTG CMGAT SBITP PNZBV XWUPV RIHUM IBPHG UXUQP YYHNZ MOKXD LZBAK LNTCC MBJTZ KXRSM FSKZC SSELP UMARE BCIPK GAVCY EXNOG LNLCC JVBXH XHRHI AZBLD LZWIF YXKLM PELQG RVPAF ZQNVK VZLCE MPVKP FERPM AZALV MDPKH GKKCL YOLRX TSNIB ELRYN IVMKP ECVXH BELNI OETUX SSYGV TZARE RLVEG GNOQC YXFCX YOQYO ISUKA RIQHE YRHDS REFTB LEVXH MYEAJ PLCXK TRFZX YOZCY XUKVV MOJLR RMAVC XFLHO KXUVE GOSAR RHBSS YHQUS LXSDJ INXLH PXCCV NVIPX KMFXV ZLTOW QLKRY TZDLC DTVXB ACSDE LVYOL BCWPE ERTZD TYDXF AILBR YEYEG ESIHC QMPOX UDMLZ VVMBU KPGEC EGIWO HMFXG NXPBW KPVRS XZCEE PWVTM OOIYC XURRV BHCCS SKOLX XQSEQ RTAOP WNSZK MVDLC PRTRB ZRGPZ AAGGK ZIMAP RLKVW EAZRT XXZCS DMVVZ BZRWS MNRIM ZSRYX IEOVH GLGNL FZKHX KCESE KEHDI FLZRV KVFIB XSEKB TZSPE EAZMV DLCSY ZGGYK GCELN TTUIG MXQHT BJKXG ZRFEX ABIAP MIKWA RVMFK UGGFY JRSIP NBJUI LDSSZ ALMSA VPNTX IBSMO
在/tmp/下创建文件夹并vi
#!/bin/bash
file_path="$1"
text=$(cat "$file_path")
text=$(echo "$text" | tr -cd 'a-zA-Z' | tr '[:upper:]' '[:lower:]')
temp_file=$(mktemp)
for ((i = 0; i < ${#text} - 2; i++)); do
triplet="${text:i:3}"
echo "$triplet $i" >> "$temp_file"
done
# 统计每个三字母组合出现的次数,并列出出现的位置
awk '{count[$1]++; positions[$1]=positions[$1]" "$2} END {
for (triplet in count) {
if (count[triplet] > 4) {
print "三字母:", triplet, "出现次数:", count[triplet]
split(positions[triplet], pos_array, " ")
for (i = 1; i < count[triplet]; i++) {
interval = pos_array[i+1] - pos_array[i]
printf "重复出现的间隔: %d\n", interval
}
}
}
}' "$temp_file"
执行脚本得到以下结果
krypton5@bandit:/tmp/mydir$ ./count.sh /krypton/krypton5/found1
三字母: rsi 出现次数: 5
重复出现的间隔: 153
重复出现的间隔: 18
重复出现的间隔: 270
重复出现的间隔: 855
三字母: dlc 出现次数: 5
重复出现的间隔: 45
重复出现的间隔: 1044
重复出现的间隔: 135
重复出现的间隔: 108
三字母: zal 出现次数: 6
重复出现的间隔: 63
重复出现的间隔: 225
重复出现的间隔: 351
重复出现的间隔: 288
重复出现的间隔: 513
三字母: gnx 出现次数: 6
重复出现的间隔: 342
重复出现的间隔: 180
重复出现的间隔: 18
重复出现的间隔: 108
重复出现的间隔: 576
计算得出可能的keylength为9
对三封邮件在vim中:%s/ //g清理空格进行取模处理,合并。创建并执行以下脚本。
#!/bin/bash
file="$1"
if [[ ! -f "$file" ]]; then
echo "文件不存在: $file"
exit 1
fi
declare -A letter_count_group
position=1
while IFS= read -r -n1 char; do
char=$(echo "$char" | tr 'a-z' 'A-Z')
if [[ "$char" =~ [A-Z] ]]; then
group=$(( (position - 1) % 9 + 1 )) # 计算分组 (1-9)
key="${group}_${char}" # 组合键
((letter_count_group[$key]++))
fi
((position++))
done < "$file"
# 输出结果
for group in {1..9}; do
total_count=0
echo "组 $group 字母统计结果:"
for letter in {A..Z}; do
key="${group}_${letter}"
if [[ -n "${letter_count_group[$key]}" ]]; then
total_count=$((total_count + letter_count_group[$key]))
fi
done
if [ "$total_count" -gt 0 ]; then
for letter in {A..Z}; do
key="${group}_${letter}"
if [[ -n "${letter_count_group[$key]}" ]]; then
percentage=$(echo "scale=2; ${letter_count_group[$key]} / $total_count * 100" | bc)
echo "$letter: ${letter_count_group[$key]} (占比: $percentage%)"
fi
done | sort -k2 -nr
else
echo "该组没有字母。"
fi
echo ""
done
得出以下结果
krypton5@bandit:/tmp/md$ ./crack.sh mixtext 太长了省略一些
组 1 字母统计结果:
O: 63 (占比: 11.00%)
K: 51 (占比: 9.00%)
C: 49 (占比: 9.00%)
D: 48 (占比: 8.00%)
Y: 46 (占比: 8.00%)
B: 39 (占比: 7.00%)
R: 35 (占比: 6.00%)
S: 34 (占比: 6.00%)
X: 30 (占比: 5.00%)
V: 18 (占比: 3.00%)
P: 17 (占比: 3.00%)
N: 17 (占比: 3.00%)
Q: 13 (占比: 2.00%)
M: 13 (占比: 2.00%)
W: 10 (占比: 1.00%)
G: 10 (占比: 1.00%)
E: 10 (占比: 1.00%)
组 2 字母统计结果:
I: 66 (占比: 12.00%)
S: 56 (占比: 10.00%)
X: 45 (占比: 8.00%)
...
组 3 字母统计结果:
C: 74 (占比: 13.00%)
R: 46 (占比: 8.00%)
M: 43 (占比: 7.00%)
...
组 4 字母统计结果:
P: 72 (占比: 13.00%)
E: 48 (占比: 8.00%)
L: 43 (占比: 7.00%)
...
组 5 字母统计结果:
I: 73 (占比: 13.00%)
S: 46 (占比: 8.00%)
E: 45 (占比: 8.00%)
...
组 6 字母统计结果:
R: 57 (占比: 10.00%)
G: 51 (占比: 9.00%)
N: 44 (占比: 8.00%)
...
组 7 字母统计结果:
K: 59 (占比: 11.00%)
G: 55 (占比: 10.00%)
Z: 53 (占比: 9.00%)
...
组 8 字母统计结果:
X: 71 (占比: 13.00%)
T: 55 (占比: 10.00%)
M: 43 (占比: 8.00%)
...
组 9 字母统计结果:
L: 64 (占比: 11.00%)
V: 50 (占比: 9.00%)
U: 48 (占比: 8.00%)
...
美式英语中出现频率最高的字母是E,根据统计的对应关系对密钥进行逆推即可得出密钥。
出于CTF规则,本文章并不会直接提供答案。