re题(26)BUUFCTF-[2019红帽杯]easyRE

BUUCTF在线评测 (buuoj.cn)

f12查看字符串,找到关键字符串

 跳转过去,点黄色的部分再跳转 

f5反汇编 

分析一下

开头就是三个字符串,因为后面有个循环是36次,这三个字符串加起来长度也是36,我们推测这三个字符串是连在一起的

__int64 sub_4009C6()
{
  __int64 result; // rax
  int i; // [rsp+Ch] [rbp-114h]
  __int64 v2; // [rsp+10h] [rbp-110h]
  __int64 v3; // [rsp+18h] [rbp-108h]
  __int64 v4; // [rsp+20h] [rbp-100h]
  __int64 v5; // [rsp+28h] [rbp-F8h]
  __int64 v6; // [rsp+30h] [rbp-F0h]
  __int64 v7; // [rsp+38h] [rbp-E8h]
  __int64 v8; // [rsp+40h] [rbp-E0h]
  __int64 v9; // [rsp+48h] [rbp-D8h]
  __int64 v10; // [rsp+50h] [rbp-D0h]
  __int64 v11; // [rsp+58h] [rbp-C8h]
  char v12[13]; // [rsp+60h] [rbp-C0h] BYREF
  char v13[4]; // [rsp+6Dh] [rbp-B3h] BYREF
  char v14[19]; // [rsp+71h] [rbp-AFh] BYREF
  char v15[32]; // [rsp+90h] [rbp-90h] BYREF
  int v16; // [rsp+B0h] [rbp-70h]
  char v17; // [rsp+B4h] [rbp-6Ch]
  char v18[72]; // [rsp+C0h] [rbp-60h] BYREF
  unsigned __int64 v19; // [rsp+108h] [rbp-18h]

  v19 = __readfsqword(0x28u);
  qmemcpy(v12, "Iodl>Qnb(ocy", 12);
  v12[12] = 127;
  qmemcpy(v13, "y.i", 3);
  v13[3] = 127;
  qmemcpy(v14, "d`3w}wek9{iy=~yL@EC", sizeof(v14));
  memset(v15, 0, sizeof(v15));
  v16 = 0;
  v17 = 0;
  sub_4406E0(0LL, v15, 37LL);
  v17 = 0;
  if ( sub_424BA0(v15) == 36 )
  {
    for ( i = 0; i < (unsigned __int64)sub_424BA0(v15); ++i )
    {
      if ( (unsigned __int8)(v15[i] ^ i) != v12[i] )
      {
        result = 4294967294LL;
        goto LABEL_13;
      }
    }
    sub_410CC0("continue!");
    memset(v18, 0, 65);
    sub_4406E0(0LL, v18, 64LL);
    v18[39] = 0;
    if ( sub_424BA0(v18) == 39 )
    {
      v2 = sub_400E44(v18);
      v3 = sub_400E44(v2);
      v4 = sub_400E44(v3);
      v5 = sub_400E44(v4);
      v6 = sub_400E44(v5);
      v7 = sub_400E44(v6);
      v8 = sub_400E44(v7);
      v9 = sub_400E44(v8);
      v10 = sub_400E44(v9);
      v11 = sub_400E44(v10);
      if ( !(unsigned int)sub_400360(v11, off_6CC090) )
      {
        sub_410CC0("You found me!!!");
        sub_410CC0("bye bye~");
      }
      result = 0LL;
    }
    else
    {
      result = 4294967293LL;
    }
  }
  else
  {
    result = 0xFFFFFFFFLL;
  }
LABEL_13:
  if ( __readfsqword(0x28u) != v19 )
    sub_444020();
  return result;
}

 写个脚本爆破一下,这里v[12]12和v[13]3是数字,我在python中写\127,爆破的结果不对,是因为这是8进制的,写十六进制的\x7f就可以,或者写\177,爆破的结果只得到一条信息,然而并不是真正的flag

C语言——转义字符_c语言转义字符-CSDN博客

p='Iodl>Qnb(ocy\x7fy.i\x7fd`3w}wek9{iy=~yL@EC'

flag1 = []
for i in range(36):
        for key in range(32, 127):
            if chr(key ^ i) == p[i] :
                flag1.append(chr(key))
print(''.join(flag1))

#Info:The first four chars are `flag`

 

