# URCHINSEC CTF MMXXII WRITEUP
i avoided to be an organizer so i could play on this CTF after finishing a UE :grinning::grinning::grinning::grinning:

so here are my solves
## DISCORD CHALLENGES
### WELCOME [50 Points]

**solution**
joined the server under #urchinsec-ctf-rules! channel we
flag : urchin{welcome_hacker!!}

****
### urchinbot [50 Points]

**solution**
i didnt solve it because the bot was acting weird so the free flag was given
flag : urchin{y0u_c4n_pl4y_witH_BOTS}

****
## OSINT CHALLENGES
##
### dummies [100]

**solution**
i just took some text and google it
flag : urchin{lorem_ipsum}

****
### welcome To OSINT [100]

**solution**
easy challenge also like previously you just need to google but if you are familiar with type a question you are already know the answer
flag : urch{ransomware}

****
### Zipped [150 points]

**solution**
i downloaded the picture and its look like

i guessed this must be dar es salaam and i dont actually live Dar es salaam haha, but i was able to solve early,
`osint way like pro`
googled `building with telecom tower in dar`

see the third result its **Airtel headquarter** so since i dont live dar i had to call my young bro to tell where exactly state located and he told me **mikocheni**
look at tcra zip code

boooom
flag : urchin{14112}
*****
## FORENSICS CHALLENGE
### Streams [100 points]

**solution**
we were given a pcap file so a wireshark tool is a way to go, so the first thing to look is for **http** request since its easy challenge

then follow **tcp stream** we got flag

flag : urchin{wireshark_1s_pr3tty_g00d_f0r_analys!NG}
****
### Duck Duck Dock [150 points]

**solution**
i took so long to solve this because i was thinking the hard way,
using dive

exploring a docker layers found this existing file /opt/jump.sh

i extracted the file and found weird texts

using chef

i struglled with this output until i found because chef didnt decode some character well
flag : urchin{d>cker_f>rensics_is_fun}
****
### Meta [150 points]

**solution**
using exiftool to see meta data since challenge called meta

using chef to decode strings from **Artist** section

flag : urchin{metadatas_4re_v3ry_int3r3sting_stuff}
****
### virxx [200 points]

**solution**
well, challenge name virxx?? what virus? mhhhhh
opening file

just a strings!! came back to challenge name , its obviously this strings is a reverse shell payload so its always treated like virus... then what?? upload to virustotal

oh we get the flag there
flag : urchin{basic_skill_in_mal_analysis}
****
## CRYPTOGRAPHY CHALLENGES
##
### Base [100 points]

**Solution**
well since its marked as easy
since its weird strings then base85 is a way to go
base85

base58

last base64

boom
flag : urchin{base64_encoding_is_easy}
***
### Table [100 points]

**solution**
got one solve?? mhhhhh!!!
when since its a table things then lets consider about vigenere cipher ehh
but vigenere works with KEY EHH, then what is it?
guessing key : urchin
we get

ooops we are close i am able to decode initial urchin , so the organixation actual is urchinsec why not try as key????? ehh
then key : urchinsec

booom!!! we get flag easy piiz
flag : urchin{vigener3e_1s_34szpiz}
***
### Owner [100 points]

**solution**
its a hash , from my brain its actually a md5 but let prove it

ok i know google is a best tool for cracking md5 outhere hahah
just copied to google and it gave me

flag : urchin{admin}
***
### Morbase [150 points]

**solution**
well its a morse code
decoding using chef

the resuls is full capital letters and also its a base64
`why base64?`
`answer` : loo at first DXJJAGLUE fromoutput its actually a urchin word

if you solved this then you will know the struggle because base64 care about case, so that means output of a and A is different,
after manually fixing

boom
falg : urchin{l!f3_1s_b34ut!ful!!}
***
## REVERSE ENGINEERING CHALLENGE
aint my things but i can do easy one LOOOL!!!
### Add [100 points]

**solution**
we were given binary so i downloaded and run it
we were asked what two number makes 2022110 so its simple

boom!!
flag : urchin{fairly_34SyyT0_g3t}
***
### welcome [100 points]

**solution**
easy one , just run the binary and get flag

boom
flag : urchin{welcome_to_urchin_sec_ctf_2022}
***
### HellorUser [100 points]

**solution**
static analysis mhh!!, manually?? then lets start with strings

boom!!! am a RE engineer haha!!
flag : urchin{hellouser_GO_r3v3rsing_GO}
***
### CC [150 points]

**solution**
well the same way lets start with strings thou

we got some hex value
using chef

boom!!
flag : urchin{r3p0rt_r3p0rt_CC_d}
***
## WEB CHALLENGES
### Around

**solution**
from the name its all about LOOKING AROUND and get a flag haha
under main.js source code we get

under main.css source code

what more? what first?
look at robots.txt

boom!!!
flag : urchin{moving_i5_fUN_b11_rockingggg1}
***
### Panel [ 100 points]

