First price at CISCN2022!

👴开门见山就是一句:👴今年是国一!

虽然今年是我打过最抽象的ctf,但是👴国一,👴不计较!

初赛

crypto

签到

签到题就是个抽象玩意,整了个什么电报机,发一串密文过去就行

ISO9798

抽象黑盒aes,随便打一串东西过去,然后按顺序把第二块和第一块再打回去就行了(

可信计算

这可能是最抽象的两道题

基于挑战码的双向认证

我还在研究题目的时候,我队pwn手突然告诉我他出了,我:?

过去一问,cat /root/cube-shell/instance/flag_server/flag2.txt

给哥们人看傻了

基于挑战码的双向认证2

发现是修了flag文件的权限,哥们就继续看题去了,vim打开的时候一堆告警,然后ls一看,我超,.swp文件赫然屹立在那,反手一个还原准备diff研究,结果又没过多久,pwn手跟我说又出了,我:???

过去一问,root弱密码,密码是toor

?????

后来知乎看到个好笑的:

  • 哎,linux怎么提权啊?
  • 没想到你还会pwn?
  • 没,我在做crypto

本次比赛成为自我打ctf以来首个没写一行脚本ak了的比赛,好好好,这题出的好,下次不要再出了

半决赛

首先,再丢wp之前,重中之重的第一件事,都给👴狠狠地把知乎全部看一遍,协办的抽象人,抽象事,还得是我们华东百

所以什么时候才能回到2021华东百永远的家啊(悲

crypto

old

👴就是古典大师!👴就是猜谜的神!

base64+w型栅栏+凯撒

run_faster

开局一堆base64,解密全靠猜

many time pad attack

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
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(' ')

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)


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('ciphertext.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)

know(0, 1, 'h')
know(2, 14, '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)

拿到密码W@_0u_Y0u_C@n_R3@11y_D@nc3_b@by

解压之后的东西显然一个是字典一个是hash,john爆破就完了

share_Masker

这题很离谱,t非常小,导致加密性很差,只要有t个人的数据基本就能恢复函数f(x)了,题目最后改了y0y1,但是后面还有很多的数据,直接用后面的就行了

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
sigma = [(7,[297321905442622086655777122878347065868,311772637731397992755988835643237309539,258409395646949644587189814494650948892,229661884007090559984271007393218884878,210755618260134386557578317684284231344,42629503464484411074530409224833347744,87967363214749550457151328532891556884],[157737545918213953755327108333947991114,317872077880940679809614010825371698417,86624037161883155206577260542472171215,317028281506890684277032990811191697980,258465451871053539349471730150916835415,153264157207783262444002861546206936120,289000922263555251522752972082118420994]),(6,[284334878252345214914712482285696924991,165926984986379306821357416122362386359,193637829384529193495630025917170738695,334882665693477520093059906349807755805,268900344625159440411103370834067861440,91280291221404377771897658696028311940,194953122620210846204934290972270327939],[262772073226095364909240613130896626446,25045221876552835532755896106687587027,290132234127387762127754534163582347803,80323928284560765486185338101062119046,63130854914629293225876778792832543500,194242464018353077430988407022608500272,240358378198563571900194429955390922636]),(17035696356725523435736689352030103776,[16310928756724449650677618214978002701,174336045848228030779714764020238703557,89970216714490906504041327043501903033,282986139634559662214090998546272252057,339756653680570402572151189598090053491,226753195189776187233360667707631451395,302393844239337444779445791166076726499],[83693785572982730284187343563453427812,214382896695971150381852644184906500093,31159746526526831505464896928473401209,109689344372495890477346170739794680979,29464723212738599605243411728123573920,75125389557289762047890120501768842472,83648594694726104892013738976521242930]),(38112363242026170740607299231457590593,[280000669740991152715116414064868844069,117811978751516994318608886491996928160,219066592573340196843386896082513768757,266149851847970337077776861076744575928,273302369856624536044807995922274461035,173837090212655468667252338987442545651,50087494512497153546666189839574987813],[73484909955976133758554085839755813985,168471312867111360682072380440949499624,83002489231793947696180306610753347913,181850915483480478365724927212070209022,31988378704099854892369800287869533334,164069190306115241515513330672566738572,20968485724549308806624305705098823296]),(76205233544349126480906642720404032012,[305030447654966106812630819156617224327,257813469706458852963999235126479482896,19646572578527020171226397193701594536,3096227741298015254290242781056337079,193144454612049425264096843609040583875,131663867163342491996417738843070115893,225042609653050824400550143744526504013],[208200244179108274626478654760656272041,277206679130540511812071164296954433046,133008232900469968393807801737445456047,238187942999310821463031176837431989322,335849605574781654583052890135691606436,43803219416914764604640200649104568720,276238575687619035021067058885214417017]),(204686711424689899259236245265099671151,[55330193663121150614151839948543176192,25374040475906722895551110102466752751,332336287589555261940407367033926210828,236841791562130849608160123633242883485,55132078392822701591355541344100417356,210710935440224596506310010347651890748,246494841359851005113390287205601666834],[339473507188035864234953276558636239614,89814961534867822212610057802248875196,159676081157870578324052534325163446042,278059126074846033027152940362124597383,34703917213859578532087467475347648823,165380347281896132594808120070625786348,139330263516220676740626115157795922525]),(209876243505419239230507609298903863123,[231630314654660388240597169920746438098,319108745154870162781675696472178978700,136580385441834975057798631246982481820,183577018802271270939653308168737951908,323824187627341537434200499585439611550,311284989895183246538067216295958716481,5852988257601121115352692251212404181],[262250385316363078475977443655961217681,44659897377225764927692903931629165495,110331796885242604675024331721197688011,156069809351174897850410833685907713393,71518006372186014009593799874320845431,215822592720683375077289686677881608555,217455673260072965643775624241188442131])]
xlist = [141586027935236199910852696821624556539, 40666427516342492776926786656956980320, 211934535135753616032329255822871485104, 72848036554241506309424877106561776890, 294883308555980411146995456458745170680, 80828132368001405431441629923575932026, 305927509378389767202094045755269682626]

p=340282366920938463463374607431768211507
t=2
n=7
F=GF(p)

key = []
tlist = []
ylist = []
for i in range(n):
ylist.append(sigma[i][0])
tlist.append(sigma[i][1])
key.append(sigma[i][2])

B = []
for i in range(2, n):
qwq = []
temp = 1
for j in range(2, n):
qwq.append(temp)
temp = temp * xlist[i] % p
B.append(qwq)
B = Matrix(F, B)
B = B.inverse()
A = Matrix(F, ylist[2:])
A = A.transpose()
C = B*A
print(C)

决赛

破烂疫情,又是延期又是线上,没去成南开,也没法抄流量,我那时候天天喊的最多的话,大概是寄了

不过👴是国一!好!

先丢个榜

image-20220828133631102

我宣布,决赛就是帆哥哥爆杀之日!(白泽哥太猛了,根本打不过

线上比个赛,又是双机位又是录屏的

Day1

web_unserialize_game

一眼反序列化,先反手把反序列化入口扬了,fix万事

然后break的payload如下

1
2
3
$a=new Game();
$a->setAB("create_function","}EVAL(\$_POST['a']);//");
echo urlencode(serialize($a));

web_just

www.zip泄漏源码,修了半天都修不过去,最后还得是szz哥哥,把白名单全🐑了,然后fix成功了,好好好好好好

web_so_easy_4_u

先发现了几个api

api/save.php存数据

api/get.php读数据

刚开始一直在看hash怎么算,后来想到可以直接把hash赋值了,越界读../../../../../../../flag

然后修的话,break之后能任意文件读,把save.php读出来把.和/过滤掉即可

web_backdoor

这题是真的骚,虽然开源了我还没来得及复现,但是比赛的时候我一直修不好,让我以为这题的check写的非常认真的时候,szz哥哥跟我说修好了,把__sleep里原来的return注释掉,换成return “aa”;,我:?好好好好好好

Day2

web_HouTai

进行一个对黑名单的补

1
2
3
4
// const blacklists = [`"`, `\\`, `|`, `&`, `+`, `-`, `*`, `/`, `^`];
const blacklists = [`"`, `\\`, `|`, `&`, `+`, `-`, `*`, `/`, `^`, `#`];
// const blackwords = [`select`, `drop`, `insert`, `update`, `delete`, `like`, `order`, `truncate`, `create`, `reg`, `sub`, `left`, `right`, `mid`, `if`, `log`, `pro`, `func`, `history`, `file`, `plugin`, `role`, `collation`, `event`];
const blackwords = [`select`, `drop`, `insert`, `update`, `delete`, `like`, `order`, `truncate`, `create`, `reg`, `sub`, `left`, `right`, `mid`, `if`, `log`, `pro`, `func`, `history`, `file`, `plugin`, `role`, `collation`, `event`, `union`, `database`, `flag`];

web_flasf

接着补黑名单,然后urlopen和read有ssrf,换成request访问然后就突然好了

web_即将上线的项目

前台是个命令执行,直接读flag就行了name=system&content=cat /flaaaaaaggggggggggg&B1=提交

这题是真的恶心,丢个rce给你,不让你杀system函数,check拿着system在根目录乱跑,exp的payload又多的要命,修,修个🔨

这题多给了10次fix机会,不过每次都是patch失败 check不通过或者patch失败 check通过 exp通过幸运二选一罢了

赛后

比赛打完了,这会写博客已经忘的差不多了,我只记得有个最nt的机制是这个

截屏2022-08-24 12.28.18

我还记得我replace打成了repalce,等我发现之后硬是最后五分钟不让我交了😅

头一次拿国一,腾讯会议里的颁奖典礼也没多少意思,抽奖的时候抽了个二等奖,不过我的蓝牙耳机已经堆成山了,所以成功和Dbt👴exchange了一下,好!

Summary

第二年国赛了啊,总算是把国一拿到了,但是还是没有公费旅游,没有茶歇,没有线下真人awd,倒是有大中午的Asuri集体直播干饭

本来想回学校再看看👴这逆天学校还有什么破烂要求,结果👴开学前夕摇身一变中风险,完事解封了这逆天学校还是不让返校,看着身边的好兄弟们都上学去了,我只能憋在家里等着学校安排,没学上,没班上,在学校还得看人脸色,👴多少也有些可悲了罢

tnnd,既然学校不让去,那👴就直接去字节上班去喽