s4ch1n

Normal - ImaginaryCTF

Posted on

Description:

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

I have never used verilog before so I had to learn the syntax of verilog.

After going through the syntax of verilog and then analyzing the program it was passing the flag through all the NOR gates. If flagchecker returns 1, flag is correct or else it is incorrect. So I just brute forced the gates with all printable characters.

I should have use boolean algebra or bit hacking to reduce the computation and redundant part of the code. Anyways here is my solution.

import string

def convert(l1):
  l2 = []
  j = 0
  for i in range(2, len(l1)+2, 2):
    l2.append(int(l1[j:i], 16))
    j = i
  return l2

def _not(x):
  y = ""
  for i in bin(x)[2:].rjust(8, "0"):
    if i == '0':
      y += '1'
    else:
      y += '0'
  return y

def nor(l1, l2):
  l3 = []
  for i in zip(l1, l2):
    l3.append(int(_not(i[0] | i[1]), 2))
  return l3

def process(flag):
  c1 = "d208851a855f817d9b3744bd03fdacae61a70c9b953fca57f78e9d2379814c21"
  c2 = "44940e8301e14fb33ba0da63cd5d2739ad079d571d9f5b987a1c3db2b60c92a3"
  flag = convert(flag)
  c1 = convert(c1)
  c2 = convert(c2)
  w1 = nor(flag, c1)
  w2 = nor(flag, w1)
  w3 = nor(c1, w1)
  w4 = nor(w2, w3)
  w5 = nor(w4, w4)
  w6 = nor(w5, c2)
  w7 = nor(w5, w6)
  w8 = nor(c2, w6)
  return nor(w7, w8)

def str_to_hex(s):
  h = ""
  for i in s:
    h += hex(ord(i))[2:]
  return h

def decode():
  #flag = "696374667b00000000000000000000000000000000000000000000000000007d"
  flag = "ictf{"
  for i in range(5, 32):
    print(flag)
    for j in string.printable:
      c = flag
      c += j
      if process(str_to_hex(c))[i] == 0:
        print(c)
        flag += j
        break
  print(flag)

decode()
Flag:
flag: ictf{A11_ha!1_th3_n3w_n0rm_n0r!}