一个算不上逆向的简单逆向题目

最近参加了某某ctf比赛,初赛非常业余的那种,算是第一次接触ctf的题目,找flag的过程还觉得蛮刺激的,这不经让我想起了想起了刚开始学习python的时候接触到的Python Challenge,不知道现在学python的小朋友还玩不玩这个游戏?

下面是其中一道逆向题的解题过程,这道题极度简单,其实这道题根本不需要逆向就能解决,因为在cmd中运行一下flag就显示出来了。但是我还是想在熟悉逆向工具IDA的过程中以逆向的方式来找一下flag。

首先在IDA中打开这个文件 easy_easy。

找到_main这个函数,按F5可以得到反编译后的伪代码。如下

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char v4[210]; // [esp+1Ah] [ebp-E2h]
  int v5; // [esp+ECh] [ebp-10h]

  __main();
  menu();
  system("cls");
  v5 = 0;
  qmemcpy(&v4[42], &unk_403040, 0xA8u);
  while ( v5 <= 41 )
  {
    v4[v5] = v4[4 * v5 + 42] - 52;
    ++v5;
  }
  puts(v4);
  return 0;
}

第16行的puts(v4) 应该就是输出的flag,让我们来看看flag到底藏在哪里?

v4是一个长度为210存储字符的数组。

第10行的qmemcpy 函数应该就是快速复制内存数据的函数,将unk_403040中数据复制到v442位的后面,长度0xA8就是168,这个长度就是v4长度210-42=168,这个长度帮助我们理解后面的内容。

再接下来就是一个for循环,遍历0到41来构造v4中的数据生成flag用来输出。

v4[v5] = v4[4 * v5 + 42] - 52;

因为前面把unk_403040的数据复制到了v4[42:210]的位置,也就是对这部分的数据每四位的第一个数据减去52依次放到v4[0:42]的位置。

我们双击unk_403040会跳到相应的区域可以看到下面这样的数据

.data:00403040 unk_403040      db  9Ah         ; DATA XREF: _main+34↑o
.data:00403041                 db    0
.data:00403042                 db    0
.data:00403043                 db    0
.data:00403044                 db 0A0h
.data:00403045                 db    0
.data:00403046                 db    0
.data:00403047                 db    0
.data:00403048                 db  95h
.data:00403049                 db    0
.data:0040304A                 db    0
.data:0040304B                 db    0
.data:0040304C                 db  9Bh
.data:0040304D                 db    0
.data:0040304E                 db    0
.data:0040304F                 db    0
.data:00403050                 db 0AFh
.data:00403051                 db    0
.data:00403052                 db    0
.data:00403053                 db    0
.data:00403054                 db  95h
.data:00403055                 db    0
.data:00403056                 db    0
.data:00403057                 db    0
.data:00403058                 db  67h ; g
.data:00403059                 db    0
.data:0040305A                 db    0
.data:0040305B                 db    0
.data:0040305C                 db  6Bh ; k
.data:0040305D                 db    0
.data:0040305E                 db    0
.data:0040305F                 db    0
......
......
......
.data:004030E1                 db    0
.data:004030E2                 db    0
.data:004030E3                 db    0
.data:004030E4                 db 0B1h
.data:004030E5                 db    0
.data:004030E6                 db    0
.data:004030E7                 db    0
.data:004030E8                 db    0
.data:004030E9                 db    0
.data:004030EA                 db    0
.data:004030EB                 db    0
.data:004030EC                 db    0
.data:004030ED                 db    0
.data:004030EE                 db    0
.data:004030EF                 db    0
.data:004030F0                 db    0
.data:004030F1                 db    0
.data:004030F2                 db    0
.data:004030F3                 db    0
.data:004030F4                 db    0
.data:004030F5                 db    0
.data:004030F6                 db    0
.data:004030F7                 db    0
.data:004030F8                 db    0
.data:004030F9                 db    0
.data:004030FA                 db    0
.data:004030FB                 db    0
.data:004030FC                 db    0
.data:004030FD                 db    0
.data:004030FE                 db    0
.data:004030FF                 db    0

目测第四列的数据就是我们要找的flag。先把这些个数据复制粘贴到sublime text中处理,我还是觉得sublime text多行编辑功能很好用,经过几个多行编辑以及查找替换终于得到我们想要的数据,一段十六进制数字,只要把他们丢到python中稍微处理一下打印出来就得到flag了。

9A A0 95 9B AF 95 67 6B 6B 6D 68 6D 68 61 6D 95 6A 64 61 68 68 97 65 61 6C 6B 95 96 61 65 9A 6B 64 6A 9A 96 97 67 66 99 9A B1
flag = "9A A0 95 9B AF 95 67 6B 6B 6D 68 6D 68 61 6D 95 6A 64 61 68 68 97 65 61 6C 6B 95 96 61 65 9A 6B 64 6A 9A 96 97 67 66 99 9A B1".split(" ")
"".join([chr(int(x,16)-52) for x in flag ])

整个过程就是这么简单。

Tag:ctf Published under (CC) BY-NC-SA