首页
社区
课程
招聘
[推荐]2019 KCTF 总决赛 | 第七题《东北奇闻》点评及解题思路
发表于: 2019-12-19 18:16 4804

[推荐]2019 KCTF 总决赛 | 第七题《东北奇闻》点评及解题思路

2019-12-19 18:16
4804


第七道题《东北奇闻》历时2天,已于17号中午12点关闭攻击通道。此题共有941人围观,最终共有8支战队攻破。


1、题目简介


“老弟,你搁这儿干哈呢?坐这儿小心一会儿撞到你把波棱盖儿卡马路牙子上秃噜皮了。”“大姐我刚来还不认识路呢。”没想到这次居然来到了东北。好歹我也是六级的鸡米花了,对于系统的套路还是比较了解的,一般来跟我打招呼的都会是我这次任务的对象。“夜晚在外面不安全,麻利地跟大姐回家,吃顿热乎的饭。”看着眼前热情的大姐,我就跟她回家去了。原来大姐一家是卖豆花的,我端着一碗豆花对她家仔细打量起来。厅堂正中的桌子四四方方,上面摆着一个绿皮挂钟,墙上挂着一把鲜红的尺子,门上都贴着崭新的符纸,我仔细分辨一下上面似乎写着“与天同寿”。深夜,我在热乎乎的炕上被什么声音吵醒,门外传来一阵阵整齐的脚步声,挂钟响了十二下,我从窗口向外望去,来时的冷清的街道灯火辉煌,人声鼎沸,这些人在做些什么?难道是非法交易?房间里的符纸又是什么意思?不行,我得一探究竟。

[说明:本题是一道Android题]


本道题一开赛,各个战队争分夺秒,凝聚团队智慧,凭借强大实力向榜首前进!赛况激烈,异彩纷呈。

接下来让我们一起来看一下这道题的点评和详细解析吧。



2、看雪评委crownless点评


这是一道jni题。so做了一些混淆,字符串加密可以干扰静态分析。这对选手破解赛题构成了挑战。


这道题主要考察了动态调试的能力和密码学算法的领悟能力。



3、出题团队简介


本题出题战队 ech0:



队长卓桐个人简介:野生Android程序员。



4、设计思路


比较忙,没时间写新题了,炒一下冷饭吧。

分析流程


java层比较简单,直接看so,动态注册jni函数。


但是加了类似花指令的效果,对静态分析有些影响,对其进行一些修复,或者直接动态调试。


对其进行修复,可以查看伪代码:


JNI_OnLoad注册jni函数:


或者通过给出的提示,直接通过字符串定位到jni函数:


分析该jni函数主要获取用户输入的字符串,调用加密函数。



加密函数


可以对函数进行修复:



首先设置一个16字节的key,然后进行25次加密,根据数组长度200和8得出,动态调试知道为分块加密,一块为8个字节,加密后也是8字节。

对加密后的字节格式化为hex形式的字符串,和预置的字符串比较,如果相同弹出字符串:
Correct flag = flag{…}

解密


用于比较的解密后的字符串为:

68dd8a0f7065609e3106fb2bb1059423e80fb1347318ffeb83b8a074a7e6c9cfd9b426919547bcfcd9b426919547bcfcd9b426919547bcfcd9b426919547bcfcd9b426919547bcfcd9b426919547bcfcd9b426919547bcfcd9b426919547bcfcd9b426919547bcfcd9b426919547bcfcd9b426919547bcfcd9b426919547bcfcd9b426919547bcfcd9b426919547bcfcd9b426919547bcfcd9b426919547bcfcd9b426919547bcfcd9b426919547bcfcd9b426919547bcfcd9b426919547bcfcd9b426919547bcfc


从后往前观察发现16个字符为一组,后面的都是相同的字符串,得出d9b426919547bcfc为8个0加密后的值,所以其实需要解密的是:

68dd8a0f7065609e3106fb2bb1059423e80fb1347318ffeb83b8a074a7e6c9cf

