红明谷-g0
看名字就是go语言题目,用IDA-golang-helper
还原符号表之后,看到只有几个函数,其中main_Encode
就是加密函数

函数逻辑比较简单,输入长度等于20,打乱位置,进入main_Encode
加密,最后进入main_fun1
进行比较,直接看main_Encode
中的加密算法
动态调试后发现一张表,表的长度为58位,判断为换表base58加密


进入main_fun1
函数中找到加密后的字符串,注意 runtime_memequal
这个比较的函数需要在汇编中寻找比较的字符串首地址,在伪代码中是找不到的

1 2 3 4 5 6 7 8 9 10 11 12
| import base58
Cipher = '2GVdudkYo2CBXoQii7gfpkjTc4gT' Plain = '' new_table = '12Nrst6CDquvG7BefghJKLMEFHPQZabRSTUVmyzno89ApwxWXYcdkij345' old_table = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
for i in range(len(Cipher)): Plain += old_table[new_table.index(Cipher[i])] print(base58.b58decode(Plain.encode()))
|
虎符-re
mips
架构文件,本来想用qemu
动态调试的,但是好像虚拟机的so文件出问题了,就静态分析算了,反正有IDA7.5
不怕
看伪代码很浓厚的C++气息,两次判断,pre
函数里面还判断了输入的长度

server_check_redemption_code
函数大概的意思就是生成一张宽256长和字符串长度相同的表,当表的列值与输入的字符串的ASCII值相同时就做一个标记,用C语言还原后的代码如下
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
| #include <stdio.h> #include <string.h> #include <stdlib.h> int main() { char string[] = ""; char input[] = "";
int string_len = strlen(string); int input_len = strlen(input);
int* s = (int*)malloc(input_len << 10); memset((void*)s, 0, input_len << 10); int count = 0; for (int i = 1; i < input_len; i++) { for (int j = 0; j < 256; j++) { if (j != input[i]) { s[256 * i + j] = s[256 * count + j]; } else s[256 * i + j] = i + 1; } count = s[256 * count + input[i]]; } int sign = 0; for (int k = 0; k < string_len; k++) { sign = s[256 * sign + string[k]]; if (sign == input_len) { printf("%d", k - input_len + 1); } } }
|
题目中有两个字符串,所以生成了两张表,两张表中相同的值就是需要输入的flag
Ninja Must Die 3 Is A Cruel Game, So Hard For Me
I Love Ninja Must Die 3. Beautiful Art And Motive Operation Is Creative.
两个字符串中相同的值为Ninja Must Die
虎符-gocrypt
变种的xtea
在写脚本的时候忘记了小端存储,这个地方搞了很久,以后遇到不能在犯错误了
用插件还原符号表后看到函数并没有多少,输入检测函数main_check
,数据加密函数main_main__ptr_myCipher_Encrypt
main_check
函数中有一个正则匹配来规定flag输入的格式

1
| 正则匹配格式:flag{([0-9a-f]{8})-([0-9a-f]{4})-([0-9a-f]{4})-([0-9a-f]{4})-([0-9a-f]{12})}
|
在进入main_check
返回一个值给标志,判断是否进入下一个步骤

main__ptr_myCipher_Encrypt
函数中的加密算法就是变种的xtea
加密,随机数变成了0x12345678

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
| #include <stdio.h> #include <stdint.h>
void XTEA_decrypt(uint32_t rounds, uint32_t* v, uint32_t* k) { uint32_t delta = 0x12345678; uint32_t sum = rounds * delta; uint32_t v0 = v[0], v1 = v[1]; for (int i = 0; i < rounds; i++) { v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum >> 11) & 3]); sum -= delta; v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]); } v[0] = v0; v[1] = v1; } int main(){ uint32_t rounds = 32; uint32_t v[2][2] = { { 0x0ec311f0, 0x45c79af3 }, { 0xedf5d910, 0x542702cb } }; uint32_t k[4] = { 0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f }; XTEA_decrypt(rounds, v[0], k); XTEA_decrypt(rounds, v[1], k); printf("%x-%x\n", v[0][0], v[0][1]); printf("%x-%x\n", v[1][0], v[1][1]); }
|

虎符-CrackMe
这个题需要输入两次,第一次输入后判断输入的长度,长度需要17位,输入后将输入的字符串的前7位和后10位分割,分别存储在不同的内存中

第二次输入需要输入一个数字,在经过两轮简单的计算后与指定的两个值进行比较,直接写脚本爆破,最后计算出需要输入的值为90038

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 40 41 42 43 44 45 46
|
#include <stdlib.h> #include <stdio.h> #include <math.h> double cal(double a, double b) { double _a; double var = 0.0; _a = a; a = pow(a, b - 1); *(&var + 1) = *(&a + 1); var = a / exp(_a); return var; }
int main(int argc, char* argv[]) { double input_num; for (int i = 0; i < 99999; i++) { input_num = i; printf("%d\n", i); double v16 = 0.0, v17 = 0.0, v18 = 0.0, v19 = 0.0; int num1 = 0x13B03, num2 = 0x5A2; v19 = (double)((int)input_num / 0x305B) + 1.0; do { v17 = v17 + cal(v18, v19) * 0.001; v18 = v18 + 0.001; } while (v18 <= 100.0);
double v21 = 0.0; double v22 = (double)((int)input_num % 0x305B) + 1.0; do { v16 = v16 + cal(v21, v22) * 0.001; v21 = v21 + 0.001; } while (v21 <= 100.0); if ((int)(v17 + v17 + 3.0) == num1 && (int)(v16 + v16 + 3.0) == num2) { printf("%f", input_num); break; } } return 0; }
|
后面就比较简单了,首先将输入的数字转为ascii
码,然后在后面追加input_num*2
,一共追加5次,取前7位进行异或计算出一个key
供后面使用
1 2 3 4 5 6
| Cipher = [8, 77, 89, 6, 115, 2, 64] key = list(map(ord,list("9903819"))) Plain = bytes(key[i]^Cipher[i] for i in range(7)) print(Plain)
|
后面就是一个标准的RC4
加密
1 2 3 4 5 6 7 8
| from Cryptodome.Cipher import ARC4
Cipher = bytes([178, 214, 142, 63, 170, 20, 83, 84, 198, 6]) Key = b'1ti5K3y' rc4 = ARC4.new(Key) Plain = rc4.decrypt(Cipher) print(Plain)
|
