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

news2024/10/5 16:19:47

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.coloradmin.cn/o/1658308.html

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

相关文章

Telegram Premium会员有什么功能?

Telegram Premium 是 Telegram 的付费版本&#xff0c;现已上线。付费版本被定位为帮助运行平台并进一步开发它的一种方式。但除此之外&#xff0c;它对你有什么好处&#xff1f;以下是Telegram Premium中包含的八个主要功能&#xff1a; 1.没有广告。 Telegram Premium是无广…

李飞飞团队 AI4S 最新洞察:16 项创新技术汇总,覆盖生物/材料/医疗/问诊……

不久前&#xff0c;斯坦福大学 Human-Center Artificial Intelligence (HAI) 研究中心重磅发布了《2024年人工智能指数报告》。 作为斯坦福 HAI 的第七部力作&#xff0c;这份报告长达 502 页&#xff0c;全面追踪了 2023 年全球人工智能的发展趋势。相比往年&#xff0c;扩大了…

[Linux]如何在Ubuntu 22.04系統安裝Node-red?

Node-red是一個建立在Node.js上的視覺化程式設計工具&#xff0c;其常見的應用情境為建置或轉換各項硬體之間的通信協定的物聯網或工聯網場域&#xff0c;其可藉由設置來安裝第三方應用模組來建置多樣的通信協定節點&#xff0c;包含modbus in/out, mqtt in/out, websocket in/…

Java数组创建与使用

一.创建和初始化 1.数组是怎么创建的&#xff1f; 直接举例子&#xff1a; int[] arr new int[10]; 这里只简单的举一个int开辟数组的例子。 可见java数组的创建于C语言是不同的。前面是一个int[ ]就是一个数组的数据类型&#xff0c;后面的arr是数组名&#xff0c;最后[…

【代码随想录——栈与队列】

1.栈和队列理论基础 栈和队列的原理大家应该很熟悉了&#xff0c;队列是先进先出&#xff0c;栈是先进后出。 2.用栈实现队列 type MyQueue struct {head []intheadSize intstore []intstoreSize int }func Constructor() MyQueue {return MyQueue{head : make([]int,100),h…

《ESP8266通信指南》11-Lua开发环境配置

往期 《ESP8266通信指南》10-MQTT通信&#xff08;Arduino开发&#xff09;-CSDN博客 《ESP8266通信指南》9-TCP通信&#xff08;Arudino开发&#xff09;-CSDN博客 《ESP8266通信指南》8-连接WIFI&#xff08;Arduino开发&#xff09;&#xff08;非常简单&#xff09;-CSD…

qt for android 无法进入调试c++代码解决方法

1.上一篇文章介绍了qt 5.15.13配合NDK25 的解决方法&#xff0c;但是还存在一个问题是可以调试qml代码但是无法进入c代码中。 在网上进行搜索&#xff0c;得到的答案是确实存在这个问题&#xff0c;包括这个qt6版本。 2.看来这个问题没有办法了&#xff0c;静下来思考下。这个…

AI助力临沂商贸的世界语言

“你好”“Bonjour”“Hola”……“中国老板娘”能够流利运用 17 种语言&#xff0c;近日在海外爆火。借由 AI 技术的助力&#xff0c;商家在镜头前自如切换各国语言&#xff0c;与来自全球各地的外商实现无障碍的沟通交流。这种现象背后&#xff0c;是 AI 技术对传统商贸模式的…

Python 控制 Keysight (原Agilent) 直流电源

前言 直流电源是如图型号,是keysight 6631系列;由于本身直流电源的功能也不复杂,所以控制起来相对比较简单,本来不想写这篇文章的,但是想想还是做一个简单的记录吧! 硬件环境结构图: 通信方式:由于该直流电源只GPIB接口,所以是通过GPIB线与设备进行通信 实现原理: …

中国网安上市公司2023财报摘要及启示

