REVERSE-COMPETITION-GeekChallenge2021
- Re0
- 刘壮桌面美化大师
- 买Activity
- Re1
- 调试
- 珍惜生命
- new_language
- easypyc
- Brute_force
- win32
- wasm
- 猜拳
- have_a_tea
Re0
64位exe,ida打开,main函数中没发现什么重要的逻辑
Shift+F12打开字符串窗口,直接找到flag明文
刘壮桌面美化大师
apk文件,jadx-gui打开,MainActivity中什么都没有,于是查看与MainActivity在同一目录下的其它类
在DesktopbeautifierConfigureActivityKt类里面找到一个好像和flag相关的方法loadTitlePref
loadTitlePref要获取R.string.flag,我们跟过去发现只是一个整型,实际上是一个资源id
在android中,一个资源id和一个实际的资源绑定,而这个实际的资源在资源文件res中
于是在如下位置找到flag
买Activity
apk文件,加载了buyactivity库,MainActivity大概作用是保存输入到一个msgList里,没什么大用,于是Msg和MsgAdapter这两个类就不用看了
查看ExportedActivity这个类,发现可以直接在一个文本框打印flag
来到Decode类,从本地获取一个字符串,然后对这个字符串顺序异或16即为flag
这个时候可以直接用jeb调试smali,指定启动ExportedActivity即可获得flag
这里我们按照getDecodedFlag方法的逻辑计算flag
ida打开libbuyactivity.so,来到Java_com_sorrowrain_buyactivity_Decode_stringFromNative
可以看到两个字符串和一些操作,下面的操作一时看不懂,直接将两个字符串拼接,然后顺序异或16
可以看到两个字符串拼接顺序异或16后,得到的字符串中含有"{}",说明这个字符串大概率就是flag,但是顺序不对
s="CSD!Os!yiyO#|iU`bu1Ikxc$dFdOCBq!Oh dtm"
flag=""
for c in s:flag+=chr(ord(c)^16)
print(flag)
# SCT1_c1iyi_3lyEpre!Y{hs4tVt_SRa1_x0td}
看着像栅栏,直接用工具,栏数为2,得到flag
解栅栏前:
解栅栏后:
Re1
64位的exe,ida打开
主要的逻辑在main函数中,输入的长度为44,输入经标准base64变换后与0x40异或,最后与data比较
取出data的数据,写逆脚本即可
import base64
res=[21,113,44,4,37,113,40,16,21,44,121,40,34,45,18,38,25,45,6,58,26,20,25,112,24,114,6,57,26,22,121,112,33,7,22,38,25,45,6,58,33,24,14,38,34,114,26,38,35,45,22,114,26,24,10,58,26,24,112,125]
for i in range(len(res)):res[i]^=0x40
flag="".join(chr(i) for i in res)
print(base64.b64decode(flag))
# SYC{XOR_and_base64_are_the_basis_of_reverse}
调试
64位elf,反编译main函数后就只有一个字符串拷贝
查看main函数的汇编代码,在偏移0x144C处有一条jnz条件跳转指令,如果[rbp+var_144]非零则跳转到loc_1455,但是在偏移0x1382处给[rbp+var_144]赋值为0,所以ida反编译到jnz就判定为不跳转,进而jmp到loc_14A0即main函数结束处
我们看到loc_1455中偏移为0x146B处调用了sub_11C8函数,根据函数调用约定可知上面拷贝来的字符串作为参数传入了sub_11C8函数进行处理
于是可以猜测出题人就是想通过上述不执行jnz条件跳转的方式来隐藏flag
这里我们先去看一下sub_11C8函数,ida分析sub_11C8失败,先在偏移0x11C8处右键->undefine
我们知道函数的开头一般是push rbp,机器码为0x55,于是在偏移0x11CD处,按c将数据转为代码,再按p创建函数,反编译后得到
sub_11CD没看懂什么逻辑,实际上也不需要看懂
出题人通过不执行sub_11CD的方式来隐藏flag,于是我们可以patch程序,将jnz改写成jz,如图
保存后,直接运行elf,即可得到flag
或者不patch程序,根据题目的提示,用ida远程调试elf的时候,在执行jnz之前将零标志位的值修改为0即可将程序流引向执行sub_11CD,进而获得flag
珍惜生命
.pyc文件,用uncompyle6来反编译
输入flag和key,flag长度为51,key长度为8
验证key经过多元方程组运算后是否与"Syclover"相同,然后输入的flag中{}中包含的内容与key做循环异或,结果与一个给定的flag元组比较,验证输入的flag是否正确
def Challenge():import sysprint("Welcome to py's world")S = input('plz give me your flag:')Key = input('plz give me your key(string):')if len(S) != 51 or len(Key) != 8:print("the flag's or key's strlen...")sys.exit()else:tmp = S[4:50]KEY_cmp = 'Syclover'key = []key_cmp = ''for i in Key:key.append(ord(i))try:key_cmp += chr((key[1] * key[2] - key[5] * 72 - key[4] * 3 - key[3] ^ key[1] + (key[3] << 2) + key[2] * 6 - key[7] & key[6] - 1000) - 14)key_cmp += chr((key[5] * 7 + key[3] * 3 + key[2] + key[6] - (key[2] >> 2) - key[1] ^ key[0] + key[7] + (key[4] ^ key[1]) + (key[4] | key[7])) - 801)key_cmp += chr((key[6] * 5 + key[2] * 6 - key[3] * 7 + key[4] | key[5] + key[4] * 10 + key[0] ^ key[1] * 3 - key[7] + key[0] + key[1]) - 924)key_cmp += chr(key[1] * 3 + key[5] * 9 + key[0] + key[2] * 2 + key[3] * 5 - key[4] * (key[6] ^ key[7]) + 321 - 16)key_cmp += chr((key[5] * 12 - key[0] ^ key[6] - key[3] * 23 + key[4] * 3 + key[2] * 8 + key[1] - key[7] * 2 + key[6] * 4 + 1324) + 1)key_cmp += chr(key[3] * 54 - key[1] * 3 + key[2] * 3 + key[4] * 11 - key[5] * 2 + key[0] + key[7] * 3 - key[6] - 6298 + 40)key_cmp += chr(key[7] - key[6] * key[3] + key[2] * key[2] - key[4] * 32 + key[5] * (key[0] >> 2) - key[1] * key[1] - 6689 + 41)key_cmp += chr((key[5] - key[3] * 41 + key[6] * 41 + key[5] ^ (key[4] & key[6] | key[0]) - (key[7] * 24 | key[2]) + key[1] - 589) - 36)except ValueError:print("You know what I'm going to say...")sys.exit()if key_cmp != KEY_cmp:print("You know what I'm going to say...")sys.exit()flag = [113, 74, 71, 35, 29, 91, 29, 12, 114, 73, 60, 52, 69, 5, 113, 35, 95, 38, 20, 112, 95, 7, 74, 12, 102, 23, 7, 31, 87, 5, 113, 98, 85, 38, 16, 112, 29, 6, 30, 12, 65, 73, 83, 36, 12, 23]for i in range(46):if ord(tmp[i]) ^ key[((i + 1) % len(key))] != flag[i]:print("You know what I'm going to say...")sys.exit()print('Yeah!Submit your flag in a hurry~')Challenge()
核心在求解key,用z3解多元方程组即可,需要注意两个地方
1、用BitVec定义变量时需要是16位,笔者开始用8位,一直解不出来
2、此方程组多解,要用while s.check()==sat来输出多组解,需要的是key的8个值都小于128的一组解
from z3 import *
key=[BitVec("key[%d]"%i,16) for i in range(8)]
KEY_cmp="Syclover"
KEY_num=[ord(c) for c in KEY_cmp]
s=Solver()
s.add(((key[1] * key[2] - key[5] * 72 - key[4] * 3 - key[3] ^ key[1] + (key[3] << 2) + key[2] * 6 - key[7] & key[6] - 1000) - 14)==KEY_num[0])
s.add(((key[5] * 7 + key[3] * 3 + key[2] + key[6] - (key[2] >> 2) - key[1] ^ key[0] + key[7] + (key[4] ^ key[1]) + (key[4] | key[7])) - 801)==KEY_num[1])
s.add(((key[6] * 5 + key[2] * 6 - key[3] * 7 + key[4] | key[5] + key[4] * 10 + key[0] ^ key[1] * 3 - key[7] + key[0] + key[1]) - 924)==KEY_num[2])
s.add((key[1] * 3 + key[5] * 9 + key[0] + key[2] * 2 + key[3] * 5 - key[4] * (key[6] ^ key[7]) + 321 - 16)==KEY_num[3])
s.add(((key[5] * 12 - key[0] ^ key[6] - key[3] * 23 + key[4] * 3 + key[2] * 8 + key[1] - key[7] * 2 + key[6] * 4 + 1324) + 1)==KEY_num[4])
s.add((key[3] * 54 - key[1] * 3 + key[2] * 3 + key[4] * 11 - key[5] * 2 + key[0] + key[7] * 3 - key[6] - 6298 + 40)==KEY_num[5])
s.add((key[7] - key[6] * key[3] + key[2] * key[2] - key[4] * 32 + key[5] * (key[0] >> 2) - key[1] * key[1] - 6689 + 41)==KEY_num[6])
s.add(((key[5] - key[3] * 41 + key[6] * 41 + key[5] ^ (key[4] & key[6] | key[0]) - (key[7] * 24 | key[2]) + key[1] - 589) - 36)==KEY_num[7])
while s.check():print(s.model())
# [key[6] = 54,
# key[1] = 38,
# key[3] = 99,
# key[0] = 83,
# key[7] = 46,
# key[2] = 121,
# key[5] = 45,
# key[4] = 64]
最后key与flag循环异或即可得到flag
flag = [113, 74, 71, 35, 29, 91, 29, 12, 114, 73, 60, 52, 69, 5, 113, 35, 95, 38, 20, 112, 95, 7, 74, 12, 102, 23, 7, 31, 87, 5, 113, 98, 85, 38, 16, 112, 29, 6, 30, 12, 65, 73, 83, 36, 12, 23]
key=[0]*8
key[6] = 54
key[1] = 38
key[3] = 99
key[0] = 83
key[7] = 46
key[2] = 121
key[5] = 45
key[4] = 64
for i in range(len(flag)):flag[i]^=key[(i+1)%len(key)]
print("SYC{"+"".join(chr(i) for i in flag)+"}")
# SYC{W3$c0m3_T0_th3_py_w0r1d_@nd_z3_1s_s0000_g00d!!}
new_language
32位.Net程序,dnSpy打开,来到Main
text为输入,长度为38,将输入作为下标从sbox中取值,保存到array中,然后array与已知的array2比较
取出sbox和array2,写逆运算脚本即可得到flag
sbox=[99,124,119,123,242,107,111,197,48,1,103,43,254,215,171,118,202,130,201,125,250,89,71,240,173,212,162,175,156,164,114,192,183,253,147,38,54,63,247,204,52,165,229,241,113,216,49,21,4,199,35,195,24,150,5,154,7,18,128,226,235,39,178,117,9,131,44,26,27,110,90,160,82,59,214,179,41,227,47,132,83,209,0,237,32,252,177,91,106,203,190,57,74,76,88,207,208,239,170,251,67,77,51,133,69,249,2,127,80,60,159,168,81,163,64,143,146,157,56,245,188,182,218,33,16,255,243,210,205,12,19,236,95,151,68,23,196,167,126,61,100,93,25,115,96,129,79,220,34,42,144,136,70,238,184,20,222,94,11,219,224,50,58,10,73,6,36,92,194,211,172,98,145,149,228,121,231,200,55,109,141,213,78,169,108,86,244,234,101,122,174,8,186,120,37,46,28,166,180,198,232,221,116,31,75,189,139,138,112,62,181,102,72,3,246,14,97,53,87,185,134,193,29,158,225,248,152,17,105,217,142,148,155,30,135,233,206,85,40,223,140,161,137,13,191,230,66,104,65,153,45,15,176,84,187,22]
array2=[64,249,133,69,146,253,253,207,182,4,157,207,251,4,60,81,59,77,146,77,207,26,38,207,64,77,177,77,64,195,77,253,253]
flag=[]
for i in range(len(array2)):for j in range(len(sbox)):if sbox[j]==array2[i]:flag.append(j)break
print("SYC{"+"".join(chr(i) for i in flag)+"}")
# SYC{right!!_y0u_c0mpIete_C#_reVer3e!!}
easypyc
python打包成的exe,用pyinstxtractor脚本解包
uncompyle6反编译easypyc.pyc失败,原因是解包后的easypyc.pyc文件魔数被破坏,需要修正正确
此为被破坏的easypyc.pyc文件
想要修正easypyc.pyc需要对照同目录下的struct.pyc进行修正,如图
此为修正后的easypyc.pyc文件
保存后再用uncompyle6反编译
whatbox = [0] * 256def aaaaaaa(a, b):k = [0] * 256t = 0for m in range(256):whatbox[m] = mk[m] = ord(a[(m % b)])else:for i in range(256):t = (t + whatbox[i] + k[i]) % 256temp = whatbox[i]whatbox[i] = whatbox[t]whatbox[t] = tempdef bbbbbbbbbb(a, b):q = 0w = 0e = 0for k in range(b):q = (q + 1) % 256w = (w + whatbox[q]) % 256temp = whatbox[q]whatbox[q] = whatbox[w]whatbox[w] = tempe = (whatbox[q] + whatbox[w]) % 256a[k] = a[k] ^ whatbox[e] ^ 102 #魔改,多异或了一个102def ccccccccc(a, b):for i in range(b):a[i] ^= a[((i + 1) % b)]else:for j in range(1, b):a[j] ^= a[(j - 1)]if __name__ == '__main__':kkkkkkk = 'Geek2021'tttttt = [117, 62, 240, 152, 195, 117, 103, 74, 240, 151, 173, 162, 17, 75, 141, 165, 136, 117, 113, 33, 98, 151, 174, 4, 48, 25, 254, 101, 185, 127, 131, 87]ssss = input('Please input your flag:')inp = [0] * len(ssss)if len(ssss) != 32:print('Length Error!!!!')exit(0)for i in range(len(ssss)):inp[i] = ord(ssss[i])else:aaaaaaa(kkkkkkk, len(kkkkkkk))bbbbbbbbbb(inp, 32)ccccccccc(inp, 32)for m in range(32):if tttttt[m] != inp[m]:raise Exception('sorry your flag is wrong')print('success!!!!!!')print('your flag is {}'.format(ssss))
aaaaaaa和bbbbbbbbbb是魔改了一点的RC4,最后异或的时候多异或了一个102,解RC4的时候要加上,密钥为"Geek2021"
ccccccccc对RC4加密后的密文进行异或运算,结果与tttttt比较
先逆ccccccccc解得正确的RC4密文
tttttt = [117, 62, 240, 152, 195, 117, 103, 74, 240, 151, 173, 162, 17, 75, 141, 165, 136, 117, 113, 33, 98, 151, 174, 4, 48, 25, 254, 101, 185, 127, 131, 87]
for i in range(len(tttttt)-1,0,-1):tttttt[i]^=tttttt[i-1]
tttttt[len(tttttt)-1]^=tttttt[0]
for i in range(len(tttttt)-2,-1,-1):tttttt[i]^=tttttt[i+1]
print(tttttt)
# [34, 87, 28, 210, 186, 225, 87, 69, 104, 210, 181, 143, 128, 51, 105, 175, 135, 170, 87, 83, 3, 64, 181, 140, 38, 18, 59, 220, 71, 155, 93, 161]
再解魔改RC4即可得到flag
#include<stdio.h>
void rc4_init(unsigned char* s, unsigned char* key, unsigned long Len_k)
{int i = 0, j = 0;char k[256] = { 0 };unsigned char tmp = 0;for (i = 0; i < 256; i++) {s[i] = i;k[i] = key[i % Len_k];}for (i = 0; i < 256; i++) {j = (j + s[i] + k[i]) % 256;tmp = s[i];s[i] = s[j];s[j] = tmp;}
}/*
RC4加解密函数
unsigned char* Data 加解密的数据
unsigned long Len_D 加解密数据的长度
unsigned char* key 密钥
unsigned long Len_k 密钥长度
*/
void rc4_crypt(unsigned char* Data, unsigned long Len_D, unsigned char* key, unsigned long Len_k) //加解密
{unsigned char s[256];rc4_init(s, key, Len_k);int i = 0, j = 0, t = 0;unsigned long k = 0;unsigned char tmp;for (k = 0; k < Len_D; k++) {i = (i + 1) % 256;j = (j + s[i]) % 256;tmp = s[i];s[i] = s[j];s[j] = tmp;t = (s[i] + s[j]) % 256;Data[k] = Data[k] ^ s[t]^102; //这里加一个异或102}
}
void main()
{//密钥unsigned char key[] = "Geek2021";unsigned long key_len = sizeof(key) - 1;//密钥//unsigned char key[] = {};//unsigned long key_len = sizeof(key);//密文unsigned char data[] = { 34, 87, 28, 210, 186, 225, 87, 69, 104, 210, 181, 143, 128, 51, 105, 175, 135, 170, 87, 83, 3, 64, 181, 140, 38, 18, 59, 220, 71, 155, 93, 161 };//解密rc4_crypt(data, sizeof(data), key, key_len);for (int i = 0; i < sizeof(data); i++){printf("%c", data[i]);}printf("\n");return;
}
//SYC{Just_a_Eeeeeeasy_Rc4_right?}
Brute_force
64位exe,ida打开,go语言,左侧函数窗找到main_main
要求运行时加参数,且参数的长度为24
进入main_unnamed630函数,第40行有一个main_encode函数,做了md5散列,返回十六进制摘要
直接在ida中调试一下,断点下在main_unnamed630函数第49行调用runtime_memequal函数前
参数设置为一段长度为24的字符串,如图
程序运行后在此处断下
v15指向我们的输入经main_encode函数处理返回的十六进制摘要,此时为"e2fc714c4727ee9395f324cd2e7f331f"
v19指向要去比较的长度为32的md5十六进制摘要,此时为"957a3926d4ff16d0d3bac4ed3044537b"
通过在线网站查询到v15指向的字符串就是我们输入的前四个字符"abcd"的md5十六进制摘要
那么这题的流程就是将长度为24的输入分成6组,每组4个字符,对每组进行md5散列,返回散列值的十六进制摘要,与已知的长度为32的md5十六进制摘要比较,从而验证输入
每组4个字符,每个字符的ascii码范围为[48,128),可爆破,和题目名称呼应
"957a3926d4ff16d0d3bac4ed3044537b"只是第1组要去比较的md5十六进制摘要,其他5组可通过调试得到
最后全部6组md5十六进制摘要和爆破脚本如下
# -*- coding:utf-8 -*-
import hashlib
s="957a3926d4ff16d0d3bac4ed3044537b"
#s="d7bf94ada03842f20934c5605728fbc5"
#s="5781f597ce91fb5f66057f35846bcb78"
#s="ae4b9b5b2468a3d15b6b8690b761e160"
#s="4ad50c4af2c5beda7aca217afbac9bd6"
#s="f40b339be4c5898741b8a0d2a8007bd5"
for i0 in range(48,128):for i1 in range(48, 128):for i2 in range(48, 128):for i3 in range(48, 128):flag=chr(i0)+chr(i1)+chr(i2)+chr(i3)h=hashlib.md5()h.update(flag.encode(encoding='utf-8'))if h.hexdigest()==s:print(flag)exit()
# 7h3_g0_pr0g@rm_13_slgned
win32
题目名为win32,实际是个64位的exe,upx脱壳,ida打开
题目描述中提到了base64,猜测可能是变表base64
交叉引用Str2来到sub_140011B80函数,主要逻辑在case 0x111处
输入传入sub_1400110F5函数处理,结果放入变量Str1中,与已知的Str2比较,验证输入
进入sub_1400110F5->sub_140011F90
sub_140011F90函数构造了一个表,和标准的base64表是一样的,下面就是正常的base64算法
直接解Str2的base64即可得到flag
wasm
wasm逆向参考:一种Wasm逆向静态分析方法
使用wasm2c将.wasm文件转为.c文件,对.c文件用gcc只编译不链接得到.o文件
ida分析.o文件,w2c_main->w2c_f11
大概的逻辑如下图,判断输入的长度是否等于22,w2c_f10对输入进行变换,w2c_f9对变换后的输入进行比较验证
进入w2c_f10函数,唯一的参数就是我们的输入
看到循环体里有一个异或0x66的运算,结合题目文件名xorwasm,这个异或0x66的运算可能有很大作用
之前猜测w2c_f9是对变换后的输入进行比较验证的函数,但是跟进去分析并没有找到最后要去比较的数据
参考博客里写道,“对于wasm,所有的字符串会被存放在二进制文件的末尾,以此能获取一些关键的信息”
而且在ida字符串窗口中也能找到一些明文字符串
在Hex View中找到这些明文字符串,可以看到在"infinity"这个有意义的单词前正好有22个数据,猜测这些数据就是最后要去比较的数据
直接取出这22个数据,异或0x66后即可得到flag
arr=[0x35, 0x3f, 0x25, 0x1d, 0x11, 0x07, 0x15, 0x0b, 0x39, 0x2f, 0x15, 0x39,0x35, 0x56, 0x39, 0x21, 0x09, 0x56, 0x02, 0x47, 0x47, 0x1b]
for i in range(len(arr)):arr[i]^=0x66
print("".join(chr(i) for i in arr))
# SYC{wasm_Is_S0_Go0d!!}
猜拳
64位exe,加了upx壳,但是工具脱不掉壳
根据提示"API断点"猜测可能是通过调试器对按钮相关的API下断点,程序停下来后修改寄存器的值,从而改变程序执行流,得到flag
程序直接扔进x64dbg,然后F9会被程序检测到调试器从而结束进程
这时我们先运行程序,然后让x64dbg去附加(attach)到运行中的程序
附加成功后,右键->搜索->所有模块->字符串
可以发现一些明文字符串
双击字符串"Congratulations on getting the flag"(相当于ida中的交叉引用),找到引用该字符串的指令
我们看到该字符串的上方有一条"Sycl0v3r"的字符串,还有一条"call re.7FF7A77E13D8"的指令
多次调试发现,程序将"Sycl0v3r"作为密钥传入0x7FF7A77E13D8处的函数,对密文进行解密,返回flag
在上图标红处,即"00007FF7A77E1567"处,右键->设置新的运行点,将rip设置到此处
随后F8单步步过,在"call re.7FF7A77E13D8"这条指令执行后即可得到flag
have_a_tea
64位ELF,start函数中存在SMC,在偏移0x1A2F处下断点
启动调试,程序断下来后,F8来到偏移0x0870处
再多按几次F8,来到偏移0x1361处
之后可以不用按F8,往下走,来到偏移0x14C6处,可以看到"db 55h"
我们知道"push rbp"的机器码为0x55,于是这里就是一个函数的起始地址
在偏移0x14C6处按c,将数据转成代码,再按p创建函数,然后F5反编译
sub_55C97B2014C6->sub_55C97B2012BD,可以看到程序正常运行时会打印的字符串
进入sub_55C97B2010B7函数,分析可知
程序对输入进行CBC模式的TEA加密,已知iv和key,密文为res
笔者没有CBC模式的TEA解密脚本,只能先对密文解TEA,然后按CBC模式加密思路来逆CBC
对密文解TEA:
#include <stdio.h>
#include <stdint.h>//加密函数
void encrypt(uint32_t* v, uint32_t* k) {uint32_t v0 = v[0], v1 = v[1], sum = 0, i; /* set up */uint32_t delta = 0x9e3779b9; /* a key schedule constant */uint32_t k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3]; /* cache key */for (i = 0; i < 32; i++) { /* basic cycle start */sum += delta;v0 += ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1);v1 += ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);} /* end cycle */v[0] = v0; v[1] = v1;
}
//解密函数
void decrypt(uint32_t* v, uint32_t* k) {uint32_t v0 = v[0], v1 = v[1], sum = 0xC6EF3720, i; /* set up */uint32_t delta = 0x9e3779b9; /* a key schedule constant */uint32_t k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3]; /* cache key */for (i = 0; i<32; i++) { /* basic cycle start */v1 -= ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);v0 -= ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1);sum -= delta;} /* end cycle */v[0] = v0; v[1] = v1;
}int main()
{uint32_t v[2] = { 0xc9fa3b95,0x7cfd0735 };//0x243a2b27,0x1d133211//uint32_t v[2] = { 0x958c7c9f,0xc143b59e };//0x8d945ac6,0x2393665c//uint32_t v[2] = { 0x61741e89,0xf47dcdc4 };//0xfbbc14c5,0x9e22f9c1//uint32_t v[2] = { 0xd6e2a1f2,0x6a38e9ad };//0x3e1a2ff0,0xab1ca587//uint32_t v[2] = { 0xc2c16feb,0x8c0ee999 };//0xb883e88a,0x683ae9d0uint32_t k[4] = { 0x65766967,0x756f795f,0x7075635f,0x6165745f };int n = sizeof(v) / sizeof(uint32_t);decrypt(v, k);for (int i = 0; i < n; i++){printf("0x%x,", v[i]);}printf("\n");return 0;
}
按CBC模式加密思路来逆CBC
from Crypto.Util.number import long_to_bytes
res=[0xc9fa3b95,0x7cfd0735,0x958c7c9f,0xc143b59e,0x61741e89,0xf47dcdc4,0xd6e2a1f2,0x6a38e9ad,0xc2c16feb,0x8c0ee999]
iv=[0]*10
iv[0]=0x5f797274
iv[1]=0x64726168
for i in range(8):iv[i+2]=res[i]
plain=[0x243a2b27,0x1d133211,0x8d945ac6,0x2393665c,0xfbbc14c5,0x9e22f9c1,0x3e1a2ff0,0xab1ca587,0xb883e88a,0x683ae9d0]
flag=""
for i in range(10):flag+=long_to_bytes(plain[i]^iv[i])[::-1]
print(flag)
# SYC{ySaySanDian_Zh0n_La_y1n_Cha_xIan}