2019 KCTF 总决赛 | 第七题《东北奇闻》点评及解题思路
2019-12-19 19:09:00 Author: mp.weixin.qq.com(查看原文) 阅读量:68 收藏


第七道题《东北奇闻》历时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

static const 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
};
 
static const 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
};
 
 
 
static const 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
};
 
static const 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];
 
 





 
 
    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_t len = 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;
  unsigned int *v3;
  unsigned int v4;
  unsigned int v5;
  unsigned int v6;
  unsigned int v7;
  int v8;
  unsigned int v9;
  int v10;
  unsigned int v11;
  int v12;
  unsigned int v13;
  int v14;
  unsigned int v15;
  int v16;
  unsigned int v17;
  int v18;
  unsigned int v19;
  int v20;
  unsigned int v21;
  int v22;
  unsigned int v23;
  int v24;
  unsigned int v25;
  int v26;
  unsigned int v27;
  unsigned int v28;
  unsigned int v29;
  unsigned int v30;
  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};
  
  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}
6
合作伙伴

 

上海第五空间信息科技研究院】(简称:第五空间)是经上海市社会组织管理局批准成立,上海市科协作为业务主管部门的新型研发机构,由翼盾智能科技创始人积聚社会力量发起成立,立足科技事业,支撑国家战略,开展科技研究,推进协同创新。

 

杭州安恒信息技术股份有限公司】(简称:安恒信息)成立于2007年,科创板股票代码:688023,一直专注于网络信息安全领域,公司主营业务为网络信息安全产品的研发、生产及销售,并为客户提供专业的网络信息安全服务。公司的产品及服务涉及应用安全、大数据安全、云安全、物联网安全、工业控制安全及工业互联网安全等领域。



第八题《龙都星劫》目前尚无人攻破
快来争夺一血吧!
戳查看更多Write Up

文章来源: http://mp.weixin.qq.com/s?__biz=MjM5NTc2MDYxMw==&amp;mid=2458302107&amp;idx=1&amp;sn=cf843ca40fc7464dce1ae6cb7a03ff72&amp;chksm=b181861186f60f07669c78587994f2400609636e39769e765ea7a31abd43cf50870f3d3f6250#rd
如有侵权请联系:admin#unsafe.sh