【CTF-Crypto】RSA-选择明密文攻击 一文通

RSA:选择明密文攻击

关于选择明/密文攻击,其实这一般是打一套组合拳的,在网上找到了利用的思路,感觉下面这个题目是真正将这个问题实现了,所以还是非常棒的一道题,下面先了解一下该知识点:(来自laz佬博客)

  • 选择明文攻击:

image-20240509153810967

这样可以发现n 就是这两个数的公约数,推导
c 2 = 2 e + k 1 n c 4 = 4 e + k 2 n c 2 ∗ c 2 = ( 2 e + k 1 n ) ( 2 e + k 1 n ) = 4 e + 2 ∗ 2 e k 1 n + ( k 1 n ) 2 c 2 ∗ c 2 − c 4 = ( 2 e + k 1 n ) ( 2 e + k 1 n ) = 4 e + 2 ∗ 2 e k 1 n + ( k 1 n ) 2 − 4 e + k 2 n = n K ′ c_2 = 2 ^ e + k_1n\\ c_4 = 4 ^ e + k_2n\\ c_2*c_2 = (2^e + k_1n)(2^e + k_1n) = 4^e + 2*2^ek_1n + (k_1n)^2\\ c_2*c_2 - c_4 = (2^e + k_1n)(2^e + k_1n) = 4^e + 2*2^ek_1n + (k_1n)^2 - 4 ^ e + k_2n = nK' c2=2e+k1nc4=4e+k2nc2c2=(2e+k1n)(2e+k1n)=4e+22ek1n+(k1n)2c2c2c4=(2e+k1n)(2e+k1n)=4e+22ek1n+(k1n)24e+k2n=nK
同理可得c3*c3-c9 或者 c2*c2*c2 - c8 都会是上面这种结果形式

所以任意取两组的结果的最大公约数应该是n

个人踩坑:

image-20240509172300314

注意最终使用的时候 要用最小倍数互素的两个数 否则没法解n

在上面 一个是2 一个是3 gcd(2,3)=1 所以可以成功解n

下面那个 两个都是3 gcd(3,3)=3 没办法成功解n

个人感觉这一点非常重要 因为在比赛过程中 就因为这个导致没做出来

获取n之后可以进行下一步攻击了

  • 选择密文攻击

image-20240509153845855

解释:密文c是我们想要去获取的真实数据(记为flagc),其中x是我们可以去构建的数据(记为myc) 推导
m y c = x e   m o d   n y = f l a g c ∗ m y c = ( m ∗ x ) e   m o d   n 这样把 y 发给服务器解密得到的结果就是 m ∗ x 其中 x 是我们自己选择的与 n 互素的数 直接一除得到 m myc = x^e~mod~n\\ y = flagc * myc = (m*x)^e~mod~n\\ 这样把y发给服务器解密 得到的结果就是m*x 其中x是我们自己选择的与n互素的数\\ 直接一除 得到m myc=xe mod ny=flagcmyc=(mx)e mod n这样把y发给服务器解密得到的结果就是mx其中x是我们自己选择的与n互素的数直接一除得到m
下面上例题:

题目来源就是2024宁波天一永安杯,但是在复现的过程中,原始题目环境没了,所以把代码改成python本地交互进行复现

附件:

task.py:

import asyncio
import json
import websockets
from rsa_crypt import *


