【NSSCTF】刷题记录——[SWPUCTF 2024 新生赛]系列(REVERSE篇(1)


最终flag get


![](https://img-blog.csdnimg.cn/703fffc79fee4c2e9d402120610b944e.png)


——20230815——


##### [SWPUCTF 2021 新生赛]简简单单的解密


题目源码如下:



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©
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:


![](https://img-blog.csdnimg.cn/cf5c46bce7324a638afb6e9dcd8d401f.png)


————20230818下午———— 


##### [SWPUCTF 2021 新生赛]re1


下载附件,是一个exe文件,先上die看下有没有壳:


![](https://img-blog.csdnimg.cn/94f77538de5245bda8e4b5d0308b2307.png)


看出来是没壳的,而且是个64位文件,那么ida64来一下:


![](https://img-blog.csdnimg.cn/5fcd28897c42459fb17009842cd55baa.png)



按一下空格键,转换下显示模式,找到main函数后按F5转换成伪代码方便查看:


![](https://img-blog.csdnimg.cn/7437d25f775047c89cf724d58a84041d.png)


 代码如下:



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———— 


##### [SWPUCTF 2021 新生赛]re2


下载附件,首先die


![](https://img-blog.csdnimg.cn/8772d18552544914a676092a39089c36.png)很好,无壳,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)


运行结果是


![](https://img-blog.csdnimg.cn/11755476361f4c23b4f85dba3704b3d7.png)


提交flag、结果错误,啊这……看了一眼像是caesar,于是厚着脸皮手动改成NSSCTF{nss


\_caesar}提交,成功……


P.S 严重吐槽CSDN的编辑器,太特么垃圾了


————20230824凌晨———— 


##### [SWPUCTF 2021 新生赛]fakerandom


题目源码如下:



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


![](https://img-blog.csdnimg.cn/a15679aa599e4d6982ce026498439e5d.png)


————20230825凌晨———— 


##### [SWPUCTF 2021 新生赛]非常简单的逻辑题


源码如下:



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中第727位的值与第3212位的值穿插叠加
print(result)
print(‘————————’)
print(result)

result = ‘v0b9n1nkajz@j0c4jjo3oi1h1i937b395i5y5e0e$i’


然后愣是弄不懂要怎么解……先跳过


想了两个晚上也没想怎么把这题逆出来,看了其他师傅的也还是搞不明白,枯了……


只好换个思路,直接暴力破解……



flag=‘’
s = ‘wesyvbniazxchjko1973652048@KaTeX parse error: Expected 'EOF', got '&' at position 3: +-&̲*<>' result = '…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[i2:i2+2]):
flag+=chr(j)
break
print(flag)


flag get……


![](https://img-blog.csdnimg.cn/f4c083994f2648c183c1e979f552ccf0.png)


 有没有师傅行行好,教我一下怎么逆这个题啊,就是想不通T T


##### [SWPUCTF 2021 新生赛]fakebase


源码如下:



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


好了不想做,先放着……



##### [SWPUCTF 2021 新生赛]easyapp


因为没有保存,所以这题的记录丢失……


过程就是先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


![](https://img-blog.csdnimg.cn/17ae43bf23f8414299188967d2286515.png)


##### [SWPUCTF 2021 新生赛]老鼠走迷宫


附件下载后又是没有扩展名,die后发现经过编译


![](https://img-blog.csdnimg.cn/deea6f6f84664837a005d63c4f0fb569.png)


于是把扩展名改成.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,

结束

一次完整的面试流程就是这样啦,小编综合了腾讯的面试题做了一份前端面试题PDF文档,里面有面试题的详细解析,分享给小伙伴们,有没有需要的小伙伴们都去领取!

  • 16
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值