Description Link to heading

3z

Attachement : chall

Solving Link to heading

Open the binary in ghidra, see that there are too many conditions in the check function.

void check(char *param_1)

{
  if (*param_1 >> 4 != '\x06') {
    bye();
  }
  if (param_1[1] != param_1[2]) {
    bye();
  }
  if (((byte)(param_1[6] | param_1[3]) != 0x7a) || ((byte)(param_1[6] & param_1[3]) != 0x42)) {
    bye();
  }
  if (param_1[0x1c] != param_1[4]) {
    bye();
  }
  if ((int)param_1[0x1d] * (int)param_1[5] == 0x3c0f) {
    if (((int)param_1[8] + (int)param_1[6] + (int)param_1[7] != 0x12e) ||
       ((int)param_1[7] * (int)param_1[6] - (int)param_1[8] != 0x2a8a)) {
      bye();
    }
  }
  else {
    bye();
  }
  if ((((int)param_1[9] - (int)param_1[8] == 5) && ((int)param_1[10] - (int)param_1[9] == 0x1b)) &&
     ((byte)(param_1[10] ^ param_1[0xb]) == 0x20)) {
    if (((param_1[0xc] != param_1[0xf]) || ((int)param_1[0xb] + (int)param_1[0xc] != 0xb4)) ||
       ((int)param_1[0xc] + (int)param_1[0xd] != 0xb9)) {
      bye();
    }
  }
  else {
    bye();
  }
  if (((int)param_1[0xd] + (int)param_1[0xe]) - (int)param_1[0x10] == (int)param_1[0xd]) {
    if (((int)param_1[0x11] + (int)param_1[0x10] == 0xd9) && (param_1[0x11] == param_1[0xd])) {
      if ((int)param_1[0xe] + (int)param_1[0x10] != param_1[0xe] * 2) {
        bye();
      }
    }
    else {
      bye();
    }
  }
  else {
    bye();
  }
  if (((param_1[0x12] == 'Z') && (param_1[0x12] == param_1[0x13])) &&
     ((byte)(param_1[0x15] ^ param_1[0x13] ^ param_1[0x14]) == 0x7f)) {
    if ((char)(param_1[0x14] ^ param_1[0x15] ^ param_1[0x16]) == param_1[0x15]) {
      if ((param_1[0x15] != '_') || ((int)param_1[6] + (int)param_1[0x18] != 0xb4)) {
        bye();
      }
    }
    else {
      bye();
    }
  }
  else {
    bye();
  }
  if ((int)param_1[0x18] + ~(int)param_1[0x17] != -0x21) {
    bye();
  }
  if (param_1[0x19] != param_1[9]) {
    bye();
  }
  if ((int)param_1[0x1b] + (int)param_1[0x1a] == 0xd4) {
    if (param_1[0x1b] == param_1[0x1c]) {
      puts("You got it!");
    }
    else {
      bye();
    }
  }
  else {
    bye();
  }
  return;
}

We can reverse the function with this code :

import string 
pattern = 'n00bz{00000000000000000000000}'
def change_char(s, c, idx):
    global pattern
    s = list(pattern)
    s[idx] = c
    pattern = "".join(s)
    
if __name__ == '__main__':
    data = string.ascii_letters + string.digits + '!@#$%^&*(){}_'
    for c in data:
        change_char(pattern, pattern[4], 0x1c)
        if ((ord(c) | ord(pattern[3])) == 0x7A) and ((ord(c) & ord(pattern[3])) == 0x42):
            change_char(pattern, c, 6)
        for j in data:
            if ((ord(c) + ord(pattern[6]) + ord(j)) == 0x12E) and \
            ((ord(j) * ord(pattern[6])) - ord(c)) == 0x2A8A:
                change_char(pattern, c, 8)
                change_char(pattern, j, 7)
        change_char(pattern, '_', 9)
        change_char(pattern, 'z', 0xA)
        change_char(pattern, 'Z', 0xB)
        for f in data:
            for g in data:
                for e in data:
                    if (ord(pattern[9]) - ord(pattern[8]) == 5) and (ord(pattern[0xA]) - ord(pattern[9]) == 0x1B) and ((ord(pattern[0xA]) ^ ord(pattern[0xB])) == 0x20):
                        if (f == g) and ((ord(pattern[0xB]) + ord(f)) == 0xB4) and ((ord(f) + ord(e)) == 0xB9):
                            change_char(pattern, f, 0xC)
                            change_char(pattern, e, 0xD)
                            change_char(pattern, g, 0xF)
        change_char(pattern, pattern[0xD], 0x11)
        change_char(pattern, chr(0xD9 - ord(pattern[0xD])), 0x10)
        change_char(pattern, 'z', 0xE)
        change_char(pattern, 'Z', 0x12)
        change_char(pattern, 'Z', 0x13)
        change_char(pattern, '_', 0x15)
        change_char(pattern, chr(0xB4-ord(pattern[6])), 0x18)
        change_char(pattern, chr(ord(pattern[0x15]) ^ ord(pattern[0x13]) ^ 0x7F), 0x14)
        if (pattern[0x12] == 'Z') and (pattern[0x12] == pattern[0x13]) and ((ord(pattern[0x15]) ^ ord(pattern[0x13]) ^ ord(pattern[0x14])) == 0x7F):
            if (ord(pattern[0x14]) ^ ord(pattern[0x15]) ^ ord(c)) == ord(pattern[0x15]):
                if (pattern[0x15] == '_') and ((ord(pattern[6]) + ord(pattern[0x18])) == 0xB4):
                        change_char(pattern, c, 0x16)   
        change_char(pattern, 'z', 0x17)
        change_char(pattern, pattern[9], 0x19)
        for j in data:
            if (ord(c) + ord(j)) == 0xD4:
                if c == pattern[0x1c]:
                    change_char(pattern, c, 0x1b)
                    change_char(pattern, j, 0x1a)
print(pattern)

Result Link to heading

n00bz{x0r_XoRR_xOR}