async def handle_client(websocket):
    p = getPrime(1024)
    q = getPrime(1024)
    e = 65537
    crypt = RsaCrypt(p, q, e)
    await websocket.send("Pls send msgs and I'll return the result")
    async for message_raw in websocket:
        try:
            msg_json = json.loads(message_raw)
            if msg_json["cmd"] == "enc":
                data = bytes.fromhex(msg_json["data"])
                if b"flag" in data:
                    await websocket.send("data can't contain \'flag\'")
                else:
                    res = crypt.enc(data)
                    if res:
                        await websocket.send(res.hex())
                    else:
                        await websocket.send("args wrong")
            elif msg_json["cmd"] == "dec":
                data = bytes.fromhex(msg_json["data"])
                res = crypt.dec(data)
                if res:
                    if b"flag" in res:
                        await websocket.send("you can't decrypt flag")
                    else:
                        await websocket.send(res.hex())
                else:
                    await websocket.send("args wrong")
            elif msg_json["cmd"] == "get_flag":
                with open("flag.txt", "rb") as file:
                    flag = file.read()
                res = crypt.enc(flag)
                await websocket.send(res.hex())
        except AttributeError as err:
            await websocket.send("AttributeError: {}".format(err))
        except KeyError as err:
            await websocket.send("KeyError: {}".format(err))
        except TypeError as err:
            await websocket.send("TypeError: {}".format(err))

async def main():
    server = await websockets.serve(handle_client, "0.0.0.0", 10002)
    await server.wait_closed()


asyncio.run(main())

分析一下附件,主要提供了三个功能:

  1. enc :输入明文 返回密文 并且输入的明文中不能包含flag
  2. dec :输入密文 返回明文 并且返回的明文中不能包含flag
  3. get_flag : 返回flag的密文

注意整套加密体系都是基于一组RSA加密的

然后这个交互方式比较新颖 是websocket,只要知道这个事情,其实还是蛮容易的,出题人给了我们交互的python文件

client.py:

import os
import websocket # pip install websocket-client
import re
import threading
import json


def handle_input(ws):
    try:
        while True:
            message = input()
            if message.lower() == 'exit':
                ws.close()
                break
            elif message.lower() == 'help':
                print("enc: enc <msg>")
                print("dec: dec <msg_enc>")
                print("get_flag: get_flag")
                print("help: help")
                print("exit: exit")
            elif message.startswith("enc"):
                pattern = re.compile(r'\s(.*?)$')
                match = pattern.search(message)
                if match:
                    data = match.group(1)
                    ws.send(json.dumps({"cmd": "enc", "data": data}))
            elif message.startswith("dec"):
                pattern = re.compile(r'\s(.*?)$')
                match = pattern.search(message)
                if match:
                    data = match.group(1)
                    ws.send(json.dumps({"cmd": "dec", "data": data}))
            elif message == 'get_flag':
                ws.send(json.dumps({"cmd": "get_flag"}))
    except websocket.WebSocketException as err:
        print(err)

def handle_recv(ws):
    try:
        while True:
            msg = ws.recv()
            print("Msg from server: {}".format(msg[1:]))
    except websocket.WebSocketException as err:
        print(err)

def main():
    # uri = "ws://localhost:10002"
    uri = input("input uri: ")
    print("type 'help' to get help")
    ws = websocket.create_connection(uri)
    input_thread = threading.Thread(target=handle_input, args=(ws,), daemon=True)
    recv_thread = threading.Thread(target=handle_recv, args=(ws,), daemon=True)
    recv_thread.start()
    input_thread.start()
    recv_thread.join()
    input_thread.join()

if __name__ == "__main__":
    main()

改后:

task.py

from rsa_crypt import *

def handle_client():
    p = getPrime(1024)
    q = getPrime(1024)
    e = 65537
    crypt = RsaCrypt(p, q, e)
    while 1 :
        cmd = input("cmd >")
        data = input("data >")
        if cmd == "enc":
            data = bytes.fromhex(data)
            if b"flag" in data:
                print("data can't contain \'flag\'")
            else:
                res = crypt.enc(data)
                if res:
                    print(res.hex())
                else:
                    print("args wrong")
        elif cmd == "dec":
            data = bytes.fromhex(data)
            res = crypt.dec(data)
            if res:
                if b"flag" in res:
                    print("you can't decrypt flag")
                else:
                    print(res.hex())
            else:
                print("args wrong")
        elif cmd == "get_flag":
            with open("flag.txt", "rb") as file:
                flag = file.read()
            res = crypt.enc(flag)
            print(res.hex())
       
if __name__ == "__main__":
    handle_client()

