如題。

簽到

等所有省市區IP都到達10個即可召喚flag,Ao 門久攻不下。發在羣裏/題目信息,先到先得。

re:z3

IDA, F5 得 42 元方程組。

from z3 import *
dest = [20247, 40182, 36315, 36518, 26921, 39185, 16546, 12094, 25270, 19330, 18540, 16386, 21207, 11759, 10460, 25613, 21135, 24891, 18305, 27415, 12855, 10899, 24927, 20670, 22926, 18006, 23345, 12602, 12304, 26622, 19807, 22747, 14233, 24736, 10064, 14169, 35155, 28962, 33273, 21796, 35185, 14877]
k = []
for _ in range(42):
    k.append(Int(f'k{_}'))

solver = Solver()

txt = """v4 = 34 * v49 + 12 * v46 + 53 * v47 + 6 * v48 + 58 * v50 + 36 * v51 + v52;
v5 = 27 * v50 + 73 * v49 + 12 * v48 + 83 * v46 + 85 * v47 + 96 * v51 + 52 * v52;
v6 = 24 * v48 + 78 * v46 + 53 * v47 + 36 * v49 + 86 * v50 + 25 * v51 + 46 * v52;
v7 = 78 * v47 + 39 * v46 + 52 * v48 + 9 * v49 + 62 * v50 + 37 * v51 + 84 * v52;
v8 = 48 * v50 + 14 * v48 + 23 * v46 + 6 * v47 + 74 * v49 + 12 * v51 + 83 * v52;
v9 = 15 * v51 + 48 * v50 + 92 * v48 + 85 * v47 + 27 * v46 + 42 * v49 + 72 * v52;
v10 = 26 * v51 + 67 * v49 + 6 * v47 + 4 * v46 + 3 * v48 + 68 * v52;
v11 = 34 * v56 + 12 * v53 + 53 * v54 + 6 * v55 + 58 * v57 + 36 * v58 + v59;
v12 = 27 * v57 + 73 * v56 + 12 * v55 + 83 * v53 + 85 * v54 + 96 * v58 + 52 * v59;
v13 = 24 * v55 + 78 * v53 + 53 * v54 + 36 * v56 + 86 * v57 + 25 * v58 + 46 * v59;
v14 = 78 * v54 + 39 * v53 + 52 * v55 + 9 * v56 + 62 * v57 + 37 * v58 + 84 * v59;
v15 = 48 * v57 + 14 * v55 + 23 * v53 + 6 * v54 + 74 * v56 + 12 * v58 + 83 * v59;
v16 = 15 * v58 + 48 * v57 + 92 * v55 + 85 * v54 + 27 * v53 + 42 * v56 + 72 * v59;
v17 = 26 * v58 + 67 * v56 + 6 * v54 + 4 * v53 + 3 * v55 + 68 * v59;
v18 = 34 * v63 + 12 * v60 + 53 * v61 + 6 * v62 + 58 * v64 + 36 * v65 + v66;
v19 = 27 * v64 + 73 * v63 + 12 * v62 + 83 * v60 + 85 * v61 + 96 * v65 + 52 * v66;
v20 = 24 * v62 + 78 * v60 + 53 * v61 + 36 * v63 + 86 * v64 + 25 * v65 + 46 * v66;
v21 = 78 * v61 + 39 * v60 + 52 * v62 + 9 * v63 + 62 * v64 + 37 * v65 + 84 * v66;
v22 = 48 * v64 + 14 * v62 + 23 * v60 + 6 * v61 + 74 * v63 + 12 * v65 + 83 * v66;
v23 = 15 * v65 + 48 * v64 + 92 * v62 + 85 * v61 + 27 * v60 + 42 * v63 + 72 * v66;
v24 = 26 * v65 + 67 * v63 + 6 * v61 + 4 * v60 + 3 * v62 + 68 * v66;
v25 = 34 * v70 + 12 * v67 + 53 * v68 + 6 * v69 + 58 * v71 + 36 * v72 + v73;
v26 = 27 * v71 + 73 * v70 + 12 * v69 + 83 * v67 + 85 * v68 + 96 * v72 + 52 * v73;
v27 = 24 * v69 + 78 * v67 + 53 * v68 + 36 * v70 + 86 * v71 + 25 * v72 + 46 * v73;
v28 = 78 * v68 + 39 * v67 + 52 * v69 + 9 * v70 + 62 * v71 + 37 * v72 + 84 * v73;
v29 = 48 * v71 + 14 * v69 + 23 * v67 + 6 * v68 + 74 * v70 + 12 * v72 + 83 * v73;
v30 = 15 * v72 + 48 * v71 + 92 * v69 + 85 * v68 + 27 * v67 + 42 * v70 + 72 * v73;
v31 = 26 * v72 + 67 * v70 + 6 * v68 + 4 * v67 + 3 * v69 + 68 * v73;
v32 = 34 * v77 + 12 * v74 + 53 * v75 + 6 * v76 + 58 * v78 + 36 * v79 + v80;
v33 = 27 * v78 + 73 * v77 + 12 * v76 + 83 * v74 + 85 * v75 + 96 * v79 + 52 * v80;
v34 = 24 * v76 + 78 * v74 + 53 * v75 + 36 * v77 + 86 * v78 + 25 * v79 + 46 * v80;
v35 = 78 * v75 + 39 * v74 + 52 * v76 + 9 * v77 + 62 * v78 + 37 * v79 + 84 * v80;
v36 = 48 * v78 + 14 * v76 + 23 * v74 + 6 * v75 + 74 * v77 + 12 * v79 + 83 * v80;
v37 = 15 * v79 + 48 * v78 + 92 * v76 + 85 * v75 + 27 * v74 + 42 * v77 + 72 * v80;
v38 = 26 * v79 + 67 * v77 + 6 * v75 + 4 * v74 + 3 * v76 + 68 * v80;
v39 = 34 * v84 + 12 * v81 + 53 * v82 + 6 * v83 + 58 * v85 + 36 * v86 + v87;
v40 = 27 * v85 + 73 * v84 + 12 * v83 + 83 * v81 + 85 * v82 + 96 * v86 + 52 * v87;
v41 = 24 * v83 + 78 * v81 + 53 * v82 + 36 * v84 + 86 * v85 + 25 * v86 + 46 * v87;
v42 = 78 * v82 + 39 * v81 + 52 * v83 + 9 * v84 + 62 * v85 + 37 * v86 + 84 * v87;
v43 = 48 * v85 + 14 * v83 + 23 * v81 + 6 * v82 + 74 * v84 + 12 * v86 + 83 * v87;
v44 = 15 * v86 + 48 * v85 + 92 * v83 + 85 * v82 + 27 * v81 + 42 * v84 + 72 * v87;
v45 = 26 * v86 + 67 * v84 + 6 * v82 + 4 * v81 + 3 * v83 + 68 * v87;"""

