HZNUCTF2024初赛

文章讲述了在逆向工程中,如何利用IDA工具分析64位程序,查找字符串,解密base64和AES,以及应用Tea加密算法,解决AndroidShell挑战中的flag。涉及到了字符串操作、函数跟踪和加密算法的运用。
摘要由CSDN通过智能技术生成

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}

  • 26
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值