ctfshow wp

立志做完ctfshow上的每一道逆向题(持续更新哦)

Re1

得到一个无格式文件用010看看是一个.elf文件

再用ida打开看看

可以以下就看懂程序的逻辑,判断输入的是否为flag{7ujm8ikhy6}如果是则输出flag{7ujm8ikhy6}说明flag就是flag{7ujm8ikhy6}

Re2

题目给到一份txt文件和一个名为勒索病毒的软件,打开一看是乱码且位ANSI格式

拿去解码没有头绪,再看看exe可执行文件

一个无壳的32位可执行文件,用ida打开后可以看到对flag文件进行了一个加密操作

我们对 ==sub_401037==进行分析,看看它的交叉引用函数

打开 ==sub_401A70==

可以看到要得到str1需要==”DHmqqvqxB^||zll@Jqjkwpmvez{“==与1f进行一个异或操作,这里写一个py脚本

1
2
3
4
5
6
7
string = 'DH~mqqvqxB^||zll@Jq~jkwpmvez{'
str1=''
for i in string:
str1 +=chr(ord(i)^31)
print(str1)

##[Warnning]Access_Unauthorized

继续分析下面的函数

可以看到是一个经典的rc4解密,因此可以认为str1为密钥,而enflag中的内容为被rc4加密后的密文,只需解密即可拿到flag,这里的enflag为ANSI,将其放到010Editor中查看十六进制数

在线rc4解密拿到flag

Re3

先进行查壳为一个64位的Gcc编写的程序

用ida64打开反编译再看伪代码

分析最后循环可以得到v17进行一个累加得到v16,最后v16如果与0FFF相等,则输出正确,所以要找到v16的最后一个数

这里直接写一个爆破脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
for j in range(0xffff):
v17 = [80,64227,226312059,0xA43499F6,(5 << 12) + 16,3833, j]
v16 = 0

for i in range(7):
v16 += v17[i]
while v16 > 0xffff:

v15 = v16 >> 16
v16 = (v15 + (v16 & 0xffff)) & 0xffffffff

if v16 == 0xffff:
print(hex(j))

得到最后一位0x1a9f,所以flag为flag{1a9f}

逆向4

首先查壳

一个无壳的64位可执行文件用ida打开分析再经过动调

加密函数是==sub_7FF7E7F610E0==进入加密函数

分析对我们输入的数进行了如下操作:

1,先将这个数字与26经过模运算后作为字符数组==)(*&^%489$!057@#><:2163qwe==的索引值

2,再将这串数字整除26直到整除结果为0结束循环

3,再将每个索引值与7进行异或操作然后进入==sub_7FF7E7F61220==函数

分析可知是将异或过的值与字符数组 ==..v4p$$!>Y59==进行比较,若相等则进入==sub_7FF7E7F612E0==否则==sub_7FF7E7F612B0==查看这两个函数分别是显示成功与失败的函数

因此最后一个逻辑为验证异或过的值是否与====..v4p$$!>Y59====相等

python脚本如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
check_string='/..v4p$$!>Y59-'
table = ')(*&^%489$!057@#><:2163qwe'
index =''
d = [chr(ord(char) ^ 7) for char in check_string]

def find_index(char, char_array):
return char_array.index(char)
def create_index_table(d, table):
c = []
for char in d:
index = find_index(char, table)
c.append(index)
return c

c = create_index_table(d, table)
print( c)
flag = 0
for i in range(len(c)):
flag*=26
flag+=c[i]
print(flag)

逆向5

今天来一个骚的解题方法首先得到一个无后缀的文件,首先用010editor打开发现是一个zip文件,将其后缀改为zip解压得到一个可执行文件与dll文件,随后对两个文件进行查壳,发现dll文件有一个ASPack的壳

而call_1.exe无壳,随后用ida打开进行分析

进入主函数先分析 ==sub_4020B0==发现这个函数没有什么作用,进而分析==sub_4015BD==

这段伪代码的逻辑为判断Str字符串的第二位是否为1否则不执行下面的步骤,查看Str发现为==dba54edb0?d6>7??3ef0f1caf2ad3102==

显然第二位不是1也就是说不会执行里面的两个函数,再分析==sub_401520==

可以得知这里调用了1.dll然后再输出字符串,所以我们好像需要得知1.dll干了什么事情但竟然它会输出那我们只需要让前面的if语句执行即可这里我们现在if语句处与==return sub_40163E(i);==下断点

进入动调,先F9运行至第一个断点处再F7步进至此处,将正则值ZF改为1

之后再F9后就会跳出flag了

最后得到flag{cef23bce78c190884ba7a6dfa5fc4675}

红包题 武穆遗书

先查壳,发现有一个upx壳,且为32位可执行文件

丢入upx文件夹进行自动脱壳

用ida32打开进行分析,在动调的时候发现很多地方会跳出正常一步一步的调试让程序继续运行下去

分析可知在动调中会分别调用两个函数(==sub_4011D0==,==sub_401200==)让程序直接结束这里有两种方法

一种是当程序运行至jz处时,将他的zf值改成相反的数,使其继续运行下去

另一种则是直接改变==EIP==指针使其直接跳过函数但是第二种方法实验一下在这道题是不行的

而静态分析发现改题的程序逻辑是比较v4与v6(输入值)的值是否一致,否v4是在程序要求输入之前就已经变换好了,再与输入值作比较,因此只需要动调至合适的位置即可得到flag

但是动调至==sub_401280==时会发生报错,并且怎么都不会继续执行

但是直接运行会有输入字符的页面

因此可以推测该程序应用了反调试的技术,在网上搜索有一种解决方法是直接将可以正常运行的程序直接attach至ida

在比较两个字符处打断点

在attach程序后直接随机输入 ,再f9运行至断点处,找到eax寄存器就是flag

flag:flag{fmf_is_great!}

红包六

得到一个jar文件,运行程序

这里把后缀改为zip打开压缩包,打开java文件

可以看到是将输入的字符串使用密钥==easy_key==进行DES加密,再与base64进行比较,但是代码中也有明显的提示这里没有flag,解密出来也显示不是flag

检查压缩包可以解压前是5kb而解压后确实1kb说明没有解压完全,用010editor打开可以搜索zip的文件头==50 4B 03 04==可以看见有多个文件头

前两个是压缩包解压出来的,而第三个可以是未解压出来的,再找到zip的文件尾

这里可以用脚本将压缩包脱出直接保存为java文件尝试用jd反编译

1
2
3
4
5
6
7
8
9
10
import zlib
inflator = zlib.decompressobj(-zlib.MAX_WBITS)
f=open('EzJar.jar','rb')
f.seek(659)
a=f.read(3248)
f.close()
x = inflator.decompress(a)
f=open('EzJar.class','wb')
f.write(x)
f.close()

最后分析可知算法为DES,密钥为Ctf3r_me 密文为Dg/TZuRXF4+UwSZ8Dpwgw8+VOoHVl1YlPL1QRVhroCy4ptnKEcdC05iXcpLyDnuR

解密后可以得到flag

flag:ctfshow{eb5e2541-58e6-4f8f-ae6f-5c7a6f920d73}

数学不及格

拿到文件先查壳

是一个Linux可执行文件,且是64位的,用ida64进行分析

可以发现是一个类似于解方程的题,但是这里有五个未知数,却只有四个等式,而v4与v9的关系由一个==f==函数决定,查看f函数

而这个函数就是==斐波那契数列==而v9则是斐波那契数列第v4项的值,而v4又是在1至200之间

首先先将前三个式子

​ v9 - v10 = 0x233F0E151C

​ v9 - v11 = 0x1B45F81A32

​ v9 - v12 = 0x244C071725

将三个式子联立相加得到

​ 3*v9-(v10+v11+v12)=62d10d4673

再与第四个式子v4 + v12 + v11 + v10 = 0x13A31412F8C相加得到

​ 3*v9+v4=19D024E75FF(1773860189695)

又因为v4只在1至200的范围内,数字很小因此可以忽略不记求出v9的近似值

​ v9=1773860189695/3(591286729898)

然后找个在线网站查看一下==斐波那契数列==找到v9的近似值

可以看到数列的第58位与v9十分相似,因此可以得出v9为591286729879,v4为58,剩下的就是解方程了,这里可以使用==z3==模块求解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from z3 import *
v4,v9,v10,v11,v12=Ints('v4 v9 v10 v11 v12')

v9 = 591286729879
v4=58
a = "0x233F0E151C"
a1 = int(a, 16)
b = "0x1B45F81A32"
b1 = int(b, 16)
c = "0x244C071725"
c1 = int(c, 16)
d = "0x13A31412F8C"
d1 = int(d, 16)
s = Solver()
s.add(v9-v10==a1)
s.add(v9-v11==b1)
s.add(v9-v12==c1)
s.add(v4+v12+v11+v10==d1)
if s.check() == sat:
print(s.model())

然后将这些值都转为16进制拼接起来其中argv[4]=hex(v4+25923)

1
2
3
4
5
6
7
argv = {}
argv[0]=hex(439904987003)[2:]
argv[1]=hex(474148725349)[2:]
argv[2]=hex(435392374130)[2:]
argv[3]=hex(58+25923)[2:]
c=argv[0]+argv[1]+argv[2]+argv[3]
print(bytes.fromhex(c).decode())

得到flag:flag{newbee_here}

flag白给

拿到程序先查壳

发现是一个32位的可执行文件,并且是一个upx壳,将其脱壳

脱壳后用ida打开静态分析,按f5进行反编译却没有反应,因此可以选择动态调试,用odbg打开,之后选择按ASCII搜索

找到关键字==成功了==

之后进入查看汇编代码

经过动调可知程序会将输入的序列号与==HackAv==对比,若相同则会输出成功,验证一下

因此flag为:flag{HackAv}(真白给啊)

签退

拿到软件发现是一个pyc文件可以利用uncompyle6来进行反编译在cmd中输入命令==uncompyle6 re3.pyc > re.py==

之后便得到反编译后的py文件

可以看到进行了两次加密分别是

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def encode(origin_bytes):
c_bytes = [ ('{:0>8}').format(str(bin(b)).replace('0b', '')) for b in origin_bytes ]
resp = ''
nums = len(c_bytes) // 3
remain = len(c_bytes) % 3
integral_part = c_bytes[0:3 * nums]
while integral_part:
tmp_unit = ('').join(integral_part[0:3])
tmp_unit = [ int(tmp_unit[x:x + 6], 2) for x in [0, 6, 12, 18] ]
resp += ('').join([ c_charset[i] for i in tmp_unit ])
integral_part = integral_part[3:]

if remain:
remain_part = ('').join(c_bytes[3 * nums:]) + (3 - remain) * '0' * 8
tmp_unit = [ int(remain_part[x:x + 6], 2) for x in [0, 6, 12, 18] ][:remain + 1]
resp += ('').join([ c_charset[i] for i in tmp_unit ]) + (3 - remain) * '.'
return rend(resp)
1
2
3
4
5
6
7
8
9
10
11
def rend(s):

def encodeCh(ch):
f = lambda x: chr((ord(ch) - x + 2) % 26 + x)
if ch.islower():
return f(97)
if ch.isupper():
return f(65)
return ch

return ('').join(encodeCh(c) for c in s)

而最后得到密文==BozjB3vlZ3ThBn9bZ2jhOH93ZaH9==

而要逆向则需要从前往后分析可以看到是对密文进行了一个位移操作,而且是一个简单的凯撒密码,偏移量为2

解密一下得到==ZmxhZ3tjX3RfZl9zX2hfMF93XyF9==而对于上一个其实就是一个base64编码,放到工具解密既可以得到密文

flag:flag{c_t_f_s_h_0_w_!}

真的是签到

得到一个zip文件,进行解压发现需要密码

但是题目没有给任何密码提示,猜测可能是压缩包的一个伪加密,用==010editor==打开

可以看到全局加密处为==00 00==之后可以确定是压缩包的伪加密我们只需要找到==全局方式位标记==将==09 00==改为==00 00==即可

之后再解压可以得到需要逆向的可执行文件

老规矩先查壳

发现有一个ASP的壳,我们用odbg打开,利用ESP定律进行脱壳

打开memory map可以看到==00409001==正式aspack壳的入口地址

而壳最终都会跳转至OEP进入程序,此时我们按下F8,程序单步执行,会发先esp寄存器处变红,也就是说esp发生了变化,我们右键esp选择数据窗口跟随

之后我们在下方找到==0060FF50==在其数据处右键,断点选择硬件访问然后选择BYTE就可以在硬件断点处看到

之后按F9运行,程序则会停止至==popad==处

之后单步执行至retn处,而前面的push其实也大有说法,这个以后有机会详细讲讲,单步运行至retn后会发现进入至一个页面,而这个页面就是oep的位置,此时会发现是一些字符,这是因为前面的壳压缩或加密导致odbg没有及时的去分析,此时我们需要右键分析选择分析代码

然后右键选择用==Ollydump==脱壳调试进程,点击脱壳,另存为==签到1.exe==这时我们再进行查壳发现还多了upx壳

使用命令./upx -d xxx.exe进行脱壳,发现依然报错(我嘞个骚刚)

去网上查看这一段报错,发现很有可能是upx的防脱壳(具体可以看看:https://www.52pojie.cn/thread-326995-1-1.html),用010editor打开看看

奇怪了明明是upx壳为什么会有vmp我们把vmp改成UPX(55 50 58)

但是改了之后还是不太行,只能试试upx的手动脱壳了,还是根据上面的esp定律dump出脱壳后的文件,之后用ida打开,再根据关键字终于定位到了检验函数

可以发现是对输入的字符串进行下标异或之后再与dword_402000进行对比得到结果

这里写一个c脚本来解密

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>

int main()
{
int res[18] = { 0x6c,0x2f,0x30,0x31,0x32,0x33,0xffffffb6,0xffffffbf,0xffffffa0,0xffffffcf,0x7c,0x71,0x6a,0x6c,0x70,0x64,0x75,0x63 };
for(int i = 17;i>=0;i--)
{
res[i] = res[i]^(17-i);
printf("%c",res[i]);
}
printf("\n");
return 0;
}

这里如果要用python要注意使用gb2312解码

得到flag:ctfshow{签到?????}

批量生产的伪劣产品

这一题就相对比较简单了直接把 apk文件丢尽jadx分析,查看==AndroidManifest.xml==的内容找入口==appinventor.ai_QA629A242D5E83EFA948B9020CD35CB60.checkme.a”==

之后再里面往下翻就可以看见明显的flag了

flag:ctfshow{群主最爱36D}

来一个派森

题目停供了一个python编译打包的exe文件所以需要进行反编译,将需要编译的文件拖入pyinstxtractor-master文件夹,在文件夹终端输入

1
python pyinstxtractor.py checkme.exe

打开生成的==checkme.exe_extracted==文件夹,并在里面找到checkme.pyc

之后便利用==uncompyle6==进行反编译输入命令:

1
uncompyle6 checkme.pyc > checkme.py

查看checkme.py

可以看到这一段的逻辑就是将用户输入的flag先进行base58加密,再每一个与自己的下标异或,得到check,所以写一个解密脚本将加密后的base58的内容解密出来

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
check = [
"'A'", "'5'", "'q'", "'O'", "'g'", "'q'", "'d'", "'\\x7f'",
"'['", "'\\x7f'", "'s'", "'{'", "'G'", "'A'", "'x'", "'`'", "'D'",
"'@'", "'K'", "'c'", "'-'", "'c'", "' '", "'G'", "'+'", "'+'",
"'|'", "'x'", "'}'", "'J'", "'h'", "'\\\\'", "'l'"
]

tmp = []
for i in range(len(check)):
char = check[i][1:-1] # 去掉单引号
if char.startswith('\\x'): # 处理转义字符
char = chr(int(char[2:], 16))
elif char == '\\\\':
char = '\\'
ascii_val = ord(char) # 转换为ASCII值
original_val = ascii_val ^ i # 执行XOR操作
tmp.append(chr(original_val)) # 转换回字符并添加到tmp中

tmp_string = ''.join(tmp)
print(tmp_string)

得到==A4sLctbxSvypKLvoTQYp9v6P32fcaWvCL==最后放到网上base58解密

得到flag:ctfshow{zhe_bu_shi_flag}

好好学习天天向上

拿到exe文件我们先查壳,为无壳64位的可执行文件,之后用ida64打开,把辨识度高的函数名字改掉

之后进入==sub_140001000==查看函数逻辑

在这里可以推断出输入的flag必须有32个,接着再分析==sub_140001140==函数

这里其实就是判断输入的flag是不是由==aAbdefglostuyp[]==里的字符组成的,如果是则会返回==aAbdefglostuyp[]==相应的索引值, 其实也就是说flag必须由==aAbdefglostuyp[]==内的字符组成

可以看到是由==abdefglostuyp{}_==组成,之后就可以写爆破脚本了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import random

def check(char):
check_string = 'abdefglostuyp{}_'
for i in range(len(check_string)):
if char == check_string[i]:
return i # 找到字符后返回其索引
return -1 # 如果没有找到字符,返回 -1

def validate_array(byte_array):
if len(byte_array) != 32:
return False

v4 = 0
v2 = 0

for i in range(31):
byte_value = byte_array[i]
result = check(byte_value)

if result < 0:
return False

v2 = 17 * (result + 16 * i)
v4 += check(byte_array[i + 1]) # 使用 check 函数获取下一个字符的索引值

return v4 == 0x1C836D8E5C11047F and byte_array[31] == '}'

def generate_random_array():
allowed_chars = 'abdefglostuyp{}_'
return [random.choice(allowed_chars) for _ in range(32)]

# 生成满足条件的字符数组
while True:
byte_array = generate_random_array()
if validate_array(byte_array):
break

print("找到的字符数组:", ''.join(byte_array))

但是其实这32个基本是很难爆出来的,去网上别人的wp发现大家对于flag都是猜,因为==aAbdefglostuyp[]==的字符正好可以拼成题目的名字,也就是good good study day day up然后用flag{}包住再用_连接发现正好满足32位,提交显示正确,what can i say

flag:flag{good_good_study_day_day_up}

屏幕裂开了

因为是apk文件我们用jadx打开查看

这里行成一个码表用两个序列s和k生成之后调用checkflag(char[] cArr, String str);进行检测

因此我们可以写出解密脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#tab_s
s = [i for i in range(256)]
k = (b"InfinityLoop"*22) [0:256]

for hit_count in range(99999):
j = 0
for i in range(256):
j = (s[i]+j+k[i])%256
s[i],s[j] = s[j],s[i]

answer = [0xA6,0x3D,0x54,0x0B0,0x74,0xCC,0xBD,0x2A,0x4A,0x0DE,0x0BD,0x35,0x0D1,0x1D,0x80,0x32,0x5F,0x64,0x2F,0x0C5,0x0DD,0x11,0x3E,0x95,0x0CC,0x17,0x13,0x0E5,0x5E,0x65,0x0CE,0x42,0x9E,0x47,0x0C8,0x0F3,0x4D,0x8A,0x0A6,0x1F,0x0F0,0x50,0x27,0x0A2,0x28,0x81,0x24,0x0A7,0x0B4,0x90,0x0FC,0x93,0x8A,0x0C1,0x77,0x0D5,0x16,0x1E,0x0FD,0x87,0x0C7,0x0BB,0x0B3,0x0]

v10,v11 = 0,0
v14 = s
tab = [0]*63
for j in range(63):
v11 = v11+1
v10 = (v14[v11] + v10)& 0xff
v14[v11],v14[v10] = v14[v10],v14[v11]
tab[j] = v14[(v14[v10]+ v14[v11]) %256]

flag = [answer[i]^tab[i] for i in range(63)]
print(bytes(flag))
#flag{i_hope_you_didnt_click_the_button_99999__justRE_in_Static}

flag:flag{i_hope_you_didnt_click_the_button_99999__justRE_in_Static}

二进制玩家人均全栈

得到一个没有后缀名的文件,先用010editor打开

看文件头发现为压缩包,把后缀改为zip格式

发现还要密码,但是全局加密是==00 00==可以基本判断是伪加密,改一下后面==全局方式位标记==即可,解压得到文件

先查壳,发现看不出个所以然,用010editor打开

可以发现头文件疑似被魔改了,将MZ修改为elf试试

再用查壳工具查壳

发现是upx的壳,但是也有可能是魔改upx我们先用010editor看看,这里也可以直接手动脱壳,我们在010editor中将vmp改为upx!(还有其他vmp也要改成upx)

再直接放入工具脱壳即可

用ida64打开分析,定位至关键函数

可以看见这其实是一道迷宫题提取出迷宫矩阵

1
2
3
4
5
6
7
8
1, 1, 0, 0, 0, 0, 0, 0
0, 1, 1, 1, 0, 0, 0, 0
0, 0, 0, 1, 0, 0, 0, 0
0, 1, 1, 1, 0, 0, 0, 0
0, 1, 0, 0, 0, 1, 1, 1
0, 1, 1, 1, 0, 1, 0, 1
0, 0, 0, 1, 1, 1, 0, 1
0, 0, 0, 0, 0, 0, 0, 1

1代表可以通行0代表不能通信,所以路径为:

dsddssaassddsddwwddsss

所以flag为:ctfshow{dsddssaassddsddwwddsss}

encode

得到文件先用010editor打开,头文件显示为elf文件

用查壳工具查壳

发现是upx的壳,先在010editor里看看有没有魔改的地方,发现没有直接工具脱壳

脱完壳后用ida打开分析,对一些函数进行初步分析改名得到

先分析==sub_8048AC2==函数

发现是一个base64加密

这一部分是将加密的结果再与v5进行异或,接着进入 sub_8048E24函数, sub_8048E24函数是一个RC4加密这里可以直接解出rc4的值也可以动调找出rc4

的值

这里写一个解密脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
key0 = b'Flag{This_a_Flag}'   #密钥
c = bytes.fromhex('E8D8BD91871A010E560F53F4889682F961420AF2AB08FED7ACFD5E00') #加密后的字符串
v9 = [i for i in range(256)]
v8 = (key0 * 50)[:256]
j = 0
for i in range(256):
j = (v9[i] + j + v8[i]) % 256
v9[i], v9[j] = v9[j], v9[i]
tab = [0] * 28
i, j = 0, 0
for t in range(28):
i = (i + 1) % 256
j = (v9[i] + j) % 256
v9[i], v9[j] = v9[j], v9[i]
tab[t] = v9[(v9[i] + v9[j]) % 256]

c = [tab[i] ^ v for i, v in enumerate(c)]
print(c)
# [35, 21, 37, 83, 8, 26, 89, 56, 18, 106, 57, 49, 39, 91, 11, 19, 19, 8, 92, 51, 11, 53, 97, 1, 81, 31, 16, 92]

之后再与v5进行异或

1
2
3
4
5
6
7
8
9
v5 = "Flag{This_a_Flag}"
str_values = [35, 21, 37, 83, 8, 26, 89, 56, 18, 106, 57, 49, 39, 91, 11, 19, 19, 8, 92, 51, 11, 53, 97, 1, 81, 31, 16, 92]
result = []

for i in range(len(str_values)):
result.append(chr(str_values[i] ^ ord(v5[i % len(v5)])))

print(''.join(result))

得到base64解密后的结果,但是这里还要注意base64是换了码表的

得到flag:BJD{0v0_Y0u_g07_1T!}

Easy

这一题给了一个exe可执行文件,先用查壳工具查壳

发现没有壳,尝试运行一下

发现没有任何提示,用ida打开查看main函数也看不出任何端倪

而且也不会跳转到其他函数去,所以可以看看其他函数,之后发现==__ques==似乎是在画一个图形

可以试试用od修改程序逻辑让程序直接跳转至该函数执行,只要找到==__ques==的地址即可,这里就不细说了,打印出的图像为:

HACKIT4FUN

flag:BJD{HACKIT4FUN}

BJD hamburger competition

这一天是一个untiy3D小游戏,看了网上的wp可以用==dnSpy==进行反编译,将游戏文件的BJD_hamburger_competition\BJD hamburger competition_Data\Managed\Assembly-CSharp.dll,拖入dnspy进行反编译

在末尾发现一串神秘的字符==DD01903921EA24941C26A48F2CEC24E0BB0E8CC7==,查看Sha1函数,而后面又进行了MD5加密,我们先进行MD5解密

再分析Sha1函数

这里ToString(“X2”)的意思是输出大写,所以可以判断1001进行加密是大写进制,这里试试16位大写和32位大写,而且之去前二十位,因此可以确定是MD5大写加密取前20位

flag为:BJDCTF{B8C37E33DEFDE51CF91E}(后续交flag发现要用flag{}来包)