buuctf re刷题笔记

简单记录两三道刷题的笔记和感悟

1.[FlareOn4]IgniteMe ##:

整体:

void __noreturn start()
{
  DWORD NumberOfBytesWritten; // [esp+0h] [ebp-4h] BYREF

  NumberOfBytesWritten = 0;
  hFile = GetStdHandle(0xFFFFFFF6);
  dword_403074 = GetStdHandle(0xFFFFFFF5);
  WriteFile(dword_403074, aG1v3M3T3hFl4g, 0x13u, &NumberOfBytesWritten, 0);
  sub_4010F0();
  if ( sub_401050() )
    WriteFile(dword_403074, aG00dJ0b, 0xAu, &NumberOfBytesWritten, 0);
  else
    WriteFile(dword_403074, aN0tT00H0tRWe7r, 0x24u, &NumberOfBytesWritten, 0);
  ExitProcess(0);
}

sub_401050:

int sub_401050()
{
  int v1; // [esp+0h] [ebp-Ch]
  int i; // [esp+4h] [ebp-8h]
  unsigned int j; // [esp+4h] [ebp-8h]
  char v4; // [esp+Bh] [ebp-1h]

  v1 = sub_401020((int)byte_403078);
  v4 = sub_401000();
  for ( i = v1 - 1; i >= 0; --i )
  {
    byte_403180[i] = v4 ^ byte_403078[i];
    v4 = byte_403078[i];
  }
  for ( j = 0; j < 0x27; ++j )
  {
    if ( byte_403180[j] != (unsigned __int8)byte_403000[j] )
      return 0;
  }
  return 1;
}

sub_401000主要看下这个函数,得到v4

__int16 sub_401000()
{
  return (unsigned __int16)__ROL4__(-2147024896, 4) >> 1;
}

发现被写到了内存里,我们利用ida动调下
72IS926~IQF)R{FINLI}26X.png

发现是4

根据sub_401050这个函数,最好要进行一次比对,才会返回1,所以,这个最后比对的值是知道的,直接把这个值跟之前进行异或即可
exp:

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

key = [0x0D,0x26,0x49,0x45,0x2A,0x17,0x78,0x44,0x2B,0x6C,0x5D,0x5E,0x45,0x12,0x2F,0x17,
0x2B,0x44,0x6F,0x6E,0x56,0x09,0x5F,0x45,0x47,0x73,0x26,0x0A,0x0D,0x13,0x17,0x48,
0x42,0x01,0x40,0x4D,0x0C,0x02,0x69]

value = []
v4 = 4
for i in range(len(key)-1,-1,-1):
    value.append(key[i] ^ v4)
    v4 = arr1[-1]
print ('flag{'+''.join([chr(x) for x in key[::-1]])+'}')

2.[MRCTF2020]Xor ##:

![@SR[P1%{]5EO@}Z6)6XRFEE.png][2]

由于没法查看ida伪代码,。所以这里分析了汇编,可以明显看出是简单的异或,这里直接fuzz一下异或是能够求出flag

exp:

str1 = 'MSAWB~FXZ:J:`tQJ"N@ bpdd}8g'
str2 = ''
for i in range(len(str1)):
    str2 += chr(i ^ ord(str1[i]))
print(str2)

3.[GWCTF 2019]xxor ##:

__int64 __fastcall main(int a1, char **a2, char **a3)
{
  int i; // [rsp+8h] [rbp-68h]
  int j; // [rsp+Ch] [rbp-64h]
  __int64 v6[6]; // [rsp+10h] [rbp-60h] BYREF
  __int64 v7[6]; // [rsp+40h] [rbp-30h] BYREF

  v7[5] = __readfsqword(0x28u);
  puts("Let us play a game?");
  puts("you have six chances to input");
  puts("Come on!");
  memset(v6, 0, 40);
  for ( i = 0; i <= 5; ++i )
  {
    printf("%s", "input: ");
    a2 = (char **)((char *)v6 + 4 * i);
    __isoc99_scanf("%d", a2);
  }
  memset(v7, 0, 40);
  for ( j = 0; j <= 2; ++j )
  {
    dword_601078 = v6[j];
    dword_60107C = HIDWORD(v6[j]);
    a2 = (char **)&unk_601060;
    sub_400686(&dword_601078, &unk_601060);
    LODWORD(v7[j]) = dword_601078;
    HIDWORD(v7[j]) = dword_60107C;
  }
  if ( (unsigned int)sub_400770(v7, a2) != 1 )
  {
    puts("NO NO NO~ ");
    exit(0);
  }
  puts("Congratulation!\n");
  puts("You seccess half\n");
  puts("Do not forget to change input to hex and combine~\n");
  puts("ByeBye");
  return 0LL;
}

