CTF

西湖论剑

easyCpp

Posted by pic4xiu on May 2, 2019

Auth

A Linux re

pic@ubuntu:~/Desktop$ file easyCpp 
easyCpp: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/l, for GNU/Linux 2.6.32, BuildID[sha1]=3d7df25fb01d78d7f840a0116f148283d11e2389, not stripped

Analysis

Run it and see what happened

pic@ubuntu:~/Desktop$ ./easyCpp 
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
You failed!

看到我们输入了16个字符后自动退出,我们直接分析利用ida分析一下,虽然是 C++ 的,但我们也要忍这看orz

for ( i = 0; i <= 15; ++i )
  {
    scanf("%d", &v24[4 * i]);
    std::vector<int,std::allocator<int>>::push_back(&v18, &v24[4 * i]);
  }

看到我们输入的都放到了v18

  for ( j = 0; j <= 15; ++j )
  {
    LODWORD(v23) = fib(j);
    std::vector<int,std::allocator<int>>::push_back(&v17, &v23);
  }

之后程序自动用fib()函数生成16个斐波那契数列,存到v17

v9 = __gnu_cxx::__normal_iterator<int *,std::vector<int,std::allocator<int>>>::operator+(&v24, 1LL);

这个命令使得v9是我们输入的第二个数字,之后的下一个函数我们直接跟进,看到

__int64 __fastcall main::{lambda(int)#1}::operator() const(_DWORD **a1, int a2)
{
  return (unsigned int)(**a1 + a2);
}

这个蜜汁函数意思很简单,就是把a1的数字放到a2中,即把后边的数字与第一个相加,之后到了accumulate便是通过不停的利用copy来进行数组的反转,直接分析很复杂,可以动态调试一下,当然逆向也可以猜(手动滑稽

总的来说本题分为以下几步:

  • 输入16个数字
  • 生成16个斐波那契数列
  • 第一步的数组从第二个开始的数分别与第一个加
  • 逆序上一步的数组
  • 上一步的数组与第二步的数组进行对比

补一下,有大佬用angr跑出来了,直接把数字输入记得flag,脚本如下

import angr
def main():
	p = angr.Project("./easyCpp")
	st = p.factory.entry_state()
	sm = p.factory.simgr(st)
	sm.explore(find=0x40103c, avoid=0x00401028)
	return sm.found[0].posix.dumps(0)

if __name__ == '__main__':
	print main()

Summary

This isn’t easy

不知道为什么第一题都这么难,后两道题一个是分析算法,一个去花,只有这个算法这么奇怪,还是用 C++ 写的,😔,还是太菜了,继续学习二进制啊~~

最近做了好多题,收获很多,也很杂

  • 使用ida比之前更熟练了
  • 做C语言的题做多了,现在看到伪代码差不多能直接理解了
  • 做pwn题也有思路了,汇编代码神马的也进步了

不足

  • 动态调试总是不太好,pwngdb还是得学
  • 不能静下心来仔细分析代码,老是对杂项那些感兴趣
  • 。。。

还有一些做题的心得:

  • 最近在看writeup的时候,发现最近的题简单的全是简单算法,脱壳考的比之前少多了
  • 大佬对一道题分析的时候有时候直接靠猜,猜这个描述可能不太准确,应该是知道套路,直接就把exp甩出来,可能也是他们做题做的多
  • ida的patch是真的好用,之前还没感觉

最近的目标:

  • 做题
  • Do ctf question
  • ctfの質問をする
  • Faire ctf question