Compare commits

...

40 Commits

Author SHA1 Message Date
20f393270c fix: very small things 2025-04-20 09:12:17 +03:00
80ab5ec41f fix: readme 2025-04-20 09:11:06 +03:00
2ef2aeb87d fix: small things 2025-04-20 09:07:22 +03:00
8c90060541 fix: readme 2025-04-20 09:07:17 +03:00
ef1a05991c fix: readme 2025-04-20 09:06:54 +03:00
171e66387b
fix: readme 2025-04-19 23:31:29 +03:00
95639fceda feat: readme 2025-04-19 23:06:51 +03:00
bd018eceec fix: small things 2025-04-17 18:11:43 +03:00
393f1b3a9f feat(web): path traversal help 2025-04-17 16:46:55 +03:00
b256ffa363 feat(web): idor help 2025-04-17 16:11:32 +03:00
9b0220bdf6 feat(web): idor task and flag accept 2025-04-17 00:12:02 +03:00
648e98dcd1 wip: feat: mobile 2025-04-16 22:03:45 +03:00
34182b9929 feat(web): path-traversal task and flag accept 2025-04-16 19:33:47 +03:00
a22bc44764 feat(osint): hard task help 2025-04-16 11:27:57 +03:00
d42365119e feat(osint): hard task flag accept 2025-04-15 20:46:28 +03:00
3cd537f98f feat(osint): hard task 2025-04-15 16:48:54 +03:00
dad4e6cb96 feat(osint): map task help 2025-04-14 14:44:48 +03:00
e98018030b feat(osint): map task flag sccept 2025-04-14 12:37:39 +03:00
d4a60d402f warning 2025-04-13 10:31:44 +03:00
2b2596b573 feat(osint):found-me help 2025-04-12 22:07:53 +03:00
ec1b21a418 feat(osint): found-me flag 2025-04-12 17:23:53 +03:00
74317aef47 feat(forensic): hash help 2025-04-12 17:21:53 +03:00
34c42374b5 fix: cats errors 2025-04-12 17:21:53 +03:00
dc75b05877 fix: main-icon display 2025-04-12 17:21:53 +03:00
fb88fd9d67 feat(forensic): base help 2025-04-12 12:50:35 +03:00
c5f3d37ef6 feat(web): ssti help 2025-04-11 00:29:55 +03:00
cbb5f7cffe feat(web): ssti comments:3 2025-04-10 18:03:10 +03:00
a1eb5e8c27 feat(web): ssti back 2025-04-10 00:23:44 +03:00
4a639aeb9a feat(forensic): base text 2025-04-09 21:43:43 +03:00
d3b7f4b286 feat(forensic): hash task help 2025-04-09 21:38:16 +03:00
0302e4b964 feat(forensic): hash task and flag accept 2025-04-09 16:16:22 +03:00
649c621345 feat(forensic): hex task png 2025-04-08 23:40:29 +03:00
50946c114b feat(forensic): hex task and flag accept 2025-04-08 23:34:36 +03:00
16adc1d99e feat(forensic): base task and flag accept 2025-04-08 23:00:54 +03:00
de78c5f8a0 feat(forensic): binwalk task help 2025-04-08 22:03:36 +03:00
d271d2ce4d fix(forensic): binwalk task flag accept 2025-04-08 21:20:03 +03:00
e4c34ce8bd feat(forensic): binwalk task flag accept 2025-04-08 21:18:10 +03:00
1ce1b57b4b fix(forensic): metadata task flag accept 2025-04-08 20:22:57 +03:00
4c349249eb fix: forensic metadata task help 2025-04-08 15:39:15 +03:00
b32579b957 feat: forensic metadata task help 2025-04-08 14:43:15 +03:00
36 changed files with 866 additions and 102 deletions

View File

@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="jdk" jdkName="Python 3.12 virtualenv at ~/PycharmProjects/MadokaMagicaSite/venv" jdkType="Python SDK" />
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.venv" />
</content>
<orderEntry type="jdk" jdkName="Python 3.12 (CTF-site-project)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="PyDocumentationSettings">

1
.idea/misc.xml generated
View File

@ -3,4 +3,5 @@
<component name="Black">
<option name="sdkName" value="Python 3.12 (pythonProject)" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.12 (CTF-site-project)" project-jdk-type="Python SDK" />
</project>

6
.idea/vcs.xml generated Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

26
README.md Normal file
View File

@ -0,0 +1,26 @@
# CTF для самых маленьких #
## Что это такое? ##
CTF - это игра/соревнование в области Информационной Безопасности, где команда
при помощи различных уязвимостей ищет флаг - уникальную последовательность
символов
Этот проект - русскоязычный обучающий сайт с лёгкими CTF-тасками для самых
начинающих. К каждому заданию есть подсказка, полностью объясняющая ход решения
со ссылками на другие полезные ресурсы, в том числе, англоязычные
## Как использовать? ##
Просто заходи на сайт и решай! К каждому заданию есть подсказка: попробуй
решить сам или используй подсказку на кнопку снизу слева
----------
## Возникли проблемы? ##
Не спеши писать ишью! Пиши на почту: **e.a.sunduk@gmail.com**. Хочешь
поблагодарить? Посети наши другие проекты или ставь нам звёздочку:3
---------
## А где сайтик? ##
А вот же сайтик:
https://ctf.codrs.ru/

265
app.py
View File