sub_400686:

__int64 __fastcall sub_400686(unsigned int *a1, _DWORD *a2)
{
  __int64 result; // rax
  unsigned int v3; // [rsp+1Ch] [rbp-24h]
  unsigned int v4; // [rsp+20h] [rbp-20h]
  int v5; // [rsp+24h] [rbp-1Ch]
  unsigned int i; // [rsp+28h] [rbp-18h]

  v3 = *a1;
  v4 = a1[1];
  v5 = 0;
  for ( i = 0; i <= 0x3F; ++i )
  {
    v5 += 1166789954;
    v3 += (v4 + v5 + 11) ^ ((v4 << 6) + *a2) ^ ((v4 >> 9) + a2[1]) ^ 0x20;
    v4 += (v3 + v5 + 20) ^ ((v3 << 6) + a2[2]) ^ ((v3 >> 9) + a2[3]) ^ 0x10;
  }
  *a1 = v3;
  result = v4;
  a1[1] = v4;
  return result;
}

可以发现这里进行了数据的一个异或处理,这里我们只要跟它反向来即可,也就是+变-
sub_400770:

__int64 __fastcall sub_400770(_DWORD *a1)
{
  if ( a1[2] - a1[3] == 2225223423LL
    && a1[3] + a1[4] == 4201428739LL
    && a1[2] - a1[4] == 1121399208LL
    && *a1 == -548868226
    && a1[5] == -2064448480
    && a1[1] == 550153460 )
  {
    puts("good!");
    return 1LL;
  }
  else
  {
    puts("Wrong!");
    return 0LL;
  }
}

这个只知道几个变量,这里我们可以用z3求出其余变量
z3.py:

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

from z3 import *

a2,a3,a4 = BitVecs('a2 a3 a4',64)
s = Solver()
s.add(a2 - a3 == 2225223423)
s.add(a3 + a4 == 4201428739)
s.add(a2 - a4 == 1121399208)
if s.check() == sat:
    m = s.model()
    for i in m:
        print("%s = %ld" % (i, m[i].as_long()))

求出以后,就可以按照正常操作进行写exp 了
exp:

#include <stdio.h>
int main()
{
    unsigned int xorm[6];
    xorm[0] = 3746099070;
    xorm[1] = 550153460;
    xorm[2] = 3774025685;
    xorm[3] = 1548802262;
    xorm[4] = 2652626477;
    xorm[5] = 2230518816;
    int i = 0,j=0,sum;
    int temp[2] = {0};
    int data[4] = { 2,2,3,4 };//unk哪个数字
    for (i = 0; i < 5; i += 2)
    {
        temp[0] = xorm[i];
        temp[1] = xorm[i + 1];

        sum = 0x458BCD42 * 64;
        for (j = 0; j < 64; j++)
        {
            temp[1] -= (temp[0] + sum + 20) ^ ((temp[0] << 6) + 3) ^ ((temp[0] >> 9) + 4) ^ 0x10;
            temp[0] -= (temp[1] + sum + 11) ^ ((temp[1] << 6) + 2) ^ ((temp[1] >> 9) + 2) ^ 0x20;
            sum -= 0x458BCD42;
        }
        xorm[i] = temp[0];
        xorm[i + 1] = temp[1];
    }
    for (i = 0; i < 6; i++)
        printf("%c%c%c", *((char*)&xorm[i]+2), *((char*)&xorm[i] + 1), *(char*)&xorm[i]);
}

总结:学到了,逆向的基本操作,以后还要多多刷题,爬.......

本文链接:

http://azly.top/index.php/archives/8/
1 + 2 =
快来做第一个评论的人吧~