Bugku密码学题目writeup

滴答~滴

1
-... -.- -.-. - ..-. -- .. ... -.-.

答案格式KEY{xxxxxxxxx}

摩斯电码
BKCTFMISC

聪明的小羊

一只小羊翻过了2个栅栏
KYsd3js2E{a2jda}

栅栏密码
KYsd3js2
E{a2jda}

ok

在以下网址中解密
https://www.splitbrain.org/services/ook

这不是摩斯密码

下载看看吧

1.txt的内容

1
2
3
4
5
6
7
+++++ +++++ [->++ +++++ +++<] >++.+ +++++ .<+++ [->-- -<]>- -.+++ +++.<
++++[ ->+++ +<]>+ +++.< +++[- >---< ]>--- .---- .<+++ ++++[ ->--- ----<
]>--- ----- ----- .<+++ ++++[ ->+++ ++++< ]>+++ ++.<+ +++++ +[->- -----
-<]>. <++++ ++++[ ->+++ +++++ <]>++ .<+++ [->-- -<]>- ----. <++++ +++[-
>---- ---<] >---- ----. +++++ +..++ +++.+ .<+++ [->-- -<]>- --.<+ +++++
+[->+ +++++ +<]>+ ++.++ +.+++ +++++ +.--- -.+++ ++.<+ ++[-> +++<] >++++
++.<

在以下网址中解密
https://www.splitbrain.org/services/ook

简单加密

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

凯撒,用python跑一下

1
2
3
4
5
6
7
8
9
10
11
12
13
str = "e6Z9i~]8R~U~QHE{RnY{QXg~QnQ{^XVlRXlp^XI5Q6Q6SKY8jUAA"
for a in range(127):
key = ""
for i in str:
temp = chr((ord(i)+a)%127)
if 32<ord(temp)<127:
key = key + temp
feel = 1
else:
feel = 0
break
if feel == 1:
print(key)

a2V5ezY4NzQzMDAwNjUwMTczMjMwZTRhNThlZTE1M2M2OGU4fQ==
base64解码得到flag

散乱的密文

lf5{ag024c483549d7fd@@1}
一张纸条上凌乱的写着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 }

按照顺序读下来f25dl03fa4d1g87}{c9@544@
栅栏解密得到flag{52048c453d794df1}@@,格式flag{},去掉@@

凯撒部长的奖励

凯撒密码,MSW=SYC,词频分析

一段base64

使用编码工具Converter,将文本内容复制进去
按照以下次序解码base64、Unescape、Hex to Text、Unescape(只要括号内的参数)、Dec to Text、Decode HTML。最后得到Unicode编码:

1
&#102;&#108;&#97;&#103;&#37;&#55;&#66;&#99;&#116;&#102;&#95;&#116;&#102;&#99;&#50;&#48;&#49;&#55;&#49;&#55;&#113;&#119;&#101;&#37;&#55;&#68;


最后url解码得到flag(手动解码*^▽^*:”%7B”=”{“,”%7D”=”}”)

.!?

1
2
3
4
5
6
7
8
9
..... ..... ..... ..... !?!!. ?.... ..... ..... ..... .?.?! .?... .!...
..... ..... !.?.. ..... !?!!. ?!!!! !!?.? !.?!! !!!.. ..... ..... .!.?.
..... ...!? !!.?. ..... ..?.? !.?.. ..... .!.?. ..... ..... !?!!. ?!!!!
!!!!! !?.?! .?!.? ..... ....! ?!!.? ..... ...?. ?!.?. ..... !.?.. .....
!?!!. ?!!!! !!?.? !.?!! !!!!! !!!!. ..... ...!. ?.... ...!? !!.?. .....
?.?!. ?..!. ?.... ..... !?!!. ?!!!! !!!!? .?!.? !!!!! !!!!! !!!.? .....
..!?! !.?.. ....? .?!.? ....! .!!!. !!!!! !!!!! !!!!! !!.?. ..... .!?!!
.?... ...?. ?!.?. ..... !.!!! !!!!! !.?.. ..... ..!?! !.?.. ..... .?.?!
.?... ..... !.?.

Ook短加密,解密地址https://www.splitbrain.org/services/ook

+[]-

1
2
3
4
5
6
+++++ +++++ [->++ +++++ +++<] >++.+ +++++ .<+++ [->-- -<]>- -.+++ +++.<
++++[ ->+++ +<]>+ +++.< +++++ [->-- ---<] >.<++ ++[-> ++++< ]>+++ .<+++
[->-- -<]>- ----. ++++. <+++[ ->+++ <]>+. <++++ [->-- --<]> ----- -.<++
+[->+ ++<]> ++.-. ----- ---.< +++[- >+++< ]>+++ .---- .<+++ [->-- -<]>-
.<+++ +++[- >---- --<]> ----- ----. +.<++ +++++ +[->+ +++++ ++<]> +++++
+++++ .<

在以下网址中解密
https://www.splitbrain.org/services/ook

突然天上一道雷电

gndk€rlqhmtkwwp}z
变异凯撒,gndk=flag

