# angry (rev)

{% file src="<https://243380073-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FBIa0PcXGYuP6chd3J1Ry%2Fuploads%2FbHYxweduYtn7RXBv7hIg%2Fangry_patched_skill_issues?alt=media&token=696c9f29-1025-4d0e-a33a-f39f1bc93fd8>" %}

As the challenge name suggests, we should be using angr to solve the challenge. The `main` code is as follows:

```c
undefined8 main(void)
{
  int iVar1;
  void *input;
  
  input = malloc(1);
  process(input,"Give me a password : ",0x28);
  iVar1 = check1(input); // I renamed this function
  if (iVar1 == 0) {
    puts("Bruh : (");
  }
  else {
    iVar1 = check2(input); // I renamed this function
    if (iVar1 == 0) {
      puts("Bruh : (");
    }
    else {
      puts("Congratulations !");
    }
  }
  return 0;
}
```

`process()` essentially prompts for the input and saves it into the address of `input`.&#x20;

Then, the input is encrypted using `check1`. `check1` is given below.

```c
undefined8 check1(byte *input)
{
  int 0x25;
  size_t n;
  undefined8 uVar1;
  
  n = strlen((char *)input);
  0x25 = FUN_001011fe(); // this function just returns 0x25
  if (((((((((n == (long)0x25) &&
            ((int)(char)input[15] * (int)(char)input[5] - (int)(char)input[7] == 0x12ec)) &&
           (input[6] == 'n')) &&
          (((int)(char)input[7] * (int)(char)input[7] == 0x2971 && (input[8] != 0)))) &&
         ((input[9] != 0 && ((((int)(char)input[10] & 0x3fffffffU) == L'4' && (input[11] == '_')) )))
         ) && (input[12] == 'l')) &&
       ((((((int)(char)(input[2] ^ input[13] ^ *input ^ input[1]) != (uint)(input[3] == 0x44) &&
           ((int)(char)input[17] +
            (int)(char)input[14] + (int)(char)input[15] + (int)(char)input[16] == 0x15c)) &&
          ((int)(char)(input[1] ^ input[15]) != (uint)(input[2] == 0x41))) &&
         (((((int)(char)input[16] + (int)(char)input[21]) - (int)(char)input[25] == 0x55 &&
           ((int)(char)input[33] + ((int)(char)input[17] - (int)(char)input[32]) == 156)) &&
          ((input[18] == '0' && ((input[19] == 'n' && (input[20] == 't')))))))) &&
        (((input[17] ^ input[21]) == 0x3b &&
         (((input[22] == 'd' && ((int)(char)input[0x17] != (uint)(input[21] == 10))) &&
          (input[24] == '_')))))))) &&
      (((((int)(char)input[25] - (int)(char)input[5] == 8 && (input[26] != 1)) &&
        (((input[27] == '_' &&
          ((((int)(char)input[28] + (int)(char)input[21]) - (int)(char)input[25] == 99 &&
           ((int)(char)input[29] != (uint)((int)(char)input[28] + (int)(char)input[31] == 246)))) )
         && (input[30] == 'n')))) &&
       (((((int)(char)input[0x1f] != (uint)(input[13] == 100) &&
          ((int)(char)input[31] + (int)(char)input[34] == 193)) &&
         ((int)(char)input[33] + (int)(char)input[32] == 160)) &&
        ((input[33] == 'l' && ((int)(char)input[33] - (int)(char)input[1] == 57)))))))) &&
     ((input[34] == 'l' && ((input[35] == 'y' && (input[36] == 0x7d)))))) {
    uVar1 = 1;
  }
  else {
    uVar1 = 0;
  }
  return uVar1;
}
```

It verifies that the input length is 37 and performs a series of checks on the characters of the input. If we pass these checks we move on to `enc2`:

```c
undefined8 check2(long param_1)
{
  undefined8 uVar1;
  
  if ((((*(char *)(param_1 + 8) == 'r') && (*(char *)(param_1 + 9) == '_')) &&
      (*(char *)(param_1 + 23) == 'o')) &&
     ((*(char *)(param_1 + 29) == '4' && ((char)(*(byte *)(param_1 + 10) & 0xcf) < '\n')))) {
    uVar1 = 1;
  }
  else {
    uVar1 = 0;
  }
  return uVar1;
}
```

Again, we are performing more (albeit straightforward) checks on the input.

Using claripy, we specify our flag to be a bitvector with 37 characters. Using angr, we specify the base address of the binary to be `0`, and we want to find the address `0x1286` which is the address of `puts("Congratulations !")`, and we avoid the addresses `0x1848` and `0x1837` which are the addresses of `puts("Bruh : ( ")`. We then get the simulation manager to explore the program and find the flag.

```python
import angr
import sys
import claripy

input_file_path='./angry_patched_skill_issues'
flag_length=37
known_string='L3AK{'
FIND_ADDR=0x1826
AVOID_ADDR=[0x1848, 0x1837]


proj=angr.Project(input_file_path,main_opts={'base_addr':0x00})
known_chars=[claripy.BVV((known_string[i])) for i in range(len(known_string))]
flag_chars=[claripy.BVS(f"flag_{i}",8) for i in range(flag_length-len(known_string))]
flag=claripy.Concat(*known_chars+flag_chars + [claripy.BVV(b'\n')])
state = proj.factory.entry_state(args=[input_file_path], stdin=flag)
# state=proj.factory.full_init_state(args=[input_file_path,flag])
# state = proj.factory.full_init_state(stdin=flag)
sim_manager=proj.factory.simulation_manager(state)
sim_manager.explore(find=FIND_ADDR,avoid=AVOID_ADDR)

if(len(sim_manager.found)>0):
	print(sim_manager.found[0].solver.eval(flag,cast_to=bytes))

# L3AK{angr_4_l1f3_d0nt_do_it_m4nU4lly}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://elijahchia.gitbook.io/ctf-blog/l3ak-ctf-24/angry-rev.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
