**Tags:** verilog reversing

Rating:

# Normal - 150pts

## Reversing, Verilog, Python

![Screenshot 2021-07-28 at 9.01.42 AM.png](https://www.dropbox.com/s/ubb6c4vpbbl4umt/Screenshot%202021-07-28%20at%209.01.42%20AM.png?dl=0&raw=1)

## normal.v

```verilog

module normal(out, in);

output [255:0] out;

input [255:0] in;

wire [255:0] w1, w2, w3, w4, w5, w6, w7, w8;

wire [255:0] c1, c2;

assign c1 = 256'h44940e8301e14fb33ba0da63cd5d2739ad079d571d9f5b987a1c3db2b60c92a3;

assign c2 = 256'hd208851a855f817d9b3744bd03fdacae61a70c9b953fca57f78e9d2379814c21;

nor n1 [255:0] (w1, in, c1);

nor n2 [255:0] (w2, in, w1);

nor n3 [255:0] (w3, c1, w1);

nor n4 [255:0] (w4, w2, w3);

nor n5 [255:0] (w5, w4, w4);

nor n6 [255:0] (w6, w5, c2);

nor n7 [255:0] (w7, w5, w6);

nor n8 [255:0] (w8, c2, w6);

nor n9 [255:0] (out, w7, w8);

endmodule

module main;

wire [255:0] flag = 256'h696374667b00000000000000000000000000000000000000000000000000007d;

wire [255:0] wrong;

normal flagchecker(wrong, flag);

initial begin

#10;

if (wrong) begin

$display("Incorrect flag...");

$finish;

end

$display("Correct!");

end

endmodule

```

We are given a verilog file with two modules, main and normal. The main module creates an instance of the normal module, if normal flagchecker returns 1, flag is correct else incorrect is displayed

I started off by converting all the nor gates into one single gate by hand(NOR is represented by a . and NOT is represented by ~ for simplicity)

```

nor n1 [255:0] (w1, a, b); // a.b

nor n2 [255:0] (w2, a, w1); // a.(a.b)

nor n3 [255:0] (w3, b, w1); // b.(a.b)

nor n4 [255:0] (w4, w2, w3); // (a.(a.b)).(b.(a.b))

nor n5 [255:0] (w5, w4, w4); // ~((a.(a.b)).(b.(a.b)))

nor n6 [255:0] (w6, w5, c); // (~((a.(a.b)).(b.(a.b)))).c

nor n7 [255:0] (w7, w5, w6); // (~((a.(a.b)).(b.(a.b)))).((~((a.(a.b)).(b.(a.b)))).c)

nor n8 [255:0] (w8, c, w6); // c.((~((a.(a.b)).(b.(a.b)))).c)

nor n9 [255:0] (out, w7, w8); // ((~((a.(a.b)).(b.(a.b)))).((~((a.(a.b)).(b.(a.b)))).c)).(c.((~((a.(a.b)).(b.(a.b)))).c))

```

Then I put the final expression into wolfram alpha https://www.wolframalpha.com/widgets/view.jsp?id=a52797be9f91295a27b14cb751198ae3 and recieved a simplified version of it.

I honestly didnt know how bitwise not could be done in python so I replaced all the not expressions with xor 1 which does the same thing. a= input, b=c1, c=c2

```

(a & b & (c^1)) | (a & (b^1) & c) | ((a^1) & b & c) | ((a^1) & (b^1) & (c^1))

```

Now I quickly wrote a python script to bruteforce this gate against every printable charecter and got the flag

```python

import string

def compute(chr, n):

for j in range(0, 8): # each bit in possible letter

a = (ord(chr) >> 7-j) & 1

b = (0x44940e8301e14fb33ba0da63cd5d2739ad079d571d9f5b987a1c3db2b60c92a3 >> (

255 - (8*n) - j)) & 1

c = (0xd208851a855f817d9b3744bd03fdacae61a70c9b953fca57f78e9d2379814c21 >> (

255 - (8*n) - j)) & 1

final = (a & b & (c^1)) | (a & (b^1) & c) | ((a^1) & b & c) | ((a^1) & (b^1) & (c^1))

if final != 0:

return False

return True

def main():

final = ""

n = 0

for _ in range(0,32): # each byte of flag

for chr in string.printable: # each possible letter

if compute(chr, n):

final += chr

break

n += 1

print(final)

main()

```

> flag: ictf{A11_ha!1_th3_n3w_n0rm_n0r!}

Original writeup (https://github.com/shero4/ctf-writeups/tree/main/Reversing/ImaginaryCTF%20-%20Normal%20150%20pts).