buuoj古典密码学wp

此博客用于整理,之前做过的古典密码学题目

之前存储于本地,今天移植到博客中,后续不再在此页面更新

分级十分的混乱,之后有缘再改吧(逃

古典密码学

Linux python 很重要

Bugku

实验吧(现在没了)

南邮网络攻防训练平台(现在也没了)

密码学的三个阶段

  1. 古典密码(1949以前),复杂度不高,安全性地,具有艺术性

  2. 近代密码(1949-1975),计算机诞生,加密算法在复杂程度和安全性上得到了提升

  3. 现代密码(1976至今),美国密码学专家DiffieHellman在1976年提出公开密钥密码体制概念(非对称制加密),密码学有了全新的方向

古典密码学:

  1. 涉及数学问题较少
  2. 很容易被破解,但是设计原理和分析方法对理解设计分析现代密码有帮助
  3. 主要分为:替代和置换
  4. 强化python脚本编写能力,尽力讲大多数加密方法都能写出破解脚本
  5. MD5暴力破解以及算法逆向

键盘加密

键盘布局加密

通常给出一堆无意义的字符,但是在键盘上比划一下就能拼出相应的字符

可以划归脑洞题的范围

键盘坐标加密

bye 对应的密文是 35 16 13(或者相反)

字母行总共三行,数字行总共10行(在一些脑洞题中不一定)

如果小写不对,可能是大写的

BF和Ook密码

不需要探究原理,只需要能够识别出它

BrainFuck密码

用<>+-.,[]八种符号来替换c语言的各种语法和命令

Ook密码

三种符号组成 Ook. Ook? Ook!(or short Ook,由.?!组成)

解密

使用PHP工具[Ook-masker][http://106.13.121.19/ook/]进行解密

替换密码

替换表保存明文和密文之间的关系

隐藏明文但是不打乱顺序

摩斯密码

认出(有时表现为包括但不限于01序列的密码,可以使用记事本进行转化)

可以用Bugku的[在线工具][tool.bugku.com/mosi/]进行解密

或者本地工具CTFCrackTools

摩斯密码解密代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
txt = input().strip().split
#用空格分开
key = { '01': 'A','1000': 'B','1010': 'C','100':'D',
'0':'E','0010':'F','110': 'G','0000': 'H','00': 'I',
'0111':'J','101': 'K','0100': 'L','11': 'M','10': 'N',
'111': 'O','0110': 'P','1101': 'Q','010': 'R','000': 'S',
'1': 'T','001': 'U','0001': 'V','011': 'W','1001': 'X',
'1011': 'Y','1100': 'Z','01111': '1','00111': '2',
'00011': '3','00001': '4','00000': '5','10000': '6',
'11000': '7','11100': '8','11110': '9','11111': '0',
'001100':'?','10010':'/','101101':'()','100001':'-',
'010101':'.','110011':',','011010':'@','111000':':',
'101010':':','10001':'=','011110':"'",'101011':'!',
'001101':'!','001101':'_','010010':'"','10110':'(',
'1111011':'{','111101':'}'}
for i in txt:
print(key.get(i),end=' ')

#txt =
#table = ''.maketrans('.-','01')
#txt.translate(table)
凯撒密码

只有25种可能的密钥(大小写不变),当年凯撒用的密钥是3

解码:CTFCrackTools或者自行编写脚本

加密:(x+k)%26 解密:(y-k)%26 (025来表示az)

凯撒密码解密代码
1
2
3
4
5
6
7
8
9
10
11
txt = input()
for i in range(1,26):
plain = ''
for j in txt:
if j.islower():
plain = plain + chr(97+(ord(j)-i-97)%26)
elif j.isupper():
plain = plain + chr(65+(ord(j)-i-65)%26)
else:
plain = plain + j
print(plain)
plus版本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
txt = input('请输入密文: ').strip()
n = input('是否需要推荐明文(Y/N)').strip()
for i in range(1,26):
plain = ''
for j in txt:
if j.islower():
plain = plain + chr(97+(ord(j)-i-97)%26)
elif j.isupper():
plain = plain + chr(65+(ord(j)-i-65)%26)
else:
plain = plain + j
if n.lower() == 'y':
key = ('flag','ctf','key','the','is','no','for')
for m in key:
if m in plain:
print('recomanding: '+plain)
print()
break
elif n.lower() == 'n':
print(plain)
paint()
凯撒密码的另外一种思路

充分利用替换的方法

1
2
3
4
5
6
7
8
9
10
11
12
txt = input().strip()
lower = 'abcdefghigklmnopqrstuvwxyz'
upper = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
for i in range( 1 , 26 ):
xiao = lower[i:]+lower[:i]
da = upper[i:]+upper[:i]
plain = ''
table = ''.maketrans(xiao+da,lower+upper)
for j in txt:
plain = plain + j.translate(table)
print(plain)
print()
一个很腻害的python库

pycipher 包含大多数密码学工具

1
pycipher.Caesar(3).decipher('LORYHSBWKRQ')
ROT13密码

凯撒密码的一种变体,移位数固定为13,即把明文中的每一个字母在字母表中向后移动13位,数字和非字母字符保持不变

实现的是26个字母前半段和后半段相互交换(又叫回旋13,因为明文和密文可以相互转化)

ROT13加密解密

PHP中的str_rot13()函数可以实现

1
2
3
4
<?
echo str_rot13('B');
echo str_rot13('O');
?>
1
~# php -r "echo str_rot13('heetian');"
凯撒密码的改进

移位密码是在凯撒密码的基础上发展而来的,常用ASCLL码表进行移位

1
2
3
4
#移位ASCLL凯撒
for i in txt:
flag = flag + chr(ord(i)+key)
key = key + 1

末尾两个重复字符:可能是先base64后的凯撒加密,重复字符是==

1
2
3
4
#base64解码
import base64
flag = ''
base64.b64decode(flag.encode())
凯撒密码的再次改进

凯撒密码密钥只有25种,后来出现了单字母替换密码,即一一映射

密码空间的大小是 26!,大约4e26种密钥

词频分析法

按照频率知道每个字母平均频率

对于单表替换密码的破解,标志着密码分析学的诞生

CTF题中,对于一串特别长的密文,可能通过词频分析的方法进行解题

解码

在线解码

本地工具:WinDecrypto(专门进行词频分析的软件)

培根密码

密文只有a和b,每个明文由五个a和b组成长度为5的字符串

bugku在线解码

常规密码表只有24个:i,j 、 u,v 对应的加密后的字符串相同

培根密码最大的特点是隐蔽性比较强,例如大小写,加粗字体

功能强大的培根密码解密网站(不知道为什么用不了)

1
2
3
4
5
6
7
#提取大小写
flag = ''
for i in a:
if i.isupper():
flag = flag +'A'
elif i.islower():
flag = flag +'B'
1
2
3
#互换AB
table = ''.maketrans('AB','BA')
flag.translate(table)
解码代码
1
2
3
4
5
6
7
8
9
#第一类培根密码
txt = input().lower()
a = ["aaaaa","aaaab","aaaba","aaabb","aabaa","aabab","aaabba","aaabbb","abaaa","abaab","ababa","ababb","abbaa","abbab","abbba","abbbbb","baaaa","baaab","baaba","baabb","babaa","babab","babba","babbb","bbaaa","bbaab"]
b = 'abcdefghijklmnopqrstuvwxyz'
#[chr(i) for i in range(ord('a'),ord('z')+1)]
key = dict(zip(a,b))

for i in range(0,len(txt),5):
print(key.get(txt[i:i+5]))
1
2
3
4
5
6
7
8
9
#第二类培根密码
txt = input().lower()
a = ["aaaaa","aaaab","aaaba","aaabb","aabaa","aabab","aaabba","aaabbb","abaaa","abaab","ababa","ababb","abbaa","abbab","abbba","abbbbb","baaaa","baaab","baaba","baabb","babaa","babab","babba","babbb"]
b = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', '(ij)', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', '(uv)', 'w', 'x', 'y', 'z']
dirt = {i:j for i,j in zip(cipher,plain)}
flag = ''
for i in range(0,len(txt),5):
flag = flag + dirt.get(a[i:i+5])
print(flag)
仿射加密Affine
  1. 将26个英文字母用0~25表示

  2. 需要两个密钥,a和b,取值范围是[0,25]

    要求a和26互质,即a的因数不包括2或13

  3. x为明文,y为密文

    加密公式 = (ax+b) mod 26

解码:使用乘法逆元

假设用m表示a的乘法逆元,那么(a*m)mod 26 = 1

可以写一个简单的枚举代码来求m

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#枚举乘法逆元
m = 1
while True:
if a*m%26 == 1:
print(m)
break
m = m + 1
#逆向计算
mi = input()
for i in mi:
print(chr(97+(ord(i)-97-b)*a%26),end='')
#暴力破解
for i in mi:
for j in range(0,26):
if(a*j+7)%26 == ord(i)-97:
print(chr(97+j),end='')

1
2
3
4
5
#利用pycipher库中的Affine类可以直接对仿射加密进行加解密
#加密
pycipher.Affine(a,b).decipher('flag')
#解密
pycipher.Affine(a,b).encipher('queue')

猪圈密码

更多的是对应加密

可以使用CTFCrackTools进行解密

单表替换的简单总结

  1. 明文和密文一一对应
  2. 空间足够小则采用暴力破解;密文足够长则使用词频分析法
  3. 密钥空间足够大,密文长度足够短的情况下,破解较为困难

多表替换

利用密钥的每一位分别加密每一位明文

维基利亚密码
1
2
3
4
5
6
7
8
9
10
txt = input()
password = input().lower()
key = [ord(i)-97 for i in password]*5
flag = ''
for i in range(len(txt)):
if txt[i].islower():
flag = flag + chr(97+ord(txt[i])-97-key[i]%26)
elif txt[i].isupper():
flag = flag + chr(65+ord(txt[i])-65-key[i]%26)
print(flag)
1
2
3
4
5
6
7
8
9
10
11
#更优雅的写法
txt = input()
password = input().lower()
key = [ord(i)-97 for i in password]
flag = ''
for i in range(len(txt)):
if txt[i].islower():
flag = flag + chr(97+ord((txt[i])-97-key[i%len(key)])%26)
elif txt[i].isupper():
flag = flag + chr(65+ord((txt[i])-65-key[i%len(key)])%26)
print(flag)

利用pycipher库进行解码

1
2
pycipher.Vigenere('密钥').encipher('密码')
pycipher.Vigenere('密钥').dncipher('明码')
费纳姆密码(二战中曾使用过)

明文^密钥=密文

密文^密钥=明文

解密时将密文七位一组,然后与密钥异或,再将结果转化为ASCLL即可(也可以直接一串二进制数)

1
2
3
4
5
#把一串二进制数划分为七位一组
txt = input()
mi = []
for i in range(0,len(txt),7):
mi.append(txt[i:i+7])
1
2
for m,n in zip(mi,key):
print(chr(int(m,2)^ord(n)),end='')
杰斐逊转轮加密(tagged)

36片同样大小的木质转轮,套在一根铁杆上,每个轮子有乱序26英文字母

1
2
for m,n in zip(mi,key):
flag.append(txt[m-1][txt[m-1].index(n):] + txt[m-1][:txt[m-1].index(n)])

置换密码

明文不变,打乱排列顺序

栅栏密码

总共n个字符,分为m(n的因数)组,依次取出各组的第一、二······个字母

加密解密方法是可逆的,要求是两个因数之积为n

在线解密:bugku在线工具

本地解密:CTFCrackTools

1
2
3
4
5
6
#寻找因数
txt = input()
key = []
for i in rnage(2,len(txt)):
if len(txt) % i == 0:
key.append(i)
1
2
3
4
#解密代码
for m in range(0,key):
for n in range(m,len(txt),key):
print(txt[n],end='')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
def zhalan(txt,key):
for m in range(key):
for n in range(m,len(txt),key):
s = s + txt[n]
return s
if __name__ == '__main__':
txt = input().strip()
key = []
for i in range(2,len(txt)):
if len(txt)%i == 0:
key.append(i)
for j in key:
flag = zhalan(txt,j)
print(f'{j}栏:{flag}')
1
2
pychipher.Railfence(m).encipher('')
pychipher.Railfence(m).dncipher('')
1
2
#翻转字符串
s = txt[::-1]

有可能出现题型,需要填充一定量的无关符号

列置换

将明文填写在一个矩阵中,然后以预订的顺序按列读取得到密文

列置换的密钥通常会以一个单词的形式给出

如: nice 相当于4312

按照每个字符在字母表中的前后排列来排列

矩阵列数由密钥决定,列数=密钥长度

1
2
3
#常规加密方法(不具备普遍性)
pycipher.ColTrans('key').encipher('').lower()
pycipher.ColTrans('key').decipher('').lower()
Polybius(波利比奥斯)密码

又称棋盘密码

把棋盘上的字符,对应到密码表上的坐标

很简单也很灵活,用法可能比较混乱

ADFGX密码

波利比奥斯密码的升级版

用ADFGX五个字母代替了12345五个数字

1
2
3
4
5
pycipher.ADFGX('密码表','密钥').encipher('明文')
pycipher.ADFGX('密码表','密钥').decipher('密文')
#python默认自存密码表
#help(pycipher.ADFGX)
pycipher.ADFGX('密码表',' ').decipher('密文')#不做列置换

ADFGVX密码:六个字母表示6*6=36个字符


BUU密码学刷题WP

一眼就解密

1
base64.b64decode("ZmxhZ3tUSEVfRkxBR19PRl9USElTX1NUUklOR30=")

flag{THE_FLAG_OF_THIS_STRING}

MD5

https://www.somd5.com/

flag{admin1}

Url编码

https://tool.ip138.com/urlencode/

flag{and 1=1}

看我回旋踢

flag{5cd1004d-86a5-46d8-b720-beb5ba0417e1}

摩丝

flag{ILOVEYOU}

password

根据字符数猜测:密码=姓名+出生年月日

flag{zs19900315}

变异凯撒

移位凯撒

1
2
3
4
5
6
7
txt = "afZ_r9VYfScOeO_UL^RWUc".strip()
plain = ''
cnt = 4
for i in txt:
cnt = cnt + 1
plain = plain + chr(ord(i)+cnt)
print(plain)

flag{Caesar_variation}

Quoted-printable

Quoted-printable可译为“可打印字符引用编码”,编码常用在电子邮件中

考虑用python的quopri库进行解密

1
quopri.decodestring('=E9=82=A3=E4=BD=A0=E4=B9=9F=E5=BE=88=E6=A3=92=E5=93=A6')

得到一串UTF-8密文

'\xe9\x82\xa3\xe4\xbd\xa0\xe4\xb9\x9f\xe5\xbe\x88\xe6\xa3\x92\xe5\x93\xa6'

1
2
3
4
5
s = '\xe9\x82\xa3\xe4\xbd\xa0\xe4\xb9\x9f\xe5\xbe\x88\xe6\xa3\x92\xe5\x93\xa6'
ss = s.encode('raw_unicode_escape')#此str转化为bytes
print(ss)
sss = ss.decode()
print(sss)

flag{那你也很棒哦}

Rabbit

Rabbit加密

AES、DES、RC4、Rabbit、Triple DES(3DES)这些算法都可以引入密钥

密文特征与Base64类似,明显区别是秘文里+比较多,并且经常出现/

http://www.jsons.cn/rabbitencrypt/

flag{Cute_Rabbit}

篱笆墙的影子

栅栏密码,CTFCrackTool即可解码(python内置函数不好用)

flag{wethinkwehavetheflag}

丢失的MD5

把报错的代码改对

  1. print语法错误
  2. TypeError: can't concat str to bytes,字符类型错误;哈希之前必须对Unicode对象进行编码,应当在"update"函数之中所有的所有参数进行可选参数编码,默认编码为'utf-8'

flag{e9032994dabac08080091151380478a2}

Alice与Bob

使用在线工具分解质数

https://zh.numberempire.com/numberfactorizer.php

进行MD5加密

https://md5jiami.bmcx.com/

flag{d450209323a847c8d01c6be47c81811a}

大帝的密码武器

偏移量是13

记得改对大小写

flag{PbzrPuvan}

Windows系统密码

使用在线工具,解码第二行第三组数据(为什么这个数据?因为第二行在admin下面,而前面那个数字解不出来)

flag{good-luck}

信息化时代的步伐

中文电码(misc题)

http://code.mcdvisa.com/

flag{计算机要从娃娃抓起}

凯撒?替换?呵呵!

试一试凯撒密码,发现不对

猜测是替换密码,选择传统的字典爆破思路

去掉空格,改成小写即可

萌萌哒的八戒

猪圈密码http://mmoersima.00cha.net/zhuquan.asp

flag{whenthepigwanttoeat}

传统知识+古典密码

根据所给条件一一映射,再都加60,转成ASCLL码

之后是栅栏+凯撒,胡乱操作一番就可以找到一个像flag一样的东西

flag{SHUANGYU}

权限获得第一步

上面有原题,一模一样

flag{3617656}

世上无难事

词频分析即可得到flag,记得改小写

flag{640e11012805f211b0ab24ff02a1ed09}

old-fashion

如上题,需要将模式改为Genetic,trust spaces

flag{n1_2hen-d3_hu1-mi-ma_a}

Unencode

在线解码网站http://www.hiencode.com/uu.html

类似于base64,只是后来被取代了

flag{dsdasdsa99877LLLKK}

[AFCTF2018]Morse

使用工具进行解码

观察得到这一串最大是F,猜测是base16

flag{1s't_s0_345y}

还原大师

总共三个未知量,26^3个可能性,穷举所有可能即可

md5加密:y = hashlib.md5(x.encode('utf-8')).hexdigest().upper()

1
2
3
4
5
6
7
8
9
10
11
12
13
import hashlib

m = 'TASC?O3RJMV?WDJKX?ZM'

for i in range(26):
t1 = m.replace('?',str(chr(65+i)),1)
for j in range(26):
t2 = t1.replace('?',str(chr(65+j)),1)
for k in range(26):
t3 = t2.replace('?',str(chr(65+k)),1)
s = hashlib.md5(t3.encode('utf-8')).hexdigest().upper()
if s[:4] == 'E903':
print(s)

flag{E9032994DABAC08080091151380478A2}

异性相吸

1
2
3
4
5
6
7
8
9
10
key = open("key.txt", 'rb').read()
cipher = open("密文.txt", "rb").read()

flag = []
result = ""
for i in range(len(key)):
flag.append(key[i] ^ cipher[i])
result += chr(flag[i])
print(flag)
print(result)

flag{ea1bc0988992276b7f95b54a7435e89e}

[GXYCTF2019]CheckIn

ROT5、ROT13、ROT18、ROT47 编码是一种简单的码元位置顺序替换暗码;此类编码具有可逆性,可以自我解密,主要用于应对快速浏览,或者是机器的读取,而不让其理解其意。

rot5只用于数字的替换,将当前数字往后移5位,范围是0~9

明文: 123456 密文: 678901

rot13只能用于字母的替换,将当前字母往后移13个位置(不改变字母大小写),范围为a-z或者A-Z

明文:abcdefghijklmnopqrstuvwxyz 密文:nopqrstuvwxyzabcdefghijklm 明文:ABCDEFGHIJKLMNOPQRSTUVWXYZ 密文:NOPQRSTUVWXYZABCDEFGHIJKLM

rot18就是13+5的合成,加密方法是rot5+rot13,对数字进行rot5加密,对字母进行rot13加密

明文:123456abcdefgHIJKLMN 密文:678901nopqrstUVWXYZA

rot47将每位数字/字母的ASCII值往移动47位,比如"Z"对应的ASCII值是90,则90-47=43,对应是"+"

明文:ilo1ey0u 密文::=@`6J_F 范围是可打印的字符,ASCII值为32-126

ROT47在线解码工具https://www.jisuan.mobi/YYA.html

flag{Y0u_kNow_much_about_Rot}

Cipher

playfair密码,需要 j -> i

在线解密网站

https://rumkin.com/tools/cipher/playfair/

http://www.hiencode.com/playfair.html

image-20231101090456313

flag{itisnotaproblemhavefun}

2024.1.8 星期一

[BUUCTF]yxx


给了两个文件,用二进制打开

粘下来进行二进制异或即可得到flag

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
cipher = "" ; plain = "" ; flag = ""
t = "0A 03 17 02 56 01 15 11 0A 14 0E 0A 1E 30 0E 0A 1E 30 0E 0A 1E 30 14 0C 19 0D 1F 10 0E 06 03 18".split()
for i in t:
cipher = cipher + str(bin(int( i , 16 )))[2::].zfill(8)
t = "6C 6F 76 65 6C 6F 76 65 6C 6F 76 65 6C 6F 76 65 6C 6F 76 65 6C 6F 76 65 6C 6F 76 65 6C 6F 76 65".split()
for i in t:
plain = plain + str(bin(int( i , 16 )))[2::].zfill(8)
for i in range(len( cipher )):
if cipher[i] == plain[i]:
flag = flag + "0"
else:
flag = flag + "1"
print( flag )
for i in range( 0 , len(flag) , 8 ):
t = ""
for j in range( i , i + 8 ):
t = t + str( flag[j] )
print( hex( int(t,2) )[2::] , end="" )

flag:flag{xor_xor_xor_biubiubiu}

2024.1.9 星期二

[CTFshow元旦水友赛]麻辣兔头又一锅

1
2
3
听说有人不喜欢短尾巴的兔兔?肿么可能?我也很疑惑呢。
126292,165298,124522,116716,23623,21538,72802,90966,193480,77695,98618,127096,15893,65821,58966,163254,179952,134870,45821,21712,68316,87720,156070,16323,86266,148522,93678,110618,110445,136381,92706,129732,22416,177638,110110,4324,180608,3820,67750,134150,23116,116772,50573,149156,5292
60144,146332,165671,109800,176885,65766,76908,147004,135068,182821,123107,77538,86482,88096,101725,16475,158935,123018,42322,144694,186769,176935,59296,134856,65813,131931,144283,95814,102191,185706,55744,67711,149076,108054,135112,100344,35434,121479,14506,145222,183989,17548,38904,27832,105943

“兔子”并不一定是栅栏密码,还有可能是斐波那契数列

1
2
3
4
5
import gmpy2 
a = "126292,165298,124522,116716,23623,21538,72802,90966,193480,77695,98618,127096,15893,65821,58966,163254,179952,134870,45821,21712,68316,87720,156070,16323,86266,148522,93678,110618,110445,136381,92706,129732,22416,177638,110110,4324,180608,3820,67750,134150,23116,116772,50573,149156,5292".split(",")
b = "60144,146332,165671,109800,176885,65766,76908,147004,135068,182821,123107,77538,86482,88096,101725,16475,158935,123018,42322,144694,186769,176935,59296,134856,65813,131931,144283,95814,102191,185706,55744,67711,149076,108054,135112,100344,35434,121479,14506,145222,183989,17548,38904,27832,105943".split(",")
for i in range( len( a ) ):
print(chr((gmpy2.fib(eval(a[i]))^gmpy2.fib(eval(b[i])))&0xff),end='' )

我们需要计算出两行的斐波那契数然后异或,使用python的gmpy2.fib即可计算斐波那契数列的任意位

flag:ctfshow{6d83b2f1-1241-4b25-9c1c-0a4c218f6c5f}

问题:这道题是如何构造的

全体正整数n和fib(n)构成单射,而非一一映射,出题人是如何构造的,是否可以根据指定的flag来构造密文

猜想:由于最终对Oxff进行与运算,故只需要考虑16进制下的最后两位;总共有255,如果是直接进行与运算,最劣情况下进行不超过65536次运算即可得到一个字母对应的斐波那契数;其序数可以进行暴力运算进行逆推;或者构造一组“最小剩余系”来表示所有需要的数,容量为256,进行组合即可

反驳:对于所有的已知数据,没有一个是重复的

回答:可以不是随机,每256个数就存在一个数符合预期要求;也不需要有重复的数字,python对于斐波那契数列的算力很强;故由一个flag,可以随机出一个a序列,然后暴力计算出b序列

2024.1.10 星期三

[BUUCTF·网鼎杯2020青龙组]boom

获得到一个exe文件

1
first:this string md5:46e5efe6165a5afb361217446a2dbd01

1
2
3
4
5
This time:Here are have some formulas
3x-y+z=185
2x+3y-z=321
x+y+z=173
input: x =

1
2
3
Last time: Kill it
x*x+x-7943722218936282=0
input x:

使用cmd打开

使用https://www.somd5.com/解密得到en5oy

可以使用高斯消元法https://www.luogu.com.cn/problem/P3389

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
//2021-11-13
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cmath>

using namespace std;

const int N = 105;
double a[N][N];
int n;

int main(){
scanf("%d", &n);
for(int i = 1; i <= n; i ++)
for(int j = 1; j <= n + 1; j ++)
scanf("%lf", &a[i][j]);
for(int i = 1; i <= n; i ++){
int maxx = i;
for(int j = i + 1; j <= n; j ++)
if( fabs(a[j][i]) > fabs(a[maxx][i] ) )
maxx = j;
for(int j = 1; j <= n + 1; j ++)
swap( a[i][j], a[maxx][j] );
if( !a[i][i] ){
cout << "No Solution" << endl;
return 0;
}
for(int j = 1; j <= n; j ++)
if(j != i){
double temp = a[j][i] / a[i][i];
for( int k = i + 1; k <= n + 1; ++k)
a[j][k] -= a[i][k] * temp;
}
}
for(int i = 1; i <= n; i ++)
printf("%.2lf\n", a[i][n + 1] / a[i][i]);
return 0;
}
/*
3
3 -1 1 185
2 3 -1 321
1 1 1 173
*/

也可以使用python自带库

1
2
3
4
5
from sympy import*
from sympy.abc import x,y,z

ans = solve([3*x-y+z-185,2*x+3*y-z-321,x+y+z-173],[x,y,z])
print( ans )

解得:x = 74, y = 68, z = 31

一元二次方程,可以用同样的方式去解

1
2
3
4
5
from sympy import*
from sympy.abc import x

ans = solve([x*x+x-7943722218936282],[x])
print( ans )

解得:x1 = 89127561 , x2 = -89127562

flag:flag{en5oy_746831_89127561}

isctf2023夹里夹气

观察发现是摩斯密码,将ISCTF摩斯密码加密得到.-串,发现原字符串,两个一组是.,三个一组是-

自行增加?并替换,进行莫斯解密即可

1
print( s.replace("嘤嘤嘤","-").replace("嘤嘤?",".") )

ISCTF{HSBDH_SFJ_JDNFJ_DJNFJDM}

2024.1.19 星期五

[BUUCTF·ACTF新生赛2020]crypto-classic0

有点像misc,是一个文件


提示密码是生日,直接八位数字爆破,得到19990306

直接解密即可

1
2
3
4
5
6
txt = "Ygvdmq[lYate[elghqvakl}"
flag = ""

for i in txt:
flag = flag + str(chr( (ord(i) ^ 0x7) + 3) )
print( flag )

flag:flag{my_naive_encrytion}

2024.1.20 星期六

[BUUCTF·WUSTCTF2020]B@se

1
2
3
4
密文:MyLkTaP3FaA7KOWjTmKkVjWjVzKjdeNvTnAjoH9iZOIvTeHbvD==
JASGBWcQPRXEFLbCDIlmnHUVKTYZdMovwipatNOefghq56rs****kxyz012789+/

oh holy shit, something is missing...

查找缺失的密码表

1
2
3
4
5
6
7
import string
table = "JASGBWcQPRXEFLbCDIlmnHUVKTYZdMovwipatNOefghq56rs****kxyz012789+/"
cipher = "MyLkTaP3FaA7KOWjTmKkVjWjVzKjdeNvTnAjoH9iZOIvTeHbvD=="

for i in string.ascii_letters+string.digits:
if i not in table:
print( i , end = " " )

j u 3 4

1
2
3
4
5
6
7
8
9
10
11
from itertools import *
from binascii import *
table = "JASGBWcQPRXEFLbCDIlmnHUVKTYZdMovwipatNOefghq56rs****kxyz012789+/"
cipher = "MyLkTaP3FaA7KOWjTmKkVjWjVzKjdeNvTnAjoH9iZOIvTeHbvD"
s = ['j','u','3','4']
for i in permutations( s , 4 ):
t = "JASGBWcQPRXEFLbCDIlmnHUVKTYZdMovwipatNOefghq56rs"+"".join(i)+"kxyz012789+/"
bins = ""
for j in cipher:
bins+=bin(t.index(j))[2:].zfill(6)
print(unhexlify(hex(eval("0b"+bins))[2:-1]))

flag:flag{base64_1s_v3ry_e@sy_and_fuN}

2024.1.5星期五

[BUUCTF·MRCTF2020]vigenere

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
g vjganxsymda ux ylt vtvjttajwsgt bl udfteyhfgt
oe btlc ckjwc qnxdta
vbbwwrbrtlx su gnw nrshylwmpy cgwps, lum bipee ynecgy gk jaryz frs fzwjp, x puej jgbs udfteyhfgt, gnw sil uuej su zofi. sc okzfpu bl lmi uhzmwi, x nyc dsj bl lmi enyl ys argnj yh nrgsi. nba swi cbz ojprbsw fqdam mx. cdh nsai cb ygaigroysxn jnwwi lr msylte.
cw mekr tg jptpzwi kdikjsqtaz, ftv pek oj pxxkdd xd ugnj scr, yg n esqxwxw nba onxw au ywipgkj fyiuujnxn gnss xwnz onxw jnahl avhwwxn vzkjpu nrofch fvwfoh. v jwhppek lmi vyutfp hbiafp hcguj at nxw gyxyjask ib hw seihxsqpn vtvjttajwsx ds zzj xnegfsmtf egz wtrq lt mbcukj sc hy. qty wnbw ss bbxsq vxtnl ys ghrw zw cbx vt cdh vgxwtfy ssc brzzthh bl wsjdeiwricg cw mekr zjzi grgktr ib lwfv.
vbbwwrbrtlx hteonj xwroj oyhg vgbigf ljtq iuk utrhrtl tj iuk ytztetwi. cdh nsai crolmig fudngxgkv ssg ekujmkrj gzvh. jk vnh cbz aszxgk qty. nba vt rdg qfta jf, tgw hd lum prdj umw aderv. hcqrxkuerr jgjw cbz dni lvzznr nbaj gsgqkjx. hd aul ylxaq lmei lum hec oaaqh xg, gk yldhmz nx lrxw f tjorah gdaylwyrgogs tgbpwhx. nba ufrcbz. ay mh nt shx ds tsyygr gfi mi txgbw xgywqj iuxgzkw baj hsaykuymkr guymday.
qty wnbw ssi rtyfktq of tyg txwfx paj yfxwrxask rbtnjvhnzatr, cbx vnh nba uwipgk lmi lrgdyl ds umw qpeqwytaniwx. cdh jg ssi xtgb sje imqxjek, gzv tgnahw, de zzj ycjxayxta igiih gnsy eaeksic eeunnht baj xsrvkld qdek gwhte zzfr rbadi ft bhlfmcrj td ecl ux dsje oeushvzatrh.
lum hppvs lmigr gjj tgbhdjqh nsgsk jf zzfx nba fjis gu ktpkr. egz yhr zznw rygar eh nt wcgjfk lt mcigvj sje vjjgxailx. qpae gk xwryw uvdorwrw sbt'l jbxfz. omigr zzjvt nxw wipy igsjavilx, awrxw yltek swi leuflw, lr caqp xqkfymul zzjq paj sihgryk yltz hq tyg zkssw. lr gjj jdesask dhx gbr hbiafp rbtlwerg. zznw vbbwwrpaiw bmay gjnwt niutvsvty ys iuk utrsvzatrh bl gzv lbxdi, rdg egzvh. baj bsgyj ax hxslwwicg.
iqgigfvshi rbtknwif ux yvpayshxxbtk, wianzatrhuohx, ecq zztyvuz aywtyl, swvplkv qmzr g kyecqofl apik as xwr cwg su baj hsbzafngpgogsw. dhxk nw p jujqh iugl nw qbzz jzteeomigr gfi rdjnwwi, qhz ay mh aul bltek tthxry dnzt.
jk swi reksymct g otvaq zzfx pyr efc tazww axgngzx eeonnpttk gw tgrpmimrr guhsgqkv gc gniw, jgdaueng ebcww, qxyolfvn sujhi, de ylfxxbt gk fxezz.
bi pek uwipgofl e lbxdi awrxw frnbtw, frnjnwwi bne wctgryk mmh bx zjv qrrajjh, au efxirx zta hvtyzppe, cayldhz xjeg bl tjmct igjvrrj asxd fodjrrr uj hscsujrmil.
egzv armsq gdaiwuxh bl hwserxld, imcxwxwxbt, aiicgold, qdikejri, ntv hscgkpy hd aul fteye lt yh. gnwd egr gdq fpfkv tr bnzljv, paj lmigr ok ss bnzljv wrxw.
tyg vjwsxxgowx lpik ft fdqowx, wd, htdnot lum, bi rntftx dozsnr dejww fn cnqxmrnr utigpogs. at okdnikr zzfx ueue jxwvik, jravmzyicrj kjpu-vtljvtfz, ssh iuk utqbbtojea, baj lskrxffrrr caqp tzkjli. dhx aiicgolnih zgq gi svylwmqhzwi ereukx qpae gk cdhx bzvxfjahxxbtk. ylt btdd ppj zzfx pyr gzv rbtkymihkfy gjyzmwih jumqh vrtwweaye jjgdttaei xf zzj kdyjws vjyk. oj ldck oj axyr tj eqyk lt fjvrv tyg cgjymrhrsw wdyalnscf uf ylpg hsxmh. oal bi rntftx ppiwux iuk ktpjgogsw nba swi pgzwrtivty ys xzvgxi.
xa zzj ycvzwi winzwx, cdh nsai ibjsd ggrgljh p ygo, ylt gkdjgdzsmsmrnzatrh ekxtvb nil, blxpn jjtjqosyih lumw sla igswivzmymda gfi mcfadyw iuk vwipzy gk ntslwwwda, csxlxamltr, bvrd, resvygs, htguizikvrdj, ecq hjfrsrok. yltfk vwipzy ezwi auo gi qbxf frtj of zw.
nba swi irxjnjxrj gk cdhx gbr ruodivta, yasgt gnwd egr tsymkry as e lbxdi awrxw dsj jodq eajgqx ft vsenkgntlx. ftpgmxi nba xjeg gnwr, cdh kfyvjfz qtyg oajjejpxshmtf cayl iuk hfvtazsq vtfvgswxoodnxxry qty pek lts rbcswhal zg hscsxgsx nbajxiaikk. nr dhx otvaq, gdq xwr ywsxxzkfyw paj wctgryknscf ux mybntayc, ueue ylt qktfwxam lt xwr gfliavi, swi enxlx su n ywfqaryk bldyk, lmi vyutfp rbtnjvhnzatr ds hayw. lr issrdg ywuegnzw ylt noj ylpg iztotf ljtq iuk snv jcuf blxpn onrvf hwfx.
xa iznrp, tkjrecl, ljfrrr, xmxwxn, yaskpcujj, minrq frs gnw zrxgkv xxpgkk, dsj nxw yvnvty ys lnxv tju gnw amghy gk pxokjyc ql kjjgivty lypej htwif gl ylt sxgsxxrxk tj rlhwwweniw. yltfk efc zrkh tyi gnw hscggynsc suj f wbnrd ymbr, hmy xwre onpa aul bsgx of f aderv ylpg caqp hbuf gi qygfpiirj as fxg-hwfvxam ejhxn.
egzv xaijjehvtyqc doygqiir ofksgzglnsc vtvzwieowx adhrv uigcklzeir zzjqhrrnjw ql vjttdfofl ppjy, as ebrxahe paj wqwtjnwwi, iugl hppvs lt sla yhjiru olxias zzwsjtngzx iuk otvaq. zzjwt ygox adhrv iirygjj msrgk ys qr gftxwrx ashjfzjnea cxgiyrg, tg rsgr tggpt gnss txt ojtr. xa umw aderv, blpgknjv iuk zzqpa sash bne uwipgk ufr qr xwuvdqaujh paj vnwieotzxtq ofkmcvzwqc pg tg hshg. zzj kabhsq gdabwdecpk gk xwbaymx cb rgskte xwvyxekk dsje lshxdeowx xd niutqeyokm.
xwryw nrreksxmctrq mshgodj ecq igqscvgd ripfajjw eyguj yh vt lmi hnsw ushvzatr pf zztwt cxwamdhy dtztey gk jgrkvtq paj kjpu-qkljvbvtsymda czt lpq zg wiyril ylt nalmsgvzajw ds jaxxpaz, msmcsujris cuojvh. jk ezwi qkuqegr umw zxezmfp hrrnjw xzsmsi ib egzv hbbwwixttld, ikrt sx at pufymchk lt gdaywsx ib egzv ghrw tzte umw fdqowx. at jodq weeksi sjeywqztf guwshf zzj tantwy wd gnsy rd btw hec nxjjwi baj yldhmzyw.
lr caqp reksyi p ponnpxmglnsc bl lmi bvtv nr rlhwwweniw. ren vz tj qdek zzqpak ssh unoj ylpa zzj aderv dsje mgaigaswsxh ugnj qpqk tjjdek.
xqev vy ewgis balicrxw hvnczg hvppq efr, eyksxi pqj mshteyutvt ntv hygye twerry.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/bin/python3
from ctf import source_text, key_string

getdiff = lambda char: ord(char)-ord('a')
getchar = lambda num: chr(ord('a')+num)

def vigenere(src: chr, key: chr) -> chr:
assert(src.isalpha() and key.isalpha())
return(getchar((getdiff(src) + getdiff(key) + 1) % 26))

src = source_text.lower()
count = 0
assert(len(key_string) > 5 and len(key_string) < 10)
for i in src:
if(i.isalpha()):
print(vigenere(i, key_string[count % len(key_string)]), end='')
count+=1
else:
print(i, end='')

对于这段加密代码,这是gpt给出的解释

对于网络上的wp,一般是给出这个在线网站进行破解(还挺快)https://www.guballa.de/vigenere-solver

flag:flag{vigenere_crypto_crack_man}

[BUUCTF·MRCTF2020]keyboard

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
得到的flag用
MRCTF{xxxxxx}形式上叫
都为小写字母

6
666
22
444
555
33
7
44
666
66
3

通过九键键盘加密

可以直接手搓,搓出mobilephond

提交发现不对,调用英语知识把d改成e就对了

对于大量数据的解码脚本:

1
2
3
4
txt = '6 666 22 444 555 33 7 44 666 66 3'.split()
jiujian = ['','','abc','def','ghi','jkl','mno','pqrs','tuv','wxyz']
for i in txt:
print(jiujian[int(i[0])][len(i)-1],end='')

flag:flag{mobilephone}

[BUUCTF·AFCTF2018]Vigenère

image-20240105145056831

又是未知密钥的维吉尼亚密码,在线网站一把唆https://www.guballa.de/vigenere-solver

flag:flag{Whooooooo_U_Gotcha!}

密码学的心声

  1. 数字三位一组分组,形成多组八进制数
  2. 转成十进制,也是三个数一组
  3. 每组转化为相应的ASCLL码
1
2
3
4
5
6
7
8
9
str = '111 114 157 166 145 123 145 143 165 162 151 164 171 126 145 162 171 115 165 143 150'
str = str.split(' ')
flag = []
for i in range(len(str)):
flag.append( str[i] )
result = ''
for i in flag:
result += chr(int(i,8))
print( result )

flag{ILoveSecurityVeryMuch}

robomunication

是一段音频,摩斯密码,转码后即可得到flag

flag{BOOPBEEP}

[BJDCTF2020]这是base??(undone)

前置知识:base64

达芬奇密码(undone)

[WUSTCTF2020]佛说:只能四天

http://hi.pcmoe.net/buddha.html

https://atool.vip/corevalue/

传统的凯撒密码偏移量是3

base32由AZ,27组成(还有"=")

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
import base64
def caesarCrack(c, n):
alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
c = c.upper()
m = ""
for i in c:
index = alpha.find(i)
if index != -1:
index = (index + n) % 26
m += alpha[index]
else:
m += i
return m
if __name__ == '__main__':
c = "R5UALCUVJDCGD63RQISZTBOSO54JVBORP5SAT2OEQCWY6CGEO53Z67L"
# 用'='填充字符串使其长度为8的倍数, 方便后序进行Base32解密
lenPadding = 8 - (len(c) % 8)
c += lenPadding * "="
for i in range(1, 26):
ca = caesarCrack(c, i)
m = base64.b32decode(ca)
try:
m = m.decode()
print(m)
except UnicodeDecodeError:
continue

flag{ni_hao_xiang_xiang_da_wo}

[MRCTF2020]古典密码知多少

猪圈密码+圣堂武士密码+标准银河字母密码

然后根据提示,使用栅栏密码

flag{CRYPTOFUN}

rot

需要暴力枚举后四位,根据md5判断正误

1
2
3
4
5
6
7
8
9
10
11
import hashlib
txt = 'flag{www_shiyanbar_com_is_very_good_'
md5 = '38e4c352809e150186920aac37190cbc'
for i in range(33,128):
for j in range(33,128):
for k in range(33,128):
for o in range(33,128):
flag = txt+chr(i)+chr(j)+chr(k)+chr(o)+'}'
hsh = hashlib.md5(flag.encode()).hexdigest()
if( hsh == md5 ):
print( flag )

flag{www_shiyanbar_com_is_very_good_@8Mu}

这是什么

这是什么?这不是雪豹,这是jsfuck密码

拖到010editor中,得到一串这样的符号,使用https://www.bugku.com/tools/jsfuck/#解码

flag{a0448fd730b62c13ca80200c4529daa2}

[NCTF2019]Keyboard

电脑键盘第一行的从W到O八个字母 -> 手机九键输入法的八个字母

出现频率表示第几个

flag{youaresosmartthatthisisjustapieceofcake}

[MRCTF2020]天干地支+甲子

一甲子=60

将每个干支转化成对应的数字,再+60,转化成ASCLL码即可

flag{Goodjob}

传感器

16进制转字符串即可

flag{We1c0me_t4_BJDCTF}

一张谍报

有两段长度相同的文段,局部文字相同,二者不相同的内容形成多组映射,形成密码本

依据此密码本对右下角密文进行解密即可

1
2
3
4
5
6
7
8
9
10
str1 = "今天上午,朝歌区梆子公司决定,在每天三更天不亮免费在各大小区门口设卡为全城提供二次震耳欲聋的敲更提醒,呼吁大家早睡早起,不要因为贪睡断送大好人生,时代的符号是前进。为此,全区老人都蹲在该公司东边树丛合力抵制,不给公司人员放行,场面混乱。李罗鹰住进朝歌区五十年了,人称老鹰头,几年孙子李虎南刚从东北当猎户回来,每月还寄回来几块鼹鼠干。李罗鹰当年遇到的老婆是朝歌一枝花,所以李南虎是长得非常秀气的一个汉子。李罗鹰表示:无论梆子公司做的对错,反正不能打扰他孙子睡觉,子曰:‘睡觉乃人之常情’。梆子公司这是连菩萨睡觉都不放过啊。李南虎表示:梆子公司智商捉急,小心居民猴急跳墙!这三伏天都不给睡觉,这不扯淡么!到了中午人群仍未离散,更有人提议要烧掉这个公司,公司高层似乎恨不得找个洞钻进去。直到治安人员出现才疏散人群归家,但是李南虎仍旧表示爷爷年纪大了,睡不好对身体不好。"
str2 = "喵天上午,汪歌区哞叽公司决定,在每天八哇天不全免费在各大小区门脑设卡为全城提供双次震耳欲聋的敲哇提醒,呼吁大家早睡早起,不要因为贪睡断送大好人生,时代的编号是前进。为此,全区眠人都足在该公司流边草丛合力抵制,不给公司人员放行,场面混乱。李罗鸟住进汪歌区五十年了,人称眠鸟顶,几年孙叽李熬值刚从流北当屁户回来,每月还寄回来几块报信干。李罗鸟当年遇到的眠婆是汪歌一枝花,所以李值熬是长得非常秀气的一个汉叽。李罗鸟表示:无论哞叽公司做的对错,反正不能打扰他孙叽睡觉,叽叶:‘睡觉乃人之常情’。哞叽公司这是连衣服睡觉都不放过啊。李值熬表示:哞叽公司智商捉急,小心居民猴急跳墙!这八伏天都不给睡觉,这不扯淡么!到了中午人群仍未离散,哇有人提议要烧掉这个公司,公司高层似乎恨不得找个洞钻进去。直到治安人员出现才疏散人群归家,但是李值熬仍旧表示爷爷年纪大了,睡不好对身体不好。"
str3 = "喵汪哞叽双哇顶,眠鸟足屁流脑,八哇报信断流脑全叽,眠鸟进北脑上草,八枝遇孙叽,孙叽对熬编叶:值天衣服放鸟捉猴顶。鸟对:北汪罗汉伏熬乱天门。合编放行,卡编扯呼。人离烧草,报信归洞,孙叽找爷爷。"
flag = ""
for i in range( len(str3) ):
for j in range( len(str2) ):
if str3[i] == str2[j]:
flag = flag + str1[j]
break
print( flag )

flag{南天菩萨放鹰捉猴头}

[NPUCTF2020]这是什么觅🐎

得到一个无拓展名的文件,用010editor打开,发现有'jpg',拓展名改成'jpg',打开失败,疑似是压缩包,改成zip解压获得图片

字母和数字确定一个数字,其中T1为TUE,T2为THU;S1为SAT,S2为SUN

对应的数字:3 1 12 5 7/14 4 1 18

对应的字母:C A L E G/N D A R

flag{calendar}

[极客大挑战]proof_of_work

题目链接:nc 59.110.20.54:5526 Build your own function to solve proof_of_work!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import hashlib

txt = ""
cnt = 0

for i in range( 32 , 127 ):
for j in range( 32 , 127 ):
for k in range( 32 , 127 ):
for o in range( 32 , 127 ):
txt = chr(i)+chr(j)+chr(k)+chr(o)+"CwO1X7uNTpovKiWE"
if hashlib.sha256(txt.encode('utf-8')).hexdigest() == "c88bbfe56a7638ca6bf9428a5ce583d55a8376d1c77512518bd5a40d0600da26":
print(txt)
assert 0
cnt += 1
if( cnt == 500000 ):
print( txt , hashlib.sha256(txt.encode('utf-8')).hexdigest() )
cnt = 0;
print("end")

[BUUCTF][BJDCTF2020]这是base??

base64原理:用64个可打印字符表示二进制所有数据方式。2^6=64,所以可以用每六个位元为一个单元,对应某个可打印字符。三个字节长度为24个位元,对应4个base64单元;即三个字节需要用四个base64可打印字符表示

转换时每次取3byte的数据,放进24bite的缓冲区,先进为高位,数据不足24bite则用0补齐

然后每次取6bit,按照对照表的编码输出,加密后的数据量是原来的4/3

这道题相当于base64更换密码表,加密原理相同

txt.find('c') 在列表中找到'c'字符,返回下标

b'010101'[2:].zfill('num') 从第三位开始取,返回长度为'num'的字符串,原字符串右对齐,前面填充0。(舍弃前2位,是因为二进制数前面有前缀'0b')

1
2
3
4
5
6
7
8
9
10
11
c="JKLMNOxyUVzABCDEFGH789PQIabcdefghijklmWXYZ0123456RSTnopqrstuvw+/="
txt="FlZNfnF6Qol6e9w17WwQQoGYBQCgIkGTa9w3IQKw"

end=""
for i in txt:
end+=bin(c.find(i))[2:].zfill(6)

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

flag{D0_Y0u_kNoW_Th1s_b4se_map}

[BUUCTF]达芬奇密码

观察发现数字列是一串打乱顺序的斐波那契数列

生成一个正常顺序的斐波那契

1
2
3
4
5
6
7
8
a = 1
b = 1
print( "1 1 ",end = '' )
for i in range( 1 , 40 ):
c = a + b
print( c , end = ' ' )
a = b
b = c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
a = '0 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 17711 28657 46368 75025 121393 196418 317811 514229 832040 1346269 2178309'
b = '0 233 3 2584 1346269 144 5 196418 21 1597 610 377 10946 89 514229 987 8 55 6765 2178309 121393 317811 46368 4181 1 832040 2 28657 75025 34 13 17711'
a = a.split(" ")
b = b.split(" ")

flag = []
m = '36968853882116725547342176952286'

for i in range( len(a) ):
for j in range( len(b) ):
if a[i] == b[j]:
flag.append(m[j])
break
print( ''.join(flag) )

flag{37995588256861228614165223347687}

发现的细节:

如果字符串最后有一个空格,split()操作后会多一个空格

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
"""requirment
a = []
a.append(1)
a.append(1)
print( "1 1 ",end = '' )
for i in range( 3 , 30 ):
a.append( a[i-1] + a[i-2] )
print( a[i] , end = ' ' )

a = 1
b = 1
print( "1 1 ",end = '' )
for i in range( 1 , 40 ):
c = a + b
print( c , end = ' ' )
a = b
b = c
#add_requirment:为什么要把第一位的1都改成0
"""

[AFCTF2018]Single

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
#include <bits/stdc++.h>
using namespace std;
int main()
{
freopen("Plain.txt","r",stdin);
freopen("Cipher.txt","w",stdout);
map<char, char> f;
int arr[26];
for(int i=0;i<26;++i){
arr[i]=i;
}
random_shuffle(arr,arr+26);
for(int i=0;i<26;++i){
f['a'+i]='a'+arr[i];
f['A'+i]='A'+arr[i];
}
char ch;
while((ch=getchar())!=EOF){
if(f.count(ch)){
putchar(f[ch]);
}else{
putchar(ch);
}
}
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
Jmqrida rva Lfmz (JRL) eu m uqajemf seny xl enlxdomrexn uajiderc jxoqarerexnu. Rvada mda rvdaa jxooxn rcqau xl JRLu: Paxqmdyc, Mrrmjs-Yalanja mny oekay.

Paxqmdyc-urcfa JRLu vmu m jxiqfa xl giaurexnu (rmusu) en dmnza xl jmrazxdeau. Lxd akmoqfa, Wab, Lxdanuej, Jdcqrx, Benmdc xd uxoarvenz afua. Ramo jmn zmen uxoa qxenru lxd atadc uxftay rmus. Oxda qxenru lxd oxda jxoqfejmray rmusu iuimffc. Rva nakr rmus en jvmen jmn ba xqanay xnfc mlrad uxoa ramo uxfta qdatexiu rmus. Rvan rva zmoa reoa eu xtad uio xl qxenru uvxwu cxi m JRL wenad. Lmoxiu akmoqfa xl uijv JRL eu Yaljxn JRL gimfu.

Waff, mrrmjs-yalanja eu mnxrvad enradaurenz seny xl jxoqarerexnu. Vada atadc ramo vmu xwn narwxds(xd xnfc xna vxur) werv tifnmdmbfa uadtejau. Cxid ramo vmu reoa lxd qmrjvenz cxid uadtejau mny yatafxqenz akqfxeru iuimffc. Ux, rvan xdzmnehadu jxnnajru qmdrejeqmnru xl jxoqarerexn mny rva wmdzmoa urmdru! Cxi uvxify qdxrajr xwn uadtejau lxd yalanja qxenru mny vmjs xqqxnanru lxd mrrmjs qxenru. Veurxdejmffc rveu eu m ledur rcqa xl JRLu, atadcbxyc snxwu mbxir YAL JXN JRL - uxoarvenz fesa m Wxdfy Jiq xl mff xrvad jxoqarerexnu.

Oekay jxoqarerexnu omc tmdc qxuuebfa lxdomru. Er omc ba uxoarvenz fesa wmdzmoa werv uqajemf reoa lxd rmus-bmuay afaoanru (a.z. IJUB eJRL).

JRL zmoau xlran rxijv xn omnc xrvad muqajru xl enlxdomrexn uajiderc: jdcqrxzdmqvc, urazx, benmdc mnmfcueu, datadua anzanaadenz, oxbefa uajiderc mny xrvadu. Zxxy ramou zanadmffc vmta urdxnz useffu mny akqadeanja en mff rvaua euuiau.

Iuimffc, lfmz eu uxoa urdenz xl dmnyxo ymrm xd rakr en uxoa lxdomr. Akmoqfa mljrl{Xv_I_lxiny_er_neja_rDc}

词频分析即可得到flag

flag:flag{Oh_U_found_it_nice_tRy}

鸡藕椒盐味

1
公司食堂最新出了一种小吃,叫鸡藕椒盐味汉堡,售价八块钱,为了促销,上面有一个验证码,输入后可以再换取一个汉堡。但是问题是每个验证码几乎都有错误,而且打印的时候倒了一下。小明买到了一个汉堡,准备还原验证码,因为一个吃不饱啊验证码如下:1100 1010 0000 ,而且打印的时候倒了一下。把答案哈希一下就可以提交了。(答案为正确值(不包括数字之间的空格)的32位md5值的小写形式) 注意:得到的 flag 请包上 flag{} 提交

奇校验:所有位(包括数据位和校验位)共含1个数为奇数

偶校验:所有位共含1个数为偶数

奇偶校验码能发现奇数个错误

海明校验码:校验位在 的地方

可以算出密文是110110100000

进行md5加密得到答案

flag:flag{d14084c7ceca6359eaac6df3c234dd3b}

[ACTF新生赛2020]crypto-classic1

1
2
哇,这里有压缩包的密码哦,于是我低下了头,看向了我的双手,试图从中找到某些规律
xdfv ujko98 edft54 xdfv pok,.; wsdr43
1
SRLU{LZPL_S_UASHKXUPD_NXYTFTJT}

第一层是传统脑洞题,键盘密码的一种

circle

第二层提示是维吉尼亚密码

1
2
3
4
5
6
7
8
9
10
11
c='SRLU{LZPL_S_UASHKXUPD_NXYTFTJT}'
m='ACTF{'
a=[]
for i in range(4):
a.append(str(ord(c[i])-ord(m[i])))
print(m,end='')
for i in range(5,len(c)):
if 'A'<= c[i]<= 'Z':
print(chr((ord(c[i])-int(a[i%4])-ord('A'))%26+ord('A')),end='')
else:
print(c[i],end='')

flag:flag{what_a_classical_vigenere}

[AFCTF2018]BASE

一个很大很大的文件


读取文件,进行base系列自动解密

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import re, base64
s = open('flag_encode.txt', 'rb').read()
base16_dic = r'^[A-F0-9=]*$'
base32_dic = r'^[A-Z2-7=]*$'
base64_dic = r'^[A-Za-z0-9/+=]*$'
n= 0
while True:
n += 1
t = s.decode()
if '{' in t:
print(t)
break
elif re.match(base16_dic, t):
s = base64.b16decode(s)
print(str(n) + ' base16')
elif re.match(base32_dic, t):
s = base64.b32decode(s)
print(str(n) + ' base32')
elif re.match(base64_dic, t):
s = base64.b64decode(s)
print(str(n) + ' base64')

flag:flag{U_5h0u1d_Us3_T00l5}

[UTCTF2020]basic-crypto

很多二进制数,空格隔开


二进制ascll码转字符得到

image-20240127203144559

之后解base64

image-20240127203429627

然后是凯撒密码

对最后一段进行词频分析得到flag

1
congratulations! you have finished the beginner cryptography challenge. here is a flag for all your hard efforts: utflag{n0w_th4ts_wh4t_i_c4ll_crypt0}. you will find that a lot of cryptography is just building off this sort of basic knowledge, and it really is not so bad after all. hope you enjoyed the challenge!

flag:flag{n0w_th4ts_wh4t_i_c4ll_crypt0}

[WUSTCTF2020]情书

1
2
3
4
5
6
7
Premise: Enumerate the alphabet by 0、1、2、.....  、25
Using the RSA system
Encryption:0156 0821 1616 0041 0140 2130 1616 0793
Public Key:2537 and 13
Private Key:2537 and 937

flag: wctf2020{Decryption}

1
2
3
4
5
6
7
8
9
10
11
12
a = "abcdefghijklmnopqrstuvwxyz"
c = "0156 0821 1616 0041 0140 2130 1616 0793".split(" ")

p = 43 ; q = 59
e = 13 ; d = 937
n = p * q ; phi = (p-1)*(q-1)

flag = ""
for i in c:
flag = flag + a[pow(int(i),d,n)]

print ("flag{"+flag+"}")

flag:flag{iloveyou}

[GUET-CTF2019]NO SOS

1
..-.-.-.–…….–..-…-..-…–.-.-….-..-..–.-.-..-.-..—-

略加修改

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

解密得到

1
aababababbaaaaaaabbaabaaabaabaaabbababaaaabaabaabbababaababaabbbb

培根密码解密

1
flagisguetkkp

flag:flag{guetkkp}

[UTCTF2020]zero

一个文档


零宽字符隐写https://330k.github.io/misc_tools/unicode_steganography.html

flag:flag{whyNOT@sc11_4927aajbqk14}

[NPUCTF2020]Classical Cipher

一个文件


使用https://quipqiup.com/爆破密码

密码:the_key_is_atbash

猪圈密码+古埃及象形文字http://news.558idc.com/291134.html

image-20240127213313022

image-20240127213358381

image-20240127213419878

flag:flag{classicalcode}

四面八方

1
2
3
4
key1:security
key2:information

密文啊这是,骚年加油:zhnjinhoopcfcuktlj

四方密码http://www.hiencode.com/four.html

flag:flag{yaungandsuccessful}

[BJDCTF2020]Polybius

1
2
3
密文:ouauuuoooeeaaiaeauieuooeeiea
hint:VGhlIGxlbmd0aCBvZiB0aGlzIHBsYWludGV4dDogMTQ=
flag:解出明文后,请加上BJD{}

波利比奥斯密码

根据提示,长度是14

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import itertools
s="aeoiu"
sumresult=[] ; numsumresult=[]
ciper="ouauuuoooeeaaiaeauieuooeeiea"
for i in itertools.permutations(s,5):
sumresult.append("".join(i))
for i in sumresult:
temp=""
for j in ciper:
temp+=str(i.index(j)+1)
numsumresult.append(temp)
for i in numsumresult:
flag=""
for j in range(0, len(i),2):
xx=(int(i[j])-1)*5+int(i[j+1])+96
if xx>ord('i'):
xx+=1
flag+=chr(xx)
print( flag )

得到flagispolybius

flag:flag{flagispolybius}

救世捷径

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
一个名叫CPU的神秘大陆有26个国家,有些国家之间会有一条无向路,每条路径都有不同的长度和一段神秘代码,救世主尼奥要从国家1出发,赶往国家26拯救大陆,请你帮助救世主选择最短路径,而走过的路的神秘代码连接起来便是flag。 以下是数行数据,每行第一个,第二个数字代表这条路的两个端点国家,第三个数字代表路途长度,最后一个字符串便是神秘代码。路在附件中~ 帮助救世主尼奥吧,他快被吓尿了。。。 注意:得到的 flag 请包上 flag{} 提交
1 2 100 FLAG{
2 3 87 AFQWE
2 4 57 ETKLS
2 5 50 WEIVK
2 6 51 AWEIW
3 7 94 QIECJF
3 8 78 QSXKE
3 9 85 QWEIH
4 13 54 WQOJF
4 14 47 KDNVE
4 15 98 QISNV
5 10 43 AEWJV
5 11 32 QWKXF
5 12 44 ASJVL
6 16 59 ASJXJ
6 17 92 QJXNV
6 18 39 SCJJF
6 23 99 SJVHF
7 19 99 WJCNF
8 20 96 SKCNG
9 20 86 SJXHF
10 21 60 SJJCH
11 21 57 SJHGG
12 22 47 SJCHF
14 10 55 EJFHG
16 17 59 ASJVH
18 12 53 SJFHG
18 24 93 SHFVG
21 22 33 SJFHB
19 25 88 ASHHF
20 25 96 SJVHG
22 25 23 SJVHJ
25 26 75 SDEV}

最短路问题 洛谷·P4779 【模板】单源最短路径(标准版)

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
g = []
for i in range( 27 ):
g.append([])
for i in range( 27 ):
for j in range( 27 ):
g[i].append( 1000000 )
f = open( 'c.txt' , 'r' ).readlines()
l = []
for i in f:
l.append(i.strip().split(' '))
print( l )
for i in l:
print( i )
g[int(i[0])][int(i[1])] = int( i[2] )
g[int(i[1])][int(i[0])] = int( i[2] )

def dij():
dv = [1000000 for i in range(27)]
route = [1 for i in range(27)]
vis = [0 for i in range(27)]
for i in range( 2 , 27 ):
dv[i] = g[i][1]
dv[1] = 0
vis[1] = 1
for i in range(26):
minn = 1000000
tmp = -1
for j in range( 2 , 27 ):
if vis[j] == 0 and minn > dv[j]:
minn = dv[j]
tmp = j
vis[tmp] = 1
for j in range( 2 , 27 ):
if dv[j] > dv[tmp] + g[tmp][j]:
dv[j] = dv[tmp] + g[tmp][j]
route[j] = tmp
return ( route , dv )

route , dv = dij()
y = 26
while y!=1:
print( y )
y = route[y]

得到路径

1
2
3
4
5
6
26
25
22
12
5
2

得到flag

flag:flag{WEIVKASJVLSJCHFSJVHJSDEV}

坏蛋是雷宾

1
老牌刺客之王混进了女王的住所。一天,女王得到了一个匿名举报,说她的侍卫里有一个刺客,叫做Rabin,而他的信息就在一份文件里,文件中有附带一个Pk,是523798549,密文是162853095,校验码二进制值是110001,根据说明是放在明文后一起加密的,明文与密文长度相同。加密算法和这位老牌刺客同名。快拯救女王,答案是求得的明文,进行32位md5小写哈希字符串,提交即可。 注意:得到的 flag 请包上 flag{} 提交

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
from gmpy2 import *
import hashlib
n=523798549
p=10663
q=49123
e=2
c=162853095
inv_p = invert(p, q)
inv_q = invert(q, p)

mp = powmod(c, (p + 1) // 4, p)
mq = powmod(c, (q + 1) // 4, q)

a = (inv_p * p * mq + inv_q * q * mp) % n
b = n - int(a)
c = (inv_p * p * mq - inv_q * q * mp) % n
d = n - int(c)

for i in (a, b, c, d):
print(bin(i)[2:])

m='10010011100100100101010'
mc=str(int(m,2))
md=hashlib.md5()
md.update(mc.encode("utf8"))
print( md.hexdigest() )

flag:flag{ca5cec442b2734735406d78c88e90f35}

[BJDCTF2020]编码与调制

tag:差分曼彻斯特编码

image-20240208182640371

1
密文:2559659965656A9A65656996696965A6695669A9695A699569666A5A6A6569666A59695A69AA696569666AA6

(好像从哪里见过,而且这道题更简单一点)见代码

1
2
3
4
5
6
7
8
9
10
11
12
13
from Crypto.Util.number import long_to_bytes

txt = "2559659965656A9A65656996696965A6695669A9695A699569666A5A6A6569666A59695A69AA696569666AA6"
txt = bin(int( txt , 16 ))[2:]
m = ""

for i in range( 0,len(str(txt)),2 ):
if txt[i] == "0":
m += "0"
else:
m += "1"

print( long_to_bytes(int(m,2)) )

flag:BJD{DifManchestercode}

EasyProgram

tag:misc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
get buf unsign s[256]
get buf t[256]
we have key:whoami
we have flag:????????????????????????????????

for i:0 to 256
set s[i]:i

for i:0 to 256
set t[i]:key[(i)mod(key.lenth)]

for i:0 to 256
set j:(j+s[i]+t[i])mod(256)
swap:s[i],s[j]

for m:0 to 38
set i:(i + 1)mod(256)
set j:(j + S[i])mod(256)
swap:s[i],s[j]
set x:(s[i] + (s[j]mod(256))mod(256))
set flag[m]:flag[m]^s[x]

fprint flagx to file

因为和flag相关的只有异或操作,可逆,故加密和解密过程代码相同

伪代码不初始化默认为0

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
txt = " 00 BA 8F 11 2B 22 9F 51 A1 2F AB B7 4B D7 3F EF E1 B5 13 BE C4 D4 5D 03 D9 00 7A CA 1D 51 A4 73 B5 EF 3D 9B 31 B3".replace(" "," 0x").split(" ")[1:]
key = "whoami"

s = []
t = []
for i in range( 256 ):
s.append(i)
for i in range( 256 ):
t.append(key[i%len(key)])

j = 0
for i in range( 256 ):
j = ( j + s[i] + ord( t[i] ) ) % 256
s[i] , s[j] = s[j] , s[i]

i = 0
j = 0
flag = ""
for m in range( 38 ):
i = ( i + 1 ) % 256
j = ( j + s[i] ) % 256
s[i] , s[j] = s[j] , s[i]
x = ( s[i] + ( s[j] % 256 ) ) % 256
flag += chr( int(txt[m],16) ^ s[x] )

print( flag )

flag:flag{f238yu28323uf28u2yef2ud8uf289euf}

[UTCTF2020]hill

tag:线性代数 | 希尔密码

1
wznqca{d4uqop0fk_q1nwofDbzg_eu}

希尔密码:左乘一个密钥矩阵进行加密

flag前六位为:utflag

1
2
3
4
5
6
7
8
9
10
m = "wznqca"
c = "utflag"

for i in m:
if ord(i)>=ord('a') and ord(i)<=ord('z'):
print( ord(i) - ord('a') , end = " " )
print()
for i in c:
if ord(i)>=ord('a') and ord(i)<=ord('z'):
print( ord(i) - ord('a') , end = " " )

得到

有两种方式,一种是暴力搜索,另一种是解方程(翻译:手搓),这里我们只写第一种

1
2
3
4
5
6
7
8
9
10
11
12
13
from numpy import *

M = mat([[22,13,2],[25,16,0]])
C = mat([[20,5,0],[19,11,6]])

for a in range( 100 ):
for b in range( 100 ):
for c in range( 100 ):
for d in range( 100 ):
K = mat([[a,b],[c,d]])
if ((K*C)%26==M).all():
print( K )
assert 0

得到的一个解是[[ 1 22],[11 13]]

有了密钥,使用在线工具即可得到flag

image-20240209150414038

填回其他字符,修正大小写即可

flag:utflag{d4nger0us_c1pherText_qq}