明文应该为25-32个字节,格式为flag{}。

逆向加密代码:


分析并不需要逆向所有代码,比如有16字节的key得到32*4字节的key的过程就可以省略,直接动态调试得到。

最后加密后的8个字节,每个字节都会被一个函数改变,这个函数被人工混淆和使用工具混淆过了,其实根本不用去逆,因为传入一个字节得到一个字节,范围总共256,那么只需要遍历256次,通过hook等都可以,得到一个0-255的对应的表。

把68dd8a0f7065609e3106fb2bb1059423e80fb1347318ffeb83b8a074a7e6c9cf
查表替换得到fb4e45306acaeae7c2232d529720f743ae3097e269910fad56841548349ceccf

staticconst u32 sbox1[256] = {
        0x01010400,0x00000000,0x00010000,0x01010404,
        0x01010004,0x00010404,0x00000004,0x00010000,
        0x00000400,0x01010400,0x01010404,0x00000400,
        0x01000404,0x01010004,0x01000000,0x00000004,
        0x00000404,0x01000400,0x01000400,0x00010400,
        0x00010400,0x01010000,0x01010000,0x01000404,
        0x00010004,0x01000004,0x01000004,0x00010004,
        0x00000000,0x00000404,0x00010404,0x01000000,
        0x00010000,0x01010404,0x00000004,0x01010000,
        0x01010400,0x01000000,0x01000000,0x00000400,
        0x01010004,0x00010000,0x00010400,0x01000004,
        0x00000400,0x00000004,0x01000404,0x00010404,
        0x01010404,0x00010004,0x01010000,0x01000404,
        0x01000004,0x00000404,0x00010404,0x01010400,
        0x00000404,0x01000400,0x01000400,0x00000000,
        0x00010004,0x00010400,0x00000000,0x01010004,
 
 
        0x80108020,0x80008000,0x00008000,0x00108020,
        0x00100000,0x00000020,0x80100020,0x80008020,
        0x80000020,0x80108020,0x80108000,0x80000000,
        0x80008000,0x00100000,0x00000020,0x80100020,
        0x00108000,0x00100020,0x80008020,0x00000000,
        0x80000000,0x00008000,0x00108020,0x80100000,
        0x00100020,0x80000020,0x00000000,0x00108000,
        0x00008020,0x80108000,0x80100000,0x00008020,
        0x00000000,0x00108020,0x80100020,0x00100000,
        0x80008020,0x80100000,0x80108000,0x00008000,
        0x80100000,0x80008000,0x00000020,0x80108020,
        0x00108020,0x00000020,0x00008000,0x80000000,
        0x00008020,0x80108000,0x00100000,0x80000020,
        0x00100020,0x80008020,0x80000020,0x00100020,
        0x00108000,0x00000000,0x80008000,0x00008020,
        0x80000000,0x80100020,0x80108020,0x00108000,
 
 
        0x00000208,0x08020200,0x00000000,0x08020008,
        0x08000200,0x00000000,0x00020208,0x08000200,
        0x00020008,0x08000008,0x08000008,0x00020000,
        0x08020208,0x00020008,0x08020000,0x00000208,
        0x08000000,0x00000008,0x08020200,0x00000200,
        0x00020200,0x08020000,0x08020008,0x00020208,
        0x08000208,0x00020200,0x00020000,0x08000208,
        0x00000008,0x08020208,0x00000200,0x08000000,
        0x08020200,0x08000000,0x00020008,0x00000208,
        0x00020000,0x08020200,0x08000200,0x00000000,
        0x00000200,0x00020008,0x08020208,0x08000200,
        0x08000008,0x00000200,0x00000000,0x08020008,
        0x08000208,0x00020000,0x08000000,0x08020208,
        0x00000008,0x00020208,0x00020200,0x08000008,
        0x08020000,0x08000208,0x00000208,0x08020000,
        0x00020208,0x00000008,0x08020008,0x00020200,
 
 
        0x00802001,0x00002081,0x00002081,0x00000080,
        0x00802080,0x00800081,0x00800001,0x00002001,
        0x00000000,0x00802000,0x00802000,0x00802081,
        0x00000081,0x00000000,0x00800080,0x00800001,
        0x00000001,0x00002000,0x00800000,0x00802001,
        0x00000080,0x00800000,0x00002001,0x00002080,
        0x00800081,0x00000001,0x00002080,0x00800080,
        0x00002000,0x00802080,0x00802081,0x00000081,
        0x00800080,0x00800001,0x00802000,0x00802081,
        0x00000081,0x00000000,0x00000000,0x00802000,
        0x00002080,0x00800080,0x00800081,0x00000001,
        0x00802001,0x00002081,0x00002081,0x00000080,
        0x00802081,0x00000081,0x00000001,0x00002000,
        0x00800001,0x00002001,0x00802080,0x00800081,
        0x00002001,0x00002080,0x00800000,0x00802001,
        0x00000080,0x00800000,0x00002000,0x00802080
};
 
staticconst u32 sbox2[256] = {
        0x00000100,0x02080100,0x02080000,0x42000100,
        0x00080000,0x00000100,0x40000000,0x02080000,
        0x40080100,0x00080000,0x02000100,0x40080100,
        0x42000100,0x42080000,0x00080100,0x40000000,
        0x02000000,0x40080000,0x40080000,0x00000000,
        0x40000100,0x42080100,0x42080100,0x02000100,
        0x42080000,0x40000100,0x00000000,0x42000000,
        0x02080100,0x02000000,0x42000000,0x00080100,
        0x00080000,0x42000100,0x00000100,0x02000000,
        0x40000000,0x02080000,0x42000100,0x40080100,
        0x02000100,0x40000000,0x42080000,0x02080100,
        0x40080100,0x00000100,0x02000000,0x42080000,
        0x42080100,0x00080100,0x42000000,0x42080100,
        0x02080000,0x00000000,0x40080000,0x42000000,
        0x00080100,0x02000100,0x40000100,0x00080000,
        0x00000000,0x40080000,0x02080100,0x40000100,
 
 
        0x20000010,0x20400000,0x00004000,0x20404010,
        0x20400000,0x00000010,0x20404010,0x00400000,
        0x20004000,0x00404010,0x00400000,0x20000010,
        0x00400010,0x20004000,0x20000000,0x00004010,
        0x00000000,0x00400010,0x20004010,0x00004000,
        0x00404000,0x20004010,0x00000010,0x20400010,
        0x20400010,0x00000000,0x00404010,0x20404000,
        0x00004010,0x00404000,0x20404000,0x20000000,
        0x20004000,0x00000010,0x20400010,0x00404000,
        0x20404010,0x00400000,0x00004010,0x20000010,
        0x00400000,0x20004000,0x20000000,0x00004010,
        0x20000010,0x20404010,0x00404000,0x20400000,
        0x00404010,0x20404000,0x00000000,0x20400010,
        0x00000010,0x00004000,0x20400000,0x00404010,
        0x00004000,0x00400010,0x20004010,0x00000000,
        0x20404000,0x20000000,0x00400010,0x20004010,
 
 
        0x00200000,0x04200002,0x04000802,0x00000000,
        0x00000800,0x04000802,0x00200802,0x04200800,
        0x04200802,0x00200000,0x00000000,0x04000002,
        0x00000002,0x04000000,0x04200002,0x00000802,
        0x04000800,0x00200802,0x00200002,0x04000800,
        0x04000002,0x04200000,0x04200800,0x00200002,
        0x04200000,0x00000800,0x00000802,0x04200802,
        0x00200800,0x00000002,0x04000000,0x00200800,
        0x04000000,0x00200800,0x00200000,0x04000802,
        0x04000802,0x04200002,0x04200002,0x00000002,
        0x00200002,0x04000000,0x04000800,0x00200000,
        0x04200800,0x00000802,0x00200802,0x04200800,
        0x00000802,0x04000002,0x04200802,0x04200000,
        0x00200800,0x00000000,0x00000002,0x04200802,
        0x00000000,0x00200802,0x04200000,0x00000800,
        0x04000002,0x04000800,0x00000800,0x00200002,
 
 
        0x10001040,0x00001000,0x00040000,0x10041040,
        0x10000000,0x10001040,0x00000040,0x10000000,
        0x00040040,0x10040000,0x10041040,0x00041000,
        0x10041000,0x00041040,0x00001000,0x00000040,
        0x10040000,0x10000040,0x10001000,0x00001040,
        0x00041000,0x00040040,0x10040040,0x10041000,
        0x00001040,0x00000000,0x00000000,0x10040040,
        0x10000040,0x10001000,0x00041040,0x00040000,
        0x00041040,0x00040000,0x10041000,0x00001000,
        0x00000040,0x10040040,0x00001000,0x00041040,
        0x10001000,0x00000040,0x10000040,0x10040000,
        0x10040040,0x10000000,0x00040000,0x10001040,
        0x00000000,0x10041040,0x00040040,0x10000040,
        0x10040000,0x10001000,0x10001040,0x00000000,
        0x10041040,0x00041000,0x00041000,0x00001040,
        0x00001040,0x00040040,0x10000000,0x10041000
};
 
 
 
staticconst u32 sbox3[256] = {
        0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5,0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76,
        0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0,0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0,
        0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc,0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15,
        0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a,0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75,
        0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0,0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84,
        0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b,0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf,
        0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85,0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8,
        0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5,0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2,
        0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17,0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73,
        0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88,0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb,
        0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c,0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79,
        0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9,0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08,
        0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6,0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a,
        0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e,0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e,
        0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94,0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf,
        0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68,0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16
};
 
staticconst u32 sbox4[256] = {
        0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38,0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb,
        0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87,0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb,
        0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d,0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e,
        0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2,0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25,
        0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16,0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92,
        0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda,0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84,
        0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a,0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06,
        0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02,0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b,
        0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea,0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73,
        0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85,0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e,
        0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89,0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b,
        0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20,0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4,
        0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31,0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f,
        0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d,0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef,
        0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0,0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61,
        0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26,0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d
};
 
 
 
u32 xkey[32] = {
        0xd573f1e4,0xfa05e8a8,0x2c6d872d,0xc193bc8f,
        0x18c94337,0x64bc5c3a,0x8f4696c2,0x384c937c,
        0xb658582a,0x78f874ca,0x258bf885,0x6d208f8a,
        0x5cd503d7,0xd4fa1e37,0x93dd1be,0x507f2a3e,
        0x10,0x11,0x6,0xa,
        0x16,0x1d,0x1a,0x13,
        0xb,0x3,0x1c,0x0,
        0x1d,0x10,0x19,0x1b,
};
 
#define U8a(x) ( (u8) (x>>24) )
#define U8b(x) ( (u8) (((x)>>16)&255) )
#define U8c(x) ( (u8) (((x)>>8)&255) )
#define U8d(x) ( (u8) ((x)&255) )
 
 
#define ROL(x, n) ( ((x)<<(n)) | ((x)>>(32-(n))) )
 
 
#define F1(l, r, i) \
    t = ROL(key[i] + r, key[i+16]); \
    l ^= ((sbox1[U8a(t)] ^ sbox2[U8b(t)]) \
     - sbox3[U8c(t)]) + sbox4[U8d(t)];
#define F2(l, r, i) \
    t = ROL(key[i] ^ r, key[i+16]); \
    l ^= ((sbox1[U8a(t)] - sbox2[U8b(t)]) \
     + sbox3[U8c(t)]) ^ sbox4[U8d(t)];
#define F3(l, r, i) \
    t = ROL(key[i] - r, key[i+16]); \
    l ^= ((sbox1[U8a(t)] + sbox2[U8b(t)]) \
     ^ sbox3[U8c(t)]) - sbox4[U8d(t)];
 
 
void mcrypt_decrypt(u32 *key, u8 * block)
{
    u32 t, l, r;
 
 
    r = ((u32) block[0] <<24) | ((u32) block[1] <<16)
        | ((u32) block[2] <<8) | (u32) block[3];
    l = ((u32) block[4] <<24) | ((u32) block[5] <<16)
        | ((u32) block[6] <<8) | (u32) block[7];
 
 
// v9 = __ROR4__(*v3 + v8, 32 - v3[16]);
// v10 = v6 ^ ((dword_2A410[(v9 >> 16) & 0xFF] ^ dword_2A010[v9 >> 24])
// - dword_2A810[(unsigned __int16)v9 >> 8]
// + dword_2AC10[(unsigned __int8)v9]);
// v11 = __ROR4__(v10 ^ v3[1], 32 - v3[17]);
 
 
    F3(r, l,11);
    F2(l, r,10);
    F1(r, l,9);
 
    F3(l, r,8);
    F2(r, l,7);
    F1(l, r,6);
 
    F3(r, l,5);
    F2(l, r,4);
    F1(r, l,3);
 
    F3(l, r,2);
    F2(r, l,1);
    F1(l, r,0);
 
    block[0] = U8a(l);
    block[1] = U8b(l);
    block[2] = U8c(l);
    block[3] = U8d(l);
    block[4] = U8a(r);
    block[5] = U8b(r);
    block[6] = U8c(r);
    block[7] = U8d(r);
 
    t = l = r =0;
}
 
 
static void Hex2Char(const char *szHex, unsigned char *rch)
{
    int i;
    for(i=0; i<2; i++)
    {
        if(*(szHex + i) >='0' && *(szHex + i) <='9')
            *rch = (*rch <<4) + (*(szHex + i) -'0');
        else if(*(szHex + i) >='a' && *(szHex + i) <='f')
            *rch = (*rch <<4) + (*(szHex + i) -'a' +10);
        else
            break;
    }
}
 
void HexStr2CharStr(const char *pszHexStr,int iSize, unsigned char *pucCharStr)
{
    int i;
    unsigned char ch;
    if (iSize%2 !=0)return;
    for(i=0; i<iSize/2; i++)
    {
        Hex2Char(pszHexStr+2*i, &ch);
        pucCharStr[i] = ch;
    }
}
 
 
 
 
int main(){
     
 
    int blocksize =8, j;
 
    const char *code ="68dd8a0f7065609e3106fb2bb1059423e80fb1347318ffeb83b8a074a7e6c9cf";
    code ="fb4e45306acaeae7c2232d529720f743ae3097e269910fad56841548349ceccf";
    size_tlen = strlen(code) /2;
    u8 *encode = static_cast<u8 *>(malloc(len+1));
    HexStr2CharStr(code, strlen(code), encode);
 
 
 
    for (int i =0; i <4; ++i) {
        mcrypt_decrypt(xkey, (u8 *) encode + i * blocksize);
    }
 
 
    encode[len] =0;
 
    printf("%s == %s\n", encode, code);
    return 0;
}

得到flag:flag{9eca5de49470144c1694f6}

5、解题思路


本题解题思路由打打酱油战队 梦游枪手 提供:



用jadx查看apk,找到MainActivity。



public class MainActivity extends AppC0mpatActivity {
    protected void onCreate(final Bundle bundle) {
        super.onCreate(bundle);
        setContentView((int) R.layout.activity_main);
        final EditText editText = (EditText) findViewById(R.id.ed);
        ((Button) findViewById(R.id.bt)).setOnClickListener(new OnClickListener() {
            public void onClick(View view) {
                if (editText.getText() ==null || TextUtils.isEmpty(editText.getText().toString()) !=null || MainActivity.this.showAssist(bundle) !=null) {
                    Toast.makeText(MainActivity.this,"null",1).show();
                }
            }
        });
    }
}


前两个条件是判空,所以直接查看MainActivity.this.showAssist,发现是个native方法,故转而分析libnative-lib.so。


so做了一些混淆以及字符串加密,干扰静态分析。



