[WMCTF 2023] crypto

news2024/11/16 11:35:51

 

似乎退步不了,这个比赛基本不会了,就作了两个简单题。

SIGNIN

第1个是签到题

from Crypto.Util.number import *
from random import randrange
from secret import flag

def pr(msg):
    print(msg)

pr(br"""
                        ....''''''....                        
                     .`",:;;II;II;;;;:,"^'.                    
                  '"IlllI;;;;;;;;;;;;;Il!!l;^.                 
                `l><>!!!!!!!!iiiii!!!!!!!!i><!".               
             ':>?]__++~~~~~<<<<<<<<<<<<<<<<~~+__i".            
           .:i+}{]?-__+++~~~~~~<<<<<~~~~~~+_-?[\1_!^           
          .;<_}\{]-_++~<<<<<<<<<<<<<<<<<<<~+-?]\|]+<^          
          .!-{t|[?-}(|((){_<<<<<<<<<_}1)))1}??]{t|]_"          
           !)nf}]-?/\){]]]_<<<<<<<<<_]]}}{\/?-][)vf?`          
          '!tX/}]--<]{\Un[~~<<<<<~~<~-11Yz)<--?[{vv[".         
         .<{xJt}]?!ibm0%&Ci><<<<<<<<!0kJW%w+:-?[{uu)},         
          !1fLf}]_::xmqQj["I~<<<<<<>"(ZqOu{I^<?[{cc)[`         
          `}|x\}]_+<!<+~<<__~<<<<<<+_<<_+<><++-[1j/(>          
           !\j/{]-++___--_+~~<i;I>~~~__-______?}(jf}`          
            ;~(|}?_++++~~++~+]-++]?+++~~~~+++-[1/]>^           
              ;\([?__+_-?]?-_-----__-]?-_+++-]{/].             
               l||}?__/rjffcCQQQQQLUxffjf}+-]1\?'              
                ,[\)[?}}-__[/nzXXvj)?__]{??}((>.               
                 .I[|(1{]_+~~~<~~<<<~+_[}1(1+^                 
                    ,~{|\)}]_++++++-?}1)1?!`                   
                      ."!_]{11))1{}]-+i:'                      
                          .`^","^`'.                           
""".decode())

def gen_prime(bit):
    while 1:
        P = getPrime(bit)
        if len(bin(P)) - 2 == bit:
            return P

pq_bit = 512
offset = 16

P,Q = [gen_prime(pq_bit) for i in range(2)]
N = P * Q
gift = int(bin(P ^ (Q >> offset))[2+offset:],2)
pr(N)
pr(gift)

inpP = int(input())
if inpP != P:
    pr(b"you lose!")
    exit()

secret = randrange(0,P)
bs = [randrange(0,P) for _ in range(38)]

results = [(bi * secret) % P for bi in bs]
rs = [ri & (2 ** offset - 1)  for ri in results]

pr(bs)
pr(rs)
inpsecret = int(input())
if inpsecret == secret:
    pr(flag)

两部分第一部分是个爆破p^(q>>16)

gift = int(bin(P ^ (Q >> offset))[2+offset:],2)

第二部分是一个hnp问题,与常见的不同,原来是 B = A*x + b这里给的是A和b求B,这题本来不会,但前天有一个比赛也是这个题,也不会,广大姥要了WP,根据那个WP写一下就行了。

第一部分

from pwn import *

io = remote('1.13.101.243', 26140 )
context.log_level = 'debug'


for _ in range(24):
    io.recvline()

def fac(x,tp,tq):
    global p 
    if p != 0:
        return
    if len(x) == 0:
        return
    if tp*tq>N:
        return
    if N%(tp+1)==0:
        print(tp+1)
        p = tp+1
        return
    
    v = x[0]
    r = x[1:]
    l = len(r)
    
    if (tp+(1<<(l+1)))*(tq+(1<<(l+17)))<N:
        return      
        
    if v == '0':
       fac(r, tp, tq)
       fac(r, tp+(1<<l), tq+(1<<(l+16)))
    else:
       fac(r, tp+(1<<l), tq)
       fac(r, tp, tq+(1<<(l+16)))


