Julia programming language:
using FileIO, Colorsjoin(map(hex, load("colorblind.png")))
This works because images in Julia are simple arrays containing the RGB
value of each pixel. We map the hex
function (provided to us by Colors
) over the color values, which returns an array with HEX
values. We then join all the values together, which gives us the following string:
626C6168626C6168626C61685F68656C6C6F5F686F775F6172655F796F755F746F6461795F695F686F70655F796F755F6172655F6E6F745F646F696E675F746869735F6D616E75616C6C795F696E6665726E6F4354467B6833795F3130306B5F7930755F3472335F6E30375F6833785F626C316E445F3A4F7D5F646F696E675F746869735F6D616E75616C6C795F776F756C645F62655F615F6261645F696465615F796F755F73686F756C646E745F646F5F69745F6D616E75616C6C795F6F6B
This string can probably be translated to readable text using Julia, but it was quicker to copy this output and paste it in an online hex to string converter:
blahblahblah_hello_how_are_you_today_i_hope_you_are_not_doing_this_manually_infernoCTF{h3y_100k_y0u_4r3_n07_h3x_bl1nD_:O}_doing_this_manually_would_be_a_bad_idea_you_shouldnt_do_it_manually_ok
The output above contains the flag:
infernoCTF{h3y_100k_y0u_4r3_n07_h3x_bl1nd_:O}
The goal of this challenge was to construct a string that matches the regex
given to us in the challenge attachment:
infernoCTF{.(?<=H){21}.[a-z](?<=\+a){1024}[a-z][a-j](?<!([a-u]|[w-z])(j|[a-h])).{2,64}(?<!\S){255}n.{2}(?<=\s)g_fUn\W(?<=[A-z])}(?<=\..{14})(?<=^.{33})
The given regex
is complex at first glance, but the challenge itself is very straightforward. We did not find a way to automate the solution of this challenge, so we solved it by hand. First, we simplified the regex
by removing the quantifiers after the lookbehinds, because they do not serve a purpose. Removing these quantifiers will give us an equivalent, but shorter, regex
:
infernoCTF{.(?<=H).[a-z](?<=\+a)[a-z][a-j](?<!([a-u]|[w-z])(j|[a-h])).{2,64}(?<!\S)n.{2}(?<=\s)g_fUn\W(?<=[A-z])}(?<=\..{14})(?<=^.{33})
We start by learning about lookbehinds. Positive lookbehinds (e.g, "(?<=a)b"
) match the character after the parenthesis, but only if the character is followed by the character in the parenthesis, after the =
. Negative lookbehinds (e.g, "(?<!a)b"
) match the character after the parenthesis, but only if they are not followed by the character in the parenthesis, after the !
. Knowing this, we can start constructing our flag.
Our flag starts with infernoCTF{
, because the given regex
states that we have to match these characters literally. .
in our regex matches any character in our flag, so we will put an X
as a placeholder. We now have to match the positive lookbehind (?<=H).
, which means that our string will only match the regex when we have a character following the character H
. We could try adding H+
to our flag (making our flag infernoCTF{XH+)
, but this will not match the given regex. The cause of this mismatch is the fact that lookbehinds only match the character after the parenthesis. It will not match the character in the parenthesis.
The solution for this problem is replacing our previous X
with an H
. We now have infernoCTF{H+
, which matches the first part of our regex
. The rest of the regex
follows the same principle: we have a bunch of lookbehinds that force us to precede a character with another character. Around those lookbehinds we have more common regex
symbols that make it possible to match the character in the parenthesis. Now that we got the gist of the challenge, we will quickly go over the solution:
infernoCTF{
forces us to start our flag with infernoCTF{
.(?<=H).[a-z](?<=\+a)
forces us to add H+a
[a-z][a-j](?<!([a-u]|[w-z)(j|[a-h])).{2,64}
makes us add vi
to our flag, followed by an unspecified amount (between two and sixty-four, which will be constrained later in the regex
) of placeholder characters(?<!\S)n
forces us to add an n
after a whitespace character.{2}(?<=\s)g
forces us to add a g
after a whitespace character_fUn
forces us to add _fUn
to our flag\W(?<=[A-z])}
forces us to add a }
after a non-word character between A
and z
in the ASCII table (e.g., ]
)(?<=\..{14})
forces us to count fourteen characters back and add a .
. We can safely put our .
in the collection of unspecified characters mentioned in the third step above.
The last part of our regex
forces us to make the flag exactly thirty-three characters long. This can be achieved by adding or removing a bunch of unspecified characters (which were mentioned in the same third step). One of the possible solutions is infernoCTF{H+avi . ng no g_fUn]}
.
Because of a lack of knowledge about tools that generate strings based on given regex
(that also support lookbehinds!), we decided to solve this challenge by hand. Although it is a bit of tedious work, it certainly is possible to construct the flag manually.