170708 逆向-南邮CTF逆向(maze)

1625-5 王子昂 总结《2017年7月8日》 【连续第279天总结】
A. 南邮CTF逆向(5、6)
B. 5:
又是maze,拖到IDA分析后发现主要内容就在main中:

if ( strlen(&input) != 24 || strncmp(&input, "nctf{", 5uLL) || *(&byte_6010BF + 24) != 125 )
  {
LABEL_22:
    puts("Wrong flag!");
    exit(-1);
  }
  v3 = 5LL;
  if ( strlen(&input) - 1 > 5 )                 // v9是行
                                                // v9下一字节是列
  {
    while ( 1 )
    {
      in = *(&input + v3);                      // 取第i个字节
                                                // 大写O是x-1
                                                // 小写o是x+1
                                                // .是y-1
                                                // 0是y+1
                                                // 
      v5 = 0;
      if ( in > 78 )
      {
        in = (unsigned __int8)in;
        if ( (unsigned __int8)in == 79 )        // O
        {
          v6 = sub_400650((_DWORD *)&v9 + 1);   // v6=v9的下一字节>0
                                                // v9的下一字节-1
          goto LABEL_14;
        }
        if ( in == 111 )                        // o
        {
          v6 = sub_400660((int *)&v9 + 1);      // v9的下一字节+1
                                                // v6=v9的下一字节<8
          goto LABEL_14;
        }
      }
      else
      {
        in = (unsigned __int8)in;
        if ( (unsigned __int8)in == 46 )        // .
        {
          v6 = sub_400670(&v9);                 // v6=v9>0
                                                // v9=v9-1
          goto LABEL_14;
        }
        if ( in == 48 )                         // 0
        {
          v6 = sub_400680((int *)&v9);          // v9+1
                                                // v6=v9<8
LABEL_14:
          v5 = v6;
          goto LABEL_15;
        }
      }
LABEL_15:
      if ( !(unsigned __int8)sub_400690((__int64)asc_601060, SHIDWORD(v9), v9) )// [a1+a2+8*a3]==32或35
                                                // 每步的落点限制
        goto LABEL_22;
      if ( ++v3 >= strlen(&input) - 1 )
      {
        if ( v5 )                               // v6需要非0
          break;
LABEL_20:
        v7 = "Wrong flag!";
        goto LABEL_21;
      }
    }
  }
  if ( *(&asc_601060[8 * (signed int)v9] + SHIDWORD(v9)) != 35 )// 最后一步需要为35
    goto LABEL_20;
  v7 = "Congratulations!";
LABEL_21:
  puts(v7);
  return 0LL;
}

首先判断格式nctf{}和长度,然后对其中的字符进行不断接受,四种字符oO0.表示对v9和*(&v9+1)的操作。由最后判断时为地图地址601060+8*v9+SHIDWORD(v9)可以猜出,v9为行数,每行8个字符,SHIDWORD为取v9的下一字节(查询可得知宏定义)
直接查看一下601060发现是一个长字符串,里面只有三种字符32、35和42
要求每步都落在32或35上,最后一步落在35上且不能出界(即横纵坐标超出8)
那么很简单,用IDC脚本把地图打印出来即可:
170708 逆向-南邮CTF逆向(maze)_第1张图片
从左上角走起,最终走到2结束,正好18步。得到flag

6:IDA打开,发现同样是elf,这次F5陷入无响应和报错中了
大致浏览一下汇编:
首先得到输入,flag初值为1,然后判断长度是否为0x19,不是则令flag=0
接着进行大量的数据处理,其中对输入字符串的处理夹杂在其中,其余是无效的
最后对输入字符串和0x694060的字符串进行比较,不等则令flag=0
如果flag=1则正确
查看了一下数据处理中没有对0x694060的字符串进行处理,因此只要得到该字符串然后dump下对输入字符串的处理然后逆变换即可得到需要输入的字符串
然而,并不知道怎么把汇编指令有选择地拖出来……
暂放
C.明日计划
全国大学生信息安全竞赛

你可能感兴趣的:(CTF)