首页
社区
课程
招聘
[原创]reversing.kr第15题PEPassword
发表于: 2019-2-18 11:17 3752

[原创]reversing.kr第15题PEPassword

2019-2-18 11:17
3752
1,original.exe程序没有加壳,直接运行发现密码是加密了的。直接用ida和od进行分析
通过分析发觉就是将下面两处的数据异或后放到对应的地址处输出,并没有发现什么秘密。
 do
  {
    v5 = *(&v20 + v4) ^ *(&v7 + v4);
    *(&v7 + v4) = v5;
    *(&v34 + v4++) = v5;
  }
  while ( v4 < 13 );
2.运行password check,程序没有相应的按钮,不知道程序的目的是什么,进行查壳,是SMT壳
选择单步跟踪的方法进行分析,由于第一个call会跑飞,所以我们进入到第一个call进行分析.
程序运行的时候会先对自己进行解密操作,然后回出现相应的调用函数。然后一直单步运行,就会发现相应的关键函数
GetMessageA用来从消息框获取输入的数据,
TranslateMessage 函数将虚拟键消息转换成字符消息。该字符消息又被发送给对应线程(调用TranslateMessage的线程)的消息队列,当线程再次调用GetMessage函数或PeekMessage函数获取消息的时候被读取。
DispatchMessageA 通常消息从GetMessage函数获得或者TranslateMessage函数传递的。消息被分发到回调函数(过程函数),作用是消息传递给操作系统,然后操作系统去调用我们的回调函数,也就是说我们在窗体的过程函数中处理消息。 

je明显是相等就会进入循环,所以我们要对判断的地址进行判定。这里可以下内存写入断点,看看什么时候对地址进行了写入操作。这里使用ida的交叉引用来寻找所有可能会对数据的操作。跳转到0x4091a8位置处,查看这里的数据。
跳转到0x4091a8位置处,往上面几个位置处下断点,然后运行程序
可以看到我们的输入,传入esi然后在0x409197调用函数0x4091d8,然后将eax和0xE98F842A比较,所以0x4091d8就是关键call.
里面是比较复杂的操作,每个字符进行0xffff次操作,长度未知,所以逆变换很难
这里选择对0x4091a6处进行直接爆破。然后继续运行程序,执行到用户代码处。
接下来运行程序,程序会报错,所以下面就要逐步的运行程序,对程序进行判断。
函数0x409200处出现的pushad操作,这然后对0x401000处进行异或操作,显然是解密操作
调用两次复杂函数,然后将值存入ebx,最后用ebx对eax进行变换, 由于我们有原函数origin.exe,拖入OD中找到401000处的机器码,于是可以得到eax序列的值,问题在于ebx是多少 , 这里ebx的穷举空间有0xffffffff,虽然有点大但还可以接受 ,拿eax的原始值和第一次变换值就可以穷举出ebx了 。

参考代码
ori = 0xb7aac296
tar = 0x5a5a7e05
 
def ror(a, n):
    for i in range(n):
        p = a & 1
        a = p*0x100000000 + a >> 1
    return a
 
def de(key):
    p = ori ^ key
    q = ror(p, (key & 0xff00) >> 8)
    if(q == tar):
        print("Correct! The password is ", hex(p))
        f = open("F:\ctf\\reversing.kr\\PEPassword\\ebx.txt", 'w')
        f.write(hex(p))
        f.close
        return True
    else:
        return False
 
for i in range(0xffffffff):
    de(i)
    if(i%0x10000==0):#LOG
        print(hex(i))

本文参考链接:
c92K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3f1#2x3Y4m8G2K9X3W2W2i4K6u0W2j5$3&6Q4x3V1k6@1K9s2u0W2j5h3c8Q4x3X3b7$3y4e0l9^5x3o6u0Q4x3X3b7I4i4K6u0V1x3g2)9J5k6h3S2@1L8h3H3`.
 do
  {
    v5 = *(&v20 + v4) ^ *(&v7 + v4);
    *(&v7 + v4) = v5;
    *(&v34 + v4++) = v5;
  }
  while ( v4 < 13 );
2.运行password check,程序没有相应的按钮,不知道程序的目的是什么,进行查壳,是SMT壳
选择单步跟踪的方法进行分析,由于第一个call会跑飞,所以我们进入到第一个call进行分析.
程序运行的时候会先对自己进行解密操作,然后回出现相应的调用函数。然后一直单步运行,就会发现相应的关键函数
GetMessageA用来从消息框获取输入的数据,
TranslateMessage 函数将虚拟键消息转换成字符消息。该字符消息又被发送给对应线程(调用TranslateMessage的线程)的消息队列,当线程再次调用GetMessage函数或PeekMessage函数获取消息的时候被读取。
DispatchMessageA 通常消息从GetMessage函数获得或者TranslateMessage函数传递的。消息被分发到回调函数(过程函数),作用是消息传递给操作系统,然后操作系统去调用我们的回调函数,也就是说我们在窗体的过程函数中处理消息。 

je明显是相等就会进入循环,所以我们要对判断的地址进行判定。这里可以下内存写入断点,看看什么时候对地址进行了写入操作。这里使用ida的交叉引用来寻找所有可能会对数据的操作。跳转到0x4091a8位置处,查看这里的数据。
跳转到0x4091a8位置处,往上面几个位置处下断点,然后运行程序

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 1
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回