我们首先使用jeb进行分析,搜索关键词success定位到逻辑
外层函数是一个魔改tea,过了前32字节检测才能进入下一个函数进行判断
即可得到前32位的正确数据,将后面的测试数据放在>后继续在H0.a.successWithString()中进行二轮check
进入这个函数即可看到两个[256]的sbox,将部分数据搜索即可知为twofish算法
找到源码与jeb里的很相似
[link]:https://android.googlesource.com/platform/tools/base/+/master/jobb/src/main/java/Twofish/Twofish_Algorithm.java
我们在H0.a.c处下断点动调获取key
即可得到twofish的key
根据代码可知有两段data[16],我们可以对v2[15]下断点得到所有的data
即可得到前半段flag,我们将前半部分flag输入进去再进行check即可得到part2的check
Come on you are about to get it>flag{iT3N0t7H@tH111111111111111}
之后有对我们传入的测试值的flag的part2的异或数据提取出来(这第二段算法是rc4,直接将加密后的值异或回去即可得到)
将这段数据异或我们的输入再异或data2[16]即可还原得到第二段flag
这wp应该是出题人的预期解,本人走了许多弯路最终写出这份wp供大家学习
#include <iostream>
#include <cstdio>
#include <stdint.h> // For uint32_t
using
namespace
std;
void
tea_decrypt(uint32_t* v) {
uint32_t v0 = v[0], v1 = v[1], sum = 0xC6EF3720, i;
uint32_t delta = 0x9e3779b9;
uint32_t k[5] = { 598323648, 1213115916, 970832168, 274853062};
for
(i = 0; i < 32; i++) {
v1 -= (((v0 << 4) + k[2] ^ v0) + (sum ^ (v0 >> 5)) + k[3]);
v0 -= (((v1 << 4) + k[0] ^ v1) + (sum ^ (v1 >> 5)) + k[1]);
sum -= delta;
}
v[0] = v0;
v[1] = v1;
}
uint32_t switchEndian(uint32_t num) {
return
((num >> 24) & 0x000000FF) |
((num >> 8) & 0x0000FF00) |
((num << 8) & 0x00FF0000) |
((num << 24) & 0xFF000000);
}
int
main() {
uint32_t key[] = { 598323648, 1213115916, 970832168, 274853062 };
uint32_t data[] = {
0x5E5440B0, 2057046228, 0x4A1ED228, 0x233FE7C, 0x96461450, 0x88A670ED, 0xF79BFC89, 0x20C3D75F,0
};
for
(
int
i = 0; i < 8; i += 2) {
tea_decrypt(&data[i]);
}
for
(
int
i = 0; i < 8; ++i) {
data[i] = switchEndian(data[i]);
}
printf
(
"%s"
,data);
return
0;
}
#include <iostream>
#include <cstdio>
#include <stdint.h> // For uint32_t
using
namespace
std;
void
tea_decrypt(uint32_t* v) {
uint32_t v0 = v[0], v1 = v[1], sum = 0xC6EF3720, i;
uint32_t delta = 0x9e3779b9;
uint32_t k[5] = { 598323648, 1213115916, 970832168, 274853062};
for
(i = 0; i < 32; i++) {
v1 -= (((v0 << 4) + k[2] ^ v0) + (sum ^ (v0 >> 5)) + k[3]);
v0 -= (((v1 << 4) + k[0] ^ v1) + (sum ^ (v1 >> 5)) + k[1]);
sum -= delta;
}
v[0] = v0;
v[1] = v1;
}
uint32_t switchEndian(uint32_t num) {
return
((num >> 24) & 0x000000FF) |
((num >> 8) & 0x0000FF00) |
((num << 8) & 0x00FF0000) |
((num << 24) & 0xFF000000);
}
int
main() {
uint32_t key[] = { 598323648, 1213115916, 970832168, 274853062 };
uint32_t data[] = {
0x5E5440B0, 2057046228, 0x4A1ED228, 0x233FE7C, 0x96461450, 0x88A670ED, 0xF79BFC89, 0x20C3D75F,0
};
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
最后于 2024-11-30 17:59
被Aar0n编辑
,原因: