首页
社区
课程
招聘
[原创]BUUCTF逆向题:[MRCTF2020]Xor
发表于: 2022-3-20 18:03 4166

[原创]BUUCTF逆向题:[MRCTF2020]Xor

2022-3-20 18:03
4166

1.基本信息探查:

1.EXEinfo:

32位,无壳


2.运行一下:

2.IDA分析:

找到主函数,直接F5,发现ida报错了:

显示反汇编失败,说虚拟地址401095处的call分析失败。

做法一:直接分析汇编代码

大概看一下程序流程,了解一下flag验证过程:

下面列几个关键点:

  1. 输入输出:

    ; int __cdecl main(int argc, const char **argv, const char **envp)
    _main proc near
    
    argc= dword ptr  4
    argv= dword ptr  8
    envp= dword ptr  0Ch
    
    push    offset aGiveMeYourFlag ; "Give Me Your Flag String:\\n"
    call    sub_401020       //printf上面的字符串
    push    64h ; 'd'
    push    offset byte_4212C0
    push    offset aS       ; "%s"
    call    sub_401050     //scanf接受flag
    mov     edx, offset byte_4212C0
    add     esp, 10h
    lea     ecx, [edx+1]
  2. 验证串长:

    sub     edx, ecx
    cmp     edx, 1Bh    //判断串长是否为27
    jnz     short loc_4010FF      //跳转到输出函数,输出“Wrong!”
  3. 字符串比较:

    xor     eax, eax    //eax置零
    db      66h, 66h
    nop     word ptr [eax+eax+00000000h]  
    
    loc_4010D0:
    mov     cl, byte_4212C0[eax]  //byte_4212C0处的地址为接受flag的地址
    xor     cl, al              //flag中eax处的值与eax异或
    cmp     cl, ds:byte_41EA08[eax]  //异或后和byte_41EA08[eax]进行比较
    jnz     short loc_4010FF        //不相等则输出“Wrong”
    
    inc     eax     //eax累加
    cmp     eax, edx    //做edx次循环          
    jb      short loc_4010D0

    这里就是将flag循环异或然后和一个字符串进行比较。提取进行比较的字符串

    .rdata:0041EA08 byte_41EA08     db 4Dh                  ; DATA XREF: _main+48↑r
    .rdata:0041EA09 aSawbFxzJTqjNBp db 'SAWB~FXZ:J:`tQJ"N@ bpdd}8g',0
    
    //MSAWB~FXZ:J:`tQJ"N@ bpdd}8g

    最后循环做满意味着flag验证通过,输出字符串”Right!“

做法二:分析报错想办法整出源代码

这里看一下call函数这里的汇编代码:

.text:00401090     push  offset aGiveMeYourFlag ; "Give Me Your Flag String:\\n"
.text:00401095     call  sub_401020

将一串字符压入栈,然后调用函数(这里基本可以断定是输出),接着跟入函数去看一下

int sub_401020(int a1, ...)

这里可能是参数的个数识别错误,主函数那边只压栈了一个函数,而子函数这边识别却出了问题,在子函数上按y修改里面的变量为:

改完后再F5,就能成功反汇编了。上面方法一对程序的逻辑已做分析这里就不再阐述,正如题目所说就是简单的xor。

// positive sp value has been detected, the output may be wrong!
int __cdecl main(int argc, const char **argv, const char **envp)
{
  unsigned int i; // eax

  printf((int)"Give Me Your Flag String:\\n");
  scanf("%s", flag_space);
  if ( strlen(flag_space) != 27 )
  {
LABEL_6:
    printf((int)"Wrong!\\n");
    ((void (__cdecl *)(const char *))sub_404B7E)("pause");
    _loaddll(0);
    __debugbreak();
  }
  for ( i = 0; i < 0x1B; ++i )
  {
    if ( ((unsigned __int8)i ^ (unsigned __int8)flag_space[i]) != rflag[i] )
      goto LABEL_6;
  }
  printf((int)"Right!\\n");
  ((void (__cdecl *)(const char *))sub_404B7E)("pause");
  return 0;
}

3.EXP:

写exp时注意字符串内含双引号,需要用转义字符

rflag = "MSAWB~FXZ:J:`tQJ\\"N@ bpdd}8g"
flag = ""

for i in range(27):
    flag += chr(ord(rflag[i]) ^ i)

print(flag)

MRCTF{@_R3@1ly_E2_R3verse!}



[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//