解题:


前置基础知识:

关于hex和int和bytes的转换问题

c2 = '0x0a6a9b7b2cb6429b0ace0486a01b0be6dfe072b1b44651e090218236b6d37b0645ed672ff68d5e7ec41cef35ff7d73987ac8caf6ad8c2a386d8fc8fb112c8804efa6b87056e90b56f46225b2e0a7227f24e40cd1ae25f59030beb0938bda2d7d841144c635db363ee0d46d2f035e7607a71921d289f3aae224e2807b3a2b924d1a7ac1749882bfcff02763d3fa59e6020d3f297d6f9b97e70e8521af8d777d621076976cb7c71c9d872177b8fa674a59629aaadcc9c0497e318360629a4273f2835562d4e44ad6b8c24e5f48d8bfec723698e10748b1b6b27f60f7a734186c744097b511cf3b0746e315b6be400a815138f333494bbcfc671766f06bf44a5183'
c2 = int(c2[2:], 16)
print(c2)

c2 = bytes.fromhex(c2)
c2 = bytes_to_long(c2)
print(c2)

上面这两个方法都是一样的


首先通过选择明文 enc 获得 n

image-20240509171833828

首先这样提取一下2 4 3 9 这个四个数字加密的结果

注意在传输的时候因为只接收16进制 所以数据的长度一定要是偶数 所以要前补0

from Crypto.Util.number import *

c2 = '18dad43498ef99bcf740fab4a0d841d47ea7d444fa43589668d459935ac5d49f33b5c9286b45b620cd47db42e8b06faac89c23fe226ea9c26fb5b376839751555f3a4e2630ed305f494c92e4a14f2f4e17f8fe8754a8983c23bada9f0ffde168ff9edfa8bad8600f4c2bdc2c7b24c2a95173d71624b7947ad20055f91f64eed289d83de9ec8cfbee9208f199600275bde66f6879f18cf31e7015eb57e8d336bcbd7eb8e288ee6f00aff0067dc5f2d1dec86b6e943a9a664f9bc551185c2aae7eb5ec8d23622f3c328cc376ea76dcc4e93b4f5e11f2faf16bb94e0f4abd27e39009edb183cb9bb9c5fafa6702fbe60e638fdad5b4414d2862a419647d4e9963c2'
# c2 = bytes.fromhex(c2)
# c2 = bytes_to_long(c2)
c2 = int(c2, 16)
c4 = '2de9d201fb272e6348b388986858564c60a363900d56062fe82aff41be9bc702d7e74670c4466d834ee7ee2974f91f894277ac6dbb188d052886b24a1a068194bbb53d60c9b3b3bb5f83f6224749ae96753b45c4a699c854d81d73ff2ef55c0cf2555b73c4e2d0d30765637a7407f13191db6e25787e3aecd7a6a756c5a272bd51117580b9e703845c9069e0ea1cd443b6c3b8735953638995f22e5bdf3eb0501a752dc765fc095cef2753fb20989890c79e3199bc2f26ef17a1a9eaa1d141625254494362c1b6055b290c358094af749110ccdf240352cf451fbc4b883e2ea870bfc8cfd50708446784dd02cfe08d0af5a6d65126c1af2f896992fba49b32a1'
c4 = bytes.fromhex(c4)
c4 = bytes_to_long(c4)
   
