此处主要在NSSCTF平台(NSSCTF | 在线CTF平台)上开展刷题
下载附件,内容如下:
flag = 'xxxxxxxxxxxxxxxxxx'
list = [47, 138, 127, 57, 117, 188, 51, 143, 17, 84, 42, 135, 76, 105, 28, 169, 25]
result = ''
for i in range(len(list)):
key = (list[i]>>4)+((list[i] & 0xf)<<4)
result += str(hex(ord(flag[i])^key))[2:].zfill(2)
print(result)
# result=bcfba4d0038d48bd4b00f82796d393dfec
麻……真的麻,年轻时没有好好学习,后果就是一把年纪重新捡起这些玩意看到程序就头皮发麻……慢慢分析开始吧唉
len()函数用于返回字符串、列表、字典、元组等长度,语法为【len(str)】,其中str是要计算的字符串、列表、字典、元组等。
range()函数是Python中的内置函数,用于生成一系列连续的整数,一般用于for循环体中。
在本题中,len(list)的结果是17,嵌套了range()函数后,结果是(0,17)
接下来for循环里设置了一个key变量,变量从list数组中取值,从第0位即47开始,分别使list数组中各个数值执行x向右移4位(相当于除以16并取整)的结果与同一个值的按位与运算(使用符号为&,即如果前后两个值相应的二进制位都为1,则该位的结果值为1;否则为0)的结果左移4位(相当于乘以16)的结果相加,获得的key数组为(242,168,247,147,87,51,248,17,69,162,120,196,150,193,154,145)。
result使用了ord、hex、zfill、str函数,用途分别为:
ord()用来返回对应字符的ascii码
hex()用于将10进制整数转换成16进制,以字符串形式表示
str.zfill(width)根据width长度对str进行切片
对for循环进行分析,转换和注释如下:
flag = 'xxxxxxxxxxxxxxxxxx'
list = [47, 138, 127, 57, 117, 188, 51, 143, 17, 84, 42, 135, 76, 105, 28, 169, 25]
result = ''
for i in range(len(list)):
m=list[i]
print(m)
print('__m__')
j=m>>4 # >>按位右移,左移n位相当于除以2的n次方,此处相当于除以16并取整
print(j)
print('__j__')
n=list[i] & 0xf # &按位与,如果两个相应的二进制位都为1,则该位的结果值为1;否则为0。本题中所取值的转化为二进制后与0xF(即1111,高位自动补0)进行按位“与”运算,取得值再转换为十进制表示
print(n)
print('__n__')
k=n<<4 # <<按位左移,左移n位相当于乘以2的n次方,此处相当于乘以16
print(k)
print('__k__')
key = j+k
print(key)
print('__key__')
i+=1
# result += str(hex(ord(flag[i])^key))[2:].zfill(2)
# result=bcfba4d0038d48bd4b00f82796d393dfec
得出key值
47 __m__ 2 __j__ 15 __n__ 240 __k__ 242 __key__
138 __m__ 8 __j__ 10 __n__ 160 __k__ 168 __key__
127 __m__ 7 __j__ 15 __n__ 240 __k__ 247 __key__
57 __m__ 3 __j__ 9 __n__ 144 __k__ 147 __key__
117 __m__ 7 __j__ 5 __n__ 80 __k__ 87 __key__
188 __m__ 11 __j__ 12 __n__ 192 __k__ 203 __key__
51 __m__ 3 __j__ 3 __n__ 48 __k__ 51 __key__
143 __m__ 8 __j__ 15 __n__ 240 __k__ 248 __key__
17 __m__ 1 __j__ 1 __n__ 16 __k__ 17 __key__
84 __m__ 5 __j__ 4 __n__ 64 __k__ 69 __key__
42 __m__ 2 __j__ 10 __n__ 160 __k__ 162 __key__
135 __m__ 8 __j__ 7 __n__ 112 __k__ 120 __key__
76 __m__ 4 __j__ 12 __n__ 192 __k__ 196 __key__
105 __m__ 6 __j__ 9 __n__ 144 __k__ 150 __key__
28 __m__ 1 __j__ 12 __n__ 192 __k__ 193 __key__
169 __m__ 10 __j__ 9 __n__ 144 __k__ 154 __key__
25 __m__ 1 __j__ 9 __n__ 144 __k__ 145 __key__
再对原题给的py程序转换如下:
flag = 'xxxxxxxxxxxxxxxxxx'
list = [47, 138, 127, 57, 117, 188, 51, 143, 17, 84, 42, 135, 76, 105, 28, 169, 25]
result = ''
for i in range(len(list)):
key = (list[i]>>4)+((list[i] & 0xf)<<4)
a=flag[i]
print(i)
print('__i__')
print(key)
print('__key__')
print(a)
print('__a__')
b=ord(a)
print(b)
print('__b__')
c=b^key # ^按位异或操作
print(c)
print('__c__')
d=hex(c)
print(d)
print('__d__')
result += str(d)[2:].zfill(2)
print(result)
# result=bcfba4d0038d48bd4b00f82796d393dfec
# result += str(hex(ord(flag[i])^key))[2:].zfill(2)
给出的结果如下:
0 __i__ 242 __key__ x __a__ 120 __b__ 138 __c__ 0x8a __d__ 8a
1 __i__ 168 __key__ x __a__ 120 __b__ 208 __c__ 0xd0 __d__ 8ad0
2 __i__ 247 __key__ x __a__ 120 __b__ 143 __c__ 0x8f __d__ 8ad08f
3 __i__ 147 __key__ x __a__ 120 __b__ 235 __c__ 0xeb __d__ 8ad08feb
4 __i__ 87 __key__ x __a__ 120 __b__ 47 __c__ 0x2f __d__ 8ad08feb2f
5 __i__ 203 __key__ x __a__ 120 __b__ 179 __c__ 0xb3 __d__ 8ad08feb2fb3
6 __i__ 51 __key__ x __a__ 120 __b__ 75 __c__ 0x4b __d__ 8ad08feb2fb34b
7 __i__ 248 __key__ x __a__ 120 __b__ 128 __c__ 0x80 __d__ 8ad08feb2fb34b80
8 __i__ 17 __key__ x __a__ 120 __b__ 105 __c__ 0x69 __d__ 8ad08feb2fb34b8069
9 __i__ 69 __key__ x __a__ 120 __b__ 61 __c__ 0x3d __d__ 8ad08feb2fb34b80693d
10 __i__ 162 __key__ x __a__ 120 __b__ 218 __c__ 0xda __d__ 8ad08feb2fb34b80693dda
11 __i__ 120 __key__ x __a__ 120 __b__ 0 __c__ 0x0 __d__ 8ad08feb2fb34b80693dda00
12 __i__ 196 __key__ x __a__ 120 __b__ 188 __c__ 0xbc __d__ 8ad08feb2fb34b80693dda00bc
13 __i__ 150 __key__ x __a__ 120 __b__ 238 __c__ 0xee __d__ 8ad08feb2fb34b80693dda00bcee
14 __i__ 193 __key__ x __a__ 120 __b__ 185 __c__ 0xb9 __d__ 8ad08feb2fb34b80693dda00bceeb9
15 __i__ 154 __key__ x __a__ 120 __b__ 226 __c__ 0xe2 __d__ 8ad08feb2fb34b80693dda00bceeb9e2
16 __i__ 145 __key__ x __a__ 120 __b__ 233 __c__ 0xe9 __d__ 8ad08feb2fb34b80693dda00bceeb9e2e9
这样一看好像清晰了点儿,那么,接下来要干的活就是一层层的解题了。
首先,回忆下异或,异或的基本性质就是若 a^b=c,那么 c^b=a,所以在这里,key的值可以直接用。要做的,就是把题目给的result值按照两位一切,加上0x构造十六进制值,使用int函数转换为十进制,与key异或运算后取得ASCII值,然后使用chr函数转换为字符串,最终构造flag,代码如下:
result = 'bcfba4d0038d48bd4b00f82796d393dfec'
list = [47, 138, 127, 57, 117, 188, 51, 143, 17, 84, 42, 135, 76, 105, 28, 169, 25]
flag = ''
for i in range(len(list)):
key = (list[i]>>4)+((list[i] & 0xf)<<4)
a=result[i*2]+result[i*2+1] #对result字符串切片并取值
print(a)
print('__a__')
b='0x'+a #构造十六进制
print(b)
print('__b__')
c=int(b,16) #将十六进制转化为十进制
print(c)
print('__c__')
d=c^key #异或运算取得ASCII值
print(d)
print('__d__')
e=chr(d) #将取得的ASCII值转换为字符串
print(e)
print('__e__')
flag+=str(e) #构造flag字符串
print(flag)
最终flag get
——20230815——
题目源码如下:
import base64,urllib.parse
key = "HereIsFlagggg"
flag = "xxxxxxxxxxxxxxxxxxx"
s_box = list(range(256))
j = 0
for i in range(256):
j = (j + s_box[i] + ord(key[i % len(key)])) % 256
s_box[i], s_box[j] = s_box[j], s_box[i]
res = []
i = j = 0
for s in flag:
i = (i + 1) % 256
j = (j + s_box[i]) % 256
s_box[i], s_box[j] = s_box[j], s_box[i]
t = (s_box[i] + s_box[j]) % 256
k = s_box[t]
res.append(chr(ord(s) ^ k))
cipher = "".join(res)
crypt = (str(base64.b64encode(cipher.encode('utf-8')), 'utf-8'))
enc = str(base64.b64decode(crypt),'utf-8')
enc = urllib.parse.quote(enc)
print(enc)
# enc = %C2%A6n%C2%87Y%1Ag%3F%C2%A01.%C2%9C%C3%B7%C3%8A%02%C3%80%C2%92W%C3%8C%C3%BA
注释一波:
import base64,urllib.parse
key = "HereIsFlagggg"
flag = "xxxxxxxxxxxxxxxxxxx"
s_box = list(range(256)) # range()生成一系列连续的整数,list()生成列表,此处即生成一个0-255的数组
j = 0
for i in range(256):
a=len(key)
b=i%a # %——取模,返回除法的余数
c=key[b]
d=ord(c)
print('a=',a,'b=',b,'c=',c,'d=',d,'j=',j)
print('__i=',i,'__')
j = (j + s_box[i] + d) % 256
print('__j=',j,'__')
s_box[i], s_box[j] = s_box[j], s_box[i]
print('s_box[',i,']=',s_box[i],'s_box[',j,']=',s_box[j])
print('=====================================')
res = []
print('res=',res)
print('————————for loop 1————————')
i = j = 0 #i,j值归零
for s in flag:
i = (i + 1) % 256
j = (j + s_box[i]) % 256
s_box[i], s_box[j] = s_box[j], s_box[i]
t = (s_box[i] + s_box[j]) % 256
k = s_box[t]
print('new_for_i=',i,'new_for_j=',j,'s_box[i]=',s_box[i],'s_box[j]=',s_box[j],'t=',t,'k=s_box[t]=',k)
m=ord(s)
print('m=',m)
n=m^k
print('n=',n)
o=chr(n)
print('chr(n)=',o)
p=res.append(o) #append是属于python中的一个函数,它主要是用来在列表末尾添加新的对象。语法格式为list.append(obj)
print('res.append(chr(n)=',p)
print('————————for loop 2————————')
cipher = "".join(res)
# join(): 连接字符串数组。将字符串、元组、列表中的元素以指定的字符(分隔符)连接生成一个新的字符串
# 语法: 'sep'.join(seq),参数说明:sep:分隔符。可以为空,seq:要连接的元素序列、字符串、元组、字典
# 上面的语法即:以sep作为分隔符,将seq所有的元素合并成一个新的字符串
# 返回值:返回一个以分隔符sep连接各个元素后生成的字符串
# 以utf-8对cipher编码
# encode()用来给字符串使用指定的编码格式来编码字符串。与之对应的是解码decode()。
# 语法:str.encode(encoding='UTF-8',errors='strict')
# 参数说明:str:需要操作的字符串,也就是需要编码的字符串。
# encoding -- 需要使用的编码,如: UTF-8、GBK等。
# errors -- 设置不同错误的处理方案。默认为 'strict',意为编码错误引起一个UnicodeError。
# 其他可能得值有'backslashreplace', 'replace'、'ignore', 'xmlcharrefreplace', 以及通过 codecs.register_error() 注册的任何值。
crypt = (str
(base64.b64encode
(cipher.encode('utf-8'))
, 'utf-8')
) #将cipyer以utf-8编码后以base64加密,并转换成字符串类型
print('crypt=',crypt)
enc = str(base64.b64decode(crypt),'utf-8')#对上述结果进行base64解密
enc = urllib.parse.quote(enc)#把生成的cipher中的非ASCII字符转换成%**形式
print(enc)
# enc = %C2%A6n%C2%87Y%1Ag%3F%C2%A01.%C2%9C%C3%B7%C3%8A%02%C3%80%C2%92W%C3%8C%C3%BA
然后……?(黑人问号脸),不得不说出题人是会玩的,差点以为搞了两次base64加密,原来是加密一次又解密,最后url转换一波。剩下的就跟上一题差不多了,生成key值的算法题目中已经给出,把给的enc转换回来, 逐个取值与key异或,将生成的ASCII值转换回来就完事了。
那么,走起来吧:
import urllib.parse
key = "HereIsFlagggg"
enc = "%C2%A6n%C2%87Y%1Ag%3F%C2%A01.%C2%9C%C3%B7%C3%8A%02%C3%80%C2%92W%C3%8C%C3%BA"
crypt =urllib.parse.unquote(enc)
s_box = list(range(256))
j = 0
for i in range(256):
j = (j + s_box[i] + ord(key[i % len(key)])) % 256
s_box[i], s_box[j] = s_box[j], s_box[i]
a = []
i = j = 0
for s in crypt:
i = (i + 1) % 256
j = (j + s_box[i]) % 256
s_box[i], s_box[j] = s_box[j], s_box[i]
t = (s_box[i] + s_box[j]) % 256
k = s_box[t]
a.append(chr(ord(s) ^ k))
flag = "".join(a)
print('flag=',flag)
最终flag get:
————20230818下午————
下载附件,是一个exe文件,先上die看下有没有壳:
看出来是没壳的,而且是个64位文件,那么ida64来一下:
按一下空格键,转换下显示模式,找到main函数后按F5转换成伪代码方便查看:
代码如下:
int __cdecl main(int argc, const char **argv, const char **envp)
{
char Str2[1008]; // [rsp+20h] [rbp-60h] BYREF
char Str1[1000]; // [rsp+410h] [rbp+390h] BYREF
int i; // [rsp+7FCh] [rbp+77Ch]
_main();
strcpy(Str2, "{34sy_r3v3rs3}");
printf("please put your flag:");
scanf("%s", Str1);
for ( i = 0; i <= 665; ++i )
{
if ( Str1[i] == 101 )
Str1[i] = 51;
}
for ( i = 0; i <= 665; ++i )
{
if ( Str1[i] == 97 )
Str1[i] = 52;
}
if ( strcmp(Str1, Str2) )
printf("you are wrong,see again!");
else
printf("you are right!");
system("pause");
return 0;
}
这……有点太明显了啊,上面那个花括号里的……就是flag了,偷懒一把,手工把3换成e,4换成a,flag就出来了……
当然,按照正规程序,这样是不太行的,但我今天不想做了哈哈哈哈哈嗝……
————20230822————
下载附件,首先die
很好,无壳,64位,那么ida64走一波,找到main函数,伪代码看一眼,顺便注释一下:
int __cdecl main(int argc, const char **argv, const char **envp)
{
char Str2[64]; // [rsp+20h] [rbp-90h] BYREF #定义Str2字符串,长度64位
char Str[68]; // [rsp+60h] [rbp-50h] BYREF #定义Str字符串,长度68位
int v7; // [rsp+A8h] [rbp-8h] #定义变量v7为整数类型
int i; // [rsp+ACh] [rbp-4h] #定义变量i为整数类型
_main();
strcpy(Str2, "ylqq]aycqyp{"); // 对Str2赋值
printf(&Format);
gets(Str); //要求输入Str
v7 = strlen(Str); //令v7的值等于Str的长度值
for ( i = 0; i < v7; ++i ) //令i为0,若i的值小于v7,则i+1
{
if ( (Str[i] <= 96 || Str[i] > 98) && (Str[i] <= 64 || Str[i] > 66) ) //若当前Str字符的ASCII值小于等于96或大于98的同时小于等于64或大于66
Str[i] -= 2; //则当前Str字符ASCII值-2
else
Str[i] += 24; //否则+24
}
if ( strcmp(Str, Str2) ) //比较Str与Str2字符串
printf(&byte_404024);
else
printf(aBingo);
system("pause");
return 0;
}
看得出来,这里的Str经过for循环运算与Str2相等,则说明我们输入的就是flag了。本想用C语言写,然而……死去十几年的记忆终究是死去了,只好用python
flag=''
flag1=''
a=''
b=''
enco='ylqq]aycqyp{'
length=len(enco)
for i in range(length):
if (ord(enco[i]) <= 94 or ord(enco[i]) > 96 ) and (ord(enco[i]) <= 64 or ord(enco[i]) > 66):
a+=chr(ord(enco[i])+2)
else:
b+=chr(ord(enco[i])-24)
flag= "".join(a)
flag1= "".join(b)
print(flag)
print(flag1)
运行结果是
提交flag、结果错误,啊这……看了一眼像是caesar,于是厚着脸皮手动改成NSSCTF{nss
_caesar}提交,成功……
P.S 严重吐槽CSDN的编辑器,太特么垃圾了
————20230824凌晨————
题目源码如下:
import random
flag = 'xxxxxxxxxxxxxxxxxxxx'
random.seed(1)
l = []
for i in range(4):
l.append(random.getrandbits(8))
result=[]
for i in range(len(l)):
random.seed(l[i])
for n in range(5):
result.append(ord(flag[i*5+n])^random.getrandbits(8))
print(result)
# result = [201, 8, 198, 68, 131, 152, 186, 136, 13, 130, 190, 112, 251, 93, 212, 1, 31, 214, 116, 244]
这题目乍一看,不就是玩伪随机数嘛,一开始在分析的时候没有整明白random.seed()与random.getrandbits()函数的关系,以为直接从result中按顺序取值进行异或运算后解题
后面才发现random.seed()函数是用来改变随机数生成器的种子,没有参数时,每次生成的随机数是不一样的,而当seed()有参数时,每次生成的随机数是一样的。因此解题时同样需要通过random.seed()给定random.getrandbits()函数的种子
那么,本题源代码经注释如下:
import random
flag = 'xxxxxxxxxxxxxxxxxxxx' #定义flag字符串
random.seed(1) #设定以1为种子生成伪随机数,并将其作为getrandbits函数的种子
l = [] #定义空数组l
for i in range(4):
l.append(random.getrandbits(8)) # 本for循环在0~255之间随机取4个值,并赋值给l数组
result=[] #定义空数组result
for i in range(len(l)):
random.seed(l[i])
for n in range(5):
result.append(ord(flag[i*5+n])^random.getrandbits(8)) #参照上一for循环,本for循环中,分别以l数组各值作为本for循环中的getrandbits函数的种子,并将flag各位(即x)的ASCII值与生成的随机数进行异或运算后赋值给result数组
print(result)
# result = [201, 8, 198, 68, 131, 152, 186, 136, 13, 130, 190, 112, 251, 93, 212, 1, 31, 214, 116, 244]
这样一看就明白多了,还是异或的老套路,只不过key由伪随机数构成,直接逆向就完事了
import random
flag = ''
random.seed(1)
l = []
result = [201, 8, 198, 68, 131, 152, 186, 136, 13, 130, 190, 112, 251, 93, 212, 1, 31, 214, 116, 244]
for i in range(4):
l.append(random.getrandbits(8))
for i in range(len(l)):
random.seed(l[i])
for n in range(5):
flag+=chr(result[i*5+n]^random.getrandbits(8))
print(flag)
flag get
————20230825凌晨————
源码如下:
flag = 'xxxxxxxxxxxxxxxxxxxxx'
s = 'wesyvbniazxchjko1973652048@$+-&*<>'
result = ''
for i in range(len(flag)):
s1 = ord(flag[i])//17
s2 = ord(flag[i])%17
result += s[(s1+i)%34]+s[-(s2+i+1)%34]
print(result)
# result = 'v0b9n1nkajz@j0c4jjo3oi1h1i937b395i5y5e0e$i'
注释一波:
flag = 'xxxxxxxxxxxxxxxxxxxxx'
s = 'wesyvbniazxchjko1973652048@$+-&*<>'
result = ''
for i in range(len(flag)):
s1 = ord(flag[i])//17 #对x的ASCII值除以17后取整,定值为7
s2 = ord(flag[i])%17 #对x的ASCII值除以17后取余数,定值为1
print('ord(flag[i])=',ord(flag[i]),',i=',i,',s1=',s1,',s2=',s2)
a=s1+i
a1=a%34 # 取值范围为7~27
b=s2+i+1
b1=(-b)
b2=b1%34 #负数取余,计算方式为-(b1%34),例i=0时,b=2,b1=-2,b2=-(2%34)=-(0余2),故b2=-2
print('a=',a,',a1=',a1,',b=',b,',b1=',b1,',b2=',b2)
c=s[a1]
d=s[b1]
print('c=',c,'d=',d)
result += s[(s1+i)%34]+s[-(s2+i+1)%34] #令result值等于字符串s中第7~27位的值与第32~12位的值穿插叠加
print(result)
print('————————')
print(result)
# result = 'v0b9n1nkajz@j0c4jjo3oi1h1i937b395i5y5e0e$i'
然后愣是弄不懂要怎么解……先跳过
想了两个晚上也没想怎么把这题逆出来,看了其他师傅的也还是搞不明白,枯了……
只好换个思路,直接暴力破解……
flag=''
s = 'wesyvbniazxchjko1973652048@$+-&*<>'
result = 'v0b9n1nkajz@j0c4jjo3oi1h1i937b395i5y5e0e$i'
for i in range(len(result)//2):
for j in range(0,255):
s1=j//17
s2=j%17
tmp = s[(s1+i)%34]+s[-(s2+i+1)%34]
if (tmp == result[i*2:i*2+2]):
flag+=chr(j)
break
print(flag)
flag get……
有没有师傅行行好,教我一下怎么逆这个题啊,就是想不通T T
源码如下:
flag = 'xxxxxxxxxxxxxxxxxxx'
s_box = 'qwertyuiopasdfghjkzxcvb123456#$'
tmp = ''
for i in flag:
tmp += str(bin(ord(i)))[2:].zfill(8)
b1 = int(tmp,2)
s = ''
while b1//31 != 0:
s += s_box[b1%31]
b1 = b1//31
print(s)
# s = u#k4ggia61egegzjuqz12jhfspfkay
好了不想做,先放着……
因为没有保存,所以这题的记录丢失……
过程就是先die一下看看有没有壳,发现是经过编译的,把扩展名改成zip
打开发现是个apk文件,用jdax破瓜后,在里面找到mainactivity和encoder
发现key是987654321,加密方式是异或
密文是一行unicode,转化后是一堆生僻字
解题代码如下:
result='棿棢棢棲棥棷棊棐棁棚棨棨棵棢棌'
key=987654321
flag=''
for i in result:
a=ord(i)^key
print(a)
flag+= chr(a%128)
print(flag)
flag
附件下载后又是没有扩展名,die后发现经过编译
于是把扩展名改成.exe,然后根据大佬的思路python逆向的常见思路_wiiish的博客-CSDN博客,用pyinstxtractor破瓜,接着在爆出来的文件里,找到struct.py,用文件头16位覆盖5.py的文件头。
接着反编译。
本想用pycdc的,结果翻了一堆文章就是整不明白怎么用cmake搞定它,无奈之下用了uncompyle6。
反编译后的代码如下:
# uncompyle6 version 3.9.0
# Python bytecode version base 3.7.0 (3394)
# Decompiled from: Python 2.7.18 (v2.7.18:8d21aa21f2, Apr 20 2020, 13:25:05) [MSC v.1500 64 bit (AMD64)]
# Embedded file name: 5.py
# Compiled at: 1995-09-28 00:18:56
# Size of source mod 2**32: 272 bytes
import random, msvcrt
row, col = (12, 12)
i, j = (0, 0)
maze = [
[
1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1],
[
1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 1, 0, 1],
[
1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1,
1, 1, 0, 1, 0, 1],
[
1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1,
0, 0, 0, 1, 0, 1],
[
1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1,
0, 1, 1, 1, 0, 1],
[
1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0,
0, 1, 0, 0, 0, 1],
[
1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
1, 1, 1, 1, 0, 1],
[
1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0,
0, 0, 0, 1, 0, 1],
[
1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1,
1, 1, 0, 1, 0, 1],
[
1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1,
0, 1, 0, 0, 0, 1],
[
1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1,
0, 1, 1, 1, 0, 1],
[
1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0,
0, 1, 0, 0, 0, 1],
[
1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1,
0, 1, 0, 1, 1, 1],
[
1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1,
0, 1, 0, 1, 0, 1],
[
1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1,
0, 1, 0, 1, 0, 1],
[
1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1,
0, 1, 0, 1, 0, 1],
[
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1,
1, 1, 0, 1, 0, 1],
[
1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0,
0, 1, 0, 0, 0, 1],
[
1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1,
0, 1, 1, 1, 0, 1],
[
1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1,
0, 0, 0, 1, 0, 1],
[
1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1,
1, 1, 0, 1, 0, 1],
[
1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1],
[
1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1,
0, 1, 0, 1, 0, 1],
[
1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
0, 1, 0, 0, 0, 1],
[
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 0, 1]]
print('Mice walk in a maze: wasd to move,q to quit')
print("flag is the shortest path's md5,example:if the shortest path is wasdsdw,the flag is md5('wasdsdw')")
i, j = (0, 1)
n = 0
while 1:
if i == row * 2:
if j == col * 2 - 1:
print('ohhhh!!!!you did it')
break
print('your position:({},{})'.format(i, j))
inp = msvcrt.getch()
n += 1
ti, tj = i, j
if b'a' == inp and i > 0:
tj -= 1
else:
if b'w' == inp and j > 0:
ti -= 1
else:
if b's' == inp and j < row * 2:
ti += 1
else:
if b'd' == inp and i < col * 2:
tj += 1
else:
if b'q' == inp:
exit('bye!!')
else:
print('What???')
continue
if maze[ti][tj] == 1:
print(random.choice(['no wayy!!', "it's wall", 'nop']))
continue
elif maze[ti][tj] == 0:
print(random.choice(['nice!!', 'yeah!!', 'Go on']))
i, j = ti, tj
把里面的maze单独拿出来
好吧……作为菜鸡,只好手动输入这个最短路径
path='sssssddssddssaaaassssddwwddddssssssaawwaassssddssaassddddwwddssddwwwwwwwwaawwddwwwwaaaawwddwwwwddssssddwwwwddddwwddddssaassaassddddssddssaassssssddsssssss'
MD5加密即可得到flag
die后发现又是个exe文件
找到struct.py,用文件头16位覆盖code.py的文件头后用uncompyle6反编译,结果提示版本不符合……
好吧,只好用在线反编译工具,得到代码如下:
#!/usr/bin/env python
# visit https://tool.lu/pyc/ for more information
# Version: Python 3.9
import hashlib
import base64
def init(OOOOO00O0OO00OO00, OOO00O0000OOO0O00):
OO00O000OOO0OOOOO = 0
OOO00O0000OOO0O00 = hashlib.md5(OOO00O0000OOO0O00.encode()).hexdigest()
OOO00OO0OOO00OOO0 = []
for O0O00OO00OOO0O000 in range(256):
OOOOO00O0OO00OO00.append(O0O00OO00OOO0O000)
OOO00OO0OOO00OOO0.append(OOO00O0000OOO0O00[O0O00OO00OOO0O000 % len(OOO00O0000OOO0O00)])
for O0O00OO00OOO0O000 in range(256):
OO00O000OOO0OOOOO = (OO00O000OOO0OOOOO + OOOOO00O0OO00OO00[O0O00OO00OOO0O000] + ord(OOO00OO0OOO00OOO0[O0O00OO00OOO0O000])) % 256
OOOOO00O0OO00OO00[O0O00OO00OOO0O000] = OOOOO00O0OO00OO00[OO00O000OOO0OOOOO]
OOOOO00O0OO00OO00[OO00O000OOO0OOOOO] = OOOOO00O0OO00OO00[O0O00OO00OOO0O000]
def Encrypt(O0000O0OO00OO00O0, OO0OO00O00O0O00O0):
OOOO0O00O00OOOOO0 = OO0O000O000O0O0O0 = 0
O00O00OOOO00O0000 = ''
for O0OO0O0O0OO0O0OOO in OO0OO00O00O0O00O0:
OOOO0O00O00OOOOO0 = (OOOO0O00O00OOOOO0 + 1) % 256
OO0O000O000O0O0O0 = (OO0O000O000O0O0O0 + O0000O0OO00OO00O0[OOOO0O00O00OOOOO0]) % 256
O0000O0OO00OO00O0[OOOO0O00O00OOOOO0] = O0000O0OO00OO00O0[OO0O000O000O0O0O0]
O0000O0OO00OO00O0[OO0O000O000O0O0O0] = O0000O0OO00OO00O0[OOOO0O00O00OOOOO0]
O0OO0O0OOO00O0O00 = (O0000O0OO00OO00O0[OOOO0O00O00OOOOO0] + O0000O0OO00OO00O0[OO0O000O000O0O0O0]) % 256
OOO000O0OOOOO00O0 = chr(ord(O0OO0O0O0OO0O0OOO) ^ O0000O0OO00OO00O0[(O0000O0OO00OO00O0[OOOO0O00O00OOOOO0] + O0000O0OO00OO00O0[OO0O000O000O0O0O0]) % 256])
O00O00OOOO00O0000 += OOO000O0OOOOO00O0
O00O00OOOO00O0000 = base64.b64encode(O00O00OOOO00O0000.encode())
return O00O00OOOO00O0000
input_str = input('input flag pls:')
s = []
init(s, 'bJLVFYw3WI5ncGez')
if Encrypt(s, input_str).decode() == 'w4s1PUYsJ8OYwpRXVjvDkVPCgzIEJ27Dt2I=':
print('good!')
continue
print('nonono!')
continue
看不懂,放弃(摊手)
源码如下:
flag = 'xxxxxxxxxxxxxxxxxx'
flag = flag[::-1]
result = 0
for i in range(0,len(flag)-1):
s1 = ord(flag[i])
s2 = ord(flag[i+1])
if i == 0:
result = (s1<<8)^(s2<<4)^s2
else:
result = (result<<4)^((s1<<8)^(s2<<4)^s2)
print(result)
# result = 591620785604527668617886
注释一波:
flag = 'xxxxxxxxxxxxxxxxxx'
flag = flag[::-1]
print(flag)
result = 0
for i in range(0,len(flag)-1):
print('i=',i)
s1 = ord(flag[i])
s2 = ord(flag[i+1])
print('s1=',s1,',s2=',s2)
if i == 0:
result = (s1<<8)^(s2<<4)^s2 #给result赋初始值,初始值为120*256的值与120*16的值异或后,再与120异或,最终结果为32760
print(s1<<8,s2<<4,result)
else:
result = (result<<4)^((s1<<8)^(s2<<4)^s2) #接着将初始result值重复进行上一步骤直至循环结束
print(result)
print('loop=',i)
print('————————————')
print(result)
# result = 591620785604527668617886
好了,不会(摊手)
[SWPUCTF 2021 新生赛]astJS(跪了)
附件一打开就知道是我不会的题(摊手)
————20230828凌晨————