# 2020 Defenit CTF - MoM's Touch >###### TAGS: `reversing`>[name=rlaclgjs@PLUS]
## Attachments* writeup    * [solver code](https://gist.github.com/rlaclgjs1107/d3f748657494ee286948888fd753f03f#file-sol-py)  
Attachments are uploaded on [gist](https://gist.github.com/rlaclgjs1107/d3f748657494ee286948888fd753f03f)
## ChallengeChallenge provides an `ELF` file named `momsTouch`. When I opened `momsTouch` with IDA, I noticed that this is a basic reversing challenge for analyzing the flag-checking program. So, let's check out how this program check our input!## Analysis```Cint __cdecl main(){  char *buf; // eax  char *s; // esi  ssize_t v2; // eax
  sub_80486B0();  puts("Mom Give Me The FLAG!");  buf = (char *)malloc(0x64u);  s = buf;  if ( !buf )  {    perror("[*]Error : malloc()");    goto LABEL_12;  }  v2 = read(0, buf, 0x64u);  if ( v2 < 0 )  {    perror("[*]Error : read()");LABEL_12:    exit(-1);  }  if ( s[v2 - 1] == 10 )    s[v2 - 1] = 0;  if ( strlen(s) != 73 )  {    puts("Mom, Check the legnth..");    exit(0);  }  if ( (unsigned __int8)sub_80487A0((int)s) )    puts("Correct! Mom! Input is FLAG!");  else    puts("Try Again..");  free(s);  return 0;}```This is the `main` function we have. In this function, we can figure out some meaningful information. 1. The flag length is 73.2. This program verify our input in a function `sub_80487a0`.
```C {.line-numbers}int __cdecl sub_80487A0(int a1){  signed int v1; // esi  int v2; // ebp  int v3; // eax  int result; // eax
  v1 = 0;  while ( 1 )  {    v2 = (unsigned __int8)(16 * LOBYTE(dword_80492AC[v1]) | ((unsigned int)dword_80492AC[v1] >> 4));    v3 = rand();    if ( (dword_80492AC[(unsigned __int8)(4 * (v3 + v3 / 255) | ((unsigned int)(v3 % 255) >> 2))] ^ dword_80492AC[v2] ^ *(char *)(a1 + v1)) != dword_8049144[v1] )      break;    ++v1;    LOBYTE(result) = 1;    if ( v1 > 72 )      return (unsigned __int8)result;  }  LOBYTE(result) = 0;  return (unsigned __int8)result;}```So, this is the function `sub_80487A0`. This function uses random number(not actually "real" random because we can find a seed in other function), complex conditional expression to check our input. 
However, Let's see `v1`. `v1` is increasing for each loop, unless we fail to pass the conditional expression just above. Then, if `v1` is over 72, the function returns `1` that means 'true'. Since we know 73 is the length of the flag, I guessed that this function checks our flag character by character. 
If we can see whether the program enters `++v1;` part or not, we can brute force the flag by 1 printable character. ## SolutionSo, I write gdb script on python to automate brute forcing process. Here is my solution. ```pythonimport gdb import string
class BP_Manager(gdb.Breakpoint):    def stop(self):        global count        count += 1        return False
gdb.execute('file momsTouch')bp = BP_Manager("*0x0804881c")
trial = "_"*73count = 0 
trial_pos = 0 
while trial_pos < 73:     for ch in string.printable:        if ch in ['\"', '`', '\'','$', '&','(', ')', '>', '<', '|', ';', '\\']:            continue        trial = trial[:trial_pos] + ch + trial[trial_pos+1:]        trial_file = open("trial", "w")        print(trial, file=trial_file)        print("Trying '%s'..."%trial)            trial_file.close()        gdb.execute("r < trial")            print("count : %d"%count)        print("trial_pos : %d"%trial_pos)
        if count == trial_pos+1:            trial_pos += 1            count = 0             break        else:             print("Wrong...")            count = 0 
print(trial)```
After waiting some time, we can get the flag!```Correct! Mom! Input is FLAG![Inferior 1 (process 30928) exited normally]Warning: not runningcount : 73trial_pos : 72Defenit{ea40d42bfaf7d1f599abf284a35c535c607ccadbff38f7c39d6d57e238c4425e}```## Flag`Defenit{ea40d42bfaf7d1f599abf284a35c535c607ccadbff38f7c39d6d57e238c4425e}`