但没有反调试,可以真机调试找出showAssist的地址。


我是选择用frida hook RegisterNatives函数,输出showAssist的地址。



在00019F80处下断,运行程序输入flag就能停下了。


大致流程为,申请200字节大小的空间,将输入的flag写到那个空间 ,每8字节一组加密。再与内置的结果比较。



后面都是0加密的结果,也就是说flag加密后与"68dd8a0f7065609e3106fb2bb1059423e80fb1347318ffeb83b8a074a7e6c9cf"相同则通过。


直接抠加密函数sub_9CB0代码,将下面的混淆代码nop掉就能F5了。



部分伪代码如下:


v7 =__ROR4__(*encrypt + flag4, 32 - encrypt[16]);
  v8 = flag0 ^ ((des2[(v7 >> 16) & 0xFF] ^ des1[v7 >> 24]) - S[(unsigned__int16)v7 >> 8] + S2[(unsigned __int8)v7]);
  v9 =__ROR4__(v8 ^ encrypt[1], 32 - encrypt[17]);
  v10 = (des1[v9 >> 24] - des2[(v9 >> 16) & 0xFF] + S[(unsigned__int16)v9 >> 8]) ^ flag4 ^ S2[(unsigned __int8)v9];
  v11 =__ROR4__(encrypt[2] - v10, 32 - encrypt[18]);
  v12 = (((des2[(v11 >> 16) & 0xFF] + des1[v11 >> 24]) ^ S[(unsigned__int16)v11 >> 8]) - S2[(unsigned __int8)v11]) ^ v8;
  v13 =__ROR4__(v12 + encrypt[3], 32 - encrypt[19]);
  v14 = (S2[(unsigned__int8)v13] + (des2[(v13 >> 16) & 0xFF] ^ des1[v13 >> 24]) - S[(unsigned __int16)v13 >> 8]) ^ v10;
  v15 =__ROR4__(encrypt[4] ^ v14, 32 - encrypt[20]);
  v16 = S2[(unsigned__int8)v15] ^ v12 ^ (des1[v15 >> 24] - des2[(v15 >> 16) & 0xFF] + S[(unsigned __int16)v15 >> 8]);
  v17 =__ROR4__(encrypt[5] - v16, 32 - encrypt[21]);
  v18 = v14 ^ (((des1[v17 >> 24] + des2[(v17 >> 16) & 0xFF]) ^ S[(unsigned__int16)v17 >> 8]) - S2[(unsigned __int8)v17]);
  v19 =__ROR4__(encrypt[6] + v18, 32 - encrypt[22]);
  v20 = v16 ^ ((des2[(v19 >> 16) & 0xFF] ^ des1[v19 >> 24]) - S[(unsigned__int16)v19 >> 8] + S2[(unsigned __int8)v19]);
  v21 =__ROR4__(encrypt[7] ^ v20, 32 - encrypt[23]);
  v22 = S2[(unsigned__int8)v21] ^ v18 ^ (des1[v21 >> 24] - des2[(v21 >> 16) & 0xFF] + S[(unsigned __int16)v21 >> 8]);
  v23 =__ROR4__(encrypt[8] - v22, 32 - encrypt[24]);
  v24 = v20 ^ (((des2[(v23 >> 16) & 0xFF] + des1[v23 >> 24]) ^ S[(unsigned__int16)v23 >> 8]) - S2[(unsigned __int8)v23]);
  v25 =__ROR4__(encrypt[9] + v24, 32 - encrypt[25]);
  v26 = v22 ^ ((des1[v25 >> 24] ^ des2[(v25 >> 16) & 0xFF]) - S[(unsigned__int16)v25 >> 8] + S2[(unsigned __int8)v25]);
  v27 =__ROR4__(encrypt[10] ^ v26, 32 - encrypt[26]);
  v28 = (des1[v27 >> 24] - des2[(v27 >> 16) & 0xFF] + S[(unsigned__int16)v27 >> 8]) ^ S2[(unsigned __int8)v27] ^ v24;
  v29 =__ROR4__(encrypt[11] - v28, 32 -*((_BYTE *)encrypt + 0x6C));
  v30 = ((S[(unsigned__int16)v29 >> 8] ^ (des1[v29 >> 24] + des2[(v29 >> 16) & 0xFF])) - S2[(unsigned __int8)v29]) ^ v26;
  *(_BYTE *)result = sub_DF18(v30 >> 24);
  *((_BYTE *)result + 1) = sub_DF18((v30 >> 16) & 0xFF);
  *((_BYTE *)result + 2) = sub_DF18((unsigned __int16)v30 >> 8);
  *((_BYTE *)result + 3) = sub_DF18((unsigned __int8)v30);
  *((_BYTE *)result + 4) = sub_DF18(v28 >> 24);
  *((_BYTE *)result + 5) = sub_DF18((v28 >> 16) & 0xFF);
  *((_BYTE *)result + 6) = sub_DF18((unsigned __int16)v28 >> 8);
  *((_BYTE *)result + 7) = sub_DF18((unsigned __int8)v28);

