DDCTF 2019 逆向题writeup(二)

文章目录

      • 总结
      • 脱壳分析
      • 定位关键call
      • 逆向分析
      • 编写脚本

总结

  • 其实输入只能是0-9和A-F有很大的提示作用,开始没想明白
  • and和add没看清,走了很多弯路
  • python模块itertools的排列组合函数
  • 结合IDA分析会简便,但是太烂不想脱壳dump

脱壳分析

首先是一个ASPack 2.12 -> Alexey Solodovnikov。利用ESP定律脱壳。

定位关键call

这个call执行完后,显示了input code:的字符串。所以需要跟入。
DDCTF 2019 逆向题writeup(二)_第1张图片
跟进之后,发现了明文字符串。其中call 012A11F0函数是对输入进行验证,必须是0-9,A-F。其实这里就可以想到16进制数。在这个函数里面兜兜转转好长时间,脑子瓦特了。
下一个关键的函数就是012A1240,需要进去看一下。
DDCTF 2019 逆向题writeup(二)_第2张图片
反复调试,发现12A1000比较奇怪,因为它的输入是我们输入的flag。因此里面必有蹊跷。
DDCTF 2019 逆向题writeup(二)_第3张图片
进去之后会发现里面有几个循环,循环不可怕,可怕的是循环里面有各种左移,右移,异或等操作。所以抓住这个函数死不松手进行分析。这个循环的输入是6个字符串为一组。输出是4个字符串。刚开始试的时候,发现输入如果不是6的倍数,看到输出会有“=”,一度以为是自定义base64。
DDCTF 2019 逆向题writeup(二)_第4张图片

逆向分析

重点对这里分析,会将输入拆分为6个一组。比如第一组123456。会再拆分置为 0x12 ,0x34, 0x56。其中0x12经过计算放置在esp+0x18,0x34经过计算放置在esp+0x19处,以此类推。这里就理解为什么要求输入必须是16进制数里面的字符了。不是的话这里转化不了呀。。。
DDCTF 2019 逆向题writeup(二)_第5张图片
然后4个输出的数据就是edx,作为偏移,然后加上0x12A3020。这里的代码和第一道逆向题的思路差球不多,就是索引到指定的字符串然后再与0x76异或。最后和谁去比呢?
DDCTF 2019 逆向题writeup(二)_第6张图片
在之前调试这个位置看到DDCTF{reverse+},其实就是和reverse+进行对比。其中reverse+长度是8。所以输入的长度是12的16进制字符。
DDCTF 2019 逆向题writeup(二)_第7张图片

编写脚本

import itertools

cover = [0x37,0x34,0x35,0x32,0x33,0x30,0x31,0x3E,0x3F,0x3C,0x3D,0x3A,0x3B,0x38,0x39,0x26,0x27,0x24,0x25,0x22,0x23,0x20,0x21,0x2E,0x2F,0x2C,0x17,0x14,0x15,0x12,0x13,0x10
,0x11,0x1E,0x1F,0x1C,0x1D,0x1A,0x1B,0x18,0x19,0x06,0x07,0x04,0x05,0x02,0x03,0x00
,0x01,0x0E,0x0F,0x0C,0x46,0x47,0x44,0x45,0x42,0x43,0x40,0x41,0x4E,0x4F,0x5D,0x59
,0x01,0x00,0x00,0x00,0xF8,0x1B,0x2B,0x00,0xB8,0x2E,0x2B,0x00]
cc = ""

input_ = list(itertools.product([1,2,3,4,5,6,7,8,9,"A","B","C","D","E","F"],repeat = 6))


for i in range(len(input_)):
    
    a = int(str(input_[i][0])+str(input_[i][1]),16)
    one = a>>0x2
    
    b = int(str(input_[i][2])+str(input_[i][3]),16)
    tmp = (a&0x3)<<0x4
    tmp_1 = b>>0x4
    two = tmp_1+tmp

    c = int(str(input_[i][4])+str(input_[i][5]),16)
    tmp_2 = ((b&0xF)*2)*2
    tmp_3 = c>>0x6
    three = tmp_2+tmp_3
    
    four = c&0x3F

    fuzz = chr(cover[one]^0x76) + chr(cover[two]^0x76) + chr(cover[three]^0x76) + chr(cover[four]^0x76)
    if(fuzz =="reve" or fuzz =="rse+"):
        print str(hex(a))+str(hex(b))+str(hex(c))

你可能感兴趣的:(二进制漏洞)