CTF 天津垓

运行

可知刚开始的显示以及输入错误后的提示

ida打开

所以是前边的v25-v30放在一起

1个int64是8个字节,1个char是1个字节,因此1个int64可转为8个char

在v25右键->set lvar type

改为

修改后的结果

 

已经显示出了错误时的报错了。同理,有一些其他地方也是字符串,只是被ida识别错误了,若是不确定是否被识别错误了,可以查看char形式,会发现是一堆字符串。同理,修改多处

修改好后 根据后边的代码逻辑可知:我们应该输入Caucasus@s_ability

代码如下:

def round1():
    str_list = [ord(each) for each in "Rising_Hopper!"]
    v1 = [17, 8, 6, 10, 15, 20, 42, 59, 47, 3, 47, 4, 16, 72, 62, 0, 7, 16]
    flag = []
    for i in range(18):
        for des in range(0x100): # range(32, 127)
            v15 = ~(des & str_list[i % 14]) & (des | str_list[i % 14])
            if v15 == v1[i]:
                flag.append(chr(des))
                break
    print("".join(flag))

期间有个反调试,patch掉。我修改后忘了在哪了。在输入后会显示

之后我们如果只是在

 这两个函数里徘徊的话,是发现不了下一步的算法的。

我们可以发现 Str 是一个全局变量,在其他地方有被调用的。即我们的输入在其他地方会用到。

在该位置会看到

函数是byte,所以这应该是smc自解码的考点。具体smc的作用自行搜索

通过脚本的方式解决

import sys
from idautils import *
from idc import *
import idaapi

if __name__ == "__main__":
    lpAddress = 0x10040164D
    str_list = [ord(c) for c in "Caucasus@s_ability"]
    for i in range(1045):
        bt = Byte(lpAddress+i)  # Byte是取值的,不用这个,则是取了地址
        bt ^= str_list[i % 18]
        #PatchByte(lpAddress + i, Byte((lpAddress + i) ^ (str_list[i % 18]))
        # PatchByte的参数只能是个值,不能进行计算?
        #PatchByte(lpAddress + i, (Byte(lpAddress + i)) ^ (str_list[i % 18])  # 这是pacth值,顾名思义
        PatchByte(lpAddress + i, bt)

# 写法2 推荐用函数
def smc(lpaddress,length,key):
    for i in range(length):
        bt = Byte(lpAddress+i)
        bt ^= key[i % 18]
        PatchByte(lpAddress+i,bt)
str_list = [ord(c) for c in "Caucasus@s_ability"]
addr = 0x10040164D
lengthh = 1045
smc(addr,lengthh,str_list)

结果如下(经过脚本后的内容)

按c转化成代码 按P构造函数

解密脚本如下

def round1():
    str_list = [ord(each) for each in "Rising_Hopper!"]
    v1 = [17, 8, 6, 10, 15, 20, 42, 59, 47, 3, 47, 4, 16, 72, 62, 0, 7, 16]
    flag = []
    for i in range(18):
        for des in range(0x100): # range(32, 127)
            v15 = ~(des & str_list[i % 14]) & (des | str_list[i % 14])
            if v15 == v1[i]:
                flag.append(chr(des))
                break
    print("".join(flag))


def round2():
    flag = []
    Str = [ord(c) for c in "Caucasus@s_ability"]
    constant1 = 19683
    constant2 = 2147483659
    v9 = [2007666, 2125764, 1909251, 2027349, 2421009, 1653372, 2047032, 2184813, 2302911, 2263545, 1909251, 2165130,
          1968300, 2243862, 2066715, 2322594, 1987983, 2243862, 1869885, 2066715, 2263545, 1869885, 964467, 944784,
          944784, 944784, 728271, 1869885, 2263545, 2283228, 2243862, 2184813, 2165130, 2027349, 1987983,
          2243862, 1869885, 2283228, 2047032, 1909251, 2165130, 1869885, 2401326, 1987983, 2243862,
          2184813, 885735, 2184813, 2165130, 1987983, 2460375]
    #print(len(v9))
    for i in range(len(v9)):
        for Str in range(0x100):
            f = constant1 * Str % constant2
            #print(f)
            if f == v9[i]:
                flag.append(chr(Str))

    print("".join(flag))

round1()
round2()

 成功如下:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值