$a = '%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2';
$b = '%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2';

var_dump($a === $b);
var_dump(urldecode($a));
var_dump(urldecode($b));
var_dump(md5(urldecode($a)) === md5(urldecode($b)));

QQ截图20200920115029.png

说起python的字符串替换我们可能会想到的就是使用 replace函数

比如有一段字符串 "这是简单替换",我们想把 "简单" 替换为 "复杂":

>>> s = "这是简单替换"
>>> s.replace("简单","复杂")
'这是复杂替换'

根据 replace 函数的设定,他只能处理一组映射关系的替换,所以在替换多组数据时我们可能要使用多个replace进行类似嵌套的操作,这在数据量大的情况下显得很鸡肋而且影响代码美观。

如 "101010" 使用替换的方法使之变成 "010101",也就是 "1" 和 "0" 互换,这时候的表达式可能会写:

>>> s = "101010"
>>> s.replace("1","a").replace("0","1").replace("a","0")
'010101'

上述操作虽然能达到目的,但是看起来效果很鸡肋,完全时靠 replace 进行的逐个替换,而且替换有交集时还得使用临时交换,当数据量很大时总不能写 N 个replace吧,那这时候就有了另一个比较简便的方法:

>>> s = "101010"
>>> trans = s.maketrans("1 0","0 1")
>>> s.translate(trans)
'010101'

关于 maketrans 方法

关于 translate 方法

在大量的替换处理中就会变得非常便捷

Readme:可自动识别需要加密还是解密,如:

C:\cmd>python3 morse.py "123456"

[+]"123456"的加密结果:.----/..---/...--/....-/...../-....

C:\cmd>python3 morse.py ".----/..---/...--/....-/...../-...."

[-]".----/..---/...--/....-/...../-...."的解密结果:123456

源码如下:

#/usr/bin/python3
# _*_ coding:utf-8 _*_
import sys

"""对照表"""
t = {"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": "--..",
	 "1": ".----", "2": "..---", "3": "...--", "4": "....-",
	 "5": ".....", "6": "-....", "7": "--...", "8": "---..",
	 "9": "----.", "0": "-----",
	 "(": ".--.-", "-": "-....-", "?": "..--..", "/": "-..-.","_":"..--.-",
	 ".": ".-.-.-", "@": ".--.-.", ")": "-.--.-", "}":"-----.-","{":"----.--",
	 
	 '.-': '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',
	 '.----': "1",'..---': '2', '...--': '3', '....-': '4', '.....': '5', '-....': '6',
	 '--...': '7', '---..': '8', '----.': '9', '-----': '0',
	 '.--.-': '(', '-....-': '-', '..--..': '?',"-.--.-":")", "-----.-":"}","----.--":"{",
	 '-..-.': '/', '.-.-.-': '.', '.--.-.': '@',"..--.-":"_",
	 }



def edcode(p):
	s = ''
	if './' in p or '-/' in p:   # 判断输入的字符串是要加密还是解密
		"""解密"""
		for i in p.strip('/').split('/'):   # 循环取出每一个解密的元素
			s += t[i]   # 进行对照表解密
			
		print('\n[-]"{}"的解密结果:'.format(p) + s)    # 打印结果
			
	else:
		"""加密"""
		for i in list(p):
			s += t[i.upper()] + '/'	# 每个字符加密后拼接一起,使用'/'隔开
			
		print('\n[+]"{}"的加密结果:'.format(p) + s.strip('/'))   # 首尾去'/',打印结果
	
if __name__ == '__main__':
	if len(sys.argv) == 2:   # 判断是否按照指定格式运行脚本
		try:
			p = sys.argv[1]   # 取需要加密或者解密的参数
			edcode(p)
		
		except:   # 人生如戏,难免发生意外,提示运行错误
			print("\n[!]请检查输入的参数是否合法,暂时只支持字母数字和一下特殊字符:'_','-','.','@','/','?'")
			
	else:
		print("""
[*]使用方法:python3 this.py "要加密或者解密的字符串"
[+]加密:python3 morse.py "123456"
[-]解密:python3 morse.py ".----/..---/...--/....-/...../-...."   # 解密一定要带有 '/'符号,不然识别不出
			""")

这题是关于RSA解密相关的,下载题目文件后压缩包里有两个文件,分别是公钥和加密的文件,我们的思路就是通过公钥爆破出私钥,再根据私钥解密出密文

其中 .pem格式的是openssl的文件类型,所以我们需要用到openssl来解出RSA中的N 值与 e值,这个过程完全是可计算的,并不是爆破,毕竟传统的rsa公钥是(e,N)的形式,这里只是通过openssl把他格式化了一下

