The Link: My Solution This article is last updated over 5 years ago, the information mentioned may be changed or developed.Tags: The Link, NUSSOC, National University of Singapore School of Computing, nussoc.com, Hacking challenge 0x00: What is The Link? Link: http://nussoc.com/ 0x01: Level 1. code is in the code. — From the official hint From the source of level 1, we can see an AJAX request: 12345678910111213141516 $(document).ready(function(){ $('#submit').click(function(){ if($('.password').val().trim() != ''){ $.ajax({ type: 'GET', url: 'submit.php', data:{pass:$('.password').val()}, success:function(html) { window.location.href="process.php?unique_code="+$('.password').val(); } }); } else { alert('Please enter code!'); } }); When the “code” is submitted, it firstly checks against a webpage called submit.php and pass pass as a parameter. In page submit.php?pass=mypass, there’s a piece of JS code as follows. 12345678910111213141516171819 function a(){ var pass = 'mypass'; var passwd; passwd = 'wewanttohireyou'; passwd= passwd + 'showuswhatyougot'; passwd= ''; passwd='youdidit'; passwd=passwd+'_welldone'; if (passwd==pass) { return 'Challenge Passed'; } else { return 'Challenge Failed'; }} Basically, the passcode supposed to be the value of passwd. Throwing it into a console. (actually can just read, I just kinda lazy). The pass code is youdidit_welldone. You did it. Well done. 0x02: Level 2 Okay, in level 2, there’s quite some obstacles. let’s solve them one by one. 0x0200: User-agent Browse “The Link” using “Link” — [Official hint](https://www.facebook.com/NusSchoolOfComputing?sk=app_202980683107053&app_data=1f07b25f-f4b3-4e09-bca6-8f5621f3c6df%3A0) When the level is first opened, the box shows “BROWSER NOT SUPPORTED”. When checking its source code, there’s a commented “tinyurl” link that points to an article on Wikipedia. 1 <!-- http://tinyurl.com/5ru8yvp --> It’s about a browser called Links). (Maybe it just happen that there’s such a browser that have the same name as the hacking event, and with an extra s.) I tried to google for links user agent, then I come across with this site that happened to have the UA string for that classical browser. I then grabbed the first line of it, says: Links (6.9; Unix 6.9-astral sparc; 80×25) Using Chrome’s DevTools Device Emulator to change my UA string to it. I successfully accessed the correct page. 0x0201: QR codes. On the puzzle window, there’s 2 QR codes, and between them, there’s some spacing. Firing up the view-source window, I see this few lines. 123 <div style="padding:10px;float:left;"><img src="images/qrcode1.svg" width="100px" height="100px"/></div><!-- http://nussoc.com/challenges/2/images/qrcode2.svg --><div style="padding:10px;float:left;"><img src="images/qrcode3.svg" width="100px" height="100px"/></div> Obviously, there’s a 1, a 3, and hidden in between, there’s a 2. Scanning them one by one, this is the result i get. QR code 1: b25lc3RlcGZ1cnRoZXI= QR code 2: _tojoin_ QR code 3: a236210022be614ff79d33a8268093ac So, first one we can see there’s an equal sign at the end, likely it’s a base64 encoded string. In the JS console, I typed: 12 > atob("b25lc3RlcGZ1cnRoZXI=");< "onestepfurther" So here, we got the first portion. Nothing much to say about the second one. _tojoin_ is _tojoin_. The last part is a 32-char hexadecimal string. What does it reminds you? MD5, right? Throw it into google, I got this. There’s only 4 results at the time of writing, where the first two of them gives the result of thelink. So, we’ve also got the last portion. Joining them together, we can easily get the passcode, onestepfurther_tojoin_thelink. 0x03: Level 3 This is a super tough level. I didn’t manage to solve it at the time of writing. But I do get something. EDiT: Seems I have made a careless mistake. runningkeycipherentrytothelink is the code. When entering the level, there’s nothing special hidden in the source code. The only clues are: In the URL, there’s a parameter says ctext=syfgmcvsreubduijxbuzezskhxeipuadeab On the picture, there’s a book titled “Web application security for Dummies” In the first 5 hours, no one have solved it. The admin has posted quite a lot of hints in the forum. Did you notice the book in the background? That might give you a hint . Saying the book is useful. Heard of “Tabula Recta”? That is one of the encryption methods used. Use the book to find the key! http://www.bradreese.com/qualys-web-application-security-for-dummies.pdf A download link to the book. How many possible ciphers using book ? We have used one of them .. A book-related encryption method is used. Some researches has been done on google, and through trial and error, I found out that the encryption method they used is called Running Key Cipher. To crack the key using computer, I have found this site (1, 2) which provides a Python script for auto cracking Vigenere Cipher (the base cipher used by Running key). In fact, what we need to use is only a few things: english_quintgrams.txt.zip as a dictionary for language analysis ngram_score.py for calculating match score with N-gram algorithm pycipher for Vigenere decryption algorithm To prepare the book, we need some pre-processing to the PDF file. After downloading it, we need to convert it to a txt file. There’s plenty of such tools, just google for it. Then we need to filter out all other characters, left only with letters, and convert them to uppercase. We can do this with Python. 123456 import ref = open("WAS.txt").read() # read the filef = re.sub(r'[^A-Z]', '', f.upper()) # convert the string to uppercase and remove other charsof = open("WAS.out.txt", 'w')of.write(f) # create a new file and write to it Then we can write our own script for decryption. 12345678910111213141516171819202122232425262728293031323334 from ngram_score import ngram_scorefrom pycipher import Vigenerefrom itertools import permutationswl = file("WAS.out.txt").read() # the bookg = ngram_score("english_quintgrams.txt") # the scorerct = 'SYFGMCVSREUBDUIJXBUZEZSKHXEIPUADEAB' # the ctextdef w(key): """Calculate the key""" a = Vigenere(key).decipher(ct) return (a, key)d = [] # used to store all the resultsdef s(t): """Store the deciphered text, score, and key used""" s = g.score(t[0]) d.append[1] for i in range(len(wl)-len(ct)+1): # for all possible keys s(w(wl[i:i+len(ct)])) # calculate the keyd = sorted(d, key=lambda a: a[1]) # sort by their scoreprint d[-10:] # Print the best 10 results``` After calculation, the best result obtained is:```python('RUNNINGKEYCIPHERENTRYTOTHELINKIPNHN', -151.94413608449415, 'BESTEPPINGSTONESTOBIGGERATTACKSORTO') 'RUNNINGKEYCIPHERENTRYTOTHELINKIPNHN' is the plain text 'BESTEPPINGSTONESTOBIGGERATTACKSORTO' is the key, found on page 34(40) of the book. (“be stepping stones to bigger attack or to leak sensitive …”) Highest score of -151.94 After several attempts, none of the codes below are the answer: RUNNINGKEYCIPHERENTRYTOTHELINKIPNHN runningkeycipherentrytothelinkipnhn runningkeycipherentrytothelink ipnhn IPNHN rho isrho runningkeycipherentrytothelinkisrho # it’s not rho. Removing the unreadable 5 letters, the key is runningkeycipherentrytothelink. 0x04: Level 4 Somehow easier. This time there’s an MP3 file on the webpage. The filename of it reads OWASP Appsec Tutorial - Appsec Basics - Challenge. After googling, that’s extracted from a YouTube video. Through Observation, the audio file is 9 minutes long, but the video is only 8:31. By comparing the difference, there’s some weird sound heard in between. By googling ‘hide message in MP3’, I found out an method that can hide image in the spectrogram of the audio file. Using a tool to show out the spectrogram, words can be seen. I forgot to include the “One” in the beginning. The tool I used is called Sonic Visualiser So the passcode is GoodJob_AllSetForLastOne. 0x05: Level 5 Not as difficult as Level 3. Nothing special on the webpage. Checking the source code, I see a link of .pcap packet file. 1 <!-- http://nussoc.com/challenges/5/files/challenge5.pcap --> Open it with Wireshark, I see some HTTP packets. Filtering all the HTTP packets, this is what I get: Reading them one by one, I observed there’s a web app that allows file uploads, and the client is keep uploading something. In fact, only two of the packets are useful. No. 32: POST /app/uploader.php HTTP/1.1 (application/octet-stream) A file is uploaded. (That’s the Hex of the file) 12345678910 52 61 72 21 1a 07 00 cf 90 73 00 00 0d 00 00 0000 00 00 00 b9 60 74 24 94 35 00 50 00 00 00 3c00 00 00 02 9d 58 3d cd f2 93 28 47 1d 33 08 0020 00 00 00 63 32 56 6a 63 6d 56 30 fe 64 5e 038d 9b fd b3 00 b0 02 b0 4c 46 eb 7c 93 d3 a0 069f 3e 88 d2 67 5e 6a 78 1c 3f 28 19 50 5e b1 aacd d2 18 ee 89 88 b4 9e fb 3d 33 1e 24 b6 ac 4c24 86 73 67 f0 64 c5 34 8b 41 5e 67 9f 6f 40 66a8 a5 50 7d b7 4c d5 af 91 ef b0 69 19 86 f1 4e1c 3c d4 49 2b dc 2a fc 1b c4 3d 7b 00 40 07 00 52 61 72 71 is Rar!, so we can confirm it’s an RAR file. Opening the archive, there’s a file called c2VjcmV0, password protected. No. 52: POST /app/uploader.php HTTP/1.1 (text/plain) A plain text file is uploaded. iamhere.txt which says: 1 password is welcome Okay, password is welcome. Using this password, we can open the file in that RAR archive. It says: VFdsemMybHZia052YlhCc1pYUmxaRjlYWld4amIyMWxWRzlVYUdWTWFXNXI= Umm… [A-Za-z0-9]+={0,2}, yet another Base64. 12 > atob("VFdsemMybHZia052YlhCc1pYUmxaRjlYWld4amIyMWxWRzlVYUdWTWFXNXI=")< "TWlzc2lvbkNvbXBsZXRlZF9XZWxjb21lVG9UaGVMaW5r" Another Base64?! I just don’t know why the setter like Base64 so much. Well… 12 > atob("TWlzc2lvbkNvbXBsZXRlZF9XZWxjb21lVG9UaGVMaW5r")< "MissionCompleted_WelcomeToTheLink" Nothing special, that’s the key. MissionCompleted_WelcomeToTheLink. 0x06: Afterwords Despite I have spent quite short time to finish the last level, I didn’t manage to get into the ranking. Well, whatever. I got it solved. And I hope this could help you. Just outside of the ranking, my score is 1573. t[0], s, t[1][↩︎] Related