DASCTF 2024暑期挑战赛 Reverse writeup

DosSnake

没看

Strangeprograme

0x413D50处发现关键函数,分别解密DASCTF段和hook memcmp函数
请添加图片描述

在0x414b90处寻找DASCTF段地址并解密
请添加图片描述

解密完DASCTF段后跟进sub_411064(),修复函数

请添加图片描述

发现进行IAT Hook memcmp函数

请添加图片描述

疑似存在SEH反调试操作,检测到调试则不进行iathook,无法发现真实函数

直接运行exe,在输入前用本地附加调试即可绕过

请添加图片描述

跟进memcmp,发现真实函数

请添加图片描述

请添加图片描述

getflag脚本,首8字节作为异或key,后续每8字节一组异或,注意tea的轮次为16轮

#include<stdio.h>
void TeaDec(unsigned int* data, unsigned int* key)
{
    int result; // eax
    unsigned int i; // [esp+DCh] [ebp-2Ch]
    unsigned int v4; // [esp+E8h] [ebp-20h]
    unsigned int v5; // [esp+F4h] [ebp-14h]
    unsigned int v6; // [esp+100h] [ebp-8h]

    v6 = *data;
    v5 = data[1];
    v4 = 0;
    for (int i = 0; i < 16; i++) {
        v4 -= 0x61c88647;
    }
    for (i = 0; i < 16; ++i)
    {
        v4 += 0x61C88647;
        v5 -= (key[3] + (v6 >> 5)) ^ (v4 + v6) ^ (key[2] + 16 * v6);
        v6 -= (key[1] + (v5 >> 5)) ^ (v4 + v5) ^ (*key + 16 * v5);
    }
    *data = v6;
    data[1] = v5;
}
int main()
{
    unsigned char encflag[41] =
    {
      0xF9, 0x4D, 0x2B, 0xBC, 0x13, 0xDD, 0x13, 0x62, 0xC9, 0xFC,
      0xFF, 0x89, 0x7D, 0x4F, 0xC9, 0x0F, 0x63, 0x1D, 0x6D, 0x52,
      0x50, 0xFD, 0x41, 0xE3, 0x33, 0x76, 0x28, 0x97, 0x38, 0x36,
      0xF9, 0x6B, 0x90, 0x39, 0x14, 0x83, 0x2C, 0xE2, 0x2C, 0x1F,0
    };
    unsigned char TeaKey[16] =
    {
      0x78, 0x56, 0x34, 0x12, 0x12, 0x11, 0x10, 0x09, 0x16, 0x15,
      0x14, 0x13, 0x18, 0x17, 0x16, 0x15
    };
    unsigned int* phead = (unsigned int*)encflag;
    for (int i = 8; i >=2; i-=2) {
        *(unsigned int*)&encflag[4 * i + 4] ^= phead[1];
        *(unsigned int*)&encflag[4 * i] ^= phead[0];
        TeaDec(phead, TeaKey);
    }
    TeaDec(phead, TeaKey);
    printf("%s", encflag);
    return 0;
}

BabyAndroid

NoteActivity发现关键函数,逻辑如下:

  1. 解密并加载dex,获取encrypt方法
  2. 调用Native函数sendInit处理后使用encrypt加密数据
  3. 发送request

请添加图片描述

loadData方法,rc4解密dex,key=“DASCTF”

请添加图片描述

解密脚本,得到dex

import sys
from Crypto.Cipher import ARC4

def encrypt_file(input_file, output_file, key):
    with open(input_file, 'rb') as file:
        data = file.read()

    cipher = ARC4.new(key)
    encrypted_data = cipher.encrypt(data)

    with open(output_file, 'wb') as file:
        file.write(encrypted_data)

    print("Encryption completed. Encrypted file saved as", output_file)

input_file = 'Sex.jpg'
output_file = 'decrypted_Sex.dex'
key = b'DASCTF'

encrypt_file(input_file, output_file, key)

分析dex真实encrypt方法的加密逻辑

请添加图片描述

解密脚本,解出request的data

