2020 DawgCTF Re WP

题目附件:https://lanzous.com/ibdyfxg  

Ask Nicely

直接IDA打开,找到flag函数,拼写出了就行 2020 DawgCTF Re WP
DawgCTF{+h@nk_Y0U}
   

Put your thang down flip it and reverse it

代码分析

IDA打开函数
__int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
  puts("Let me search ya.");
  fgets(string, 44, stdin);
  if ( strnlen(string, 0x2BuLL) != 43 )
  {
    sub_1195();
    exit(1);
  }
  sub_12F2();
  sub_11F7();
  sub_11BB();
  return 0LL;
}

sub_1195函数:输出错误信息

int sub_1195()
{
  return puts("Wrong. You need to work it.");
}

 

sub_12F2函数:对输入进行取反

__int64 sub_12F2()
{
  __int64 result; // rax
  signed int i; // [rsp+0h] [rbp-4h]

  for ( i = 0; i <= 42; ++i )
  {
    result = i;
    string[i] = ~string[i];
  }
  return result;
}

 

sub_11F7:二进制取反与顺序取反

__int64 sub_11F7()
{
  __int64 result; // rax
  char v1; // ST07_1
  char v2; // [rsp+1h] [rbp-13h]
  signed int i; // [rsp+4h] [rbp-10h]
  unsigned int j; // [rsp+8h] [rbp-Ch]
  signed int k; // [rsp+Ch] [rbp-8h]

  v2 = 0;
  for ( i = 0; i <= 42; ++i )
  {
    for ( j = 0; j < 8; ++j )
    {
      if ( (unsigned __int8)string[i] & (unsigned __int8)(1 << j) )
        v2 |= 1 << (8 - j - 1);
    }
    result = i;
    string[i] = v2;
    v2 = 0;
  }
  for ( k = 0; k <= 20; ++k )
  {
    v1 = string[k];
    string[k] = string[42 - k];
    result = 42 - k;
    string[result] = v1;
  }
  return result;
}

所谓二进制取反,例如:23表示为二进制00010111,转换后为:11101000,232

 

sub_11BB:字符串比较

int sub_11BB()
{
  char *v0; // rsi
  int result; // eax

  v0 = s2;
  if ( !strncmp(string, s2, 0x2CuLL) )
    result = sub_11A8(string, v0);
  else
    result = sub_1195();
  return result;
}

 

s2的值已知,因此我们只需要逆向解就行。

 

脚本

# -*- coding:utf-8 -*-
model = [0x41,0xF5,0x51,0xD1,0x4d,0x61,0xd5,0xe9,
         0x69,0x89,0x19,0xdd,0x09,0x11,0x89,0xcb,
         0x9d,0xc9,0x69,0xf1,0x6d,0xd1,0x7d,0x89,
         0xd9,0xb5,0x59,0x91,0x59,0xb1,0x31,0x59,
         0x6d,0xd1,0x8b,0x21,0x9d,0xd5,0x3d,0x19,
         0x11,0x79,0xd0]

for i in range(21):
    model[i],model[42-i] = model[42-i],model[i]

for i in range(43):
    tmp = int(bin(model[i]).replace('0b','').rjust(8,'0')[::-1],2)
    tmp = ~tmp&0xFF
    print (chr(tmp),end="")

 

get flag!

DawgCTF{.tIesreveRdnAtIpilF,nwoDgnihTyMtuP}

 

Elf in the Elf 

文件分析

里面有4408个文件,我们通过分析文件,发现里面的math函数算法都相同,不过里面的运算不同,整个文件分为了加,减,异或,取反和直接比较。

加法

/x83/xc2 特征码为加法,操作符号读取位置:0x116e,[rbp+var_1]数据读取位置:0x1165,减数读取位置:0x1170

.text:000000000000115F 88 45 EC                                      mov     [rbp+var_14], al
.text:0000000000001162 C6 45 FF 0D                                   mov     [rbp+var_1], 0Dh
.text:0000000000001166 0F BE 45 FF                                   movsx   eax, [rbp+var_1]
.text:000000000000116A 0F BE 55 EC                                   movsx   edx, [rbp+var_14]
.text:000000000000116E 83 C2 0D                                      add     edx, 0Dh
.text:0000000000001171 39 D0                                         cmp     eax, edx
.text:0000000000001173 75 0E                                         jnz     short loc_1183
 

减法

/x83/xea 特征码为减法,操作符号读取位置:0x116e,[rbp+var_1]数据读取位置:0x1165,减数读取位置:0x1170

.text:000000000000115D 89 F8                                         mov     eax, edi
.text:000000000000115F 88 45 EC                                      mov     [rbp+var_14], al
.text:0000000000001162 C6 45 FF 4B                                   mov     [rbp+var_1], 4Bh ; 'K'
.text:0000000000001166 0F BE 45 FF                                   movsx   eax, [rbp+var_1]
.text:000000000000116A 0F BE 55 EC                                   movsx   edx, [rbp+var_14]
.text:000000000000116E 83 EA 01                                      sub     edx, 1
.text:0000000000001171 39 D0                                         cmp     eax, edx

 

