CTF密码学总结(一)

目录

CTF 密码学总结

题目类型总结:

简单密码类型:

复杂密码类型:

密码学脚本类总结:

单独的密文类型(优先使用ciphey工具)

多层传统加密混合:

Bugku的密码学的入门题/.-:(摩斯密码、url编码、出人意料的flag)

攻防世界之混合编码:(base64解密、unicode解密、ASCII转字符脚本、传统base64解密、ASCII解密)

单层传统加密:

Bugku crypto之聪明的小羊:(题目描述暗示、栅栏密码)

攻防世界之转轮机加密:(转轮机加密、)

复杂加密类型

ECC椭圆曲线加密:

攻防世界 之easy_ECC:(ECC加密)

python类型逻辑加密

pyc文件反编译:

攻防世界之easychallenge:(源代码修改逻辑解密、)

传统密码类型解析

凯撒密码(24个字母):

摩斯密码(只有01(无规则)或.-,空格或/做分隔符):

云影密码(01248):

栅栏密码(分组数作密钥):

培根密码(大小写的ABab,而且必须是5个一组,不是5个就考虑摩斯密码):

与佛论禅编码,要加上佛曰:才能转换(BASE64类型转不了就ROT13一下)

转轮机加密:

URL编码规则:

解密工具、脚本积累

Ciphey工具:

CTF-RSA-tool工具:

RSA前景知识:

RSA脚本工具使用说明:

多组n,e,c在解题时长这个样子:

一组n,e,c的题目样式:

脚本类型示例:

ECC加密:

ECC脚本积累(解出最后的公钥和私钥即可):


CTF 密码学总结

出人意料的flag:

指在题目中获取到了flag,但是这个flag可能长得不像flag,或者flag还要经过进一步的脑洞处理,而不是常规的解密处理。

题目类型总结:

题目描述暗示:

指题目给出的描述中有解题的大方向思路,以及对解题过程中出现的一些疑惑点的解释。

简单密码类型:

摩斯密码:

指解题中的密文涉及摩斯密码,摩斯密码的特征是以.-或01组成的,分隔符有空格或斜杠/。

url编码:

指解题中的密文涉及url编码,url编码的特征是使用 "%" 其后跟随两位的十六进制数来替换非 ASCII 字符。

传统base64解密:

指题目中密文是涉及base64加密,密文通常是4的倍数,基本元素是ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/和补充的'='

unicode解密:

指解题中密文涉及 unicode 解密,unicode现在已知的特征是ASCII(英文也是ASCII码)转unicode码时是 &# 前缀 +2 个 16 进制数,并用 ; 分隔。中文转unicode时是 \u + 4 个 16 进制数,中间没有间隔。

举例:1234 ----->1234 牛逼-------->\u725b\u903c

ASCII解密:

指解题中密文涉及ASCII码,需要转成字符。ASCII共128个可显示字符,范围是0~127或0~7F。不同通常每个ASCII码的间隔依据出题者来定。

栅栏密码:

指解题中密文涉及栅栏密码,因为栅栏密码有传统的矩阵型和 W 型,所以需要自己辨认。根据题目给的 key 分段来逐个尝试。

转轮机加密:

指解密中密文涉及转轮机加密,转轮机密文的特点是等长的分好组的乱序字母,原理是转齿轮把一个字母换成另一个来拼成一句话,所以会有多组密钥,但是只有一组密文。

格式举例,等长的分好组的字符串:

ZWAXJGDLUBVIQHKYPNTCRMOSFE

KPBELNACZDTRXMJQOYHGVSFUWI

复杂密码类型:

ECC加密:

是一种建立公开密钥加密的算法,基于椭圆曲线数学的椭圆曲线密码学。

密码学脚本类总结:

ASCII转字符脚本:

指解题中遇到长串ASCII码形式,需要转字符,但是一个个转太麻烦,又没有在线的长串ASCII码转字符网站。且给出的长串ASCII码的间隔依情况而定,如:/119/101/,这时需要自己根据对应间隔写出批量转换脚本。

源代码修改逻辑解密:

指解题中在有较完整源代码的情况下代码逻辑比较明朗,且可以逆向。这时需要充分利用有源代码的优势来在源代码中修改处逆向逻辑,不要自己从头到尾另写一份。

单独的密文类型(优先使用ciphey工具)

多层传统加密混合:

Bugku的密码学的入门题/.-:(摩斯密码、url编码、出人意料的flag)

CTF密码学总结(一)_第1张图片

摩斯密码是以.-或01组成的,分隔符有空格或斜杠/,所以直接扔去摩斯密码在线解密即可。

网址:https://www.bejson.com/enc/morse/

CTF密码学总结(一)_第2张图片

答案差不多了,却被%u7b和%u7d卡住了,猜想是{ }的url编码,{的url编码是%7B,}的url编码是%7D

所以去掉u符号(这里u符号应该是什么十六进制之类的,我也不知道)

直接得到flag:

FLAG{D3FCBF17F9399504}

结果全部要小写:

flag{d3fcbf17f9399504}

攻防世界之混合编码:(base64解密、unicode解密、ASCII转字符脚本、传统base64解密、ASCII解密)

下载附件,打开,发现两个等号和19azA~Z的典型base64编码型,直接base64转换:

CTF密码学总结(一)_第3张图片

转了一堆&#出来,根据以前的做题经验,猜unicode或hex:

一开始用了十六进制来转,转了个四不像出来,后来发现转错了,unicode在线解码网址:

http://www.jsons.cn/unicode/

CTF密码学总结(一)_第4张图片

