Skip to content

Instantly share code, notes, and snippets.

@domen111
Last active December 23, 2019 06:55
Show Gist options
  • Save domen111/335ee906690d9398b3f286be1462402d to your computer and use it in GitHub Desktop.
Save domen111/335ee906690d9398b3f286be1462402d to your computer and use it in GitHub Desktop.
justCTF 2019 Writeup
module fsmir (
input clk ,
input [7:0] di ,
output logic [7:0] c ,
output solved
);
initial c = 8'b0;
assign solved = c == 8'd59;
always @(posedge clk) begin
c <= 8'b0;
case (c)
8'b1001: if((di ^ c) == 8'b1110000) c <= 8'b1010;
8'b101001: if((di ^ c) == 8'b1010000) c <= 8'b101010;
8'b11100: if((di ^ c) == 8'b1101000) c <= 8'b11101;
8'b1010: if((di ^ c) == 8'b1111001) c <= 8'b1011;
8'b1100: if((di ^ c) == 8'b1101001) c <= 8'b1101;
8'b110000: if((di ^ c) == 8'b1011001) c <= 8'b110001;
8'b111001: if((di ^ c) == 8'b110) c <= 8'b111010;
8'b11000: if((di ^ c) == 8'b1000111) c <= 8'b11001;
8'b11110: if((di ^ c) == 8'b1011101) c <= 8'b11111;
8'b10: if((di ^ c) == 8'b1110001) c <= 8'b11;
8'b10100: if((di ^ c) == 8'b1110011) c <= 8'b10101;
8'b101011: if((di ^ c) == 8'b1000101) c <= 8'b101100;
8'b10000: if((di ^ c) == 8'b1100010) c <= 8'b10001;
8'b101010: if((di ^ c) == 8'b1110101) c <= 8'b101011;
8'b100111: if((di ^ c) == 8'b1001001) c <= 8'b101000;
8'b10111: if((di ^ c) == 8'b1100100) c <= 8'b11000;
8'b11: if((di ^ c) == 8'b1110111) c <= 8'b100;
8'b1111: if((di ^ c) == 8'b1101010) c <= 8'b10000;
8'b101101: if((di ^ c) == 8'b1011001) c <= 8'b101110;
8'b101000: if((di ^ c) == 8'b1001011) c <= 8'b101001;
8'b101: if((di ^ c) == 8'b1010001) c <= 8'b110;
8'b110110: if((di ^ c) == 8'b1010001) c <= 8'b110111;
8'b1110: if((di ^ c) == 8'b1011000) c <= 8'b1111;
8'b100010: if((di ^ c) == 8'b1010110) c <= 8'b100011;
8'b100101: if((di ^ c) == 8'b1000011) c <= 8'b100110;
8'b100: if((di ^ c) == 8'b1000111) c <= 8'b101;
8'b10010: if((di ^ c) == 8'b1111110) c <= 8'b10011;
8'b1101: if((di ^ c) == 8'b1100000) c <= 8'b1110;
8'b110001: if((di ^ c) == 8'b1011110) c <= 8'b110010;
8'b110101: if((di ^ c) == 8'b1011100) c <= 8'b110110;
8'b110011: if((di ^ c) == 8'b1101100) c <= 8'b110100;
8'b101111: if((di ^ c) == 8'b1011011) c <= 8'b110000;
8'b1: if((di ^ c) == 8'b1110100) c <= 8'b10;
8'b11001: if((di ^ c) == 8'b1110011) c <= 8'b11010;
8'b100000: if((di ^ c) == 8'b1010111) c <= 8'b100001;
8'b100011: if((di ^ c) == 8'b1001011) c <= 8'b100100;
8'b100100: if((di ^ c) == 8'b1111011) c <= 8'b100101;
8'b110111: if((di ^ c) == 8'b1011111) c <= 8'b111000;
8'b100001: if((di ^ c) == 8'b1001000) c <= 8'b100010;
8'b11101: if((di ^ c) == 8'b1000010) c <= 8'b11110;
8'b110: if((di ^ c) == 8'b1000000) c <= 8'b111;
8'b1000: if((di ^ c) == 8'b1011011) c <= 8'b1001;
8'b110010: if((di ^ c) == 8'b1011100) c <= 8'b110011;
8'b10011: if((di ^ c) == 8'b1111100) c <= 8'b10100;
8'b100110: if((di ^ c) == 8'b1000111) c <= 8'b100111;
8'b111010: if((di ^ c) == 8'b1000111) c <= 8'b111011;
8'b10001: if((di ^ c) == 8'b1111000) c <= 8'b10010;
8'b10101: if((di ^ c) == 8'b1001010) c <= 8'b10110;
8'b0: if((di ^ c) == 8'b1101010) c <= 8'b1;
8'b111000: if((di ^ c) == 8'b1001100) c <= 8'b111001;
8'b110100: if((di ^ c) == 8'b1000110) c <= 8'b110101;
8'b1011: if((di ^ c) == 8'b1111111) c <= 8'b1100;
8'b11011: if((di ^ c) == 8'b1101000) c <= 8'b11100;
8'b11111: if((di ^ c) == 8'b1000000) c <= 8'b100000;
8'b101110: if((di ^ c) == 8'b1001111) c <= 8'b101111;
8'b10110: if((di ^ c) == 8'b1111111) c <= 8'b10111;
8'b11010: if((di ^ c) == 8'b1101111) c <= 8'b11011;
8'b111: if((di ^ c) == 8'b1111100) c <= 8'b1000;
8'b101100: if((di ^ c) == 8'b1000011) c <= 8'b101101;
default : c <= 8'b0;
endcase
end
endmodule
#!/usr/env python3
# The flag is hidden somewhere on the server, it contains `flag` in its name
import sys
import signal
import subprocess
import os
MODULE = os.path.dirname(__file__)
def user_command():
return input()
def send(msg):
print(msg)
def read_file(filename):
try:
with open(filename, "r") as f:
return f.read()
except:
return ''
def md5_file(filename):
out = subprocess.check_output(['/task/md5service.sh'], input=filename.encode(), stderr=subprocess.DEVNULL)
return out
def main():
def handler(signum, frame):
print('Time limit exceeded. Good bye!')
sys.stdout.flush()
sys.exit(1)
signal.signal(signal.SIGALRM, handler)
signal.alarm(30)
print("Welcome to md5service!")
print("I have two commands:")
print("MD5 <file> -- will return a md5 for a file")
print("READ <file> -- will read a file")
for i in range(500):
cmd = input("Cmd: ")
splitted = cmd.split(' ', 1)
if len(splitted) != 2:
print('\nBad command. Use MD5|READ <file>')
continue
cmd, arg = splitted
arg = arg.strip()
if cmd == 'MD5':
print('Executing MD5 on %r' % arg)
sys.stdout.flush()
print('Result:')
print(md5_file(arg))
elif cmd == 'READ':
print('Executing READ on %r' % arg)
sys.stdout.flush()
print('RESULT:')
print(read_file(arg))
else:
print('Unrecoginzed command. Try again!')
sys.stdout.flush()
print('500 commands limits exceeded. Bye!')
sys.stdout.flush()
if __name__ == '__main__':
main()
#!/bin/bash
read x;
y=`md5sum $x`;
echo $y | cut -c1-32;
import re
c_re = re.compile("\\t{3}9'b([01]+) : case\\(di\\)")
di_re = re.compile("\\t{4}8'b([01]+): c <= 9'b([01]+);")
with open('fsmir2.sv', 'r') as content_file:
raw_data = content_file.read()
cur_c = None
data = {}
for line in raw_data.split('\n'):
case_c_res = c_re.match(line)
case_di_res = di_re.match(line)
if case_c_res != None:
cur_c = case_c_res[1]
elif case_di_res != None:
data[case_di_res[2]] = (cur_c, case_di_res[1])
flag = ""
now = "101001101"
while now != "0":
way = data[now]
flag += chr(int(way[1], 2))
now = way[0]
flag = flag[::-1]
print(flag)
from pwn import *
from sys import argv
# serv = ("md5service.nc.jctf.pro", 1337)
serv = ("46.101.173.184", 1341)
r = remote(*serv)
def md5(file):
global r
while True:
try:
r.sendline("MD5 " + file)
r.recvuntil("Result:\n")
md5value = r.recvline().decode()
return md5value[2:-4]
except EOFError:
r = remote(*serv)
def check_valid(v, target):
if v == target:
log.success(v)
return True
elif v != "":
log.warn(v)
return False
def search_missing(s, target):
q = s.find('?')
assert q != -1
for c in charset:
ns = s[:q] + c + s[q+1:]
log.info("checking... " + ns)
v = md5(ns)
if check_valid(v, target):
return ns
return ""
def chrrange(a, b):
return [chr(i) for i in range(ord(a), ord(b)+1)]
charset = chrrange('0', '9') + chrrange('a', 'z') + chrrange('A', 'Z') + chrrange('!', '/') + chrrange(':', '@')
charset.remove('?')
charset.remove('*')
s = input()
target = md5(s)
log.info("target: " + target)
while True:
q = s.find('*')
if q == -1: break
ns = s[:q] + s[q+1:]
log.info("checking... " + ns)
v = md5(ns)
if check_valid(v, target):
s = ns
continue
ns = search_missing(s[:q] + "?" + s[q:], target)
if ns != "":
s = ns
log.success(s)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment