解题过程

打开软件是加壳的,使用010打开,可以看到是魔改的upx,将关键词改成UPX ,然后脱壳成功,使用IDA打开,可以看到是没有符号的,分析起来比较难顶,使用go_parser还原符号后打开main_main,

先运行一下查看有没有什么提示

image-20230807142101343

有个wrong,字符串搜索定位过去,然后查看交叉引用,

可以看到在main 里面对应这两个地方,应该是要走到下面的success 才是正确的flag,然后从上面进行分析,有两个main_sub的函数,第一个

image-20230807142715400

有个aes,直接猜是AES加密,第二个函数

image-20230807143027899

image-20230807111902922

这里很多3字节编码的操作,看起来像base64,后面引用了一个外部的字符串off_53D370,应该就是编码表,这个不是标准的编码表是变表

image-20230807143234676

再往后面就是一个数组的比较了,这里函数的参数识别有问题,按Y修改下,查了下这个panicIndex函数好像是处理数组越界的,没有实际的含义。

image-20230807112123391

逻辑清楚很多了,这里可以再修正下数组的定义,这里是对编码后的base64字符串进行操作

image-20230807143358081

然后就是最后的判断了,这里比较的是编码后的字符串和encodearray,没有其他的操作了

image-20230807143445742

所以还原思路,首先对encodearray 还原成base64,然后变表base64 解码,最后aes解密,aes密钥动调获取的和flag的输入数据放一块,正好16位

import struct
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad
import base64


def decode_custom_base64(data, custom_table):
    # 标准Base64编码表
    standard_table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

    # 使用自定义表将加密数据映射回到标准的Base64编码
    trans = str.maketrans(custom_table, standard_table)
    decoded_data = base64.b64decode(data.translate(trans))

    return decoded_data



custom_table = "456789}#IJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123ABCDEFGH"

encodearray = [
    0xC9F5C5CFC889CEE6,
    0xCCAC7FCE91C0D9D2,
    0x92EAD496C0B7CFE9,
    0x93AEA5CB84DFD7E2,
    0xC9F0CEDF97BECAA6,
    0xDB65B1C46BAEE1B7,
    0xC3ED8CD69392EDCE,
    0xA7B5B2AAA594DAA3
]

result = []
key=b'wvgitbygwbk2b46d'
for num in encodearray:
    bytes_ = struct.pack('<Q', num)
    for b in bytes_:
        result.append(b)

# print(result)
base=''
for i in range(len(result)):
    base+=chr((result[i]-key[i%16])^0x1A)
print(base)


decoded_data = decode_custom_base64(base, custom_table)
print(decoded_data)


aes = AES.new(b"wvgitbygwbk2b46d",mode=AES.MODE_ECB)
print(aes.decrypt(decoded_data))

内容来源于网络如有侵权请私信删除

文章来源: 博客园

原文链接: https://www.cnblogs.com/immune53/p/17613012.html

你还没有登录,请先登录注册
  • 还没有人评论,欢迎说说您的想法!