RE復現
login_system
這個函式就是判斷username,點進去發現是線性方程,用z3解
from z3 import *
s=Solver()
a=[0]*16
for i in range(16):
a[i]=Int('a'+"["+str(i)+"]")
s.add(a[2]+a[1]+a[0]+a[3]==447)
s.add(101*a[2]+a[0]+9*a[1]+8*a[3]==12265)
s.add(5*a[2]+3*a[0]+4*a[1]+6*a[3]==2000)
s.add(88*a[2]+12*a[0]+11*a[1]+87*a[3]==21475)
s.add(a[6]+59*a[5]+100*a[4]+a[7]==7896)
s.add(443*a[4]+200*a[5]+10*a[6]+16*a[7]==33774)
s.add(556*a[5]+333*a[4]+8*a[6]+7*a[7]==44758)
s.add(a[6]+a[5]+202*a[4]+a[7]==9950)
s.add(78*a[10]+35*a[9]+23*a[8]+89*a[11]==24052)
s.add(78*a[8]+59*a[9]+15*a[10]+91*a[11]==25209)
s.add(111*a[10]+654*a[9]+123*a[8]+222*a[11]==113427)
s.add(6*a[9]+72*a[8]+5*a[10]+444*a[11]==54166)
s.add(56*a[14]+35*a[12]+6*a[13]+121*a[15]==11130)
s.add(169*a[14]+158*a[13]+98*a[12]+124*a[15]==27382)
s.add(147*a[13]+65*a[12]+131*a[14]+129*a[15]==23564)
s.add(137*a[14]+132*a[13]+620*a[12]+135*a[15]==51206)
if s.check()==sat:
m=s.model()
for i in range(16):
print(m[a[i]],end=",")
a=[117,115,101,114,48,49,95,110,107,99,116,102,50,48,50,52]
for i in range(16):
print(chr(a[i]),end="")
#user01_nkctf2024
有一個簡單的異或求解
a=[0x7E, 0x5A, 0x6E, 0x77, 0x3A, 0x79, 0x35, 0x76, 0x7C]
for i in range(9):
a[i]=(a[i]+i-9)^i
print(chr(a[i]),end="")
#uSer1p4ss
v17指向的是password的第十位,即第十位要是_
dest已經求出,可以知道password的前十位是uSer1p4ss_
後面的關鍵就是這個函式了
跟進,很明顯的AES特徵,拿出S_BOX,然後求逆S_BOX
然後就是網上找的板子
class AES:#128-ECB
sbox = [0x31, 0x52, 0x5A, 0xC8, 0x0B, 0xAC, 0xF3, 0x3A, 0x8B, 0x54,
0x27, 0x9B, 0xAB, 0x95, 0xDE, 0x83, 0x60, 0xCB, 0x53, 0x7F,
0xC4, 0xE3, 0x0A, 0x97, 0xE0, 0x29, 0xD5, 0x68, 0xC5, 0xDF,
0xF4, 0x7B, 0xAA, 0xD6, 0x42, 0x78, 0x6C, 0xE9, 0x70, 0x17,
0xD7, 0x37, 0x24, 0x49, 0x75, 0xA9, 0x89, 0x67, 0x03, 0xFA,
0xD9, 0x91, 0xB4, 0x5B, 0xC2, 0x4E, 0x92, 0xFC, 0x46, 0xB1,
0x73, 0x08, 0xC7, 0x74, 0x09, 0xAF, 0xEC, 0xF5, 0x4D, 0x2D,
0xEA, 0xA5, 0xDA, 0xEF, 0xA6, 0x2B, 0x7E, 0x0C, 0x8F, 0xB0,
0x04, 0x06, 0x62, 0x84, 0x15, 0x8E, 0x12, 0x1D, 0x44, 0xC0,
0xE2, 0x38, 0xD4, 0x47, 0x28, 0x45, 0x6E, 0x9D, 0x63, 0xCF,
0xE6, 0x8C, 0x18, 0x82, 0x1B, 0x2C, 0xEE, 0x87, 0x94, 0x10,
0xC1, 0x20, 0x07, 0x4A, 0xA4, 0xEB, 0x77, 0xBC, 0xD3, 0xE1,
0x66, 0x2A, 0x6B, 0xE7, 0x79, 0xCC, 0x86, 0x16, 0xD0, 0xD1,
0x19, 0x55, 0x3C, 0x9F, 0xFB, 0x30, 0x98, 0xBD, 0xB8, 0xF1,
0x9E, 0x61, 0xCD, 0x90, 0xCE, 0x7C, 0x8D, 0x57, 0xAE, 0x6A,
0xB3, 0x3D, 0x76, 0xA7, 0x71, 0x88, 0xA2, 0xBA, 0x4F, 0x3E,
0x40, 0x64, 0x0F, 0x48, 0x21, 0x35, 0x36, 0x2F, 0xE8, 0x14,
0x5D, 0x51, 0xD8, 0xB5, 0xFE, 0xD2, 0x96, 0x93, 0xA1, 0xB6,
0x43, 0x0D, 0x4C, 0x80, 0xC9, 0xFF, 0xA3, 0xDD, 0x72, 0x05,
0x59, 0xBF, 0x0E, 0x26, 0x34, 0x1F, 0x13, 0xE5, 0xDC, 0xF2,
0xC6, 0x50, 0x1E, 0xE4, 0x85, 0xB7, 0x39, 0x8A, 0xCA, 0xED,
0x9C, 0xBB, 0x56, 0x23, 0x1A, 0xF0, 0x32, 0x58, 0xB2, 0x65,
0x33, 0x6F, 0x41, 0xBE, 0x3F, 0x6D, 0x11, 0x00, 0xAD, 0x5F,
0xC3, 0x81, 0x25, 0xA8, 0xA0, 0x9A, 0xF6, 0xF7, 0x5E, 0x99,
0x22, 0x2E, 0x4B, 0xF9, 0x3B, 0x02, 0x7A, 0xB9, 0x5C, 0x69,
0xF8, 0x1C, 0xDB, 0x01, 0x7D, 0xFD]
s_box = {}
ns_box = { }
Rcon = {
1: ['0x01', '0x00', '0x00', '0x00'],
2: ['0x02', '0x00', '0x00', '0x00'],
3: ['0x04', '0x00', '0x00', '0x00'],
4: ['0x08', '0x00', '0x00', '0x00'],
5: ['0x10', '0x00', '0x00', '0x00'],
6: ['0x20', '0x00', '0x00', '0x00'],
7: ['0x40', '0x00', '0x00', '0x00'],
8: ['0x80', '0x00', '0x00', '0x00'],
9: ['0x1B', '0x00', '0x00', '0x00'],
10: ['0x36', '0x00', '0x00', '0x00']
}
Matrix = [
['0x02', '0x03', '0x01', '0x01'],
['0x01', '0x02', '0x03', '0x01'],
['0x01', '0x01', '0x02', '0x03'],
['0x03', '0x01', '0x01', '0x02']
]
ReMatrix = [
['0x0e', '0x0b', '0x0d', '0x09'],
['0x09', '0x0e', '0x0b', '0x0d'],
['0x0d', '0x09', '0x0e', '0x0b'],
['0x0b', '0x0d', '0x09', '0x0e']
]
plaintext = [[], [], [], []]
plaintext1 = [[], [], [], []]
subkey = [[], [], [], []]
def __init__(self, key):#金鑰擴充套件
self.s_box = dict(zip(["0x%02x"%i for i in range(256)], ["0x%02x"%i for i in self.sbox]))
self.ns_box = dict(zip(self.s_box.values(), self.s_box.keys()))
for i in range(4):
for j in range(0, 8, 2):
self.subkey[i].append("0x" + key[i * 8 + j:i * 8 + j + 2])
# print(self.subkey)
for i in range(4, 44):
if i % 4 != 0:
tmp = xor_32(self.subkey[i - 1], self.subkey[i - 4],0)
self.subkey.append(tmp)
else: # 4的倍數的時候執行
tmp1 = self.subkey[i - 1][1:]
tmp1.append(self.subkey[i - 1][0])
# print(tmp1)
for m in range(4):
tmp1[m] = self.s_box[tmp1[m]]
# tmp1 = self.s_box['cf']
tmp1 = xor_32(tmp1, self.Rcon[i / 4], 0)
self.subkey.append(xor_32(tmp1, self.subkey[i - 4],0))
def AddRoundKey(self, round):#輪金鑰加
for i in range(4):
self.plaintext[i] = xor_32(self.plaintext[i], self.subkey[round * 4 + i],0)
# print('AddRoundKey',self.plaintext)
def PlainSubBytes(self):
for i in range(4):
for j in range(4):
self.plaintext[i][j] = self.s_box[self.plaintext[i][j]]
# print('PlainSubBytes',self.plaintext)
def RePlainSubBytes(self):
for i in range(4):
for j in range(4):
self.plaintext[i][j] = self.ns_box[self.plaintext[i][j]]
def ShiftRows(self):#行移位
p1, p2, p3, p4 = self.plaintext[0][1], self.plaintext[1][1], self.plaintext[2][1], self.plaintext[3][1]
self.plaintext[0][1] = p2
self.plaintext[1][1] = p3
self.plaintext[2][1] = p4
self.plaintext[3][1] = p1
p1, p2, p3, p4 = self.plaintext[0][2], self.plaintext[1][2], self.plaintext[2][2], self.plaintext[3][2]
self.plaintext[0][2] = p3
self.plaintext[1][2] = p4
self.plaintext[2][2] = p1
self.plaintext[3][2] = p2
p1, p2, p3, p4 = self.plaintext[0][3], self.plaintext[1][3], self.plaintext[2][3], self.plaintext[3][3]
self.plaintext[0][3] = p4
self.plaintext[1][3] = p1
self.plaintext[2][3] = p2
self.plaintext[3][3] = p3
# print('ShiftRows',self.plaintext)
def ReShiftRows(self):
p1, p2, p3, p4 = self.plaintext[0][1], self.plaintext[1][1], self.plaintext[2][1], self.plaintext[3][1]
self.plaintext[3][1] = p3
self.plaintext[2][1] = p2
self.plaintext[0][1] = p4
self.plaintext[1][1] = p1
p1, p2, p3, p4 = self.plaintext[0][2], self.plaintext[1][2], self.plaintext[2][2], self.plaintext[3][2]
self.plaintext[0][2] = p3
self.plaintext[1][2] = p4
self.plaintext[2][2] = p1
self.plaintext[3][2] = p2
p1, p2, p3, p4 = self.plaintext[0][3], self.plaintext[1][3], self.plaintext[2][3], self.plaintext[3][3]
self.plaintext[0][3] = p2
self.plaintext[1][3] = p3
self.plaintext[2][3] = p4
self.plaintext[3][3] = p1
def MixColumns(self):#列混淆
for i in range(4):
for j in range(4):
self.plaintext1[i].append(MatrixMulti(self.Matrix[j], self.plaintext[i]))
# print('MixColumns',self.plaintext1)
def ReMixColumns(self):
for i in range(4):
for j in range(4):
self.plaintext1[i].append(MatrixMulti(self.ReMatrix[j], self.plaintext[i]))
def AESEncryption(self, plaintext):
self.plaintext = [[], [], [], []]
for i in range(4):
for j in range(0, 8, 2):
self.plaintext[i].append("0x" + plaintext[i * 8 + j:i * 8 + j + 2])
self.AddRoundKey(0)
for i in range(9):
self.PlainSubBytes()
self.ShiftRows()
self.MixColumns()
self.plaintext = self.plaintext1
self.plaintext1 = [[], [], [], []]
self.AddRoundKey(i + 1)
self.PlainSubBytes()
self.ShiftRows()
self.AddRoundKey(10)
return Matrixtostr(self.plaintext)
def AESDecryption(self, cipher):
self.plaintext = [[], [], [], []]
for i in range(4):
for j in range(0, 8, 2):
self.plaintext[i].append('0x' + cipher[i * 8 + j:i * 8 + j + 2])
# print(self.ns_box)
self.AddRoundKey(10)
for i in range(9):
self.ReShiftRows()
self.RePlainSubBytes()
self.AddRoundKey(9-i)
self.ReMixColumns()
self.plaintext = self.plaintext1
self.plaintext1 = [[], [], [], []]
self.ReShiftRows()
self.RePlainSubBytes()
self.AddRoundKey(0)
return Matrixtostr(self.plaintext)
def Encryption(self, text):
group = PlaintextGroup(TextToByte(text), 32, 1)
# print(group)
cipher = ""
for i in range(len(group)):
cipher = cipher + self.AESEncryption(group[i])
return cipher
def Decryption(self, cipher):
group = PlaintextGroup(cipher, 32, 0)
# print(group)
text = ''
for i in range(len(group)):
text = text + self.AESDecryption(group[i])
text = ByteToText(text)
return text
def xor_32(start, end, key):
a = []
for i in range(0, 4):
xor_tmp = ""
b = hextobin(start[i])
c = hextobin(end[i])
d = bin(key)[2:].rjust(8,'0')
for j in range(8):
tmp = int(b[j], 10) ^ int(c[j], 10) ^ int(d[j],10)
xor_tmp += str(tmp )
a.append(bintohex(xor_tmp))
return a
def xor_8(begin, end):
xor_8_tmp = ""
for i in range(8):
xor_8_tmp += str(int(begin[i]) ^ int(end[i]))
return xor_8_tmp
def hextobin(word):
word = bin(int(word, 16))[2:]
for i in range(0, 8-len(word)):
word = '0'+word
return word
def bintohex(word):
word = hex(int(word, 2))
if len(word) == 4:
return word
elif len(word) < 4:
return word.replace('x', 'x0')
def MatrixMulti(s1, s2):
result = []
s3 = []
for i in range(4):
s3.append(hextobin(s2[i]))
for i in range(4):
result.append(MultiProcess(int(s1[i], 16), s3[i]))
for i in range(3):
result[0] = xor_8(result[0], result[i+1])
return bintohex(result[0])
def MultiProcess(a, b):
if a == 1:
return b
elif a == 2:
if b[0] == '0':
b = b[1:] + '0'
else:
b = b[1:] + '0'
b = xor_8(b, '00011011')
return b
elif a == 3:
tmp_b = b
if b[0] == '0':
b = b[1:] + '0'
else:
b = b[1:] + '0'
b = xor_8(b, '00011011')
return xor_8(b, tmp_b)
elif a == 9:
tmp_b = b
return xor_8(tmp_b, MultiProcess(2, MultiProcess(2, MultiProcess(2, b))))
elif a == 11:
tmp_b = b
return xor_8(tmp_b, xor_8(MultiProcess(2, MultiProcess(2, MultiProcess(2, b))), MultiProcess(2, b)))
elif a == 13:
tmp_b = b
return xor_8(tmp_b, xor_8(MultiProcess(2, MultiProcess(2, MultiProcess(2, b))), MultiProcess(2, MultiProcess(2, b))))
elif a == 14:
return xor_8(MultiProcess(2, b), xor_8(MultiProcess(2, MultiProcess(2, MultiProcess(2, b))), MultiProcess(2, MultiProcess(2, b))))
def Matrixtostr(matrix):
result = ""
for i in range(4):
for j in range(4):
result += matrix[i][j][2:]
return result
def PlaintextGroup(plaintext, length, flag):
group = re.findall('.{'+str(length)+'}', plaintext)
group.append(plaintext[len(group)*length:])
if group[-1] == '' and flag:
group[-1] = '16161616161616161616161616161616'
elif len(group[-1]) < length and flag:
tmp = int((length-len(group[-1])) / 2)
if tmp < 10:
for i in range(tmp):
group[-1] = group[-1] + '0'+str(tmp)
else:
for i in range(tmp):
group[-1] = group[-1] + str(tmp)
elif not flag:
del group[-1]
return group
#字串轉16進位制
def TextToByte(words):
text = words.encode('utf-8').hex()
return text
def ByteToText(encode):
tmp = int(encode[-2:])
word = ''
for i in range(len(encode)-tmp*2):
word = word + encode[i]
# print(word)
word = bytes.decode(binascii.a2b_hex(word))
return word
#位元組非輪異或
def xorbytes(bytes1,bytes2):
length=min(len(bytes1),len(bytes2))
output=bytearray()
for i in range(length):
output.append(bytes1[i]^bytes2[i])
return bytes(output)
res='B0CC93EAE92FEF5699396E023B4F9E42'.lower()
key = ''
for i in username:
key+=hex(ord(i))[2:].rjust(2,"0")
A1 = AES(key)
tail_pass=""
for i in range(0,len(res),32):
tail_pass+=bytes.fromhex(A1.AESDecryption(res[i:i+32])).decode()
print(tail_pass)
print(hashlib.md5(str(username+pre_pass+"_"+tail_pass).encode("utf-8")).hexdigest())
#user01_nkctf2024
#uSer1p4ss
#9ee779cd2abcde48
#2961bba0add6265ba83bc6198e0ec758
下面來學習一下標準的AES加密:
AES為分組密碼,分組密碼也就是把明文分成一組一組的,每組長度相等,每次加密一組資料,直到加密完整個明文。在AES標準規範中,分組長度只能是128位,也就是說,每個分組為16個位元組(每個位元組8位)。金鑰的長度可以使用128位、192位或256位。金鑰的長度不同,推薦加密輪數也不同
AES-128 金鑰長度為4(32位元字) 加密輪數10
AES-192 金鑰長度為6(32位元字) 加密輪數12
AES-256 金鑰長度為8(32位元字) 加密輪數14
AES的加密處理單位是位元組,128位輸入的明文和金鑰key都被分成16位元組,然後放在對應矩陣裡,偷一下圖()
繼續借用一下例子
同理,金鑰也是透過相同的矩陣表示,
Genshin
下載的是.beam字尾的檔案,考察erlang beam檔案的逆向
首先要配置好erlang的編譯器Index - Erlang/OTP
配置好環境後可以透過
io:format("~p~n",[beam_disasm:file("genshin.beam")]).
獲得位元組碼
另外可以透過
escript genshin.beam "111111"
來執行程式
這是得到的位元組碼,分為了main,check,transform等函式,一段一段看
{beam_file,genshin,
[{main,1,2},{module_info,0,11},{module_info,1,13}],
[{vsn,[294325075297162417208450880208266398775]}],
[{version,"8.3.1"},
{options,[]},
{source,
[47,109,110,116,47,100,47,67,84,70,47,20986,39064,47,50,48,50,51,45,
56,45,100,117,105,110,101,105,115,97,105,47,103,101,110,115,104,105,
110,46,101,114,108]}],
[{function,main,1,2,
[{label,1},
{line,1},
{func_info,{atom,genshin},{atom,main},1},
{label,2},
{test,is_nonempty_list,{f,3},[{x,0}]},
{get_list,{x,0},{x,1},{x,0}},
{test,is_nil,{f,3},[{x,0}]},
{move,{x,1},{x,0}},
{call_only,1,{genshin,check,1}},
{label,3},
{move,
{literal,"Usage: xxxxxxxx genshin.beam <input_string>~n"},
{x,0}},
{line,2},
{call_ext_only,1,{extfunc,io,format,1}}]},
{function,check,1,5,
[{line,3},
{label,4},
{func_info,{atom,genshin},{atom,check},1},
{label,5},
{test,is_list,{f,4},[{x,0}]},
{allocate,1,1},
{move,{x,0},{y,0}},
{move,{literal,[21407,31070,46,46,46,126,110]},{x,0}},
{line,4},
{call_ext,1,{extfunc,io,format,1}},
{move,{integer,1},{x,1}},
{move,nil,{x,2}},
{move,{y,0},{x,0}},
{init_yregs,{list,[{y,0}]}},
{line,5},
{call,3,{genshin,transform,3}},
{line,6},
{call_ext,1,{extfunc,erlang,list_to_binary,1}},
{test,is_eq_exact,
{f,6},
[{tr,{x,0},{t_bitstring,8,false}},
{literal,
<<107,114,102,103,130,68,118,106,107,119,88,109,131,70,
114,130,122,81,111,40,107,77,76,38,52,73,72,101>>}]},
{move,{literal,[21551,21160,65281,126,110]},{x,0}},
{line,7},
{call_ext_last,1,{extfunc,io,format,1},1},
{label,6},
{move,{literal,[20851,38381,126,110]},{x,0}},
{line,8},
{call_ext_last,1,{extfunc,io,format,1},1}]},
{function,transform,3,8,
[{line,9},
{label,7},
{func_info,{atom,genshin},{atom,transform},3},
{label,8},
{test,is_nonempty_list,{f,9},[{x,0}]},
{get_list,{x,0},{x,3},{x,0}},
{line,10},
{gc_bif,'bxor',
{f,0},
4,
[{x,3},{tr,{x,1},{t_integer,{1,'+inf'}}}],
{x,3}},
{gc_bif,'+',{f,0},4,[{tr,{x,3},{t_integer,any}},{integer,4}],{x,3}},
{line,11},
{gc_bif,'+',
{f,0},
4,
[{tr,{x,1},{t_integer,{1,'+inf'}}},{integer,1}],
{x,1}},
{test_heap,2,4},
{put_list,{x,3},{x,2},{x,2}},
{call_only,3,{genshin,transform,3}},
{label,9},
{test,is_nil,{f,7},[{x,0}]},
{move,{x,2},{x,0}},
{line,9},
{call_ext_only,1,{extfunc,lists,reverse,1}}]},
{function,module_info,0,11,
[{line,0},
{label,10},
{func_info,{atom,genshin},{atom,module_info},0},
{label,11},
{move,{atom,genshin},{x,0}},
{call_ext_only,1,{extfunc,erlang,get_module_info,1}}]},
{function,module_info,1,13,
[{line,0},
{label,12},
{func_info,{atom,genshin},{atom,module_info},1},
{label,13},
{move,{x,0},{x,1}},
{move,{atom,genshin},{x,0}},
{call_ext_only,2,{extfunc,erlang,get_module_info,2}}]}]}
然後丟給chatgpt問了一下基本的問題
當解釋 {get_list, {x, 0}, {x, 1}, {x, 0}}
指令的每個引數時,以下是它們的含義:
get_list
:指令的操作碼,表示從列表中獲取元素。{x, 0}
:第一個引數,表示目標暫存器,指定要將列表的第一個元素儲存在哪個暫存器中。在這裡,{x, 0}
表示暫存器x0
。{x, 1}
:第二個引數,表示源暫存器,指定要從哪個暫存器中獲取列表。在這裡,{x, 1}
表示暫存器x1
。{x, 0}
:第三個引數,表示目標暫存器,指定要將列表的第一個元素儲存在哪個暫存器中。在這裡,再次使用{x, 0}
表示暫存器x0
。
因此,該指令的作用是將暫存器 x1
中的列表的第一個元素提取出來,並將其儲存在暫存器 x0
中以供後續使用。
-
{func_info, {atom, genshin}, {atom, main}, 1}
: 函式資訊,表示函式名為genshin:main/1
-
{test, is_nil, {f, 3}, [{x, 0}]}`: 檢查引數是否為空列表
{f, 3}
是一個表示函式的元組,其中f
表示函式,3
表示該函式在位元組碼中的位置。在Erlang位元組碼中,函式由函式指令序列組成。每個函式指令都有一個唯一的位置識別符號,稱為函式索引。這個索引是一個非負整數,用於表示函式在位元組碼中的位置。在這裡,
{f, 3}
表示該函式指令位於函式索引為3的位置。
然後大概看一下各個函式的意思
最後得到的check大概是
flag[i] = (flag[i]^(i+1))+4
寫出指令碼
A=[107,114,102,103,130,68,118,106,107,119,88,109,131,70,114,130,122,81,111,40,107,77,76,38,52,73,72,101]
for j in range(len(A)):
A[j] = (A[j] -4 )^ (j+1)
flag="".join([chr(x) for x in A])
print(flag)
#flag{Funny_erLang_x0r__:)__}
尤拉!
阿里雲的一道唯一能聽懂的題
圖論題
無向圖求尤拉路徑,限制條件變為了前一步的y必須和後一步的x相同,才能繼續走
然後有一個限制條件
用dfs搜
map=[0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000001, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000000]
import numpy as np
map=np.array(map).reshape(9, 9)
map=map.tolist()
c=[]
for i in range(9):
for j in range(9):
if map[i][j]==1:
c.append((i,j))
print(c)
def dfs(maze, start):
rows = len(maze)
cols = len(maze[0])
visited = [[False for _ in range(cols)] for _ in range(rows)] # 用於記錄訪問過的位置
paths = [] # 用於記錄路徑
def check(input):
m = input[11] > input[12] and input[13] < input[14] and input[10] == input[18] and input[21] == input[25] and \
input[20] > input[15] and input[13] < input[23] and input[17] < input[14] and input[24] == "7" and input[27] == "4"
return m
def is_valid(x, y):
# 可透過的路徑(值為1)
check1 = 0 <= x < rows and 0 <= y < cols and not visited[x][y] and maze[x][y] == 1
# check2 = maze[y][x] == 0 or True
return check1
def dfs_helper(x, y, path):
visited[x][y] = True # 標記當前位置為已訪問
visited[y][x] = True
if len(path) == 17:
flag = "aliyunctf{"
flag+=f"{path[0][0]}"
for tem in path:
flag+=str(tem[1])
flag+="}"
if check(flag):
print(flag)
paths.append(path.copy())
for new_x, new_y in c:
if new_x != path[-1][1]:
continue
if is_valid(new_x, new_y):
path.append((new_x, new_y))
dfs_helper(new_x, new_y, path)
path.pop()
visited[x][y] = False # 恢復當前位置的未訪問狀態
visited[y][x] = False
# 呼叫DFS輔助函式從起點開始搜尋
dfs_helper(start[0], start[1],[start])
return paths
for start in c:
result = dfs(map, start)