Verticode (90 pts)

Solved by: sardinachanx

Problem:

Welcome to Verticode, the new method of translating text into vertical codes. Each verticode has two parts: the color shift and the code . The code takes the inputted character and translates it into an ASCII code, and then into binary, then puts that into an image in which each black pixel represents a 1 and each white pixel represents a 0 .

For example, A is 65 which is 1000001 in binary, B is 66 which is 1000010 , and C is 67 which is 1000011 , so the corresponding verticode would look like this.

Except, it isn't that simple.

A color shift is also integrated, which means that the color before each verticode shifts the ASCII code, by adding the number that the color corresponds to, before translating it into binary. In that case, the previous verticode could also look like this.

The table for the color codes is:

  • 0 = Red
  • 1 = Purple
  • 2 = Blue
  • 3 = Green
  • 4 = Yellow
  • 5 = Orange

This means that a red color shift for the letter A , which is 65 + 0 = 65 , would translate into 1000001 in binary; however, a green color shift for the letter A , which is 65 + 3 = 68 , would translate into 1000100 in binary.

Given this verticode, read the verticode into text and find the flag.

Note that the flag will not be in the typical sctf{flag} format, but will be painfully obvious text. Once you find this text, you will submit it in the sctf{text} format. So, if the text you find is adunnaisawesome , you will submit it as sctf{adunnaisawesome} .

Files:

code1.png

Hint:

Try looking up some imaging libraries.

Solution:

This is another fairly straight-forward algorithm/crypto problem - I actually felt that it was more on the algorithm side than crypto. (Because when do they ever tell you how to decrypt something?) The task was simply to

  1. Find the color of the row from the leading pixels
  2. Jump to the beginning of the actual b/w verticode
  3. Read in the b/w verticode
  4. Shift it by the magnitude specified by the color
  5. Rinse and repeat

I then wrote up something like this:

import java.awt.image.BufferedImage;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.imageio.ImageIO;

public class Code1 {

    public static final int SHIFT = 12;
    public static final int SKIP = 74;
    public static final int RED = 0xff0000;
    public static final int RED_VALUE = 0;
    public static final int ORANGE = 0xffa500;
    public static final int ORANGE_VALUE = 5;
    public static final int YELLOW = 0xffff00;
    public static final int YELLOW_VALUE = 4;
    public static final int GREEN = 0x008000;
    public static final int GREEN_VALUE = 3;
    public static final int BLUE = 0x0000ff;
    public static final int BLUE_VALUE = 2;
    public static final int PURPLE = 0x800080;
    public static final int PURPLE_VALUE = 1;
    public static final int BLACK = 0x000000;
    public static final int WHITE = 0xffffff;
    public static final int MASK = 0xffffff;

    public static void main(String[]args){
        try {
            BufferedImage image = ImageIO.read(new File("code1.png"));
            calculate(image);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static String calculate(BufferedImage image){
        Map<Integer, Integer> values = new HashMap<Integer, Integer>();
        values.put(RED, RED_VALUE);
        values.put(ORANGE, ORANGE_VALUE);
        values.put(YELLOW, YELLOW_VALUE);
        values.put(GREEN, GREEN_VALUE);
        values.put(BLUE, BLUE_VALUE);
        values.put(PURPLE, PURPLE_VALUE);
        String finalThing = "";
        try {
            for(int i = 0; i < image.getHeight(); i+= SHIFT){
                int value = image.getRGB(0, i);
                value = value & MASK;
                Integer cV = values.get(value);
                if(cV == null){
                    throw new IllegalStateException("Something's wrong with your colors at "
                            + "line number " + i + " , color is: " + Integer.toHexString(value));
                }
                int color = cV.intValue();
                String s = "";
                for(int j = 84; j < 168; j+= SHIFT){
                    int bitRGB;
                    try{
                        bitRGB = image.getRGB(j, i);
                    }
                    catch(ArrayIndexOutOfBoundsException e){
                        e.printStackTrace();
                        System.out.println(i + "," + j);
                        throw e;
                    }
                    bitRGB = bitRGB & MASK;
                    if(bitRGB == WHITE){
                        s += "0";
                    }
                    else if(bitRGB == BLACK){
                        s += "1";
                    } else{
                        throw new IllegalStateException("Something's wrong with your black and white at "
                                + "line number " + j + " , color is: " + Integer.toHexString(bitRGB));
                    }
                }
                int charValue = Integer.parseInt(s, 2);
                charValue -= color;
                finalThing += (char) charValue;
            }

        }
        finally{

            File file = new File("output.txt");
            BufferedWriter bw = null;
            try{
                bw = new BufferedWriter(new FileWriter(file));
                bw.write(finalThing);
            } catch(IOException e){

            }
            finally{
                if(bw != null){
                    try{
                        bw.close();
                    }
                    catch(IOException e){

                    }
                }
            }
            System.out.println(finalThing);
        }

        return finalThing;
    }
}

Running the code gave me this:

JoeLopowasamanofmildtemperamentshortstatureandhadthegoaltobecometheworldsfastesttelephoneeaterThoughLoponeverknewevenbasicphysicshecreatedatelescopecapableofsightingthesmallesthaironanalienwholivedquiteafewlightyearsawayJoeLopoquicklydestroyedalargeboulderandusedtheshatteredremainstoformeightsmallstatuesthatstronglyresembledtinycreaturesbeingorrelatedtothewaterfleaHeplacedtheminacircularpatterntoformasortofshrineandplacedthetelescopeinthemiddleofitHethenchanneledthepowerofthestonewaterfleasintothetelescopetoviewthepoweroftheheavensHewasinatrancewiththebeautyofthemysteriousdimensionanddidntevennoticetheverylargetornadoheadingtowardhimTheshrinewasquicklydemolishedandtheimmediatewithdrawlofpowersentJoeLobointoalairofpitchblacknessfoundtobeaparalleldimensionthatcausABCiamtheflagalllowercasenojokeDEFanyonewhosefirstnamebeganwithJalongwithMLandQtobecomeratheruncomfortableJoewasalsosuddenlyintroducedtoundroclamaticolomphasisciousytheeccentrictapewormwithastrongmorrocanaccentImundroclamaticolomphasisciousytheeccentrictapewormIlikepizzasohowareyadoinIhavenoideasaidJoe

Nice story about Joe Lopo, with the flag hidden in the middle:

iamtheflagalllowercasenojoke

FLAG: sctf{iamtheflagalllowercasenojoke}