kCTF transformers

看雪ctf第二题 变形金刚

(人生中第一篇优秀竟然是这种水题。。。)
下载apk后使用jadx打开
图片.png-81.6kB
在判断输入是否为空之后,传入了eq函数进行分析,eq函数是native函数,用ida打开so
图片.png-26.7kB
可以看到so采用了动态注册的方式,去三元表里找到eq函数的地址,并下断
图片.png-17kB
可以看到第一次是根据apk的一处字符串,取出了’-‘后,存到到了一块区域
图片.png-20.4kB
然后再次根据使用初始的字符串生成了第二处字符串
图片.png-21.3kB
最后生成了第三个table,这个table是最后一处,并且会参与后面的运算
图片.png-11.6kB
这块应该就是rc4的初始化部分,其实不用管,直接在加密函数前下断,dump出最终用来rc4加密的密钥表,

char s[256] = { 0xF0,0x37,0xE1,0x9B,0x2A,0x15,0x17,0x9F,0xD7,0x58,0x4D,0x6E,0x33,0xA0    ,0x39,0xAE,0x04,0xD0,0xBE,0xED,0xF8,0x66,0x5E,0x00,0xD6,0x91,0x2F,0xC3,0x10,0x4C,    0xF7,0xA6,0xC1,0xEC,0x6D,0x0B,0x50,0x65,0xBB,0x34,0xFA,0xA4,0x2D,0x3B,0x23,0xA1,0x96,0xD5,0x1D,0x38,0x56,0x0A,0x5D,0x4F,0xE4,0xCC,0x24,0x0D,0x12,0x87,0x35,0x85,0x8E,0x6F,0xC6,0x13,0x9A,0xD3,0xFC,0xE7,0x08,0xAC,0xB7,0xE9,0xB0,0xE8,0x41,0xAA,0x55,0x53,0xC2,0x42,0xBC,0xE6,0x0F,0x8A,0x86,0xA8,0xCF,0x84,0xC5,0x48,0x74,0x36,0x07,0xEB,0x88,0x51,0xF6,0x7F,0x57,0x05,0x63,0x3E,0xFE,0xB8,0xC9,0xF5,0xAF,0xDF,0xEA,0x82,0x44,0xF9,0xCD,0x06,0xBA,0x30,0x47,0x40,0xDE,0xFD,0x1C,0x7C,0x11,0x5C,0x02,0x31,0x2C,0x9C,0x5F,0x46,0x27,0xC4,0x83,0x73,0x16,0x90,0x20,0x76,0x7B,0xF2,0xE3,0xF3,0x77,0x52,0x80,0x25,0x09,0x26,0x3F,0xC7,0x18,0x1B,0xA3,0xFF,0xFB,0xCB,0xA9,0x8C,0x54,0x7A,0x68,0xB4,0x70,0x4B,0xE2,0x49,0x22,0x7E,0xA5,0xB6,0x81,0x9D,0x4E,0x67,0xF1,0xA7,0x3C,0xD9,0x94,0xEF,0x32,0x6B,0x1F,0xB1,0x60,0xB9,0x64,0x59,0x01,0xB3,0x7D,0xE0,0x6C,0xAD,0x97,0x19,0xB5,0x3A,0xF4,0xD8,0x8D,0x98,0x03,0x93,0x1A,0xDC,0x1E,0x4A,0xC0,0x5A,0xE5,0xD1,0x3D,0x14,0xC8,0x79,0xBD,0x43,0xDB,0x69,0xD2,0x61,0x95,0x9E,0x21,0x45,0x89,0x2B,0xAB,0x29,0xA2,0x8B,    0x2E,0xD4,0x0E,0x62,0xCA,0x28,0xDA,0x5B,0x72,0x8F,0x99,0x75,0xEE,0x78,0x0C,0x71,0xBF,0xDD,0xCE,0x92,0x6A,0xB2 };//S-box

