Skip to main content

Phase 7 (250 pts)

This has a huge jump in points and also difficulty.

Problem Statement#

At least we can say our code is reusable
(Flag uses the same rockyou.txt format as BBomb Phase 4)
Author: treap_treap

Ghidra#

uint phase7(undefined8 param_1,undefined4 param_2,undefined4 param_3,undefined4 param_4,           undefined4 param_5,undefined4 param_6,undefined4 param_7,undefined4 param_8,char *param_9           )
{  undefined uVar1;  int iVar2;  int curr;  uint currNum;  undefined8 *__ptr;  void *pvVar3;  undefined8 isPrime;  undefined4 extraout_XMM0_Da;  undefined4 extraout_XMM0_Da_00;  undefined4 uVar4;  undefined in_stack_ffffffffffffffa8;  uint result;  int counter;  int check_val;  int count;  int counter3;  int counter2;
  puts("\nAt least we can say our code is resuable");  result = 1;  __ptr = (undefined8 *)malloc(0x18);  counter = 0;  uVar4 = extraout_XMM0_Da;  while (counter < 3) {    pvVar3 = calloc(0x29,1);    __ptr[counter] = pvVar3;    counter = counter + 1;    uVar4 = extraout_XMM0_Da_00;  }  getInput(uVar4,param_2,param_3,param_4,param_5,param_6,param_7,param_8,7,param_9,"%s%s%s",*__ptr,           __ptr[1],__ptr[2],in_stack_ffffffffffffffa8);  check_val = 0;  count = 0;  do {    if (2 < count) {      if (check_val != 0x1fd) {        result = 0;      }      counter2 = 0;      while (counter2 < 3) {        free((void *)__ptr[counter2]);        counter2 = counter2 + 1;      }      free(__ptr);      return result;    }    curr = atoi((char *)__ptr[count]);    check_val = check_val + curr;    if (0 < count) {      curr = atoi((char *)__ptr[(long)count + -1]);      iVar2 = atoi((char *)__ptr[count]);      if (iVar2 < curr) {        result = 0;      }    }    counter3 = 0;    while (counter3 < 3) {      curr = atoi((char *)__ptr[count]);      if (curr < 100) {        result = 0;        break;      }      currNum = atoi((char *)__ptr[count]);      isPrime = prime(currNum);      result = result & (uint)isPrime;      uVar1 = *(undefined *)(__ptr[count] + 2);      *(undefined *)(__ptr[count] + 2) = *(undefined *)(__ptr[count] + 1);      *(undefined *)(__ptr[count] + 1) = *(undefined *)__ptr[count];      *(undefined *)__ptr[count] = uVar1;      counter3 = counter3 + 1;    }    count = count + 1;  } while( true );}

Solution#

It took me a while to understand why did the author choose to use string input instead of digits. Then I realised it's most likely because the author is preparing for the function below which rotates the digits to perform the checks.

For every permutation of every single number, it will check for:

  1. The number is greater than 100
  2. The number is prime

Thus, time for some Python scripting again.

Solve.py#

valid = []for i in range(100, 400):    prime = True    if (i & 1 == 0):        continue    for j in range(3, i // 2 + 1, 2):        if (i % j == 0):            prime = False            break    if (prime):        valid.append(i)for num in valid:    string = list(str(num))    # Removing numbers which will eventually permutate to < 100    if "0" in string:        continue    isPrime = True
    for z in range(3):        t = string[2]        string[2] = string[1]        string[1] = string[0]        string[0] = t        newNum = int("".join(string))        # Make sure it is at least odd        if (newNum & 1 == 0):            isPrime = False            break        for j in range(3, newNum // 2 + 1, 2):            if (newNum % j == 0):                isPrime = False                break        if isPrime == False:            break
    if (isPrime):        print(num)

Output#

output

This time, we get more results.

We know that the sum must equate to 0x1fd which is actually just 509 in decimal.

Doing some guessing and checking, we have arrived at the answer: 113, 197, 199

Flag#

DawgCTF{iloveme_123abc_batman}