1.Sign_in_passwd
打开环境,下载附件,用记事本打开flag的文件
发现里面是像base密码但又不像base密码的一串,第二行的%,就很像url密码啊,之前做题没接触过啊,还是做题做少了
没有啥解题思路,看了一下别人的wp,要base64换表????这是个啥
浅了解一下,我发现自己其实对base64也不太了解,就只是知道大概字符串编码成什么样会是base64,那么今天就把他了解清楚吧
base64原理:
简单来说就是——“把3个字节变成4个字节”
这么说吧,3个字节一共24个
bit
,把这24个bit
依次分成4个组,每个组6个bit
,再把这6个bit
塞到一个字节中去(最高位补两个0就变成8个bit
),就会变成4个字节。没了。因为6个
bit
最多能表示2^6=64,也就是说Base64编码出来的字符种类只有64个,这也是Base64名字的由来。对重组后的数据处理,每组最前面添加两个“0”,构成每组8个bit。由于在最前面添加的0,所以对数值不构成影响。
这里要注意其实严格上来说base64并不属于加密,只是为了方便传输而已。
到这里你可能会发现貌似只有字节数是3的倍数才能处理啊,那么现实情况中,不是3的倍数的情况多的是,怎么办?
方法::补零加 “
=”
号(2个0为一个=)因此Base64编码后有时候可以看到
=
或者==
这都是正常的。那么解码的密文就有一定的要求的,从前面的分析中得出来,加密之后形成的密文长度一定是4的倍数,且字符串中的字符一定要在映射表中,或者字符为
=
,还有,只可能有一个=
或一个==.
映射表:
我看有些大佬说,会有些题目遇到换映射表的情况,但我暂时还没遇到,等遇到了我在研究吧。
我看见base64的应用中有一条是:Url中有二进制数据,这个时候需要Base64编码(Web安全的Base64),那是不是可以验证我们题目中的第二行
经过查阅资料发现,在逆向中base64换表是经常用到的(怪不得,我都不咋研究逆向)
诶哟,这个题就是上述的换映射表的情况,我真服了,所提到的base64换表就是换编码所对应的映射表。
开始做题!
首先对第二行将要转换的表做url解码:
再进行base64换表
2.badkey1
下载附件后,大概知道这个题是个rsa的密码题
尝试运行一下,大概知道我们应该输入什么
审计代码,发现当有ValueError错误时,会输出flag
捋一下,这个题目中的关键点
1.proof_of_work()函数要求用户找到一个长度为4的字符串XXXX,使得sha256(XXXX + proof[4:])等于给定的哈希值_hexdigest。如果用户提供了正确的XXXX,函数返回True,否则返回False。
2.如果proof_of_work()返回False,程序将退出。
3.程序设置一个10秒的定时器。用户需要在10秒内完成接下来的任务,否则程序将被中断。
4.程序提示用户提供一个“错误的”RSA密钥对。用户需要输入两个质数p和q,这些质数需要满足一些条件(例如,它们必须是512位长的质数,且不能使p % e == 1 或 q % e == 1)。
5.程序尝试使用用户提供的p和q值构造一个RSA密钥对。如果构造成功,程序将输出"This is not a bad RSA keypair.“。如果在尝试构造密钥对时引发了ValueError异常(即密钥对不满足RSA算法的基本属性),程序将输出"How could this happen?”,并显示秘密标志(flag)。如果程序被中断(例如,由于10秒定时器到期),程序将输出"Hacker detected."
首先是proof,我觉得找到长度怕是够呛,我估摸着肯定要爆破,但由于自己水平有限,不会写脚本,所以找了一个大佬的wp,浅浅借鉴了一下
import hashlib
import itertools
import string
def find_proof(prefix, target_hash):
for combination in itertools.product(string.ascii_letters + string.digits, repeat=4):
test_str = ''.join(combination)
test_hash = hashlib.sha256((test_str + prefix).encode()).hexdigest()
if test_hash == target_hash:
return test_str
return None
proof_prefix = find_proof(proof_suffix, target_hash)
这串代码的意义就是
传入服务器发来的proof, target_hash
爆破sha256
接着构造d=k*q使得不满足RSA生成密钥的条件
from Crypto.Util.number import
while True:
p = getPrime(512)
e = 65537
k = inverse(e, p - 1)
t = (e * k * p - 1) // (p - 1)
for j in range(1, e+1):
if t % j == 0:
q = t // j + 1
if isPrime(q) and q.bit_length() == 512:
print(p)
print(q)
break
完成这两个条件即可得到flag
完整脚本如下
import hashlib
import itertools
from Crypto.Util.number import getPrime,inverse
from pwn import *
from Crypto.PublicKey import RSA
p = remote('39.105.26.155',29558)
t = p.recv()
hexdigest = t.decode('utf-8')[33:97]
proof = t.decode('utf-8')[12:28]
def find_proof(prefix, target_hash):
for combination in itertools.product(string.ascii_letters + string.digits, repeat=4):
test_str = ''.join(combination)
test_hash = hashlib.sha256((test_str + prefix).encode()).hexdigest()
if test_hash == target_hash:
return test_str
return None
result = find_proof(proof, hexdigest)
p.sendline(result)
t = p.recv()
print(t.decode('utf-8'))
# p.interactive()
weak_p = 10531798713566879985296310428910390829209559732187698122767912917088107059584145754739337891177477443973692234213380752118071230162618029537072442550315509
weak_q = 10354167589067169202907092046919351418658108936732776652403348338383910730719553355212239030073966381178568000602060877173120275918735882350052550806863399
p.sendline(str(weak_p).encode())
p.sendline(str(weak_q).encode())
t = p.recv()
print(t.decode('utf-8'))