中国科学技术大学第五届信息安全大赛 Write Up
题目位置和官方题解 Hackergame 2018 hackergame2018-writeups
签到题
输入框限制了输入长度,改一下就 ok,或者直接修改 url 的 key 参数也行The flag is: flag{Hackergame2018_Have_Fun!}
猫咪问答
题目是让你回答几个问题,但是我怎么也没想到真的要搜索!flag{G00G1E-is-always-YOUR-FRIEND}
游园会的集章卡片
图片拼接不需要根据题面把文件重命名完之后,塞到 word 里或者直接关掉图标对齐在桌面调整就能看出flag{H4PPY_1M4GE_PR0CE551NG}
猫咪和键盘
首先瞎搞把注释里的 URL base64 搞出来,结果居然是代码模板的链接我也来写一个类型安全的 printf,仔细对比一下,应该是只修改了 main 函数,对照最长的那句还原就行了
#define def_typed_printf(f,str) constexpr static const char str_fmt##f[] = str; auto f = _typed_printf<str_fmt##f,0>();
#define ABC "FfQ47if9Zxw9jXE68VtGA"
#define BAC "JDk6Y6Xc88UrUtpK3iF8p"
#define CAB "7BMs4y2gzdG8Ao2gv6aiJ"
int main(){
def_typed_printf(f_l_x_g_1, "%s%s%s%s");
f_l_x_g_1("fl")("a")("g")("{");
def_typed_printf(a_a_a_a_a_a_a_a_a, "%s%s%s%s%s%s%d");
a_a_a_a_a_a_a_a_a(ABC)("")(BAC)("")(CAB)("")('}');
def_typed_printf(def_typed_printf_, "%s%d%s");
def_typed_printf_("typed_printf")('_')("}");
return 0;
}
由于目标程序使用的是 c++17 因此我还需要更新 g++才能编译
# ubuntu
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo apt update
sudo apt install -y g++-7
g++-7 -std=c++17 typed_printf.cpp -o flag
./flag
> flag{FfQ47if9Zxw9jXE68VtGAJDk6Y6Xc88UrUtpK3iF8p7BMs4y2gzdG8Ao2gv6aiJ125typed_printf95}
Word 文档
打开文件提示错误,word 自动修复后仔细看文件,发现关键字 zip,尝试将文件后缀改为 zip 解压即可看到 flag 文件flag{xlsx,pptx,docx_are_just_zip_files}
黑曜石浏览器
题面
为了文档安全,请使用最新版本黑曜石浏览器(HEICORE)访问。
看题意明显是要改 UA,尝试将 UA 改为 HEICORE,失败,估计还需要版本号才行 搜索「黑曜石浏览器」找到网站https://heicore.com/index.html
(我真是服了出题人)。打开开发者工具会卡死或者跳转到其他页面,尝试用 curl 访问找到 UAvar HEICORE_UA = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) HEICORE/49.1.2623.213 Safari/537.36";
,替换后得到 flag黑曜石浏览器赛高
curl 'http://202.38.95.46:12001/' -H 'User-Agent: HEICORE/49.1.2623.213' | grep flag
<p>The flag is: <code>flag{H3ic0re_49.1.2623.213_sai_kou}</code></p>
回到过去
直接把序列打到 ed 里然后一行一行查看拼接就行了,注意(不可见字符)需要手动处理,得到
flag{t4a2b8c44039f93345a3d9b2}
我是谁
题面
Can you tell me who I am?
打开开发者工具刷新一下能看到网页的状态码是418 I'M A TEAPOT
,所以这是个teapot
(出题人脑洞太大)
提交之后得到flag{i_canN0t_BReW_c0ffEE!}
第二小题让我们用其他 methods 请求,先试试 POST
curl 'http://202.38.95.46:12005/the_super_great_hidden_url_for_brewing_tea/' -X POST
<p>The method "POST" is deprecated.</p>
<p>See RFC-7168 for more information.</p>
翻阅RFC-7168 - The Hyper Text Coffee Pot Control Protocol for Tea Efflux Appliances (HTCPCP-TEA) 用 method 作为关键字搜索很快能发现茶壶支持BREW
方法,在跟据请求后提示查阅资料补上 Content-Type 后
curl 'http://202.38.95.46:12005/the_super_great_hidden_url_for_brewing_tea/' -v -X BREW -H 'Content-Type: message/teapot'
* HTTP 1.0, assume close after body
< HTTP/1.0 300 MULTIPLE CHOICES
< Content-Type: text/html; charset=utf-8
< Content-Length: 19
< Alternates: {"/the_super_great_hidden_url_for_brewing_tea/black_tea" {type message/teapot}}
< Server: Werkzeug/0.14.1 Python/3.6.6
根据Alternates
头替换 url 最后得到
curl 'http://202.38.95.46:12005/the_super_great_hidden_url_for_brewing_tea/black_tea' -X BREW -H 'Content-Type: message/teapot'
Here is your tea: flag{delivering_tea_to_DaLa0}
猫咪银行
思路一开始是 sql inject、同时进行多次不同买入/卖出操作(竞争)、购买负数买入分钟负数,但是都不对,卡了很久最后发现可以在买入时间上进行溢出操作(买入时间10000000000000000000
),然后可以立即取出抢银行成功flag{Evil_Integer._Evil_Overflow.}
猫咪遥控器
装了半天 turtle 失败,突发奇想写了个 SVG小乌龟画图
str = "";
seq = str.split("").reduce((pre, cur) => {
last = pre.slice(-1)[0];
if (last && last[0] === cur) {
last[1]++;
} else {
pre.push([cur, 1]);
}
return pre;
}, []);
console.log(seq.join("\n"));
dir = {
U: [0, -1],
D: [0, 1],
L: [-1, 0],
R: [1, 0],
};
posArr = [[0, 0]];
seq = seq.reduce((pre, cur) => {
pos = pre.slice(-1)[0];
now = [];
now[0] = pos[0] + cur[1] * dir[cur[0]][0];
now[1] = pos[1] + cur[1] * dir[cur[0]][1];
pre.push(now);
return pre;
}, posArr);
svgPath = "M " + seq.join(" L");
console.log(svgPath);
flag{MeowMeow}
猫咪克星
题目是让你连上指定机器完成 python 表达式,由于 30s 的时间限制,我们手动算肯定来不及
import socket
target = '202.38.95.46'
port = 12009
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((target, port))
buf_size = 4096
data = ['']
while True:
buffe = client.recv(buf_size).decode('utf-8')
if buffe == 'Timeout!\n':
break
if not buffe:
continue
buffe = filter(lambda s: s, buffe.split('\n'))
data += buffe
# print(data) # DEBUG
calc = None
stop = None
ban = ['You', 'Timeout', 'flag']
while not calc:
if not data:
break
calc = data.pop(0)
if calc and 'You' in calc:
calc = None
continue
if calc and 'flag' in calc:
print(calc)
calc = None
client.close()
exit()
if not calc:
continue
calc = calc.replace("__import__('os').system('find ~')", '0')
calc = calc.replace('sleep(100)', 'sleep(0)')
calc = calc.replace('exit()', '0')
print(calc)
ret = str(eval(calc)) + '\n'
print(ret)
client.send(ret.encode('utf-8'))
比较需要注意的几个数据包含exit() sleep(100) system('find ~')
(然后就被猫咪拿了 shell),因为数量不多我选择了硬编码替换
int(((27>>int(13!=__import__('os').system('find ~')))*(25<<78))>((34*1)|(37|86)))
int(int((int(1!=exit())-int(__import__('time').sleep(100)!=10))>=(2>>8))>=int((1&int(5!=exit()))==(37*int(__import__('time').sleep(100)!=1))))
最后 flag{'Life_1s_sh0rt_use_PYTH0N'*1000}
猫咪电路
很有创意的一道题,没有很复杂的电路,带火把一路调试就行了花了半小时熟悉游戏 3 天后。。。 0110 1010 0011 1100 1011 1111 1111 1111 1111 1010 flag{0110101000111100101111111111111111111010}
C 语言作业
逆向程序之后,发现它是个简单的计算器程序,而且考虑了除以 0 的情况。再仔细翻翻,看到这个程序初始化的时候把几个信号注册到__err
函数上了,而这个函数是可以用来执行程序。那我们的目的显然就是要让计算器崩溃执行 err 函数。
除 0 的情况已经被程序考虑了,所以我们只能用最小的 INT 除以 -1 让程序崩溃,输入-2147483648/-1
成功崩掉这个计算器。
之后要绕过执行命令不能包含sh
的限制,其中 vim 使用:!
是可以执行命令的,进入 vim 后运行:!cat flag
就行了,结果它告诉我真的 flag 在-
文件里,那就继续:!cat ./-
得到 flag。手速来不及可以使用echo -e "-2147483648/-1\nvim\n:!cat flag\n:!cat ./-" | nc 202.38.95.46 12008
一键获取 flag