这三个数的看着像ASCII,因为题目暗示混合编码,直接转换看看:ASCCII表对照法:

CTF密码学总结(一)_第5张图片

ASCII转字符脚本法:(这里因为string.split切片后返回的是列表,所以可以直接用索引获取。)

import re

r="/119/101/108/99/111/109/101/116/111/97/116/116/97/99/107/97/110/100/100/101/102/101/110/99/101/119/111/114/108/100"

r=re.split("/",r)

#print(r)

flag=""

for i in range(1,len(r)):

flag+=chr(int(r[i]))

print(flag)

单层传统加密:

Bugku crypto之聪明的小羊:(题目描述暗示、栅栏密码)

CTF密码学总结(一)_第6张图片

好的,传统栅栏密码,下面是我以前的笔记:

所谓栅栏密码,就是把要加密的明文分成N个一组,然后把每组的第1个字连起来,形成一段无规律的话。 不过栅栏密码本身有一个潜规则,就是组成栅栏的字母一般不会太多。(一般不超过30个,也就是一、两句话)

传统栅栏密码(矩阵行列,密钥是行数):

假如有一个字符串:123456789

取字符串长度的因数进行分组,假如key=3

1 2 3 \\分组情况,每三个数字一组,分为三组

4 5 6

7 8 9

然后每一组依次取一个数字组成一个新字符串:147258369 \\加密完成的字符串

解题:

试一般的栅栏密码,取5为矩阵行数,得到" cyperrocaegireeol} eahfocec gnbip不正确,取5为矩阵列数,得到" cebgccfe en eohplprgecrayoii aoreg”,也不正确,除了常规的栅栏密码,还有

由题目描述可知分两组:

fa{fe13f590

lg6d46d0d0}

那么答案很明显了,上一个下一个即可得flag:

flag{6fde4163df05d900}

攻防世界之转轮机加密:(转轮机加密、)

下载附件:

CTF密码学总结(一)_第7张图片

好了,记住了,以后这个内容格式的就是转轮机加密了:

CTF密码学总结(一)_第8张图片

原理就是转齿轮把一个字母换成另一个,直接上一个修改后的大佬脚本:

rotor = [ #这里是要输入的转轮机原始字符串

"ZWAXJGDLUBVIQHKYPNTCRMOSFE", "KPBELNACZDTRXMJQOYHGVSFUWI",

"BDMAIZVRNSJUWFHTEQGYXPLOCK", "RPLNDVHGFCUKTEBSXQYIZMJWAO",

"IHFRLABEUOTSGJVDKCPMNZQWXY", "AMKGHIWPNYCJBFZDRUSLOQXVET",

"GWTHSPYBXIZULVKMRAFDCEONJQ", "NOZUTWDCVRJLXKISEFAPMYGHBQ",

"XPLTDSRFHENYVUBMCQWAOIKZGJ", "UDNAJFBOWTGVRSCZQKELMXYIHP",

"MNBVCXZQWERTPOIUYALSKDJFHG", "LVNCMXZPQOWEIURYTASBKJDFHG",

"JZQAWSXCDERFVBGTYHNUMKILOP"

]

cipher = "NFQKSEVOQOFNP" #这是要输入转轮机密文

key = [2,3,7,5,13,12,9,1,8,10,4,11,6] #这是要输入转轮机密钥

tmp_list=[]

for i in range(0, len(rotor)):

tmp=""

k = key[i] - 1

for j in range(0, len(rotor[k])):

if cipher[i] == rotor[k][j]:

if j == 0:

tmp=rotor[k]

break

else:

tmp=rotor[k][j:] + rotor[k][0:j]

break

tmp_list.append(tmp)

# print(tmp_list)

message_list = []

for i in range(0, len(tmp_list[i])):

tmp = ""

for j in range(0, len(tmp_list)):

tmp += tmp_list[j][i]

message_list.append(tmp)

print(message_list)

def spread_list(lst):

for item in lst:

if isinstance(item,(list,tuple)):

yield from spread_list(item)

else:

yield item

pass

if __name__ == '__main__':

for i in spread_list(message_list):

print("*"*25)

print(i) #在多个输出中查找有语义的字符串即为flag内容

复杂加密类型

ECC椭圆曲线加密:

攻防世界 之easy_ECC:(ECC加密)

下载附件,打开:

CTF密码学总结(一)_第9张图片

CTF密码学总结(一)_第10张图片

椭圆曲线ECC加密,没接触过,不懂原理,主要是找不到集成脚本,算了,浏览中发现一篇讲得透彻的博客:

https://blog.csdn.net/weixin_30951231/article/details/95919343

这里直接使用脚本:

#!/usr/bin/env python3

# -*- coding: UTF-8 -*-

# @Time :2020/9/28

# @Author :PeterJoin

import collections

import random

EllipticCurve = collections.namedtuple('EllipticCurve', 'name p a b g n h')

def banner():

print(("""%s

_____ ____ ____

| ____/ ___/ ___|

| _|| | | |

| |__| |__| |___

|_____\____\____|

%s%s

# Coded By PeterJoin -椭圆曲线加密(´・ω・)%s

""" % ('\033[91m', '\033[0m', '\033[93m', '\033[0m')))

curve = EllipticCurve(

'secp256k1',

# Field characteristic.

p=int(input('p=')),

# Curve coefficients.

a=int(input('a=')),

b=int(input('b=')),

# Base point.

g=(int(input('Gx=')),

int(input('Gy='))),

# Subgroup order.

n=int(input('k=')),

# Subgroup cofactor.

h=1,

)

# Modular arithmetic ##########################################################

def inverse_mod(k, p):

"""Returns the inverse of k modulo p.

This function returns the only integer x such that (x * k) % p == 1.

k must be non-zero and p must be a prime.

"""

if k == 0:

raise ZeroDivisionError('division by zero')

if k < 0:

# k ** -1 = p - (-k) ** -1 (mod p)

return p - inverse_mod(-k, p)

# Extended Euclidean algorithm.

s, old_s = 0, 1

t, old_t = 1, 0

r, old_r = p, k

while r != 0:

quotient = old_r // r

old_r, r = r, old_r - quotient * r

old_s, s = s, old_s - quotient * s

old_t, t = t, old_t - quotient * t

gcd, x, y = old_r, old_s, old_t

assert gcd == 1

assert (k * x) % p == 1

return x % p

# Functions that work on curve points #########################################

def is_on_curve(point):

"""Returns True if the given point lies on the elliptic curve."""

if point is None:

# None represents the point at infinity.

return True

x, y = point

return (y * y - x * x * x - curve.a * x - curve.b) % curve.p == 0

def point_neg(point):

"""Returns -point."""

assert is_on_curve(point)

if point is None:

# -0 = 0

return None

x, y = point

result = (x, -y % curve.p)

assert is_on_curve(result)

return result

def point_add(point1, point2):

"""Returns the result of point1 + point2 according to the group law."""

assert is_on_curve(point1)

assert is_on_curve(point2)

if point1 is None:

# 0 + point2 = point2

return point2

if point2 is None:

# point1 + 0 = point1

return point1

x1, y1 = point1

x2, y2 = point2

if x1 == x2 and y1 != y2:

# point1 + (-point1) = 0

return None

if x1 == x2:

# This is the case point1 == point2.

m = (3 * x1 * x1 + curve.a) * inverse_mod(2 * y1, curve.p)

else:

# This is the case point1 != point2.

m = (y1 - y2) * inverse_mod(x1 - x2, curve.p)

x3 = m * m - x1 - x2

y3 = y1 + m * (x3 - x1)

result = (x3 % curve.p,

-y3 % curve.p)

assert is_on_curve(result)

return result

def scalar_mult(k, point):

"""Returns k * point computed using the double and point_add algorithm."""

assert is_on_curve(point)

if k < 0:

# k * point = -k * (-point)

return scalar_mult(-k, point_neg(point))

result = None

addend = point

while k:

if k & 1:

# Add.

result = point_add(result, addend)

# Double.

addend = point_add(addend, addend)

k >>= 1

assert is_on_curve(result)

return result

# Keypair generation and ECDHE ################################################

def make_keypair():

"""Generates a random private-public key pair."""

private_key = curve.n

public_key = scalar_mult(private_key, curve.g)

return private_key, public_key

private_key, public_key = make_keypair()

print("private key:", hex(private_key))

print("public key: (0x{:x}, 0x{:x})".format(*public_key))

if __name__ == '__main__':

banner()

make_keypair()

运行之后照着输入题目附件给的参数即可:

CTF密码学总结(一)_第11张图片

解出的x+y就是flag了,原理太难了,以后有机会再接触。

python类型逻辑加密

pyc文件反编译:

攻防世界之easychallenge:(源代码修改逻辑解密、)

下载附件,是pyc文件,于是要反编译,一开始看资料说用uncompyle6,我也不知道为什么我的老是报错,后来又找了个在线反编译,可以支持的Python版本比较多:

https://tool.lu/pyc/

反编译代码:

#!/usr/bin/env python

# visit https://tool.lu/pyc/ for more information

import base64

def encode1(ans):

s = ""

for i in ans:

x = ord(i) ^ 36

x = x + 25

s += chr(x)

return s

def encode2(ans):

s = ""

for i in ans:

x = ord(i) + 36

x = x ^ 36

s += chr(x)

return s

def encode3(ans):

return base64.b32encode(ans)

flag = " "

print "Please Input your flag:"

flag = raw_input()

final = "UC7KOWVXWVNKNIC2XCXKHKK2W5NLBKNOUOSK3LNNVWW3E==="

if encode3(encode2(encode1(flag))) == final:

print "correct"

else:

print "wrong"

本来是自己一层层改的,怎么加密就怎么逆过来解密,后来发现又犯了以前的错误,有源码就要用源码啊!!!

直接在源码上修改即可:

#!/usr/bin/env python

# visit https://tool.lu/pyc/ for more information

import base64

def decode1(ans):

s = ''

for i in ans:

x = ord(i) -25

x = x ^ 36

s += chr(x)

return s

def decode2(ans):

s = ''

for i in ans:

x = i ^ 36

x = x - 36

s += chr(x)

return s

def decode3(ans):

return base64.b32decode(ans)

final = 'UC7KOWVXWVNKNIC2XCXKHKK2W5NLBKNOUOSK3LNNVWW3E==='

print(decode1(decode2(decode3(final))) )

传统密码类型解析

凯撒密码(24个字母):

特点:24个字母间的移动

在密码学中,恺撒密码(英语:Caesar cipher),或称恺撒加密、恺撒变换、变换加密,是一种最简单且最广为人知的加密技术。它是一种替换加密的技术,明文中的所有字母都在字母表上向后(或向前)按照一个固定数目进行偏移后被替换成密文。例如,当偏移量是3的时候,所有的字母A将被替换成D,B变成E,以此类推。

加密就是明文向后移动展现出对应的密文。

解密就是密文向前移动展现出对应的明文。

明文字母表

A

B

C

D

E

F

G

H

I

J

K

L

M

N

O

P

Q

R

S

T

U

V

W

X

Y

Z

密文字母表

A

B

C

D

E

F

G

H

I

J

K

L

M

N

O

P

Q

R

S

T

U

V

W

X

Y

Z

摩斯密码(只有01(无规则)或.-,空格或/做分隔符):

摩尔斯电码也被称作摩斯密码,是一种时通时断的信号代码,通过不同的排列顺序来表达不同的英文字母、数字和标点符号。它发明于1837年,是一种早期的数字化通信形式。不同于现代化的数字通讯,摩尔斯电码只使用零和一两种状态的二进制代码,它的代码包括五种:短促的点信号“・”,读“滴”(Di)保持一定时间的长信号“-”,读“嗒”(Da)表示点和划之间的停顿、每个词之间中等的停顿,以及句子之间长的停顿。

摩斯电码:(格式要求:可用空格或单斜杠/来分隔摩斯电码,但只可用一种,不可混用)

CTF密码学总结(一)_第12张图片

云影密码(01248):

此密码运用了1248代码,因为本人才疏学法,问未发现有过使用的先例,因此暂归为原创密码。由于这个密码,我和片风云影初识,为了纪念,将其命名为“云影密码”。

有了1,2,4,8这四个苘单的数字,你可以以加法表示出0~9任何个数字,例如0=28,7=124,9=18这样,再用1-26来表示A-Z,就可以用作密码了。为了不至于混乱,我个人引入了第五个数字0,来用作间隔,以遍免翻译错误,所以还可以称“01248密码”

注意(3个及以上数字时):

虽然是相加,但是可以在数字内不按顺序相加,如124可写成(12)4和1(24)结果分别是7和16,只要保证不大于26即可

题目(总不超过26):

12401011801180212011401804

第一步分割:

即124 、1、118、118、212、114、18、4

第二步基本翻译:

例如124可以表示7,也可以表示16(但不可能是34,因为不会超过26),所以可以放弃来翻译其他没有异议的,可得:124、a、s、s、w、o、18、d

第三步推测得出明文:

可以推测后面的18表示r,前面的为p最合适。

所以最后明文:

password(密码)

栅栏密码(分组数作密钥):

所谓栅栏密码,就是把要加密的明文分成N个一组,然后把每组的第1个字连起来,形成一段无规律的话。 不过栅栏密码本身有一个潜规则,就是组成栅栏的字母一般不会太多。(一般不超过30个,也就是一、两句话)

传统栅栏密码(矩阵行列,密钥是行数):

假如有一个字符串:123456789

取字符串长度的因数进行分组,假如key=3

1 2 3 \\分组情况,每三个数字一组,分为三组

4 5 6

7 8 9

然后每一组依次取一个数字组成一个新字符串:147258369 \\加密完成的字符串

解题:

试一般的栅栏密码,取5为矩阵行数,得到" cyperrocaegireeol} eahfocec gnbip不正确,取5为矩阵列数,得到" cebgccfe en eohplprgecrayoii aoreg”,也不正确,除了常规的栅栏密码,还有一种w型的栅栏密码。

w型的栅栏密码(第一行是Key数,后面排成w型横竖读取):

同样一个字符串:123456789

key=3

1----5----9 \\让数字以W型组织,同样是三组,但每组的数量不一定相同

-2--4-6--8

--3----7--

加密密文:159246837

解题:

题目提示:栅栏密码,密钥长度为5

是将明文按照w型排列,并横(竖)向读取密文,其解密过程就是加密的逆过程,即将密文横(竖)向按一定规律排列后,以w型读取,对于此题,根据题目提示为以下5行。

CTF密码学总结(一)_第13张图片

培根密码(大小写的ABab,而且必须是5个一组,不是5个就考虑摩斯密码):

培根所用的密码是一种本质上用二进制数设计的,没有用通常的0和1来表示,而是采用a和b

培根密码加密方式

第一种方式:

A aaaaa B aaaab C aaaba D aaabb E aabaa F aabab G aabba H aabbb I abaaa J abaab

K ababa L ababb M abbaa N abbab O abbba P abbbb Q baaaa R baaab S baaba T baabb

U babaa V babab W babba X babbb Y bbaaa Z bbaab

第二种方式:

a AAAAA g AABBA n ABBAA t BAABA

b AAAAB h AABBB o ABBAB u-v BAABB

c AAABA i-j ABAAA p ABBBA w BABAA

d AAABB k ABAAB q ABBBB x BABAB

e AABAA l ABABA r BAAAA y BABBA

f AABAB m ABABB s BAAAB z BABBB

举例

    例1、 baabaaabbbabaaabbaaaaaaaaabbabaaaabaaaaaabaaabaabaaaabaabbbaabbbaababb

             baaba aabbb abaaa bbaaa aaaaa abbab aaaab aaaaa abaaa baaba  aaaba abbba abbba ababb

                s           h         i           y         a         n         b         a        i           s          c         o          o        l 

附加解密Python脚本如下:

#!/usr/bin/python

# -*- coding: utf-8 -*-

import re

alphabet = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']

first_cipher = ["aaaaa","aaaab","aaaba","aaabb","aabaa","aabab","aabba","aabbb","abaaa","abaab","ababa","ababb","abbaa","abbab","abbba","abbbb","baaaa","baaab","baaba","baabb","babaa","babab","babba","babbb","bbaaa","bbaab"]

second_cipher = ["aaaaa","aaaab","aaaba","aaabb","aabaa","aabab","aabba","aabbb","abaaa","abaaa","abaab","ababa","ababb","abbaa","abbab","abbba","abbbb","baaaa","baaab","baaba","baabb","baabb","babaa","babab","babba","babbb"]

def encode():

