Tags: verilog 

Rating:

# Solution for Imaginary CTF 2021 Challenge "Normal"
Category: Reverse Engineering
## Challenge Description
Norse senor snorts spores, abhors non-nors, adores s'mores, and snores.
### Provided Verilog Code
```
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
```
## Solution
The challenge is written in the Verilog hardware description language. It also gave us a Makefile for the "iverilog" compiler, and the "vvp" command is the simulation runtime engine. The provided Verilog code already compiles and runs fine:
```
fm@nuc7vm2004:/mnt/hgfs/fpga/projects/icebreaker/fm4dd/normal$ make
iverilog -o normal.vvp -s main normal.v
vvp normal.vvp
Incorrect flag...
```
This needs only minor modifications:
1. The ```if (wrong) begin``` condition triggers because the output of module 'normal' is non-zero (true). We remove it.
2. The wire definitions look suspiciously like 32-character definitions. Let's use $display to show the content of 'wrong', and 'flag'
```
vi normal.v
...
module main;
...
initial begin
#10;
$display("%s", flag);
$display("%s", wrong);
end
endmodule
```
The Verilog $display task creates debug output, and has format modifiers similar to 'printf' - nifty!
```
fm@nuc7vm2004:/mnt/hgfs/fpga/projects/icebreaker/fm4dd/normal$ make
iverilog -o normal.vvp -s main normal.v
vvp normal.vvp
ictf{ }
A11_ha!1_th3_n3w_n0rm_n0r!
```
Now that looks already like a flag, doesn't it?
3. Just for perfection, lets combine the two strings 'wrong' and 'flag' for a single flag line. Creating the 'out' wire, and OR the values:
```
vi normal.v
...
module main;
...
wire [255:0] out;
assign out = flag | wrong;
..
initial begin
#10;
$display("%s", out);
end
endmodule
```
### Final Code
```
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;
wire [255:0] out;
assign out = flag | wrong;

normal flagchecker(wrong, flag);

initial begin
#10;
$display("%s", out);
end
endmodule
```

And here we go:
```
fm@nuc7vm2004:/mnt/hgfs/fpga/projects/icebreaker/fm4dd/normal$ make
iverilog -o normal.vvp -s main normal.v
vvp normal.vvp
ictf{A11_ha!1_th3_n3w_n0rm_n0r!}
```

Bonus: Showing the wire signals in GTKWave
![Showing the wire signals in GTKWave](https://gist.githubusercontent.com/fm4dd/bad29d573168966ec09c8d465c75c208/raw/cf24f7af814db6d291e8ff6657980b43b7940ba5/ictf-normal-flag-gtkwave.png)

P.S. 2nd Bonus - write the code to the FPGA and output the flag on a LCD display...