for expr in txt.splitlines():
    print(expr)
    left, right = expr.split(" = ")
    right = right.rstrip(";")
    leftno = int(left.strip().lstrip('v'))
    s = 0
    for item in right.split(' + '):
        if '*' in item: coef, val = item.split(' * ')
        else:
            coef, val = 1, item.strip()
        val = int(val.lstrip('v'))
        s += coef * k[val - 46]
    solver.add(dest[leftno - 4] == s)

if solver.check() == sat:
    m = solver.model()
    for i in range(42):
        print(chr(m[k[i]].as_long()), end='')

misc:the_best_ctf_game

據說用 WinHex 打開就能看出來,反正我是看不出來,是隊友看的。

crypto:bd

RSA Wiener‘s attack,跑段 sage 分解。

# https://raw.githubusercontent.com/KangMing-ux/Wiener-attack/master/wiener_attack.sage
def wiener_attack(n,e):
    hi_1,hi_2=1,0
    ki_1,ki_2=0,1
    a,b=e,n
    R.<t> = PolynomialRing(QQ)
    r=1
    while r:
        p,r=divmod(a,b)
        hi=p*hi_1+hi_2
        ki=p*ki_1+ki_2
        print(hi,ki)
        hi_1,hi_2=hi,hi_1
        ki_1,ki_2=ki,ki_1
        a,b=b,r
        if hi==0:
            continue
        f=t^2-(n-(ki*e-1)/hi+1)*t+n
        rts=f.roots()
        flag=0
        for ii in range(len(rts)):
            flag+=rts[ii][0] in ZZ
        if flag==2:
            break
    p,q=rts[0][0],rts[1][0]
    if p<q:
        return p,q
    else:
        return q,p