string = raw_input("please input string to encode:\n") #这里接收要加密的字符串

e_string1 = ""

e_string2 = ""

for index in string:

for i in range(0,26):

if index == alphabet[i]:

e_string1 += first_cipher[i]

e_string2 += second_cipher[i]

break

print "first encode method result is:\n"+e_string1

print "second encode method result is:\n"+e_string2

return

def decode():

e_string = raw_input("please input string to decode:\n") #这里接收要解密的字符串

e_array = re.findall(".{5}",e_string)

d_string1 = ""

d_string2 = ""

for index in e_array:

for i in range(0,26):

if index == first_cipher[i]:

d_string1 += alphabet[i]

if index == second_cipher[i]:

d_string2 += alphabet[i]

print "first decode method result is:\n"+d_string1

print "second decode method result is:\n"+d_string2

return

if __name__ == '__main__':

while True:

print "\t*******Bacon Encode_Decode System*******"

print "input should be lowercase,cipher just include a b"

print "1.encode\n2.decode\n3.exit"

s_number = raw_input("please input number to choose\n")

if s_number == "1":

encode()

raw_input()

elif s_number == "2":

decode()

raw_input()

elif s_number == "3":

break

else:

continue

与佛论禅编码,要加上佛曰:才能转换(BASE64类型转不了就ROT13一下)

网址:

与佛论禅

题目文字:

夜哆悉諳多苦奢陀奢諦冥神哆盧穆皤三侄三即諸諳即冥迦冥隸數顛耶迦奢若吉怯陀諳怖奢智侄諸若奢數菩奢集遠俱老竟寫明奢若梵等盧皤豆蒙密離怯婆皤礙他哆提哆多缽以南哆心曰姪罰蒙呐神。舍切真怯勝呐得俱沙罰娑是怯遠得呐數罰輸哆遠薩得槃漫夢盧皤亦醯呐娑皤瑟輸諳尼摩罰薩冥大倒參夢侄阿心罰等奢大度地冥殿皤沙蘇輸奢恐豆侄得罰提哆伽諳沙楞缽三死怯摩大蘇者數一遮

转换后的

MzkuM3gvMUAwnzuvn3cgozMlMTuvqzAenJchMUAeqzWenzEmLJW9

的确是BASE64类型,但是直接BASE64是转换不出来的,还要先ROT13一下,可以算是一个小混淆,长见识了。

转轮机加密:

特点是等长的分好组的乱序字母,原理是转齿轮把一个字母换成另一个来拼成一句话。

格式是这样的:

CTF密码学总结(一)_第14张图片

脚本解题积累:

rotor = [ #这里是要输入的转轮机原始字符串

"ZWAXJGDLUBVIQHKYPNTCRMOSFE", "KPBELNACZDTRXMJQOYHGVSFUWI",

"BDMAIZVRNSJUWFHTEQGYXPLOCK", "RPLNDVHGFCUKTEBSXQYIZMJWAO",

"IHFRLABEUOTSGJVDKCPMNZQWXY", "AMKGHIWPNYCJBFZDRUSLOQXVET",

"GWTHSPYBXIZULVKMRAFDCEONJQ", "NOZUTWDCVRJLXKISEFAPMYGHBQ",

"XPLTDSRFHENYVUBMCQWAOIKZGJ", "UDNAJFBOWTGVRSCZQKELMXYIHP",

"MNBVCXZQWERTPOIUYALSKDJFHG", "LVNCMXZPQOWEIURYTASBKJDFHG",

"JZQAWSXCDERFVBGTYHNUMKILOP"

]

cipher = "NFQKSEVOQOFNP" #这是要输入转轮机密文

key = [2,3,7,5,13,12,9,1,8,10,4,11,6] #这是要输入转轮机密钥

tmp_list=[]

for i in range(0, len(rotor)):

tmp=""

k = key[i] - 1

for j in range(0, len(rotor[k])):

if cipher[i] == rotor[k][j]:

if j == 0:

tmp=rotor[k]

break

else:

tmp=rotor[k][j:] + rotor[k][0:j]

break

tmp_list.append(tmp)

# print(tmp_list)

message_list = []

for i in range(0, len(tmp_list[i])):

tmp = ""

for j in range(0, len(tmp_list)):

tmp += tmp_list[j][i]

message_list.append(tmp)

print(message_list)

def spread_list(lst):

for item in lst:

if isinstance(item,(list,tuple)):

yield from spread_list(item)

else:

yield item

pass

if __name__ == '__main__':

for i in spread_list(message_list):

print("*"*25)

print(i) #在多个输出中查找有语义的字符串即为flag内容

URL编码规则:

URL 编码使用 "%" 其后跟随两位的十六进制数来替换非 ASCII 字符。

ASCII Value

URL-encode

ASCII Value

URL-encode

ASCII Value

URL-encode

ASCII Value

URL-encode

ASCII Value

URL-encode

ASCII Value

URL-encode

NULL结束符

%00

0

%30