**solution**
well the first hint is look at robots.txt

we got /secret.php
look at source code we got user:admin and password:V1ZkU2RHRlhOV2hrUjFaclRWUkplazVCYnowSwo=
decoding it

login with decoded password adminated1234

boom!!
flag : urchin{l33t_1337_L337_Hxxx0r}
***
### En-Code [100 points]

**solution**
look at source code we get weird strings

using chef i gave a shot to base85

boom
flag : urchin{html 1s c00l}
***
### HeadStart [ 150 points]

**solution**
first i thought an error was not intended lol, then later i had do directory search and found

i started with source endpoint
```
from flask import Flask, request, jsonify, render_template, url_for
from decouple import config
import jinja2_highlight
class MyFlask(Flask):
jinja_options = dict(Flask.jinja_options)
jinja_options.setdefault('extensions',[]).append('jinja2_highlight.HighlightExtension')
app = MyFlask(__name__)
flag = config('FLAG')
@app.route('/')
def index():
data = {'error':'Endpoint Specified Is Not Recognized'}
return jsonify(data)
@app.route('/getflag', methods=["PEWPEW"])
def getflag():
if request.method != 'PEWPEW':
data = {'error':'something went wrong'}
return jsonify(data)
else:
data = {'success':f'{flag}'}
return jsonify(data)
@app.route('/source')
def source():
return render_template('index.html')
if __name__ == '__main__':
app.run()
```
above code found on source endpoint, so actually there route called /getflag but only accept PEWPEW method to read a flag ohhh pewpew
get a flag

boom!!!
flag : urchin{m3th0ds_4re_F4scin@ting}
***
### Route

**solution**
opened the page on dowload navigation i got http://178.128.46.171:9004/download.php?file=document.txt
since we were told to get flag.txt then i changed to

boom!!
flag : urchin{LFI_pr3tty_l4m333}
***
### login

**solution**
there login page !!
lookin for source code we found view-source:http://178.128.46.171:9005/main.js javascipt
weird so i had to beautify it
we get
```
(async () => {
await new Promise(((_0x1f3ax1) => {
return window['addEventListener']('load', _0x1f3ax1)
})), document['querySelector']('form')['addEventListener']('submit', ((_0x1f3ax1) => {
_0x1f3ax1['preventDefault']();
const _0x1f3ax2 = {
u: 'input[name=username]',
p: 'input[name=password]'
},
_0x1f3ax3 = {};
for (const _0x1f3ax1 in _0x1f3ax2) {
_0x1f3ax3[_0x1f3ax1] = btoa(document['querySelector'](_0x1f3ax2[_0x1f3ax1])['value'])['replace'](/=/g, '')
};
return 'YWRtaW4' !== _0x1f3ax3['u'] ? alert('Incorrect Username') : 'dXJjaGlue3Bld19wZXdfcGV3X3Bld19wZXdfcGV3fQo' !== _0x1f3ax3['p'] ? alert('Incorrect Password') : void(alert(`${'Correct Password! Your flag is '}${atob(_0x1f3ax3['p'])}${'.'}`))
}))
})()
```
oops there kind of weird strings lets decode in chef

boom!!
flag : urchin{pew_pew_pew_pew_pew_pew}
***
### Route II

**solution**
spend time with this easy challenge lmao,

above error is LFI , exploiting using

but i could not get flag because it was not in php file and i was able only get lfi for php extension so i had to bruteforce!!

then

boom !! easy as hell
flag : urchin{RFI_@@@__PPEWWPEWW}
***
## MACHINE CHALLENGES
### Urchinbank -User

**solution**
for this challenge i could solve in time because i missed some potential info in dns enumaration but this is way to solve the box which i believe only user is hard !!
first to deal with challenge that you were given a domain which is not public is to add in /etc/hosts

first i added urchinbank.com alone then api and ibank was added later after i found it
Domain enumaration

found .git in api.urchinbank.com

dump those source code via git-dumper

dumped source code

in app.py there upload class where it takes strings and there opened with os.popen() method which actually led to command injection Bingo
```
class UploadFile(Resource):
def post(self):
try:
parser = reqparse.RequestParser()
parser.add_argument(
'file', type=str, help='File Required to be downloaded')
args = parser.parse_args()
_fileLink = args['file']
if _fileLink != "":
cmd = str(_fileLink)
msg = os.popen(f'{cmd}').read()
return {'StatusCode': 200, 'Message': str(msg)}
except Exception as e:
return {'error': str(e)}
```
i could go further because the server with port 8080 was down but i shared a progress for user
from here you can finish by creating payload and sent to server
using endpoint

example
```
curl -XPOST api.urchinbank.com:8080/upload -d "file=id"
```
thanks for **ChainPeter** for giving a hint to this challenge after competition ended!!
---
THANKS FOR READING!!! @malwarepeter