Ha1cyon_CTF-公开赛(wp)
阅读原文时间:2023年07月08日阅读:2

一.babyasm

00007FF7A8AC5A50  push        rbp
00007FF7A8AC5A52  push        rdi
00007FF7A8AC5A53  sub         rsp,238h
00007FF7A8AC5A5A  lea         rbp,[rsp+20h]
00007FF7A8AC5A5F  mov         rdi,rsp
00007FF7A8AC5A62  mov         ecx,8Eh
00007FF7A8AC5A67  mov         eax,0CCCCCCCCh
00007FF7A8AC5A6C  rep stos    dword ptr [rdi]
00007FF7A8AC5A6E  mov         rax,qword ptr [__security_cookie (07FF7A8AD3018h)]
00007FF7A8AC5A75  xor         rax,rbp
00007FF7A8AC5A78  mov         qword ptr [rbp+208h],rax
00007FF7A8AC5A7F  lea         rcx,[__06A15900_ConsoleApplication@cpp (07FF7A8AD902Ah)]
00007FF7A8AC5A86  call        __CheckForDebuggerJustMyCode (07FF7A8AC1122h)
00007FF7A8AC5A8B  lea         rdx,[string "flag{this_is_a_fake_flag}" (07FF7A8ACF450h)]
00007FF7A8AC5A92  lea         rcx,[flag]
00007FF7A8AC5A96  call        std::basic_string<char,std::char_traits<char>,std::allocator<char> >::basic_string<char,std::char_traits<char>,std::allocator<char> > (07FF7A8AC15E1h)
00007FF7A8AC5A9B  nop
00007FF7A8AC5A9C  mov         dword ptr [p],0
00007FF7A8AC5AA3  mov         dword ptr [rbp+64h],0
00007FF7A8AC5AAA  jmp         main+64h (07FF7A8AC5AB4h)
00007FF7A8AC5AAC  mov         eax,dword ptr [rbp+64h]
00007FF7A8AC5AAF  inc         eax
00007FF7A8AC5AB1  mov         dword ptr [rbp+64h],eax
00007FF7A8AC5AB4  movsxd      rax,dword ptr [rbp+64h]
00007FF7A8AC5AB8  mov         qword ptr [rbp+1F8h],rax
00007FF7A8AC5ABF  lea         rcx,[flag]
00007FF7A8AC5AC3  call        std::basic_string<char,std::char_traits<char>,std::allocator<char> >::length (07FF7A8AC122Bh)
00007FF7A8AC5AC8  mov         rcx,qword ptr [rbp+1F8h]
00007FF7A8AC5ACF  cmp         rcx,rax
00007FF7A8AC5AD2  jae         main+1B2h (07FF7A8AC5C02h)
00007FF7A8AC5AD8  mov         eax,dword ptr [rbp+64h]
00007FF7A8AC5ADB  and         eax,1
00007FF7A8AC5ADE  cmp         eax,1
00007FF7A8AC5AE1  jne         main+126h (07FF7A8AC5B76h)
00007FF7A8AC5AE7  movsxd      rax,dword ptr [rbp+64h]
00007FF7A8AC5AEB  mov         rdx,rax
00007FF7A8AC5AEE  lea         rcx,[flag]
00007FF7A8AC5AF2  call        std::basic_string<char,std::char_traits<char>,std::allocator<char> >::operator[] (07FF7A8AC1442h)
00007FF7A8AC5AF7  movsx       eax,byte ptr [rax]
00007FF7A8AC5AFA  xor         eax,42h
00007FF7A8AC5AFD  mov         dword ptr [p],eax
00007FF7A8AC5B00  mov         dl,30h
00007FF7A8AC5B02  lea         rcx,[rbp+144h]
00007FF7A8AC5B09  call        std::setfill<char> (07FF7A8AC1046h)
00007FF7A8AC5B0E  mov         qword ptr [rbp+1F8h],rax
00007FF7A8AC5B15  mov         edx,2
00007FF7A8AC5B1A  lea         rcx,[rbp+168h]
00007FF7A8AC5B21  call        std::setw (07FF7A8AC10D2h)
00007FF7A8AC5B26  mov         qword ptr [rbp+200h],rax
00007FF7A8AC5B2D  lea         rdx,[std::hex (07FF7A8AC1488h)]
00007FF7A8AC5B34  mov         rcx,qword ptr [__imp_std::cout (07FF7A8AD71C0h)]
00007FF7A8AC5B3B  call        qword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (07FF7A8AD7160h)]
00007FF7A8AC5B41  mov         rcx,qword ptr [rbp+200h]
00007FF7A8AC5B48  mov         rdx,rcx
00007FF7A8AC5B4B  mov         rcx,rax
00007FF7A8AC5B4E  call        std::operator<<<char,std::char_traits<char>,__int64> (07FF7A8AC12F8h)
00007FF7A8AC5B53  mov         rcx,qword ptr [rbp+1F8h]
00007FF7A8AC5B5A  mov         rdx,rcx
00007FF7A8AC5B5D  mov         rcx,rax
00007FF7A8AC5B60  call        std::operator<<<char,std::char_traits<char>,char> (07FF7A8AC11A4h)
00007FF7A8AC5B65  mov         edx,dword ptr [p]
00007FF7A8AC5B68  mov         rcx,rax
00007FF7A8AC5B6B  call        qword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (07FF7A8AD7158h)]
00007FF7A8AC5B71  jmp         main+1ADh (07FF7A8AC5BFDh)
00007FF7A8AC5B76  movsxd      rax,dword ptr [rbp+64h]
00007FF7A8AC5B7A  mov         rdx,rax
00007FF7A8AC5B7D  lea         rcx,[flag]
00007FF7A8AC5B81  call        std::basic_string<char,std::char_traits<char>,std::allocator<char> >::operator[] (07FF7A8AC1442h)
00007FF7A8AC5B86  movsx       eax,byte ptr [rax]
00007FF7A8AC5B89  mov         dword ptr [p],eax
00007FF7A8AC5B8C  mov         dl,30h
00007FF7A8AC5B8E  lea         rcx,[rbp+194h]
00007FF7A8AC5B95  call        std::setfill<char> (07FF7A8AC1046h)
00007FF7A8AC5B9A  mov         qword ptr [rbp+1F8h],rax
00007FF7A8AC5BA1  mov         edx,2
00007FF7A8AC5BA6  lea         rcx,[rbp+1B8h]
00007FF7A8AC5BAD  call        std::setw (07FF7A8AC10D2h)
00007FF7A8AC5BB2  mov         qword ptr [rbp+200h],rax
00007FF7A8AC5BB9  lea         rdx,[std::hex (07FF7A8AC1488h)]
00007FF7A8AC5BC0  mov         rcx,qword ptr [__imp_std::cout (07FF7A8AD71C0h)]
00007FF7A8AC5BC7  call        qword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (07FF7A8AD7160h)]
00007FF7A8AC5BCD  mov         rcx,qword ptr [rbp+200h]
00007FF7A8AC5BD4  mov         rdx,rcx
00007FF7A8AC5BD7  mov         rcx,rax
00007FF7A8AC5BDA  call        std::operator<<<char,std::char_traits<char>,__int64> (07FF7A8AC12F8h)
00007FF7A8AC5BDF  mov         rcx,qword ptr [rbp+1F8h]
00007FF7A8AC5BE6  mov         rdx,rcx
00007FF7A8AC5BE9  mov         rcx,rax
00007FF7A8AC5BEC  call        std::operator<<<char,std::char_traits<char>,char> (07FF7A8AC11A4h)
00007FF7A8AC5BF1  mov         edx,dword ptr [p]
00007FF7A8AC5BF4  mov         rcx,rax
00007FF7A8AC5BF7  call        qword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (07FF7A8AD7158h)]
00007FF7A8AC5BFD  jmp         main+5Ch (07FF7A8AC5AACh)
00007FF7A8AC5C02  mov         dword ptr [rbp+1E4h],0
00007FF7A8AC5C0C  lea         rcx,[flag]
00007FF7A8AC5C10  call        std::basic_string<char,std::char_traits<char>,std::allocator<char> >::~basic_string<char,std::char_traits<char>,std::allocator<char> > (07FF7A8AC1302h)
00007FF7A8AC5C15  mov         eax,dword ptr [rbp+1E4h]
00007FF7A8AC5C1B  mov         edi,eax
00007FF7A8AC5C1D  lea         rcx,[rbp-20h]
00007FF7A8AC5C21  lea         rdx,[__xt_z+540h (07FF7A8ACEFE0h)]
00007FF7A8AC5C28  call        _RTC_CheckStackVars (07FF7A8AC1596h)
00007FF7A8AC5C2D  mov         eax,edi
00007FF7A8AC5C2F  mov         rcx,qword ptr [rbp+208h]
00007FF7A8AC5C36  xor         rcx,rbp
00007FF7A8AC5C39  call        __security_check_cookie (07FF7A8AC1190h)
00007FF7A8AC5C3E  lea         rsp,[rbp+218h]
00007FF7A8AC5C45  pop         rdi
00007FF7A8AC5C46  pop         rbp
00007FF7A8AC5C47  ret

