内容简介:比赛入口地址:题目存档:官方 Writeup:
比赛入口地址: http://hack.lug.ustc.edu.cn/
题目存档: https://hack2018.lug.ustc.edu.cn/
官方 Writeup: https://github.com/ustclug/hackergame2018-writeups
第二年参加中科大的 Hackergame,今年多了许多大佬参加。
题目共 32 题,只解出 20 题。
比赛最终得分:3650;总排名:13;参赛组:其他;组内排名:11。
本题解持续更新,未解出题的题解后续发布。
最后更新时间:2018-10-16 14:00
题外话
去贵阳玩了四天,在外面用手机把前面的 12 道题做出来了。
然后 MC 手机没法玩,还通宵去网咖玩 MC 把题做出来。
签到题 (Solved, 50pt)
直接访问 /?key=hackergame2018
,就能得到 Flag。
Flag: flag{Hackergame2018_Have_Fun!}
猫咪问答 (Solved, 100pt)
社工题,上网找答案吧。
1. 1958 出处:百度百科 2. 9211B026 出处:网上搜索“中国科大学号的演变史” 3. 9 出处:手工爆破一下 4. TP311.1/94 出处:中国科技大学图书馆网站 5. 3A202 出处:LUG@USTC官网 LUG活动 栏目
Flag: flag{G00G1E-is-always-YOUR-FRIEND}
游园会的集章卡片 (Solved, 100pt)
拼图题,在手机上拼一下就好了。
Flag: flag{H4PPY_1M4GE_PR0CE551NG}
猫咪和键盘 (Solved, 150pt)
cpp 里面的代码顺序被破坏了,找规律,写个脚本重新排一下。
lines=open('typed_printf.cpp','r').readlines() for line in lines: print line[0]+line[32:39]+line[1:7]+line[20:22]+line[8:20]+line[22:32]+line[39:-1]
观察一下代码就可以直接出 Flag
Flag:flag{FfQ47if9Zxw9jXE68VtGAJDk6Y6Xc88UrUtpK3iF8p7BMs4y2gzdG8Ao2gv6aiJ125typed_printf95}
Word 文档 (Solved, 150pt)
docx 格式,直接 zip 解压,就看到 flag.txt 文件了
Flag: flag{xlsx,pptx,docx_are_just_zip_files}
猫咪银行 (Solved, 150pt)
以为是“货币兑换”有漏洞,后来发现没什么问题。
然后尝试“买入分钟”改得很大,“取出时间”的年份异常大或者异常小,就感觉像是溢出。
换了几个数字,多试几遍,成功买到了 Flag。
正确操作流程: 用 CTB 兑换 6606 个 TDSU 买入理财产品。买入分钟:2333333333333333333;买入份额:1000 取出理财产品 用 TDSU 兑换 20 个 CTB 购买 FLAG
Flag: flag{Evil_Integer._Evil_Overflow.}
黑曜石浏览器 (Solved, 150pt)
访问黑曜石浏览器官网: https://heicore.com/
在官网网页源代码里找到 黑曜石浏览器 的 User-Agent:
Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) HEICORE/49.1.2623.213 Safari/537.36
直接在手机上用 curl 加上 User-Agent 去访问题目链接,就能得到 Flag。
Flag: flag{H3ic0re_49.1.2623.213_sai_kou}
回到过去 (Solved, 150pt)
题目给出键盘记录,直接复现一下就能看到 Flag。
Flag: flag{t4a2b8c44039f93345a3d9b2}
我是谁 (450pt)
哲学思考 (Solved, 150pt)
直接在手机上用 curl,看 HTTP 请求里的 Status Code,就得到答案:TEAPOT。
提交答案得到 Flag
Flag: flag{i_canN0t_BReW_c0ffEE!}
Can I help me? (Solved, 300pt)
根据 brew coffee 提示,找到 HTCPCP/1.0 协议
参考:RFC 2324 / RFC 7168
直接在手机上用 nc 发请求
Flag: flag{delivering_tea_to_DaLa0}
家里有矿 (750pt)
sha1 (Solved, 150pt)
Google 有个现成的 sha1 碰撞,是两个 pdf 文件。
pdf 文件下载: https://shattered.io/
直接将两个 pdf 文件作为 nonce1 和 nonce2 提交,就能得到 Flag。
import requests import json import hashlib from base64 import * url='http://202.38.95.46:12006' s=requests.session() r=s.post(url+'/getjob') r=json.loads(r.text) suffix=bytes(r['suffix']) pdf1=requests.get('https://shattered.io/static/shattered-1.pdf').content pdf2=requests.get('https://shattered.io/static/shattered-2.pdf').content data={'nonce1':b64encode(pdf1),'nonce2':b64encode(pdf2),'coin':1} r=s.post(url+'/submitjob',data) print r.text
Flag: flag{sha1_21d0e7b1be5a3cae}
md5 (Solved, 150pt)
写个脚本跑,加上约束条件。开了 8 个 python 程序,跑了半个小时就出结果了。
import requests import json import time import hashlib from base64 import * import random import string def NumberOf0(n,length1,length2,length3): return bin(n)[2:].rjust(length1,'0')[length2:length3].count('0') url='http://202.38.95.46:12006' rand_list='' for i in range(256): rand_list+=chr(i) match_nonce1='' match_nonce2='' while True: nonce_table=[] hash_table=[] t=time.time() s=requests.session() r=s.post(url+'/getjob') r=json.loads(r.text) suffix=r['suffix'] print 'suffix: %s' % suffix nonce1=''.join(random.sample(rand_list,8)) hash1=hashlib.md5(nonce1+bytes(suffix[:16])).hexdigest() hash1=int(hash1,16) nonce_table.append(nonce1) hash_table.append(hash1) match=0 while match<102 and t+60>time.time(): #print 'len: %d' % len(hash_table) match=0 while True: nonce2=''.join(random.sample(rand_list,8)) hash2=hashlib.md5(nonce2+bytes(suffix[:16])).hexdigest() hash2=int(hash2,16) if NumberOf0(hash1^hash2,128,0,20)<17: continue break for i in range(len(hash_table)): match=NumberOf0(hash_table[i]^hash2,128,0,128) if match>95: print match if match<102: continue match_nonce1=nonce_table[i] match_nonce2=nonce2 break nonce_table.append(nonce2) hash_table.append(hash2) if match<102: continue data={'nonce1':b64encode(match_nonce1),'nonce2':b64encode(match_nonce2),'coin':0} r=s.post(url+'/submitjob',data) print r.text break
Flag: flag{md5_7cfa0da2c09776ae}
sha256 (Unsolved, 350pt)
后续发布
秘籍残篇 (550pt)
滑稽 Art (Unsolved, 150pt)
后续发布
天书易解 (Unsolved, 400pt)
后续发布
猫咪遥控器 (Solved, 200pt)
根据提示,猜测需要把给出的控制方向画出轨迹,直接在手机上画吧。
seq=[] r=open('seq.txt').read() now=[130,1] for i in r: if 'L'==i: seq.append(now) now=[now[0],now[1]-1] if 'R'==i: seq.append(now) now=[now[0],now[1]+1] if 'D'==i: seq.append(now) now=[now[0]-1,now[1]] if 'U'==i: seq.append(now) now=[now[0]+1,now[1]] op='' for y in range(550): for x in range(130): if [x,y] in seq: op+='A' else: op+=' ' op+='\n' print op
Flag: flag{MeowMeow}
她的诗 (Solved, 200pt)
这首诗经过 uuencode
编码,有点像 base64
的编码方式,可以在最后隐写字符。
from codecs import decode lines = open("poem.txt", "r").readlines() flag='' for i in lines: i=i[:-1] j=1 s='' while True: a=i[j:j+4] if len(a)<=0: break a=a.ljust(4,' ') b=chr((((ord(a[0])-32)<<2)&0xff)+((ord(a[1])-32)>>4)) c=chr((((ord(a[1])-32)<<4)&0xff)+((ord(a[2])-32)>>2)) d=chr((((ord(a[2])-32)<<6)&0xff)+(ord(a[3])-32)) s+=b+c+d j+=4 data = "begin 666 <data>\n" + i + " \nend\n" decode_data = decode(data.encode("ascii"), "uu").decode("ascii") flag+=s[len(decode_data):] print flag
Flag: flag{STegAn0grAPhy_w1tH_uUeNc0DE_I5_50_fun}
猫咪克星 (Solved, 200pt)
给出 python3 表达式,只需要算出结果提交。然后不断循环 n 次,就能得到 Flag。
PS:话说,我用 python2 也可以解。
from pwn import * context.log_level='debug' io=remote('202.38.95.46', 12009) io.recvline() for i in range(200): res=io.recvline() if 'flag' in res: print res break res=res.replace(b"__import__('time').sleep",b'') res=res.replace(b'exit()',b'0') res=res.replace(b'\\x',b'') res=res.replace(b'print',b'len') res=str(eval(res)) io.sendline(res)
Flag: flag{'Life_1s_sh0rt_use_PYTH0N'*1000}
猫咪电路 (Solved, 200pt)
出门在外地,凌晨去网咖通宵做题,顺便把这题 mc 给秒了。
作为 mc 老玩家,觉得很简单啊,而且这个红石电路不算复杂。
Flag: flag{0110101000111100101111111111111111111010}
FLXG 的秘密 (550pt)
来自未来的漂流瓶 (Unsolved, 200pt)
后续发布
难以参悟的秘密 (Unsolved, 350pt)
后续发布
C 语言作业 (Solved, 250pt)
简单 pwn。程序看上去好像没什么问题。
后来发现触发 signal 可以任意命令执行。
那么可以输入 2147483648/-1
来触发 SIGFPE
信号。
带有 sh
的命令被黑名单,那么我们使用 vim
的命令执行功能来执行任意命令
然后执行 :!/bin/sh
打开 shell
发现 flag
文件被改名为 -
不过我们可以执行 vim -- -
打开它,然后就看到 Flag 了
Flag: flag{816484e67b21efd5de8f1661d180a007}
加密算法和解密算法 (Solved, 250pt)
由于是 BrainFuck 虚拟机指令,我直接上网找 BrainFuck To C 的转换。
得到 C 代码,分析,每 10 字节一分组进行加密。改动明文中的一位,都会影响加密结果的每一位。
加密过程可以整理出 10 条方程式,直接上 z3 求解。
from z3 import * flag='' table='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_' x=[BitVec('x%d' % i,8) for i in range(10)] solver = Solver() solver.add((x[0]*23+x[1]*5+x[2]*40+x[3]*61+x[4]*47+x[5]*21+x[6]*62+x[7]*9+x[8]*18+x[9]*17+2)%64==9) solver.add((x[0]*46+x[1]*3+x[2]*40+x[3]*54+x[4]*31+x[5]*23+x[6]*54+x[7]*11+x[9]*5+6)%64==51) solver.add((x[0]*21+x[1]*16+x[2]*63+x[3]*33+x[4]*60+x[5]*26+x[6]*39+x[7]*32+x[8]*48+x[9]*39+8)%64==17) solver.add((x[0]*16+x[1]*27+x[2]*5+x[3]*53+x[4]*37+x[5]*17+x[6]*24+x[7]*61+x[8]*23+x[9]*50+8)%64==21) solver.add((x[0]*35+x[1]*22+x[2]*2+x[3]*43+x[4]*4+x[5]*36+x[6]*3+x[7]*22+x[8]*58+x[9]*37+3)%64==15) solver.add((x[0]*17+x[2]*51+x[3]*46+x[4]*37+x[5]*44+x[6]*11+x[7]*13+x[8]*7+x[9]*18+5)%64==34) solver.add((x[0]*34+x[1]*15+x[2]*10+x[3]*52+x[4]*27+x[5]*19+x[6]*38+x[7]*15+x[8]*30+x[9]*4+5)%64==21) solver.add((x[0]*19+x[1]*38+x[2]*52+x[3]*8+x[4]*49+x[5]*7+x[6]*36+x[7]*40+x[8]*60+x[9]*45+7)%64==41) solver.add((x[0]*12+x[1]*55+x[2]*41+x[3]*4+x[4]*39+x[5]*62+x[6]*48+x[7]*1+x[8]*21+x[9]*2+4)%64==42) solver.add((x[0]*38+x[1]*14+x[2]*43+x[3]*59+x[4]*55+x[5]*10+x[6]*50+x[7]*18+x[8]*36+x[9]*13+9)%64==40) for i in range(10): solver.add(x[i] >= 0) for i in range(10): solver.add(x[i] <= 63) res=[] while solver.check() == sat: res=solver.model() break tmp_flag='' for i in range(len(x)): tmp_flag+=table[res[x[i]].as_long()] flag+=tmp_flag x=[BitVec('x%d' % i,8) for i in range(10)] solver = Solver() solver.add((x[0]*23+x[1]*5+x[2]*40+x[3]*61+x[4]*47+x[5]*21+x[6]*62+x[7]*9+x[8]*18+x[9]*17+2)%64==56) solver.add((x[0]*46+x[1]*3+x[2]*40+x[3]*54+x[4]*31+x[5]*23+x[6]*54+x[7]*11+x[9]*5+6)%64==34) solver.add((x[0]*21+x[1]*16+x[2]*63+x[3]*33+x[4]*60+x[5]*26+x[6]*39+x[7]*32+x[8]*48+x[9]*39+8)%64==3) solver.add((x[0]*16+x[1]*27+x[2]*5+x[3]*53+x[4]*37+x[5]*17+x[6]*24+x[7]*61+x[8]*23+x[9]*50+8)%64==12) solver.add((x[0]*35+x[1]*22+x[2]*2+x[3]*43+x[4]*4+x[5]*36+x[6]*3+x[7]*22+x[8]*58+x[9]*37+3)%64==60) solver.add((x[0]*17+x[2]*51+x[3]*46+x[4]*37+x[5]*44+x[6]*11+x[7]*13+x[8]*7+x[9]*18+5)%64==28) solver.add((x[0]*34+x[1]*15+x[2]*10+x[3]*52+x[4]*27+x[5]*19+x[6]*38+x[7]*15+x[8]*30+x[9]*4+5)%64==30) solver.add((x[0]*19+x[1]*38+x[2]*52+x[3]*8+x[4]*49+x[5]*7+x[6]*36+x[7]*40+x[8]*60+x[9]*45+7)%64==37) solver.add((x[0]*12+x[1]*55+x[2]*41+x[3]*4+x[4]*39+x[5]*62+x[6]*48+x[7]*1+x[8]*21+x[9]*2+4)%64==50) solver.add((x[0]*38+x[1]*14+x[2]*43+x[3]*59+x[4]*55+x[5]*10+x[6]*50+x[7]*18+x[8]*36+x[9]*13+9)%64==46) for i in range(10): solver.add(x[i] >= 0) for i in range(10): solver.add(x[i] <= 63) res=[] while solver.check() == sat: res=solver.model() break tmp_flag='' for i in range(len(x)): tmp_flag+=table[res[x[i]].as_long()] flag+=tmp_flag x=[BitVec('x%d' % i,8) for i in range(10)] solver = Solver() solver.add((x[0]*23+x[1]*5+x[2]*40+x[3]*61+x[4]*47+x[5]*21+x[6]*62+x[7]*9+x[8]*18+x[9]*17+2)%64==56) solver.add((x[0]*46+x[1]*3+x[2]*40+x[3]*54+x[4]*31+x[5]*23+x[6]*54+x[7]*11+x[9]*5+6)%64==34) solver.add((x[0]*21+x[1]*16+x[2]*63+x[3]*33+x[4]*60+x[5]*26+x[6]*39+x[7]*32+x[8]*48+x[9]*39+8)%64==3) solver.add((x[0]*16+x[1]*27+x[2]*5+x[3]*53+x[4]*37+x[5]*17+x[6]*24+x[7]*61+x[8]*23+x[9]*50+8)%64==12) solver.add((x[0]*35+x[1]*22+x[2]*2+x[3]*43+x[4]*4+x[5]*36+x[6]*3+x[7]*22+x[8]*58+x[9]*37+3)%64==60) solver.add((x[0]*17+x[2]*51+x[3]*46+x[4]*37+x[5]*44+x[6]*11+x[7]*13+x[8]*7+x[9]*18+5)%64==28) solver.add((x[0]*34+x[1]*15+x[2]*10+x[3]*52+x[4]*27+x[5]*19+x[6]*38+x[7]*15+x[8]*30+x[9]*4+5)%64==30) solver.add((x[0]*19+x[1]*38+x[2]*52+x[3]*8+x[4]*49+x[5]*7+x[6]*36+x[7]*40+x[8]*60+x[9]*45+7)%64==37) solver.add((x[0]*12+x[1]*55+x[2]*41+x[3]*4+x[4]*39+x[5]*62+x[6]*48+x[7]*1+x[8]*21+x[9]*2+4)%64==50) solver.add((x[0]*38+x[1]*14+x[2]*43+x[3]*59+x[4]*55+x[5]*10+x[6]*50+x[7]*18+x[8]*36+x[9]*13+9)%64==46) for i in range(10): solver.add(x[i] >= 0) for i in range(10): solver.add(x[i] <= 63) res=[] while solver.check() == sat: res=solver.model() break tmp_flag='' for i in range(len(x)): tmp_flag+=table[res[x[i]].as_long()] flag+=tmp_flag x=[BitVec('x%d' % i,8) for i in range(10)] solver = Solver() solver.add((x[0]*23+x[1]*5+x[2]*40+x[3]*61+x[4]*47+x[5]*21+x[6]*62+x[7]*9+x[8]*18+x[9]*17+2)%64==6) solver.add((x[0]*46+x[1]*3+x[2]*40+x[3]*54+x[4]*31+x[5]*23+x[6]*54+x[7]*11+x[9]*5+6)%64==55) solver.add((x[0]*21+x[1]*16+x[2]*63+x[3]*33+x[4]*60+x[5]*26+x[6]*39+x[7]*32+x[8]*48+x[9]*39+8)%64==4) solver.add((x[0]*16+x[1]*27+x[2]*5+x[3]*53+x[4]*37+x[5]*17+x[6]*24+x[7]*61+x[8]*23+x[9]*50+8)%64==12) solver.add((x[0]*35+x[1]*22+x[2]*2+x[3]*43+x[4]*4+x[5]*36+x[6]*3+x[7]*22+x[8]*58+x[9]*37+3)%64==10) solver.add((x[0]*17+x[2]*51+x[3]*46+x[4]*37+x[5]*44+x[6]*11+x[7]*13+x[8]*7+x[9]*18+5)%64==34) solver.add((x[0]*34+x[1]*15+x[2]*10+x[3]*52+x[4]*27+x[5]*19+x[6]*38+x[7]*15+x[8]*30+x[9]*4+5)%64==33) solver.add((x[0]*19+x[1]*38+x[2]*52+x[3]*8+x[4]*49+x[5]*7+x[6]*36+x[7]*40+x[8]*60+x[9]*45+7)%64==51) solver.add((x[0]*12+x[1]*55+x[2]*41+x[3]*4+x[4]*39+x[5]*62+x[6]*48+x[7]*1+x[8]*21+x[9]*2+4)%64==46) solver.add((x[0]*38+x[1]*14+x[2]*43+x[3]*59+x[4]*55+x[5]*10+x[6]*50+x[7]*18+x[8]*36+x[9]*13+9)%64==7) for i in range(10): solver.add(x[i] >= 0) for i in range(10): solver.add(x[i] <= 63) res=[] while solver.check() == sat: res=solver.model() break tmp_flag='' for i in range(len(x)): tmp_flag+=table[res[x[i]].as_long()] flag+=tmp_flag print 'Flag: flag{%s}' % flag
Flag: flag{h1ll-c1ph3r-w1th-10xr-w1th-10xbl3-matr1x}
王的特权 (Unsolved, 250pt)
后续发布
她的礼物 (Solved, 250pt)
把文件里 call sleep
system
signal
alarm
的地方用 0x90
NOP 填充
把除了 输出 Key
之外无关 puts
和 printf
也用 0x90
NOP 填充
然后运行程序,把“她的诗”解密后第 10 行提交过去:
However, someday, someone will find it.
不用半分钟就能自动输出 Flag
Flag: flag{HowEVER,_Somedaj,_sOMe0NE_wILl_FiND_it.}
困惑的 flxg 小程序 (Unsolved, 250pt)
后续发布
CWK的试炼 (650pt)
神庙设计图, Get! (Solved, 250pt)
用 Google 的 dwebp.exe
工具将 webp
图片转为 png
图片。
用 Stegsolve
打开 png
图片, Green
第 0 通道 隐写了一个 onion
地址,然后就想到 tor
。
Onion 地址: ustcctfbase7l74q.onion 2333
用 tor
代理 nc
连接这个 onion
地址,提示需要输入 blueprint
的 CRC32
才能继续。
然后还提示 blueprint
用类似的方法藏在图片内。
其实 blueprint
是一个 ELF
文件,经过 base64
编码后,逐 bit
以黑白代表 0
和 1
藏在了 Green
第 0 通道 中神庙的区域内。
经过处理,得到 webp.bmp
文件:
然后写个脚本把 blueprint
提取出来并算 CBC32
值。
from PIL import Image from base64 import * import binascii im=Image.open('webp.bmp') w=im.size[0] h=im.size[1] def bw(color): if color==(0,0,0): return 0 else: return 1 coffset=[] for i in range(615): coffset.append([0,0,0]) i=0 for y in range(h): for x in range(w): if bw(im.getpixel((x,y)))==1: coffset[i][0]=y coffset[i][1]=x i+=1 break i=0 for y in range(h): for x in range(w): if bw(im.getpixel((w-x-1,y)))==1: coffset[i][2]=w-x-1 i+=1 break #print coffset table='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=' raw='' i=0 for offset in coffset: tmp_raw='' data='' y=offset[0] for x in range(offset[1],offset[2]+1): data+=str(bw(im.getpixel((x,y)))) #print data if i==0: raw+='0'+data else: match_1=0 for j in range(0,8): tmp_raw=raw[len(raw)/8*8:] tmp_raw+='0'*j+data match_2=1 for k in range(len(tmp_raw)/8): if chr(int(tmp_raw[k*8:k*8+8],2)) not in table: match_2=0 break if match_2==1: match_1=1 raw+='0'*j+data break if match_1==0: print 'error' i+=1 s='' for t in range(len(raw)/8): s+=chr(int(raw[t*8:t*8+8],2)) length=len(s)/4*4 if length!=len(s): length+=4 s=s.ljust(length,'=') s=b64decode(s) open('trial.elf','wb').write(s) print 'CRC32: %X' % (binascii.crc32(s) & 0xffffffff)
CRC32: 3D6540C7
将 CRC32 提交过去,拿到 Flag
Flag: flxg{But_the_Sun_Also_Rises}
此小技耳 (Unsolved, 400pt)
后续发布
Z 同学的 RSA (Unsolved, 300pt)
后续发布
数理基础扎实的发烧友 (Unsolved, 300pt)
后续发布
一些宇宙真理 (Unsolved, 300pt)
后续发布
对抗深渊 (Unsolved, 350pt)
后续发布
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 这位科学家研发鸟类面部识别技术
- 第五届NJSD全球软件大会推荐书单
- 第五届蓝桥杯Java B——分糖果
- 第五届蓝桥杯Java B——矩阵翻硬币
- 第五届蓝桥杯Java B——地宫取宝
- 第五届大学生RDMA编程挑战赛正式开赛
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Design Accessible Web Sites
Jeremy Sydik / Pragmatic Bookshelf / 2007-11-05 / USD 34.95
It's not a one-browser web anymore. You need to reach audiences that use cell phones, PDAs, game consoles, or other "alternative" browsers, as well as users with disabilities. Legal requirements for a......一起来看看 《Design Accessible Web Sites》 这本书的介绍吧!