@ -1,8 +1,11 @@
import werkzeug
from flask import Flask, render_template, request, url_for, session, redirect, g, abort, send_file
from flask import Flask, render_template, request, url_for, session, redirect, g, abort, send_file, render_template_string
import sqlite3
from random import getrandbits
from func import *
import base64
#Вот сюда тебе и надо, начинающий мастер OSINT'а! Только не смотри другие флаги: кто посмотрит, тот РџРѕРїРєР° :>
connection = sqlite3.connect('database.db')
cursor = connection.cursor()
@ -22,6 +25,16 @@ app = Flask(__name__)
app.config['SECRET_KEY'] = 'ca4ac4ada05f91a5790d2132992bfaed86df15c4d08f2dfe'
DATABASE = 'database.db'
@app.route("/osint/found_me", methods=('GET', 'POST'))
def osintfound():
Y0u_Fin4ly_F0und_7his = 'C4TchFl4g{Pls_supp0rt_my_pr0j3ct}'
if request.method == 'POST':
user_flag = request.form['user_flag']
if user_flag == Y0u_Fin4ly_F0und_7his:
return render_template('found-me.html', flag=Y0u_Fin4ly_F0und_7his, success_flag='.')
return render_template('found-me.html', flag=Y0u_Fin4ly_F0und_7his, error='Ошибка: неверный флаг!')
return render_template('found-me.html')
def get_db():
db = getattr(g, '_database', None)
if db is None:
@ -64,69 +77,6 @@ def websql():
return redirect(url_for('success_login'), code=302)
return render_template('sql-injection.html')
@app.route("/web/idor")
def webidor():
return render_template('idor.html')
@app.route("/web/path-traversal")
def webpt():
return render_template('path-traversal.html')
@app.route("/web/ssti")
def webssti():
return render_template('ssti.html')
@app.route("/web/portswigger-guide")
def webpsguide():
return render_template('portswigger-guide.html')
@app.route("/forensic/metadata")
def fmetadata():
session['task1_id'] = id = hex(getrandbits(45))[2:]
session['task1_flag'] = flag_task1 = f'C4TchFl4g{{{hex(getrandbits(45))[2:]}}}'
task1_flag(flag_task1, id)
if request.method == 'POST':
user_flag = request.form['user_flag']
if user_flag == flag_task1:
return render_template('task1-metadata.html', flag=flag_task1, success_flag='.')
return render_template('task1-metadata.html', flag=flag_task1, error='Ошибка: неверный флаг!')
if flag_task1:
return render_template('task1-metadata.html', flag=flag_task1)
abort(404)
return render_template('task1-metadata.html')
@app.route("/forensic/getimg")
def forensic_task1():
return send_file(f'/tmp/task1/{session['task1_id']}.jpg')
@app.route("/forensic/base-guide")
def fbase():
return render_template('base.html')
@app.route("/forensic/.docx_files")
def fbinwalk():
return render_template('binwalk.html')
@app.route("/forensic/hex")
def fhex():
return render_template('hex.html')
@app.route("/forensic/hash")
def fhash():
return render_template('hash.html')
@app.route("/osint/questions")
def osintquestions():
return render_template('osint-questions.html')
@app.route("/osint/geoguessr")
def osintgeoguessr():
return render_template('osint-geoguessr.html')
@app.route("/osint/really_hard_task")
def osintrht():
return render_template('osint-hardtask.html')
@app.route("/web/success_login-sqltask", methods=('GET', 'POST'))
def success_login():
flag = session.get('sql_flag')
@ -139,9 +89,190 @@ def success_login():
return render_template('success-sql.html', flag=flag)
abort(404)
@app.errorhandler(werkzeug.exceptions.NotFound)
def handle_bad_request(e):
return '<img src="https://http.cat/404.jpg">', 404
idor_main_users = {}
@app.route("/web/idor", methods=('GET', 'POST'))
def webidor():
if request.method == 'POST':
if 'user_flag' in request.form.keys():
flag = session.get('idor_flag')
user_flag = request.form['user_flag']
if user_flag == flag and 'idor_id' in session.keys() and session['idor_id'] in idor_main_users.keys():
del idor_main_users[session['idor_id']]
return render_template('idor.html', flag=flag, success_flag='.')
return render_template('idor.html', flag=flag, error='Ошибка: неверный флаг!')
login = request.form['login']
mail = request.form['mail']
password = request.form['pass']
if not login:
return render_template('idor.html', error='Ошибка: не оставляйте себя без имени!')
if not password:
return render_template('idor.html', error='Ошибка: Пароль важен, заполните поле!')
session['idor_flag'] = f'C4TchFl4g{{{hex(getrandbits(45))[2:]}}}'
session['idor_id'] = id = getrandbits(8) + 16
idor_main_users[id] = {'login': login,'mail': mail}
return redirect(url_for('webidor_user', id=session['idor_id']), code=302)
return render_template('idor.html')
@app.route("/web/idor/user_id<int:id>", methods=('GET', 'POST'))
def webidor_user(id):
if 'idor_id' not in session.keys():
abort(404)
if id <= 15:
idor_users = {0: ('admin', 'superadmin@codrs.ru', 'Самый крутой админ EVER!!! Не согласен - не прав!'), 1: ('LiTeRallY_me', 'l0ser@codrs.ru', 'О, я-я-я!!!'), 2: ('meg4_c4t', 'meowmeow@codrs.ru', 'Мяу-мяу, мяу-мяу... мяу-мяу, мяу-мяу'), 3: ('Pepeg4', 'pepeg@codrs.ru', 'Pepe love you too'), 4: ('ChestWithCat', 'chast@codrs.ru', 'Сундук из майнкрафта. На сундуке кот. Есть рыба, кота приручить?'), 5: ('legacy_user', 'legacy@coders-squad.com', 'А вот прошлый домен был лучше! Продались российским корпорациям!!!!!'), 6: ('m&ms', 'm&ms_lover@codrs.ru', 'Ставлю лайки за покупку m&ms, писать в ТГ'), 7: ('am0ng US', 'US_agent@gmail.com','Russishe Sweine!'), 8: ('anime_girl', 'megumin@codrs.ru', 'アニメ - 世界で一番いいもの'), 9: (session['idor_flag'], 'supercat@codrs.ru', 'О, смотри! Там флаг!!! Ты нашёл:3'), 10: ('b0ss_0f_this-GYM', 'b0ss@codrs.ru', 'И что же ты хотел увидеть в описании у Босса качалки?'),
11: ('CS2_Destroyer', 'player777@codrs.ru', 'Погнали в Напы выскочим, размотаем всех. Не играешь? Я в соло вытащу, а ты посмотришь'), 12: ('VerySweetBread', 'sweetbread@codrs.ru', '生姜猫が大好きです'), 13: ('pupok', 'pup_zemli@codrs.ru', 'Whait.. WHAT?!'), 14: ('secret_KGB_agent', 'b0rn_in_US4@codrs.su', 'Союз нерушимый республик свободных!'), 15: ('nikitata', '1ida_1over@codrs.ru', 'Раст победа?')}
return render_template('idor_user.html', user=idor_users[id])
if id not in idor_main_users.keys():
abort(404)
return render_template('idor-main-user.html', login=idor_main_users[id]['login'], mail=idor_main_users[id]['mail'])
@app.route("/web/path-traversal", methods=('GET', 'POST'))
def webpt():
flag_task3 = 'С4Tch_Fl4g{Y0u_Find_4_littl3_kitty}'
if request.method == 'POST':
user_flag = request.form['user_flag']
if user_flag == flag_task3:
return render_template('path-traversal.html', flag=flag_task3, success_flag='.')
return render_template('path-traversal.html', flag=flag_task3, error='Ошибка: неверный флаг!')
filename = request.args.get("file")
if not filename:
return render_template('path-traversal.html')
try:
return send_file(filename)
except FileNotFoundError:
abort(404)
@app.route("/web/ssti", methods=('GET', 'POST'))
def webssti():
id = session.get('ssti_id')
flag = session.get('flag_ssti')
if id not in comments.keys():
session['ssti_id'] = id = hex(getrandbits(45))[2:]
comments[id] = []
session['flag_ssti'] = flag = f'C4TchFl4g{{{hex(getrandbits(45))[2:]}}}'
if request.method == 'POST':
if 'user_flag' in request.form.keys():
user_flag = request.form['user_flag']
if user_flag == flag:
return render_template('ssti.html', flag=flag, success_flag='.')
return render_template('ssti.html', flag=flag, error='Ошибка: неверный флаг!')
username = request.form['username']
comment = request.form['user_comment']
comments[id].append((username, comment))
def render(x):
try:
return render_template_string(x, flag=flag)
except:
return x
return render_template('ssti.html', render_template_string=render, comments=comments[id], flag=flag)
comments = {}
@app.route("/web/portswigger-guide")
def webpsguide():
return render_template('portswigger-guide.html')
@app.route("/forensic/metadata", methods=('GET', 'POST'))
def fmetadata():
flag_task1 = session.get('flag_task1')
if request.method == 'POST':
user_flag = request.form['user_flag']
if user_flag == flag_task1:
return render_template('task1-metadata.html', flag=flag_task1, success_flag='.')
return render_template('task1-metadata.html', flag=flag_task1, error='Ошибка: неверный флаг!')
if not flag_task1:
session['task1_id'] = id = hex(getrandbits(45))[2:]
session['flag_task1'] = flag_task1 = f'C4TchFl4g{{{hex(getrandbits(45))[2:]}}}'
task1_flag(flag_task1, id)
return render_template('task1-metadata.html', flag=flag_task1)
@app.route("/forensic/getimg")
def forensic_task1():
if 'task1_id' not in session.keys():
abort(404)
return send_file(f'/tmp/task1/{session['task1_id']}.jpg')
@app.route("/forensic/base-guide", methods=('GET', 'POST'))
def fbase():
flag_task4 = session.get('flag_task4')
if request.method == 'POST':
user_flag = request.form['user_flag']
if user_flag == flag_task4:
return render_template('base.html', flag=flag_task4, success_flag='.')
return render_template('base.html', flag=flag_task4, error='Ошибка: неверный флаг!')
if not flag_task4:
session['flag_task4'] = flag_task4 = f'C4TchFl4g{{{hex(getrandbits(45))[2:]}}}'
base32str = str(base64.b32encode(flag_task4.encode()))[2:-1]
base64str = str(base64.b64encode(f"Ой-ой, похоже, что самое главное всё ещё зашифровано.. Сможешь расшифровать, ОП? {base32str}".encode()))[2:-1]
return render_template('base.html', base_task=base64str)
@app.route("/forensic/.docx_files", methods=('GET', 'POST'))
def fbinwalk():
flag_task3 = 'C4TchFl4g{GT4_6_1eaks}'
if request.method == 'POST':
user_flag = request.form['user_flag']
if user_flag == flag_task3:
return render_template('binwalk.html', flag=flag_task3, success_flag='.')
return render_template('binwalk.html', flag=flag_task3, error='Ошибка: неверный флаг!')
return render_template('binwalk.html')
@app.route("/forensic/hex", methods=('GET', 'POST'))
def fhex():
flag_task2 = "C4TchFl4g{I_hir3d_7his_c4r_t0_st4r3_4t_Y0u}"
if request.method == 'POST':
user_flag = request.form['user_flag']
if user_flag == flag_task2:
return render_template('hex.html', flag=flag_task2, success_flag='.')
return render_template('hex.html', flag=flag_task2, error='Ошибка: неверный флаг!')
return render_template('hex.html')
@app.route("/forensic/hash", methods=('GET', 'POST'))
def fhash():
flag_task5 = "C4TchFl4g{superadmin}"
if request.method == 'POST':
user_flag = request.form['user_flag']
if user_flag == flag_task5:
return render_template('hash.html', flag=flag_task5, success_flag='.')
return render_template('hash.html', flag=flag_task5, error='Ошибка: неверный флаг!')
return render_template('hash.html')
@app.route("/osint/mapmaster", methods=('GET', 'POST'))
def osintgeoguessr():
flag_task6 = "C4TchFl4g{1905}"
if request.method == 'POST':
user_flag = request.form['user_flag']
if user_flag == flag_task6:
return render_template('mapmaster.html', flag=flag_task6, success_flag='.')
return render_template('mapmaster.html', flag=flag_task6, error='Ошибка: неверный флаг!')
return render_template('mapmaster.html')
@app.route("/osint/really_hard_task", methods=('GET', 'POST'))
def osintrht():
flag_task7 = "C4Tch_Fl4g{13ts_p14y_min3cr4ft_t0g3th3r}"
if request.method == 'POST':
user_flag = request.form['user_flag']
if user_flag == flag_task7:
return render_template('osint-hardtask.html', flag=flag_task7, success_flag='.')
return render_template('osint-hardtask.html', flag=flag_task7, error='Ошибка: неверный флаг!')
return render_template('osint-hardtask.html')
@app.errorhandler(werkzeug.exceptions.HTTPException)
def error_handler(e):
return f'<img src="https://http.cat/{e.code}.jpg">', e.code
app.run(host="0.0.0.0", debug=False)
connection.close()