很无语,很多花指令没啥用的,给了个txt文件,应该是个加密过的,然后又给了asm文件,应该是个encoder,仔细看了看唯一动了flag的地方就是那个xor,额外关注一下,然后把加密后的转换成字符串,发现隔一个就会乱码,说明是突破点,同时发现验证后,就是偶数的时候异或,奇数不异或,写个脚本,过了

#301d7972751d6b2c6f355f3a38742d74341d61776d7d7d
str="662e61257b26301d7972751d6b2c6f355f3a38742d74341d61776d7d7d"
flag=""
w=0
for i in range(0,len(str),2):
    tmp=""
    tmp+=str[i]
    tmp+=str[i+1]
    if w%2==0:
        flag+=chr(int(tmp,16))
    else:
        a=int(tmp,16)^0x42
        flag+=chr(a)
    w+=1
# a=0x30^0x42
# print(chr(a))
print(flag)

二.Baby obfuscation

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int v3; // eax
  int v4; // ebx
  int v5; // esi
  int v6; // ebx
  int v7; // ebx
  int v8; // esi
  int v9; // edi
  int v10; // ebx
  int v11; // ebx
  int v12; // ebx
  int v13; // esi
  int v14; // eax
  int v15; // ebx
  int v16; // esi
  int v17; // ebx
  int v18; // eax
  bool v19; // bl
  int v20; // eax
  int v21; // esi
  int v22; // ebx
  int v23; // ebx
  int v24; // eax
  int v25; // eax
  int v26; // eax
  int v27; // eax
  int v28; // ebx
  int a[64]; // [rsp+20h] [rbp-60h]
  int v31; // [rsp+120h] [rbp+A0h]
  char Str[1008]; // [rsp+130h] [rbp+B0h]
  int v33[1000]; // [rsp+520h] [rbp+4A0h]
  int v34; // [rsp+14C0h] [rbp+1440h]
  int v35; // [rsp+14D0h] [rbp+1450h]
  int v36; // [rsp+14D4h] [rbp+1454h]
  int v37; // [rsp+14D8h] [rbp+1458h]
  int v38; // [rsp+14DCh] [rbp+145Ch]
  int v39; // [rsp+14E0h] [rbp+1460h]
  int v40; // [rsp+14E4h] [rbp+1464h]
  int v41; // [rsp+14E8h] [rbp+1468h]
  int v42; // [rsp+14ECh] [rbp+146Ch]
  int v43; // [rsp+14F0h] [rbp+1470h]
  int k; // [rsp+14F4h] [rbp+1474h]
  int j; // [rsp+14F8h] [rbp+1478h]
  int i; // [rsp+14FCh] [rbp+147Ch]

  _main();
  memset(v33, 0, sizeof(v33));
  v34 = 0;
  memset(a, 0, sizeof(a));
  v31 = 0;
  for ( i = 0; i <= 64; ++i )
    a[i] = i + 1;
  v39 = 2;
  v40 = 3;
  v41 = 4;
  v42 = 5;
  v35 = 2;
  v36 = 3;
  v37 = 4;
  v38 = 5;
  puts("WHERE IS MY KEY!?");
  scanf("%32s", Str);
  v43 = strlen(Str);                            // 字符串长度
  v3 = F0X1(a[j], a[j]);                        // F0x1为求最大公约数
  for ( j = v3 / a[j]; j <= v43; ++j )
  {
    v4 = (a[j] + a[j + 1]) * (a[j] + a[j + 1]);
    if ( v4 >= F0X5(2, 2) * a[j] * a[j + 1] )   // 看位数里有多少个1
    {
      v5 = ~Str[F0X4(j, 1)];                    // 减一
      v6 = F0X4(j, 1);
      v33[j] = ~(v5 + *(&v39 + v6 % F0X5(2, 2)));// F0x5是2的几次方
    }
    v7 = F0X1(a[j], a[j + 1]);
    if ( v7 > F0X1(a[j + 1], ~(~a[j + 1] + a[j])) )// 无视
    {
      v8 = v33[j];
      v9 = ~v33[j];
      v10 = F0X4(j, 1);
      v33[j] = ~(v9 + a[v10 % F0X5(2, 2)]) * v8;
    }
    v11 = a[j + 1];
    v12 = F0X5(2, 1) * v11;
    v13 = a[j];
    v14 = F0X5(2, 1);
    v15 = F0X1(v13 * v14, v12);                 // 2*a[j],2*a[j+1]
    v16 = F0X5(2, 1);
    if ( v15 == v16 * F0X1(a[j], a[j + 1]) )
    {
      v17 = F0X4(j, 1);
      v33[j] ^= *(&v39 + v17 % F0X5(2, 2));
    }
    v18 = F0X5(V0X3, a[j]);                     // 3的a[j]次方
    v19 = v18 < a[j] + 1;                       // false
    v20 = F0X5(2, 4);
    if ( F0X3(v20 >= j, v19) )                  // 无视
    {
      v21 = ~Str[F0X4(j, 1)];
      v22 = F0X4(j, 1);
      v33[j] ^= ~(v21 + *(&v39 + v22 % F0X5(2, 2)));
    }
    v23 = F0X5(2, 3);
    v24 = F0X1(a[j], a[j]);
    v33[j] *= v23 + F0X5(2, v24 / a[j]);
  }
  v25 = F0X5(2, 4);
  v26 = F0X4(v25, 1);
  if ( v26 == v43 )
  {
    v27 = F0X1(a[k], a[k]);
    for ( k = v27 / a[k]; k <= v43; ++k )
    {
      v28 = v33[k];
      if ( v28 == F0X4(A0X6[k], 1) / 10 )
        ++V0X2;
    }
    if ( V0X2 == v43 )
      puts("\nPASS");
    else
      puts("\nDENIED");
  }
  else
  {
    puts("\nDENIED");
  }
  return 0;
}