`

%60

%90

À

%c0

ð

%f0

%01

1

%31

a

%61

%91

Á

%c1

ñ

%f1

%02

2

%32

b

%62

%92

Â

%c2

ò

%f2

%03

3

%33

c

%63

%93

Ã

%c3

ó

%f3

%04

4

%34

d

%64

%94

Ä

%c4

ô

%f4

%05

5

%35

e

%65

%95

Å

%c5

õ

%f5

%06

6

%36

f

%66

%96

Æ

%c6

ö

%f6

%07

7

%37

g

%67

%97

Ç

%c7

÷

%f7

backspace

%08

8

%38

h

%68

˜

%98

È

%c8

ø

%f8

tab

%09

9

%39

i

%69

%99

É

%c9

ù

%f9

换行符

%0a

:

%3a

j

%6a

š

%9a

Ê

%ca

ú

%fa

%0b

;

%3b

k

%6b

%9b

Ë

%cb

û

%fb

%0c

<

%3c

l

%6c

œ

%9c

Ì

%cc

ü

%fc

c return

%0d

=

%3d

m

%6d

%9d

Í

%cd

ý

%fd

%0e

>

%3e

n

%6e

ž

%9e

Î

%ce

þ

%fe

%0f

?

%3f

o

%6f

Ÿ

%9f

Ï

%cf

ÿ

%ff

%10

@

%40

p

%70

%a0

Ð

%d0

%11

A

%41

q

%71

¡

%a1

Ñ

%d1

%12

B

%42

r

%72

¢

%a2

Ò

%d2

%13

C

%43

s

%73

£

%a3

Ó

%d3

%14

D

%44

t

%74

%a4

Ô

%d4

%15

E

%45

u

%75

¥

%a5

Õ

%d5

%16

F

%46

v

%76

|

%a6

Ö

%d6

%17

G

%47

w

%77

§

%a7

%d7

%18

H

%48

x

%78

¨

%a8

Ø

%d8

%19

I

%49

y

%79

©

%a9

Ù

%d9

%1a

J

%4a

z

%7a

ª

%aa

Ú

%da

%1b

K

%4b

{

%7b

«

%ab

Û

%db

%1c

L

%4c

|

%7c

¬

%ac

Ü

%dc

%1d

M

%4d

}

%7d

¯

%ad

Ý

%dd

%1e

N

%4e

~

%7e

®

%ae

Þ

%de

%1f

O

%4f

%7f

¯

%af

ß

%df

空格

%20

P

%50

%80

°

%b0

à

%e0

!

%21

Q

%51

%81

±

%b1

á

%e1

"

%22

R

%52

%82

²

%b2

â

%e2

#

%23

S

%53

ƒ

%83

³

%b3

ã

%e3

$

%24

T

%54

%84

´

%b4

ä

%e4

%

%25

U

%55

%85

µ

%b5

å

%e5

&

%26

V

%56

%86

%b6

æ

%e6

'

%27

W

%57

%87

·

%b7

ç

%e7

(

%28

X

%58

ˆ

%88

¸

%b8

è

%e8

)

%29

Y

%59

%89

¹

%b9

é

%e9

*

%2a

Z

%5a

Š

%8a

º

%ba

ê

%ea

+

%2b

[

%5b

%8b

»

%bb

ë

%eb

,

%2c

\

%5c

Œ

%8c

¼

%bc

ì

%ec

-

%2d

]

%5d

%8d

½

%bd

í

%ed

.

%2e

^

%5e

Ž

%8e

¾

%be

î

%ee

/

%2f

_

%5f

%8f

¿

%bf

ï

%ef

解密工具、脚本积累

Ciphey工具:

Ciphey 是一个使用自然语言处理和人工智能的全自动解密/解码/破解工具,只需要输入加密文本,它就能给你返回解密文本。

Ciphey 基本使用:

文件输入:

ciphey -f encrypted.txt

# 或

python -m ciphey -f encrypted.txt

不规范的方法:

ciphey -- "Encrypted input"

# 或

python -m ciphey -- "Encrypted input"

正常方式:

ciphey -t "Encrypted input"

# 或

python -m ciphey -t "Encrypted input"

要去除进度条、概率表和所有噪音,请使用安静模式:

ciphey -t "encrypted text here" -q

Ciphey 支持解密的密文和编码多达51种,下面列出一些基本的选项基本密码:

Caesar Cipher

ROT47 (up to ROT94 with the ROT47 alphabet)

ASCII shift (up to ROT127 with the full ASCII alphabet)

Vigenère Cipher

Affine Cipher

Binary Substitution Cipher (XY-Cipher)

Baconian Cipher (both variants)

Soundex

Transposition Cipher

Pig Latin

现代密码学:

Repeating-key XOR

Single XOR

编码:

Base32

Base64

Z85 (release candidate stage)

Base65536 (release candidate stage)

ASCII

Reversed text

Morse Code

DNA codons (release candidate stage)

Atbash

Standard Galactic Alphabet (aka Minecraft Enchanting Language)

Leetspeak

Baudot ITA2

URL encoding

SMS Multi-tap

DMTF (release candidate stage)

UUencode

Braille (Grade 1)

Ciphey 的功能不仅于本文介绍的这些,本文所介绍的只是冰山一角,它还可以添加属于你自己的解码器:

https://github.com/Ciphey/Ciphey/wiki/Adding-your-own-ciphers

CTF-RSA-tool工具:

RSA前景知识:

RSA公开密钥密码体制是一种使用不同的加密密钥与解密密钥,“由已知加密密钥推导出解密密钥在计算上是不可行的”密码体制 。

在公开密钥密码体制中,加密密钥(即公开密钥)PK是公开信息,而解密密钥(即秘密密钥)SK是需要保密的。加密算法E和解密算法D也都是公开的。虽然解密密钥SK是由公开密钥PK决定的,但却不能根据PK计算出SK [2] 。

RSA公开密钥密码体制的原理是:根据数论,寻求两个大素数比较简单,而将它们的乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥 [4] 。

CTF密码学总结(一)_第15张图片

RSA脚本工具使用说明:

usage: solve.py [-h]

用法:solve.py[-h] (--decrypt DECRYPT | -c DECRYPT_INT | --private | -i INPUT | -g)

[--createpub] [-o OUTPUT] [--dumpkey] [--enc2dec ENC2DEC] [-k KEY] [-N N] [-e E] [-d D] [-p P] [-q Q] [--KHBFA KHBFA][--pbits PBITS]

[-v]

It helps CTFer to get first blood of RSA-base CTF problems 它有助于CTFer获得RSA基础CTF问题的第一滴血

-v, --verbose print details 详细的打印细节

optional arguments:可选参数(注意!!!这里之间只可选一个,且必选一个!):

-h, --help show this help message and exit --帮助显示此帮助消息并退出

--decrypt DECRYPT decrypt a file, usually like "flag.enc" 解密文件,通常类似于“flag.enc”

(通常搭配k的.pem或.pub一起使用)

-c DECRYPT_INT,

--decrypt_int DECRYPT_INT 解密长整形数

--private Print private key if recovered 打印私钥(如果已解密)

-i INPUT input a file with all necessary parameters (see examples/input_example.txt)

输入包含所有必要参数的文件(请参见示例/输入(示例.txt)

-g, --gadget Use some gadgets to pre-process your data first 使用一些小工具先预处理数据

some gadgets:一些小工具预处理数据(全部可选):

--createpub Take N and e and output to file specified by "-o" or just print it

获取N和e并输出到由“-o”指定的文件或者直接打印出来就行了

-o OUTPUT, --output OUTPUT 输出 Specify the output file path in --createpub mode.

在--createpub模式下指定输出文件路径。

--dumpkey Just print the RSA variables from a key - n,e,d,p,q

只打印一个key-n、e、d、p、q中的RSA变量

--enc2dec ENC2DEC get cipher (in decimalism) from a encrypted file

从加密文件中获取密码(十进制)

the RSA variables:RSA变量:Specify the variables whatever you got指定您得到的变量:(全部可选,实验中发现输入时只能用N、e参数进行命令行输入)

-k KEY, pem file, usually like ".pub" or ".pem", and it begins with "-----BEGIN"

pem文件,通常类似于“.pub”或“.pem”,并以“-----BEGIN”开始

-N N the modulus 模量

-e E the public exponent 公共指数

-d D the private exponent 私人指数

-p P one factor of modulus 模量的一个因子

-q Q one factor of modulus 模量的一个因子

extra variables:额外变量:Used in some special methods 在一些特殊的方法中使用:

--KHBFA KHBFA use Known High Bits Factor Attack, this specify the High Bits of factor

使用已知的高位因子攻击,这指定因子高位

--pbits PBITS customize the bits lenth of factor, default is half of n`s bits lenth

自定义因子的位长度,默认值为n's比特长度

多组n,e,c在解题时长这个样子:

CTF密码学总结(一)_第16张图片

CTF密码学总结(一)_第17张图片

CTF密码学总结(一)_第18张图片

可以看到特征真的就是多个n,e,c,甚至还有d,且不管这里的n,e,c是大还是小,长还是短,都列入多组n,e,c类型里。

一组n,e,c的题目样式:

从这里可以看到一组,n,e,c里面甚至可以没有c,这里的n,e,c也不管大小,长短,这里最后一个hbop的解题要用到前面说得sagemath,这里暂且不说。

脚本类型示例:

补充:

单个n,e,c,q,p,的时候最好用单个参数输入的方式,不要用文本读取的方式,因为文本读取的时候DEBUG显示的十六进制的d有时并不是我们想要的

# 只需要一组密钥的

# wiener_attack

python2 solve.py --verbose -i examples/wiener_attack.txt

# 或者通过命令行,只要指定对应参数就行了

python2 solve.py --verbose --private -N 460657813884289609896372056585544172485318117026246263899744329237492701820627219556007788200590119136173895989001382151536006853823326382892363143604314518686388786002989248800814861248595075326277099645338694977097459168530898776007293695728101976069423971696524237755227187061418202849911479124793990722597 -e 354611102441307572056572181827925899198345350228753730931089393275463916544456626894245415096107834465778409532373187125318554614722599301791528916212839368121066035541008808261534500586023652767712271625785204280964688004680328300124849680477105302519377370092578107827116821391826210972320377614967547827619

# factordb.com

python2 solve.py --verbose -k examples/jarvis_oj_mediumRSA/pubkey.pem --decrypt examples/jarvis_oj_mediumRSA/flag.enc

CTF密码学总结(一)_第19张图片

CTF密码学总结(一)_第20张图片

CTF密码学总结(一)_第21张图片

# Boneh and Durfee attack

# TODO: get an example public key solvable by boneh_durfee but not wiener

# small q attack

python2 solve.py --verbose --private -k examples/small_q.pub

CTF密码学总结(一)_第22张图片

# 2017强网杯线上赛 RSA 费马分解(p&q相近时)

python2 solve.py --verbose -i examples/closed_p_q.txt

# Common factor between ciphertext and modulus attack

python2 solve.py --verbose -k examples/common_factor.pub --decrypt examples/common_factor.cipher

CTF密码学总结(一)_第23张图片

CTF密码学总结(一)_第24张图片

# small e

python2 solve.py --verbose -k examples/small_exponent.pub --decrypt examples/small_exponent.cipher

CTF密码学总结(一)_第25张图片

CTF密码学总结(一)_第26张图片

# rabin method when e == 2

python2 solve.py --verbose -k examples/jarvis_oj_hardRSA/pubkey.pem --decrypt examples/jarvis_oj_hardRSA/flag.enc

CTF密码学总结(一)_第27张图片

CTF密码学总结(一)_第28张图片

CTF密码学总结(一)_第29张图片

