[BUUCTF]REVERSE——[Wangding Cup 2020 Blue Dragon Group] singal

[Wangding Cup 2020 Blue Dragon Group] singal

annex

step

  1. Routine inspection, 32-bit program, no shell
    Insert picture description here
  2. Try the program locally
    Insert picture description here
  3. 32-bit ida is loaded. First, find the main function and determine the style of the flag string. Flag{……}
    Insert picture description here
    According to the prompt string of the input point, find the corresponding function, and confirm that the length of the string is 15
    Insert picture description here
    right-click the function and find the call The place of this function comes to the vm_operad() function. Look at the main function to know that the parameter v4 in vm_operad calls the qmemcpy function in the upper line. Baidu says that qmemcpy=memcpy in the reverse direction is the copy function of memcpy in the C language. , Copy 0x1C8 bytes of data in unk_403040 to v4
    unk_403040 This address has a lot of data copy 0x1C8 is
    Insert picture description here
    selected to 0x403208 , shift+e is converted into an array of
    Insert picture description here
    4 bytes equal to an int, the interl processor is little-endian storage, just right The value of the a1 array is the hexadecimal number before the three 00s. To sort it out,
    v4=[10, 4, 16, 8, 3, 5, 1, 4, 32, 8, 5, 3, 1, 3, 2, 8, 11, 1, 12, 8, 4, 4, 1, 5, 3, 8, 3, 33, 1, 11, 8, 11, 1, 4, 9, 8, 3, 32, 1, 2, 81, 8, 4, 36, 1, 12, 8, 11, 1, 5, 2, 8, 2, 37, 1, 2, 54, 8, 4, 65, 1, 2, 32, 8, 5, 1, 1, 5, 3, 8, 2, 37, 1, 4, 9, 8, 3, 32, 1, 2, 65, 8, 12, 1]
    pay attention to the little-endian order when the 32-bit program is stored. I will not reverse the order. Let’s look for the processing in the memory. Some data at the time

Then call the array and 114 enter the vm_operad function

int __cdecl vm_operad(int *a1, int _114)
{
  int result; // eax
  char Str[200]; // [esp+13h] [ebp-E5h] BYREF
  char v4; // [esp+DBh] [ebp-1Dh]
  int v5; // [esp+DCh] [ebp-1Ch]
  int v6; // [esp+E0h] [ebp-18h]
  int v7; // [esp+E4h] [ebp-14h]
  int v8; // [esp+E8h] [ebp-10h]
  int v9; // [esp+ECh] [ebp-Ch]

  v9 = 0;
  v8 = 0;
  v7 = 0;
  v6 = 0;
  v5 = 0;
  while ( 1 )
  {
    result = v9;
    if ( v9 >= _114 )
      return result;
    switch ( a1[v9] )
    {
      case 1:
        Str[v6 + 100] = v4;
        ++v9;
        ++v6;
        ++v8;
        break;
      case 2:
        v4 = a1[v9 + 1] + Str[v8];
        v9 += 2;
        break;
      case 3:
        v4 = Str[v8] - LOBYTE(a1[v9 + 1]);
        v9 += 2;
        break;
      case 4:
        v4 = a1[v9 + 1] ^ Str[v8];
        v9 += 2;
        break;
      case 5:
        v4 = a1[v9 + 1] * Str[v8];
        v9 += 2;
        break;
      case 6:
        ++v9;
        break;
      case 7:
        if ( Str[v7 + 100] != a1[v9 + 1] )
        {
          printf("what a shame...");
          exit(0);
        }
        ++v7;
        v9 += 2;
        break;
      case 8:
        Str[v5] = v4;
        ++v9;
        ++v5;
        break;
      case 10:
        read(Str);
        ++v9;
        break;
      case 11:
        v4 = Str[v8] - 1;
        ++v9;
        break;
      case 12:
        v4 = Str[v8] + 1;
        ++v9;
        break;
      default:
        continue;
    }
  }
}

When the value is equal to 7, the value of the str array will be compared with the next bit of the a1 array, and the equality will continue without waiting for an error. The number after 7 is the value that needs to be compared with the correct input after encryption, just the value of 7 is at the end of the a1 array, extract this string of values