kali自带有openssl,可在 pubkey.pem的当前目录运行一下命令解出N值与e值

openssl rsa -pubin -text -modulus  -in pubkey.pem

运行效果如下:

root@kali:~/CTF/openssl# ls
pubkey.pem
root@kali:~/CTF/openssl# openssl rsa -pubin -text -modulus  -in pubkey.pem
RSA Public-Key: (256 bit)
Modulus:
    00:c2:63:6a:e5:c3:d8:e4:3f:fb:97:ab:09:02:8f:
    1a:ac:6c:0b:f6:cd:3d:70:eb:ca:28:1b:ff:e9:7f:
    be:30:dd
Exponent: 65537 (0x10001)
Modulus=C2636AE5C3D8E43FFB97AB09028F1AAC6C0BF6CD3D70EBCA281BFFE97FBE30DD
writing RSA key
-----BEGIN PUBLIC KEY-----
MDwwDQYJKoZIhvcNAQEBBQADKwAwKAIhAMJjauXD2OQ/+5erCQKPGqxsC/bNPXDr
yigb/+l/vjDdAgMBAAE=
-----END PUBLIC KEY-----

或者可以使用在线工具计算,http://tool.chacuo.net/cryptrsakeyparse

其中 "65537"就是 e值,而 "C2636AE5C3D8E43FFB97AB09028F1AAC6C0BF6CD3D70EBCA281BFFE97FBE30DD" 是16进制的N值,我们需要把它转为10进制,我个人比较喜欢用python

root@kali:~/CTF/openssl# python3
Python 3.8.3 (default, May 14 2020, 11:03:12) 
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> int(0xC2636AE5C3D8E43FFB97AB09028F1AAC6C0BF6CD3D70EBCA281BFFE97FBE30DD)
87924348264132406875276140514499937145050893665602592992418171647042491658461
>>> 

这就计算出了N值,这时候我们需要通过类似爆破的方式来计算 p值与q值,可以用过在线网站进行计算,网址:http://www.factordb.com/index.php,下面是解密结果:

下面我们就可以根据rsa加密的原理进行计算出密钥,使用到的一个工具是rsatool,安装方法:

git clone https://github.com/ius/rsatool.git
cd rsatool  //进入这个目录
python setup.py install

然后可以使用下面的命令生成密钥文件:

python rsatool.py -o private.pem -p 275127860351348928173285174381581152299 -q 319576316814478949870590164193048041239 -e 65537

运行完成后即可在目录下生成一个私钥文件 private.pem,将 private.pem 与 flag.enc 放在同一个目录下,然后运行openssl解密,计算出 加密的明文信息

openssl rsautl -decrypt -in flag.enc -inkey private.pem

下面是运行效果:

root@kali:~/CTF/openssl# ls
flag.enc  private.pem
root@kali:~/CTF/openssl# openssl rsautl -decrypt -in flag.enc -inkey private.pem
PCTF{256b_i5_m3dium}
root@kali:~/CTF/openssl#

可以看到加密后的信息被解密出来了

题目描述:

快速口算分值: 350小明要参加一个高技能比赛,要求每个人都要能够快速口算四则运算,2秒钟之内就能够得到结果,但是小明就是一个小学生没有经过特殊的培训,那小明能否通过快速口算测验呢?

平台题目地址

做题地址

这个无论是直接手算或者发送到BURP上都不能完成,所以我写了个py脚本,可以一键拿key

import requests
from lxml import etree

"""发送请求包,获取式子和cookie"""
r = requests.get("http://lab1.xseclab.com/xss2_0d557e6d2a4ac08b749b61473a075be1/index.php")
html = etree.HTML(r.text)   # 转为 lxml对象进行xpath解析
r.encoding = r.apparent_encoding
formula = str(html.xpath("/html/body/form/text()[2]")[0]).strip()[:-1]    # 获取式子,转为字符串对象
formula = eval(formula)    # 计算答案
cookie = r.headers['Set-Cookie'].split(";")[0]     # 截取服务器给的cookie

"""自定义cookie发送post包"""
headers = {'Cookie':cookie, 'Content-Type':'application/x-www-form-urlencoded'}   # 自定义header头
data = "v={}".format(str(formula))   # 要发送的post主体
p = requests.post("http://lab1.xseclab.com/xss2_0d557e6d2a4ac08b749b61473a075be1/index.php", data = data, headers =headers)
p.encoding = p.apparent_encoding
html = etree.HTML(p.text)
print(html.xpath("//body/text()")[0])   # 打印出key

拿下key