IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> DASCTF八月挑战赛_Crypto_复现 -> 正文阅读

[Python知识库]DASCTF八月挑战赛_Crypto_复现

easymath

k e y w o r d s : keywords: keywords: 位移运算模运算中逆元与模数非互质情况

D e s c r i p t i o n Description Description

assert(len(open('flag.txt', 'rb').read()) < 50)
assert(str(int.from_bytes(open('flag.txt', 'rb').read(), byteorder='big') << 10000).endswith(
   '1862790884563160582365888530869690397667546628710795031544304378154769559410473276482265448754388655981091313419549689169381115573539422545933044902527020209259938095466283008'))

A n a l y s i s Analysis Analysis

首先明确flag长度小于 50 50 50,也就是说大概给出了flag的数值范围

然后已知一个这样的式子 c ≡ f l a g ? 2 10000 ( m o d 1 0 175 ) c\equiv flag\cdot 2^{10000}\pmod {10^{175}} cflag?210000(mod10175)

为什么可以有这样一个式子呢?

首先位移运算就相当于乘以 2 n 2^n 2n;然后endwith()函数给出数字末尾的数值,那么就相当于模掉这个数值的长度(是 10 10 10进制的长度)


可以看出我们只需要知道 2 10000 2^{10000} 210000对于模数 1 0 175 10^{175} 10175的逆元即可

而这两者是非互质的,所以不能直接求解,但是我们可以通过把模数进一步减小达到两者互质的条件

在原来式子的基础上再取模 5 175 5^{175} 5175,此时式子变为 c ≡ f l a g ? 2 10000 ( m o d 5 175 ) c\equiv flag\cdot 2^{10000}\pmod{5^{175}} cflag?210000(mod5175)

直接求逆元乘以 c c cflag即可

S o l v i n g ? c o d e Solving~code Solving?code

from Crypto.Util.number import *
import gmpy2

c = 1862790884563160582365888530869690397667546628710795031544304378154769559410473276482265448754388655981091313419549689169381115573539422545933044902527020209259938095466283008
# print(len(str(c)))
# print(gmpy2.invert(2**10000,5**175))
flag = c * gmpy2.invert(2**10000,5**175) % pow(5,175)
print(long_to_bytes(flag))

let’s play with rsa~

k e y w o r d s : keywords: keywords: 毫无难点的rsa

D e s c r i p t i o n Description Description

from sympy import isprime,nextprime
from Crypto.Util.number import getPrime as getprime ,long_to_bytes,bytes_to_long,inverse
flag='flag{***************}'

def play():
    p=getprime(1024)
    q=getprime(1024)

    n=p*q
    e=65537

    print "Hello,let's play rsa~\n"
    print 'Now,I make some numbers,wait a second\n'
    n1=getprime(200)
    n2=getprime(200)
    number=n1*n2
    print "Ok,i will send two numbers to you,one of them was encoded.\n"
    print "Encode n1:%d,\n"%(pow(n1,e,n))
    print "And n2:%d.\n"%n2

    print "Information that can now be made public:the public key (n,e):(%d,%d)\n"%(n,e)
    while True:
        try:
            c=int(raw_input("ok,now,tell me the value of the number (encode it for safe):"))
        except:
            print "Sorry,the input is illeagal, and the integer is accept~"
        else:
            break
    d=inverse(e,(p-1)*(q-1))
    m=pow(c,d,n)
    if m==number:
        print "It's easy and interesting,didn't it?\n"
        print "This is the gift for you :"+flag
    else:
        print "Emmmmm,there is something wrong, bye~\n"

if __name__ == '__main__':
    play()

A n a l y s i s Analysis Analysis

题目要求传递的是密文 c c c,只要该密文解密之后得到的明文等于 n 1 ? n 2 n_1\cdot n_2 n1??n2?即可

而我们已知 c 1 ≡ n 1 e ( m o d n ) c_1 \equiv n_1^{e}\pmod n c1?n1e?(modn);以及 n 2 n_2 n2?

c ≡ ( n 1 ? n 2 ) e ( m o d n ) c\equiv ({n_1\cdot n_2})^{e}\pmod n c(n1??n2?)e(modn)

拆开也就是 c ≡ c 1 ? n 2 e ( m o d n ) c\equiv c_1 \cdot n_2^e\pmod n cc1??n2e?(modn)

同余式左边参数都已知,那么直接代入就好了

S o l v i n g ? c o d e Solving~code Solving?code

