這次個人賽難度真的undingable,就只能做做雜項苟着這樣子,re手轉行做misc警告(
拿到題目是看到有一個flag1.txt
和一個加密壓縮包password.7z
file一下txt文件可以看到:
是uuencode文件,所以用python跑一下解出flag.7z
:
import uu
uu.decode('flag1.txt')
然后password.7z
的密碼什么提示都沒有,一度以為是從txt里找線索,后來放了hint才知道是6-8位數字,弱口令猜了一輪都沒用以后果斷用cRARk-7z爆破:
crark-7z -l6 -g8 -p"password.def" .\password.7z
password.def
里寫的是:
##
$1 *
(定義密碼規則,這里是遍歷純數字,具體可以看readme
爆破出密碼是321456
解開password.7z
,得到flag.7z
的password是7324623c
。
解開能看到一張圖片和一個encode.py
,很容易就猜到是flag的圖片經過encode.py
以后得到的challenge.png
,所以我們需要對着encode.py
寫逆算法。
簡單分析一下encode.py
:
# encode.py
import numpy as np
import cv2
import sys
import random
def encode(image):
i = random.randint(520,540)
np.random.seed(i) #用一個520-540的種子初始化隨機函數,注意random.randint的區間是前閉后閉
# image = 1298 * 695
to_hide = cv2.imread(image)
to_hide_array = np.asarray(to_hide) #把flag圖片讀進成ndarray
for i in range(to_hide_array.shape[0]):
np.random.shuffle(to_hide_array[i]) #對ndarray進行亂序
gray = cv2.cvtColor(to_hide_array, cv2.COLOR_BGR2GRAY) #生成灰度圖片
cv2.imwrite('challenge.png', gray) #寫入challenge.png中
print("encode!")
def main():
if len(sys.argv) != 2:
print('error!')
exit(1)
encode(sys.argv[1])
if __name__ == '__main__':
main()
邏輯很清晰,就是用了一個亂序對flag圖片進行了處理。
這里涉及到np.random.shuffle的工作機制,大概就是對某個長度的一維數組進行位置上的隨機亂序,而對相同的隨機數種子和相同長度的數組來說打亂的效果是一樣的,它不關心數組的數據是啥,只關心什么位置的該被打亂到什么位置。
所以關鍵亂序部分的逆算法是:
for i in range(to_hide_array.shape[0]):
# np.random.shuffle(to_hide_array[i])
length=to_hide_array.shape[1]
l=[ll for ll in range(length)] #構造一個跟to_hide_array[i]相同長度的數組l
tmps=[-1 for _ in range(length)] #臨時數組,用來填還原的結果
np.random.shuffle(l) #對l進行亂序處理
for j in range(length):
tmps[l[j]]=to_hide_array[i][j] #亂序前在j位置的數在亂序后會被轉到l[j],所以根據l[j]->j來還原順序
to_hide_array[i]=np.asarray(tmps)
接下來就剩爆破520-540這個隨機數種子了,注意random.randint的區間是前閉后閉,不要爆破少了(
exp:
import numpy as np
import cv2
import sys
import random
def decode(image,x):
np.random.seed(x)
# image = 1298 * 695
to_hide = cv2.imread(image)
to_hide_array = np.asarray(to_hide)
for i in range(to_hide_array.shape[0]):
# np.random.shuffle(to_hide_array[i])
length=to_hide_array.shape[1]
l=[ll for ll in range(length)]
tmps=[-1 for _ in range(length)]
np.random.shuffle(l)
for j in range(length):
tmps[l[j]]=to_hide_array[i][j]
to_hide_array[i]=np.asarray(tmps)
gray = cv2.cvtColor(to_hide_array, cv2.COLOR_BGR2GRAY)
cv2.imwrite('challenge'+str(x)+'.png', gray)
print('challenge'+str(x)+'.png',"decode!")
def main():
if len(sys.argv) != 2:
print('error!')
exit(1)
# decode(sys.argv[1],520)
for i in range(520,541):
decode(sys.argv[1],i)
if __name__ == '__main__':
main()
可以解出challenge540.png
有:
得到flag:flag{931549887f0a1398807eb68a656180ef}