Rating: 0

In this challenge, we will be given one binary and one cmm file.

The binary will print flag very slowly. So we must figure out the algorithm in this binary.

But IDA pro is not working on this binary.

After some googling I found that cmm file is related to [haskell compiler]()

Fortunately, the cmm file is somehow human-readable.

With some guessing I summerize some pseudo classes.

```python
def s0():
return [97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,48,49,50,51,52,53,54,55,56,57,33,35,36,37,38,39,34,40,41,42,43,44,45,46,47,58,59,60,61,62,63,64,91,92,93,94,95,96,123,124,125,126]

def s1():
return [49,118,73,123,101,91,56,84,100,93,45,110,81,46,55,79,34,98,108,40,106,113,64,60,48,86,121,38,90,51,126,92,112,115,44,97,68,94,59,66,78,57,74,85,111,104,124,67,69,50,95,54,33,71,39,114,72,117,102,62,36,83,37,77,120,103,122,75,89,52,96,99,43,87,88,65,53,70,41,109,82,125,35,80,116,76,63,42,61,105,47,58,119,107]

def s2():
return [66,112,125,105,123,88,85,37,102,36,68,82,92,48,60,76,120,61,111,34,83,108,96,98,122,41,45,101,54,50,124,38,74,113,70,84,33,40,67,53,121,104,59,64,117,42,46,87,97,90,35,81,118,44,63,99,114,56,119,69,109,52,95,116,49,57,80,72,58,106,93,62,91,78,86,77,110,55,89,71,107,75,39,94,47,126,79,73,100,115,65,43,51,103]

def s3():
return [95,114,43,35,121,104,91,89,41,83,56,97,88,74,119,86,38,106,118,34,111,61,73,40,54,62,112,103,44,102,45,77,93,113,98,78,52,39,69,68,75,70,92,116,60,51,71,37,124,36,99,115,80,81,109,125,126,48,64,82,59,117,85,50,122,57,105,87,66,46,47,72,67,107,33,123,58,79,100,94,90,84,55,96,65,110,108,49,101,53,76,42,120,63]


```

And I also find out that there is some global constant which seems related to flag.

```
[section ""data" . dt_r33R_closure" {
dt_r33R_closure:
const GHC.Types.I#_con_info;
const 0;
}]

==================== Output Cmm ====================
[section ""data" . dt1_r36n_closure" {
dt1_r36n_closure:
const GHC.Types.I#_con_info;
const 39;
}]

==================== Output Cmm ====================
[section ""data" . flags1_r36o_closure" {
flags1_r36o_closure:
const Main.Index_con_info;
const dt_r33R_closure+1;
const dt1_r36n_closure+1;
const 3;
}]

==================== Output Cmm ====================
[section ""data" . dt2_r36p_closure" {
dt2_r36p_closure:
const GHC.Types.I#_con_info;
const 5;
}]

==================== Output Cmm ====================
[section ""data" . dt3_r36q_closure" {
dt3_r36q_closure:
const GHC.Types.I#_con_info;
const 282;
}]

==================== Output Cmm ====================
[section ""data" . flags2_r36r_closure" {
flags2_r36r_closure:
const Main.Index_con_info;
const dt2_r36p_closure+1;
const dt3_r36q_closure+1;
const 3;
}]

```

Each byte of flag is defined by two number.

We know the first byte is 'N' and the s0_closure()[39] is also 'N'. I thought it's not a coincidence.

So I suppose that the second number is index value.

Now what about the first number?

After some testing and brainstorming, I figure out the complete algorithm

```python
def foo(n):
if n==0:
return s0()
else:
return s1()+foo(n-1)+s2()+foo(n-1)+s3()

flag = [[0,39],[5,282],....]

for i in flag:
print foo(i[0])[i[1]]

```

Finally,
The flag is `N1CTF{did_cmm_helped?1109ef6af4b2c6fc274ddc16ff8365d1}`