看这里,
由京东安全与华安普特赞助开源聚合杯网络安全大赛
官方题库发布了!
CTF题型看这里,
解题思路看这里,
脑洞大开、奇思妙想还是看这里!
囊括数据分析、PWN、命令注入漏洞、
PHP弱密码漏洞、主机密码破解……
1
WEB
MD5文件
题目描述:
请输入两个诡异的文件
地址 http://202.98.28.108:10991/w77230hy76hw
解析思路:
这个题目没有源码泄露的问题,但是题目提示说要提交两个不同的文件,但是其实相同。听上去比较矛盾,但是我们知道php中有很多hash比较漏洞。本题目尝试了一些弱类型比较不可行,于是我们搜索到两个md5强碰撞的文件拿去提交
最终payload:
file1=M%C9h%FF%0E%E3%5C%20%95r%D4w%7Br%15%87%D3o%A7%B2%1B%DCV%B7J%3D%C0x%3E%7B%95%18%AF%BF%A2%00%A8%28K%F3n%8EKU%B3_Bu%93%D8Igm%A0%D1U%5D%83%60%FB_%07%FE%A2file2=M%C9h%FF%0E%E3%5C%20%95r%D4w%7Br%15%87%D3o%A7%B2%1B%DCV%B7J%3D%C0x%3E%7B%95%18%AF%BF%A2%02%A8%28K%F3n%8EKU%B3_Bu%93%D8Igm%A0%D1%D5%5D%83%60%FB_%07%FE%A2
我们看到两段不同的字符串,他们计算得到的md5却是相同的。
最终得到flag{qiu82nuqq2nfi}
秘密花园
题目描述:
这是个秘密通道~只有知道真正密码的人才能进入
答题地址:http://202.98.28.108:10991/h723ghh982
解析思路:
首先我们查看页面的源代码发现一个提示:
于是我们访问的url上加上对应的参数,获得了页面源代码
发现是php序列化的漏洞问题,只需要传入对应的cookie值比较相等即可。
我们复制全部源代码到本地zend中进行序列化构造payload
虽然我们看到源码最后有定义了KEY变量的值,可是,注意php的变量影响范围,在上半部分的KEY变量不会受到另一个php文件头中的文件的影响。所以他的值为空。我们利用cookiemanager插件修改cookie变量Whale,传入变量为:s:0:””%0b
再次访问login页面获取flag
2
CRYPTO
打开脑洞
题目描述:
打开脑洞
了解比特币吗~
flag格式:flag{xxx}
解析思路:
题目首先给出了一个比特币计算网址Brainwalletx (https://brainwalletx.github.io/)截图,“brainwallet”是通过记忆恢复密码在您的脑海中存储比特币的概念。该特定页面从所述密码生成地址,以及私钥/公钥对。私钥是挑战的标志,我们得到passprase的第一个和最后三个字母。为了测试我们获得了正确的密码,我们还以QR码的形式给出了结果地址。这似乎是一个只有通过暴力破解才能解决的问题,事实上,我们在图片右下方给出了完整的混乱密码。一旦你拿走了我们可以看到的字母的位置,我们剩下的字母就是:ucoitsgr,而这一切都是关于它们的切换。应该可行:
我们扫描二维码得到了一个比特币的地址(其实是搜索之后才发现是比特币地址的):
现在我们只是没有私钥,那么可以通过这个找回网址不断计算出比特币地址来与题目中给出的进行比较(对每个“uccoitsgr”进行排列组合,并且在Passphrase字段输入)。这里利用了selenium自动浏览器不断去爆破就行。
代码如下:
fromselenium importwebdriver
fromselenium.webdriver.common.keys importKeys
fromitertools importpermutations
importtime
# nullcon8itsgr8
driver = webdriver.Firefox()
driver.get( "https://brainwalletx.github.io/#generator")
addr = driver.find_element_by_id( "addr")
passp = driver.find_element_by_id( "pass")
start = '8ln'
end = 'nl8'
qr = '17iUnGoZbFrGS7uU9z2d2yRT9BKgVqnKnn'
"""
We only need to look for the characters we don't know the position of
"""
fori inpermutations( 'ucoitsgr'):
print(i)
pp = start + ''.join(i) + end
passp.send_keys(pp)
"""
Need to sleep to let the value update :(
"""
time.sleep( 1)
rec_addr = addr.get_attribute( "value")
ifrec_addr == qr:
print(pp)
break
passp.clear()
爆破的时候请注意,每次输入密码之后,我们要1秒之后地址才会更新,所以需要sleep1秒
爆破思路的解题时间可能会长一些~我们稍等片刻~
最终flag{5KjzfnM4afWU8fJeUgGnxKbtG5FHtr6Suc41juGMUmQKC7WYzEG}
泡泡龙
题目描述:
我吹了很多泡泡~请把其中的加密信息解密
xinik-samak-luvak-dotuk-dumok-sanik-domak-dimik-sinih-zudih-zumil-homak-dorik-humal-homik-dorak-huzex
解析思路:
根据题目提示,是bubblebubble算法,我们通过在线网址:(http://ctf.ssleye.com/bubble.html)可以解密:
flag{bubblebabble_I_bubblebubble}
飞的更高
题目描述:
只要集齐我的5个分身,我就能飞得更高
解析思路:
首先下载所给的文件,是一个抓包软件抓取的数据包,解题流程如下:
1.用wireshark分析数据包
打开数据包,发现是一堆TCP的包,先不理会底层的数据,只关心应用层。
应用层的协议只有HTTP,过滤出HTTP的包进一步分析:
请求都发往http://sz.mail.ftn.qq.com,猜测是qq邮箱的地址。
同时观察第一个请求
POST了一段这样的JSON:
{
"path": "fly.rar",
"appid": "",
"size": 525701,
"md5": "e023afa4f6579db5becda8fe7861c2d3",
"sha": "ecccba7aea1d482684374b22e2e7abad2ba86749",
"sha3": ""
}
目标url为:
http: //set2.mail.qq.com/cgi-bin/uploadunite?func=CreateFileinputf=jsonoutputf=jsonsid=x5O8ZuWvSp9yXFgM
这应该是一个上传文件的操作,文件名为fly.rar,文件大小为525701。
进一步分析以验证猜想,过滤出全部的POST数据包:
http.request.method == "POST"
其中倒数第二个包的内容是:
至此已经可以确定:
数据包的内容:一封带附件的邮件
发件人:81101652@qq.com
收件人:king@woldy.net
附件:fly.rar
附件大小:525701 Bytes
接下来寻找附件数据在哪里。
2.寻找附件数据
第一个请求向服务器POST附件信息,紧接着就应该是上传,结合数据包推断第2~6个,共5个数据包应为附件数据。
5个数据包中的Media Type域的大小各为
131436
131436
131436
131436
1777
合计527521,而前面附件信息里已知附件大小为525701,相差不多,多出来的部分应该是头部的信息之类。
3.还原附件数据
观察5个包Media Type域的内容,前面很大一部分内容是相同的,那么这一部分是通信时所需的头部的内容,不是附件本身的内容,通过计算将多余的数据去除。
已知:
附件被分成5个部分
5个子部分合计大小为527521
附件原大小为525701
求:
每个子部分头部多余的数据
容易求出,头部多余的部分:
527521?5257015=364Bytes
将5个数据包的Media Type域分别导出为二进制文件:
然后使用dd命令分别将其前364个字节去除:
dd if= 1bs= 1skip= 364of= 1.1
dd if= 2bs= 1skip= 364of= 2.1
dd if= 3bs= 1skip= 364of= 3.1
dd if= 4bs= 1skip= 364of= 4.1
dd if= 5bs= 1skip= 364of= 5.1
之后合并文件:
cat 1.1 2.1 3.1 4.1 5.1 fly.rar
校验md5值:
md5sumfly.rar
结果:
e023afa4f6579db5becda8fe7861c2d3
而第一步中得到的数据包中POST数据为:
{
"path": "fly.rar",
"appid": "",
"size": 525701,
"md5": "e023afa4f6579db5becda8fe7861c2d3",
"sha": "ecccba7aea1d482684374b22e2e7abad2ba86749",
"sha3": ""
}
二者一致。同理再校验sha值,同样一致。
至此,由网络包还原出了附件数据fly.rar:
4.处理附件数据
本以为到这里已经大功告成,解压fly.rar即可。
结果还有后招……竟然解压失败……
分析原因,fly.rar文件通过了md5和sha校验,肯定是没问题的,自己的思路到这里断了,怎么想也没结果。
无奈搜答案,得出结果——伪加密。
即这是一个未加密过的rar文件,但是却将加密位置为了1,
只需将文件开头处0x74位后面的0x84位置改为0x80即可修改后顺利解压,得到flag.txt。
5.处理flag.txt
这回答案该有了吧,打开flag.txt查看,这又是一个二进制文件。
无语。
继续二进制打开。
发现这是个win32的程序,Linux跑不了,转到windows查看。
是个满屏幕跑苍蝇的程序……还挺逼真的……
还是二进制打开分析。
文件内搜PNG、Rar、JFIF,文件尾有一个PNG,提取出来,是个二维码:
扫之,得到结果
flag{m1Sc_oxO2_Fly}
千年蛤蜊
题目描述:
找到蛤蜊并打开它找到珍珠。
提示:flag在ppt中
https://zxing.org/w/decode.jspx
解析思路:
根据题目提示,先解压img文件。然后在ppt/media目录下找到有问题的图片:
搜索发现,这是一个Maxcode,通过在线工具:https://Zxing.org扫描
flag{TH1NK ABOUT 1T B1LL. 1F U D13D, WOULD ANY1 CARE??}
3
STEGA
搜查证据
题目描述:
我发现一个压缩文件应该有一些证据,但是出于某种原因,他们都坏了。你能找出来哪里出了问题吗?
答案格式:flag{xxx}
解析思路:
题目给出的压缩包解压错误,我们诊断错误看到:
用好压打开观察:
Crc转换之后能够有flag的成分,所以根据签名排序,利用命令提取crc:
forx in$(zipinfo -v evidence.zip | grep CRC | cut -d: -f 2 | sed 's# +#0x#g'); doexportx; python -c 'import os; from struct import pack; from sys import stdout; stdout.write( pack("I", int(os.environ["x"], 16)) )'; done
得到flag:
flag{th3_vi11i4n_w3_n33d_#freeleffen}
口号
题目描述:
孩子和妈妈的对话中夹杂了隐藏的小纸条哦~注意文件标题
hint:这不是base64但是用了python3的base64模块
password=password
答案格式:flag{xxx}
解析思路:
根据标题中的提示:
解密base64得到一个steghide的网址,我们用这个工具解密。
密码为提示中的password=password
steghide extract -sf momandson.jpg -p password
得到一个base58的字符串:
W^7?+dsk3VRB_4W^-?2X=QYIEFgDfAYpQ4AZBT9VQg %9AZBu9Wh@|fWgua4Wgup0ZeeU}c_3kTVQXa}eE
再根据提示,用python3中的base64模块解密得到flag
python3
import base64
base64.b85decode(b 'W^7?+dsk3VRB_4W^-? 2X=QYIEFgDfAYpQ4AZBT9VQg%9AZBu9Wh@|fWgua4Wgup0ZeeU}c_3kTVQXa}eE')
b 'flag{We are fsociety, we are finally free, we are finally awake!}'
最终flag{We are fsociety, we are finally free, we are finally awake!}
4
REVERSE
引擎逆向
题目描述:
运行go.sh验证你的flag....
答案格式:flag{xxx}
解析思路:
典型的z3解题,通过z3暴力破解找到flag:
典型的z3解题,通过z3暴力破解找到flag:
fromz3 import*
fromstruct importunpack_from
defsolve(records):
B = []
N = 34857
fori inxrange(N):
B.append(BitVec(i, 1))
s = Solver()
fori inB:
s.add(Or(i == 0, i == 1))
s.add(B[ 0] == 0)
s.add(B[ 1] == 1)
s.add(B[ 34792] == 1)
fori inxrange( 34):
s.add(B[ 2+ i * 8+ 7] == 0)
fori inxrange(len(records)):
op_type, q1, q2, q3, q4 = records[i]
ifop_type == 1:
s.add(B[q1] B[q2] == B[q4])
elifop_type == 2:
s.add(B[q1] | B[q2] == B[q4])
elifop_type == 3:
s.add(B[q1] ^ B[q2] == B[q4])
elifop_type == 4:
s.add(Or(And(B[q1] == 1, B[q2] == B[q4]), And(B[q1] == 0, B[q3] == B[q4])))
r = []
ifs.check() == sat:
model = s.model()
fori inxrange(N):
r.append(model[B[i]].as_long())
else:
print'Oops'
returnr
defget_records():
withopen( 'cp', 'rb') asf:
cp = f.read()
some_val, count = unpack_from( 'QQ', cp)
res = []
fori inxrange(count):
res.append(unpack_from( 'QQQQQ', cp, i * 40+ 16))
returnres
defset_bit(n, b, p):
returnn | (b p)
defget_str(r, offset, lenght):
s = ''
n = 0
l = r[offset:]
fori inxrange(lenght * 8):
n = set_bit(n, l[i], i 7)
ifi 0andi 7== 7:
s += chr(n)
n = 0
returns
records = get_records()
print'Wait'
l = solve(records)
print'Done'
printget_str(l, 2, 34)
printget_str(l, 34793, 8)
flag{wind*w(s)_*f_B1ll(ion)_g@t5s}
5
PWN
格式问题
题目描述:
nc 202.98.28.108 9898
解析思路:
Ida查看,发现有缓冲区溢出漏洞,但是只会读入0x19(25)个字符
计算缓冲区溢出占位,我们想要调用flag函数(0x 0007F3)
所以我们输入24*a加上flag的地址/x73
echo-e "aaaaaaaaaaaaaaaaaaaaaaaaxf3"| nc 202.98.28.1089898
得到flag:
FLAG{72hs9jenuxkei745t6heixoamghn}
微信号:开源聚合网络空间安全研究院