1
2
3
4
5
6
7
8
9
10
list = 'gndk€rlqhmtkwwp}z'
flag = ''
num = 1
for i in list:
a = ord(i)
a -= num
flag += chr(a)
num +=1

print(flag)

托马斯.杰斐逊

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
1: <ZWAXJGDLUBVIQHKYPNTCRMOSFE <
2: <KPBELNACZDTRXMJQOYHGVSFUWI <
3: <BDMAIZVRNSJUWFHTEQGYXPLOCK <
4: <RPLNDVHGFCUKTEBSXQYIZMJWAO <
5: <IHFRLABEUOTSGJVDKCPMNZQWXY <
6: <AMKGHIWPNYCJBFZDRUSLOQXVET <
7: <GWTHSPYBXIZULVKMRAFDCEONJQ <
8: <NOZUTWDCVRJLXKISEFAPMYGHBQ <
9: <QWATDSRFHENYVUBMCOIKZGJXPL <
10: <WABMCXPLTDSRJQZGOIKFHENYVU <
11: <XPLTDAOIKFZGHENYSRUBMCQWVJ <
12: <TDSWAYXPLVUBOIKZGJRFHENMCQ <
13: <BMCSRFHLTDENQWAOXPYVUIKZGJ <
14: <XPHKZGJTDSENYVUBMLAOIRFCQW <

密钥: 2,5,1,3,6,4,9,7,8,14,10,13,11,12
密文:HCBTSXWCRQGLES
flag格式 flag{你解密的内容}

看了下王心慰的博客了解了下思路
先根据秘钥所提供的行号重新排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
KPBELNACZDTRXMJQOYHGVSFUWI
IHFRLABEUOTSGJVDKCPMNZQWXY
ZWAXJGDLUBVIQHKYPNTCRMOSFE
BDMAIZVRNSJUWFHTEQGYXPLOCK
AMKGHIWPNYCJBFZDRUSLOQXVET
RPLNDVHGFCUKTEBSXQYIZMJWAO
QWATDSRFHENYVUBMCOIKZGJXPL
GWTHSPYBXIZULVKMRAFDCEONJQ
NOZUTWDCVRJLXKISEFAPMYGHBQ
XPHKZGJTDSENYVUBMLAOIRFCQW
WABMCXPLTDSRJQZGOIKFHENYVU
BMCSRFHLTDENQWAOXPYVUIKZGJ
XPLTDAOIKFZGHENYSRUBMCQWVJ
TDSWAYXPLVUBOIKZGJRFHENMCQ

然后将密文的字母移动到第一列

1
2
3
4
5
6
7
8
9
10
11
12
13
14
HGVSFUWIKPBELNACZDTRXMJQOY
CPMNZQWXYIHFRLABEUOTSGJVDK
BVIQHKYPNTCRMOSFEZWAXJGDLU
TEQGYXPLOCKBDMAIZVRNSJUWFH
SLOQXVETAMKGHIWPNYCJBFZDRU
XQYIZMJWAORPLNDVHGFCUKTEBS
WATDSRFHENYVUBMCOIKZGJXPLQ
CEONJQGWTHSPYBXIZULVKMRAFD
RJLXKISEFAPMYGHBQNOZUTWDCV
QWXPHKZGJTDSENYVUBMLAOIRFC
GOIKFHENYVUWABMCXPLTDSRJQZ
LTDENQWAOXPYVUIKZGJBMCSRFH
ENYSRUBMCQWVJXPLTDAOIKFZGH
SWAYXPLVUBOIKZGJRFHENMCQTD

