《算法还原 - CTF 》Crypto篇 十题

题目一:凯撒密码的base64形式

给出字符串。要求:解密获得flag

 e6Z9i~]8R~U~QHE{RnY{QXg~QnQ{^XVlRXlp^XI5Q6Q6SKY8jUAA

解题思路

观察最后的AA,联想到base64编码最后常出现的==,A的ASCII码值为65,=的ASCII的码值为61,分析可能是base64编码做了偏移,尝试将密文所有字符的ASCII码值-4,然后再做base64解码。

print(ord('A')) # 65
print(ord('=')) # 61

答案

enc = 'e6Z9i~]8R~U~QHE{RnY{QXg~QnQ{^XVlRXlp^XI5Q6Q6SKY8jUAA'

ok = ''
for x in enc:
    ok += chr(ord(x) -4)
print(ok == "a2V5ezY4NzQzMDAwNjUwMTczMjMwZTRhNThlZTE1M2M2OGU4fQ==")

import base64
ok = base64.b64decode(ok.encode()).decode()
print(ok == "key{68743000650173230e4a58ee153c68e8}")

也可以从 010 编辑器 批量改字符
《算法还原 - CTF 》Crypto篇 十题_第1张图片

《算法还原 - CTF 》Crypto篇 十题_第2张图片

也可以得到
a2V5ezY4NzQzMDAwNjUwMTczMjMwZTRhNThlZTE1M2M2OGU4fQ==

总结:
遍历密文字符串的每个字符,获取它的ascii码值,-4之后转化为新的ASCII字符,拼接转化的字符之后获得还原的base64字符串,然后再做base64解密。这里的4就相当于凯撒密码的密钥。

base64编码之后做偏移加密,凯撒密码的base64形式(自己起的名字)。

结果

key{68743000650173230e4a58ee153c68e8}

题目二:恺撒密码

Fhfpgs{3r811r068s5pr27ro4op1p37723q7rr2}

解题思路

恺撒密码:它的偏移量最多就是25。请通过穷举找到 Susctf{XXX} 的字符串

答案


def unlock(text):
    for i in text:
        if 65 + key <= ord(text) < 92 or 97 + key <= ord(text) < 123:
            text = chr(ord(text) - key)
        elif 65 <= ord(text) < 65 + key or 97 <= ord(text) < 97 + key:
            text = chr(ord(text) - key + 26)
        else:
            text = text
    return text


text = 'Fhfpgs{3r811r068s5pr27ro4op1p37723q7rr2}'
plaintext = ""
for key in range(1, 27):
    for k in list(map(unlock, text)):
        plaintext = plaintext + k
    print("第%d把钥匙的结果是%s" % (key, plaintext))
    plaintext = ""

输出结果

1把钥匙的结果是Egeofr{3q811q068r5oq27qn4no1o37723p7qq2}2把钥匙的结果是Dfdneq{3p811p068q5np27pm4mn1n37723o7pp2}3把钥匙的结果是Cecmdp{3o811o068p5mo27ol4lm1m37723n7oo2}4把钥匙的结果是Bdblco{3n811n068o5ln27nk4kl1l37723m7nn2}5把钥匙的结果是Acakbn{3m811m068n5km27mj4jk1k37723l7mm2}6把钥匙的结果是Zbzjam{3l811l068m5jl27li4ij1j37723k7ll2}7把钥匙的结果是Yayizl{3k811k068l5ik27kh4hi1i37723j7kk2}8把钥匙的结果是Xzxhyk{3j811j068k5hj27jg4gh1h37723i7jj2}9把钥匙的结果是Wywgxj{3i811i068j5gi27if4fg1g37723h7ii2}10把钥匙的结果是Vxvfwi{3h811h068i5fh27he4ef1f37723g7hh2}11把钥匙的结果是Uwuevh{3g811g068h5eg27gd4de1e37723f7gg2}12把钥匙的结果是Tvtdug{3f811f068g5df27fc4cd1d37723e7ff2}13把钥匙的结果是Susctf{3e811e068f5ce27eb4bc1c37723d7ee2}14把钥匙的结果是Rtrbse{3d811d068e5bd27da4ab1b37723c7dd2}15把钥匙的结果是Qsqard{3c811c068d5ac27cz4za1a37723b7cc2}16把钥匙的结果是Prpzqc{3b811b068c5zb27by4yz1z37723a7bb2}17把钥匙的结果是Oqoypb{3a811a068b5ya27ax4xy1y37723z7aa2}18把钥匙的结果是Npnxoa{3z811z068a5xz27zw4wx1x37723y7zz2}19把钥匙的结果是Momwnz{3y811y068z5wy27yv4vw1w37723x7yy2}20把钥匙的结果是Lnlvmy{3x811x068y5vx27xu4uv1v37723w7xx2}21把钥匙的结果是Kmkulx{3w811w068x5uw27wt4tu1u37723v7ww2}22把钥匙的结果是Jljtkw{3v811v068w5tv27vs4st1t37723u7vv2}23把钥匙的结果是Ikisjv{3u811u068v5su27ur4rs1s37723t7uu2}24把钥匙的结果是Hjhriu{3t811t068u5rt27tq4qr1r37723s7tt2}25把钥匙的结果是Gigqht{3s811s068t5qs27sp4pq1q37723r7ss2}26把钥匙的结果是Fhfpgs{3r811r068s5pr27ro4op1p37723q7rr2}

最后找到,第13把钥匙的结果是

Susctf{3e811e068f5ce27eb4bc1c37723d7ee2}

题目三:摩斯密码

 ..-./.-../.-/--./----.--/-../...--/..-./-.-./-.../..-./.----/--.../..-./----./...--/----./----./...../-----/....-/-----.-

在 https://www.bejson.com/enc/morse/

可以得到

FLAG%u7bD3FCBF17F9399504%u7d

FLAG{D3FCBF17F9399504}

然后转小写

flag{d3fcbf17f9399504}

题目给了描述:一只小羊翻过了2个栅栏

fa{fe13f590lg6d46d0d0}


def encrypt_fence(string, key):  # 没用到
    ciphertext = ""
    temp = []
    for i in range(key):
        temp.append("")
    for index, i in enumerate(string):
        temp[index % key] += i
    # print("".join(temp))
    ciphertext = "".join(temp)
    return ciphertext

def decrypt_fence(string, key):
    plaintext = ""
    length = len(string)
    min_row = length // key
    max_num = length % key
    temp = []
    index = 0
    for i in range(key):
        if i < max_num:
            temp.append(string[index:index + min_row + 1])
            index += min_row + 1
        else:
            temp.append(string[index:index + min_row])
            index += min_row
    # print(temp)
    for i in range(length):
        plaintext += temp[i % key][i // key]
    return plaintext


print(decrypt_fence("fa{fe13f590lg6d46d0d0}", 2) == 'flag{6fde4163df05d900}')
# print(encrypt_fence("flag{6fde4163df05d900}", 2) == 'fa{fe13f590lg6d46d0d0}')

结果

flag{6fde4163df05d900}

题目四:各种进制

二进制、八进制、十进制、十六进制,你能分的清吗? 来源:第七届大学生网络安全技能大赛

d87 x65 x6c x63 o157 d109 o145 b100000 d116 b1101111 o40 x6b b1100101 b1101100 o141 d105 x62 d101 b1101001 d46 o40 d71 x69 d118 x65 x20 b1111001 o157 b1110101 d32 o141 d32 d102 o154 x61 x67 b100000 o141 d115 b100000 b1100001 d32 x67 o151 x66 d116 b101110 b100000 d32 d102 d108 d97 o147 d123 x31 b1100101 b110100 d98 d102 b111000 d49 b1100001 d54 b110011 x39 o64 o144 o145 d53 x61 b1100010 b1100011 o60 d48 o65 b1100001 x63 b110110 d101 o63 b111001 d97 d51 o70 d55 b1100010 d125 x20 b101110 x20 b1001000 d97 d118 o145 x20 d97 o40 d103 d111 d111 x64 d32 o164 b1101001 x6d o145 x7e

发现规律
b 开头是 二进制
o 开头是 八进制
d 开头是 十进制
x 开头是 16进制


enc = 'd87 x65 x6c x63 o157 d109 o145 b100000 d116 b1101111 o40 x6b b1100101 b1101100 o141 d105 x62 d101 b1101001 d46 o40 d71 x69 d118 x65 x20 b1111001 o157 b1110101 d32 o141 d32 d102 o154 x61 x67 b100000 o141 d115 b100000 b1100001 d32 x67 o151 x66 d116 b101110 b100000 d32 d102 d108 d97 o147 d123 x31 b1100101 b110100 d98 d102 b111000 d49 b1100001 d54 b110011 x39 o64 o144 o145 d53 x61 b1100010 b1100011 o60 d48 o65 b1100001 x63 b110110 d101 o63 b111001 d97 d51 o70 d55 b1100010 d125 x20 b101110 x20 b1001000 d97 d118 o145 x20 d97 o40 d103 d111 d111 x64 d32 o164 b1101001 x6d o145 x7e'
el = enc.split(' ')
ok = ''

a = 0
for x in el:
    if x[0] == "d":
        a = 10
    if x[0] == "x":
        a = 16
    if x[0] == "o":
        a = 8
    if x[0] == "b":
        a = 2
    ok += chr(int(x[1:], a))

print(ok)

# Welcome to kelaibei. Give you a flag as a gift.  flag{1e4bf81a6394de5abc005ac6e39a387b} . Have a good time~

结果

flag{1e4bf81a6394de5abc005ac6e39a387b}

题目五:贝斯家族

@iH<,{bdR2H;i6*Tm,Wx2izpx2!

发现规律 base91 编码

结果

flag{554a5058c9021c76}

题目六:这不是md5

666c61677b616537333538376261353662616566357d

p = "666c61677b616537333538376261353662616566357d"
s = []
for i in range(0, len(p), 2):
    b = p[i : i + 2]
    s.append(chr(int(b, 16)))
print("".join(s))

结果

flag{ae73587ba56baef5}

题目七:散乱的密文

lf5{ag024c483549d7fd@@1} 一张纸条上凌乱的写着2 1 6 5 3 4

本题要点:栅栏密码

看到 2 1 6 5 3 4 这一串数字~

是乱序的…看一下上面这串字符,也是乱序的~

按照数字的顺序写下来~

列出表格

2 1 6 5 3 4
l f 5 { a g
0 2 4 c 4 8
3 5 4 9 d 7
f d @ @ 1 }

调整表格

1 2 3 4 5 6
f l a g { 5
2 0 4 8 c 4
5 3 d 7 9 4
d f 1 } @ @
一行行列出来就是flag了(要去掉两个@)

结果

flag{52048c453d794df1}

题目八:这是个盲兔子,竟然在唱歌!

⡥⠂⡶⡃⡔⡷⡦⡛⡨⠁⠟⡚⠉⠇⡳⡜⡉⡤⡴⡑⡓⡆⡑⡔⡆⡠⡩⡹⠂⡢⡪⡵⡢⡟⡶⡹⠃⡒⠁⡥⡞⠟⡚⡞⡣⡣⡤⡀⡡⡆⠉⡼⡻⠀⠉⡧⡙⠇⡦⡇⡧⡅⡺⡑⠺⡑⡉⡑⠂⡞⡱⡳⠁⡊⡢⡩⡊⡚⡊⡕⡛⠀⡕⠂⡩⡱⡾⡴⠂⡶⡛⠈⡹⡇⡗⡑⠃⠁⡆⡝⡽⡺⡨⡙⠛⠅⠁⡠⡇⡩⡅⡸⡑⡧⡑⡸⠅⡆⡨⠛⡣⡨⡑⡢⡝⠁⡟⡚⡿⠺⠛⡿⡕⡴⡛⡡⠀⡔⠉⠂⡴⡃⠃⠀⡿⡹⠄⡺⡀⡵⡊⡝⡪⡨⡛⡦⡖⡛⡧⡡⡪⠈⡲⠟⡝⡔⡕⠅⡄⡞⠟⠂⡵⡉⠅⡩⡦⡼⡈⡴⡩⡈⠟⡞⡦⡩⡆⡛⡴⡾⡈⡁⡁⡗⠺⡹⡾⡆⡢⡹⡠⡈⡃⡛⠆⡁⡖⡻⡉⡡⡻⡓⠆⡁⡼⡷⠃⡛⠅⡵⠈⡝⡂⠉⡃⡄⡠⡠⡡⡒⡁⡃⡁⠅⡾⡨⠆⡘⠇⡄⡁⡲⠅⡖⠛⡓⡤⡃⡕⡺⡃⡝⡛⡳⠀⡢⡒⡙⠂⠺⡱⡉⡻⡒⡨⡄⡒⡒⡈⡱⡧⡽⠆⡉⡷⡹⠛⡊⠟⡥⡜⡳⡶⠆⡺⠉⠂⡂⡛⡥⡓⡝⡴⠆⡽⡟⠅⡿⡻⡸⡺⠆⡇⠂⠈⡼⡤⡕⠂⠈⡤⠅⠛⠁⡇⡟⡧⡈⡗⡲⡊⡸⠉⡻⠺⡱⡻⡥⠍=

https://www.qqxiuzi.cn/bianma/wenbenjiami.php?s=mangwen

得到

U2FsdGVkX1/j97ClyTDacvadvPYI2RZERoFI3b1Un/jnSSTpQv9LK09Wi7VwWuJa
aya2nAC1zRYzjzek0e2YAND2Fk8Iwga31vmMJXi+51PwYuHaWaH5vX+SXaRm1ojO
+OeDkQ0d92Ds30OI4JpEzmZXkVfkWQZ8B/mde5tn/2Ey5YVLxDYx/nVYvkDNxqqg
INvRIPxsk6qfKyQKc6qLG3k5E8mr9stPPQbqsq5NX6h7tqB5f+cTseJsmkC0Rbi2
AyKbXtbbxAWM6yGI+z/UlCF6J92rkUcmD6Mo5OKHJ6w28LTe28T5+1woWxgBzH9K
AKU=

但是记住要把最后一个换行给删除了,=符号不用管就放在那里就可以了,然后提示也是给我们提示了,兔子,那就大胆猜测一波是和兔子有关的解码,在网上可以查得到,然后我们用这个网站

https://tool.ruyo.net/rabbitencrypt/

得到

♬♯♩¶♬♫¶♭♩¶♫♪‖♯♬♭♩♬‖♫‖∮‖♩♬§‖♪¶‖♬♩♬§‖♩¶∮♬♬‖♪¶♭¶♯♫♯♩♫‖‖♬§‖♫♬♯♬§♫‖♩♩♫∮♬♩♫‖‖♪¶∮♫‖♫♫♯=

下面是一串音符,对应了题目提示的歌唱,于是我们在网上搜索一下和音符有关的解码可以得到相关网站,这里我们可以用:

https://www.qqxiuzi.cn/bianma/wenbenjiami.php?s=yinyue
得到

bugku{2at746c5jfc6nh5klxs0c7bcvrzfv5nv}

题目九:二进制操作

d4e8e5a0f1f5e9e3eba0e2f2eff7eea0e6eff8a0eaf5edf0a0eff6e5f2a0f4e8e5a0ece1faf9a0e4efe7a1a0d4e8e5a0e6ece1e7a0e9f3baa0c2c4c3d4c6fbd9b0f5dfe1f2e5dff3ede1f2b7fd

要求:需要将每一组二进制数最高位的1去掉,也就是转换成十进制之后再减去128。
2的七次方为128,每组转换十进制数都减去128寓意二进制去掉了最高位的1。具体代码如下


a = 'd4e8e5a0f1f5e9e3eba0e2f2eff7eea0e6eff8a0eaf5edf0a0eff6e5f2a0f4e8e5a0ece1faf9a0e4efe7a1a0d4e8e5a0e6ece1e7a0e9f3baa0c2c4c3d4c6fbd9b0f5dfe1f2e5dff3ede1f2b7fd'
for i in range(0,len(a),2):
    print(chr(int(a[i:i+2],16)-128),end='')    #每组十进制数减去128

# The quick brown fox jump over the lazy dog! The flag is: BDCTF{Y0u_are_smar7}>>>

题目十:二进制转换成ASCII码

011001100110110001100001011001110111101101111010011010000100010101100011001110010011000000110011001101000110101001101111011001000111001101101010011001100110111101110011011010110110111101111101

a = '011001100110110001100001011001110111101101111010011010000100010101100011001110010011000000110011001101000110101001101111011001000111001101101010011001100110111101110011011010110110111101111101'
for i in range(0,len(a),8):
    print(chr(int(a[i:i+8],2)),end='')



a = '011001100110110001100001011001110111101101111010011010000100010101100011001110010011000000110011001101000110101001101111011001000111001101101010011001100110111101110011011010110110111101111101'
flag = ''
for i in range(0,len(a),8):
    flag = flag + (chr(int(a[i:i+8],2)))
print(flag)

结果

flag{zhEc9034jodsjfosko}

你可能感兴趣的:(算法,python)