本题是输入了一个字符串,进行了rc4加密,和魔改的base64加密
RC4算法初始化函数
RC4加密过程
魔改的base64加密
最后加密的字符串是byte_602080
我们可以将byte_602080提取出来,下面是提取数据的IDC脚本,得到了密文
#include<idc.idc> static main(){ Message("\nStart:-------------------------------------------------------------------\n"); auto addr=0x602080; auto i=0; auto length=51 ; for(i=addr;i<=addr+length;i++){ Message("0x%02x,",Byte(i)); } Message("End:-----------------------------------------------------------------------\n"); }
然后先进行base64解密
然后进行RC4解密
我们RC4解密时候,不编写整个RC4加密算法的解密脚本
我们知道RC4加密算法最后是要得到一个数据和明文进行异或
*(_BYTE *)(i + a2) ^= LOBYTE(v9[(unsigned __int8)(v7 + v8)]);
该数据 xor 明文=密文
密文 xor 该数据 =明文
我们如果能得到每次循环的这个数据,与base64解密得到结果(RC加密后的密文)依次异或就能得到明文
这个需要远程动态调试,我们需要在88次循环中截取到每次最后进行异或的这个数据
观察这一句对应的汇编代码,xor edx,esi
发现此时edx存储的正是这个要和明文异或的数据
我们将这个文件放在Linux虚拟机中进行动态调试
编写脚本自动化调试提取每次edx的值
这是使用脚本自动化动态调试得到的每次的数据
编写wp
#include <stdio.h> #include <string.h> int main() { char data[] = {0x5a, 0x60, 0x54, 0x7A, 0x7A, 0x54, 0x72, 0x44, 0x7C, 0x66, 0x51, 0x50, 0x5B, 0x5F, 0x56, 0x56, 0x4C, 0x7C, 0x79, 0x6E, 0x65, 0x55, 0x52, 0x79, 0x55, 0x6D, 0x46, 0x6B, 0x6C, 0x56, 0x4A, 0x67, 0x4C, 0x61, 0x73, 0x4A, 0x72, 0x6F, 0x5A, 0x70, 0x48, 0x52, 0x78, 0x49, 0x55, 0x6C, 0x48, 0x5C, 0x76, 0x5A, 0x45, 0x3D}; char flag[255]; memset(flag, 0, sizeof(flag)); int j = 0; char l[] = {0x10, 0x59, 0x9C, 0x92, 0x06, 0x22, 0xCF, 0xA5, 0x72, 0x1E, 0x45, 0x6A, 0x06, 0xCB, 0x08, 0xC3, 0xE4, 0x49, 0x5A, 0x63, 0x0C, 0xDF, 0xF6, 0x5F, 0x08, 0x28, 0xBD, 0xE2, 0x10, 0x15, 0x1F, 0x6E, 0xAA, 0x5A, 0xCA, 0xEC, 0x80, 0xAF, 0x9B, 0x16, 0xBB, 0x3D, 0x13, 0x2F, 0x6A, 0xA4, 0xC7, 0x2E, 0xBC, 0x4B, 0x60, 0x9A, 0xAF, 0xE9, 0xCE, 0xDA, 0x67, 0x39, 0xBA, 0x3B, 0x85, 0xEB, 0xD2, 0x6B, 0xAB, 0x06, 0x6B, 0x10, 0x57, 0x2C, 0x88, 0x70, 0xF7, 0x4F, 0xAA, 0x7F, 0x12, 0x47, 0xD6, 0xDE, 0x74, 0xB2, 0x1D, 0xA4, 0xD7, 0x76, 0x9A, 0xE0}; for (int i = 0; i < sizeof(data); i += 4) { flag[strlen(flag)] = (((data[i] - 0x3D) & 0x3F) << 2) | (((data[i + 1] - 0x3D) & 0x30) >> 4); flag[strlen(flag)] = (((data[i + 1] - 0x3D) & 0x0F) << 4) | (((data[i + 2] - 0x3D) & 0x3C) >> 2); flag[strlen(flag)] = ((data[i + 3] - 0x3D) & 0x3F) | ((data[i + 2] - 0x3D) & 0x03) << 6; } for (int i = 0; i < strlen((const char *)flag); i++) { flag[i] ^= l[j++]; } printf("%s", flag); return 0; }