二进制专项之babyRE

昨天没弄出来,有反调试和异常,一直找不到主要加密区域

文件类型

64位exe文件,缺少两个常见dll文件,直接百度下载即可,注意为64位的不然还是会显示0xc000000d报错

算法分析

在这里插入图片描述
可以看出来函数直接通过程序传参,这样一来,调试的时候就没法直接给参数了,当然也可以直接改对应的参数区域值,但当时改了半天都没改到地方,索性直接改了Rip执行位置
接着加载了一个名字叫cod的资源主要加密函数就parameter传参的两个地方,StartAddress发现是比较函数,所以重点进入v17这个地方的函数很好所以寄了
在这里插入图片描述

看师傅们的wp后加密流程为:

  • 载入资源
  • sub_7ff6e4731087中进行解密,但是。。有个反调试操作,老6,直接看是看不到的需要交叉引用才能看到,但问题是怎么被调用执行的呢,回调?还是钩子?亦或异常?不对,一直有一个checkmycode的函数在对一个地址进行写入,但是也没有出现调用的情况,很奇怪,但可以猜测到确实执行并进行了写入
  • 执行解密的函数
  • 完成比较
cod

可以用http://www.dayanzai.me/resource-hacker.html这个工具提取出对应的资源模块,然后在外部进行解密,然后将解密的段用这个工具直接替换
在这里插入图片描述
通过查看模块加载结构确定函数位置,在最后一个段,不用看结构应该也能猜到,然后反编译发现有花指令出现
出现了三种类型的:
在这里插入图片描述

在函数内部又构建了一个无意义的函数,导致调用失败全部nop掉
在这里插入图片描述
进入下条指令,也没有用,nop掉
在这里插入图片描述
加一的位置被jmp指令占据,而且上面两条跳转等于一定会发生跳转,也要nop掉

弄完后发现是32位程序的由于ida8.0开始判定的程序是64位所以不能完成反编译(ida8版本64位和32位合在一起,但感觉处理某些异常感觉不如idapro)于是将资源随便找了个32位程序加载进去,得到反编译,这里用的idapro
在这里插入图片描述
更改完对应花指令后虽然还是显示堆栈不平衡,但是可以直接被反编译,相反,ida free就不行,反编译完成后得到三个函数,为了更直观我们甚至可以直接将ret nop掉,很神奇,完全不管堆栈平衡了吗

RC4变种

在这里插入图片描述
可以得到一个酷似RC4加密的函数,因为标识符0x100,对应256,但是虽然只赋值了四个,一般来说密钥也确实是四个,但他使用密钥的时候是按字节进行的a67为计数,所以现在密钥,密文(原程序验证区域)都有了,改一下RC4加密算法就好了

wp

import base64


def rc4_main(key, message):
    print("RC4解密主函数调用成功")
    print('\n')
    s_box = rc4_init_sbox(key)
    crypt = rc4_excrypt(message, s_box)
    return crypt


def rc4_init_sbox(key):
    s_box = list(range(256))
    # print("原来的 s 盒:" % s_box)
    print('\n')
    j = 0
    for i in range(256):
        j = (j*2 + s_box[i] + key[i % len(key)]) % 256
        s_box[i], s_box[j] = s_box[j], s_box[i]
    # print("混乱后的 s 盒:%s"% s_box)
    print('\n')
    return s_box


def rc4_excrypt(plain, box):
    print("调用解密程序成功。")
    print('\n')
    print(plain)
    res = []
    i = j = n=0
    for s in plain:
        s -=n%0xd
        i = (i + j) % 256
        j = (j + box[i]) % 256
        box[i], box[j] = box[j], box[i]
        t = (box[i] + box[j]+j) % 256
        k = box[t]
        res.append(chr((s&0xff) ^ k))
        n+=1
    print("res用于解密字符串,解密后是:%res" % res)
    print('\n')
    cipher = "".join(res)
    print("解密后的字符串是:%s" % cipher)
    print('\n')
    print("解密后的输出(没经过任何编码):")
    print('\n')
    return cipher


# key ="Nu1Lctf233"    #密钥
key = [0x5d, 0x42, 0x62, 0x29, 0x03, 0x36, 0x47, 0x41, 0x15, 0x36]

s = [0xF7, 0x2E, 0x34, 0xF0, 0x72, 0xCF, 0x5E, 0x0A, 0xBB, 0xEC, 0xB1, 0x2B, 0x70, 0x88, 0x88, 0xED,
     0x46, 0x38, 0xDB, 0xDA, 0x6C, 0xBD, 0xD4, 0x06, 0x77, 0xF2, 0xCF, 0x56, 0x88, 0xC6, 0x31, 0xD2,
     0xB7, 0x5A, 0xC1, 0x42, 0xB0, 0xF4, 0x48, 0x37, 0xF5, 0x2C, 0xF5, 0x58]

rc4_main(key, s)

改变:
对i,j,s运算多添加了一些东西,密钥也由原来长度增加至10

DASCTF{03446c2c-dff7-11ed-9285-54e1ad98d649}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值