3DS CTF 2016 WAT misc400 Writeup

Hi,

In this task we were given several punching cards (DEC9 model). To solve the task I wrote a script to create a table to map each character to its corresponding code. Than I decoded the content of the punch cards. The decoded content was a FORTRAN program. I fixed the code(missing lines) and I run it to get the required value which was 3.1423405966415094.

My script:

''' dec9.card
     ________________________________________________________________
    /&-0123456789ABCDEFGHIJKLMNOPQR/STUVWXYZ:#@'="[.<(+^!$*);\],%_>?   
12 / O           OOOOOOOOO                        OOOOOO               
11|   O                   OOOOOOOOO                     OOOOOO      
 0|    O                           OOOOOOOOO                  OOOOOO
 1|     O        O        O        O                                   
 2|      O        O        O        O       O     O     O     O        
 3|       O        O        O        O       O     O     O     O           
 4|        O        O        O        O       O     O     O     O          
 5|         O        O        O        O       O     O     O     O          
 6|          O        O        O        O       O     O     O     O           
 7|           O        O        O        O       O     O     O     O            
 8|            O        O        O        O OOOOOOOOOOOOOOOOOOOOOOOO     
 9|             O        O        O        O                                 
  |__________________________________________________________________         
'''

import os

def gen_from_template():
 f = open("dec9.card")
 card = f.readlines()
 f.close()

 for i in range(5,68):   
  pcode = ""
  for j in range(2,14):
   if card[j][i] == "O":
    pcode += "y"+card[j][0:2].replace(" ","")
  print '"'+pcode+"\":"+'"'+card[1][i]+"\",\n"

pcode_template ={"y12":"&","y11":"-","y0":"0","y1":"1","y2":"2","y3":"3",
"y4":"4","y5":"5","y6":"6","y7":"7","y8":"8","y9":"9","y12y1":"A","y12y2":"B",
"y12y3":"C","y12y4":"D","y12y5":"E","y12y6":"F","y12y7":"G","y12y8":"H","y12y9":"I",
"y11y1":"J","y11y2":"K","y11y3":"L","y11y4":"M","y11y5":"N","y11y6":"O","y11y7":"P",
"y11y8":"Q","y11y9":"R","y0y1":"/","y0y2":"S","y0y3":"T","y0y4":"U","y0y5":"V",
"y0y6":"W","y0y7":"X","y0y8":"Y","y0y9":"Z","y2y8":":","y3y8":"#","y4y8":"@","y5y8":"'",
"y6y8":"=","y7y8":"\"","y12y2y8":"[","y12y3y8":".","y12y4y8":"<","y12y5y8":"(","y12y6y8":"+",
"y12y7y8":"^","y11y2y8":"!","y11y3y8":"$","y11y4y8":"*","y11y5y8":")","y11y6y8":";",
"y11y7y8":"\"","y0y2y8":"]","y0y3y8":",","y0y4y8":"%","y0y5y8":"_","y0y6y8":">",
"y0y7y8":"?"}

def decode_card(fcard):
 dec = ""
 f = open(fcard)
 card = f.readlines()
 f.close()

 for i in range(4,len(card[0])):   
  pcode = ""
  for j in range(4,16):
   if card[j][i] == "O":
    pcode += "y"+card[j][0:2].replace(" ","")
  if len(pcode):
   dec+=pcode_template[pcode]
 return dec

t = ""

path = "misc400"

for root, dirs, files in os.walk('misc400'):
 for fcard in sorted(files):
  t+=decode_card(os.path.join(path, fcard))+ " "

'''
for fcard in os.listdir(path):
        if os.path.isfile(os.path.join(path, fcard)):
  t+=decode_card(os.path.join(path, fcard))+ " "
'''

print t


The decoded program:

PROGRAM PRGM
INTEGER C,X
DOUBLE PRECISION I,R,A
DOUBLE PRECISION RES

1598 C=1337
RES=1
X=0

GO TO 5523

1599 A=1/RES
GO TO 2852

7599 A=-1/RES
GO TO 2852

2852 I=I+A
GO TO 9513

9513 RES=RES+2
X=X+1
IF(X.EQ.C) THEN
GO TO 1318
ENDIF

5523 IF(MOD(X,2).EQ.0) THEN
GO TO 1599
ELSE
GO TO 7599
END IF

1318 I=I*4
PRINT*,I

END PROGRAM PRGM

Build and run

The flag was 3DS{3.1423405966415094}