MoeCTF

Some challenges in MoeCTF.

Posted by JBNRZ on 2023-01-02
Estimated Reading Time 50 Minutes
Words 8.8k In Total
Viewed Times

本来这是我最先参加的一次新生赛,也是第一次正式做题
但没想到 wp 拖了一个学期才整理,太忙了懒得,刚开始也没想法去整理
那时还没有确定个人方向其实也差不多有方向了,毕竟 Misc 和 Web 基本做完了

Misc

A_band

  1. 引入眼帘的 01
    A_band
  2. 2 进制转 16 进制,转 字符,得到 aaencode
    A_band
  3. aaencode 解码,base家族
    A_band
  4. base32 base58 base64
1
moectf{Why_s0_many_1nstruments?}

bell202

  1. 题目描述
1
:喂喂?这什么声音?喂?诶我调制解调器放哪了?
  1. 其实提示的很明显了,但但是还是太菜,没意识到,找到项目
    https://github.com/kamalmostafa/minimodem
    bell202
  2. kali 安装 minimodem
1
apt install minimodem

bell202
4. flag

1
moectf{zizi_U_he@rd_the_meanin9_beh1nd_the_s0und}

cccrrc

  1. crc32 碰撞
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import binascii
import string

dic = string.printable # 打印出字符表
crc1 = 0x67B2D3DF
crc2 = 0x628ABED2
crc3 = 0x6B073427
crc4 = 0x08C8DA10
for i in dic:
for j in dic:
for n in dic:
for m in dic:
s = (i + j + n + m).encode()
if crc1 == (binascii.crc32(s)):
text1 = s
if crc2 == (binascii.crc32(s)):
text2 = s
if crc3 == (binascii.crc32(s)):
text3 = s
if crc4 == (binascii.crc32(s)):
text4 = s
print(text1 + text2 + text3 + text4)
  1. flag
1
moectf{qwq_crc!}

hamming

  1. 汉明码原理
    https://www.youtube.com/watch?v=X8jsijhllIA
  2. 以传递信息 hello world 为例
    先得到二进制数据

hello wolrd
0110100001100101011011000110110001101111001000000111011101101111011100100110110001100100

发送方对数据进行处理,加入检验位,形成多个 4x4 矩阵,在 2 ^ k 处加入奇偶校验,0 号位总奇偶校验
每 11 bit 数据为一组

0 列 1 列 2 列 3 列
0
1 1 0
1 0 0
0 0 1 1

1 号位校验 1,3 列中 1 的奇偶,填入 0
2 号位校验 2,3 列中 1 的奇偶,填入 1
4 号位校验 1,3 行中 1 的奇偶,填入 0
8 号位校验 2,3 行中 1 的奇偶,填入 1

0 列 1 列 2 列 3 列
0 1 0
0 1 1 0
1 1 0 0
0 0 1 1

0 号位校验 剩余 位中 1 的奇偶,填入 1

0 列 1 列 2 列 3 列
1 0 1 0
0 1 1 0
1 1 0 0
0 0 1 1

此时为正确的信息,假设某一位数据(3,3)发生了改变
(当错误位数大于等于 2 时,无法得出正确结论)

0 列 1 列 2 列 3 列
1 0 1 0
0 1 1 0
1 1 0 1
0 0 1 1

根据 4 个块校验位,可以锁定错误位

0 列 1 列 2 列 3 列
1 0 1 0
0 1 1 0
1 1 0 x
0 0 1 1
  1. alice.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from secret import mytext#It's in alice's device. We can't know!
from polar_router import send_over_weak_noisy_channel#how it works doesn't matter, u don't need this lib
from Crypto.Util.number import bytes_to_long
from functools import reduce

def hamming_encode(bitsblock):#do u know how it works?
for t in range(4):
bitsblock[1<<t]=reduce(
lambda x,y:x^y ,
[bit for i,bit in enumerate(bitsblock) if i&(1<<t)]
)
return bitsblock

bintxt=bin(bytes_to_long(mytext))[2:]
lenbintxt=len(bintxt)
assert lenbintxt%11==0
blocks=lenbintxt//11
bitlist=list(map(int,bintxt))
raw_msg=[[0]*3+[bitlist[i]]+[0]+bitlist[i+1:i+4]+[0]+bitlist[i+4:i+11] for i in range(0,lenbintxt,11)]

encoded_msg=[hamming_encode(raw_msg[i]) for i in range(blocks)]

send_over_weak_noisy_channel(encoded_msg)#send it
  1. bob.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
from polar_router import recv_over_weak_noisy_channel#how it works doesn't matter, u don't need this lib, just ignore it
from Crypto.Util.number import long_to_bytes#really useful!

def hamming_correct(bitblock):
#you should write this function, to help polar decode the msg
#Good luck and take it easy!
pass

def decode(msg):
blocks=len(msg)
bitlist=[]
#Let's cancel the noise...
for i in range(blocks):
wrongbitpos=hamming_correct(msg[i])
msg[i][wrongbitpos]=int(not msg[i][wrongbitpos])
#add corrected bits to a big list
bitlist.extend([msg[i][3]]+msg[i][5:8]+msg[i][9:16])
#...then, decode it!
totallen=len(bitlist)
bigint=0
for i in range(totallen):
bigint<<=1
bigint+=bitlist[i]
return long_to_bytes(bigint)

noisemsg=recv_over_weak_noisy_channel()#it's a big matrix!
msg=decode(noisemsg)
print(msg)#Well done
  1. 需要利用学到的 haming code 编写 hamming_correct(bitlock)
1
2
3
4
5
6
def hamming_correct(bitblock):
flag_ = 0
for x in range(16):
if bitblock[x] == 1:
flag_ ^=x
return flag_
  1. flag
1
moectf{Oh_Bin4ry_Mag1c_1s_s0o_c0O1!}

hide-and-seek

  1. ctrl-A ctrl-C ctrl-V
1
moectf{Hey_U_ve_f0und_m3!}

Locked_bass

  1. 两次伪加密,base64 解码
1
moectf{N0w_th1s_i4_a_b@ss_U_can_u3e_to_pla9}

Misc 方向指北

  1. pdf文末 Morse 加密
1
moectf{WEL2OME_4O_MI3C_1UCKY!}

nyanyanya

  1. LSB
    nyanyanya
1
moectf{A_go0d_way_t0_h14e_in50rmation_in_ima9e3}

rabbit

  1. 文件结尾
1
U2FsdGVkX1+EPlLmNvaJK4Pe06nW0eLquWsUpdyv3fjXM2PcDBDKlXeKupnnWlFHewFEGmqpGyC1VdX8
  1. rabbit 加密
1
moectf{We1c0m3_t0_moectf_an7_3n7oy_y0urse1f}

usb

  1. script
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
import json
hiddata=[]
with open("userdata.json") as f:
data=f.read()
data=json.loads(data)
for i in data:
try:
hiddata.append(i["_source"]["layers"]["usbhid.data"])
except:
pass
normalKeys = {"04":"a", "05":"b", "06":"c", "07":"d", "08":"e", "09":"f", "0a":"g", "0b":"h", "0c":"i", "0d":"j", "0e":"k", "0f":"l", "10":"m", "11":"n", "12":"o", "13":"p", "14":"q", "15":"r", "16":"s", "17":"t", "18":"u", "19":"v", "1a":"w", "1b":"x", "1c":"y", "1d":"z","1e":"1", "1f":"2", "20":"3", "21":"4", "22":"5", "23":"6","24":"7","25":"8","26":"9","27":"0","28":"<RET>","29":"<ESC>","2a":"<DEL>", "2b":"\t","2c":"<SPACE>","2d":"-","2e":"=","2f":"[","30":"]","31":"\\","32":"<NON>","33":";","34":"'","35":"<GA>","36":",","37":".","38":"/","39":"<CAP>","3a":"<F1>","3b":"<F2>", "3c":"<F3>","3d":"<F4>","3e":"<F5>","3f":"<F6>","40":"<F7>","41":"<F8>","42":"<F9>","43":"<F10>","44":"<F11>","45":"<F12>"}

shiftKeys = {"04":"A", "05":"B", "06":"C", "07":"D", "08":"E", "09":"F", "0a":"G", "0b":"H", "0c":"I", "0d":"J", "0e":"K", "0f":"L", "10":"M", "11":"N", "12":"O", "13":"P", "14":"Q", "15":"R", "16":"S", "17":"T", "18":"U", "19":"V", "1a":"W", "1b":"X", "1c":"Y", "1d":"Z","1e":"!", "1f":"@", "20":"#", "21":"$", "22":"%", "23":"^","24":"&","25":"*","26":"(","27":")","28":"<RET>","29":"<ESC>","2a":"<DEL>", "2b":"\t","2c":"<SPACE>","2d":"_","2e":"+","2f":"{","30":"}","31":"|","32":"<NON>","33":":","34":"\"","35":"<GA>","36":"<","37":">","38":"?","39":"<CAP>","3a":"<F1>","3b":"<F2>", "3c":"<F3>","3d":"<F4>","3e":"<F5>","3f":"<F6>","40":"<F7>","41":"<F8>","42":"<F9>","43":"<F10>","44":"<F11>","45":"<F12>"}

def main():
result = ""
for press in hiddata:
if press == '':
continue
if ':' in press:
Bytes = press.split(":")
else:
Bytes = [press[i:i+2] for i in range(0, len(press), 2)]
if Bytes[0] == "00":
if Bytes[2] != "00" and normalKeys.get(Bytes[2]):
result += normalKeys[Bytes[2]]
elif int(Bytes[0],16) & 0b10 or int(Bytes[0],16) & 0b100000: # shift key is pressed.
if Bytes[2] != "00" and normalKeys.get(Bytes[2]):
result += shiftKeys[Bytes[2]]
else:
print("[-] Unknow Key : %s" % (Bytes[0]))
print("[+] Found : %s" % (result))
if __name__ == "__main__":
main()

# [+] Found : moectf{\<CAP>l\<CAP>earnee\<DEL>d_a6ou7_\<CAP>usb\<CAP>_tr@ffic}
# moectf{Learned_a6ou7_USB_tr@ffic}

what_do_you_recognize_me_by

  1. png
    png
1
moectf{You_r4c0gnize_%e!}

zip 套娃

  1. 4 位爆破,10 位掩码,伪加密
1
moectf{!zip_qwq_ZIP}

小纸条

  1. 猪圈密码
1
moectf{ILOVEMYBIGBED}

想听点啥

  1. 根据后缀名找到软件,读到flag
1
moectf{Want_s0me_mor3_mus1c?}

肥肠简单的取证

  1. base64 编码过的flag,strings直接搜
1
moectf{soo0oO0o0O0O_3asy!}

好像可能会有点难的取证

  1. volatility -f WIN-S60U4TV3ES2-20221008-092303 --profile=Win7SP1x64 cmdscan,发现利用openssl对文件进行了加密
  2. 使用镜像挂载工具挂载E01文件,会发现有一个盘被Bitlocker锁定。先不管,复制挂载的系统盘下的recover_key_encryped,使用openssl解密
  3. openssl enc -aes-128-ecb -d -a -in .\recover_key_encryped -out de.txt -nosalt ,密码为 ‘zhebushikey’ 包括引号
  4. 理论上来说可以直接加上 -pass pass:‘zhebushikey’,但是我这里总是莫名其妙报bad encrypt
  5. 解密后得到Bitlock密钥,揭开后看到根目录有flag.txt
  6. 镜像挂载工具推荐Arsenal Image Mounter,FTK老是有莫名其妙的问题
  7. 这题同样可以逃课,DiskGenius可以直接恢复出未加密的Bitlock密钥,直接解锁即可

Web

ezhtml

  1. f12

cookiehead

  1. 加参

God_of_Aim

  1. 控制台传参;看js

What are you uploading

  1. 抓包;前端校验

inclusion

  1. php伪协议,
1
php://filter/read=convert.base64-encode/resource=flag.php

sqlmap_boy

  1. 如题怎么说呢,一直不会用sqlmap

ezphp

  1. 要传入flag,get和post都行,否则会执行 exit($giveme)
  2. flag的内容不能是flag,否则会执行 exit($getout)
  3. 这里就出现了矛盾的点:当你传入flag值的时候,原来的flag值会被覆盖掉
    怎么解决呢?这就涉及到php中双美元变量和单美元变量的区别了。举例来说,如果已经有单美元变量$ikun=f1ag,那么双美元变量 $$ikun=moectf将会先把里面的$ikun替换成f1ag,因此,双美元变量的赋值语句也就变成了$f1ag=moectf
  4. 知道了这一点,再结合 foreach ($_GET as $key => $value) 这一栏,我们就可以实现变量值的交换
  5. 注意,这里不能用post传入变量,因为post传入的参数并不能实现变量交换
  6. 地址栏后加上?moectf=flag&flag=moectf,flag就出来了
  7. 顺序很重要!必须要先用另一个变量把flag的值储存起来,否则flag一样会被覆盖
  8. index.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php

highlight_file('source.txt');
echo "<br><br>";
$flag = 'moectf{Wa0g_Yi1g_Chu0}';
$giveme = 'can can need flag!';
$getout = 'No! flag.Try again. Come on!';
if(!isset($_GET['flag']) && !isset($_POST['flag'])){
exit($giveme);
}
if($_POST['flag'] === 'flag' || $_GET['flag'] === 'flag'){
exit($getout);
}
foreach ($_POST as $key => $value) {
$$key = $value;
}
foreach ($_GET as $key => $value) {
$$key = $$value;
}
echo 'the flag is : ' . $flag;

支付系统要耐心审计啊

  1. 观察源码,发现程序会将post进callback的data值和最终的data值进行哈希校验,而显然app.secret_key是未知的,不能从这里下手。细看了一阵子发现do_callback里面data的格式有点问题,是直接拼接,又看到有个desc,猜测是通过修改amount, status和desc来使拼接后得到相同的字符串
  2. 打开burpsuite,访问/pay,并且post进amount和desc。注意此时stastus会被设置为PENDING,也就是1,则此时data后半部分为amonut+‘1’+desc
  3. 此时,页面被重定向至/transaction?id=1,这里的id就是一会要传进去的id。页面上有你的uuid和一个二维码,扫一下二维码,发现得到的值像是hash加密的值 。又看到/callback部分要求传入hash值,猜测这个就是目前data的hash值
  4. 注意,程序执行过程中有一次会将status设为FAILED,也就是2。因此我们要让现在amonut+‘2’+desc等于之前的值才行
  5. 那么,显然amout的结尾要是2,desc则没有要求,最终传入/callback时删去amount结尾的2,然后在desc前面加个1就行
1
2
amount="12" status="1" desc="12345"   amount+status+desc="12112345" //pay
amount="1" status="2" desc="12345" amount+status+desc="12112345" //callback
  1. 访问/callback,并将现有的id, user, amount, status, desc, hash全部丢进去,看到返回ok,说明我们做出来了,访问/flag得到flag
  2. app.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
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
import os
import uuid
from quart import Quart, render_template, redirect, jsonify, request, session
from hashlib import pbkdf2_hmac
from enum import IntEnum
from tortoise import fields
from tortoise.models import Model
from tortoise.contrib.quart import register_tortoise
from httpx import AsyncClient

app = Quart(__name__)
app.secret_key = os.urandom(16)


class TransactionStatus(IntEnum):
SUCCESS = 0
PENDING = 1
FAILED = 2
TIMEOUT = 3


class Transaction(Model):
id = fields.IntField(pk=True)
user = fields.UUIDField()
amount = fields.IntField()
status = fields.IntEnumField(TransactionStatus)
desc = fields.TextField()
hash = fields.CharField(64, null=True)

def __init__(self, **kwargs):
super().__init__()
for k, v in kwargs.items():
self.__setattr__(k, v)


async def do_callback(transaction: Transaction):
async with AsyncClient() as ses:
transaction.status = int(TransactionStatus.FAILED)
data = (
f'{transaction.id}'
f'{transaction.user}'
f'{transaction.amount}'
f'{transaction.status}'
f'{transaction.desc}'
).encode()
await ses.post(f'http://localhost:8000/callback', data={
'id': transaction.id,
'user': transaction.user,
'amount': transaction.amount,
'desc': transaction.desc,
'status': transaction.status,
'hash': pbkdf2_hmac('sha256', data, app.secret_key, 2**20).hex()
})


@app.before_request
async def create_session():
if 'uid' not in session:
session['uid'] = str(uuid.uuid4())
session['balance'] = 0
for tr in await Transaction.filter(user=session['uid']).all():
if tr.status == TransactionStatus.SUCCESS:
session['balance'] += tr.amount


@app.route('/pay')
async def pay():
transaction = await Transaction.create(
amount=request.args.get('amount'),
desc=request.args.get('desc'),
status=TransactionStatus.PENDING,
user=uuid.UUID(session.get('uid'))
)
app.add_background_task(do_callback, transaction)
return redirect(f'/transaction?id={transaction.id}')


@app.route('/callback', methods=['POST'])
async def callback():
form = dict(await request.form)
data = (
f'{form.get("id")}'
f'{form.get("user")}'
f'{form.get("amount")}'
f'{form.get("status")}'
f'{form.get("desc")}'
).encode()
k = pbkdf2_hmac('sha256', data, app.secret_key, 2**20).hex()
tr = await Transaction.get(id=int(form.pop('id')))
if k != form.get("hash"):
return '403'
form['status'] = TransactionStatus(int(form.pop('status')))
tr.update_from_dict(form)
await tr.save()
return 'ok'


@app.route('/transaction')
async def transaction():
if 'id' not in request.args:
return '404'
transaction = await Transaction.get(id=request.args.get('id'))
return await render_template('receipt.html', transaction=transaction)


@app.route('/flag')
async def flag():
return await render_template(
'flag.html',
balance=session['balance'],
flag=os.getenv('FLAG'),
)


@app.route('/')
@app.route('/index.html')
async def index():
with open(__file__) as f:
return await render_template('source-highlight.html', code=f.read())


register_tortoise(
app,
db_url="sqlite://./data.db",
modules={"models": [__name__]},
generate_schemas=True,
)

if __name__ == '__main__':
app.run()

Reverse

checkin

  1. 16 进制
1
moectf{Enjoy_yourself_in_Reverse_Engineering!!!}

begin

  1. 异或比较
1
2
3
a = [116,118,124,122,109,127,98,65,41,107,70,40,106,70,106,41,70,112,119,109,42,107,42,106,109,112,119,126,56,56,56,56,56,100]
a = ''.join([chr(i ^ 0x19) for i in a])
print(a)
  1. flag
1
moectf{X0r_1s_s0_int3r3sting!!!!!}

EquationPy

  1. 反编译 .pyc
1
2
3
4
5
6
7
8
9
10
11
#!/usr/bin/env python
# visit https://tool.lu/pyc/ for more information
# Version: Python 3.8

print('Maybe z3 can help you solve this challenge.')
print('Now give me your flag, and I will check for you.')
flag = input('Input your flag:')
if len(flag) == 22 and ord(flag[0]) * 7072 + ord(flag[1]) * 2523 + ord(flag[2]) * 6714 + ord(flag[3]) * 8810 + ord(flag[4]) * 6796 + ord(flag[5]) * 2647 + ord(flag[6]) * 1347 + ord(flag[7]) * 1289 + ord(flag[8]) * 8917 + ord(flag[9]) * 2304 + ord(flag[10]) * 5001 + ord(flag[11]) * 2882 + ord(flag[12]) * 7232 + ord(flag[13]) * 3192 + ord(flag[14]) * 9676 + ord(flag[15]) * 5436 + ord(flag[16]) * 4407 + ord(flag[17]) * 6269 + ord(flag[18]) * 9623 + ord(flag[19]) * 6230 + ord(flag[20]) * 6292 + ord(flag[21]) * 57 == 10743134 and ord(flag[0]) * 3492 + ord(flag[1]) * 1613 + ord(flag[2]) * 3234 + ord(flag[3]) * 5656 + ord(flag[4]) * 9182 + ord(flag[5]) * 4240 + ord(flag[6]) * 8808 + ord(flag[7]) * 9484 + ord(flag[8]) * 4000 + ord(flag[9]) * 1475 + ord(flag[10]) * 2616 + ord(flag[11]) * 2766 + ord(flag[12]) * 6822 + ord(flag[13]) * 1068 + ord(flag[14]) * 9768 + ord(flag[15]) * 1420 + ord(flag[16]) * 4528 + ord(flag[17]) * 1031 + ord(flag[18]) * 8388 + ord(flag[19]) * 2029 + ord(flag[20]) * 2463 + ord(flag[21]) * 32 == 9663091 and ord(flag[0]) * 9661 + ord(flag[1]) * 1108 + ord(flag[2]) * 2229 + ord(flag[3]) * 1256 + ord(flag[4]) * 7747 + ord(flag[5]) * 5775 + ord(flag[6]) * 5211 + ord(flag[7]) * 2387 + ord(flag[8]) * 1997 + ord(flag[9]) * 4045 + ord(flag[10]) * 7102 + ord(flag[11]) * 7853 + ord(flag[12]) * 5596 + ord(flag[13]) * 6952 + ord(flag[14]) * 8883 + ord(flag[15]) * 5125 + ord(flag[16]) * 9572 + ord(flag[17]) * 1149 + ord(flag[18]) * 7583 + ord(flag[19]) * 1075 + ord(flag[20]) * 9804 + ord(flag[21]) * 72 == 10521461 and ord(flag[0]) * 4314 + ord(flag[1]) * 3509 + ord(flag[2]) * 6200 + ord(flag[3]) * 5546 + ord(flag[4]) * 1705 + ord(flag[5]) * 9518 + ord(flag[6]) * 2975 + ord(flag[7]) * 2689 + ord(flag[8]) * 2412 + ord(flag[9]) * 8659 + ord(flag[10]) * 5459 + ord(flag[11]) * 7572 + ord(flag[12]) * 3042 + ord(flag[13]) * 9701 + ord(flag[14]) * 4697 + ord(flag[15]) * 9863 + ord(flag[16]) * 1296 + ord(flag[17]) * 1278 + ord(flag[18]) * 5721 + ord(flag[19]) * 5116 + ord(flag[20]) * 4147 + ord(flag[21]) * 52 == 9714028 and ord(flag[0]) * 2310 + ord(flag[1]) * 1379 + ord(flag[2]) * 5900 + ord(flag[3]) * 4876 + ord(flag[4]) * 5329 + ord(flag[5]) * 6485 + ord(flag[6]) * 6610 + ord(flag[7]) * 7179 + ord(flag[8]) * 7897 + ord(flag[9]) * 1094 + ord(flag[10]) * 4825 + ord(flag[11]) * 8101 + ord(flag[12]) * 9519 + ord(flag[13]) * 3048 + ord(flag[14]) * 3168 + ord(flag[15]) * 2775 + ord(flag[16]) * 4366 + ord(flag[17]) * 4066 + ord(flag[18]) * 7490 + ord(flag[19]) * 5533 + ord(flag[20]) * 2139 + ord(flag[21]) * 87 == 10030960 and ord(flag[0]) * 1549 + ord(flag[1]) * 8554 + ord(flag[2]) * 6510 + ord(flag[3]) * 6559 + ord(flag[4]) * 5570 + ord(flag[5]) * 1003 + ord(flag[6]) * 8562 + ord(flag[7]) * 6793 + ord(flag[8]) * 3509 + ord(flag[9]) * 4965 + ord(flag[10]) * 6111 + ord(flag[11]) * 1229 + ord(flag[12]) * 5654 + ord(flag[13]) * 2204 + ord(flag[14]) * 2217 + ord(flag[15]) * 5039 + ord(flag[16]) * 5657 + ord(flag[17]) * 9426 + ord(flag[18]) * 7604 + ord(flag[19]) * 5883 + ord(flag[20]) * 5285 + ord(flag[21]) * 17 == 10946682 and ord(flag[0]) * 2678 + ord(flag[1]) * 4369 + ord(flag[2]) * 7509 + ord(flag[3]) * 1564 + ord(flag[4]) * 7777 + ord(flag[5]) * 2271 + ord(flag[6]) * 9696 + ord(flag[7]) * 3874 + ord(flag[8]) * 2212 + ord(flag[9]) * 6764 + ord(flag[10]) * 5727 + ord(flag[11]) * 5971 + ord(flag[12]) * 5876 + ord(flag[13]) * 9959 + ord(flag[14]) * 4604 + ord(flag[15]) * 8461 + ord(flag[16]) * 2350 + ord(flag[17]) * 3564 + ord(flag[18]) * 1831 + ord(flag[19]) * 6088 + ord(flag[20]) * 4575 + ord(flag[21]) * 9 == 10286414 and ord(flag[0]) * 8916 + ord(flag[1]) * 8647 + ord(flag[2]) * 4522 + ord(flag[3]) * 3579 + ord(flag[4]) * 5319 + ord(flag[5]) * 9124 + ord(flag[6]) * 9535 + ord(flag[7]) * 5125 + ord(flag[8]) * 3235 + ord(flag[9]) * 3246 + ord(flag[10]) * 3378 + ord(flag[11]) * 9221 + ord(flag[12]) * 1875 + ord(flag[13]) * 1008 + ord(flag[14]) * 6262 + ord(flag[15]) * 1524 + ord(flag[16]) * 8851 + ord(flag[17]) * 4367 + ord(flag[18]) * 7628 + ord(flag[19]) * 9404 + ord(flag[20]) * 2065 + ord(flag[21]) * 9 == 11809388 and ord(flag[0]) * 9781 + ord(flag[1]) * 9174 + ord(flag[2]) * 3771 + ord(flag[3]) * 6972 + ord(flag[4]) * 6425 + ord(flag[5]) * 7631 + ord(flag[6]) * 8864 + ord(flag[7]) * 9117 + ord(flag[8]) * 4328 + ord(flag[9]) * 3919 + ord(flag[10]) * 6517 + ord(flag[11]) * 7165 + ord(flag[12]) * 6895 + ord(flag[13]) * 3609 + ord(flag[14]) * 3878 + ord(flag[15]) * 1593 + ord(flag[16]) * 9098 + ord(flag[17]) * 6432 + ord(flag[18]) * 2584 + ord(flag[19]) * 8403 + ord(flag[20]) * 4029 + ord(flag[21]) * 30 == 13060508 and ord(flag[0]) * 2511 + ord(flag[1]) * 8583 + ord(flag[2]) * 2428 + ord(flag[3]) * 9439 + ord(flag[4]) * 3662 + ord(flag[5]) * 3278 + ord(flag[6]) * 8305 + ord(flag[7]) * 1100 + ord(flag[8]) * 7972 + ord(flag[9]) * 8510 + ord(flag[10]) * 8552 + ord(flag[11]) * 9993 + ord(flag[12]) * 6855 + ord(flag[13]) * 1702 + ord(flag[14]) * 1640 + ord(flag[15]) * 3787 + ord(flag[16]) * 8161 + ord(flag[17]) * 2110 + ord(flag[18]) * 5320 + ord(flag[19]) * 3313 + ord(flag[20]) * 9286 + ord(flag[21]) * 74 == 10568195 and ord(flag[0]) * 4974 + ord(flag[1]) * 4445 + ord(flag[2]) * 7368 + ord(flag[3]) * 9132 + ord(flag[4]) * 5894 + ord(flag[5]) * 7822 + ord(flag[6]) * 7923 + ord(flag[7]) * 6822 + ord(flag[8]) * 2698 + ord(flag[9]) * 3643 + ord(flag[10]) * 8392 + ord(flag[11]) * 4126 + ord(flag[12]) * 1941 + ord(flag[13]) * 6641 + ord(flag[14]) * 2949 + ord(flag[15]) * 7405 + ord(flag[16]) * 9980 + ord(flag[17]) * 6349 + ord(flag[18]) * 3328 + ord(flag[19]) * 8766 + ord(flag[20]) * 9508 + ord(flag[21]) * 65 == 12514783 and ord(flag[0]) * 4127 + ord(flag[1]) * 4703 + ord(flag[2]) * 6409 + ord(flag[3]) * 4907 + ord(flag[4]) * 5230 + ord(flag[5]) * 3371 + ord(flag[6]) * 5666 + ord(flag[7]) * 3194 + ord(flag[8]) * 5448 + ord(flag[9]) * 8415 + ord(flag[10]) * 4525 + ord(flag[11]) * 4152 + ord(flag[12]) * 1467 + ord(flag[13]) * 5254 + ord(flag[14]) * 2256 + ord(flag[15]) * 1643 + ord(flag[16]) * 9113 + ord(flag[17]) * 8805 + ord(flag[18]) * 4315 + ord(flag[19]) * 8371 + ord(flag[20]) * 1919 + ord(flag[21]) * 2 == 10299950 and ord(flag[0]) * 6245 + ord(flag[1]) * 8783 + ord(flag[2]) * 6059 + ord(flag[3]) * 9375 + ord(flag[4]) * 9253 + ord(flag[5]) * 1974 + ord(flag[6]) * 8867 + ord(flag[7]) * 6423 + ord(flag[8]) * 2577 + ord(flag[9]) * 6613 + ord(flag[10]) * 2040 + ord(flag[11]) * 2209 + ord(flag[12]) * 4147 + ord(flag[13]) * 7151 + ord(flag[14]) * 1011 + ord(flag[15]) * 9446 + ord(flag[16]) * 4362 + ord(flag[17]) * 3073 + ord(flag[18]) * 3006 + ord(flag[19]) * 5499 + ord(flag[20]) * 8850 + ord(flag[21]) * 23 == 11180727 and ord(flag[0]) * 1907 + ord(flag[1]) * 9038 + ord(flag[2]) * 3932 + ord(flag[3]) * 7054 + ord(flag[4]) * 1135 + ord(flag[5]) * 5095 + ord(flag[6]) * 6962 + ord(flag[7]) * 6481 + ord(flag[8]) * 7049 + ord(flag[9]) * 5995 + ord(flag[10]) * 6233 + ord(flag[11]) * 1321 + ord(flag[12]) * 4455 + ord(flag[13]) * 8181 + ord(flag[14]) * 5757 + ord(flag[15]) * 6953 + ord(flag[16]) * 3167 + ord(flag[17]) * 5508 + ord(flag[18]) * 4602 + ord(flag[19]) * 1420 + ord(flag[20]) * 3075 + ord(flag[21]) * 25 == 10167536 and ord(flag[0]) * 1489 + ord(flag[1]) * 9236 + ord(flag[2]) * 7398 + ord(flag[3]) * 4088 + ord(flag[4]) * 4131 + ord(flag[5]) * 1657 + ord(flag[6]) * 9068 + ord(flag[7]) * 6420 + ord(flag[8]) * 3970 + ord(flag[9]) * 3265 + ord(flag[10]) * 5343 + ord(flag[11]) * 5386 + ord(flag[12]) * 2583 + ord(flag[13]) * 2813 + ord(flag[14]) * 7181 + ord(flag[15]) * 9116 + ord(flag[16]) * 4836 + ord(flag[17]) * 6917 + ord(flag[18]) * 1123 + ord(flag[19]) * 7276 + ord(flag[20]) * 2257 + ord(flag[21]) * 65 == 10202212 and ord(flag[0]) * 2097 + ord(flag[1]) * 1253 + ord(flag[2]) * 1469 + ord(flag[3]) * 2731 + ord(flag[4]) * 9565 + ord(flag[5]) * 9185 + ord(flag[6]) * 1095 + ord(flag[7]) * 8666 + ord(flag[8]) * 2919 + ord(flag[9]) * 7962 + ord(flag[10]) * 1497 + ord(flag[11]) * 6642 + ord(flag[12]) * 4108 + ord(flag[13]) * 6892 + ord(flag[14]) * 7161 + ord(flag[15]) * 7552 + ord(flag[16]) * 5666 + ord(flag[17]) * 4060 + ord(flag[18]) * 7799 + ord(flag[19]) * 5080 + ord(flag[20]) * 8516 + ord(flag[21]) * 43 == 10435786 and ord(flag[0]) * 1461 + ord(flag[1]) * 1676 + ord(flag[2]) * 4755 + ord(flag[3]) * 7982 + ord(flag[4]) * 3860 + ord(flag[5]) * 1067 + ord(flag[6]) * 6715 + ord(flag[7]) * 4019 + ord(flag[8]) * 4983 + ord(flag[9]) * 2031 + ord(flag[10]) * 1173 + ord(flag[11]) * 2241 + ord(flag[12]) * 2594 + ord(flag[13]) * 8672 + ord(flag[14]) * 4810 + ord(flag[15]) * 7963 + ord(flag[16]) * 7749 + ord(flag[17]) * 5730 + ord(flag[18]) * 9855 + ord(flag[19]) * 5858 + ord(flag[20]) * 2349 + ord(flag[21]) * 71 == 9526385 and ord(flag[0]) * 9025 + ord(flag[1]) * 9536 + ord(flag[2]) * 1515 + ord(flag[3]) * 8177 + ord(flag[4]) * 6109 + ord(flag[5]) * 4856 + ord(flag[6]) * 6692 + ord(flag[7]) * 4929 + ord(flag[8]) * 1010 + ord(flag[9]) * 3995 + ord(flag[10]) * 3511 + ord(flag[11]) * 5910 + ord(flag[12]) * 3501 + ord(flag[13]) * 3731 + ord(flag[14]) * 6601 + ord(flag[15]) * 6200 + ord(flag[16]) * 8177 + ord(flag[17]) * 5488 + ord(flag[18]) * 5957 + ord(flag[19]) * 9661 + ord(flag[20]) * 4956 + ord(flag[21]) * 48 == 11822714 and ord(flag[0]) * 4462 + ord(flag[1]) * 1940 + ord(flag[2]) * 5956 + ord(flag[3]) * 4965 + ord(flag[4]) * 9268 + ord(flag[5]) * 9627 + ord(flag[6]) * 3564 + ord(flag[7]) * 5417 + ord(flag[8]) * 2039 + ord(flag[9]) * 7269 + ord(flag[10]) * 9667 + ord(flag[11]) * 4158 + ord(flag[12]) * 2856 + ord(flag[13]) * 2851 + ord(flag[14]) * 9696 + ord(flag[15]) * 5986 + ord(flag[16]) * 6237 + ord(flag[17]) * 5845 + ord(flag[18]) * 5467 + ord(flag[19]) * 5227 + ord(flag[20]) * 4771 + ord(flag[21]) * 72 == 11486796 and ord(flag[0]) * 4618 + ord(flag[1]) * 8621 + ord(flag[2]) * 8144 + ord(flag[3]) * 7115 + ord(flag[4]) * 1577 + ord(flag[5]) * 8602 + ord(flag[6]) * 3886 + ord(flag[7]) * 3712 + ord(flag[8]) * 1258 + ord(flag[9]) * 7063 + ord(flag[10]) * 1872 + ord(flag[11]) * 9855 + ord(flag[12]) * 4167 + ord(flag[13]) * 7615 + ord(flag[14]) * 6298 + ord(flag[15]) * 7682 + ord(flag[16]) * 8795 + ord(flag[17]) * 3856 + ord(flag[18]) * 6217 + ord(flag[19]) * 5764 + ord(flag[20]) * 5076 + ord(flag[21]) * 93 == 11540145 and ord(flag[0]) * 7466 + ord(flag[1]) * 8442 + ord(flag[2]) * 4822 + ord(flag[3]) * 7639 + ord(flag[4]) * 2049 + ord(flag[5]) * 7311 + ord(flag[6]) * 5816 + ord(flag[7]) * 8433 + ord(flag[8]) * 5905 + ord(flag[9]) * 4838 + ord(flag[10]) * 1251 + ord(flag[11]) * 8184 + ord(flag[12]) * 6465 + ord(flag[13]) * 4634 + ord(flag[14]) * 5513 + ord(flag[15]) * 3160 + ord(flag[16]) * 6720 + ord(flag[17]) * 9205 + ord(flag[18]) * 6671 + ord(flag[19]) * 7716 + ord(flag[20]) * 1905 + ord(flag[21]) * 29 == 12227250 and ord(flag[0]) * 5926 + ord(flag[1]) * 9095 + ord(flag[2]) * 2048 + ord(flag[3]) * 4639 + ord(flag[4]) * 3035 + ord(flag[5]) * 9560 + ord(flag[6]) * 1591 + ord(flag[7]) * 2392 + ord(flag[8]) * 1812 + ord(flag[9]) * 6732 + ord(flag[10]) * 9454 + ord(flag[11]) * 8175 + ord(flag[12]) * 7346 + ord(flag[13]) * 6333 + ord(flag[14]) * 9812 + ord(flag[15]) * 2034 + ord(flag[16]) * 6634 + ord(flag[17]) * 1762 + ord(flag[18]) * 7058 + ord(flag[19]) * 3524 + ord(flag[20]) * 7462 + ord(flag[21]) * 11 == 11118093:
print('Congratulate!!!You are right!')
else:
print('What a pity...Please try again >__<')
  1. solve
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
from z3 import *

flag = [Int("input[%d]"%i) for i in range(22)]

s = Solver()
s.add(flag[0] * 7072 + flag[1] * 2523 + flag[2] * 6714 + flag[3] * 8810 + flag[4] * 6796 + flag[5] * 2647 + flag[6] * 1347 + flag[7] * 1289 + flag[8] * 8917 + flag[9] * 2304 + flag[10] * 5001 + flag[11] * 2882 + flag[12] * 7232 + flag[13] * 3192 + flag[14] * 9676 + flag[15] * 5436 + flag[16] * 4407 + flag[17] * 6269 + flag[18] * 9623 + flag[19] * 6230 + flag[20] * 6292 + flag[21] * 57 == 10743134)
s.add(flag[0] * 3492 + flag[1] * 1613 + flag[2] * 3234 + flag[3] * 5656 + flag[4] * 9182 + flag[5] * 4240 + flag[6] * 8808 + flag[7] * 9484 + flag[8] * 4000 + flag[9] * 1475 + flag[10] * 2616 + flag[11] * 2766 + flag[12] * 6822 + flag[13] * 1068 + flag[14] * 9768 + flag[15] * 1420 + flag[16] * 4528 + flag[17] * 1031 + flag[18] * 8388 + flag[19] * 2029 + flag[20] * 2463 + flag[21] * 32 == 9663091)
s.add(flag[0] * 9661 + flag[1] * 1108 + flag[2] * 2229 + flag[3] * 1256 + flag[4] * 7747 + flag[5] * 5775 + flag[6] * 5211 + flag[7] * 2387 + flag[8] * 1997 + flag[9] * 4045 + flag[10] * 7102 + flag[11] * 7853 + flag[12] * 5596 + flag[13] * 6952 + flag[14] * 8883 + flag[15] * 5125 + flag[16] * 9572 + flag[17] * 1149 + flag[18] * 7583 + flag[19] * 1075 + flag[20] * 9804 + flag[21] * 72 == 10521461)
s.add(flag[0] * 4314 + flag[1] * 3509 + flag[2] * 6200 + flag[3] * 5546 + flag[4] * 1705 + flag[5] * 9518 + flag[6] * 2975 + flag[7] * 2689 + flag[8] * 2412 + flag[9] * 8659 + flag[10] * 5459 + flag[11] * 7572 + flag[12] * 3042 + flag[13] * 9701 + flag[14] * 4697 + flag[15] * 9863 + flag[16] * 1296 + flag[17] * 1278 + flag[18] * 5721 + flag[19] * 5116 + flag[20] * 4147 + flag[21] * 52 == 9714028)
s.add(flag[0] * 2310 + flag[1] * 1379 + flag[2] * 5900 + flag[3] * 4876 + flag[4] * 5329 + flag[5] * 6485 + flag[6] * 6610 + flag[7] * 7179 + flag[8] * 7897 + flag[9] * 1094 + flag[10] * 4825 + flag[11] * 8101 + flag[12] * 9519 + flag[13] * 3048 + flag[14] * 3168 + flag[15] * 2775 + flag[16] * 4366 + flag[17] * 4066 + flag[18] * 7490 + flag[19] * 5533 + flag[20] * 2139 + flag[21] * 87 == 10030960)
s.add(flag[0] * 1549 + flag[1] * 8554 + flag[2] * 6510 + flag[3] * 6559 + flag[4] * 5570 + flag[5] * 1003 + flag[6] * 8562 + flag[7] * 6793 + flag[8] * 3509 + flag[9] * 4965 + flag[10] * 6111 + flag[11] * 1229 + flag[12] * 5654 + flag[13] * 2204 + flag[14] * 2217 + flag[15] * 5039 + flag[16] * 5657 + flag[17] * 9426 + flag[18] * 7604 + flag[19] * 5883 + flag[20] * 5285 + flag[21] * 17 == 10946682)
s.add(flag[0] * 2678 + flag[1] * 4369 + flag[2] * 7509 + flag[3] * 1564 + flag[4] * 7777 + flag[5] * 2271 + flag[6] * 9696 + flag[7] * 3874 + flag[8] * 2212 + flag[9] * 6764 + flag[10] * 5727 + flag[11] * 5971 + flag[12] * 5876 + flag[13] * 9959 + flag[14] * 4604 + flag[15] * 8461 + flag[16] * 2350 + flag[17] * 3564 + flag[18] * 1831 + flag[19] * 6088 + flag[20] * 4575 + flag[21] * 9 == 10286414)
s.add(flag[0] * 8916 + flag[1] * 8647 + flag[2] * 4522 + flag[3] * 3579 + flag[4] * 5319 + flag[5] * 9124 + flag[6] * 9535 + flag[7] * 5125 + flag[8] * 3235 + flag[9] * 3246 + flag[10] * 3378 + flag[11] * 9221 + flag[12] * 1875 + flag[13] * 1008 + flag[14] * 6262 + flag[15] * 1524 + flag[16] * 8851 + flag[17] * 4367 + flag[18] * 7628 + flag[19] * 9404 + flag[20] * 2065 + flag[21] * 9 == 11809388)
s.add(flag[0] * 9781 + flag[1] * 9174 + flag[2] * 3771 + flag[3] * 6972 + flag[4] * 6425 + flag[5] * 7631 + flag[6] * 8864 + flag[7] * 9117 + flag[8] * 4328 + flag[9] * 3919 + flag[10] * 6517 + flag[11] * 7165 + flag[12] * 6895 + flag[13] * 3609 + flag[14] * 3878 + flag[15] * 1593 + flag[16] * 9098 + flag[17] * 6432 + flag[18] * 2584 + flag[19] * 8403 + flag[20] * 4029 + flag[21] * 30 == 13060508)
s.add(flag[0] * 2511 + flag[1] * 8583 + flag[2] * 2428 + flag[3] * 9439 + flag[4] * 3662 + flag[5] * 3278 + flag[6] * 8305 + flag[7] * 1100 + flag[8] * 7972 + flag[9] * 8510 + flag[10] * 8552 + flag[11] * 9993 + flag[12] * 6855 + flag[13] * 1702 + flag[14] * 1640 + flag[15] * 3787 + flag[16] * 8161 + flag[17] * 2110 + flag[18] * 5320 + flag[19] * 3313 + flag[20] * 9286 + flag[21] * 74 == 10568195)
s.add(flag[0] * 4974 + flag[1] * 4445 + flag[2] * 7368 + flag[3] * 9132 + flag[4] * 5894 + flag[5] * 7822 + flag[6] * 7923 + flag[7] * 6822 + flag[8] * 2698 + flag[9] * 3643 + flag[10] * 8392 + flag[11] * 4126 + flag[12] * 1941 + flag[13] * 6641 + flag[14] * 2949 + flag[15] * 7405 + flag[16] * 9980 + flag[17] * 6349 + flag[18] * 3328 + flag[19] * 8766 + flag[20] * 9508 + flag[21] * 65 == 12514783)
s.add(flag[0] * 4127 + flag[1] * 4703 + flag[2] * 6409 + flag[3] * 4907 + flag[4] * 5230 + flag[5] * 3371 + flag[6] * 5666 + flag[7] * 3194 + flag[8] * 5448 + flag[9] * 8415 + flag[10] * 4525 + flag[11] * 4152 + flag[12] * 1467 + flag[13] * 5254 + flag[14] * 2256 + flag[15] * 1643 + flag[16] * 9113 + flag[17] * 8805 + flag[18] * 4315 + flag[19] * 8371 + flag[20] * 1919 + flag[21] * 2 == 10299950)
s.add(flag[0] * 6245 + flag[1] * 8783 + flag[2] * 6059 + flag[3] * 9375 + flag[4] * 9253 + flag[5] * 1974 + flag[6] * 8867 + flag[7] * 6423 + flag[8] * 2577 + flag[9] * 6613 + flag[10] * 2040 + flag[11] * 2209 + flag[12] * 4147 + flag[13] * 7151 + flag[14] * 1011 + flag[15] * 9446 + flag[16] * 4362 + flag[17] * 3073 + flag[18] * 3006 + flag[19] * 5499 + flag[20] * 8850 + flag[21] * 23 == 11180727)
s.add(flag[0] * 1907 + flag[1] * 9038 + flag[2] * 3932 + flag[3] * 7054 + flag[4] * 1135 + flag[5] * 5095 + flag[6] * 6962 + flag[7] * 6481 + flag[8] * 7049 + flag[9] * 5995 + flag[10] * 6233 + flag[11] * 1321 + flag[12] * 4455 + flag[13] * 8181 + flag[14] * 5757 + flag[15] * 6953 + flag[16] * 3167 + flag[17] * 5508 + flag[18] * 4602 + flag[19] * 1420 + flag[20] * 3075 + flag[21] * 25 == 10167536)
s.add(flag[0] * 1489 + flag[1] * 9236 + flag[2] * 7398 + flag[3] * 4088 + flag[4] * 4131 + flag[5] * 1657 + flag[6] * 9068 + flag[7] * 6420 + flag[8] * 3970 + flag[9] * 3265 + flag[10] * 5343 + flag[11] * 5386 + flag[12] * 2583 + flag[13] * 2813 + flag[14] * 7181 + flag[15] * 9116 + flag[16] * 4836 + flag[17] * 6917 + flag[18] * 1123 + flag[19] * 7276 + flag[20] * 2257 + flag[21] * 65 == 10202212)
s.add(flag[0] * 2097 + flag[1] * 1253 + flag[2] * 1469 + flag[3] * 2731 + flag[4] * 9565 + flag[5] * 9185 + flag[6] * 1095 + flag[7] * 8666 + flag[8] * 2919 + flag[9] * 7962 + flag[10] * 1497 + flag[11] * 6642 + flag[12] * 4108 + flag[13] * 6892 + flag[14] * 7161 + flag[15] * 7552 + flag[16] * 5666 + flag[17] * 4060 + flag[18] * 7799 + flag[19] * 5080 + flag[20] * 8516 + flag[21] * 43 == 10435786)
s.add(flag[0] * 1461 + flag[1] * 1676 + flag[2] * 4755 + flag[3] * 7982 + flag[4] * 3860 + flag[5] * 1067 + flag[6] * 6715 + flag[7] * 4019 + flag[8] * 4983 + flag[9] * 2031 + flag[10] * 1173 + flag[11] * 2241 + flag[12] * 2594 + flag[13] * 8672 + flag[14] * 4810 + flag[15] * 7963 + flag[16] * 7749 + flag[17] * 5730 + flag[18] * 9855 + flag[19] * 5858 + flag[20] * 2349 + flag[21] * 71 == 9526385)
s.add(flag[0] * 9025 + flag[1] * 9536 + flag[2] * 1515 + flag[3] * 8177 + flag[4] * 6109 + flag[5] * 4856 + flag[6] * 6692 + flag[7] * 4929 + flag[8] * 1010 + flag[9] * 3995 + flag[10] * 3511 + flag[11] * 5910 + flag[12] * 3501 + flag[13] * 3731 + flag[14] * 6601 + flag[15] * 6200 + flag[16] * 8177 + flag[17] * 5488 + flag[18] * 5957 + flag[19] * 9661 + flag[20] * 4956 + flag[21] * 48 == 11822714)
s.add(flag[0] * 4462 + flag[1] * 1940 + flag[2] * 5956 + flag[3] * 4965 + flag[4] * 9268 + flag[5] * 9627 + flag[6] * 3564 + flag[7] * 5417 + flag[8] * 2039 + flag[9] * 7269 + flag[10] * 9667 + flag[11] * 4158 + flag[12] * 2856 + flag[13] * 2851 + flag[14] * 9696 + flag[15] * 5986 + flag[16] * 6237 + flag[17] * 5845 + flag[18] * 5467 + flag[19] * 5227 + flag[20] * 4771 + flag[21] * 72 == 11486796)
s.add(flag[0] * 4618 + flag[1] * 8621 + flag[2] * 8144 + flag[3] * 7115 + flag[4] * 1577 + flag[5] * 8602 + flag[6] * 3886 + flag[7] * 3712 + flag[8] * 1258 + flag[9] * 7063 + flag[10] * 1872 + flag[11] * 9855 + flag[12] * 4167 + flag[13] * 7615 + flag[14] * 6298 + flag[15] * 7682 + flag[16] * 8795 + flag[17] * 3856 + flag[18] * 6217 + flag[19] * 5764 + flag[20] * 5076 + flag[21] * 93 == 11540145)
s.add(flag[0] * 7466 + flag[1] * 8442 + flag[2] * 4822 + flag[3] * 7639 + flag[4] * 2049 + flag[5] * 7311 + flag[6] * 5816 + flag[7] * 8433 + flag[8] * 5905 + flag[9] * 4838 + flag[10] * 1251 + flag[11] * 8184 + flag[12] * 6465 + flag[13] * 4634 + flag[14] * 5513 + flag[15] * 3160 + flag[16] * 6720 + flag[17] * 9205 + flag[18] * 6671 + flag[19] * 7716 + flag[20] * 1905 + flag[21] * 29 == 12227250)
s.add(flag[0] * 5926 + flag[1] * 9095 + flag[2] * 2048 + flag[3] * 4639 + flag[4] * 3035 + flag[5] * 9560 + flag[6] * 1591 + flag[7] * 2392 + flag[8] * 1812 + flag[9] * 6732 + flag[10] * 9454 + flag[11] * 8175 + flag[12] * 7346 + flag[13] * 6333 + flag[14] * 9812 + flag[15] * 2034 + flag[16] * 6634 + flag[17] * 1762 + flag[18] * 7058 + flag[19] * 3524 + flag[20] * 7462 + flag[21] * 11 == 11118093)
if s.check() == sat:
m = s.model()
for i in range(22):
print(chr(int(str(m[flag[i]]))), end='')

D_flat

  1. C# 逆向,dnSpy
    D_flat
    D_flat
  2. main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
private static void Main()
{
int f = 0;
int[] flag = new int[]{109, 111, 101, 99, 116, 102, 123, 68, 95, 102, 108, 97, 116, 101, 95, 105, 115, 95, 67, 95, 115, 104, 97, 114, 112, 33, 125};
Console.WriteLine("In music theory, there is a note that has the same pitch as D flat.");
Console.WriteLine("Do you know it?\nNow plz input your flag:");
string input = Console.ReadLine();
byte[] byteArray = Encoding.ASCII.GetBytes(input);
for (int i = 0; i < input.Length; i++)
{
if (flag[i] == (int)byteArray[i])
{
f++;
}
}
if (f == flag.Length)
{
Console.WriteLine("TTTTTQQQQQQLLLLLLL!!! This is your flag!");
return;
}
Console.WriteLine("QwQ, plz try again.");
}
  1. int 转 chr
1
moectf{D_flate_is_C_sharp!}

chicken_soup(花指令)

  1. f5
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
int __cdecl main(int argc, const char **argv, const char **envp)
{
int result; // eax
char v4[100]; // [esp+10h] [ebp-68h] BYREF

puts("I poisoned the program... Can you reverse it?!");
puts("Come on! Give me your flag:");
sub_4012A0("%s", v4);
if ( strlen(v4) == 38 )
{
((void (__cdecl *)(char *))loc_401000)(v4);
((void (__cdecl *)(char *))loc_401080)(v4);
if ( sub_401110(v4, &unk_403000) )
puts("\nTTTTTTTTTTQQQQQQQQQQQQQLLLLLLLLL!!!!");
else
puts("\nQwQ, please try again.");
result = 0;
}
else
{
puts("\nQwQ, please try again.");
result = 0;
}
return result;
}
  1. 跳转 loc_401000 loc_401080 ,发现无法正常识别,花指令
1
可以看到就是对输入用loc_401000loc_401080进行了加密,然后跟unk_403000进行对比。 双击loc_401000可以发现跳转到了汇编代码,IDA拖着大红色,后面有一堆杂乱的数据无法识别,这是因为IDA的分析被花指令扰乱了。 在loc_40100DU将代码转为未定义的数据,然后在unk_40100E处按C转为代码。40100D处是无用指令,就是它扰乱了IDA的分析,所以我们要将它patch掉。

chicken_soup

1
选中这3句按ctrl+alt+k,输入nop然后点patch,对40100D处的0x90也按C转为代码,然后在loc_401000处按P创建函数,F5就可以得到伪代码。 
  1. loc_401000是一个加的操作,即input[i] += input[i + 1];,loc_401080是一个移位的操作,即input[i] = ((input[i] >> 4) | (input[i] << 4)) & 0xff;,就是将每一个字节的前4bit放到后4bit,后4bit放到前4bit。
1
2
3
4
5
6
7
8
9
enc = [0xcd,0x4d,0x8c,0x7d,0xad,0x1e,0xbe,0x4a,0x8a,0x7d,0xbc,0x7c,0xfc,0x2e,0x2a,0x79,0x9d,0x6a,0x1a,0xcc,0x3d,0x4a,0xf8,0x3c,0x79,0x69,0x39,0xd9,0xdd,0x9d,0xa9,0x69,0x4c,0x8c,0xdd,0x59,0xe9,0xd7]

