peteris.rocks

Swedbank Ethical Hacker Puzzle

Solution to a puzzle by Swedbank for their Ethical Hacker position

Last updated on

Swedbank is a Swedish bank that operates in Scandinavia and the Baltic states.

They are looking for a security expert as indicated by their job posting for "Ethical Hacker" (archived copy).

Do you like to solve puzzles and to figure out how things work?
How about finding security flaws in applications and devices?

Job title: Ethical Hacker
Base of operations: Vilnius / Riga / Tallinn

In the job posting, all you see is this crypted message:

KFllYWgsIHdlIGtub3csIGl0IHdhcyB0cml2aWFsIC4uLikKCkRlc2lyZWQgc2 tpbGxzOgoqIFdpZGUgc3BlY3RydW0gSVQga25vd2xlZGdlIChuZXR3b3JrLCBPU ywgYXBwbGljYXRpb25zLCBkYXRhYmFzZXMsIHByb3RvY29scywgZXRjLikKKiBL bm93aW5nIHRoZSBjb21tb24gYmVzdCBwcmFjdGljZXMsIHZ1bG5lcmFiaWxpd GllcywgYW5kIGV4cGxvaXRhdGlvbiB0ZWNobmlxdWVzCiogS2VlbiB0byBkZXZ lbG9wIHNlY3VyaXR5IHRlc3RpbmcgZXhwZXJ0aXNlIGFjcm9zcyBhIG51bWJlciB vZiBhcmVhcwoqIE5vdCByZWx5aW5nIG9uIHJlYWR5LW1hZGUgdG9vbHMgdG 8gc29sdmUgY2hhbGxlbmdlcwoqIEFiaWxpdHkgdG8gY3JlYXRlIHlvdXIgb3duIH Rvb2xzCiogQXQgbGVhc3QgYmFzaWMgY3J5cHRvZ3JhcGh5IGtub3dsZWRnZ QoqIFRoaW5raW5nIG91dHNpZGUgb2YgdGhlIGJveCBieSBkZWZhdWx0CiogQ XR0ZW50aW9uIHRvIGRldGFpbHMKCjdkMDYzYTc1MmMzYTIwNzUzZTNiM 2EyMjc1MjEzZDMwNzUzNzM0MjYzYzM2MjY3OTc1MzYzYTNhMzk3NDdjN WY1ZjA3MzAyNjI1M2EzYjI2M2MzNzNjMzkzYzIxM2MzMDI2NmY1ZjdmNz UwNTMwM2IzMDIxMjczNDIxM2MzYTNiNzUyMTMwMjYyMTNjM2IzMjc1 MzQzYjMxNzUzMTNhMzYyMDM4MzAzYjIxM2MzYjMyNzUyMTNkMzA3NT MzM2MzYjMxM2MzYjMyMjY1ZjdmNzUwMzMwMjczYzMzMmM3NTIzMjA zOTNiMzAyNzM0MzczYzM5M2MyMTNjMzAyNjc1MjczMDI1M2EyNzIxMz AzMTc1MzcyYzc1M2EyMTNkMzAyNzI2NWY3Zjc1MTQyNjI2M2MyNjIxNzU zMTMwMjMzMDM5M2EyNTMwMjcyNjc1M2MzYjc1MzMzYzJkM2MzYjMy NzUyNjMwMzYyMDI3M2MyMTJjNzUzNzIwMzIyNjVmN2Y3NTA2M2QzNDI 3MzA3NTJjM2EyMDI3NzUzZTNiM2EyMjM5MzAzMTMyMzA3NTIyM2MyMT NkNzUzNjNhMzkzOTMwMzQzMjIwMzAyNjVmNWYxYTI1MjUzYTI3MjEyMDN iM2MyMTNjMzAyNjZmNWY3Zjc1MTkzMDM0MjczYjNjM2IzMjc1M2IzMDIy NzUyMTMwMzYzZDNiM2EzOTNhMzIzYzMwMjY3NTM3MmM3NTIxMzAy NjIxM2MzYjMyNzUzMTNjMjMzMDI3MjYzMDc1MjYyYzI2MjEzMDM4MjY1Z jdmNzUwNjNlM2MzOTM5NzUyNjMwMjE3NTMxMzAyMzMwMzkzYTI1M zgzMDNiMjE3NTIxM2QyNzNhMjAzMjNkNzUyNjI1MzAzNjNjMzQzOTNjMm YzMDMxNzUyMTI3MzQzYzNiM2MzYjMyMjY1ZjdmNzUxNzMwNzUzNDc 1MjUzNDI3MjE3NTNhMzM3NTI2MzAzNjIwMjczYzIxMmM3NTNjM2IzNjNj MzEzMDNiMjE3NTI3MzAyNjI1M2EzYjI2MzA3NTIxMzAzNDM4NWY1ZjAyM zQzYjIxNzUyMTNhNzUzZjNhM2MzYjc1MjAyNjZhNzUxMjMwMjE3NTIxM2Qz MDc1MzYzYTNiMjEzNDM2MjEyNjc1MzMyNzNhMzg2ZjVmM2QyMTIxMjUyNj ZmN2E3YTNmM2EzNzdiM2Q2MTM2M2U3YjM4MzA3YTM2M2EzYjIxMzQzNjIxN2EK