用脚本将每一列遍历出来,并找到特殊的句子即为flag

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
a ="""HGVSFUWIKPBELNACZDTRXMJQOY
CPMNZQWXYIHFRLABEUOTSGJVDK
BVIQHKYPNTCRMOSFEZWAXJGDLU
TEQGYXPLOCKBDMAIZVRNSJUWFH
SLOQXVETAMKGHIWPNYCJBFZDRU
XQYIZMJWAORPLNDVHGFCUKTEBS
WATDSRFHENYVUBMCOIKZGJXPLQ
CEONJQGWTHSPYBXIZULVKMRAFD
RJLXKISEFAPMYGHBQNOZUTWDCV
QWXPHKZGJTDSENYVUBMLAOIRFC
GOIKFHENYVUWABMCXPLTDSRJQZ
LTDENQWAOXPYVUIKZGJBMCSRFH
ENYSRUBMCQWVJXPLTDAOIKFZGH
SWAYXPLVUBOIKZGJRFHENMCQTD"""
b="HCBTSXWCRQGLES"
a=a.splitlines()
for j in range(26):
for i in range(len(b)):
print(a[i][j],end=''),
print()

通解

这是2017 ISCC write up basic的Wheel Cipher,与Bugku这题类似

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
list1 = """因为key的关系,所以这一行换行很重要
ZWAXJGDLUBVIQHKYPNTCRMOSFE
KPBELNACZDTRXMJQOYHGVSFUWI
BDMAIZVRNSJUWFHTEQGYXPLOCK
RPLNDVHGFCUKTEBSXQYIZMJWAO
IHFRLABEUOTSGJVDKCPMNZQWXY
AMKGHIWPNYCJBFZDRUSLOQXVET
GWTHSPYBXIZULVKMRAFDCEONJQ
NOZUTWDCVRJLXKISEFAPMYGHBQ
XPLTDSRFHENYVUBMCQWAOIKZGJ
UDNAJFBOWTGVRSCZQKELMXYIHP
MNBVCXZQWERTPOIUYALSKDJFHG
LVNCMXZPQOWEIURYTASBKJDFHG
JZQAWSXCDERFVBGTYHNUMKILOP"""
key = [2 ,3 ,7 ,5 ,13 ,12 ,9 ,1 ,8 ,10 ,4 ,11 ,6]
crypto = 'NFQKSEVOQOFNP'

# 换行操作
list2 = []
list1 = list1.splitlines()
for i in key:
list2.append(list1[i])

# 将密文移动到第一列生成密码表
def Table():
table = []
for i in range(len(key)):
num = list2[i].find(crypto[i])
list = ''
for j in range(26):
if num >= 25:
num -= 26
list += list2[i][num]
num += 1
table.append(list)
return table

# 遍历
def Flag(table):
for j in range(26):
for i in range(len(key)):
print(table[i][j] ,end=''),
print()


if __name__ == '__main__':
table = Table()
Flag(table)

# FIREINTHEHOLE

zip伪加密

伪加密参考:https://blog.csdn.net/pdsu161530247/article/details/73612910
用winhex打开flag.zip,09改成00,保存即可。

告诉你个秘密(ISCCCTF)

1
2
636A56355279427363446C4A49454A7154534230526D6843
56445A31614342354E326C4B4946467A5769426961453067

HEX转ASCII

1
cjV5RyBscDlJIEJqTSB0RmhCVDZ1aCB5N2lKIFFzWiBiaE0g

base64解码

1
r5yG lp9I BjM tFhB T6uh y7iJ QsZ bhM

注意键盘上的位置,r5yG中间是t,以此类推答案就是tongyuan,
注意flag格式需要大写

这不是MD5

16进制转字符串

贝斯家族

贝斯==base,家族应该不是64,其他类型
试来试去,base91解码成功:Base91编码

富强民主

核心价值观编码

Python(N1CTF)

开局得到两个脚本,需要去逆解。

challenge.py
1
2
3
4
5
6
7
from N1ES import N1ES
import base64
key = "wxy191iss00000000000cute"
n1es = N1ES(key)
flag = "N1CTF{*****************************************}"
cipher = n1es.encrypt(flag)
print base64.b64encode(cipher) # HRlgC2ReHW1/WRk2DikfNBo1dl1XZBJrRR9qECMNOjNHDktBJSxcI1hZIz07YjVx
N1ES.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# -*- coding: utf-8 -*-
def round_add(a, b):
f = lambda x, y: x + y - 2 * (x & y)
res = ''
for i in range(len(a)):
res += chr(f(ord(a[i]), ord(b[i])))
return res

def permutate(table, block):
return list(map(lambda x: block[x], table))

def string_to_bits(data):
data = [ord(c) for c in data]
l = len(data) * 8
result = [0] * l
pos = 0
for ch in data:
for i in range(0,8):
result[(pos<<3)+i] = (ch>>i) & 1
pos += 1
return result

