第十六届全国大学生信息安全竞赛CISCN---Cypto

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'))

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值