str=[]
a1=[10, 4, 16, 8, 3, 5, 1, 4, 32, 8, 5, 3, 1, 3, 2, 8, 11, 1, 12, 8, 4, 4, 1, 5, 3, 8, 3, 33, 1, 11, 8, 11, 1, 4, 9, 8, 3, 32, 1, 2, 81, 8, 4, 36, 1, 12, 8, 11, 1, 5, 2, 8, 2, 37, 1, 2, 54, 8, 4, 65, 1, 2, 32, 8, 5, 1, 1, 5, 3, 8, 2, 37, 1, 4, 9, 8, 3, 32, 1, 2, 65, 8, 12, 1, 7, 34, 7, 63, 7, 52, 7, 50, 7, 114, 7, 51, 7, 24, 7, 167, 255, 255, 255, 7, 49, 7, 241, 255, 255, 255, 7, 40, 7, 132, 255, 255, 255, 7, 193, 255, 255, 255, 7, 30, 7, 122]
for i in range(0,len(a1)):
          if a1[i]==7:
                    str.append(a1[i+1])

print(a1)

Insert picture description here
str=[34, 63, 52, 50, 114, 51, 24, 167, 49, 241, 40, 132, 193, 30, 122]
Then the other case options in switch are operations on the str array, and finally get The value in str, the reverse algorithm to solve

There is a function called LOBYTE in it. When I did it, I went to Baidu. Some said it was the rightmost one, and some said the four digits on the right. There is no unified statement. I found the wp of other masters and said that this is a function of ida. Ignore this function. rax is a 64-bit register, eax is a 32-bit register, ax is a 16-bit register, al is the lower 8 bits of the ax register, and ah is the upper 8 bits of the ax register.
Insert picture description here

a1=[]
v4=[10, 4, 16, 8, 3, 5, 1, 4, 32, 8, 5, 3, 1, 3, 2, 8, 11, 1, 12, 8, 4, 4, 1, 5, 3, 8, 3, 33, 1, 11, 8, 11, 1, 4, 9, 8, 3, 32, 1, 2, 81, 8, 4, 36, 1, 12, 8, 11, 1, 5, 2, 8, 2, 37, 1, 2, 54, 8, 4, 65, 1, 2, 32, 8, 5, 1, 1, 5, 3, 8, 2, 37, 1, 4, 9, 8, 3, 32, 1, 2, 65, 8, 12, 1, 7, 34, 7, 63, 7, 52, 7, 50, 7, 114, 7, 51, 7, 24, 7, 167, 255, 255, 255, 7, 49, 7, 241, 255, 255, 255, 7, 40, 7, 132, 255, 255, 255, 7, 193, 255, 255, 255, 7, 30, 7, 122]
for i in range(0,len(v4)):
          if v4[i]==7:
                    a1.append(v4[i+1])
#print(a1)

a1 = [34, 63, 52, 50, 114, 51, 24, 167, 49, 241, 40, 132, 193, 30, 122]
a1.reverse()
v4.reverse()

v9 = 0
us = 0
v5 = 0
flag = []
for i in range(0, len(v4)):
    if i == len(v4) - 1:
        flag.append(us)

    if v4[i] == 1 and v4[i - 1] != 1:
        v5 = a1[v9]
        v9 += 1
        flag.append(us)

    if v4[i] == 2:
        if (v4[i + 1] != 3 and v4[i + 1] != 4 and v4[i + 1] != 5):
            us = v5 - v4[i - 1]
            # print(us,v5,a[i-1])

    if v4[i] == 3:
        if (v4[i + 1] != 2 and v4[i + 1] != 4 and v4[i + 1] != 5):
            us = v5 + v4[i - 1]  # LOBYTE是al有8位,参与运算的5、33、32是全值,所以LOBYTE可省略

    if v4[i] == 4:
        if (v4[i + 1] != 3 and v4[i + 1] != 2 and v4[i + 1] != 5):
            us = v5 ^ v4[i - 1]

    if v4[i] == 5:
        if (v4[i + 1] != 3 and v4[i + 1] != 4 and v4[i + 1] != 2):
            us = int(v5 / v4[i - 1])
    if v4[i] == 8:
        v5 = us

    if v4[i] == 11:
        us = v5 + 1

    if v4[i] == 12:
        us = v5 - 1
        # print("12:",us)

flag.reverse()
out = ''
for j in flag:
    out += chr(j)
print("flag{" + out + "}")

flag{757515121f3d478 }

Guess you like

Origin blog.csdn.net/mcmuyanga/article/details/114309960