s_box = [54, 132, 138, 83, 16, 73, 187, 84, 146, 30, 95, 21, 148, 63, 65, 189, 188, 151, 72, 161, 116, 63, 161, 91, 37, 24, 126, 107, 87, 30, 117, 185, 98, 90, 0, 42, 140, 70, 86, 0, 42, 150, 54, 22, 144, 153, 36, 90, 149, 54, 156, 8, 59, 40, 110, 56,1, 84, 103, 22, 65, 17, 190, 41, 99, 151, 119, 124, 68, 17, 166, 125, 95, 65, 105, 133, 49, 19, 138, 29, 110, 7, 81, 134, 70, 87, 180, 78, 175, 108, 26, 121, 74, 29, 68, 162, 142, 177, 143, 86, 129, 101, 117, 41, 57, 34, 177, 103, 61, 135, 191, 74, 69, 147, 90, 49, 135, 124, 106, 19, 89, 38, 21, 41, 17, 155, 83, 38, 159, 179, 19, 157, 68, 105, 151, 166, 171, 122, 179, 114, 52, 183, 89, 107, 113, 65, 161, 141, 18, 121, 95, 4, 95, 101, 81, 156, 17, 190, 38, 84, 9, 171, 180, 59, 45, 15, 34, 89, 75, 164, 190, 140, 6, 41, 188, 77, 165, 105, 5, 107, 31, 183, 107, 141, 66, 63, 10, 9, 125, 50, 2, 153, 156, 162, 186, 76, 158, 153, 117, 9, 77, 156, 11, 145, 12, 169, 52, 57, 161, 7, 158, 110, 191, 43, 82, 186, 49, 102, 166, 31, 41, 5, 189, 27]

def generate(o):
k = permutate(s_box,o)
b = []
for i in range(0, len(k), 7):
b.append(k[i:i+7] + [1])
c = []
for i in range(32):
pos = 0
x = 0
for j in b[i]:
x += (j<<pos)
pos += 1
c.append((0x10001**x) % (0x7f))
return c



class N1ES:
def __init__(self, key):
if (len(key) != 24 or isinstance(key, bytes) == False ):
raise Exception("key must be 24 bytes long")
self.key = key
self.gen_subkey()

def gen_subkey(self):
o = string_to_bits(self.key)
k = []
for i in range(8):
o = generate(o)
k.extend(o)
o = string_to_bits([chr(c) for c in o[0:24]])
self.Kn = []
for i in range(32):
self.Kn.append(map(chr, k[i * 8: i * 8 + 8]))
return

def encrypt(self, plaintext):
if (len(plaintext) % 16 != 0 or isinstance(plaintext, bytes) == False):
raise Exception("plaintext must be a multiple of 16 in length")
res = ''
for i in range(len(plaintext) / 16):
block = plaintext[i * 16:(i + 1) * 16]
L = block[:8]
R = block[8:]
for round_cnt in range(32):
L, R = R, (round_add(L, self.Kn[round_cnt]))
L, R = R, L
res += L + R
return res

加密过程和round_add都是可逆的,直接在源码文件中加入解密用代码如下:

N1ES.pysixstars's writeup
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
def re_round_add(a, b):
f = lambda x, y: x + y - 2 * (x & y)
res = ''
for i in range(len(a)):
t1=ord(a[i])
t2=ord(b[i])
t3=-1
for j in range(256):
if f(t1,j)==t2:
t3=j
break
assert t3>=0
res += chr(t3)
return res
...
class N1ES:
...
def decrypt(self, plaintext):
if (len(plaintext) % 16 != 0 or isinstance(plaintext, bytes) == False):
raise Exception("plaintext must be a multiple of 16 in length")
res = ''
for i in range(len(plaintext) / 16):
block = plaintext[i * 16:(i + 1) * 16]
L = block[:8]
R = block[8:]
L, R = R, L
for round_cnt in range(32)[::-1]:
L, R = (re_round_add(R, self.Kn[round_cnt])), L
res += L + R
return res

然后修改challenge.py运行直接得到flag

challenge.pysixstars's writeup
1
2
3
4
5
6
7
8
9
10
11
12
from N1ES import N1ES
import base64
key = "wxy191iss00000000000cute"
n1es = N1ES(key)
flag = "N1CTF{*****************************************}"
cipher = n1es.encrypt(flag)
print base64.b64encode(cipher) # HRlgC2ReHW1/WRk2DikfNBo1dl1XZBJrRR9qECMNOjNHDktBJSxcI1hZIz07YjVx

t='HRlgC2ReHW1/WRk2DikfNBo1dl1XZBJrRR9qECMNOjNHDktBJSxcI1hZIz07YjVx'
t=base64.b64decode(t)
s = n1es.decrypt(t)
print s

非预期解