还是挺恶心人的,这么多逻辑运算,看上去挺吓人的,实际上,分析起来,发现挺简单的。。。

~ (~ a+b)这玩意的意思就是减法。。。花里胡哨。。

final=[0x0,0x1E79,0x1E79,0x2135,0x170D,0x1F41,0x1901,0x2CED,0x11F9,0x2649,0x2581,0x2DB5,0x14B5,0x25E5,0x2A31,0x30D5]
v33=[]
v39=[2,3,4,5]
v33.append(0)
for i in range(1,16):
    v33.append((final[i]-1)/10)
flag=""
for w in range(1,16):
    v33[w]/=10
    v33[w]=int(v33[w])
    v33[w]^=v39[(w-1)%4]
    v5=(~v33[w])-v39[(w-1)%4]
    flag+=chr(~v5&0xff)
print(flag)

第三题:

逻辑还是很清晰的,结果我用手逆了。。。。。。心态炸了。。。昂哥说要学会暴算,讲道理要听,

魔改了base64可还行,基本可以看出是4个字符,换成了三个字符,base64应该是3个ASCII字符,变成了4个字符。。。。直接爆破吧,手逆有点不现实,但是应该也能写出来,等wp吧,顺便学习一下

#include<cstdio>
#include<cstdlib>
#include<cstring>
using namespace std;
__int64 __fastcall find_pos(char a1)
{
  return strrchr("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234{}789+/=", a1)
       - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234{}789+/=";
}
char table[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234{}789+/=";
void *__fastcall RxEncode(const char *Str, int len)
{
  void *result; // rax
  int v3; // [rsp+18h] [rbp-38h]
  signed int v4; // [rsp+1Ch] [rbp-34h]
  int v5; // [rsp+20h] [rbp-30h]
  signed int v6; // [rsp+24h] [rbp-2Ch]
  int v7; // [rsp+28h] [rbp-28h]
  int v8; // [rsp+28h] [rbp-28h]
  signed int i; // [rsp+2Ch] [rbp-24h]
  unsigned char *v10; // [rsp+30h] [rbp-20h]
  unsigned char *s; // [rsp+38h] [rbp-18h]

  v3 = 3 * (len / 4);
  v4 = 0;
  v5 = 0;
  if ( Str[len - 1] == '=' )
    v4 = 1;
  if ( Str[len - 2] == '=' )
    ++v4;
  if ( Str[len - 3] == '=' )
    ++v4;
  if ( v4 == 3 )
  {
    v3 += 2;
  }
  else if ( v4 <= 3 )
  {
    if ( v4 == 2 )
    {
      v3 += 3;
    }
    else if ( v4 <= 2 )
    {
      if ( v4 )
      {
        if ( v4 == 1 )
          v3 += 4;
      }
      else
      {
        v3 += 4;
      }
    }
  }
  s =(unsigned char*)malloc(v3);
  if ( s )
  {
    memset(s, 0, v3);
    v10 = s;
    while ( v5 < len - v4 )
    {
      v6 = 0;
      v7 = 0;
      while ( v6 <= 3 && v5 < len - v4 )
      {
        v7 = (v7 << 6) | (char)find_pos(Str[v5]);
        ++v6;
        ++v5;
      }
      v8 = v7 << 6 * (4 - v6);
      for ( i = 0; i <= 2 && i != v6; ++i )
        *v10++ = v8 >> 8 * (2 - i);
    }
    *v10 = 0;
    result = s;
  }
  else
  {
    puts("No enough memory.");
    result = 0LL;
  }
  return result;
}
void Solve(int a,int b,int c,int trys)
{
    for(int i=0;i<strlen(table);i++)
        for(int j=0;j<strlen(table);j++)
            for(int k=0;k<strlen(table);k++)
                for(int l=0;l<strlen(table);l++)
                {
                    char test[4];
                    test[0]=table[i];
                    test[1]=table[j];
                    test[2]=table[k];
                    test[3]=table[l];
                    test[4]='\0';
                    unsigned char *str=(unsigned char *)RxEncode(test,4);
                    if(str[0]==a && str[1]==b && str[2]==c)
                    {
                        printf("%c%c%c%c  %d\n",table[i],table[j],table[k],table[l],trys);
                    }

                }
}//npuctf{w0w+y0U+cAn+r3lllY+dAnc3}
int main()
{
    int data[25]={0x9E,0x9B,0x9C,0xB5,0xFE,0x70,0xD3,0x0F,0xB2,0xD1,0x4F,0x9C,0x02,0x7F,0xAB,0xDE,0x59,0x65,0x63,0xE7,0x40,0x9D,0xCD,0xFA};
    for(int i=0;i<8;i++)
        Solve(data[3*i],data[3*i+1],data[3*i+2],i);
    return 0;
}

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器