如下是rc4的加密函数
图片.png-7.2kB
可以看到在rc4加密结束后,还进行了魔改base64的编码
图片.png-21.5kB
大概流程就是base64(rc4(input)),最终要校验的地方是下面那一块
图片.png-10.7kB
最后进行解码即可,rc4部分

char input[] = "\xfd\x1e\x8a\x4e\x9\xca\x90\x3\xe7\xf1\x85\x9f\x9b\xf7\x83\x3e";
int len = strlen(input);
int j = 0;
int s1;
for (int i = 0; i < len ; i++) {
if (i != len) {
v28 = (v28 + 1) % 256;
v35 = (unsigned __int8)s[v28];
v30 = (v30 + v35) % 256;
s[v28] = s[v30];
s[v30] = v35;
v17 = (char *)(unsigned __int8)s[v28];
rc4_result[i] = s[(unsigned __int8)(v35 + (BYTE)v17)] ^ input[i];
//if (rc4_result[i] >= 128)
//rc4_result[i] -= 128;
printf("%c", rc4_result[i]);
}

base64部分

#include <stdio.h>
#include <string.h>
#include "base64.h"
/** 在字符串中查询特定字符位置索引
* const char *str ,字符串
* char c,要查找的字符
*/ 
const char * base64char = "\x21\x3A\x23\x24\x25\x26\x28\x29\x2B\x2D\x2A\x20\x60\x7E\x5F\x5B\x5D\x7B\x7D\x3F\x3C\x3E\x2C\x2E\x40\x5E\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x5C\x27\x3B";
const char padding_char = '=';
static char cmove_bits(unsigned char src, unsigned lnum, unsigned rnum) {
src <<= lnum; // src = src << lnum;
src >>= rnum; // src = src >> rnum;
return src;
}
/* 解码
* const char * base64 码字
* unsigned char * dedata, 解码恢复的数据
*/
int base64_decode(const char * base64, unsigned char * dedata) 
{ 
int i = 0, j=0;
int trans[4] = {0,0,0,0}; 
for (;base64[i]!='\0';i+=4){ 
// 每四个一组,译码成三个字符 
trans[0] = num_strchr(base64char, base64[i]);
trans[1] = num_strchr(base64char, base64[i+1]); // 1/3 
dedata[j++] = ((trans[0] << 2) & 0xfc) | ((trans[1]>>4) & 0x03); 
if (base64[i+2] == ';'){ continue; } 
else{ trans[2] = num_strchr(base64char, base64[i + 2]); } // 2/3 
dedata[j++] = ((trans[1] << 4) & 0xf0) | ((trans[2] >> 2) & 0x0f); 
if (base64[i + 3] == ';'){ continue; } 
else{ trans[3] = num_strchr(base64char, base64[i + 3]); 
} // 3/3 
dedata[j++] = ((trans[2] << 6) & 0xc0) | (trans[3] & 0x3f); } 
dedata[j] = '\0'; 
return 0; 
}
int main() { 
char str1[] = "\xfd\x1e\x8a\x4e\x9\xca\x90\x3\xe7\xf1\x85\x9f\9b\xf7\x83\x3e\xe\x0";
char str2[25] = {0}; //注意长度要给够
int len = 0;
base64_encode(str1,(int)strlen(str1),str2,&len);
printf("len = %d\n",len);
for(int i=0;i<18;i++)
{   printf("%x\n",str2[i]);    }
char str[] ="\x20\x7b\x39\x2A\x38\x67\x61\x2A\x6C\x21\x54\x6E\x3F\x40\x23\x66\x6A\x27\x6A\x24\x5C\x67\x3B\x3B";
for(int i=0;i<24;i++)
{   if(i%4==0)
str[i]^=7;
if(i%4==2)
str[i]^=0xf;    
}
char dedata[128];
base64_decode(str,(unsigned char*)dedata); 
printf("译码:%d",strlen(dedata)); 
for(int i=0;i<18;i++)
{   printf("%x\n",dedata[i]);
}
getchar(); 
getchar(); return 0;}