异或

\x83\xf0 特征码为异或,操作方式读取位置:0x116A,[rbp+var_1]数据读取位置:0x1165,异或值读取位置:0x116c
.text:000000000000115D 89 F8                                         mov     eax, edi
.text:000000000000115F 88 45 EC                                      mov     [rbp+var_14], al
.text:0000000000001162 C6 45 FF 26                                   mov     [rbp+var_1], 26h ; '&'
.text:0000000000001166 0F B6 45 EC                                   movzx   eax, [rbp+var_14]
.text:000000000000116A 83 F0 59                                      xor     eax, 59h
.text:000000000000116D 38 45 FF                                      cmp     [rbp+var_1], al
.text:0000000000001170 75 0E                                         jnz     short loc_1180
 

取反

\xf7\xd0 特征码为取反,操作方式读取位置:0x116A,[rbp+var_1]数据读取位置:0x1165

.text:000000000000115F 88 45 EC                                      mov     [rbp+var_14], al
.text:0000000000001162 C6 45 FF FF                                   mov     [rbp+var_1], 0FFh
.text:0000000000001166 0F B6 45 EC                                   movzx   eax, [rbp+var_14]
.text:000000000000116A F7 D0                                         not     eax
.text:000000000000116C 38 45 FF                                      cmp     [rbp+var_1], al
.text:000000000000116F 75 0E                                         jnz     short loc_117F
.text:0000000000001171 48 8D 3D 8C 0E 00 00                          lea     rdi, s          ; "Correct"

 

直接比较

\x3a\x45 特征码为直接比较,操作方式读取位置:0x116A,[rbp+var_1]数据读取位置:0x1165

.text:000000000000115D 89 F8                                         mov     eax, edi
.text:000000000000115F 88 45 EC                                      mov     [rbp+var_14], al
.text:0000000000001162 C6 45 FF 00                                   mov     [rbp+var_1], 0
.text:0000000000001166 0F B6 45 FF                                   movzx   eax, [rbp+var_1]
.text:000000000000116A 3A 45 EC                                      cmp     al, [rbp+var_14]
.text:000000000000116D 75 0E                                         jnz     short loc_117D
.text:000000000000116F 48 8D 3D 8E 0E 00 00                          lea     rdi, s          ; "Correct"

 

总结

因为[rbp+var_1]数据读取位置都在0x1165,而加减法可以归为同一类,操作数的特征码第二位不同,因此我们对于加减法和异或,各需要一个变量读取另一个数据。

因为在这几个操作中,同一位置特征码不同,因此我们可以用异或的另一数据位置的特征码,判断加减操作;用加减的数据的特征码,判断异或,取反,直接比较。

 

文件多合一

# -*- coding:utf-8 -*-

enc = []
filep = "C:\\Users\\10245\\Desktop\\elfs\\elf_"
for i in range(4408):
    path = filep + str(i)
    print (path)
    with open(path, 'rb') as f:
        f.seek(0x1165,0) # [rbp+var_1]数据读取位置
        rnum = ord(f.read(1))
        f.seek(0x116c,0) # 加减法判断,异或数据
        lnum = ord(f.read(1))
        f.seek(0x1170,0) # 加减法数据
        rrnum = ord(f.read(1))
        print (rnum,lnum,rrnum)
        if lnum == 0x55:
            f.seek(0x116f,0)
            sm = ord(f.read(1))
            if sm == 0xc2:
                enc.append((rnum-rrnum)&0xff)
            else:
                enc.append((rnum+rrnum)&0xff)
        elif rrnum == 0x75:
            enc.append(rnum^lnum)
        elif rrnum == 0x8d:
            enc.append(rnum)
        elif rrnum == 0xe:
            enc.append((~rnum)&0xff)
        else:
            print ('error')
            exit(0)

with open(r'C:\Users\10245\Desktop\flag','wb') as f:
    s = bytearray(enc)
    # print (s)
    f.write(s)

得到flag文件

2020 DawgCTF Re WP

这就是一段异或操作

 

脚本

# -*- coding:utf-8 -*-

model = [0x2d,0x08,0x1e,0x0e,0x2a,0x3d,0x2f,0x12,0x1a,0x1e,0x29,
         0x0e,0x36,0x58,0x07,0x36,0x1d,0x01,0x5a,0x36,0x0f,0x05,
         0x29,0x0e,0x14,0x63]

for i in model:
    print (chr(i^0x69),end="")

 

get flag!

DawgCTF{sw@g_1n_th3_fl@g}

上一篇:深入理解 C++ 中的 RVO


下一篇:2020 UNCTF RE 复现