N = int(io.recvline())
print(N)
gift = int(io.recvline())
x = bin(gift)[2:].zfill(512-16)
print(x[:50])

p = 0
#p前15位未知
for hp in range(1<<15):
    if hp%0x1000 == 0:
        print(hex(hp))
    tp = (1<<511)+ (hp<<512-16-1)
    if x[0] == '0':
        tp += 1<<(512-16-1)
    tq = (1<<(511))
    fac(x[1:],tp,tq)
    if p != 0:
        break 

io.sendline(str(p).encode())

第二部分

A = eval(io.recvline())
b = eval(io.recvline())
B = 2^16

print(f"{p = }")
print(f"{A = }")
print(f"{b = }")

sol = int(input('sol='))


io.sendline(str(sol).encode())
print(io.recvline())

io.interactive()

badprime

这是个RSA题,最后才出,难度比较小。

p = k*M + r

可以输入M,给出p%M的值,显然这里只能输入M,然后coppersimth求k

原题

from Crypto.Util.number import *
from secret import flag

M = 0x7cda79f57f60a9b65478052f383ad7dadb714b4f4ac069997c7ff23d34d075fca08fdf20f95fbc5f0a981d65c3a3ee7ff74d769da52e948d6b0270dd736ef61fa99a54f80fb22091b055885dc22b9f17562778dfb2aeac87f51de339f71731d207c0af3244d35129feba028a48402247f4ba1d2b6d0755baff6

def getMyprime(BIT):
    while True:
        p = int(pow(65537, getRandomRange(M>>1, M), M)) + getRandomInteger(BIT-int(M).bit_length()) * M
        if isPrime(p):
            return p

p = getMyprime(1024)
q = getPrime(1024)
n = p * q
m = bytes_to_long(flag)

print("Try to crack the bad RSA")
print("Public key:", n)
print("The flag(encrypted):", pow(m, 65537, n))
print("Well well, I will give you the hint if you please me ^_^")
leak = int(input("Gift window:"))
if M % leak == 0:
    print("This is the gift for you: ", p % leak)
else:
    print("I don't like this gift!")

取数

┌──(kali㉿kali)-[~]
└─$ nc 1.13.101.243 26086
Try to crack the bad RSA
Public key: 9742410937110696461407112349699118236918457640950632920212795068374737936993342570963570443656476362238888124280173501476715660532234383908363410810325565092828457724260500094074310976465439133379654136956954969400177970645885438501653328305955812320073239582404081688376029009382502861319019563066540964659677575484346073160213626650310710260741949702931555358818963239172398313264967023252795746331804500033700165496526109847749240713539566702141086846689655725502183261216470115828779150622670477792032393842776851714610961219730469419362345806447065512890382493060186679828260265857866140764306386881882549166059
The flag(encrypted): 1673402070143155927322001035133684146816738492230807731633827901952184786734541292011662658981062894242325327877506962350481690686305101327856759348839937660438396133590644401938568726337539332758333618463217894304453290225710789062464107920895112595149601246277505775421072733759692860886887303527889771493564848232892813177891652600172884862175447947822901530128111336592984421258891521336361945375551264204284260029356005647086620008139176194080359501299190921098147822016114664277256058464418457390881573150209603439315104193219972739816965833683983804527550309212725954113363913887790377813026135333782360027419
Well well, I will give you the hint if you please me ^_^
Gift window:19467773070115377343221509599623925236459751278180415885837207534756855405403128279156705968461708578168638327032034542684864920135818987044810141311008655898015207220772515212093850725541003213054560185603695585660265284153421684796257245143362498012760214539505870197264858636122745485373430
This is the gift for you:  3919234716983693931577570915609109697211099065875069949073051641072090520857441022482511192871418764059751265895543741460544614322144961090655257474754910444266016317938260233309368531551350066234134348206616531225276790017532193136255605520389973662219840028068705375923569595556552528548183

求值

