IDA
查壳
不是exe文件,是64位,用ida打开
得到第一段flag:HZNUCTF{W0w_u
根据题目意思,需要查找字符串,用shift+F12打开字符串界面
跟进,F5反汇编
函数名就是第三段flag,返回看该函数汇编代码
发现有一组字符,就是第四段flag
HZNUCTF{W0w_u_h@ve_l34rned_hOw_2_use_IDa_welcome_2_the_w0rld_of_rEver3e}
babyre
查壳
用32位ida打开
从“j_strlen(Str) == 34”可以看出,flag是34位的。前半截有17次与v15的判断,可知是flag的前17位,所以flag的后17位参与的是与v14的比较。
一.先求出前17位
这里是一连串的赋值,但是,对v16的前两位进行赋值时只赋值了一个字符,这样就差了一位,我们进汇编代码里面查询
方框里的两行对应的是对v16[0]和v16[1]的赋值,v16[1]赋值的数对应的码是0,所以没有显示为字符。根据“if ( (Str[i] ^ 0x31) != v15[i] )”编写代码求出前17位flag
二。求后17位
跟进sub_4110EB函数,
继续跟进sub_411398
跟进byte_41A000
是个base64加密,只需进行解密即可得到后17位
综上HZNUCTF{R3_1s_veRy_1nt3rest1ng@_@}
babyandriod
用jadx打开
输入的两个数组传进了logincheck函数,函数里面是判断,如果返回的结果是1就输出登
录成功否则输出登录失败,根据该判断方法编写解密脚本如下
a = [[214, 144, 233, 254, 204, 225, 61, 183, 22, 182, 20, 194, 40, 251, 44, 5],
[43, 103, 154, 118, 42, 190, 4, 195, 170, 68, 19, 38, 73, 134, 6, 153],
[156, 66, 80, 244, 145, 239, 152, 122, 51, 84, 11, 67, 237, 207, 172, 98],
[228, 179, 28, 169, 201, 8, 232, 149, 128, 223, 148, 250, 117, 143, 63, 166],
[71, 7, 167, 252, 243, 115, 23, 186, 131, 89, 60, 25, 230, 133, 79, 168],
[104, 107, 129, 178, 113, 100, 218, 139, 248, 235, 15, 75, 112, 86, 157, 53],
[30, 36, 14, 94, 99, 88, 209, 162, 37, 34, 124, 59, 1, 33, 120, 135],
[212, 0, 70, 87, 159, 211, 39, 82, 76, 54, 2, 231, 160, 196, 200, 158],
[234, 191, 138, 210, 64, 199, 56, 181, 163, 247, 242, 206, 249, 97, 21, 161],
[224, 174, 93, 164, 155, 52, 26, 85, 173, 147, 50, 48, 245, 140, 177, 227],
[29, 246, 226, 46, 130, 102, 202, 96, 192, 41, 35, 171, 13, 83, 78, 111],
[213, 219, 55, 69, 222, 253, 142, 47, 3, 255, 106, 114, 109, 108, 91, 81],
[141, 27, 175, 146, 187, 221, 188, 127, 17, 217, 92, 65, 31, 16, 90, 216],
[10, 193, 49, 136, 165, 205, 123, 189, 45, 116, 208, 18, 184, 229, 180, 176],
[137, 105, 151, 74, 12, 150, 119, 126, 101, 185, 241, 9, 197, 110, 198, 132],
[24, 240, 125, 236, 58, 220, 77, 32, 121, 238, 95, 62, 215, 203, 57, 72]
]
arr1 = [54, 211, 36, 120, 87, 37, 88, 120, 0, 34, 99, 135, 120, 162, 66, 66]
arr2 = [28, 228, 28, 201, 228, 169, 179, 232, 28, 228, 28, 201, 228, 169, 169, 228]
name = ''
key = ''
for i in range(0, 16):
for j in range(0, 16):
for k in range(0, 16):
if a[j][k] == arr1[i]:
name += chr(j*16+k)
elif a[j][k] == arr2[i]:
key += chr(j*16+k)
print("name = ", name)
print("key = ", key)
输出结果
name = yuanshenqidong!!
key = 2024031620240330
在显示登陆成功后还有一段代码
这里出现了一个checkflag函数,跟进去看
里面出现了AES,它是吧name当做key传入,而加密字符是
yjvAwO+OE3Ft5Fl5oK984D0xDlXTBMbvEuqno81AycYSGFnNZAQ4kwgU4n4p6MWh
放入解密工具里
HZNUCTF{welc0m3_2_4ndro1d_r3verse_?O.o_o.O?}
TupEA
无壳
用ida打开
在sub_41100A函数里进行了加密后在循环里做移位操作
跟进sub_41100A函数
这是一个tea加密算法。写脚本如下
#include<stdio.h>
#include<stdint.h>
void decrypt(uint32_t* v,uint32_t* key)
{
uint32_t k0,k2,k3,k1;
uint32_t v0,v1;
v0=v[0],v1=v[1];
k0=key[0],k1=key[1],k2=key[2],k3=key[3];
uint32_t delta=0xd33b470,sum=delta*32;
for(int i=0;i<32;i++)
{
v1-=((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
v0-=((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
sum-=delta;
}
v[0]=v0,v[1]=v1;
}
int main() {
char s[33] = {
0x4a, 0x9c, 0x16, 0xe3, 0xe9, 0x90, 0xb1, 0x49, 0x54, 0xa1,0x82,
0x9e, 0x3e, 0x3f, 0xc4, 0xae, 0x0c, 0x81, 0x20, 0x5f,0x40, 0xce,
0x51, 0xae, 0x3b, 0x52, 0x9b, 0xb0, 0xaa, 0xc1,0xf5, 0x53, };
uint32_t k[4] = { 2,0,2,4 };
for (int i = 0; i < 32; i += 8)
{
uint32_t v[2] = {*(uint32_t*)&s[i], *(uint32_t*)&s[i + 4]};
decrypt(v, k);
for (int j = 0; j < 2; j++)
{
for (int k = 0; k < 4; k++)
{
printf("%c", v[j] & 0xff);
v[j] >>= 8;
}
}
}
return 0;
}
运行出结果
运动的elf
根据字符串得到提示,本题要用到动态调试。由"HZNUCTF{"可知,括号里面的是flag.继续往下看
这个fun1函数是验证函数,跟进去看
由这里可知,返回值是v6和v7的异或。v6和v7初始值是1,是否改变取决于
要想返回值是1,则需要v6和v7二者有一个为1,v6和v7的值取决于v12和v11,向上追踪,
这里看出v11和v12是Xor()函数返回值,跟进Xor函数
发现它是比较字符串是否相等的函数,相等返回0,不同返回1
但是与v12不同的是, std::string::operator+=(v11, "#")说明v11在加了“#”后经过Xor函数返回值一定是1,故v6一定是0,所以v7必须是1,也就是v12一定是0,因为v12=v15,所以v15一定是0,而v15是v13和v14异或的结果,所以v13=v14,v13是输入的flag,所以flag是v14,因为std::string::basic_string(v14, &v[abi:cxx11]);所以v14就等于v数组,跟进v.
点进地址,
提取数据
HZNUCTF{66c7f0f462eeedd9d1f2d46bdc10e4e24167c4875cf2f7a2297da02b8f4ba8e0}