XCTF reverse新手练习

1、python-trade

首先在线反编译工具将pyc文件反编译(https://tool.lu/pyc/),对源码进行分析逆向即可。

#源码
import base64

def encode(message):
    s = ''
    for i in message:
        x = ord(i) ^ 32
        x = x + 16
        s += chr(x)
    
    return base64.b64encode(s)

correct = 'XlNkVmtUI1MgXWBZXCFeKY+AaXNt'
flag = ''
print 'Input flag:'
flag = raw_input()
if encode(flag) == correct:
    print 'correct'
else:
    print 'wrong'
#解密代码
# -*- coding: UTF-8 -*-
import base64
buf = base64.b64decode('XlNkVmtUI1MgXWBZXCFeKY+AaXNt') 
flag = ''
for i in buf:
	x = ord(i)-16 
	x ^= 32 
	flag += chr(x)
print (flag)

2、getit

上来载入了C32发现打不开,猜测应该是Linux下的文件

XCTF reverse新手练习_第1张图片

使用Winhex打开发现确实是.elf文件

 

XCTF reverse新手练习_第2张图片

 直接IDA载入静态分析,找到关键词处

XCTF reverse新手练习_第3张图片

 去关键词处,发现是s,t两个变量,s是c61b68366edeb7bdce3c6820314b7498,t是开头为53h,后面是harifCTF{????????????????????????????????},猜想这两个应该就是关键所在了

XCTF reverse新手练习_第4张图片

 在s处查看交叉引用,转到定义处

XCTF reverse新手练习_第5张图片

看到关键代码,按F5查看伪代码

XCTF reverse新手练习_第6张图片

伪代码如下:

char v3; // al
  __int64 v5; // [rsp+0h] [rbp-40h]
  int i; // [rsp+4h] [rbp-3Ch]
  FILE *stream; // [rsp+8h] [rbp-38h]
  char filename[8]; // [rsp+10h] [rbp-30h]
  unsigned __int64 v9; // [rsp+28h] [rbp-18h]

  v9 = __readfsqword(0x28u);
  LODWORD(v5) = 0;
  while ( (signed int)v5 < strlen(s) )
  {
    if ( v5 & 1 )
      v3 = 1;
    else
      v3 = -1;
    *(&t + (signed int)v5 + 10) = s[(signed int)v5] + v3;
    LODWORD(v5) = v5 + 1;
  }
  strcpy(filename, "/tmp/flag.txt");
  stream = fopen(filename, "w");
  fprintf(stream, "%s\n", u, v5);
  for ( i = 0; i < strlen(&t); ++i )
  {
    fseek(stream, p[i], 0);
    fputc(*(&t + p[i]), stream);
    fseek(stream, 0LL, 0);
    fprintf(stream, "%s\n", u);
  }
  fclose(stream);
  remove(filename);
  return 0;

容易得知while循环时关键之所在,写出破解代码如下:

s = 'c61b68366edeb7bdce3c6820314b7498'
t = 'harifCTF{????????????????????????????????}'
t = chr(0x53) + t
t = list(t)

v5 = 0
v3 = 0

while v5 < len(s):
    if (v5 & 1):
        v3 = 1
    else:
        v3 = -1
    t[v5 + 10] = chr(ord(s[v5]) + v3)
    v5= v5 + 1
t = "".join(t)
print(t)

3、csaw2013reversing2

题目描述:听说运行就能拿到Flag,不过菜鸡运行的结果不知道为什么是乱码

拿到程序后首先第一件事就是运行,发现弹窗确实是乱码

XCTF reverse新手练习_第7张图片

载入OD中动态调试,首先通过字符串搜索找到flag,转去flag处

XCTF reverse新手练习_第8张图片

 源程序解读:

(1)源程序处有两个flag,其中一个的text含有数值,另一个的text不含有数值

XCTF reverse新手练习_第9张图片

(2)当程序运行到108A处时会发现两个flag中的上面的text有了基本的初值(弹出的那个乱码值)

XCTF reverse新手练习_第10张图片

(3)程序从1094跳转到10B9,然后在经过10c0这条语句成功将下面flag中的text赋予了一样的初值,然后进行了弹窗

XCTF reverse新手练习_第11张图片

对源程序的流程进行修改:

(1)将1094处的跳转改成109B,让text得到其他的值

XCTF reverse新手练习_第12张图片

(2)程序在10A3处仍有跳转,这个跳转跳过了10c0处对第二个flag中的text赋值的语句,所以要进行修改跳转到10B9(源程序是跳转到这然后开始赋值)

XCTF reverse新手练习_第13张图片

(3) 最后一步步单步发现真正的flag

4、maze

源文件又是elf文件,果断IDA载入

上来就shift+f12查看字符串,又有新发现

XCTF reverse新手练习_第14张图片

 逐渐跟踪到程伪代码处

const char *v3; // rsi
  signed __int64 v4; // rbx
  signed int v5; // eax
  char v6; // bp
  char v7; // al
  const char *v8; // rdi
  __int64 v10; // [rsp+0h] [rbp-28h]

  v10 = 0LL;
  puts("Input flag:");
  scanf("%s", &s1, 0LL);
    //限制长度为24,且以"nctf{"开头,以‘}’结尾i
  if ( strlen(&s1) != 24 || (v3 = "nctf{", strncmp(&s1, "nctf{", 5uLL)) || *(&byte_6010BF + 24) != 125 )
  {
LABEL_22:
    puts("Wrong flag!");
    exit(-1);
  }
  v4 = 5LL;
//从第5个字符才开始判断
  if ( strlen(&s1) - 1 > 5 )
  {
    while ( 1 )
    {
      v5 = *(&s1 + v4);
      v6 = 0;
      if ( v5 > 78 )
      {
        v5 = (unsigned __int8)v5;
        if ( (unsigned __int8)v5 == 79 )
        {
          v7 = sub_400650((char *)&v10 + 4, v3);
          goto LABEL_14;
        }
        if ( v5 == 111 )
        {
          v7 = sub_400660((char *)&v10 + 4, v3);
          goto LABEL_14;
        }
      }
      else
      {
        v5 = (unsigned __int8)v5;
        if ( (unsigned __int8)v5 == 46 )
        {
          v7 = sub_400670(&v10, v3);
          goto LABEL_14;
        }
        if ( v5 == 48 )
        {
          v7 = sub_400680(&v10, v3);

LABEL_14:
          v6 = v7;
          goto LABEL_15;
        }
      }

LABEL_15:
      v3 = (const char *)HIDWORD(v10);
      if ( !(unsigned __int8)sub_400690(asc_601060, HIDWORD(v10), (unsigned int)v10) )
        goto LABEL_22;
      if ( ++v4 >= strlen(&s1) - 1 )
      {
        if ( v6 )
          break;

LABEL_20:
        v8 = "Wrong flag!";
        goto LABEL_21;
      }
    }
  }
  if ( asc_601060[8 * (signed int)v10 + SHIDWORD(v10)] != 35 )
    goto LABEL_20;
  v8 = "Congratulations!";

LABEL_21:
  puts(v8);
  return 0LL;

最后我也没搞明白,找到大神的方案,参考一下:https://bbs.pediy.com/thread-249498.htm

你可能感兴趣的:(CTF)