which is a Base64 encoded text.

You can decode it online at base64decode.org:

(Yeah, we know, it was trivial ...)

Desired skills:

  • Wide spectrum IT knowledge (network, OS, applications, databases, protocols, etc.)
  • Knowing the common best practices, vulnerabilities, and exploitation techniques
  • Keen to develop security testing expertise across a number of areas
  • Not relying on ready-made tools to solve challenges
  • Ability to create your own tools
  • At least basic cryptography knowledge
  • Thinking outside of the box by default
  • Attention to details

It lists the desired skills in plain text and gives you the next piece of the puzzle at the end (I've added line breaks for clarity):

7d063a752c3a20753e3b3a2275213d30753734263c36267975363a3a39747c5f5f073026253a3b263c373c393c213
c30266f5f7f7505303b30212734213c3a3b75213026213c3b3275343b3175313a362038303b213c3b3275213d3075
333c3b313c3b32265f7f750330273c332c752320393b302734373c393c213c3026752730253a2721303175372c753
a213d3027265f7f751426263c26217531302330393a25302726753c3b75333c2d3c3b327526303620273c212c7537
2032265f7f75063d342730752c3a2027753e3b3a22393031323075223c213d75363a39393034322030265f5f1a252
53a2721203b3c213c30266f5f7f75193034273b3c3b32753b3022752130363d3b3a393a323c302675372c75213026
213c3b3275313c233027263075262c26213038265f7f75063e3c3939752630217531302330393a2538303b2175213
d273a20323d75262530363c34393c2f3031752127343c3b3c3b32265f7f75173075347525342721753a3375263036
20273c212c753c3b363c31303b2175273026253a3b263075213034385f5f02343b2175213a753f3a3c3b7520266a7
512302175213d3075363a3b21343621267533273a386f5f3d212125266f7a7a3f3a377b3d61363e7b38307a363a3b
213436217a

It's got numbers and letters from a-z which indicates that it might be a hex encoded message.

If you use python3 to decode it

import codecs

s = '7d063a752c...'
d = codecs.decode(s, 'hex')
print(d)

all you'll get is gibberish:

b'}\x06:u,: u>;:"u!=0u74&<6&yu6::9t|__\x070&%:;&<7<9<!<0&o_\x7fu\x050;0!\'4!<:;u!0&!<;2u4;1u1:6 80;!<;2u!=0u3<;1<;2&_\x7fu\x030\'<3,u# 9;0\'47<9<!<0&u\'0%:\'!01u7,u:!=0\'&_\x7fu\x14&&<&!u10#09:%0\'&u<;u3<-<;2u&06 \'<!,u7 2&_\x7fu\x06=4\'0u,: \'u>;:"90120u"<!=u6:99042 0&__\x1a%%:\'! ;<!<0&o_\x7fu\x1904\';<;2u;0"u!06=;:9:2<0&u7,u!0&!<;2u1<#0\'&0u&,&!08&_\x7fu\x06><99u&0!u10#09:%80;!u!=\': 2=u&%06<49</01u!\'4<;<;2&_\x7fu\x170u4u%4\'!u:3u&06 \'<!,u<;6<10;!u\'0&%:;&0u!048__\x024;!u!:u?:<;u &ju\x120!u!=0u6:;!46!&u3\':8o_=!!%&ozz?:7{=a6>{80z6:;!46!z'

Maybe it's ROT13 or something like that? No, doesn't look like it.

If you try adding or substracting a number to each letter code, you'll eventually discover that adding -85 to the char code

print(''.join(map(lambda c: chr(c-85 if c-85 > 0 else c), d)))

gives the following:

(: ,:  >;:" !=0 74&<6&$ 6::9'

0&%:;&<7<9<!<0&
* 0;0!'4!<:; !0&!<;2 4;1 1:6 80;!<;2 !=0 3<;1<;2&
* 0'<3, # 9;0'47<9<!<0& '0%:'!01 7, :!=0'&
* &&<&! 10#09:%0'& <; 3<-<;2 &06 '<!, 7 2&
* =4'0 ,: ' >;:"90120 "<!= 6:99042 0&

%%:'! ;<!<0&
* 04';<;2 ;0" !06=;:9:2<0& 7, !0&!<;2 1<#0'&0 &,&!08&
* ><99 &0! 10#09:%80;! !=': 2= &%06<49</01 !'4<;<;2&
* 0 4 %4'! :3 &06 '<!, <;6<10;! '0&%:;&0 !048

4;! !: ?:<;  & 0! !=0 6:;!46!& 3':8
=!!%&%%?:7&=6>&80%6:;!46!%

Still gibberish but you can see what is perhaps the outline of the text: line breaks and bullet points.

We can probably now decode three characters: new line, bullet point and space because there's usually a space right after a bullet point.

def decode(c):
  if c == 127: return '*'
  if c == 95: return '\n'
  if chr(c) == 'u': return ' '
  return '-' # chr(c)

print(''.join(map(decode, d)))

Which gives us:

--- --- ---- --- ------- ------

-----------------
* ----------- ------- --- ----------- --- --------
* ------ --------------- -------- -- ------
* ------ ---------- -- ------ -------- ----
* ----- ---- --------- ---- ----------

--------------
* -------- --- ------------ -- ------- ------- -------
* ----- --- ----------- ------- ----------- ---------
* -- - ---- -- -------- -------- -------- ----

---- -- ---- --- --- --- -------- -----
----------------------------

The last line had no spaces which made me guess that perhaps it's a URL? The gibberish for the last line is x!!xx%%xxx%xxx% which has a double ! and a double % which could mean http://.

remap = {
  'u': ' ',
  '_': '\n',
  '\x7f': '*',
  '=': 'h',
  '!': 't',
  '%': 'p',
  '&': 's',
  'o': ':',
  'z': '/'
}

print(''.join(map(lambda c: remap[chr(c)] if chr(c) in remap else '-', d)))

which gives us clues to guess all other letters:

--- --- ---- th- --s--s- ------

--sp--s-----t--s:
* ----t--t--- t-st--- --- -------t--- th- -------s
* ------ -----------t--s --p--t-- -- -th--s
* -ss-st ------p--s -- ------ s-----t- ---s
* -h--- ---- --------- --th ---------s

-pp--t---t--s:
* -------- --- t--h-------s -- t-st--- -----s- s-st--s
* ----- s-t ------p---t th----h sp--------- t-------s
* -- - p--t -- s-----t- -------t --sp--s- t---

---t t- ---- -s- --t th- ---t--ts ----:
https://----h------/---t--t/

The final text is

-So you know the basics? cool--

Responsibilities:
* Penetration testing and documenting the findings
* Verify vulnerabilities reported by others
* Assist developers in fixing security bugs
* Share your knowledge with colleagues

Opportunities:
* Learning new technologies by testing diverse systems
* Skill set development through specialized trainings
* Be a part of security incident response team

Want to join us? Get the contacts from:
https://job.h=ck.me/contact/

You still have to guess that = stands for but it should not take too much time to realize that the address is https://job.h4ck.me/contact/ which is the next piece of the puzzle.

The website is pretty basic:

Login form

<form method="POST">
<table>
<tr><td><label for="user">User:</label></td><td><input type="input" name="user"></td></tr>
<tr><td><label for="user">Pass:</label></td><td><input type="password" name="pass"></td></tr>
<tr><td colspan=2><input type="submit" value="Login"></td></tr>
</form>

They most likely want you to use an SQL injection to break it.

The good old ' OR 1=1 -- does not work for the password field but does work for the username field.

QR code when logged in

It's a QR code obviously but when you try to decode it online, it doesn't work.

If you google for qr code and compare the example with the found QR code, you'll notice that the colors are inverted.

QR code in Google Search

Inverting the colors gives us the following QR code:

QR code with colors inverted

You can decode it online at zxing.org to get the following text message that was encoded in the QR code:

Congratulations, you have completed our little challenge! Would you like to join our team? https://job.h4ck.me/contact/VGhlIGVuZCEK.txt

There is no puzzle at that address and it simply says

If you are interested in joining our team, please send your CV to: [email protected].