View File

@ -2,6 +2,8 @@ import os
def task1_flag(flag_task1, id):
os.system('exiftool -all= static/imgs/task1.jpg')
os.system('mkdir /tmp/task1')
if not os.path.exists('/tmp/task1'):
os.mkdir('/tmp/task1')
os.system(f'cp static/imgs/task1.jpg /tmp/task1/{id}.jpg')
os.system(f"exiftool -Comment='{flag_task1}' /tmp/task1/{id}.jpg")
os.system(f"exiftool -Comment='{flag_task1}' /tmp/task1/{id}.jpg")

BIN
static/imgs/Yandex-task.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 MiB

BIN
static/imgs/cat.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

9
static/imgs/flag.txt Normal file
View File

@ -0,0 +1,9 @@
__ __
| \/ |
| \ / | ___ _____ ________ _ __ ___ ___ _____ __ _ __ ___ ___ _____ ________ _ __ ___ ___ _____ __
| |\/| |/ _ \/ _ \ \ /\ / /______| '_ ` _ \ / _ \/ _ \ \ /\ / / | '_ ` _ \ / _ \/ _ \ \ /\ / /______| '_ ` _ \ / _ \/ _ \ \ /\ / /
| | | | __/ (_) \ V V / | | | | | | __/ (_) \ V V / | | | | | | __/ (_) \ V V / | | | | | | __/ (_) \ V V /
|_| |_|\___|\___/ \_/\_/ |_| |_| |_|\___|\___/ \_/\_( ) |_| |_| |_|\___|\___/ \_/\_/ |_| |_| |_|\___|\___/ \_/\_/
|/
С4Tch_Fl4g{Y0u_Find_4_littl3_kitty}

BIN
static/imgs/hextask.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

View File