from Crypto.Util.number import *
import gmpy2
from pwn import *

io = remote("node4.buuoj.cn","27103")
io.recvuntil(b"n1:")
c1 = int(bytes.decode(io.recvuntil(b",")[:-1]))
# print(c1)
io.recvuntil(b"n2:")
n2 = int(bytes.decode(io.recvuntil(b".")[:-1]))
# print(n2)
io.recvuntil(b':')
temp = io.recvline()
# print(temp.split(b':'))
temp2 = temp.split(b":")[1]
n, e = int(bytes.decode(temp2.split(b",")[0][1:])), int(bytes.decode(temp2.split(b",")[1][:-2]))
# print(n,e)

c = c1 * pow(n2,e,n) % n
io.recvuntil(b":")
io.sendline(str(c).encode())
io.interactive()

ezRSA

k e y w o r d s : keywords: keywords: 同余式的转换

D e s c r i p t i o n Description Description

from secret import flag
from Crypto.Util.number import *
from random import getrandbits
from hashlib import sha256


class EzRsa:
    def __init__(self):
        self.E = 0x10001
        self.P = getPrime(1024)
        self.Q = getPrime(1024)
        while GCD((self.P-1)*(self.Q-1), self.E) != 1:
            self.Q = getPrime(1024)
        self.N = self.P*self.Q

    def encrypt(self):
        f = getrandbits(32)
        c = pow(f, self.E, self.N)
        return (f, c)

    def encrypt_flag(self, flag):
        f = bytes_to_long(flag)
        c = pow(f, self.E, self.N)
        return c


def proof():
    seed = getrandbits(32)
    print(seed)
    sha = sha256(str(seed).encode()).hexdigest()
    print(f"sha256({seed>>18}...).hexdigest() = {sha}")
    sha_i = input("plz enter seed: ")
    if sha256(sha_i.encode()).hexdigest() != sha:
        exit(0)


if __name__ == "__main__":
    proof()
    print("welcome to EzRsa")
    print("""
    1. Get flag
    2. Encrypt
    3. Insert
    4. Exit
    """)
    A = EzRsa()
    coin = 5
    while coin > 0:
        choose = input("> ")
        if choose == "1":
            print(
                f"pow(flag,e,n) = {A.encrypt_flag(flag)}\ne = 0x10001")
            exit(0)
        elif choose == "2":
            f, c = A.encrypt()
            print(f"plain = {f}\ncipher = {c}")
            coin -= 1
        elif choose == "3":
            q = getrandbits(1024)
            n = A.P*q
            f = getrandbits(32)
            c = pow(f, 0x10001, n)
            print(f"plain = {f}\ncipher = {c}")
            coin -= 1
        elif choose == "4":
            print("bye~")
        else:
            print("wrong input")
    print("Now you get the flag right?")

A n a l y s i s Analysis Analysis

proof函数,从来没有遇到过这么无语的proof函数

直接把程序打印出来的seed再提交上去就好了

def proof():
    seed = getrandbits(32)
    print(seed)

然后分析主程序

分为三个功能:Get flagEncryptInsert

分别是得到flag的密文c_flag;得到一组明文及密文plaint1,cipher1(以 ( n , e ) (n,e) (n,e)作为公钥);得到一组明文及密文plaint2,cipher2(以 ( p ? q o t h e r , e ) (p*q_{other},e) (p?qother?,e)作为公钥)

总共可以执行 5 5 5次上述功能;此时对于flag的RSA加密,我们只知道 e e e的大小

很快分析出,Encrypt一定是用来求得 n n n的,Insert一定是用来求得 p p p从而把 n n n分解的

两个功能的加密过程是相似的,猜测两个功能都要分别执行两次

