上周末打的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做(
寫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]<res[i][j+1])
for i in range(4): #col=1時當前值<下方的值&&col=2時當前值>下方的值
for j in range(5):
if col[5*i+j]==1:
s.add(res[i][j]<res[i+1][j])
elif col[5*i+j]==2:
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}