import java.io.FileOutputStream;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

class DecryptoToFile {
    private static final String KEY = "DSACTF";
    private static final String TAG = "Encrypto";

    private static byte[] customHash(String input) {
        byte[] keyBytes = new byte[16];
        int[] temp = new int[16];
        for (int i = 0; i < input.length(); i++) {
            int charVal = input.charAt(i);
            for (int j = 0; j < 16; j++) {
                temp[j] = ((temp[j] * 31) + charVal) % 251;
            }
        }
        for (int i2 = 0; i2 < 16; i2++) {
            keyBytes[i2] = (byte) (temp[i2] % 256);
        }
        return keyBytes;
    }

    public static void decryptToFile(String encryptedData, String outputFile) throws Exception {
        byte[] encryptedBytes = Base64.getDecoder().decode(encryptedData);
        byte[] keyBytes = customHash(KEY);
        SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "AES");
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
        byte[] decryptedBytes = cipher.doFinal(encryptedBytes);

        try (FileOutputStream fos = new FileOutputStream(outputFile)) {
            fos.write(decryptedBytes);
        }

        System.out.println("Decryption completed. Decrypted file saved as " + outputFile);
    }
}
public class Main {
    public static void main(String[] args) throws Exception {
       DecryptoToFile.decryptToFile("TwMkYUkg4bYsY0hL99ggYWnVjWyXQrWAdNmToB0eBXbS6wBzL6ktorjNWI9VOroTU4HgIUYyzGLpcHzd1zNGT+bFZZI7IoxJwpcgXfdwW1LSmiNSP+PuSUsqAzNclF1nJ07b4tYyLWg0zTypbzWsLhOIM+6uci3RFZLREUCALafi01M8mS+KMNxX1Pyn8mSP+KKKjQ5S5fasHRSn+L9qBFws0mWavpfI0QEiMgarxv0iGhYU8cfgonWyL70RvoXET5VUDP1vfYWIBLzzzaAqLC0OiMtUK3TTATSU7yijdgXm18OKMcGIke/NZIM6Sr5fL3t6psDOOkw2C/5uYrJVPn+D6U9KTL64bgREppDqMOvhvbhtuf/S3ASW/+rhtPMtoaD8FxDg0wWSLZA53fQfNA==","Decrypt.txt");
    }
}

得到一组浮点数(共29个)

458.853181,-18.325492,-18.251911,-2.097520,-21.198660,-22.304648,21.103162,-5.786284,-15.248906,15.329286,16.919499,-19.669045,30.928253,-37.588034,-16.593954,-5.505211,3.014744,6.553616,31.131491,16.472500,6.802400,-78.278577,15.280099,3.893073,56.493581,-34.576344,30.146729,4.445671,6.732204

分析libnote.so,搜索sendInit方法,将字符串存储到vector并进行一维DCT-II变换

请添加图片描述

其中encrypt方法调用了**_Z7encryptRKNSt6__ndk16vectorIiNS_9allocatorIiEEEE()**,恢复函数名得到

encrypt(std::ndk1::vector<int, std::ndk1::allocator<int>> const&)

根据参数恢复符号,跟进发现是DCT-II变换

请添加图片描述

逆变换DCT-III求解

import cv2
import numpy as np

# 定义一个输入的频谱(DCT-II变换的结果)
spectrum = np.array([458.853181,-18.325492,-18.251911,-2.097520,-21.198660,-22.304648,21.103162,-5.786284,-15.248906,15.329286,16.919499,-19.669045,30.928253,-37.588034,-16.593954,-5.505211,3.014744,6.553616,31.131491,16.472500,6.802400,-78.278577,15.280099,3.893073,56.493581,-34.576344,30.146729,4.445671,6.732204], dtype=np.float32)

# 对频谱进行逆变换
signal = cv2.idct(spectrum).tolist()

for num in signal:
    print(chr(round(num[0])),end='')# round对浮点数四舍五入,第二个参数可指定保留小数位数,默认不保留小数

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

OrientalGlass

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值