for i in range(len(enc)):
enc[i] = ((enc[i] >> 4) | (enc[i] << 4)) & 0xff

for i in range(len(enc)-1, 0, -1):
enc[i-1] -= enc[i]

print(bytes(enc))
  1. flag
1
moectf{p4tch_pr0gr4m_t0_d3c0mpi1e_it!}

fake_key(动态调试)

  1. f5
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
int __cdecl main(int argc, const char **argv, const char **envp)
{
char Str[112]; // [rsp+20h] [rbp-80h] BYREF
int v5; // [rsp+90h] [rbp-10h]
int v6; // [rsp+94h] [rbp-Ch]
int j; // [rsp+98h] [rbp-8h]
int i; // [rsp+9Ch] [rbp-4h]

sub_401800(argc, argv, envp);
v6 = strlen(::Str);
puts("I changed the key secretly, you can't find the right key!");
puts("And I use random numbers to rot my input, you can never guess them!");
puts("Unless you debug to get the key and random numbers...");
puts("Now give me your flag:");
scanf("%s", Str);
v5 = strlen(Str);
for ( i = 0; i < v5; ++i )
Str[i] ^= ::Str[i % v6];
for ( j = 0; j < v5; ++j )
Str[j] += rand() % 10;
if ( (unsigned int)sub_4015A2(Str, &unk_403020) )
puts("\nRight! TTTTTQQQQQLLLLL!!!");
else
puts("QwQ, plz try again.");
return 0;
}
  1. 这道题比较迷惑的点可能在于IDA的命名问题。实际上line18中Str[i] ^= ::Str[i % v6];所使用的两个Str并不是同一个变量。选中变量名按N可以对其进行重命名。对代码重命名之后可以得到比较清晰的伪代码:
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
int __cdecl main(int argc, const char **argv, const char **envp)
{
char input[112]; // [rsp+20h] [rbp-80h] BYREF
int input_len; // [rsp+90h] [rbp-10h]
int key_len; // [rsp+94h] [rbp-Ch]
int j; // [rsp+98h] [rbp-8h]
int i; // [rsp+9Ch] [rbp-4h]

sub_401800(argc, argv, envp);
key_len = strlen(key);
puts("I changed the key secretly, you can't find the right key!");
puts("And I use random numbers to rot my input, you can never guess them!");
puts("Unless you debug to get the key and random numbers...");
puts("Now give me your flag:");
scanf("%s", input);
input_len = strlen(input);
for ( i = 0; i < input_len; ++i )
input[i] ^= key[i % key_len];
for ( j = 0; j < input_len; ++j )
input[j] += rand() % 10;
if ( (unsigned int)strcmp(input, &enc) )
puts("\nRight! TTTTTQQQQQLLLLL!!!");
else
puts("QwQ, plz try again.");
return 0;
}
  1. 可以看到首先对输入与密钥进行循环异或,然后加上一个随机数。 双击key会发现是字符串yunzh1jun。在line17下断点调试起来程序,双击key,会发现key变成了yunzh1junTCL,trackYYDS,这才是真正的key。 关于如何获取随机数,可以在line19下断,提取出此时的input数据,然后跑完整个for循环,再提取input数据,两者相减就是生成的随机数。
  2. exp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
enc = [0x15, 0x21, 0x0F, 0x19, 0x25, 0x5B, 0x19, 0x39, 0x5F, 0x3A, 
0x3B, 0x30, 0x74, 0x07, 0x43, 0x3F, 0x09, 0x5A, 0x34, 0x0C,
0x74, 0x3F, 0x1E, 0x2D, 0x27, 0x21, 0x12, 0x16, 0x1F]
key = b'yunzh1junTCL,trackYYDS'

add1 = [0x11, 0x1D, 0x06, 0x12, 0x00, 0x59, 0x02, 0x1D, 0x06, 0x3C,
0x2B, 0x24, 0x44, 0x1C, 0x1A, 0x09, 0x0B, 0x03, 0x31, 0x31,
0x2C, 0x3B, 0x11, 0x1D, 0x06, 0x12, 0x00, 0x59, 0x02]
add2 = [0x12, 0x24, 0x0A, 0x12, 0x09, 0x5D, 0x0A, 0x25, 0x08, 0x40,
0x30, 0x29, 0x45, 0x23, 0x1B, 0x0A, 0x10, 0x05, 0x38, 0x37,
0x2D, 0x3F, 0x13, 0x20, 0x08, 0x14, 0x01, 0x5F, 0x0A]

flag=''
for i in range(len(enc)):
flag += chr((enc[i] - add2[i] + add1[i]) ^ key[i % len(key)])

print(flag)

Art(UPX,异或取模深搜爆破)

  1. 脱壳 f5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int __cdecl main(int argc, const char **argv, const char **envp)
{
char input_cpy[112]; // [rsp+20h] [rbp-60h] BYREF
char input[108]; // [rsp+90h] [rbp+10h] BYREF
int i; // [rsp+FCh] [rbp+7Ch]

sub_402030(argc, argv, envp);
puts("Do you know UPX???");
puts("Oh no...Something seems to be wrong...My equations has multiple solutions...");
puts("May be I can check it by a hash algorithm. You can never reverse it!!!");
printf("Input your flag:");
scanf("%s", input);
for ( i = 0; i <= 27; ++i )
input_cpy[i] = input[i];
for ( i = 1; i <= 27; ++i )
input[i - 1] ^= (input[i - 1] % 17 + input[i]) ^ 0x19;
if ( !strcmp(input, &enc) && (unsigned int)sub_401550(input_cpy) )
puts("\nGood job!!! You know UPX and hash!!!");
else
puts("\nQwQ. Something wrong. Please try again. >_<");
return 0;
}
  1. sub_401550是一个SHA1,用来限制多解的情况。整个加密逻辑只有一句,即input[i - 1] ^= (input[i - 1] % 17 + input[i]) ^ 0x19;。只有最后一位是已知,所以正常思路应该是从最后一位开始爆破,又由于涉及到多解,所以要使用深搜算法来爆破。但是这个题由于明文第一位已知,所以可以直接从前往后爆破。
1
2
3
4
5
6
7
8
9
10
11
12
13
check = [0x2, 0x18, 0xf, 0xf8, 0x19, 0x4, 0x27, 0xd8, 0xeb, 0x0, 0x35, 0x48, 0x4d, 0x2a, 0x45, 0x6b, 0x59, 0x2e, 0x43, 0x1, 0x18, 0x5c, 0x9, 0x9, 0x9, 0x9, 0xb5, 0x7d]
tmp = [0]*28
tmp[len(check)-1]=check[-1]

def DFS(deep):
if deep == 0:
print(bytes(tmp))
else:
for i in range(0xff):
if (i ^ 0x19) ^ (i % 0x11 + tmp[deep]) == check[deep - 1]:
tmp[deep - 1] = i
DFS(deep - 1)
DFS(len(check)-1)

太菜了,后面的已经看不懂 wp 了,不写了


如果您喜欢此博客或发现它对您有用,则欢迎对此发表评论。 也欢迎您共享此博客,以便更多人可以参与。 如果博客中使用的图像侵犯了您的版权,请与作者联系以将其删除。 谢谢 !