首页
社区
课程
招聘
[原创]CTF2018第二题半加器 writeup
发表于: 2018-12-3 22:26 3695

[原创]CTF2018第二题半加器 writeup

2018-12-3 22:26
3695

The input file was linked with debug information

and the symbol filename is:

'C:\Users\83966\Desktop\Exam\Debug\Exam.pdb'

        题目似乎并没有特别的保护方式,除了使用vs2017的C++开发,静态链接ucrt运行时库,使用的调试版本,导致大量未优化的代码影响IDA全自动出来的结果太难看..因为经验不足,IDA全自动出来的代码确实在很大程度上影响了分析思路。

The input file was linked with debug information

and the symbol filename is:

'C:\Users\83966\Desktop\Exam\Debug\Exam.pdb'

而且文件体积较大,基本可以确定是使用的Debug版本。Ctrl + E 找到start, 一路跟随,并没有发现什么有用的信息,遂放弃直接看静态代码的方式。运行程序,有提示输入的信息,IDA中 Shift+ F12搜索 Please Input,找到字符串,顺便把 aPleaseInput 下面的 unk_5B25CC A了一下,转换成字符串,直接识别出来 输入错误; 的字符。任意输入一串字符,果真提示有 输入错误。查找 输入提示和错误信息的交叉引用,都提示出在 sub_4A19B0中使用,如下 图1 :


进到 sub_4A19B0,习惯性地F5,发现堆栈 居然 不平衡,无法自动转换为伪代码,再结合IDA自动出来的一万多个函数,想当然地认为程序应该是被处理过(当时并没有想到是因为未优化过导致。),老实地回到汇编状态,阅读aPleaseInput附近的代码,大至判断输入的长为10到30个字符之间,如下图2所示:

得出第一个满足条件:输入的长度10到30个字符。
长度验证通过后,进入到标签 loc_4A1A30, 在 loc_4A1A30下,有对疑似输入的缓存byte_5F3068和dword_5F3088作为sub_48E5BF的入参,进行一某种运算, dword_5F3088作为函数的返回,第七个字节的值必须为 0x41(字符 A)。如下图3所示:

这步验证通过后,来到把 dword_5f3088作为结果,来到sub_48D3A4, 该函数里面直接jmp到sub_49DBD0, 对该函数直接F5, 得到如下代码
int __usercall sub_49DBD0@<eax>(int xmm0_4_0@<xmm0>, char *a1)
{
  unsigned int i; // [esp+D0h] [ebp-8h]

  sub_48D7B4(&unk_5F6007);
  a1[7] = '#';
  for ( i = 0; i < sub_48A9A6((int)a1); ++i )
    a1[i] ^= 0x1Fu;
  return sub_48D935(1, (int)a1, xmm0_4_0);
}
从该函数看出,把输入的第七个字符设置成 '#',然后对内存中的每一个字符与 0x1F异或(跟进sub_48a9a6 可以大概得出该函数是对输入的计算长度,类似strlen)。
int __usercall sub_49DBD0@<eax>(int xmm0_4_0@<xmm0>, char *a1)
{
  unsigned int i; // [esp+D0h] [ebp-8h]

  sub_48D7B4(&unk_5F6007);
  a1[7] = '#';
  for ( i = 0; i < sub_48A9A6((int)a1); ++i )
    a1[i] ^= 0x1Fu;
  return sub_48D935(1, (int)a1, xmm0_4_0);
}
从该函数看出,把输入的第七个字符设置成 '#',然后对内存中的每一个字符与 0x1F异或(跟进sub_48a9a6 可以大概得出该函数是对输入的计算长度,类似strlen)。
再点进 sub_49dbd0调用的 sub_48D935,一路跟下去,发现快跟丢了,静态分析就暂且停下,开始动态调试。

在上面图3的预处理输入后设置一个断点,以 0123456789 作为测试输入,调试发现第一步预处理应该只是一个字符串的拷贝。

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

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