攻防世界 crypto入门WP
攻防世界 crypto入门WP
前言
下学期要求密码和Re,现在这俩几乎是空白,趁着暑假的功夫,最近也能闲下来,就学一学crypto
,其实真正接触发现挺有意思的,各种密码的加密千奇百怪,层出不穷,也是需要慢慢积累经验,花了一天时间把攻防世界的密码入门全做了,这里简单说一下自己做的时候的思路,顺便练习python…python实在没学好,自己太辣鸡了。。。一些特别基础的就带过来,就写一些自己还没那么熟悉的
正文
混合编码
JiM3NjsmIzEyMjsmIzY5OyYjMTIwOyYjNzk7JiM4MzsmIzU2OyYjMTIwOyYjNzc7JiM2ODsmIzY5OyYjMTE4OyYjNzc7JiM4NDsmIzY1OyYjNTI7JiM3NjsmIzEyMjsmIzEwNzsmIzUzOyYjNzY7JiMxMjI7JiM2OTsmIzEyMDsmIzc3OyYjODM7JiM1NjsmIzEyMDsmIzc3OyYjNjg7JiMxMDc7JiMxMTg7JiM3NzsmIzg0OyYjNjU7JiMxMjA7JiM3NjsmIzEyMjsmIzY5OyYjMTIwOyYjNzg7JiMxMDU7JiM1NjsmIzEyMDsmIzc3OyYjODQ7JiM2OTsmIzExODsmIzc5OyYjODQ7JiM5OTsmIzExODsmIzc3OyYjODQ7JiM2OTsmIzUwOyYjNzY7JiMxMjI7JiM2OTsmIzEyMDsmIzc4OyYjMTA1OyYjNTY7JiM1MzsmIzc4OyYjMTIxOyYjNTY7JiM1MzsmIzc5OyYjODM7JiM1NjsmIzEyMDsmIzc3OyYjNjg7JiM5OTsmIzExODsmIzc5OyYjODQ7JiM5OTsmIzExODsmIzc3OyYjODQ7JiM2OTsmIzExOTsmIzc2OyYjMTIyOyYjNjk7JiMxMTk7JiM3NzsmIzY3OyYjNTY7JiMxMjA7JiM3NzsmIzY4OyYjNjU7JiMxMTg7JiM3NzsmIzg0OyYjNjU7JiMxMjA7JiM3NjsmIzEyMjsmIzY5OyYjMTE5OyYjNzc7JiMxMDU7JiM1NjsmIzEyMDsmIzc3OyYjNjg7JiM2OTsmIzExODsmIzc3OyYjODQ7JiM2OTsmIzExOTsmIzc2OyYjMTIyOyYjMTA3OyYjNTM7JiM3NjsmIzEyMjsmIzY5OyYjMTE5OyYjNzc7JiM4MzsmIzU2OyYjMTIwOyYjNzc7JiM4NDsmIzEwNzsmIzExODsmIzc3OyYjODQ7JiM2OTsmIzEyMDsmIzc2OyYjMTIyOyYjNjk7JiMxMjA7JiM3ODsmIzY3OyYjNTY7JiMxMjA7JiM3NzsmIzY4OyYjMTAzOyYjMTE4OyYjNzc7JiM4NDsmIzY1OyYjMTE5Ow==
密码的题很多就是给你个txt,好评,上来给你一串字符,判断为base64
,那么先base64decode
一下,得到:
LzExOS8xMDEvMTA4Lzk5LzExMS8xMDkvMTAxLzExNi8xMTEvOTcvMTE2LzExNi85Ny85OS8xMDcvOTcvMTEwLzEwMC8xMDAvMTAxLzEwMi8xMDEvMTEwLzk5LzEwMS8xMTkvMTExLzExNC8xMDgvMTAw
解密之后还是base64
,在这里说一下base编码的特征
-
base64:
(1)在base64中的可打印字符包括字母A-Z、a-z、数字0-9,+ / =。
(2)永远是4的倍数,不足四的用=补齐。
-
base32:
base32中只有大写字母(A-Z)和数字234567
-
base16:
base16中只有数字0-9以及大写字母ABCDEF
继续base64decode
得到
/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
很明显的ascii码
主要为了练习练习py,每个题都写了exp
#coding=utf-8
import base64
cipher_ascii = '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'
cipher_ascii = cipher_ascii.replace('/',',')
cipher_list = list(map(int,cipher_ascii.split(',')))
lst = []
for num in cipher_list:
lst.append(chr(num))
plain = "".join(lst)
print('cyberpeace{'+plain+'}')
#cyberpeace{welcometoattackanddefenceworld}
幂数加密
考点是云影密码
此密码运用了1248代码
原理很简单,有了1,2,4,8
这四个简单的数字,你可以以加法表示出0-9任何一个数字,例如0=28,7=124,9=18
。 这样,再用1-26来表示A-Z,就可以用作密码了。 为了不至于混乱,我个人引入了第五个数字0,来用作间隔,以避免翻译错误,所以还可以称“01248密码”。 题目: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(密码)
cipher
是8842101220480224404014224202480122
因此根据云影密码的原理,写个脚本:
#coding=utf-8
num_str = '8842101220480224404014224202480122'
num = num_str.replace('0',',')
num_list = num.split(',')
print(num_list)
lst = []
asc2 = 0
for i in range(len(num_list)):
for j in num_list[i]:
asc2 += int(j)
lst.append(asc2)
asc2 = 0
flag = ''
for i in lst:
flag+=chr(i+96)
print('cyberpeace{'+flag.upper()+'}')
#cyberpeace{WELLDONE}
Railfence
给的提示很直白,连我这个小新手都知道是栅栏密码,给的**是5,这里说明一下栅栏密码加密方式:
即把将要传递的信息中的字母交替排成上下两行,再将下面一行字母排在上面一行的后边,从而形成一段密码。栅栏密码是一种置换密码。
例如密文:TEOGSDYUTAENNHLNETAMSHVAED
解密过程:先将密文分为两行
**T E O G S D Y U T A E N N
H L N E T A M S H V A E D ****
再按上下上下的顺序组合成一句话
THE LONGEST DAY MUST HAVE AN END.
-
进阶
密文为:
PFEE SESN RETM MFHA IRWE OOIG MEEN NRMA ENET SHAS DCNS IIAA IEER BRNK FBLE LODI
去掉空格:PFEESESNRETMMFHAIRWEOOIGMEENNRMAENETSHASDCNSIIAAIEERBRNKFBLELODI
共64个字符,以8个字符为一栏,排列成8*8的方阵(凯撒方阵):
P F E E S E S N R E T M M F H A I R W E O O I G M E E N N R M A E N E T S H A S D C N S I I A A I E E R B R N K F B L E L O D I
从上向下竖着读:PRIMEDIFFERENCEBETWEENELEMENTSRESMONSIBLEFORHIROSHIMAANDNAGASAKI
插入空格:PRIME DIFFERENCE BETWEEN ELEMENTS RESMONSIBLE FOR HIROSHIMA AND NAGASAKI
但是在这里,发现用栅栏密码怎么也得不到看着靠谱的flag
,才知道这是W型栅栏密码 举个简单例子
#同样一个字符串:123456789
key=3
1----5----9 #让数字以W型组织,同样是三组,但每组的数量不一定相同
-2--4-6--8
--3----7--
#加密密文:159246837
因此直接在线W型栅栏密码
,**是5,直接出flag了。
这里mark一个网站:http://www.atoolbox.net/Tool.php
easy_RSA
RSA、DES这样的应该是密码学题目的常态,因此原理还是得弄清楚,RSA是基于数学难题的,这点上学期的课没有白听,大致地说,RSA算法基于一个十分简单的数论事实:将两个大质数相乘十分容易,但是想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加***。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qhMG25Qn-1593442175638)(C:\Users\86189\AppData\Roaming\Typora\typora-user-images\image-20200629183902255.png)]
题目描述是
在一次RSA**对生成中,假设p=473398607161,q=4511491,e=17 求解出d
因此在这里我们的目的是先求出r=(p-1)*(q-1)
,然后找到e*d % r ==1
这个d就是所求,在这里使用gmpy2.invert求逆元
d = gmpy2.invert(e,n) # 求逆元,de = 1 mod n
贴下exp:
#coding=utf-8
import gmpy2
p=473398607161
q=4511491
e=17
phin = (p-1)*(q-1)
d = gmpy2.invert(e,phin)
d = str(d)
print('cyberpeace{'+d+'}') #RSA私钥即为d
#cyberpeace{125631357777427553}
easychallenge
这题的考点主要就是给了一个pyc
文件,也就是类似java的class文件
,只需要将其反编译即可得到py文件,发现就是一个编码,三重编码得到密文,因此只需要对应写好解码,在依次解码即可得到flag
mark反编译pyc网站: https://tool.lu/pyc/
贴出exp:
#!/usr/bin/env python
# encoding: utf-8
import base64
def encode1(ans):
s = ''
for i in ans:
x = ord(i) ^ 36
x = x + 25
s += chr(x)
return s
def decode1(ans):
s = ''
for i in ans:
x = ord(i)
x = x - 25
x = x ^ 36
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 decode2(ans):
s = ''
for i in ans:
x = ord(i)
x = x ^ 36
x = x - 36
s += chr(x)
return s
def encode3(ans):
return base64.b32encode(ans)
def decode3(ans):
return base64.b32decode(ans)
final = 'UC7KOWVXWVNKNIC2XCXKHKK2W5NLBKNOUOSK3LNNVWW3E==='
#if encode3(encode2(encode1(flag))) == final:
print(decode1(decode2(decode3(final).decode('ISO-8859-1'))))
#cyberpeace{interestinghhhhh}
值得注意到是,这里编码还只能是ISO-8859-1
,因为如果是其他的,python会用\xx
来表示,这样一直会报错,经过多次尝试编码是ISO-8859-1
时,才能够正确解码。
轮转机加密
题目描述是
2: < KPBELNACZDTRXMJQOYHGVSFUWI <
3: < BDMAIZVRNSJUWFHTEQGYXPLOCK <
4: < RPLNDVHGFCUKTEBSXQYIZMJWAO <
5: < IHFRLABEUOTSGJVDKCPMNZQWXY <
6: < AMKGHIWPNYCJBFZDRUSLOQXVET <
7: < GWTHSPYBXIZULVKMRAFDCEONJQ <
8: < NOZUTWDCVRJLXKISEFAPMYGHBQ <
9: < XPLTDSRFHENYVUBMCQWAOIKZGJ <
10: < UDNAJFBOWTGVRSCZQKELMXYIHP <
11: < MNBVCXZQWERTPOIUYALSKDJFHG <
12: < LVNCMXZPQOWEIURYTASBKJDFHG <
13: < JZQAWSXCDERFVBGTYHNUMKILOP <
**为:2,3,7,5,13,12,9,1,8,10,4,11,6
密文为:NFQKSEVOQOFNP
给的提示就是轮转机加密,这种加密还挺有意思,并且它要结合具体语义的,即在最后是选取有语义的一条为明文,结合题目来说
通过所给顺序排序 : 2,3,7,5,13,12,9,1,8,10,4,11,6
将排序后的第一个字符串移位,使得N在字符串首部
第二个字符串移位,使得F在字符串首部
依次按照下列所给提示排序
NFQKSEVOQOFNP
也就是先按数字把每行字符串排好序,在按照**把每行的字符串给换一下,二次排完后再找列中有具体语义的。
贴出exp:
#coding=utf-8
"""
**为:2,3,7,5,13,12,9,1,8,10,4,11,6
密文为:NFQKSEVOQOFNP
"""
key = "2,3,7,5,13,12,9,1,8,10,4,11,6"
cipher_text = "NFQKSEVOQOFNP"
file = open("C:\\Users\\86189\\Desktop\\1.txt",encoding='utf-8')
cipher_str = []
for line in file:
cipher_str.append(line.strip())
key_index = key.split(',')
cipher_nowstr = []
for index in key_index:
cipher_nowstr.append(cipher_str[int(index) - 1])
table = 0
cipher_last = []
for c in cipher_text:
str = cipher_nowstr[table]
num = str.index(c)
cipher_last.append(str[num:]+str[:num])
table+=1
flag = ''
for str in cipher_last:
flag += str[-9] #倒数第九列有具体语义
print('flag{'+flag.lower()+'}')
#fireinthehole
easyRSA
这个题恐怕是耗费我时间最多的一题,一直在配置python环境,头大。。。这里是推荐使用CTF-RSA-TOOLS
,但是导入的很多包都没有,因此开始漫长入坑路,终于在我的vps下配置好了,那我们开始看题。
题目给了一个公钥的pem
文件还有一个flag.enc
,但是flag.enc
是无法打开的,当我们知道公钥和密文后是能够根据公钥来**密文的内容从而获得明文的。
分析公钥和私钥产生
- 随机选择两个不同大质数 p 和 q,计算 N=p×q
- 根据欧拉函数,求得 r=φ(N)=(p−1)(q−1)
- 选择一个小于 r 的整数 e,使 e 和 r 互质。并求得 e 关于 r 的模反元素,命名为 dd,有 ≡1(modr)
- 将 p 和 q 的记录销毁
此时,(N,e)(N,e) 是公钥,(N,d)(N,d) 是私钥
消息加密
首先需要将消息 m 以一个双方约定好的格式转化为一个小于 N,且与 N 互质的整数 n。如果消息太长,可以将消息分为几段,这也就是我们所说的块加密,后对于每一部分利用如下公式加密:
≡ c (modN)
消息解密
利用** d 进行解密。
≡n(modN)
我们可以知道,RSA公钥主要有两个信息:模数(modulus)和指数(exponent),也就是我们所说的N和e。只要有了这两个信息,我们便可以生成公钥,然后使用rsa库对数据进行加密
kali中有openssl
能够对pem文件提取出其模数n和指数e
openssl rsa -pubin -text -modulus -in warmup -in pubkey.pem
当得到模数n时,通过对它的因数分解分别能得到p和q,当得到这俩数之后和e之后,便可以通过这五个数来构造RSA私钥对密文进行解密了,这里可以直接使用RSA_TOOLS
python2 solve.py -k ../pubkey.pem --decrypt ../flag.enc # -k指定公钥 --decrypt 指定解密文件
或者也可以通过脚本来解密:
先通过openssl
得到了模数和指数,在分解模数n得到p和q
#coding=utf-8
import gmpy2
import rsa
q = 275127860351348928173285174381581152299
p = 319576316814478949870590164193048041239
n = 87924348264132406875276140514499937145050893665602592992418171647042491658461
e = 65537
d = int(gmpy2.invert(e,(p-1)*(q-1)))
pri_key = rsa.PrivateKey(n,e,d,p,q)
f = open('C:\\Users\\86189\\Desktop\\547de1d50b95473184cd5bf59b019ae8\\flag.enc','rb')
print(rsa.decrypt(f.read(),pri_key))
#b'PCTF{256b_i5_m3dium}\n'
上一篇: 数据结构与算法_快速排序
下一篇: 查找二叉树的节点(某一值的节点)