Ha1cyon_CTF-公开赛(wp)

一.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;
}

讲下面代码分部分讲解//数码管显示 module seg_driver( input clk , input rst_n , input [31:0]data,//待显示的数据 output wire[7:0] sel , output wire[7:0] seg ); //wire [31:0]data; // assign dig_seg = 8'd0; // assign dig_sel = 1'b0; reg [7:0] dig_sel; reg [7:0] dig_seg; localparam NUM_0 = 8'hC0, NUM_1 = 8'hF9, NUM_2 = 8'hA4, NUM_3 = 8'hB0, NUM_4 = 8'h99, NUM_5 = 8'h92, NUM_6 = 8'h82, NUM_7 = 8'hF8, NUM_8 = 8'h80, NUM_9 = 8'h90, NUM_A = 8'h88, NUM_B = 8'h83, NUM_C = 8'hC6, NUM_D = 8'hA1, NUM_E = 8'h86, NUM_F = 8'h8E, LIT_ALL = 8'h00, BLC_ALL = 8'hFF; parameter CNT_REF = 25'd1000; reg [9:0] cnt_20us; //20us计数器 reg [3:0] data_tmp; //用于取出不同位选的显示数据 // assign data = 32'hABCD_4413; //描述位选信号切换 //描述刷新计数器 always@(posedge clk or negedge rst_n)begin if(!rst_n)begin cnt_20us <= 25'd0; end else if(cnt_20us >= CNT_REF - 25'd1)begin cnt_20us <= 25'd0; end else begin cnt_20us <= cnt_20us + 25'd1; end end always@(posedge clk or negedge rst_n)begin if(!rst_n)begin dig_sel <= 8'hfe;//8'b1111_1110 end else if(cnt_20us >= CNT_REF - 25'd1)begin dig_sel <= {dig_sel[6:0],dig_sel[7]}; end else begin dig_sel <= dig_sel; end end assign sel = dig_sel; //段选信号描述 always@(posedge clk or negedge rst_n)begin if(!rst_n)begin data_tmp <= 4'd0; end else begin case(sel) 8'b1111_1110:data_tmp <= data[ 3-:4]; 8'b1111_1101:data_tmp <= data[ 7-:4]; 8'b1111_1011:data_tmp <= data[11-:4]; 8'b1111_0111:data_tmp <= data[15-:4]; 8'b1110_1111:data_tmp <= data[19-:4]; 8'b1101_1111:data_tmp <= data[23-:4]; 8'b1011_1111:data_tmp <= data[27-:4]; 8'b0111_1111:data_tmp <= data[31-:4]; default: data_tmp <= 4'hF; endcase end end always@(posedge clk or negedge rst_n)begin if(!rst_n)begin dig_seg <= BLC_ALL; end else begin case(data_tmp) 4'h0 : dig_seg <= NUM_0; 4'h1 : dig_seg <= NUM_1; 4'h2 : dig_seg <= NUM_2; 4'h3 : dig_seg <= NUM_3; 4'h4 : dig_seg <= NUM_4; 4'h5 : dig_seg <= NUM_5; 4'h6 : dig_seg <= NUM_6; 4'h7 : dig_seg <= NUM_7; 4'h8 : dig_seg <= NUM_8; 4'h9 : dig_seg <= NUM_9; 4'hA : dig_seg <= NUM_A; 4'hB : dig_seg <= NUM_B; 4'hC : dig_seg <= NUM_C; 4'hD : dig_seg <= NUM_D; 4'hE : dig_seg <= NUM_E; 4'hF : dig_seg <= NUM_F; default: ; endcase end end assign seg = dig_seg ; endmodule
最新发布
06-09
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值