# Small fractions method when p/q is close to a small fraction

python2 solve.py --verbose -k examples/smallfraction.pub --private

CTF密码学总结(一)_第30张图片

# Known High Bits Factor Attack

python2 solve.py --verbose -i examples/KnownHighBitsFactorAttack.txt

# 需要多组密钥的

# 第三届上海市大学生网络安全大赛--rrrsa d泄漏攻击

python2 solve.py --verbose -i examples/d_leak.txt

CTF密码学总结(一)_第31张图片

# 模不互素

python2 solve.py --verbose -i examples/share_factor.txt

# 共模攻击

python2 solve.py --verbose -i examples/share_N.txt

CTF密码学总结(一)_第32张图片

# Basic Broadcast Attack(低加密指数广播攻击)

python2 solve.py --verbose -i examples/Basic_Broadcast_Attack.txt

CTF密码学总结(一)_第33张图片

ECC加密:

介绍:

椭圆曲线密码学(英语:Elliptic curve cryptography,缩写为 ECC),一种建立公开密钥加密的算法,基于椭圆曲线数学。

ECC的主要优势是在某些情况下它比其他的方法使用更小的密钥——比如RSA加密算法——提供相当的或更高等级的安全。ECC的另一个优势是可以定义群之间的双线性映射,基于Weil对或是Tate对;双线性映射已经在密码学中发现了大量的应用,例如基于身份的加密。其缺点是同长度密钥下加密和解密操作的实现比其他机制花费的时间长 [1] ,但由于可以使用更短的密钥达到同级的安全程度,所以同级安全程度下速度相对更快。一般认为160比特的椭圆曲线密钥提供的安全强度与1024比特RSA密钥相当。

关键总结:

设私钥、公钥分别为k、K,即K = kG,其中G为G点。

  公钥加密:

  选择随机数r,将消息M生成密文C,该密文是一个点对,即:

  C = {rG, M+rK},其中K为公钥

  私钥解密:

  M + rK - k(rG) = M + r(kG) - k(rG) = M

  其中k、K分别为私钥、公钥。

题目样式举例:

CTF密码学总结(一)_第34张图片

ECC脚本积累(解出最后的公钥和私钥即可):

import collections

import random

EllipticCurve = collections.namedtuple('EllipticCurve', 'name p a b g n h')

curve = EllipticCurve(

'secp256k1',

# Field characteristic.

p=int(input('p=')),

# Curve coefficients.

a=int(input('a=')),

b=int(input('b=')),

# Base point.

g=(int(input('Gx=')),

int(input('Gy='))),

# Subgroup order.

n=int(input('k=')),

# Subgroup cofactor.

h=1,

)

# Modular arithmetic ##########################################################

def inverse_mod(k, p):

"""Returns the inverse of k modulo p.

This function returns the only integer x such that (x * k) % p == 1.

k must be non-zero and p must be a prime.

"""

if k == 0:

raise ZeroDivisionError('division by zero')

if k < 0:

# k ** -1 = p - (-k) ** -1 (mod p)

return p - inverse_mod(-k, p)

# Extended Euclidean algorithm.

s, old_s = 0, 1

t, old_t = 1, 0

r, old_r = p, k

while r != 0:

quotient = old_r // r

old_r, r = r, old_r - quotient * r

old_s, s = s, old_s - quotient * s

old_t, t = t, old_t - quotient * t

gcd, x, y = old_r, old_s, old_t

assert gcd == 1

assert (k * x) % p == 1

return x % p

# Functions that work on curve points #########################################

def is_on_curve(point):

"""Returns True if the given point lies on the elliptic curve."""

if point is None:

# None represents the point at infinity.

return True

x, y = point

return (y * y - x * x * x - curve.a * x - curve.b) % curve.p == 0

def point_neg(point):

"""Returns -point."""

assert is_on_curve(point)

if point is None:

# -0 = 0

return None

x, y = point

result = (x, -y % curve.p)

assert is_on_curve(result)

return result

def point_add(point1, point2):

"""Returns the result of point1 + point2 according to the group law."""

assert is_on_curve(point1)

assert is_on_curve(point2)

if point1 is None:

# 0 + point2 = point2

return point2

if point2 is None:

# point1 + 0 = point1

return point1

x1, y1 = point1

x2, y2 = point2

if x1 == x2 and y1 != y2:

# point1 + (-point1) = 0

return None

if x1 == x2:

# This is the case point1 == point2.

m = (3 * x1 * x1 + curve.a) * inverse_mod(2 * y1, curve.p)

else:

# This is the case point1 != point2.

m = (y1 - y2) * inverse_mod(x1 - x2, curve.p)

x3 = m * m - x1 - x2

y3 = y1 + m * (x3 - x1)

result = (x3 % curve.p,

-y3 % curve.p)

assert is_on_curve(result)

return result

def scalar_mult(k, point):

"""Returns k * point computed using the double and point_add algorithm."""

assert is_on_curve(point)

if k < 0:

# k * point = -k * (-point)

return scalar_mult(-k, point_neg(point))

result = None

addend = point

while k:

if k & 1:

# Add.

result = point_add(result, addend)

# Double.

addend = point_add(addend, addend)

k >>= 1

assert is_on_curve(result)

return result

# Keypair generation and ECDHE ################################################

def make_keypair():

"""Generates a random private-public key pair."""

private_key = curve.n

public_key = scalar_mult(private_key, curve.g)

return private_key, public_key

private_key, public_key = make_keypair()

print("private key:", hex(private_key))

print("public key: (0x{:x}, 0x{:x})".format(*public_key))

你可能感兴趣的:(笔记,ctf)