N1ES.py郁离歌的writeup
1
2
3
4
5
6
7
8
9
10
11
12
from N1ES import N1ES
import base64
key = "wxy191iss00000000000cute"
n1es = N1ES(key)
flag = "N1CTF{*****************************************}"
t='HRlgC2ReHW1/WRk2DikfNBo1dl1XZBJrRR9qECMNOjNHDktBJSxcI1hZIz07YjVx'
t=base64.b64decode(t)
s = n1es.encrypt(t)
print s
for i in range(0,100):
s = n1es.encrypt(s)
print s

来自宇宙的信号

银河战队出击
flag格式 flag{字母小写}

对照密码表得到flag,参考百度百科:标准银河字母

easy_crypto

一看0和1以为是进制转换,但仔细观察发现长度不对,感觉更像是摩斯电码,于是用代码替换下

1
2
3
4
5
6
7
8
a='0010 0100 01 110 1111011 11 11111 010 000 0 001101 1010 111 100 0 001101 01111 000 001101 00 10 1 0 010 0 000 1 01111 10 11110 101011 1111101'
b=a.replace('0','-')
b=b.replace('1','.')
print(b)

c=a.replace('0','.')
c=c.replace('1','-')
print(c)

其中一种解码后得到flag

进制转换

一堆不同进制的数值,猜测是转成16进制再转成字符串

Payload
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import binascii

a='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'

list1 = []
a=a.split(" ")

b = []
for i in a:
if i[0] == 'd':
b.append(hex(int(i[1:])))
elif i[0] == 'x':
b.append('0'+i)
elif i[0] == 'o':
b.append(hex(int(i[1:],8)))
elif i[0] == 'b':
b.append(hex(int(i[1:],2)))

c = ''
for j in b:
c += j[2:]

print(binascii.a2b_hex(c).decode('utf-8'))

affine

放射函数,在实验吧做过类似题目

1
2
3
4
5
6
7
8
9
10
11
12
13
list = 'abcdefghijklmnopqrstuvwxyz'
newlist = ''

for i in range(len(list)):
newlist += list[(17 * i - 8) % 26]


y = 'szzyfimhyzd'
x = ''
for j in y:
x += list[newlist.find(j)] #查找新列表字符对应的位置,在旧列表同样的位置即为flag

print('flag{' + x + '}')

Crack it

使用kali下的John the Ripper工具破解密码

Payload
1
2
3
4
5
6
7
8
9
10
11
root@kali:~/Desktop# john --wordlist=/usr/share/john/password.lst shadow 
Warning: detected hash type "sha512crypt", but the string is also recognized as "crypt"
Use the "--format=crypt" option to force loading these as that type instead
Using default input encoding: UTF-8
Loaded 1 password hash (sha512crypt, crypt(3) $6$ [SHA512 128/128 AVX 2x])
Press 'q' or Ctrl-C to abort, almost any other key for status
hellokitty (root)
1g 0:00:00:02 DONE (2019-02-27 08:07) 0.4115g/s 869.1p/s 869.1c/s 869.1C/s ilovegod..celtic
Use the "--show" option to display all of the cracked passwords reliably
Session completed
root@kali:~/Desktop#

rsa

一看n、e、enc那么长,估计是Wiener’s Attack
使用rsa-wiener-attack脚本破解,这里需要修改下主函数↓

Payload
1
2
3
4
5
6
7
8
9
10
11
12
if __name__ == "__main__":
#test_is_perfect_square()
#print("-------------------------")
# test_hack_RSA()
N = 460657813884289609896372056585544172485318117026246263899744329237492701820627219556007788200590119136173895989001382151536006853823326382892363143604314518686388786002989248800814861248595075326277099645338694977097459168530898776007293695728101976069423971696524237755227187061418202849911479124793990722597
e = 354611102441307572056572181827925899198345350228753730931089393275463916544456626894245415096107834465778409532373187125318554614722599301791528916212839368121066035541008808261534500586023652767712271625785204280964688004680328300124849680477105302519377370092578107827116821391826210972320377614967547827619
d = hack_RSA(e,N) #解除私钥d
print(d)
enc = 38230991316229399651823567590692301060044620412191737764632384680546256228451518238842965221394711848337832459443844446889468362154188214840736744657885858943810177675871991111466653158257191139605699916347308294995664530280816850482740530602254559123759121106338359220242637775919026933563326069449424391192
m = hex(pow(enc, d, N)).rstrip("L") #解出二进制明文
# print(m)
print(str(binascii.unhexlify(m[2:]), encoding='utf-8')) #转码成明文,需要导入binascii库