P.<x> = PolynomialRing(Zmod(n))
f = x*M + M_prime
f.small_roots(X=2^53, beta=0.2, epsilon=0.03)
k = 4429807550221656


p = k*M + M_prime
q = n//p 
d = inverse_mod(65537, (p-1)*(q-1))
m = pow(c,d,n)
#71802904779908417281632177730640329722234828721755228551576131323789654417934437971480843565056115983321708839293
bytes.fromhex(hex(m)[2:])
#b'wmctf{b4d_primE_f4ctor_1s_the_w3akness_for_RSA}'

welconsigner2

这是WP里的,在这里复制保存一下。

两题都是对快速注入错误,求d,第一题一开始给错了,反正不会也就没看。以下是WP原文

对于快速幂的第i步运算,正常情况下已知Ai = Ai-1 * Bi-1^di (mod n);Bi = Bi-1^2 (mod n)
错误注入后,上述式子改为在模数n_下进行计算,此时得到Ai' = Ai-1 * Bi-1^di (mod n_);Bi' = Bi-1^2 (mod n_)

我们以快速幂的最后一次计算为例(错误也注入在最后一次),此时An、An'即为错误注入前、后的RSA签名。此时Bn、Bn'的值都是可以通过计算得到的,通过在模n、n_上分别尝试计算An-1的值我们即可确定dn的值(对于正确的dn值,An、An'倒推出的An-1值应该是相同的)
类似地,在得到An-1与dn的值之后,我们可以将错误注入在倒数第二次,进一步求出An-2与dn-1的值,如此即可利用n次错误注入恢复完整的RSA私钥d

from Crypto.Util.number import *

nbits = 512


def oracle(index):
    io.sendlineafter(b'|	[Q]uit', b's')
    io.sendlineafter(b'Where your want to interfere:', str(index).encode())
    io.recvuntil(b'signature of \"Welcome_come_to_WMCTF\" is ')
    sig = int(io.recvline().strip())
    return sig

msg = bytes_to_long(b"Welcome_come_to_WMCTF")
def func(sig, n, e, n_):
    nn = nbits*2
    dbit = [0 for _ in range(nn+1)]
    from tqdm import trange
    for i in trange(nn):
        for now_dbit in range(2):
            now = dbit[:]
            now[nn-i] = now_dbit
            B, B_ = msg, msg
            N, N_ = n, n
            res, res_ = 1, 1
            for j in range(nn):
                if now[j] == 1:
                    res = res * B % N
                    res_ = res_ * B_ % N_
                if j >= nn-1-i:
                    N_ = n_
                B = B ** 2 % N
                B_ = B_**2 % N_
            sig_ = oracle(i)
            tmp = (sig * inverse(res, N) % N) * res_ % N_
            if tmp == sig_:
                dbit = now
                break
        else:
            raise Exception(f"Failure[{i}]")
    dbit[0] = 1
    d = int(''.join(str(_) for _ in dbit)[::-1], 2)
    print(d)
    print(pow(233, e*d, n))
    return d

from pwn import *
io = remote('1.13.101.243', 26891)

io.sendlineafter(b'|	[Q]uit', b'g')
io.recvuntil(b'n = ')
n = int(io.recvline().strip())
io.recvuntil(b'flag_ciphertext = ')
ct = bytes.fromhex(io.recvline().strip().decode())

sig = oracle(0)

io.sendlineafter(b'|	[Q]uit', b'f')
io.sendlineafter(b'bytes, and index:', b'255,1')
tmp = 255
index = 1
n_ = n ^ (int(tmp)<<int(index))
e = 17

d = func(sig, n, e, n_)
io.close()
from Crypto.Cipher import AES
from hashlib import md5

key = bytes.fromhex(md5(str(d).encode()).hexdigest())
enc = AES.new(key, mode=AES.MODE_ECB)
flag = enc.decrypt(ct)
print(flag)
# WMCTF{F4u1t_1nj3ct1on_1n_RS4*&iu2726457}

welcomesigner1

第二个的快速幂算法有变化

def myfastexp(m,d,N,j,N_):
    A = 1
    d = bin(d)[2:]
    n = len(d)
    for i in range(n-1,-1,-1):
        if i < j:
            #print(A)
            N = N_
        A = A*A % N
        if d[i] == "1":
            A = A * m % N
    return A

这需要将N_改为一个素数且%4==3然后通过勒让德符号计算,反正特别复杂,看得头大

from Crypto.Util.number import *
from tqdm import trange

nbits = 512
m = bytes_to_long(b"Welcome_come_to_WMCTF")

def init():
    while True:
    # generate
        p = getPrime(nbits)
        q = getPrime(nbits)
        n = p*q
        e = 17
        if GCD(e,(p-1)*(q-1)) == 1:
            d = inverse(e,(p-1)*(q-1))
            break
    while True:
        n_ = next_prime(n)
        if n_ % 4 == 3:
            break
    print(f"{n = }\n{n_ = }")
    return n, e, n_, d


def oracle(index):
    io.sendlineafter(b'|	[Q]uit', b's')
    io.sendlineafter(b'Where your want to interfere:', str(index).encode())
    io.recvuntil(b'signature of \"Welcome_come_to_WMCTF\" is ')
    sig = int(io.recvline().strip())
    return sig

def func(sig, n, e, n_):
    def ZZ_sqrt_root(res):
        R.<x> = ZZ[]
        return (x^2-ZZ(res)).roots()
    def GF_sqrt_root(res, p):
        if pow(res, (p-1)//2, p) == 1:
            ans = ZZ(pow(res, (p+1)//4, p))
            return [ans, p-ans]
        return []

    nn = 2*nbits
    dbits = ''
    A = sig
    for i in trange(1, nn+1):
        sig_ = oracle(i)
        As_ = [sig_]
        for j in dbits:
            nxt = list()
            for A_ in As_:
                if j == '1':
                    nxt += GF_sqrt_root(ZZ(A_*inverse(m, n_)%n_), n_)
                else:
                    nxt += GF_sqrt_root(ZZ(A_), n_)
            As_ = [ZZ(_) for _ in nxt]
        flag = False
        for j in range(2):
            for A_ in As_:
                if j == 1:
                    s = crt([
                        ZZ(A*inverse(m, n)%n),
                        ZZ(A_*inverse(m, n_)%n_)
                    ], [n, n_])
                else:
                    s = crt([A, A_], [n, n_])
                ans = ZZ_sqrt_root(s)
                if ans:
                    dbits += str(j)
                    A = max(_[0] for _ in ans)
                    flag = True
        if not flag:
            raise Exception(f"Error[{i}], {dbits}")
    ans = int(dbits.rstrip('0')[::-1], 2)
    print(f"{ans = }")
    print(pow(233, e*ans, n))
    return ans

from pwn import *
host, port = '1.13.101.243:26592'.split(':')
io = remote(host, int(port))
io = process('./server.py')

io.sendlineafter(b'|	[Q]uit', b'g')
io.recvuntil(b'n = ')
n = int(io.recvline().strip())
io.recvuntil(b'flag_ciphertext = ')
ct = bytes.fromhex(io.recvline().strip().decode())

sig = oracle(0)

flag = False
for tmp in trange(256):
    for index in range(1024):
        n_ = n ^^ (int(tmp)<<int(index))
        if isPrime(n_) and n_%4 == 3:
            print(tmp, index)
            flag = True
            break
    if flag:break
io.sendlineafter(b'|	[Q]uit', b'f')
io.sendlineafter(b'bytes, and index:', f'{tmp},{index}'.encode())

print(f"{ct = }")

e = 17
d = func(sig, n, e, n_)
io.close()

from Crypto.Cipher import AES
from hashlib import md5

key = bytes.fromhex(md5(str(d).encode()).hexdigest())
enc = AES.new(key, mode=AES.MODE_ECB)
flag = enc.decrypt(ct)
print(flag)
# WMCTF{F4u1t_1nj3ct1on_1n_RS4!$%@5!#$128467}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/908982.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

WMS仓库管理系统选择指南:如何确保您的仓库提高效率?

如何选择WMS仓库管理系统&#xff1f;仓库管理主要包括以下四个方面&#xff1a; 1.商品出入库管理 2.库存调拨 3.库存盘点 4.虚拟库存/实际库存管理 为了更好地管理仓库&#xff0c;我们需要确保基本的硬件设施得以满足&#xff0c;例如划分存储区域、使用货架以及进行员工培训…

Vivado2018.3版本_编译下载打包固化程序

Vivado2018.3版本_编译下载打包固化程序 概述&#xff1a; 在Vivado中开发导出硬件平台&#xff0c;然后在SDK中进行C语言的开发工作&#xff0c;然后把SDK编译生成的.elf文件加入Vivado工程中&#xff0c;编译生成.bit文件&#xff0c;转换成.mas文件&#xff0c;就可以固化到…

使用kubeadm工具升级kubernetes

一、背景&#xff1a; kubeadm部署的kubernetes集群进行升级&#xff0c;通常先升级控制节点&#xff0c;控制节点升级完成后再升级工作节点&#xff0c;本博文只升级了控制节点&#xff0c;工作节点按照相同的流程进行升级即可 环境说明&#xff1a; 主机名节点11.0.1.200k8s…

机器学习笔记之优化算法(十五)Baillon Haddad Theorem简单认识

机器学习笔记之优化算法——Baillon Haddad Theorem简单认识 引言 Baillon Haddad Theorem \text{Baillon Haddad Theorem} Baillon Haddad Theorem简单认识证明过程证明&#xff1a;条件 1 ⇒ 1 \Rightarrow 1⇒ 条件 2 2 2证明&#xff1a;条件 3 ⇒ 3 \Rightarrow 3⇒条件 1…

功率放大器的介绍和应用领域有哪些

功率放大器是将输入信号的功率放大到输出端所需水平的一种电子设备。在实际应用中&#xff0c;功率放大器被广泛使用于音频、视频、通讯等领域。下面&#xff0c;安泰电子将详细介绍功率放大器的工作原理、类型以及应用领域。 功率放大器的工作原理是将输入信号的功率放大到输出…

js 简单的页面导航

实现效果&#xff1a; 实现原理&#xff1a; 实现原理是通过创建数组里面包含对应页面的信息&#xff0c;当点击的时候为数组传递一个对象&#xff0c;里面包含要显示的信息。 跳转链接实现原理&#xff1a; 通过创建一个数组&#xff0c;里面包含所有可以跳转的页面链接名称&a…

【3Ds Max】可编辑多边形“边界”层级的简单使用

目录 示例 &#xff08;1&#xff09;挤出 &#xff08;2&#xff09;插入顶点 &#xff08;3&#xff09;切角 &#xff08;4&#xff09;利用所选内容创建图形 &#xff08;5&#xff09;封口 &#xff08;6&#xff09;桥 示例 这里我们首先创建一个长方体&#xff…

3D角色展示

先看效果&#xff1a; 再看代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>3D卡片悬停</title><style>font-face {font-family: "Exoct";src: url("htt…

解决群晖视频信息插件无法同步的问题

今天发现群晖下载的电影和电视剧没办法显示图片和相关信息&#xff0c;开始以为是升级了什么东西导致的&#xff0c;后来发现api.themoviedb.org 这个API接口ping都没法ping通&#xff0c;估计被墙了。好吧&#xff0c;重新登陆群晖修改hosts文件吧。下面一步一步来讲讲如何修改…

Adobe联创去世,没他就没有PDF,乔布斯也因他逆风翻盘

量子位 | 公众号 QbitAI Adobe联合创始人John Warnock去世了&#xff0c;享年82岁。 他是PDF格式的发明人之一&#xff0c;贡献了PDF中的核心技术PostScript—— 如果没有它&#xff0c;打印机就无法打印复杂页面。可以说&#xff0c;Warnock的这项发明&#xff0c;在上世纪…

【C++】STL——set的介绍和使用、set的构造函数、set的迭代器、set的容量和增删查改函数

文章目录 1.set的介绍2.set的使用2.1set的构造函数2.2set的迭代器2.3set的容量函数2.4set的增删查改函数 1.set的介绍 set的介绍 &#xff08;1&#xff09;set是按照一定次序存储元素的容器。 &#xff08;2&#xff09;在set中&#xff0c;元素的value也标识它(value就是key…

LTDC之外部SDRAM

1.配置外部SDRAM&#xff08;嵌入式基础知识&#xff0c;此处不做分析&#xff09; 2.编写SDRAM配置代码&#xff08;copy正点原子例程&#xff09; sdram.c#include "sdram.h" #include "fmc.h"uint8_t SDRAM_Send_Cmd(uint8_t bankx,uint8_t cmd,uint8_…

区块链与算力网络:创造未来网络的安全与共享

在数字革命的浪潮下&#xff0c;网络技术正焕发着前所未有的活力&#xff0c;而算力网络以其独特的区块链技术应用&#xff0c;为网络的安全性和资源共享带来了新的可能性。本文将带您深入探索算力网络中区块链技术的神奇应用&#xff0c;为您呈现这个充满活力和创新的网络未来…

全方位介绍SRM系统供应商采购管理

SRM系统是一种用于管理与供应商合作关系的解决方案。本文将全面介绍SRM系统供应商采购管理的概念、重要性、功能模块以及应用优势&#xff0c;以帮助企业了解如何通过SRM系统提升采购管理效率和供应链合作关系。 一、SRM系统供应商采购管理概述 1.1 什么是SRM系统供应商采购管…

19 真实的战场:如何在大型项目中涉及GUI自动化测试策略

大型全球化电商网站 GUI 测试的策略设计 组件 -> 模块 -> 端到端 1&#xff09; 首先&#xff0c;要从前端组件的级别来保证质量&#xff0c;也就是需要对那些自定义开发的组件进行完整全面的测试。通常前端组件会基于 Jest 做比较严格的单元测试。 Jest 是由 Facebook 发…

内网渗透神器CobaltStrike之Profile文件编写(十)

简介 在网络渗透测试和红队模拟攻击中&#xff0c;隐藏命令与控制&#xff08;C2&#xff09;流量的特征对于成功绕过入侵检测系统至关重要。Cobalt Strike提供了一个强大的工具——Malleable C2 profiles&#xff0c;用于自定义C2流量&#xff0c;从而使其看起来像正常的网络…

docker搭建opengrok环境2

引言&#xff1a; 虚拟机关闭后重新开启&#xff0c;理论上是需要重新启动一下docker的&#xff0c;以重新启动其中的服务。 命令基础&#xff1a; docker images&#xff1a;查看docker中现有的镜像 docker container ls -all&#xff1a;查看docker中目前在运行的containe…

Centos7 交叉编译QT5.9.9源码 AArch64架构

环境准备 centos7 镜像 下载地址&#xff1a;http://mirrors.aliyun.com/centos/7.9.2009/isos/x86_64/ aarch64交叉编译链 下载地址&#xff1a;https://releases.linaro.org/components/toolchain/binaries/7.3-2018.05/aarch64-linux-gnu/ QT5.9.9源代码 下载地址&#xff1…

现货白银投资什么的?

也许很多投资者听说过现货白银&#xff0c;但并不知道它投资的是什么&#xff0c;过程中是如何进行买卖的&#xff0c;也不知道如果参与其中&#xff0c;自己需要承担什么风险&#xff0c;最终的收益会如何。对于上述的这些问题本文&#xff0c;将为大家简单地介绍一下。 虽然现…

Linux文件类型

注意&#xff1a; 硬链接&#xff0c;与软链接相似&#xff0c;但不是特殊的文件类型。 只能引用同一文件系统中的文件。它引用的是文件在文件系统中的物理索引&#xff08;也称为inode&#xff09;。当 移动或者删除原始文件时&#xff0c;硬链接不 会被破坏&#xff0c;因为它…