再往下看,又是一个循环,我们点进sub_400E44函数 

 sub_410CC0("continue!");
    memset(v18, 0, 65);
    sub_4406E0(0LL, v18, 64LL);
    v18[39] = 0;
    if ( sub_424BA0(v18) == 39 )
    {
      v2 = sub_400E44(v18);
      v3 = sub_400E44(v2);
      v4 = sub_400E44(v3);
      v5 = sub_400E44(v4);
      v6 = sub_400E44(v5);
      v7 = sub_400E44(v6);
      v8 = sub_400E44(v7);
      v9 = sub_400E44(v8);
      v10 = sub_400E44(v9);
      v11 = sub_400E44(v10);
      if ( !(unsigned int)sub_400360(v11, off_6CC090) )
      {
        sub_410CC0("You found me!!!");
        sub_410CC0("bye bye~");
      }

 

有点复杂,进入黄色的部分看看

 一看到这一串,我们可以猜到是base64加密,且加密了10次,我们找找是对什么进行了加密 

 

加密完是个if语句,里面有个函数,猜测是个比较的函数,括号里是用来比较的两个字符串,看看第二个字符串是什么

 sub_410CC0("continue!");
    memset(v18, 0, 65);
    sub_4406E0(0LL, v18, 64LL);
    v18[39] = 0;
    if ( sub_424BA0(v18) == 39 )
    {
      v2 = sub_400E44(v18);
      v3 = sub_400E44(v2);
      v4 = sub_400E44(v3);
      v5 = sub_400E44(v4);
      v6 = sub_400E44(v5);
      v7 = sub_400E44(v6);
      v8 = sub_400E44(v7);
      v9 = sub_400E44(v8);
      v10 = sub_400E44(v9);
      v11 = sub_400E44(v10);
      if ( !(unsigned int)sub_400360(v11, off_6CC090) )
      {
        sub_410CC0("You found me!!!");
        sub_410CC0("bye bye~");
      }

我们点进去,一直找到源头,是一大串字符,看字符串的最后是两个等号,这也是base64加密的一个标志,我们对它进行10次base64解密 

 

 

是个网址,进去看看 

 

是篇文章,这是作者把理论运用到题目里了啊 

 

我们再往下找,发现没啥有用信息了,但是我们刚找字符串的时候是不是在字符串的下面发现了可疑的字符,点进去看一看

 

分析一下 

unsigned __int64 sub_400D35()
{
  unsigned __int64 result; // rax
  unsigned int v1; // [rsp+Ch] [rbp-24h]
  int i; // [rsp+10h] [rbp-20h]
  int j; // [rsp+14h] [rbp-1Ch]
  unsigned int v4; // [rsp+24h] [rbp-Ch]
  unsigned __int64 v5; // [rsp+28h] [rbp-8h]

  v5 = __readfsqword(0x28u);
  v1 = sub_43FD20(0LL) - qword_6CEE38;
  for ( i = 0; i <= 1233; ++i )
  {
    sub_40F790(v1);
    sub_40FE60();
    sub_40FE60();
    v1 = sub_40FE60() ^ 0x98765432;
  }
  v4 = v1;                                      // 上面都没用
  if ( ((unsigned __int8)v1 ^ byte_6CC0A0[0]) == 102 && (HIBYTE(v4) ^ (unsigned __int8)a0x56) == 103 )// v1等于v4,相当于v1第一个和最后一个字节和byte_6CC0A0的第一个和第四个字节异或,异或完的是f和g,猜测这个是v1这四个字母分别与byte_6CC0A0前四位异或完是flag。
前面第一条信息说前四个字符是flag,这里也可以知道v1是4个字符
为什么v1会是一个数组呢,因为HIBYTE()函数的作用是获取高字节也就是数组的最后一位,同时还有BYTE()、BYTE1()、BYTE2()第一个是获取数组的第一位,第二个就是获取第二位,依次类推。


                                                // 逆向异或可以得到v1数组也就是v4数组
  {
    for ( j = 0; j <= 24; ++j )
      sub_410E90((unsigned __int8)(byte_6CC0A0[j] ^ *((_BYTE *)&v4 + j % 4)));// 这是让byte_6CC0A0与v4数组循环异或,抑或完的就是flag
  }
  result = __readfsqword(0x28u) ^ v5;
  if ( result )
    sub_444020();
  return result;
}

写个脚本,得到flag

key2=[0x40,0x35,0x20,0x56,0x5D,0x18,0x22,0x45,0x17,0x2F,0x24,0x6E,0x62,0x3C,0x27,0x54,0x48,0x6C,0x24,0x6E,0x72,0x3C,0x32,0x45,0x5B]
key3='flag'
key4=[]
flag=[]
for x in range(4):
    key4.append(chr(key2[x] ^ ord(key3[x])))
print(key4)
for i in range(25):
    flag.append(chr(key2[i]^ord(key4[i%4])))
print(''.join(flag))
#flag{Act1ve_Defen5e_Test}

本题用到了主动防御,就是引导别人走向错误解题方向,把真正的解题方向隐藏起来,让人更难破解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值