【wp】2021CISCN初赛
上周末打的CISCN初赛,发现没整理wp来火速补上。
这次RE属实拉跨,就做了俩签到题,做完就去摸MISC了,冲刺卷还能摸出个robot是我没想到的。(以及想看零解HMI的wp,翻了半天没翻到check我可好奇死了x
Reverse
glass
说签到真的是签到题
用JEB看java层发现是直接调用so的,那直接apktool解压然后去逆so文件
显而易见的前两个函数是RC4相关(还以为会魔改= =,第三个函数是一个自定义加密函数
密文在unk_497C
,长度0x27,先还原encrypt之前的数组,然后进行RC4解密(写了一些注释在代码里
exp:
# 还原encrypt前的数据
arr=[0xA3, 0x1A, 0xE3, 0x69, 0x2F, 0xBB, 0x1A, 0x84, 0x65, 0xC2, 0xAD, 0xAD, 0x9E, 0x96, 0x05, 0x02, 0x1F, 0x8E, 0x36, 0x4F, 0xE1, 0xEB, 0xAF, 0xF0, 0xEA, 0xC4, 0xA8, 0x2D, 0x42, 0xC7, 0x6E, 0x3F, 0xB0, 0xD3, 0xCC, 0x78, 0xF9, 0x98, 0x3F]
key=b"12345678"
pos=0
for j in range(0,39,8): #第一部分逐字节xor 根据xor的特性直接把加密方法照搬
k=0
while k!=8 and j+k<39:
arr[pos+k]^=key[k]
k+=1
pos+=8
l=[]
for i in range(0,39,3): #第二部分乱七八糟的xor 直接拿已知数组copy了一下加密流程试出对应关系
l+=[arr[i+1]^arr[i+2],arr[i]^arr[i+1],arr[i]^arr[i+1]^arr[i+2]]
data=bytes(l)
# RC4加/解密
from arc4 import ARC4
rc4=ARC4(key)
ans=rc4.encrypt(data)
print(ans)
CISCN{6654d84617f627c88846c172e0f4d46c}
baby_bc
.bc
文件前不久某场比赛才接触过,直接走流程
先用clang -c baby.bc -o baby.bc.o
(也可以clang baby.bc -o baby
得到可执行文件),然后直接用ida逆.o
文件
(是附件更新前做出来的,吐槽一句怎么更新附件以后还把符号表混淆了x
前半个check是用输入填充地图/棋盘,map空的部分填输入的ascii码-48,map有值的部分输入要为'0'。输入只能为0-5。
后半个check有四个部分,分别是同一行的数据各不相同、同一列的数据各不相同、col=1时当前值<下方的值&&col=2时当前值>下方的值、row=1时当前值>右方的值&&row=2时当前值<右方的值。
这个check规则不就是futoshiki吗hhh
比赛的时候想在网上找脚本,但是没找到能用的,完全靠手推(。
赛后被队里师兄提醒说其实可以用z3约束求解,猛然想起好像确实能用做哦(傻了x),现在复盘的话不如来学着写z3做(
参考wp:【CISCN2021】第十四届全国大学生信息安全竞赛初赛-writeup
写z3脚本有:
from z3 import *
from hashlib import md5
row=[0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00]
col=[0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01]
s=Solver()
res=[[Int("x%d%d"%(i,j)) for i in range(5)] for j in range(5)]
s.add(res[2][2]==4) #原map中已知值
s.add(res[3][3]==3)
for i in range(5):
for j in range(5):
s.add(res[i][j]>=1)
s.add(res[i][j]<=5)
for k in range(j): #同一行互不相等
s.add(res[i][j]!=res[i][k])
for k in range(i): #同一列互不相等
s.add(res[i][j]!=res[k][j])
for i in range(5): #row=1时当前值>右方的值&&row=2时当前值<右方的值
for j in range(4):
if row[4*i+j]==1:
s.add(res[i][j]>res[i][j+1])
elif row[4*i+j]==2:
s.add(res[i][j]下方的值
for j in range(5):
if col[5*i+j]==1:
s.add(res[i][j]res[i+1][j])
ans=s.check()
if ans==sat:
# print(s.model())
m=s.model()
flag=[]
for i in res:
for j in i:
flag.append(m[j].as_long())
flag=[x+0x30 for x in flag]
flag[12]=0x30
flag[18]=0x30
flag=bytes(flag)
print(flag)
print("CISCN{"+md5(flag).hexdigest()+"}")
输入是1425353142350212150442315,得到flag:
CISCN{8a04b4597ad08b83211d3adfa1f61431}
Misc
tiny_traffic
翻流量包的时候有看到get了secret文件,这种文件名立刻警觉,感觉是关键文件
查看响应包21615,有一个Content-Encoding:br,查了一下是Brotli压缩的文本
于是试图导出http对象,得到secret文件后解压缩发现解不出什么可见字符,于是逐个试了一遍没后缀名的文件解压,试出了:
import brotli
with open('test','rb') as f:
data=brotli.decompress(f.read())
print(data)
手动拆一下就是
syntax = "proto3";
message PBResponse {
int32 code = 1;
int64 flag_part_convert_to_hex_plz = 2;
message data {
string junk_data = 2;
string flag_part = 1;
}
repeated data dataList = 3;
int32 flag_part_plz_convert_to_hex = 4;
string flag_last_part = 5;
}
message PBRequest {
string cate_id = 1;
int32 page = 2;
int32 pageSize = 3;
}
查了一下proto3跟python的联动,找到了这篇文章,https://blog.csdn.net/menghaocheng/article/details/80176763,格式跟需求都一样,直接按步骤做
写入protobuf处理脚本:
import brotli
with open('test','rb') as f:
data=brotli.decompress(f.read())
with open('../test.proto','wb') as f:
f.write(data)
运行./protoc.exe --python_out=./ test.proto
得到test_pb2.py
不知道先调哪个message于是两个都试了一下,最后exp是:
import brotli
import test_pb2
res=test_pb2.PBResponse()
with open('secret','rb') as f:
s=brotli.decompress(f.read())
res.ParseFromString(s)
print(res)
得到:
于是再拼接一下变成flag:
print("CISCN{"+hex(15100450)[2:]+"e2345"+"7889b0"+hex(16453958)[2:]+"d172a38dc}")
CISCN{e66a22e23457889b0fb1146d172a38dc}
robot
看了一眼别人的wp发现我这个好像非预期了= =
依然是翻流量包,都是TCP协议包,于是直接追踪TCP流,能看到很明显的符合r"tgPos{\d+}\.Value\.\[\d+,\d+,-?\d+]"
这种正则的字符串。
这种中括号形式就很像坐标,更何况这还是机器人绘制,肯定需要定位。
一开始以为是x,y,z这样分布,不过后来发现每个第三个值为-10的坐标点都是每个tgPos的最后一个,所以猜测第三个值是用来标定是否结束的。
所以把这里追踪的结果全部复制下来,然后用python提取并画图
import re
import matplotlib.pyplot as plt
x=[]
y=[]
with open('tcp.txt','r') as f:
for line in f.readlines():
ret=re.search(r"tgPos{\d+}\.Value\.\[\d+,\d+,-?\d+]",line) #提取目标字符串
if ret!=None:
s=ret.group()
idx1=s.find('[')
idx2=s.find(',')
idx3=s.rfind(',')
x.append(int(s[idx1+1:idx2]))
y.append(int(s[idx2+1:idx3]))
plt.scatter(x,y)
plt.show()
可以得到图片:
垂直镜像处理一下就是:
由print("CISCN{"+md5(b'easy_robo_xx').hexdigest()+"}")
得到flag:
CISCN{d4f1fb80bc11ffd722861367747c0f10}