c3 = '36705a0d4481f6fed91c9bde14b675c43365813530b8952cc932ca92754e6b41cd49b931f1c1e17b633d72a68b5cc7b99532e3c425967aaabcca9a581614d06ceab5d06907a6a148c78c6bd784337eddf15895e871f7d8878ac834d4f59d0f0b4a849864398f44c09bbc095699bcec9ba87b39648f36d7d03984fd41b776c554d8fc128c1d2e78930d4249b51f6d58b558ef6d639e660ece301559933d311559fa2069676269d4e9442fb4926ff785d1b696f53420c64e3fea0700cf36e66db1398e352095e5e5fe251851cc2bf66bcc9ee16acab3e1379f02434e04b7a2ac373c6a82258ee88b9908ec0f670bdcbf2e57ecacd36b7acf35a3c853e4cb0ccc5f'
c9 = '044ba814c1c82f43ff7a4889e8f3413dfe4ec72c31f31ab70d576183f8faa1087a026301eeb9008315f113518df67630c2ba79bf941c5738cf78ccbe8d1452acfefc2e28731d0dce39a24d20588f27cb292e9185e73e56816e897884b12b2f857f1b9a566e5565fe2166afbfcef175dc8b8293361e29540fdbdbe6d2e7e65ea32b298576c4e400fe073a91b50ec97c7307ae7e6906c1e63361074f03f8b821bd55429f7161d7c0c05650406edaf0c94cbe26e1a442d6aa4527bdb70ce7d6d1155c9884a4cf10a78e1d68a67fdd2a919b1720a0a72fbe89da25599e0d1b04c969a549cac0d6802185f8294d35f3ecc8e51ff34052679e74e2b75667069f8ed10f'
c3 = int(c3, 16)
c9 = bytes.fromhex(c9)
c9= bytes_to_long(c9)

import gmpy2
print(gmpy2.gcd(c2 * c2 - c4, c3 * c3 - c9))

解得n之后

选择一个与n互素的x 先定为2测试一下

n = 16032715414973858391922072115505553924583249589860959102756767840433294451133495052970007553452554521932448831261452842632482022717930586378351925416682300801289110695586482452615115097726370136071224128287946142570794333305809297613875542364042636628694279973720665500782947643469013148558110483334922445477906616889670820981163140916119277042171383253155665772004573320513998731826184696725416178822833563136042551726041765924480362272382414738787726080960984488729479653680476479707779289631190083186571773329730791782347813567295448630512467064947881713508881619790565808541425379082620941932361583541190744879827
print(gmpy2.gcd(2, n))  #2和n互素  
#result = 1可以

通过交互 获得flagc密文

image-20240509173220199

然后利用返回的密文 构造新的待解密密文

#2对应的密文为c2
c2 = '18dad43498ef99bcf740fab4a0d841d47ea7d444fa43589668d459935ac5d49f33b5c9286b45b620cd47db42e8b06faac89c23fe226ea9c26fb5b376839751555f3a4e2630ed305f494c92e4a14f2f4e17f8fe8754a8983c23bada9f0ffde168ff9edfa8bad8600f4c2bdc2c7b24c2a95173d71624b7947ad20055f91f64eed289d83de9ec8cfbee9208f199600275bde66f6879f18cf31e7015eb57e8d336bcbd7eb8e288ee6f00aff0067dc5f2d1dec86b6e943a9a664f9bc551185c2aae7eb5ec8d23622f3c328cc376ea76dcc4e93b4f5e11f2faf16bb94e0f4abd27e39009edb183cb9bb9c5fafa6702fbe60e638fdad5b4414d2862a419647d4e9963c2'
c2 = int(c2, 16)
enc = c2 * flagc % n
print(hex(enc)[2:])
print(hex(enc)[2:].zfill(512))  #如果长度不合适 可以补充一下

image-20240509173437366

