目录
- 中科大-Hackergame2018 write-up
- 签到题
- 猫咪问答
- 游园会的集章卡片
- 猫咪和键盘
- Word 文档
- 猫咪银行
- 黑曜石浏览器
- 回到过去
- 我是谁
- 家里有矿
- 秘籍残篇
- 猫咪遥控器
- 她的诗
- 猫咪克星
- 猫咪电路
- FLXG 的秘密
欢迎前往个人主页享受更优质的浏览体验。https://yof3ng.github.io
中科大-Hackergame2018 write-up
这个比赛主要面向新生,较为友好,链接:https://hack.lug.ustc.edu.cn/
此场比赛充满了猫咪与flxg(废理兴工),虽然作为一个老腊肉去做小鲜肉的题很不好意思,但该做的还是要做啦。
签到题
打开题目链接之后,题面如下图:
Key的输入框限制了长度,通过开发者工具修改页面源码,或者抓包发送 hackergame2018获取 flag:
The flag is: flag{Hackergame2018_Have_Fun!}
猫咪问答
这一题虽然表面上是对中科大新生有优势,但是实际上是个社工题。考验学生的搜索能力,信息收集能力。毕竟信安肯定是要跟这个打交道的啦。简单搜索(百度,必应,谷歌)一下,提交得到flag:
flag{G00G1E-is-always-YOUR-FRIEND}
游园会的集章卡片
这一题实际上考验学生的拼图能力,只不过是花的实时间长短而已,需要注意的就是字母和数字的分辨,可能有的其他题目会需要一个前面的过程来获取到零碎的图片,再到这一步拼图。拼完图可以得到flag:
flag{H4PPY_1M4GE_PR0CE551NG}
猫咪和键盘
题目是一份经过了乱序处理的代码,虽然说是乱序,但还是有一定规律的,比如说可以看出跟列有关系,某列整体移到另一个位置之类的。
简单来说,要还原整个项目是不太可能实现的,所以我们需要根据出题人给我们的路,认真抉择,然后行动。比如源码首部的author,name,url等信息,可以谷歌得到项目的一部分源码,再还原一部分关键性的代码,理解逻辑即可。
根据name,author可以在搜到位于github的项目源码,前一部分自定义函数是相同的,主函数不同,我们还原一下ABC,BAC,CAB:
ABC:FfQ47if9Zxw9jXE68VtGA
BAC:JDk6Y6Xc88UrUtpK3iF8p
CAB:7BMs4y2gzdG8Ao2gv6aiJ
根据主函数逻辑可以得到flag是像下面这样拼接的:
printf("%s%s%s%s %s%s%s%s%s%s%d %s%d%s","f","l","a","g",ABC,"",BAC,"",CAB,"}","type_printf","_","}")
flag{FfQ47if9Zxw9jXE68VtGAJDk6Y6Xc88UrUtpK3iF8p7BMs4y2gzdG8Ao2gv6aiJ125type_printf92}
Word 文档
这题的话主要是给新生扩充一个知识点:office套件实际上都属于zip压缩包,将后缀改为zip就能以压缩包的形式打开office文档,然后看见其文件结构。
猫咪银行
又是一通过非法获取钱财买flag的题目呢,经过简单的尝试输入后发现没什么特殊的漏洞,不能以科学计数(如 0e516516)的方式作为切入点,改cookie只能重置账户,买1/4个flag跟没买似的。
仔细看可以发现,理财时间有下限,但是没有上限,先兑换TDSU,输一个大数试试看,oh一不小心就溢出了:
但是我们需要控制溢出的收益,不然收益为负,够你受的了。通过控制输入的大数的大小来调节:922337203685477500
The flag is:
flag{Evil_Integer._Evil_Overflow.}
护网杯中那个辣条之王溢出的题比较精妙,需要通过条件竞争的手法(即多线程同时购买,同一时间多次购买只需要一次付钱),再判断溢出点,从而getflag:题解 https://qingchenldl.github.io/2018/10/13/%E6%8A%A4%E7%BD%91%E6%9D%AFWP-BitPwn/?tdsourcetag=s_pcqq_aiomsg
黑曜石浏览器
这就是那个坑到无数老少爷们,一时风头无俩的黑曜石浏览器(HeiCore),确实出题人比较良心,为这个题目甚至专门写了一个前端页面来迷惑各位CTFer,这个黑曜石浏览器主页是在百度上不能搜索到的,在必应和谷歌上可以查到,很明显这个页面很不正经,简直是在嘲笑各位CTFer的智商嘛是不是?
好回到题目,实际上我们也做了比较久,尝试过各种方法之后回到了原点:黑曜石浏览器主页,这个主页除了假正经之外还有就是,不能查看源码,用谷歌的开发者工具看主页时会返回404。那么问题已经比较明显了,这里就是出题人的阻碍,为啥要阻碍,因为关键在这里,拿到关键的东西之后我们就可以去题目那里获取flag了。
谷歌用不了我们用火狐嘛,来看看network,看看源码:
哦嚯,获得了一个user-agent,题目页面不是需要通过黑曜石浏览器访问吗,既然我们没有黑曜石浏览器这个东西,当然也可以通过user-agent来代表我们是黑曜石浏览器的身份咯,构造请求,加上user-agnet,getflag。
The flag is:
flag{H3ic0re_49.1.2623.213_sai_kou}
回到过去
#input_sequence
q
ed
a
flag{
.
a
44a2b8
a3d9b2c #关键在这一行最后的c是保留不保留
c44039
f93345
}
.
2m3 #开始换行
2m5
2m1
2 #切换到第二行
s/4/t #将当前行的第一个4替换为t
q
q
这一题介绍了一下ed编辑器的使用,给出了一个文件如上,里面有键盘记录,实际上根据键盘记录,利用ed编辑器重写一遍就可获得flag,但是这个还是有一个坑点,那就是那个多出来的 ESC特殊符,刚开始在MobaXterm上面自带的ed做题,发现 2m3之类的换行命令无法实现,后来使用云服务器进行一波操作得到flag:
flag{t4a2b8c44039f93345a3d9b2}
我是谁
这一题有两个小题,充满哲学。考察的是客户端错误相应代码和 “递茶”协议。。。
第一题通过查看network,可以看到status code里面有
418 I AM A TEAPOT
,正好问我是谁嘛,把TEAPOT填进去,getflag1:
flag{i_canN0t_BReW_c0ffEE!}
然后可以获取第二小题的链接,简单查看一下,响应如下:
#这年头给大佬递茶都不简单了
Brewing tea is not so easy.
Try using other methods to request this page.
#试试post请求,响应如下:
The method "POST" is deprecated.
See RFC-7168 for more information.
#试试brew请求,响应如下:
Please check if there is anything missing in your header.
结合两题的信息 I AM A TEAPOT + brew tea + RFC-7168搜索一下,可以得到说明文档:
https://tools.ietf.org/html/rfc7168
根据文档构造请求header里面的Content-Type: message/teapot,发送过去得到如下信息:
根据返回的信息,我们需要将构造的请求发送到另一个url,即在原url后面加上递茶类型black_tea:
/the_super_great_hidden_url_for_brewing_tea/black_tea
getflag:
家里有矿
提示:
- 本题的浏览器“挖矿”只为演示性目的,几乎不占资源。我们不会以任何形式盗取或浪费大家电脑的算力。
- 本题如果使用程序求解,对于普通配置的个人电脑,在解法正确且最优的情况下,求解程序的期望运行时间不会超过几分钟。
该题并不是常规的web 题,解题过程不涉及注入、XSS、敏感文件泄露、弱类型等安全问题。
但是我暂时不会,所以待更新。
秘籍残篇
从这题就开始涉及古文化,玄学知识了。这题也是一个两小题的题目,第一题给出了一段malbolge语言的代码在文件中。一个骚操作。。直接用火狐浏览器打开文件,然后调整页面大小(%30),宽度得到以下嘲讽CTFer的图案:
猫咪遥控器
为了报复猫咪把自己的代码打乱(见:猫咪与键盘),D 同学把猫咪遥控器绑在可以上(UP)下(DOWN)左(LEFT)右(RIGHT)移动的三轴机械臂上,开始使用树莓派(一款基于 Linux 的单片机计算机)控制三轴机械臂,进而控制猫咪在草地上跑来跑去。
此题给出的txt文件中有 U(UP),D(DOWN),L(LEFT),R(RIGHT),即上下左右咯,既然是让猫咪按这个跑,很简单就是画出路线图嘛,写一个简单的python脚本,利用tutle海龟库写,getflag:
flag{MeowMeow}
#coding=utf-8
import turtle as T
with open('seq.txt','r') as f:
strings = f.read()
print(strings)
T.speed(0)
for i in strings:
if (i=='U'):
T.seth(90)
T.fd(1)
elif(i=="D"):
T.seth(270)
T.fd(1)
elif(i=="L"):
T.seth(180)
T.fd(1)
elif(i=="R"):
T.seth(0)
T.fd(1)
运行结果:
她的诗
题目给了一个poem.zip,包含一个python解密脚本和一个包含加密后诗的文件。根据解密脚本可以知道是uuencode,开始过于相信这个解密脚本,没想到出题人在这儿动手脚
#!/usr/bin/env python3 # This script helps you decode "her poem" from codecs import decode fin = open("poem.txt", "r") fout = open("poem.out", "w") for i in fin: data = "begin 666 \n" + i + " \nend\n" decode_data = decode(data.encode("ascii"), "uu") print(decode_data) fout.write(decode_data.decode("ascii") + "\n") fin.close() fout.close()
重点!在线解密密文即可得到真正的flag,flag分散藏在每行的头部,但是flag少了一个n需要自行添加在最后面补全为一个单词fun。
猫咪克星
nc 202.38.95.46 12009
蟒蛇是一种非常容易使用的编程语言,考验你像不像蟒蛇的标准就是给你一些 Python 3 表达式。如果你能正确计算出来,你就通过了验证。
简单来说就是要在30秒内完成指定次数表达式的计算,然后可以得到服务器给出的flag,但是坑爹的是表达式中有一些特殊函数,类似于目录遍历 find ~,sleep(100),exit(),所以这种东西我采取了替换的方法。
因为print函数在python3和python2中不同,而我需要使用python2中的pwntools库(python3的socket不知为何无用),同时拥有python3的print函数特性,这时候就需要:from _ _ future _ _ import print_function
引入python3 print函数。
最终脚本如下(脚本比较简陋,可能需要多跑几次才能出flag):
from __future__ import print_function
#coding:utf-8
from pwn import *
sh = remote("202.38.95.46",12009)
getit = sh.recvline()
while True:
strings = sh.recvline()
strings = strings.replace('sleep(100)','int(1)')
strings = strings.replace('exit()','1')
strings = strings.replace('find ~','echo 1')
strings = strings.replace("__import__('time').",'')
print(strings)
key = eval(strings)
sh.sendline(str(key))
if 'flag' in strings:
print(strings)
exit(0)
脚本运行结果如下:
猫咪电路
当年玩的minercraft被做成了题目,好吧,红石电路,这是一个存档,需要我们按规律输入信号,然后直到光柱亮起,正确的信号即为flag:
flag{0110101000111100101111111111111111111010}
FLXG 的秘密
题目有点长,我总结一下,给出的文件中是伏羲六十四卦的卦象,简单搜索一下可以知道,伏羲六十四卦可以跟二进制扯上关系,六十四卦分别对应二进制000000-111111,对应关系如下:
'坤': '000000', '剥': '000001', '比': '000010', '观': '000011', '豫': '000100', '晋': '000101', '萃': '000110', '否': '000111', '谦': '001000', '艮': '001001', '蹇': '001010', '渐': '001011', '小过': '001100', '旅': '001101', '咸': '001110', '遁': '001111', '师': '010000', '蒙': '010001', '坎': '010010', '涣': '010011', '解': '010100', '未济': '010101', '困': '010110', '讼': '010111', '升': '011000', '蛊': '011001', '井': '011010', '巽': '011011', '恒': '011100', '鼎': '011101', '大过': '011110', '姤': '011111', '复': '100000', '颐': '100001', '屯': '100010', '益': '100011', '震': '100100', '噬嗑': '100101', '随': '100110', '无妄': '100111', '明夷': '101000', '贲': '101001', '既济': '101010', '家人': '101011', '丰': '101100', '离': '101101', '革': '101110', '同人': '101111', '临': '110000', '损': '110001', '节': '110010', '中孚': '110011', '归妹': '110100', '睽': '110101', '兑': '110110', '履': '110111', '泰': '111000', '大畜': '111001', '需': '111010', '小畜': '111011', '大壮': '111100', '大有': '111101', '夬': '111110', '乾': '111111'
写一个python脚本将那个文件中的卦象分别解成二进制,可以发现bit数正好是4039032,可以整除8(8bit为1byte)。到这基本上可以判断思路正确。
脚本如下:
import re
special = '''乾﹑坤﹑屯﹑蒙﹑需﹑讼﹑师﹑比﹑小畜﹑履﹑泰﹑否﹑同人﹑大有﹑谦﹑豫﹑随﹑蛊﹑临﹑观﹑噬嗑﹑贲﹑剥﹑复﹑无妄﹑大畜﹑颐﹑大过﹑坎﹑离﹑咸﹑恒﹑遁﹑大壮﹑晋﹑明夷﹑家人﹑睽﹑蹇﹑解﹑损﹑益﹑夬﹑姤﹑萃﹑升﹑困﹑井﹑革﹑鼎﹑震﹑艮﹑渐﹑归妹﹑丰﹑旅﹑巽﹑兑﹑涣﹑节﹑中孚﹑小过﹑既济﹑未济'''
#二进制顺序的卦象
guashu = '''坤、剥、比、观、豫、晋、萃、否、谦、艮、蹇、渐、小过、旅、咸、遁、师、蒙、坎、涣、解、未济、困、讼、升、蛊、井、巽、恒、鼎、大过、姤、复、颐、屯、益、震、噬嗑、随、无妄、明夷、贲、既济、家人、丰、离、革、同人、临、损、节、中孚、归妹、睽、兑、履、泰、大畜、需、小畜、大壮、大有、夬、乾'''
def Getword():
strings = []
s=special.split('﹑')
s2 = guashu.split("、")
diction = {}
with open('G://数据//ctf赛题//中科大ctf//flxg的秘密.txt',encoding="utf-8") as f:
strings2 = f.read()
for i in strings2:
strings.append(i)
f.close()
strings = set(strings)
#因为卦象中存在一个字或者两个字的卦象,jieba分词库不准确,就用/来区别
for i in s:
diction[i]=strings2.count(i)
strings2 = strings2.replace(i,'/'+i+'/')
return diction,strings2,s2
if __name__ == '__main__':
diction,strings2,s2 = Getword()
finalbin =''
finaldiclist=[]
dicts={}
n=0
for i in diction.items():
n+=i[1]*6
print('bits='+str(n/8))
finalstrings = strings2.split('/')
for a in finalstrings:
if a in s2:
finaldiclist.append(a)
#建立卦象与二进制的关系字典
nice =0
n=0
for i in s2:
dicts[i] = format(n,'b').zfill(6)
n=n+1
print(dicts)
print(len(finaldiclist)*6/8)
#按字典解密写入文件
for b in finaldiclist:
finalbin+=dicts[b]
with open('finalbin.txt','w+') as ff:
ff.write(finalbin)
接下来利用python的libnum库,将二进制转换为字符串得到第一个flag:
用binwalk分析一下内容,发现里面有一个压缩包,进行提取得到以下文件:一个flag elf程序 ,passkey.txt,简单看一下,接下来的第二题应该是逆向了。。待更新。。。
先到这 。