e = 46867417013414476511855705167486515292101865210840925173161828985833867821644239088991107524584028941183216735115986313719966458608881689802377181633111389920813814350964315420422257050287517851213109465823444767895817372377616723406116946259672358254060231210263961445286931270444042869857616609048537240249
n = 86966590627372918010571457840724456774194080910694231109811773050866217415975647358784246153710824794652840306389428729923771431340699346354646708396564203957270393882105042714920060055401541794748437242707186192941546185666953574082803056612193004258064074902605834799171191314001030749992715155125694272289

p, q = wiener_attack(n, e)
c = 37625098109081701774571613785279343908814425141123915351527903477451570893536663171806089364574293449414561630485312247061686191366669404389142347972565020570877175992098033759403318443705791866939363061966538210758611679849037990315161035649389943256526167843576617469134413191950908582922902210791377220066
phi = (p-1)*(q-1)
d = inverse_mod(e, phi)
text = c.powermod(d, n)
print(bytes.fromhex(hex(text)[2:]))

misc:電腦被黑

ext3grep 恢復所有文件,把 flag.txt 的內容用恢復得到的 demo 的算法恢復。

enc = b'D*\x03\xe5)\xa3\xafb\x051N\xf3\xd6\xeb\x90f$\\\xb7\x92\xf6\xd7M\x0bjA\xa3\x85\xef\x90Z~[\xec\xc1\xf0\xd4a\x12\x12E\xeb\xb8'
v4 = 34
v5 = 0
result = []

for v6 in enc:
    result.append(((v6 ^ v4) - v5) & 0xff)
    v4 = (v4 + 34) & 0xff
    v5 = (v5 + 2) & 0xf

print(bytes(result))

web:littlegame

原型鏈污染。查看 routes/index.js:

var express = require('express');
const setFn = require('set-value');
var router = express.Router();
/* omitted */
const Admin = {
    "password1":process.env.p1,
    "password2":process.env.p2,
    "password3":process.env.p3
}
/* omitted */
router.post("/DeveloperControlPanel", function (req, res, next) {
    // not implement
    if (req.body.key === undefined || req.body.password === undefined){
        res.send("What's your problem?");
    }else {
        let key = req.body.key.toString();
        let password = req.body.password.toString();
        if(Admin[key] === password){
            res.send(process.env.flag);
        }else {
            res.send("Wrong password!Are you Admin?");
        }
    }

});
router.get('/SpawnPoint', function (req, res, next) {
    req.session.knight = {
        "HP": 1000,
        "Gold": 10,
        "Firepower": 10
    }
    res.send("Let's begin!");
});
router.post("/Privilege", function (req, res, next) {
    // Why not ask witch for help?
    if(req.session.knight === undefined){
        res.redirect('/SpawnPoint');
    }else{
        if (req.body.NewAttributeKey === undefined || req.body.NewAttributeValue === undefined) {
            res.send("What's your problem?");
        }else {
            let key = req.body.NewAttributeKey.toString();
            let value = req.body.NewAttributeValue.toString();
            setFn(req.session.knight, key, value);
            res.send("Let's have a check!");
        }
    }
});

module.exports = router;

/Privilege 可以用 set-value 這個包的函數設定 req.session.knight 下的屬性。把 .__proto__.pass 設置成隨便你想要的什麼密碼,這樣作爲 Object 的 Admin 下就會多出一個隱藏的屬性 pass。在 /DeveloperControlPanel 提交 key=pass&password=111111 獲取 flag。

後記

本文經過重寫補充,至於原因我暫且矇在鼓裏。