sub_DF18函数里面有更强的混淆,但是动态调试时发现只是一个字节变换,可以写个脚本抠出[0,255]的变换结果,然后写代码输出解密用的表。


加密部分的代码看起来有点乱,但是仔细钻研了下,发现其实是花式xor。返回的加密结果其实就是v28和v30,已知v28和v30可以求出v29,之后用v26 =  ((S[(unsigned __int16)v29 >> 8] ^ (des1[v29 >> 24] + des2[(v29 >> 16) & 0xFF])) - S2[(unsigned __int8)v29]) ^ v30;
求出v26的值,以此类推,就能还原出flag了。


其他的表可以直接导出,弄一份可编译的C代码,完整代码见附件。


int decryptstring(unsigned char* buffer)
{
  int v2;// r10
  unsigned int *v3;// ST00_4
  unsigned int v4;// r5
  unsigned int v5;// r11
  unsigned int v6;// r8
  unsigned int v7;// r2
  int v8;// r11
  unsigned int v9;// r4
  int v10;// r8
  unsigned int v11;// r5
  int v12;// lr
  unsigned int v13;// r6
  int v14;// r12
  unsigned int v15;// r5
  int v16;// lr
  unsigned int v17;// r6
  int v18;// r12
  unsigned int v19;// r6
  int v20;// lr
  unsigned int v21;// r5
  int v22;// r12
  unsigned int v23;// r6
  int v24;// lr
  unsigned int v25;// r6
  int v26;// r12
  unsigned int v27;// r5
  unsigned int v28;// r4
  unsigned int v29;// r5
  unsigned int v30;// r6
  unsigned int result1;
  unsigned int result2;
  unsigned int flag0;
  unsigned int flag4;
  unsigned char enc[9]={0};
  for (int i =0; i <4; ++i)
  {
    enc[i]=ctable2[buffer[i]];
    enc[4+i]=ctable2[buffer[4+i]];
  }
  result1 = (enc[0]<<24)+(enc[1]<<16)+(enc[2]<<8)+enc[3];
  result2 = (enc[4]<<24)+(enc[5]<<16)+(enc[6]<<8)+enc[7];
  v30 = result1;
  v28 = result2;
  v29 = ror(encrypt[11] - v28,32 - *((unsigned char *)encrypt +0x6C));
  v26 = v30 ^ ((S[(unsigned short)v29 >>8] ^ (des1[v29 >>24] + des2[(v29 >>16) &0xFF])) - S2[(unsigned char)v29]);
  v27 = ror(encrypt[10] ^ v26,32 - encrypt[26]);
  v24 = v28 ^ (des1[v27 >>24] - des2[(v27 >>16) &0xFF] + S[(unsigned short)v27 >>8]) ^ S2[(unsigned char)v27];
  v25 = ror(encrypt[9] + v24,32 - encrypt[25]);
  v22 = v26 ^ ((des1[v25 >>24] ^ des2[(v25 >>16) &0xFF]) - S[(unsigned short)v25 >>8] + S2[(unsigned char)v25]);
  v23 = ror(encrypt[8] - v22,32 - encrypt[24]);
  v20 = v24 ^ (((des2[(v23 >>16) &0xFF] + des1[v23 >>24]) ^ S[(unsigned short)v23 >>8]) - S2[(unsigned char)v23]);
  v21 = ror(encrypt[7] ^ v20,32 - encrypt[23]);
  v18 = v22 ^ S2[(unsigned char)v21] ^ (des1[v21 >>24] - des2[(v21 >>16) &0xFF] + S[(unsigned short)v21 >>8]);
  v19 = ror(encrypt[6] + v18,32 - encrypt[22]);
  v16 = v20 ^ ((des2[(v19 >>16) &0xFF] ^ des1[v19 >>24]) - S[(unsigned short)v19 >>8] + S2[(unsigned char)v19]);
  v17 = ror(encrypt[5] - v16,32 - encrypt[21]);
  v14 = v18 ^ (((des1[v17 >>24] + des2[(v17 >>16) &0xFF]) ^ S[(unsigned short)v17 >>8]) - S2[(unsigned char)v17]);
  v15 = ror(encrypt[4] ^ v14,32 - encrypt[20]);
  v12 = v16 ^ S2[(unsigned char)v15] ^ (des1[v15 >>24] - des2[(v15 >>16) &0xFF] + S[(unsigned short)v15 >>8]);
  v13 = ror(v12 + encrypt[3],32 - encrypt[19]);
  v10 = v14 ^ (S2[(unsigned char)v13] + (des2[(v13 >>16) &0xFF] ^ des1[v13 >>24]) - S[(unsigned short)v13 >>8]);
  v11 = ror(encrypt[2] - v10,32 - encrypt[18]);
  v8 = v12 ^ (((des2[(v11 >>16) &0xFF] + des1[v11 >>24]) ^ S[(unsigned short)v11 >>8]) - S2[(unsigned char)v11]);
  v9 = ror(v8 ^ encrypt[1],32 - encrypt[17]);
  flag4 = v10 ^ (des1[v9 >>24] - des2[(v9 >>16) &0xFF] + S[(unsigned short)v9 >>8]) ^ S2[(unsigned char)v9];
  v7 = ror(*encrypt + flag4,32 - encrypt[16]);
  flag0 = v8 ^ ((des2[(v7 >>16) &0xFF] ^ des1[v7 >>24]) - S[(unsigned short)v7 >>8] + S2[(unsigned char)v7]);
  for (int i =0; i <4; ++i)
  {
    enc[i]=(flag0>>((3-i)*8))&0xff;
    enc[4+i]=(flag4>>((3-i)*8))&0xff;
  }
  printf("%s",enc);
  return 0;
}
int main(int argc,char const *argv[])
{
  unsigned char buffer[9]={0};
  //"68dd8a0f7065609e3106fb2bb1059423e80fb1347318ffeb83b8a074a7e6c9cf"
  unsigned char str1[8]={0x68,0xdd,0x8a,0x0f,0x70,0x65,0x60,0x9e};
  unsigned char str2[8]={0x31,0x06,0xfb,0x2b,0xb1,0x05,0x94,0x23};
  unsigned char str3[8]={0xe8,0x0f,0xb1,0x34,0x73,0x18,0xff,0xeb};
  unsigned char str4[8]={0x83,0xb8,0xa0,0x74,0xa7,0xe6,0xc9,0xcf};
  decryptstring(str1);
  decryptstring(str2);
  decryptstring(str3);
  decryptstring(str4);
  printf("\n");
  return 0;
}

将"68dd8a0f7065609e3106fb2bb1059423e80fb1347318ffeb83b8a074a7e6c9cf"拆成四组分别解密就得到flag了。


flag:flag{9eca5de49470144c1694f6}


#END

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2019-12-31 15:45 被kanxue编辑 ,原因:
收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//