#结果:
flag = '0xccd8c2cef6e8cae6e8beccd8c2cefa'
print(long_to_bytes(int(flag[2:], 16)//2))  #除数就是x

拿下:

image-20240509173509038

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【可实战】被测需求理解(需求文档是啥样的、从哪些角度进行需求评审、需求分析需要分析出哪些内容、如何提高需求分析能力)

产品人员会产出一个需求文档&#xff0c;然后组织一个需求的宣讲。测试人员的任务就是在需求宣讲当中&#xff0c;分析需求有没有存在一些问题&#xff0c;然后在需求宣讲结束之后通过分析需求文档&#xff0c;分析里面的测试点并预估一个排期。 一、需求文档是什么样的&#x…

SmartEDA电路仿真软件风靡教育圈:揭秘其背后的魅力所在

在当今的电子信息时代&#xff0c;随着科技的飞速发展&#xff0c;电路设计与仿真软件在教育领域的应用越来越广泛。特别是SmartEDA这款电路仿真软件&#xff0c;以其强大的功能和直观易用的操作界面&#xff0c;赢得了众多教师的青睐。那么&#xff0c;究竟是什么原因让SmartE…

给汉字注音可以主要拼音不要声调吗?这两个注音小技巧你一定会需要

一&#xff0c;前言 在中文学习中&#xff0c;拼音是一种非常重要的工具&#xff0c;它帮助学习者正确地发音和理解汉字。然而&#xff0c;在拼音的使用中&#xff0c;一个常见的问题是是否应该包含声调。有些人认为&#xff0c;只要拼音中有声母和韵母&#xff0c;就可以准确…

如何使用client-go构建pod web shell

代码示例及原理 原理是利用websocket协议实现对pod的exec登录&#xff0c;利用client-go构造与远程apiserver的长连接&#xff0c;将对pod容器的输入和pod容器的输出重定向到我们的io方法中&#xff0c;从而实现浏览器端的虚拟终端的效果消息体结构如下 type Connection stru…

苏州金龙何以成为塞尔维亚中国客车第一品牌?研发向上服务助力!

5月7日至8日&#xff0c;一场举世瞩目的会晤在塞尔维亚举行。作为塞尔维亚中国客车第一品牌&#xff0c;苏州金龙海格客车也为当地民众绿色公共出行提供了“中国力量”。 目前&#xff0c;苏州金龙海格客车在塞尔维亚保有量近200台&#xff0c;是在塞尔维亚保有量最大的中国客车…

鸿蒙OpenHarmony开发板【快速入门】大合集

快速入门 快速入门概述 基于IDE入门 搭建开发环境 搭建Windows环境搭建Ubuntu环境配置远程访问环境创建工程并获取源码 轻量系统&#xff08;基于Hi3861开发板&#xff09; 编写“Hello World”程序编译烧录运行 小型系统&#xff08;基于Hi3516开发板&#xff09; 编写“Hell…

上海计算机学会2023年8月月赛C++丙组T2下降幂多项式

题目描述 x 的 k 次下降幂定义为 x 的下降幂多项式是由 x 的一组下降幂及系数组成的算式&#xff1a; 给定下降幂多项式 f(x) 的系数 an​,an−1​,⋯,a0​ 与一个值 m&#xff0c;请计算f(m)mod1,000,000,007。 输入格式 第一行&#xff1a;两个整数 n 与 m第二行&#xff…

数据库加密数据模糊匹配查询技术方案

文章目录 前言沙雕方案内存加载解密密文映射表 常规做法实现数据库加密算法参考 分词组合加密&#xff08;推荐&#xff09; 超神方案总结个人简介 前言 在数据安全性和查询效率之间找到平衡是许多数据管理系统所面临的挑战之一。特别是在涉及加密数据的情况下&#xff0c;如何…

数据结构之单链表的基本操作

目录 一.定义一个单链表 二.实现基本操作 1&#xff09;链表的打印 2&#xff09;链表的尾插 3&#xff09;链表的头插 4&#xff09;链表的尾删 5&#xff09;链表的头删 6&#xff09; 链表的查找 7&#xff09;在指定位置之前插入数据 8&#xff09;在指定位置之…

Android 11 输入系统之InputDispatcher和应用窗口建立联系

InputDispatcher把输入事件传给应用之前&#xff0c;需要和应用窗口建立联系&#xff0c;了解了这个过程&#xff0c;就清楚了APP进程和InputDispatcher线程也就是SystemServer进程之间是如何传输数据了 我们向窗口addView的时候&#xff0c;都会调用到ViewRootImpl的setView方…

电脑文件加密软件有哪些?口碑、安全性最好的文件加密软件

某企业的一位员工因不慎将包含敏感客户数据的电脑丢失&#xff0c;导致企业面临巨大的法律风险和经济损失。 这一事件凸显了电脑文件加密的必要性。 如果该企业事先采用了文件加密软件对敏感数据进行保护&#xff0c;即使电脑丢失&#xff0c;攻击者也无法轻易获取到文件内容…

eve 导入linux

mkdir /opt/unetlab/addons/qemu/linux-centos7 cd /opt/unetlab/addons/qemu/linux-centos7 上传hda.qcow2 /opt/unetlab/wrappers/unl_wrapper -a fixpermissions Linux images - (eve-ng.net) Due to very high demand of this section and problems with how to crea…

图像处理(二)

图像处理&#xff08;2&#xff09; 裁剪图片 from skimage import io,dataiimg io.imread(rD:\工坊\图像处理\十个勤天2.png)roiiimg[50:150,120:200,:]io.imshow(roi) 运行结果&#xff1a; 将图片进行二值化 from skimage import io,data,colorimg io.imread(r"…

在数据分析中所需要运用到的概率论知识

数据分析 前言一、总体二、样本三、统计抽样抽取的基本准则 四、随机抽样抽签法随机数法 五、分层抽样六、整群抽样七、系统抽样八、统计参数常用的分布函数参数 九、样本统计量十、样本均值和样本方差十一、描述样本集中位置的统计量样本均值样本中位数样本众数 十二、描述样本…

Calendar 366 II for Mac v2.15.5激活版:智能日历管理软件

在繁忙的工作和生活中&#xff0c;如何高效管理日程成为了许多人的难题。Calendar 366 II for Mac&#xff0c;作为一款全方位的日历管理软件&#xff0c;以其独特的功能和优秀的用户体验&#xff0c;成为您的日程好帮手。 Calendar 366 II for Mac支持多种视图模式&#xff0c…

BS-Diff | 扩散模型在骨抑制任务上的首次登场!

摘要 胸部 X 射线&#xff08;CXR&#xff09;是肺部筛查中常用的低剂量方式。然而&#xff0c;由于大约 75% 的肺部区域与骨骼重叠&#xff0c;这反过来又阻碍了疾病的检测和诊断&#xff0c;因此 CXR 的功效受到了一定程度的影响。作为一种补救措施&#xff0c;骨抑制技术已…

泛域名SSL证书购买攻略!

购买泛域名证书&#xff08;也称为通配符证书&#xff09;通常涉及以下几个步骤&#xff1a; 1. 选择证书提供商&#xff1a; 首先&#xff0c;你需要选择一个信誉良好的SSL证书提供商&#xff0c;如 Sectigo、GlobalSign、DigiCert 或者JoySSL。部分云服务提供商如华为云也提供…

冒泡排序----深刻理解版本

前面虽然向大家介绍了冒泡排序&#xff0c;但是表达的不是很清楚&#xff0c;这次我带着更深刻的理解向大家介绍以下冒泡排序。 1.冒泡排序 冒泡排序其实是一种排序算法&#xff0c;通过数据之间的相互比较将一堆混乱的数据按照升序或者降序的顺序排列。 2.解题思路 解题思…

【人工智能基础】GAN与WGAN实验

一、GAN网络概述 GAN&#xff1a;生成对抗网络。GAN网络中存在两个网络&#xff1a;G&#xff08;Generator&#xff0c;生成网络&#xff09;和D&#xff08;Discriminator&#xff0c;判别网络&#xff09;。 Generator接收一个随机的噪声z&#xff0c;通过这个噪声生成图片…

解决uniapp软键盘弹起导致页面fixed定位元素被顶上去

在移动端开发中通常导航栏需要固定在页面的最顶端&#xff0c;但当页面中有输入框且dom元素较多时&#xff0c;点击输入框弹出软键盘会促使导航栏往上移 正常情况如图一所示&#xff0c;软键盘弹起如图二所示 图一 图二 解决办法 1&#xff09;给输入框添加 :adjust-position…
最新文章