hackergame 2018

做了做中科大的hackergame,感觉不是传统的CTF,偏重于趣味性。做了一天多就没做了…

签到题

提交 hackergame2018 即可,但是输入框进行了限制,改一下输入框限制大小就可以了(或者抓包发)。

flag{Hackergame2018_Have_Fun!}

猫咪问答

emmmmm 中科大的特色题,问的就是中科大的一些东西,直接 google 就好了:
image.png

flag{G00G1E-is-always-YOUR-FRIEND}

游园会的集章卡片

附件给了一堆图片,这个题就是拼图,把图拼起来就好了:
flag.png

flag{H4PPY_1M4GE_PR0CE551NG} (注意数字1和字母l的区别)

Word 文档

题目给了一个 OfficeOpenXML.docx,打不开。考虑用 binwalk -e 命令,得到一个压缩包。

压缩包里发现flag.txt。

flag{xlsx,pptx,docx_are_just_zip_files}

猫咪银行

题目的意思是原本有 10CTB,通过存款并取出来赚钱,赚够 20CTB去买 flag。但是问题在于有效期就 10 分钟,赚不够 20CTB,取出的时间远远超出 10 分钟。

尝试把时间输的大一些,发现直接溢出了…
image.png
直接取出,再换成CTB,去买flag:
image.png

flag{Evil_Integer._Evil_Overflow.}

黑曜石浏览器

题目说请使用黑曜石浏览器访问,谷歌一波黑曜石浏览器,发现了官网: https://heicore.com/index.php

想要下载浏览器要登录,登录需要注册,注册需要黑曜石浏览器访问… 怀疑这个官网是出题人写的…

看页面应该是这个浏览器就是个梗,出题人根据官网出的,感觉套路就是抓包把 user-agent 改成这个所谓的黑曜石浏览器的格式,但是问题是 user-agent 格式不清楚。

应该是这个官网有端倪,这个网站我右键看不了源码… ctrl+u 也不行,F12就崩溃,源码肯定有东西。没办法就直接浏览器手输 view-source:https://heicore.com 成了。找到了这个:
image.png
应该就是想要的,访问题目地址,抓包改 user-agent:
image.png

flag{H3ic0re_49.1.2623.213_sai_kou}

回到过去

题目给了个附件,打开是写 flag 文件的 ed 命令,去照着命令输:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
q
ed
a
flag{
.
a
44a2b8
a3d9b2c
c44039
f93345
}
.
2m3
2m5
2m1
2
s/4/t
q
q

命令不包括保存文件的命令,所以要在最后 q 之前加一个 “w flag.txt” 保存文件,发现成功写入 flag.txt:
image.png

flag{t4a2b8c44039f93345a3d9b2}

我是谁

哲学思考

提示输入我是谁,到底是什么东西呢?看源码等等找了半天,最后 F12 看到了服务器状态码:
image.png

I’M A TEAPOT

输入 teapot 得到 flag:

flag{i_canN0t_BReW_c0ffEE!}

Can I help me?

打开第一问给的链接:

image.png
用不同方法访问,抓包改成POST访问:

image.png
根据提示去看 RFC-7168,发现了 BREW 访问,改成 BREW,提示缺少参数:

image.png
去 RFC-7168 找一下头部参数,发现了这个:

image.png
加一个 Content-Type: message/teapot,给了一个链接:

image.png
去访问:

image.png

flag{delivering_tea_to_DaLa0}

猫咪遥控器

题目给了控制猫行动的指令,U,D,L,R 分别对应上,下,左,右。应该要把图画出来,借助 python 的 turtle 库(据说教小孩子学编程的…)

脚本如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import turtle
import time

t = turtle.Pen()
position=[0,0]
data=open("seq.txt","r").read()
for i in data:
if i=="D":
position[1]-=0.7
elif i=="U":
position[1]+=0.7
elif i=="L":
position[0]-=0.7
elif i=="R":
position[0]+=0.7
t.goto(position[0],position[1])
time.sleep(10)

结果:
Q

flag{MeowMeow}

猫咪克星

nc 过去让计算表达式的值,写个交互脚本发现了问题…算到后面无缘无故退出或者程序终止。

调试一下发现后面计算的表达式中含有 print,sleep,exit 之类的命令,而我用 eval() 直接执行显然不行,要对接受的表达式进行一点替换,把这些命令替换成 0 ,下面是最后的脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import socket
import re
def Eval(shizi):
if shizi.find("print")!=-1:
a = re.findall("print(..*?\).*?)", shizi)
for i in a:
shizi = shizi.replace(i, "").replace("print", "0")
if shizi.find("system")!=-1:
shizi = shizi.replace("__import__('os').system('find ~')", "0")
if shizi.find("sleep")!=1:
shizi=shizi.replace("__import__('time').sleep(100)","0")
if shizi.find("exit()")!=1:
shizi=shizi.replace("exit()","0")
return eval(shizi)
time = 1
sc = socket.socket()
host = "202.38.95.46"
port = 12009
addr = (host, port)
sc.connect(addr)
print(sc.recv(1024).decode())
while 1:
print("-----------round {}--------------".format(time))
data = sc.recv(1024).decode()
print(data)
if "flag" in data:
exit()
shizi = data.split('\n')[0]
result = str(Eval(shizi))
print("result:", result)
sc.send((result + "\n").encode())
time +=1

flag{‘Life_1s_sh0rt_use_PYTH0N’*1000}

他的诗

题目给了一个 poem.txt 和 helper.py 两个文件。

poem.txt里面是密文,helper.py是一段解密程序。

运行 helper.py 得到这样一首诗:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
---------
There is something in this world
that no one has ever seen before.
It is gentle and sweet.
Maybe if it could be seen,
everyone would fight over it.
That is why the world hid it,
so that no one could get their hands
on it so easily.
However, someday, someone will find it.
The person who deserves it the most
will definitely find it.
---------
Do you like this school?
I really, really love it.
But nothing can stay unchanged.
Fun things... Happy things...
They can't all possibly stay unchanged.
Even so,
can you go on loving this place?
---------
Sometimes I wonder,
what if this town was alive?
What if it had thoughts and feelings
like one of us?
If it did,
I think it would want to make the people
who live here happy.
---------
Expectations are what you have
when you have given up.
Expectations are born from
a despairingly large difference in skill.
---------
A joke only lasts for a moment,
if it leaves a misunderstanding,
it becomes a lie.
---------
If someone didn't have any pride,
wouldn't they also be lacking
in self-confidence?
If someone was free of greed,
wouldn't they have trouble
supporting their family?
And if people didn't envy one another,
wouldn't they stop inventing new things?
---------
If I don't have to do it, I won't.
If I have to do it, I'll make it.
---------
/* Here is the end of my poem.
Have you ever found my FLAG? :) */

看了半天这只是一首诗,并没有什么特殊的地方。那么 flag 到底在哪呢?

把目光放到解密的 py 脚本上,其中一句:

decode_data = decode(data.encode(“ascii”), “uu”)

这个 uu 是不是有特定含义?我改成别的字母发现报错,查了查才知道是 uuencode 编码。

既然如此,把密文放到uuencode 在线解密网站进行解密,发现了不一样的地方:

1
---------There is something in this worldfthat no one has ever seen before.It is gentle and sweet.lMaybe if it could be seen,aeveryone would fight over it.gThat is why the world hid it,{so that no one could get their handson it so easily.STHowever, someday, someone will find it.The person who deserves it the mostewill definitely find it.---------Do you like this school?I really, really love it.gABut nothing can stay unchanged.n0Fun things... Happy things...gThey can't all possibly stay unchanged.Even so,rcan you go on loving this place?A---------Sometimes I wonder,Phwhat if this town was alive?y_What if it had thoughts and feelingslike one of us?If it did,w1I think it would want to make the peopletHwho live here happy._---------Expectations are what you havewhen you have given up.uExpectations are born fromUa despairingly large difference in skill.e---------A joke only lasts for a moment,Ncif it leaves a misunderstanding,0it becomes a lie.D---------If someone didn't have any pride,wouldn't they also be lackingEin self-confidence?_IIf someone was free of greed,5wouldn't they have trouble_supporting their family?And if people didn't envy one another,5wouldn't they stop inventing new things?0_---------If I don't have to do it, I won't.fuIf I have to do it, I'll make it.---------/* Here is the end of my poem.

咱们看到了花括号{,和脚本跑出来解密结果不一样,猜想比脚本解密结果多的部分就是 flag,写个脚本比较一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# coding:utf-8
import re
import string
import difflib
flag=""
a='''
---------
There is something in this world
that no one has ever seen before.
It is gentle and sweet.
Maybe if it could be seen,
everyone would fight over it.
That is why the world hid it,
so that no one could get their hands
on it so easily.
However, someday, someone will find it.
The person who deserves it the most
will definitely find it.
---------
Do you like this school?
I really, really love it.
But nothing can stay unchanged.
Fun things... Happy things...
They can't all possibly stay unchanged.
Even so,
can you go on loving this place?
---------
Sometimes I wonder,
what if this town was alive?
What if it had thoughts and feelings
like one of us?
If it did,
I think it would want to make the people
who live here happy.
---------
Expectations are what you have
when you have given up.
Expectations are born from
a despairingly large difference in skill.
---------
A joke only lasts for a moment,
if it leaves a misunderstanding,
it becomes a lie.
---------
If someone didn't have any pride,
wouldn't they also be lacking
in self-confidence?
If someone was free of greed,
wouldn't they have trouble
supporting their family?
And if people didn't envy one another,
wouldn't they stop inventing new things?
---------
If I don't have to do it, I won't.
If I have to do it, I'll make it.
---------
/* Here is the end of my poem.
'''
a=a.replace("\n","")
b="---------There is something in this worldfthat no one has ever seen before.It is gentle and sweet.lMaybe if it could be seen,aeveryone would fight over it.gThat is why the world hid it,{so that no one could get their handson it so easily.STHowever, someday, someone will find it.The person who deserves it the mostewill definitely find it.---------Do you like this school?I really, really love it.gABut nothing can stay unchanged.n0Fun things... Happy things...gThey can't all possibly stay unchanged.Even so,rcan you go on loving this place?A---------Sometimes I wonder,Phwhat if this town was alive?y_What if it had thoughts and feelingslike one of us?If it did,w1I think it would want to make the peopletHwho live here happy._---------Expectations are what you havewhen you have given up.uExpectations are born fromUa despairingly large difference in skill.e---------A joke only lasts for a moment,Ncif it leaves a misunderstanding,0it becomes a lie.D---------If someone didn't have any pride,wouldn't they also be lackingEin self-confidence?_IIf someone was free of greed,5wouldn't they have trouble_supporting their family?And if people didn't envy one another,5wouldn't they stop inventing new things?0_---------If I don't have to do it, I won't.fuIf I have to do it, I'll make it.---------/* Here is the end of my poem."
d = difflib.Differ()
diff = list(d.compare(a,b))
for line in diff:
if line[0]=='+':
flag+=line
flag=flag.replace("+","").replace(" ","")
print flag

得到的 flag 是: flag{STegAn0grAPhy_w1tH_uUeNc0DE_I5_50_fu

缺了点什么,后面补一下”n}” bingo!

flag{STegAn0grAPhy_w1tH_uUeNc0DE_I5_50_fun}

Z 同学的 RSA

题目代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/usr/bin/env python3

import sympy

p = sympy.randprime(2 ** 1023, 2 ** 1024)
q = sympy.randprime(2 ** 1023, 2 ** 1024)

a = (p * q) ^ (p + q)
b = (p * q) ^ (p - q)

flag = open('flag.txt', 'rb').read()
m = int.from_bytes(flag, 'big')

print(a, b, pow(m, 65537, p * q))

题目只提供了 p 和 q 以及密文,p 和 q 都是 1024bit,我们要根据 a 和 b 来求私钥。因为给的都是异或运算的结果,难以通过数学变换得到。

这里用到的是逐比特猜解的思想,从低位向高位猜解。对于 a 和 b 的最低 n 个 bit 位,只和 p 和 q 的最低 n 个位有关。我们可以用 a 和 b 的最低位来验证 p 和 q 是否满足要求。

对于每位,p 和 q 就四种可能:(0,0) (0,1) (1,0) (1,1) 我们从最后第一位开始尝试,满足要求的组合放入候选列表里,对于候选列表的每项,验证高一位时又会分出四种情况,同样进行验证,更新候选列表,把符合要求的放入列表里,以此类推。最后找到满足 a 和 b 所有 bit 位的 p 和 q。

可以看一下 wiki 的相关资料:
https://ctf-wiki.github.io/ctf-wiki/crypto/streamcipher/lcg/challenge/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# -*- coding: utf-8 -*-
import gmpy2
import libnum

a=20177650286553319048656572431426864683972322616537528728644836950907654167144961938429509778926505938147163259147328872178897507791522569632637628576826135964471897661414351261453774090509205324220367785291196302551202990322952833839519685942136552490589504983264090018782888509594899124308485994909369157739590678421913334422763356613026472743079024933233557565198057398238454462971661266735075199307328588913060033329742394868127944469289321187036511972057975816136466581904044150309083660596527476198646767207896234322280486096803109351478982849399252765905154625449629131202246956928879278104313464399748896654335
b=-20177650286553319048656572431426864683972322616537528728644836950907654167144961938429509778926505938147163259147328872178897507791522569632637628576826135964471897661414351261453774090509205324220367785291196302551202990322952833839519685942136552490589504983264090018782888509594899124308485994909369157739690798236942786515359420891819523078078001184938002588184640997371794236705658312351156161124668283889171041058024858239408724965303885485356611059740480075879221661858319606783376958758348179998879989787088907672913468336293174408246405953882533580841784122100084676690051777413318254860735992696612183461891
c=13366903717795173429187761381567634048063984815133198408928503123602872647318097072713914639532980123537673828080136443096769208675278048903846468093331645356496756288494505939828792144555809683756644579691988377803769792505153509199204570978899052097185497377390921828391436597604626534413078392906362225675998274015504081511064143613477551873256333146732640157434336327576006467405800870704016822007754775192350360613102361780884075519253676949699170275909029570177548059093617965631063061181238396995096224186949430603966487712969428525308725462401758888441403291459307185920723957045088801754933390532219059494721


f1 = lambda p, q: (p * q) ^ (p + q)
f2 = lambda p, q: (p * q) ^ (p - q)

candidates = {(0, 0)}

for m in range(1025):
print(m, len(candidates))
candidates_ = set()
mask = (2 << m) - 1
for x, y in candidates:
for bx in range(2):
for by in range(2):
xx = x + (bx << m)
yy = y + (by << m)
if f1(xx, yy) & mask != a & mask:
continue
if f2(xx, yy) & mask != b & mask:
continue
candidates_.add((xx, yy))
candidates = candidates_
for x, y in candidates:
if f1(x, y) == a and f2(x, y) == b:
p, q = x, y
d = gmpy2.invert(65537, (p - 1) * (q - 1))
m = pow(c, d, p * q)
print(libnum.n2s(m))
exit()

flag{Z_loves_RSA_and_maths~!:)}

参考: https://github.com/ustclug/hackergame2018-writeups/blob/master/official/RSA_of_Z/README.md

-------------本文结束感谢您的阅读-------------
0%