@ -168,6 +168,20 @@
align-content: flex-start;
}
.comments {
background-color: rgb(35, 33, 54);
height: 10rem;
width: 95%;
text-align: left;
border-radius: 0.5rem;
overflow-y: auto;
padding: 0.5rem;
}
.comment {
margin: 2rem;
}
.navgoodlinks {
display:flex;
justify-content: start;
@ -297,10 +311,10 @@
.headerblock {
width: clamp(60rem, 65% , 140rem);
height: clamp(10rem, 20%, 10rem);
height: 10rem;
padding: 1rem;
margin-left: 0rem;
border-color: #000000;
margin-left: 0;
border-color: black;
border-radius: 0;
border: none;
box-shadow: 1em 1em 0em 0px rgba(186, 65, 166, 0.7);
@ -311,7 +325,6 @@
flex-direction: column;
background-color: rgb(0 0 0 / 85%);
box-sizing: border-box;
margin-top: 2rem;
}
.headerblock:hover {
@ -519,9 +532,14 @@
body {
background-image: url(/static/imgs/bg.gif);
width: 100vw;
height: 100vh;
height: calc(100dvh - 2rem);
margin: 0;
background-size: cover;
padding-top: 2rem;
}
body > .container {
height: calc(100% - 12rem);
}
a {

10
static/shadow Normal file
View File

@ -0,0 +1,10 @@
user1:$5$$a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3:19429:0:::::
user2:$5$$b3a8e0e1f9ab1bfe3a36f231f676f78bb30a519d2b21e6c530c0eee8ebb4a5d0:19469:0:::::
herobrine:$5$$35a9e381b1a27567549b5f8a6f783c167ebf809f1c4d6a9e367240484d8ce281:19523:0:::::
nobody:*:19429:0:::::
root:$5$$186cf774c97b60a1c106ef718d10970a6a06e06bef89553d9ae65d938a886eae:19111:0:::::
superman:$5$$73cd1b16c4fb83061ad18a0b29b9643a68d4640075a466dc9e51682f84a847f5:19999:0:::::
cat:$5$$77af778b51abd4a3c51c5ddd97204a9c3ae614ebccb75a606c3b6865aed6744e:19765:0:::::
bin:*:19111:0:9999:7:::
sys:*:19111:0:99999:7:::
_kali:$5$$fc5669b52ce4e283ad1d5d182de88ff9faec6672bace84ac2ce4c083f54fe2bc:19111:0:::::

BIN
static/Доклад.docx Normal file

Binary file not shown.

69
templates/base.html Normal file
View File

@ -0,0 +1,69 @@
{% extends 'utils/_task.html' %}
{% block content %}
{% include 'utils/_forensicsidenav.html' %}
<div id="popup" class="sql-guide capsule-window">
<p class="simpletext" style="text-align: left"><a href="https://habr.com/ru/articles/190054/" class="hltext">Кодировки Base64 и Base32</a> - метод представления бинарных данных в виде текста, однако часто используется во всяких загадках, ARG и CTF как "шифр"</p>
<p class="simpletext" style="text-align: left">Как кодировать или декодировать Base64 и Base32? Обычно для этого используют онлайн утилиты, одна из самых удобных - <a href="https://gchq.github.io/CyberChef/" class="hltext">CyberChef</a>. Также полезно знать способ с Python, для этого есть отдельная библиотека:<span class="context" style="font-size: 0.9rem">(пример кода ниже)</span></p>
<pre><code class="codefont python">import base64
data = "[данные]"
#Для Base64:
encoded_data64 = base64.b64encode(data)
decoded_data64 = base64.b64decode(encoded_data64)
#Для Base32:
encoded_data32 = base64.b32encode(data)
decoded_data32 = base64.b32decode(encoded_data32)
</code></pre>
<p class="simpletext" style="text-align: left">Также есть базовые утилиты для командной строки:<span class="context" style="font-size: 0.9rem">(пример команд ниже)</span></p>
<pre><code class="codefont bash">base64 [файл] > [закодированный файл] #Для кодировки файлов
echo -n "Ваш текст" | base64 #Для кодировки текста
base64 -d [Закодированный файл] > [Декодированный документ] #Для декодировки файлов
echo -d "Закодированный текст" | base64 #Для декодировки текста
</code></pre>
<p class="simpletext" style="text-align: left">Как различать Base64 и Base32? Они используют разный набор символов для представления данных:<span class="context" style="font-size: 0.9rem">(пример ниже)</span></p>
<pre><code class="codefont bash">
#Алфавит Base64 (чувствителен к регистру):
ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz
0123456789 + /
#Алфавит Base32 (нечувствителен к регистру):
ABCDEFGHIJKLMNOPQRSTUVWXYZ
234567
</code></pre>
<p class="simpletext" style="text-align: left">Различать их стоит по наличию символов <span class="mono">0, 1, I, L, O</span> - у Base32 их нет. Символ <span class="mono">=</span> используется как заполнитель, для необходимой длины строки, не стоит пытаться распознать по ним кодировку.</p>
<span class="close-btn usable-context" onclick="hidePopup()">скрыть</span>
</div>
<div class="container">
<div class="small capsule-window info1" style="height: auto">
<p class="simpletext">На просторах небезызвестной ветки /b форума Двач я нашёл это.. Оно определённо точно напоминает мне <abbr class="hltext" title="Смотри подсказку(кнопка снизу слева)">какую-то кодировку</abbr>.. или их там сразу две? Поможешь разгадать эту загадку?</p>
<pre><code style="width: 35rem" class="codefont bash">{{ base_task }}</code></pre>
</div>
<div class="flag-input">
<h3 class="header" style="text-align:left">Введите ответ:</h3>
<form action="/forensic/base-guide" method="post" class="simpletext">
<input class="inpt" type="text" name="user_flag" style="width: 100%; height: 1.25rem; margin: 0">
<input type="submit" value="Submit" class="btn1" style="margin-top: 1.25rem">
</form>
</div>
</div>
{% if error %}
<div id="error"> <p>{{ error }}</p> </div>
{% elif success_flag %}
<div class="task-done">
<h1 class="header">Вы прошли задание!</h1>
<img class="done" src="{{ url_for('static', filename='imgs/done_icon.png') }}">
<a href="{{ url_for('forensic') }}" class="usable-context" style="text-align: canter; margin: 1rem; padding: 1rem;"> < Вернуться к заданиям > </a>
</div>
{% endif %}
{% endblock %}

41
templates/binwalk.html Normal file
View File

@ -0,0 +1,41 @@
{% extends 'utils/_task.html' %}
{% block content %}
{% include 'utils/_forensicsidenav.html' %}
<div id="popup" class="sql-guide capsule-window">
<p class="simpletext" style="text-align: left"><a href="https://encyclopedia.kaspersky.ru/glossary/docx/" class="hltext">.docx</a> файлы это примерно одно и то же, что простой .zip архив. Внутри него отдельными файлами хранятся шрифты, содержание, разметка и приложения, в общем - всё, что использовалось в документе.</p>
<p class="simpletext" style="text-align: left">Таким образом, если файл не открывается, то можно попробовать вытащить его содержимое, используя предустановленную в Kali утилиту <a href="https://kali.tools/?p=6771" class="hltext">Binwalk</a>. (Ну или посмотреть на повреждённые сигнатуры.. Но об этом в таске про <a href="{{ url_for('fhex') }}" class="hltext">Hex</a>)</p>
<p class="simpletext" style="text-align: left">Как использовать утилиту binwalk? Для начала стоит просто просмотреть файл на наличие в нём чего-либо:<span class="context" style="font-size: 0.9rem">(пример команды ниже)</span></p>
<pre><code class="codefont bash">binwalk [файл]</code></pre>
<p class="simpletext" style="text-align: left">Если в выданных данных вы замечаете что-то, что не пустое, то можно попробовать извлечь всё содежимое, добавив соответсвующий флаг в команду:</p>
<pre><code class="codefont bash">binwalk -e [файл]</code></pre>
<p class="simpletext" style="text-align: left"> Конкретно в этом таске в извлечённых данных будут картинки, а на одной из них - флаг-ответ.</p>
<span class="close-btn usable-context" onclick="hidePopup()">скрыть</span>
</div>
<div class="container">
<div class="small capsule-window info1" style="height: auto">
<p class="simpletext">Блин, мой очень-очень важный доклад <abbr class="hltext" title="Смотри подсказку(кнопка снизу слева)">(Доклад.docx)</abbr> повредился или что-то типо того... Поможешь мне найти флаг в том, что осталось от моей работы?</p>
<a href="{{ url_for('static', filename='Доклад.docx') }}" class="simpletext header" style="font-size: 1.6rem">Доклад.docx</a>
</div>
<div class="flag-input">
<h3 class="header" style="text-align:left">Введите ответ:</h3>
<form action="/forensic/.docx_files" method="post" class="simpletext">
<input class="inpt" type="text" name="user_flag" style="width: 100%; height: 1.25rem; margin: 0">
<input type="submit" value="Submit" class="btn1" style="margin-top: 1.25rem">
</form>
</div>
</div>
{% if error %}
<div id="error"> <p>{{ error }}</p> </div>
{% elif success_flag %}
<div class="task-done">
<h1 class="header">Вы прошли задание!</h1>
<img class="done" src="{{ url_for('static', filename='imgs/done_icon.png') }}">
<a href="{{ url_for('forensic') }}" class="usable-context" style="text-align: canter; margin: 1rem; padding: 1rem;"> < Вернуться к заданиям > </a>
</div>
{% endif %}
{% endblock %}

42
templates/found-me.html Normal file
View File

@ -0,0 +1,42 @@
{% extends 'utils/_task.html' %}
{% block content %}
{% include 'utils/_forensicsidenav.html' %}
<!--Тебе сюда!!!!-->
<div id="popup" class="sql-guide capsule-window">
<p class="simpletext" style="text-align: left">Попробуй вставить ссылку на эту страницу в поисковик и провести поиск, а не просто перейти по ней. Твоя задача перейти на <a class="hltext" href="https://g.codrs.ru/Chest/CTF-site-project">Gitea</a> или <a class="hltext" href="https://github.com/cheeest/CTF-site-project">GitHub</a> проекта</p>
<p class="simpletext" style="text-align: left">Также если в браузере открыть код элементов, то можно заметить комментарии с подсказками, намекающими на GitHub и Gitea</p>
<p class="simpletext" style="text-align: left">Перейдя в файл <a class="hltext" href="https://g.codrs.ru/Chest/CTF-site-project/src/branch/master/app.pyt">app.py</a> в нём можно найти следующие строки:<span class="context" style="font-size: 0.9rem">(пример ниже)</span></p>
<pre><code class="codefont python">@app.route("/osint/found_me", methods=('GET', 'POST'))
def osintfound():
Y0u_Fin4ly_F0und_7his = '[флаг]'</code></pre>
<p class="simpletext" style="text-align: left">Собственно на строке 30 и есть флаг</p>
<span class="close-btn usable-context" onclick="hidePopup()">скрыть</span>
</div>
<div class="container">
<div class="small capsule-window info1" style="height: auto;">
<p class="simpletext">Просто найди флаг.. Так уж и быть: я разрешаю тебе использовать <abbr class="hltext" title="Смотри подсказку(кнопка снизу слева)">Google</abbr></p>
</div>
<div class="flag-input">
<h3 class="header" style="text-align:left">Введите ответ:</h3>
<form action="/osint/found_me" method="post" class="simpletext">
<input class="inpt" type="text" name="user_flag" style="width: 100%; height: 1.25rem; margin: 0">
<input type="submit" value="Submit" class="btn1" style="margin-top: 1.25rem">
</form>
</div>
</div>
<!--Спустись еще чуть ниже -->
{% if error %}
<div id="error"> <p>{{ error }}</p> </div>
{% elif success_flag %}
<div class="task-done">
<h1 class="header">Вы прошли задание!</h1>
<img class="done" src="{{ url_for('static', filename='imgs/done_icon.png') }}">
<a href="{{ url_for('osint') }}" class="usable-context" style="text-align: canter; margin: 1rem; padding: 1rem;"> < Вернуться к заданиям > </a>
</div>
{% endif %}
{% endblock %}
<!--Дада, ты почти нашёл флаг.. Раз уж ты тут, может возьмёшь его напрямую из кода? Только не смотри на другие флаги там! Так будет нечестно!-->

52
templates/hash.html Normal file
View File

@ -0,0 +1,52 @@
{% extends 'utils/_task.html' %}
{% block content %}
{% include 'utils/_forensicsidenav.html' %}
<div id="popup" class="sql-guide capsule-window">
<p class="simpletext" style="text-align: left"><a class="hltext" href="https://manpages.ubuntu.com/manpages/trusty/ru/man5/shadow.5.html">Файл Shadow</a> - это системный файл в Linux, который хранит хэшированные пароли пользователей.</p>
<p class="simpletext" style="text-align: left">Shadow содержит в себе информацию в следующем виде:</p>
<pre><code class="codefont bash">username:password_hash:last_change:min:max:warn:inactive:expire:reserved
1 username - имя пользователя
2 password_hash - Хеш пароля :$алгоритм шифрования$соль$хеш:
3 last_change - Последнее изменение (в днях с 1970)
4 min - Минимум дней между сменами пароля
5 max - Максимум дней, через которые пароль надо сменить
6 warn - За сколько дней до истечения пароля предупредить
7 inactive - Сколько дней после истечения пароль остаётся активен
8 expire - День, когда аккаунт полностью истекает (в днях с 1970)
9 reserved - Зарезервировано для будущего использования
</code></pre>
<p class="simpletext" style="text-align: left">Открыв файл Shadow нужно найти хеш пароля суперпользователя - root. Строчка будет выглядеть так:</p>
<pre><code class="codefont bash">root:$5$$186cf774c97b60a1c106ef718d10970a6a06e06bef89553d9ae65d938a886eae:19111:0:::::</code></pre>
<p class="simpletext" style="text-align: left">Видно, что алгоритм хеширования - <span class="mono">$5$</span> - sha-256, а соли вовсе нет. Можно попробовать подобрать пароль к хешу.</p>
<p class="simpletext" style="text-align: left">Для подбора пароля можно использовать онлайн утилиты, по типу <a class="hltext" href="https://crackstation.net/">Crack Station</a> или утилитой по-типу <a class="hltext" href="https://hashcat.net/hashcat/">hashcat</a>- именно она базово предустановленна в Kali:<span class="context" style="font-size: 0.9rem">(пример команды ниже)</span></p>
<pre><code class="codefont bash">hashcat -m 1470 [файл с хешом или сам хеш строкой] [словарь (в Kali базовый Rockyou)]</code></pre>
<p class="simpletext" style="text-align: left">Опция -m отвечат за тип хеша, в данном случае <span class="mono">1470 - sha-256</span></p>
<span class="close-btn usable-context" onclick="hidePopup()">скрыть</span>
</div>
<div class="container">
<div class="small capsule-window info1" style="height: auto">
<p class="simpletext">На своей рабочей машине я смог достать этот <abbr class="hltext" title="Смотри подсказку(кнопка снизу слева)">файл</abbr>.. Я где-то слышал, что в нём есть то, что поможет мне стать админом - пароль или что-то вроде.. но Вместо пароля там написан какой-то бред!<span class="context" style="font-size: 0.9rem">(в ответ напиши C4Tch_Fl4g{сюда вставь пароль админа})</span></p>
<a href="{{ url_for('static', filename='shadow') }}" class="simpletext header" style="font-size: 1.6rem">Shadow</a>
</div>
<div class="flag-input">
<h3 class="header" style="text-align:left">Введите ответ:</h3>
<form action="/forensic/hash" method="post" class="simpletext">
<input class="inpt" type="text" name="user_flag" style="width: 100%; height: 1.25rem; margin: 0">
<input type="submit" value="Submit" class="btn1" style="margin-top: 1.25rem">
</form>
</div>
</div>
{% if error %}
<div id="error"> <p>{{ error }}</p> </div>
{% elif success_flag %}
<div class="task-done">
<h1 class="header">Вы прошли задание!</h1>
<img class="done" src="{{ url_for('static', filename='imgs/done_icon.png') }}">
<a href="{{ url_for('forensic') }}" class="usable-context" style="text-align: canter; margin: 1rem; padding: 1rem;"> < Вернуться к заданиям > </a>
</div>
{% endif %}
{% endblock %}

46
templates/hex.html Normal file
View File

@ -0,0 +1,46 @@
{% extends 'utils/_task.html' %}
{% block content %}
{% include 'utils/_forensicsidenav.html' %}
<div id="popup" class="sql-guide capsule-window">
<p class="simpletext" style="text-align: left">Любой файл можно представить в виде <a href="https://course.ugractf.ru/stegano/files.html" class="hltext">Hex-данных</a>.</p>
<p class="simpletext" style="text-align: left">Для записи байтов в hex формате используется 16-ричный вид (по 2 цифры), т.е от 0 до F. В Hex'е файла можно наблюдать: важные сигнатуры, указывающие на тип файла и просто байты информации.</p>
<p class="simpletext" style="text-align: left">Эти данные можно редактировать в Hex-редакторах, например, <a href="https://course.ugractf.ru/stegano/files.html" class="hltext">xxd</a>. Открыть файл и посмотреть его Hex с помощью xxd можно так:<span class="context" style="font-size: 0.9rem">(пример команды ниже)</span></p>
<pre><code class="codefont bash">xxd [файл]</code></pre>
<p class="simpletext" style="text-align: left">Не обязательно вносить какие-либо изменения, можно просто внимательно посмотреть их представление в формате ASCII <span class="context" style="font-size: 0.9rem">(Обычно слева - данные в бинарном виде, посередине - столбик с 16-ричными данными (Hex), а справа их представление в понятном нам языке, в виде символов ASCII).</span></p>
<pre><code class="codefont bash">
│00000000│ 50 4b 03 04 14 00 06 00 ┊ 08 00 00 00 21 00 32 91 │PK•••⋄•⋄┊•⋄⋄⋄!⋄2×
│00000010│ 6f 57 66 01 00 00 a5 05 ┊ 00 00 13 00 08 02 5b 43 │oWf•⋄⋄ו┊⋄⋄•⋄••[C│
│00000020│ 6f 6e 74 65 6e 74 5f 54 ┊ 79 70 65 73 5d 2e 78 6d │ontent_T┊ypes].xm│
│00000030│ 6c 20 a2 04 02 28 a0 00 ┊ 02 00 00 00 00 00 00 00 │l ו•(×⋄┊•⋄⋄⋄⋄⋄⋄⋄│</code></pre>
<p class="simpletext" style="text-align: left">Вышеприведённый пример - начало любого .docx файла и в самом начале у него идут 2 байта отвечающие за его структуру <a href="{{ url_for('fbinwalk') }}" class="hltext" title="Задание на эту тему">архива</a> - PK или же 50 4b. Если их повредить, т.е изменить в редакторе 50 4b -> 00 00, то файл просто перестанет открываться.</p>
<p class="simpletext" style="text-align: left">Однако в случае нашего задания нужно просто посмотреть на строки без пустых или бесполезных байтов. С этим может помочь утилита <a href="https://ioflood.com/blog/strings-linux-command/" class="hltext">strings</a>:<span class="context" style="font-size: 0.9rem">(пример команды ниже)</span></p>
<pre><code class="codefont bash">strings [файл]</code></pre>
<p class="simpletext" style="text-align: left">Именно она и выведет нам флаг быстрее всех.</p>
<span class="close-btn usable-context" onclick="hidePopup()">скрыть</span>
</div>
<div class="container">
<div class="small capsule-window info1" style="height: auto">
<p class="simpletext">Друг скинул мне картинку и ведёт себя как-то странно.. Постоянно говорит какими-то загадками( Помоги мне посмотреть, что не так с изображением. Может что-то есть <abbr class="hltext" title="Смотри подсказку(кнопка снизу слева)">внутри</abbr>?</p>
<img style="heigth: auto; width: 23rem" src="{{ url_for('static', filename='imgs/hextask.jpg') }}">
</div>
<div class="flag-input">
<h3 class="header" style="text-align:left">Введите ответ:</h3>
<form action="/forensic/hex" method="post" class="simpletext">
<input class="inpt" type="text" name="user_flag" style="width: 100%; height: 1.25rem; margin: 0">
<input type="submit" value="Submit" class="btn1" style="margin-top: 1.25rem">
</form>
</div>
</div>
{% if error %}
<div id="error"> <p>{{ error }}</p> </div>
{% elif success_flag %}
<div class="task-done">
<h1 class="header">Вы прошли задание!</h1>
<img class="done" src="{{ url_for('static', filename='imgs/done_icon.png') }}">
<a href="{{ url_for('forensic') }}" class="usable-context" style="text-align: canter; margin: 1rem; padding: 1rem;"> < Вернуться к заданиям > </a>
</div>
{% endif %}
{% endblock %}

View File

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="ru">
{% include 'utils/_head.html' %}
<body>
{% include 'utils/_header.html' %}
<div class="container" style="max-width:70%; justify-content: space-between;min-width: 40rem; flex-wrap: nowrap">
<div class="profile">
<h2 class="header" style="text-align:left">Ваш Профиль:</h2>
<p class="simpletext" style="text-align:left">Логин: <span class="context">{{ login }}</span></p>
<p class="simpletext" style="text-align:left">Почта: <span class="context">{{ mail }}</span></p>
<p class="simpletext" style="text-align:left">О Вас: <br />
<span class="mono">Здесь пока совсем ничего нет</span></p>
</div>
</div>
{% include 'utils/_websidenav.html' %}
<div id="success"> <p>Вход произведён успешно!</p> </div>
</body>
</html>

48
templates/idor.html Normal file
View File

@ -0,0 +1,48 @@
{% extends 'utils/_task.html' %}
{% block content %}
{% include 'utils/_websidenav.html' %}
<div id="popup" class="sql-guide capsule-window">
<p class="simpletext" style="text-align: left"><a class="hltext" href="https://portswigger.net/web-security/access-control/idor">IDOR(Insecure direct object references)</a> - уязвимость, позволяющая пользователю получить доступ к объекту (к которому он доступ иметь не должен) напрямую, без проверок, например по ID</p>
<p class="simpletext" style="text-align: left">Как именно это работает? На сервере просто отсутствуют проверки, которые не дают пользователю реализовать доступ к определённым объектам. На сервере это может выглядеть так: <span class="context">(пример кода ниже)</span></p>
<pre><code class="codefont python">@app.route("/web/idor/user_id&lt;int:id>")
def user(id):
return render_template(f'user_id{id}.html')</code></pre>
<p class="simpletext" style="text-align: left">Грубо говоря, мы можем ввести ID в путь и получить приватную страницу пользователя<span class="context">(конкретно тут она не выглядит сильно приватной, но всё же)</span>, ID которого ввели</p>
<p class="simpletext" style="text-align: left">Для решения этого задания стоит посмотреть на путь, и заметить, что там есть id : <span class = mono>ctf.codrs.ru/web/idor/user_id184</span>. Можно попробовать поменять ID и обнаружить, что нас переносит на странички других пользователей.<span class="context">ID, на которых есть странички - Ваш ID и числа от 0 до 15</span></p>
<p class="simpletext" style="text-align: left">Походив по профилям пользователей можно увидеть, что у одного из них <span class="context">(ID 9)</span> Имя пользователя - флаг.</p>
<p class="simpletext" style="text-align: left">Далее стоит вернуться на главную, используя стрелочку назад в самом браузере, и ввести флаг в соответствующее поле. Будьте внимательны! После каждого нажатия кнопки <span class="mono">Войти</span> флаг перегенерируется.</p>
<span class="close-btn usable-context" onclick="hidePopup()">скрыть</span>
</div>
<div class="container">
<div class="small capsule-window info1" style="height: auto;">
<form action="/web/idor" method="post" class="simpletext">
<p class="simpletext">Блин, я потерял страничку пользователя с почтой <abbr class="hltext" title="Смотри подсказку(кнопка снизу слева)">supercat@codrs.ru</abbr>. Можешь поискать? Для начала войди на сайт.</p>
<div class="small-container" style="justify-content: center;" ><p>Логин: <p class="hidden">.</p> </p> <input type="text" name="login" class="inpt" /></div>
<div class="small-container" style="justify-content: center;"><p>Почта: <p class="hidden">.</p> </p> <input type="text" name="mail" class="inpt" /></div>
<div class="small-container" style="justify-content: center;"><p>Пароль:</p> <input type="password" name="pass" class="inpt"/></div>
<input type="submit" value="Войти" class="btn1">
</form>
</div>
<div class="flag-input">
<h3 class="header" style="text-align:left">Введите ответ:</h3>
<form action="/web/idor" method="post" class="simpletext">
<input class="inpt" type="text" name="user_flag" style="width: 100%; height: 1.25rem; margin: 0">
<input type="submit" value="Submit" class="btn1" style="margin-top: 1.25rem">
</form>
</div>
</div>
{% if error %}
<div id="error"> <p>{{ error }}</p> </div>
{% elif success_flag %}
<div class="task-done">
<h1 class="header">Вы прошли задание!</h1>
<img class="done" src="{{ url_for('static', filename='imgs/done_icon.png') }}">
<a href="{{ url_for('web') }}" class="usable-context" style="text-align: canter; margin: 1rem; padding: 1rem;"> < Вернуться к заданиям > </a>
</div>
{% endif %}
{% endblock %}

20
templates/idor_user.html Normal file
View File

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="ru">
{% include 'utils/_head.html' %}
<body>
{% include 'utils/_header.html' %}
<div class="container" style="max-width:70%; justify-content: space-between;min-width: 40rem; flex-wrap: nowrap">
<div class="profile">
<h2 class="header" style="text-align:left">Ваш Профиль:</h2>
<p class="simpletext" style="text-align:left">Логин: <span class="context">{{ user[0] }}</span></p>
<p class="simpletext" style="text-align:left">Почта: <span class="context">{{ user[1] }}</span></p>
<p class="simpletext" style="text-align:left">Описание: <br />
<span class="mono">{{ user[2] }}</span></p>
</div>
</div>
{% include 'utils/_websidenav.html' %}
<div id="success"> <p>Вход произведён успешно!</p> </div>
</body>
</html>

View File

@ -34,6 +34,10 @@
CTF Новости России -
<a target="_blank" rel="noopener noreferrer" class="btn2" href="https://ctfnews.ru/">CTF News</a>
</p>
<p>
CTF от СПБ -
<a target="_blank" rel="noopener noreferrer" class="btn2" href="https://forkbomb.ru/">forkbomb.ru</a>
</p>
</nav>
</div>
@ -50,9 +54,9 @@
большинство используемых утилит базово есть в
<a target="_blank" rel="noopener noreferrer" href="https://www.kali.org/get-kali/#kali-platforms" class="hltext">Kali</a>.
Если вы используете Windows, то можно работать с
<a target="_blank" rel="noopener noreferrer" href="https://www.virtualbox.org/wiki/Downloads" class="hltext">Виртуальной Машины</a>
<a target="_blank" rel="noopener noreferrer" href="https://www.virtualbox.org/wiki/Downloads" class="hltext">Виртуальной Машины</a > или использовать онлайн-утилиты</a>
</p>
<p> Good luck, have fun =) </p>
<p> Good luck, have fun :3 </p>
</div>
</div>
<div id="popup" class="meme capsule-window">

43
templates/mapmaster.html Normal file
View File

@ -0,0 +1,43 @@
{% extends 'utils/_task.html' %}
{% block content %}
{% include 'utils/_forensicsidenav.html' %}
<div id="popup" class="sql-guide capsule-window">
<p class="simpletext" style="text-align: left">У этого таска есть 2 явных решения:</p>
<p class="simpletext" style="text-align: left">1. Использовать знания, полученные в ходе решения задания <a class="hltext" href="{{ url_for('fmetadata') }}">Метаданные и как их найти</a>. Открыв метаданные данного фото и пролистав в самый низ можно увидеть координаты: <span class="context">(пример строк ниже)</span></p>
<pre><code class="codefont html">GPS Latitude : 60 deg 0' 43.30" N
GPS Longitude : 30 deg 22' 43.70" E
GPS Position : 60 deg 0' 43.30" N, 30 deg 22' 43.70" E </code></pre>
<p class="simpletext" style="text-align: left"> У нас есть координаты в градусах, секундах и минутах. Можем перевести их в десятичный формат и получаем координаты:</p>
<pre><code class="codefont html">60.012028, 30.378806</code></pre>
<p class="simpletext" style="text-align: left">Введя координаты в любые карты они покажут место в Санкт-Петербурге, расположенное на северо-востоке от станции метро <a class="hltext" href="https://yandex.ru/maps/-/CHbim08A">"Политехническая"</a>, рядом есть <a class="hltext" href="https://yandex.ru/maps/-/CHbiMWiB">Политехнический парк</a>, где располагается Политехнический университет Петра Великого. Именно ему принадлежит <a class="hltext" href="https://yandex.ru/maps/-/CHbiIL4q">Гидробашня</a>, о которой идёт речь в задании. Погуглив год её постройки, получаем ответ: 1905.</p>
<p class="simpletext" style="text-align: left">2. Провести поиск по картинке и узнать, что территория с жёлтыми зданиями это <a class="hltext" href="https://yandex.ru/maps/-/CHbiIGOr">Военная академия связи</a>. Можно зайти на панорамы карт и определить точное место съёмки и даже увидеть верхушку нужной нам башни. Узнав, что это <a class="hltext" href="https://yandex.ru/maps/-/CHbiIL4q">Гидробашня</a> Политехнического университета Петра великого можно узнать год её постройки - всё тот же 1905</p>
<span class="close-btn usable-context" onclick="hidePopup()">скрыть</span>
</div>
<div class="container">
<div class="small capsule-window info1" style="height: auto;">
<p class="simpletext" style="text-align: left">Зацените вид из окна! Весь город как на ладони, круть! Только я не знаю, можно ли делать фотки <abbr class="hltext" title="Смотри подсказку(кнопка снизу слева)">территории с жёлтыми домами</abbr> - там люди в форме и различные антенны..?
Вообще я хочу попросить помощи. Недалеко от места съёмки, в парке, есть небольшая башня, она очень красивая, я часто прохожу мимо неё, однако ничего о ней не знаю. Можешь написать, в каком году она была основана? <span class="context">(В ответ запиши C4TchFl4g{год основания башни})</span></p>
<img style="heigth: auto; width: 20rem" src="{{ url_for('static', filename='imgs/Yandex-task.jpg') }}">
</div>
<div class="flag-input">
<h3 class="header" style="text-align:left">Введите ответ:</h3>
<form action="/osint/mapmaster" method="post" class="simpletext">
<input class="inpt" type="text" name="user_flag" style="width: 100%; height: 1.25rem; margin: 0">
<input type="submit" value="Submit" class="btn1" style="margin-top: 1.25rem">
</form>
</div>
</div>
{% if error %}
<div id="error"> <p>{{ error }}</p> </div>
{% elif success_flag %}
<div class="task-done">
<h1 class="header">Вы прошли задание!</h1>
<img class="done" src="{{ url_for('static', filename='imgs/done_icon.png') }}">
<a href="{{ url_for('osint') }}" class="usable-context" style="text-align: canter; margin: 1rem; padding: 1rem;"> < Вернуться к заданиям > </a>
</div>
{% endif %}
{% endblock %}

View File

@ -0,0 +1,38 @@
{% extends 'utils/_task.html' %}
{% block content %}
{% include 'utils/_osintsidenav.html' %}
<div id="popup" class="sql-guide capsule-window">
<p class="simpletext" style="text-align: left">Это задание чем-то хоже схоже с ARG. Стоит просто следовать подсказкам и быть внимательным, переходя от этапа к этапу.</p>
<p class="simpletext" style="text-align: left">В самом задании есть намёк на <a class="hltext" href="https://github.com/cheeest/CTF-site-project">GitHub</a> или <a class="hltext" href="https://g.codrs.ru/Chest/CTF-site-project">Gitea</a> проекта. Перейдя туда можно найти файл <a class="hltext" href="https://g.codrs.ru/Chest/CTF-site-project/src/branch/master/weird_file.txt">weird_file.txt</a>, где будет текст с битой кодировкой. Вернув кодировку а её исходный вид можно прочитать текст, где ещё в base64 зашифрована важная информация:</p>
<pre><code class="codefont python">Домен майнкрафт сервера (версия 1.7.4 - 1.21.4) - ctf.codrs.ru
При входе вписать команду - /server mega_minecraft_ctf</code></pre>
<p class="simpletext" style="text-align: left">Зайдя на сервер нужно пройти мини-регистрацию и вписать вышеуказанную команду. У спавна можно увидеть табличку с обычным квадратным уравнением, ответами на которое будут координаты <span class="mono">x-42 и z-69</span>. Рядом стоит взять лодку, наступив на нажимную пластину, и поплыть к координатам. Ровно на месте будет телепорт наверх, откуда можно будет наблюдать флаг</p>
<span class="close-btn usable-context" onclick="hidePopup()">скрыть</span>
</div>
<div class="container">
<div class="small capsule-window info1" style="height: auto">
<p class="simpletext">Ты наверное уже видел Gitea или GitHub проекта.. Не находил там ничего странного? По-моему, при разработке там остался один <abbr class="hltext" title="Смотри подсказку(кнопка снизу слева)">подозрительный файл</abbr>, сможешь посмотреть его?</p>
</div>
<div class="flag-input">
<h3 class="header" style="text-align:left">Введите ответ:</h3>
<form action="/osint/really_hard_task" method="post" class="simpletext">
<input class="inpt" type="text" name="user_flag" style="width: 100%; height: 1.25rem; margin: 0">
<input type="submit" value="Submit" class="btn1" style="margin-top: 1.25rem">
</form>
</div>
</div>
{% if error %}
<div id="error"> <p>{{ error }}</p> </div>
{% elif success_flag %}
<div class="task-done">
<h1 class="header">Вы прошли задание!</h1>
<img class="done" src="{{ url_for('static', filename='imgs/done_icon.png') }}">
<a href="{{ url_for('osint') }}" class="usable-context" style="text-align: canter; margin: 1rem; padding: 1rem;"> < Вернуться к заданиям > </a>
</div>
{% endif %}
{% endblock %}

View File

@ -8,7 +8,7 @@
<p class="simpletext">< Задания категории OSINT ></p>
<nav class="navbtn">
{%- for name, descr in (
('osintquestions', "Чур ответы не гуглить!"),
('osintfound', "Чур ответы не гуглить!"),
('osintgeoguessr', "Профессионал Яндекс-карт"),
('osintrht', "Реально сложный таск"),
) %}

View File

@ -1,6 +0,0 @@
{% extends 'utils/_task.html' %}
{% include 'utils/_osintsidenav.html' %}
{% block content %}
{% endblock %}

View File

@ -0,0 +1,44 @@
{% extends 'utils/_task.html' %}
{% block content %}
{% include 'utils/_websidenav.html' %}
<div id="popup" class="sql-guide capsule-window">
<p class="simpletext" style="text-align: left"><a class="hltext" href="https://portswigger.net/web-security/file-path-traversal">Path Traversal</a> - уязвимость, позволяющая пользователю получить доступ к файлам на хосте при помощи уязвимого параметра URL.</p>
<p class="simpletext" style="text-align: left">Как это работает? Для просмотра или скачивания файла на сайте есть условная кнопка, при нажатии на неё, в путь прибавляется параметр, аргумент которого - путь к файлу:<span class="context">(пример тега ниже)</span></p>
<pre><code class="codefont html"> &lt;button class="big_btn" onclick="location.href='/cats/download_cat?file=static/imgs/cat.jpg'"></code></pre>
<p class="simpletext" style="text-align: left">Да, это просто самый обычный путь, который без проверок принимается сервером, на что в ответ, пользователь получает запрошенный файл:<span class="context">(пример кода ниже)</span></p>
<pre><code class="codefont python"> filename = request.args.get("file")
return send_file(filename)</code></pre>
<p class="simpletext" style="text-align: left">Получается можно вписать туда что-то своё? Именно! В задании от нас хотят флаг, который лежит в <span class="mono">.txt</span> файле. Получается мы можем изменить параметр заменой <span class="mono">cat.jpg -> flag.txt</span></p>
<p class="simpletext" style="text-align: left">Есть и более жестокая эксплуатация сей уязвимости: можно откатиться на директории назад, дойти до корня и взять важный системный файл. Как это сделать? <span class="mono">../</span> вернёт нас на директорию назад. Так можем попробовать снова изменить путь: <span class="mono">cat.jpg -> ../../app.py</span>, что вернёт нам соответствующий <a calss="hltext" hraf="https://g.codrs.ru/Chest/CTF-site-project/src/branch/master/app.py">python файл</a></p>
<span class="close-btn usable-context" onclick="hidePopup()">скрыть</span>
</div>
<div class="container">
<div class="small capsule-window info1" style="height: auto;">
<p class="simpletext"><abbr class="hltext" title="Смотри подсказку(кнопка снизу слева)">Посмотри</abbr> файл и помоги решить задачку, но будь внимателен, стоит проверять, что происходит при нажатии на подозрительные кнопки. Флаг в соотвествующем .txt файле</p>
<button class="btn1" onclick="location.href='/web/path-traversal?file=static/imgs/cat.jpg'">
К изображению
</button>
</div>
<div class="flag-input">
<h3 class="header" style="text-align:left">Введите ответ:</h3>
<form action="/web/path-traversal" method="post" class="simpletext">
<input class="inpt" type="text" name="user_flag" style="width: 100%; height: 1.25rem; margin: 0">
<input type="submit" value="Submit" class="btn1" style="margin-top: 1.25rem">
</form>
</div>
</div>
{% if error %}
<div id="error"> <p>{{ error }}</p> </div>
{% elif success_flag %}
<div class="task-done">
<h1 class="header">Вы прошли задание!</h1>
<img class="done" src="{{ url_for('static', filename='imgs/done_icon.png') }}">
<a href="{{ url_for('web') }}" class="usable-context" style="text-align: canter; margin: 1rem; padding: 1rem;"> < Вернуться к заданиям > </a>
</div>
{% endif %}
{% endblock %}

View File

@ -1,6 +1,8 @@
{% extends 'utils/_task.html' %}
{% include 'utils/_websidenav.html' %}
{% block content %}
{% include 'utils/_websidenav.html' %}
<div id="popup" class="sql-guide capsule-window">
<p class="simpletext" style="text-align: left"><a class="hltext" href="https://book.hacktricks.wiki/en/pentesting-web/sql-injection/index.html?highlight=sql%20inje#what-is-sql-injection">SQL-инъекция</a> - уязвимость системы, позволяющая пользователю ввести вредоносный код в SQL-запрос.<br />
<p class="simpletext" style="text-align: left">Как именно это работает? Все дело в том, что данные, которые ввёл пользователь, вставляются в запрос напрямую <span class="context" style="font-size: 0.9rem">(пример кода с сервера ниже)</span></p>

69
templates/ssti.html Normal file
View File

@ -0,0 +1,69 @@
{% extends 'utils/_task.html' %}
{% block content %}
{% include 'utils/_forensicsidenav.html' %}
<div id="popup" class="sql-guide capsule-window">
<p class="simpletext" style="text-align: left"><a href="https://portswigger.net/web-security/server-side-template-injection" class="hltext">SSTI (Server-side template injection)</a> - уязвимость, позволяющая внедрить код в шаблон, выполнив его на стороне сервера.</p>
<p class="simpletext" style="text-align: left">Как это работает? Если пользователь ввёдет где-либо на сайте не просто текст, а команду, вставляемую в шаблонизатор, то сервер может выполнить её и вернуть пользователю результат, если не стоит должных защит. Примерно так это выглядит на сервере:<span class="context" style="font-size: 0.9rem">(пример кода ниже)</span></p>
<pre><code class="codefont python">if request.method == 'POST':
comment = request.form['user_comment']
# В HTML комментарий вставляется через вызов переменной: {% raw %} &lt;p&gt; {{ comment }} &lt;/p&gt; {% endraw %}</code></pre>
<p class="simpletext" style="text-align: left">Можно заметить, что {% raw %} {{ }} {% endraw %} передают переменную. Т.е пользователь может просто написать команду такого же вида в поле ввода и она будет выполнена. </p>
<p class="simpletext" style="text-align: left">В нашем случае можем ввести в комментарии:</p>
<pre><code class="codefont python">{% raw %} {{ flag }} {% endraw %}</code></pre>
<p class="simpletext" style="text-align: left">На доске же вместо нашего "комментария" отобразится введённая переменная, т.е флаг</p>
<p class="simpletext" style="text-align: left">Однако можно в {% raw %} {{ }} {% endraw %} вписать любую команду и она будет выполнена с одним "но": Современные шаблонизаторы неохотно обрабатывают в принципе всё, что в них суют и даже здесь уязвимость создана искусственно</p>
<span class="close-btn usable-context" onclick="hidePopup()">скрыть</span>
</div>
<div class="container">
<div class="small capsule-window info1" style="height: auto;">
<p class="simpletext">Приветствую тебя, о сетевой путник! <br />
Прошу, оставь упоминание о себе здесь! Тут допускается всё: ничего страшного если твой комментарий будет <abbr class="hltext" title="Смотри подсказку(кнопка снизу слева)">немного странным</abbr></p>
<form action="/web/ssti" method="post" class="simpletext">
<div class="small-container" style="justify-content: space-between;"><p>Никнейм:</p> <input type="text" name="username" class="inpt" /></div>
<div class="small-container" style="justify-content: space-between;"><p>Комментарий:</p> <input type="text" name="user_comment" class="inpt"/></div>
<input type="submit" value="Отправить" class="btn1" style="margin-top: 1.25rem">
</form>
<div class="comments">
<div class="comment">
{% for (username, comment) in comments -%}
<p class="header" style="text-align: left">{{ username }}</p>
<p class="mono">{{ render_template_string(comment) }}</p>
{% endfor -%}
</div>
<div class="comment">
<p class="header" style="text-align: left">Sup3r_C4t</p>
<p class="mono">Мяу-мяу Мяу-мяу</p>
</div>
<div class="comment">
<p class="header" style="text-align: left">Herobrine</p>
<p class="mono">▓▒░(°◡°)░▒▓</p>
</div>
<div class="comment">
<p class="header" style="text-align: left">0MegaCTF++</p>
<p class="mono">Выходи сюда, глупый Админ! Отдавай флаг!!!!(╮°-°)╮┳━━┳ ( ╯°□°)╯ ┻━━┻</p>
</div>
</div>
</div>
<div class="flag-input">
<h3 class="header" style="text-align:left">Введите ответ:</h3>
<form action="/web/ssti" method="post" class="simpletext">
<input class="inpt" type="text" name="user_flag" style="width: 100%; height: 1.25rem; margin: 0">
<input type="submit" value="Submit" class="btn1" style="margin-top: 1.25rem">
</form>
</div>
</div>
{% if error %}
<div id="error"> <p>{{ error }}</p> </div>
{% elif success_flag %}
<div class="task-done">
<h1 class="header">Вы прошли задание!</h1>
<img class="done" src="{{ url_for('static', filename='imgs/done_icon.png') }}">
<a href="{{ url_for('web') }}" class="usable-context" style="text-align: canter; margin: 1rem; padding: 1rem;"> < Вернуться к заданиям > </a>
</div>
{% endif %}
{% endblock %}

View File

@ -26,7 +26,7 @@
<div class="task-done">
<h1 class="header">Вы прошли задание!</h1>
<img class="done" src="{{ url_for('static', filename='imgs/done_icon.png') }}">
<a href="{{ url_for('index') }}" class="usable-context" style="text-align: canter; margin: 1rem; padding: 1rem;"> < НА ГЛАВНУЮ > </a>
<a href="{{ url_for('web') }}" class="usable-context" style="text-align: canter; margin: 1rem; padding: 1rem;"> < Вернуться к заданиям > </a>
</div>
{% else %}
<div id="success"> <p>Вход произведён успешно!</p> </div>

View File

@ -1,22 +1,44 @@
{% extends 'utils/_task.html' %}
{% include 'utils/_forensicsidenav.html' %}
{% block content %}
{% include 'utils/_forensicsidenav.html' %}
<div id="popup" class="sql-guide capsule-window">
<p class="simpletext" style="text-align: left"><a href="https://book.hacktricks.wiki/en/generic-methodologies-and-resources/basic-forensic-methodology/partitions-file-systems-carving/index.html?highlight=metadata#metadata" class="hltext">Метаданные (Metadata)</a> - данные несущие информацию о других данных, например о каком-либо файле<br />
<p class="simpletext" style="text-align: left"> Что там может быть? Примерно всё, что угодно, но обычно там пишется техническая информация о файле или методе, которым он был получен: дата последнего изменения, разрешение или размер, у фотографий можно найти модель камер и тд. Также метаданные можно перезаписывать или добавлять туда новые свойства. Для этого есть много утилит, однако в Kali базово предустановлена <a href="https://kali.tools/?p=5984" class="hltext">Exiftool</a>.<br />
<p class="simpletext" style="text-align: left"> Посмотреть метаданные картинки, используя exiftool, можно следующим образом:<span class="context" style="font-size: 0.9rem">(пример команды ниже)</span></p>
<pre><code class="codefont bash">exiftool [файл]</code></pre>
<p class="simpletext" style="text-align: left">В консоли появятся метаданные, где, в нашем случае, будет спрятан флаг</p>
<p class="simpletext" style="text-align: left">Если хочется внести что-то твоё в метаданные файла или перезаписать их, то можно использовать следующую команду:
<pre><code class="codefont bash">exiftool -[Название тега, который будет изменён]='что-нибудь, что хочется оставить в метаданных' [файл]</code></pre><br />
<span class="context" style="font-size: 0.9rem">(пример)</span>
<pre><code class="codefont bash">exiftool -Comment='Я люблю котиков' cat_img.png</code></pre>
<p class="simpletext" style="text-align: left">Если же возможности использовать Exiftool нет, то можно использовать онлайн версии или другие утилиты</p>
<span class="close-btn usable-context" onclick="hidePopup()">скрыть</span>
</div>
<div class="container">
<div class="capsule-window info1">
<p class="simpletext">Перед тобой картинка. Проверь её метаданные, вдруг там что-то есть</p>
<img src="{{ url_for('forensic_task1') }}">
<div class="small capsule-window info1" style="height: auto">
<p class="simpletext">Перед тобой очень забавная картинка. Попробуй проверить её <abbr class="hltext" title="Смотри подсказку(кнопка снизу слева)">метаданные</abbr>, вдруг там что-то есть</p>
<img style="heigth: auto; width: 30rem" src="{{ url_for('forensic_task1') }}">
</div>
<div class="flag-input ">
<div class="flag-input">
<h3 class="header" style="text-align:left">Введите ответ:</h3>
<form action="success_login" method="post" class="simpletext">
<form action="/forensic/metadata" method="post" class="simpletext">
<input class="inpt" type="text" name="user_flag" style="width: 100%; height: 1.25rem; margin: 0">
<input type="submit" value="Submit" class="btn1" style="margin-top: 1.25rem">
</form>
</div>
<div id="popup" class="sql-guide capsule-window">
<p class="simpletext"style="text-align: left"><a class="hltext" href="https://book.hacktricks.wiki/en/pentesting-web/sql-injection/index.html?highlight=sql%20inje#what-is-sql-injection">SQL-инъекция</a> - уязвимость системы, позволяющая пользователю ввести вредоносный код в SQL-запрос.<br />
<span class="close-btn usable-context" onclick="hidePopup()">скрыть</span>
</div>
</div>
{% if error %}
<div id="error"> <p>{{ error }}</p> </div>
{% elif success_flag %}
<div class="task-done">
<h1 class="header">Вы прошли задание!</h1>
<img class="done" src="{{ url_for('static', filename='imgs/done_icon.png') }}">
<a href="{{ url_for('forensic') }}" class="usable-context" style="text-align: canter; margin: 1rem; padding: 1rem;"> < Вернуться к заданиям > </a>
</div>
{% endif %}
{% endblock %}

View File

@ -2,6 +2,7 @@
<link rel="stylesheet" href="{{ url_for('static', filename='index.css') }}">
<script src="{{ url_for('static', filename='scripts/animation.js') }}"></script>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
{%- if request.path != url_for('index') %}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/base16/ros-pine-moon.min.css">

View File

@ -3,7 +3,7 @@
<nav class="navlink">
<a href="{{ url_for('index') }}" class="link">На главную</a>
{%- for link, text in (
('osintquestions', "Чур ответы не гуглить!"),
('osintfound', "Чур ответы не гуглить!"),
('osintgeoguessr', "Мастер яндекс-карт"),
('osintrht', "Реально сложный таск"),
) %}

View File

@ -7,7 +7,6 @@
('webidor', "Уязвимость IDOR"),
('webpt', "Уязвимость Path Traversal"),
('webssti', "Уязвимость SSTI"),
('webpsguide', "Немного о PortSwigger"),
) %}
{%- if request.path != url_for(link) %}
<a href="{{ url_for(link) }}" class="link">{{ text }}</a>

View File

@ -12,7 +12,6 @@
('webidor', "Уязвимость IDOR"),
('webpt', "Уязвимость Path Traversal"),
('webssti', "Уязвимость SSTI"),
('webpsguide', "Немного о PortSwigger"),
) %}
<a href="{{ url_for(name) }}" class="btn1">{{ descr }}</a>
{%- endfor %}

6
weird_file.txt Normal file
View File

@ -0,0 +1,6 @@
Ты на верном пути, флаг будет скоро (надейся)
Может пока отвлечёшься и сыграешь в майн?
На версиях 1.7.4 - 1.21.4 есть один прикольный сервер,
где можно поиграть. Задёшь? Домен - Y29kcnMucnU=.
После проверки и входа в лобби найди нужный сервер при помощи команды в чате:
L3NlcnZlciBtZWdhX21pbmVjcmFmdF9jdGY=