一道CTF解题之旅 – 作者:雷石安全实验室

  概况  

前面分享了一些常见的字符串加解密的程序解题方法,现在遇到了一个加了壳的程序,程序的加密流程并不复杂主要是想分享一下脱常见压缩壳的方法。

  • 攻防世界Reserve:040

  • 难度::star::star::star:

  • 混淆情况:加壳 nsPack


  脱壳  

  • 侦壳  

    Win32控制台程序,nsPack壳

image-20200524224531975.png

  • 脱壳


OD载入程序,可以看见压缩壳的标志性指令 pushadF8两步,只有ESP寄存器被改变

image-20200524225224141.png

对于脱 nsPack壳的方法有单步法、ESP定律、二次内存镜像法等,由于单步太慢、二次内存镜像法不容易理解,这里直接使用ESP定律,在ESP所在的内存地址下硬件访问断点

image-20200524230137327.png

F9运行, popfd与前面的指令对应,在下面的 jmp指令就是跳回程序的入口点


image-20200524230315381.png


跳到入口点之后,右键开始dump内存


image-20200524230720106.png


点击获取 EIP作为 OEP,注意这里要记住修正后的地址,在下面的修复中要用到。脱壳保存文件

image-20200524230946995.png


修复导入表,打开导入表修复工具,按照下面的步骤,修正转储点击刚刚保存好的文件,至此脱壳完成。


image-20200524231216258.png

其实脱这种压缩壳只有三步:找到OEP地址,dump内存和修复导入表。


  调试  


将脱完壳的程序拖入IDA中查看,可以看到输入字符串要大于0X2A,后面有一个异或加密,同样只要再异或一次这个数就可以得到答案了


image-20200524232917546.png


OD中动态调试


这里是用来异或的字符串

未命名图片.png

用来比较的字符,正好是0x2A位


image-20200524233442133.png



  解题脚本  

void DecodeCTF40()

char Str[] = { 0x12,0x04,0x08,0x14,0x24,0x5C,0x4A,0x3D,0x56,0x0A,0x10,0x67,0x00,0x41, 0x00,0x01,0x46,0x5A,0x44,0x42,0x6E,0x0C,0x44,0x72,0x0C,0x0D,0x40,0x3E, 0x4B,0x5F,0x02,0x01,0x4C,0x5E,0x5B,0x17,0x6E,0x0C,0x16,0x68,0x5B,0x12 }; 

char keyStr[] = "this_is_not_flag"

int keyCount = 0; for (int i = 0; i <= 0x2A; ++i) { 

 keyCount = i % 16

Str[i] ^= keyStr[keyCount]; 

printf("%c", Str[i]); 

 }

}

来源:freebuf.com 2020-06-01 14:46:58 by: 雷石安全实验室

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论