推导:Encrypt功能
{ p l a i n t 1 e = c 1 ( m o d n ) p l a i n t 2 e = c 2 ( m o d n ) \begin{cases} plaint_1^e=c_1\pmod n\\ plaint_2^e=c_2\pmod n \end{cases} {plaint1e?=c1?(modn)plaint2e?=c2?(modn)?
? { p l a i n t 1 e ? c 1 = k 1 ? p ? q p l a i n t 2 e ? c 2 = k 2 ? p ? q \Rightarrow \begin{cases} plaint_1^e - c_1 = k_1 \cdot p \cdot q \\ plaint_2^e - c_2 = k_2\cdot p \cdot q \end{cases} ?{plaint1e??c1?=k1??p?qplaint2e??c2?=k2??p?q?

同余式左侧的参数我们都已知,那么两者的最大公约数一定整除 n n n,因为可能 k 1 k_1 k1? k 2 k_2 k2?之间也有公约数,所以两者的最大公约数不直接等于 n n n

我们得到
n ∣ g c d ( p l a i n t 1 e ? c 1 , p l a i n t 2 e ? c 2 ) n \mid gcd(plaint_1^e -c_1,plaint_2^e - c_2) ngcd(plaint1e??c1?,plaint2e??c2?)
而他们之间的倍数很小(等于 k 1 k_1 k1? k 2 k_2 k2?的最大公约数,所以可以直接爆破 1000 1000 1000以内的数作为倍数)

Insert功能
{ p l a i n t 3 e ≡ c 3 ( m o d p ? q o t h e r 1 ) p l a i n t 4 e ≡ c 4 ( m o d p ? q o t h e r 2 ) \begin{cases} plaint_3^e \equiv c_3 \pmod {p\cdot q_{other1}}\\ plaint_4^e \equiv c_4 \pmod {p\cdot q_{other2}} \end{cases} {plaint3e?c3?(modp?qother1?)plaint4e?c4?(modp?qother2?)?

? { p l a i n t 3 e ? c 3 = k 3 ? p ? q o t h e r 3 p a l i n t 4 e ? c 4 = k 4 ? p ? q o t h e r 4 \Rightarrow\begin{cases} plaint_3^e - c_3 = k_3 \cdot p\cdot q_{other3}\\ palint_4^e - c_4 = k_4 \cdot p \cdot q_{other4} \end{cases} ?{plaint3e??c3?=k3??p?qother3?palint4e??c4?=k4??p?qother4??

Encrypt的分析过程一致,可以得到
p ∣ g c d ( p l a i n t 3 e ? c 3 , p l a i n t 4 e ? c 4 ) p\mid gcd(plaint_3^e -c_3,plaint_4^e-c_4) pgcd(plaint3e??c3?,plaint4e??c4?)
其中两者的倍数大小依然是等于 k 3 k_3 k3? k 4 k_4 k4?的最大公约数

S o l v i n g ? c o d e Solving~code Solving?code

from Crypto.Util.number import *
from pwn import *
import gmpy2

io = remote("node4.buuoj.cn","29721")
seed = int(bytes.decode(io.recvline()))
# print(seed)
io.recvuntil(b":")
io.sendline(str(seed).encode())

e = 65537
plaint1 = []
cipher1 = []
for _ in range(2):
    io.recvuntil(b">")
    io.sendline(b"2")
    io.recvuntil(b'=')
    plaint1.append(int(bytes.decode(io.recvuntil(b"\n")[:-1])))
    io.recvuntil(b"=")
    cipher1.append(int(bytes.decode(io.recvuntil(b"\n")[:-1])))
# print(plaint1)
# print(cipher1)

n = gmpy2.gcd(plaint1[0]**e - cipher1[0],plaint1[1]**e - cipher1[1])
k = 2
while True:
    if n % k == 0:
        n = n // k
        k = 2
        continue
    else:
        k += 1
    if k > 1000:
        break
# print(n)

plaint2 = []
cipher2 = []
for _ in range(2):
    io.recvuntil(b">")
    io.sendline(b"3")
    io.recvuntil(b'=')
    plaint2.append(int(bytes.decode(io.recvuntil(b"\n")[:-1])))
    io.recvuntil(b"=")
    cipher2.append(int(bytes.decode(io.recvuntil(b"\n")[:-1])))
# print(plaint2)
# print(cipher2)
p = gmpy2.gcd(plaint2[0]**e - cipher2[0],plaint2[1]**e - cipher2[1])
k = 2
while True:
    if p % k == 0:
        p = p // k
        k = 2
        continue
    else:
        k += 1
    if k > 1000:
        break
# print(p)

assert n % p == 0
q = n // p
fai_n = (p-1)*(q-1)
d = gmpy2.invert(e,fai_n)

io.recvuntil(b">")
io.sendline(b'1')
io.recvuntil(b"=")
c_flag = int(bytes.decode(io.recvuntil(b"\n")[:-1]))

flag = pow(c_flag,d,n)
print(long_to_bytes(flag))

io.close()
  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2022-03-08 22:24:55  更:2022-03-08 22:26:15 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/31 4:13:22-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码