随着国内网络安全市场越来越来越来越卷&#xff0c;出海&#xff0c;从原来的陌生遥远不看好&#xff0c;已经成为许多厂商不得不思考的一个新方向。 阻力不变。 地缘政治问题依然存在&#xff0c;沟通成本高&#xff0c;对产品成熟度要求高&#xff0c;对团队背景和公司整体能…

如何通过OMS加快大表迁移至OceanBase

OMS&#xff0c;是OceanBase官方推出的数据迁移工具&#xff0c;能够满足众多数据迁移场景的需求&#xff0c;现已成为众多用户进行数据迁移同步的重要工具。OMS不仅支持多种数据源&#xff0c;还具备全量迁移、增量同步、数据校验等功能&#xff0c;并能够对分表进行聚合操作&…

文件操作

前言&#xff1a; 文件内容属性 要向访问文件就要打开文件——>用进程来打开——>要把文件先加载到内存中——> 一个进程可以打开多个文件&#xff0c;OS中也有可能多个进程打开了多个文件 文件以多&#xff0c;就需要进行管理&#xff0c;——先描述再组织 没有被打开…

基于Spring Boot框架实现大学生选课管理系统

文章目录 源代码下载地址项目介绍项目功能界面预览 项目备注源代码下载地址 源代码下载地址 点击这里下载源码 项目介绍 项目功能 教务处管理 开课、开班审批&#xff0c;排课处理&#xff0c;班级操作&#xff0c;选课时间段管理** 使用了sql解决了开课开班的时间段的冲突…

基于PHP后台微信图书馆借书还书小程序系统设计与实现

博主介绍&#xff1a;黄菊华老师《Vue.js入门与商城开发实战》《微信小程序商城开发》图书作者&#xff0c;CSDN博客专家&#xff0c;在线教育专家&#xff0c;CSDN钻石讲师&#xff1b;专注大学生毕业设计教育和辅导。 所有项目都配有从入门到精通的基础知识视频课程&#xff…

IDM下载器激活

文章目录 1、Internet Download Manager简介2、Internet Download Managery应用3、Internet Download Managery下载 1、Internet Download Manager简介 Internet Download Manager (IDM) 是一款功能强大的下载管理软件&#xff0c;旨在帮助用户更高效地管理和加速其下载任务。它…

【硬件开发】原型设计对于成功产品开发重要性及常见阶段

电子产品的设计与开发始于原型制作阶段。这些原型虽可能与最终产品极为相似&#xff0c;但总带有实验性质&#xff0c;因为电子原型的制作过程包括对新概念、新思想及新解决方案的测试。虽然存在出错的风险&#xff0c;跳过这一阶段可能会导致不必要的开支。不擅长电子硬件设计…

CSS和JavaScript

CSS 在html中引入CSS 我们需要先在该项目先建立css文件 html引入CSS,在<head></head>中添加<link>标签 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" co…

QT--4

QT 使用定时器完成闹钟 #include "widget.h" #include "ui_widget.h"void Widget::timestart() {timer.start(1000); }void Widget::timeend() {timer.stop(); }Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(t…

电商核心技术揭秘52:数字化内容营销创新

相关系列文章 电商技术揭秘相关系列文章合集&#xff08;1&#xff09; 电商技术揭秘相关系列文章合集&#xff08;2&#xff09; 电商技术揭秘相关系列文章合集&#xff08;3&#xff09; 电商技术揭秘四十一&#xff1a;电商平台的营销系统浅析 电商技术揭秘四十二&#…

火爆开展齐力控股集团带您了解2024年第13届生物发酵展

参展企业介绍 齐力控股集团专业生产高精度卫生级不锈钢设备配件及管道所有连接件、锻造、精加工一站式服务。产品广泛适用于制药、饮料、乳制品、啤酒、生物化工等领域。所有产品均按3A、SMS、DIN、RJT、IDF、DS等标准制造&#xff0c;所有产品均达到GMP药典要求。我们是一家有…