杂项题出题人思路清奇,其他题目啥也不会
最后放了个问卷题搞偷袭,没拿到...很气
队伍成绩:1228pt/7kill/59名/520有解
个人成绩:807pt/5kill
Misc
little tricks
题目
无描述,给了一个vhdx格式的磁盘镜像。
WriteUp
双击直接挂载,发现俩分区,一个是MSR分区,微软特色的,不知道对题目有没有用,因为不知道咋打开就放那没管;另一个是NTFS分区,但被Bitlocker加密了,不知道密码。
后来队友试弱口令试出来密码是12345678,打开发现就一个记录着密码的txt,于是DiskGenius走起,发现回收站有个pdf,于是打开拿到flag。
这个pdf十分玄学,
DiskGenius的自带预览器可以看见flag,那adobe家的AAC就只能看到假的flag,不清楚原理,大佬说是pdf水印,得看软件支持情况。
flag
*ctf{59ca21b54198345f0efa963195e}
MineGame
题目
If you love reverse, you can try it, otherwise, you must finish it as quickly as possible.
WriteUp
打开发现需要装matlab运行环境,于是去官网下了2个G去装。装好打开发现是个扫雷,心理落差极大...
而且这个扫雷要么点地板点不出东西,要么定时闪退...
本来想着拿CE暂停然后分析内存的,但是用CE的变速功能暂停不住...
后来大佬说CE的暂停功能是在左下角高级选项里的暂停按钮...
于是暂停了直接搜flag字符*ctf{和*CTF{(需要勾选UTF-16即Unicode),找到内存后把长度改长一点或者直接查看内存区域就能成功拿到flag。
flag
*CTF{Y0u_41e-gLeat_6Oy3!}
puzzle
题目
无描述,给了个44*25拼图图片。
WriteUp
本来想着依靠区块边界颜色相似性来写脚本拼,但是找不到好的相似算法,放弃。
队友用gaps跑自动拼图脚本,得到的结果是只拼了一部分的拼图。
于是拿gaps的结果去Google搜原图,成功拿到一张不怎么原的原图(图上没有flag,而且可能有裁剪)。
接着拿ps去慢慢拼吧,听说一血的大佬也是手拼的。
最后有几个带文字的区块没找到,按照字体匹配字型的方式成功推测出flag。
flag
flag{you_can_never_finish_the}
Crypto
GuessKey
题目
from random import randint
import os
from flag import flag
N=64
key=randint(0,2**N)
print key
key=bin(key)[2:].rjust(N,'0')
count=0
while True:
p=0
q=0
new_key=''
zeros=[0]
for j in range(len(key)):
if key[j]=='0':
zeros.append(j)
p=zeros[randint(0,len(zeros))-1]
q=zeros[randint(0,len(zeros))-1]
try:
mask=int(raw_input("mask:"))
except:
exit(0)
mask=bin(mask)[2:]
if p>q:
tmp=q
q=p
p=tmp
cnt=0
for j in range(0,N):
if j in range(p,q+1):
new_key+=str(int(mask[cnt])^int(key[j]))
else:
new_key+=key[j]
cnt+=1
cnt%=len(mask)
key=new_key
try:
guess=int(raw_input("guess:"))
except:
exit(0)
if guess==int(key,2):
count+=1
print 'Nice.'
else:
count=0
print 'Oops.'
if count>2:
print flag
WriteUp
根据题目源码可以知道只要知道初始的key就能以mask=0的方式让新生成的key保持原状。(你问我咋知道的,第一次连上去随便输个0发现就是对的。)
那么反正key在初始时已经输出了,那就直接nc上去一个0一个原key一个0一个原key一个0一个原key就拿到flag了。
flag
*CTF{bcceb9d0913793c7d10ffedddac47cd2}
GuessKey2
题目
I’m sorry ?
from random import randint
import os
from flag import flag
N=64
key=randint(0,2**N)
# print key
key=bin(key)[2:].rjust(N,'0')
count=0
while True:
p=0
q=0
new_key=''
zeros=[0]
for j in range(len(key)):
if key[j]=='0':
zeros.append(j)
p=zeros[randint(0,len(zeros))-1]
q=zeros[randint(0,len(zeros))-1]
try:
mask=int(raw_input("mask:"))
except:
exit(0)
mask=bin(mask)[2:]
if p>q:
tmp=q
q=p
p=tmp
cnt=0
for j in range(0,N):
if j in range(p,q+1):
new_key+=str(int(mask[cnt])^int(key[j]))
else:
new_key+=key[j]
cnt+=1
cnt%=len(mask)
key=new_key
try:
guess=int(raw_input("guess:"))
except:
exit(0)
if guess==int(key,2):
count+=1
print 'Nice.'
else:
count=0
print 'Oops.'
if count>2:
print flag
WriteUp
和前一题对比源码发现就是把初始key的输出给整没了,那么原来的方法就不行了。
那么本地跑一下简化的题目源码试试看找规律吧(猜测是输入重复输入某个数或者某组数能够使得key趋于特定值),因为N太大不好找规律,所以把N改成8试了一下,发现重复输入2**n-1就能使得key的二进制被1填充满。
于是就可以写脚本去拿flag了。
import time
import socket
N = 64
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(("52.163.228.53", 8082))
count = 0
mask = 1
guess = 2**N - 1
while True:
recv = sock.recv(6).decode().strip("\n")
print(recv, end = "")
sock.send((str(mask)+"\n").encode())
recv = sock.recv(6).decode()
print(recv, end = "")
sock.send((str(guess)+"\n").encode())
recv = sock.recv(5).decode()
print(recv)
if recv == 'Oops.':
count = 0
elif recv == 'Nice.':
mask = 0
count += 1
if count > 2:
print(sock.recv(1024))
sock.close()
break
大概guess个一百多回就能拿到flag。
flag
*CTF{27d30dad45523cbf88013674a4b5bd29}

