Description
[EN]
Scavenging an old 318br repo, we found a program missing some line of code. Even without this line, we would like to know the result of
its execution.
Specific instruction: Put the flag on the format 3DS{} and submit.[PT]
Vasculhando um repositorio antigo do 318br, nos encontramos um programa faltando uma parte. Mesmo faltando uma parte, nos gostariamos que voce nos dissesse o resultado de sua execucao.
Instrucao especifica: Colocar o resultado no formato 3DS{} e submeter.Solved by 19 Teams
Resolution
The given zip file contains 33 files like this:
****************** Third Development Software Company for DEC9 *********************
0 1 2 3 4 5 6 7 8
12345678901234567890123456789012345678901234567890123456789012345678901234567890
________________________________________________________________________________
12 /O
11|X
0|X
1|X O
2|X O
3|XO O
4|X O
5|X
6|X
7|X
8|X
9|X
|_________________________________________________________________________________
It a simple Punched Card like this one:

How does it works? It’s very simple!
_________
12 /O
11|X
0|X
1|X O
2|X O
3|XO O
The 2 first raws (12 and 11) are kind of “multiplier factor”, and the others (0-9) are the values.
- In the first column there are 2 holes (the O) : one at the raw 12, one at the raw 3.
The raw 12 adds 10 to the result 2, so for the first column it gave 12. - The second column there’s 1 hole in the raw 1, so it gave 1.
As the simplified charset is : 0-9, A-Z, we can deduce that 12 is a C, 1 is 1 etc. so the card was “C123” 🙂
The real charsets are:
029 &-0123456789ABCDEFGHIJKLMNOPQR/STUVWXYZ:#@'="¢.<(+|!$*);¬ ,%_>? IBME ¹-0123456789ABCDEFGHIJKLMNOPQR/STUVWXYZ:#²'="].<(+|[$*);¬³,%_>? EBCD &-0123456789ABCDEFGHIJKLMNOPQR/STUVWXYZ:#@'="[.<(+|]$*);^\,%_>?
A basic representation of the conversion:
12 value: [ not holed | holed ] 11 value: [ not holed | holed ] 0-9 value: [0|1|2|3|4|5|6|7|8|9|1|2|3|4|5|6|7|8|9|1|2|3|4|5|6|7|8|9] ASCII res: [0|1|2|3|4|5|6|7|8|9|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R]
For the rest of the letters and special chars, it’s a little bit more complex.
You can refer to the script below.
The 3rd card was complex to handle manually:
****************** Third Development Software Company for DEC9 *********************
0 1 2 3 4 5 6 7 8
12345678901234567890123456789012345678901234567890123456789012345678901234567890
________________________________________________________________________________
12 / O O O
11|X OOO O O OO OO
0|X
1|X O
2|X
3|X
4|X O O
5|X
6|X O
7|X O O O O
8|X
9|X O O O O
|_________________________________________________________________________________
1st column: 11 is holed + 7 = P
2nd column: 11 is holed + 9 = R
3rd column: 11 is holed + 6 = O
4th column: 12 is holed + 7 = G
5th column: 11 is holed + 9 = R
6th column: 12 is holed + 1 = A
7th column: 11 is holed + 4 = M
etc.
Giving PROGRAM PRGRM
It’s an instruction in Fortran.
As decoding all the cards is quite boring, we made a script to do that:
#!/usr/bin/python2
# Based on a write up for the Boston Key Party CTF 2015, task Haymarket
def decode(code):
if code == ['0']: return '0'
elif code == ['1']: return '1'
elif code == ['2']: return '2'
elif code == ['3']: return '3'
elif code == ['4']: return '4'
elif code == ['5']: return '5'
elif code == ['6']: return '6'
elif code == ['7']: return '7'
elif code == ['8']: return '8'
elif code == ['9']: return '9'
elif code == ['12', '1']: return 'A'
elif code == ['12', '2']: return 'B'
elif code == ['12', '3']: return 'C'
elif code == ['12', '4']: return 'D'
elif code == ['12', '5']: return 'E'
elif code == ['12', '6']: return 'F'
elif code == ['12', '7']: return 'G'
elif code == ['12', '8']: return 'H'
elif code == ['12', '9']: return 'I'
elif code == ['11', '1']: return 'J'
elif code == ['11', '2']: return 'K'
elif code == ['11', '3']: return 'L'
elif code == ['11', '4']: return 'M'
elif code == ['11', '5']: return 'N'
elif code == ['11', '6']: return 'O'
elif code == ['11', '7']: return 'P'
elif code == ['11', '8']: return 'Q'
elif code == ['11', '9']: return 'R'
elif code == ['0', '1']: return '/'
elif code == ['0', '2']: return 'S'
elif code == ['0', '3']: return 'T'
elif code == ['0', '4']: return 'U'
elif code == ['0', '5']: return 'V'
elif code == ['0', '6']: return 'W'
elif code == ['0', '7']: return 'X'
elif code == ['0', '8']: return 'Y'
elif code == ['0', '9']: return 'Z'
elif code == ['11', '2', '8']: return '!'
elif code == ['4', '8']: return '@'
elif code == ['3', '8']: return '#'
elif code == ['11', '3', '8']: return '$'
elif code == ['0', '4', '8']: return '%'
elif code == ['12', '7', '8']: return '^'
elif code == ['12']: return '&'
elif code == ['11', '4', '8']: return '*'
elif code == ['12', '5', '8']: return '('
elif code == ['11', '5', '8']: return ')'
elif code == ['11']: return '-'
elif code == ['6', '8']: return '='
elif code == ['0', '5', '8']: return '_'
elif code == ['0', '3', '8']: return ','
elif code == ['12', '6', '8']: return '+'
elif code == ['12', '2', '8']: return '['
elif code == ['0', '2', '8']: return '['
elif code == ['11', '6', '8']: return ';'
elif code == ['0', '6', '8']: return '>'
elif code == ['5', '8']: return "'"
elif code == ['2', '8']: return ':'
elif code == ['7', '8']: return '"'
elif code == ['11', '7', '8']: return ' '
elif code == ['12', '3', '8']: return '.'
elif code == ['12', '4', '8']: return '<'
else: return '?'
lines = list()
for num in range(1,34):
card = "card-" + str(format(num,'02')) + "-34.dec"
file = open(card, "r")
for line in file:
lines.append(line)
code = []
text = ""
for c in range (80):
for r in range (12):
if lines[r+4][c+3] == "O":
if r==0:
code.append('12')
if r==1:
code.append('11')
if r!=0 and r!=1:
code.append(str(r-2))
if len(code) > 0:
text += decode(code)
code = []
print text
lines = []
file.close()
Giving us:
C1234 C234567890123456789012345678901234567890 PROGRAMPRGRM INTEGERC,X DOUBLEPRECISIONI,R,A DOUBLEPRECISIONRES GOTO1598 1599A=1/RES GOTO2852 0666GOTO0665 7599A=-1/RES GOTO2852 1598C=1337 RES=1 X=0 1337X=X GOTO5523 0318I=I*4 PRINT*,I GOTO0666 5523IF(MOD(X,2).EQ.0)THEN GOTO1599 ELSE GOTO7599 ENDIF 2852I=I+A GOTO9513 9513RES=RES+2 X=X+1 IF(X.EQ.C)THEN GOTO0318 ENDIF GOTO1337
As they told in the task description, there was some code missing:
0666 GOTO 0665, but there’s no 0665, no “END PROGRAM” etc.
We modified the code to:
!C1234 !C234567890123456789012345678901234567890 PROGRAM PRGRM INTEGER C,X DOUBLE PRECISION I,R,A DOUBLE PRECISION RES GOTO 1598 1599 A=1/RES GOTO 2852 666 GOTO 665 7599 A=-1/RES GOTO 2852 1598 C=1337 RES=1 X=0 1337 X=X GOTO 5523 318 I=I*4 PRINT *,I GOTO 666 5523 IF(MOD(X,2).EQ.0) THEN GOTO 1599 ELSE GOTO 7599 ENDIF 2852 I=I+A GOTO 9513 9513 RES=RES+2 X=X+1 IF(X.EQ.C)THEN GOTO 318 ENDIF GOTO 1337 665 STOP END PROGRAM
Then executed it on an online interpreter: https://www.jdoodle.com/execute-fortran-online.
Note: The following floating-point exceptions are signalling: IEEE_DENORMAL 3.1423405966415094
Flag was 3DS{3.1423405966415094}
[3DS CTF] [MISC 400 – WAT] Write up