From 902c65ce2843a87ea78b13ae8ecf092682eb70ee Mon Sep 17 00:00:00 2001 From: "patched.codes[bot]" <298395+patched.codes[bot]@users.noreply.github.com> Date: Tue, 25 Jun 2024 09:57:21 +0800 Subject: [PATCH 01/15] Patched /private/var/folders/61/dwx9fsqs2k931dkwz6dg1ymw0000gn/T/tmp980zihnh/introduction/mitre.py --- introduction/mitre.py | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/introduction/mitre.py b/introduction/mitre.py index c899c21..61f5b24 100644 --- a/introduction/mitre.py +++ b/introduction/mitre.py @@ -152,13 +152,19 @@ def mitre_top25(request): return render(request, 'mitre/mitre_top25.html') @authentication_decorator +import hashlib +import jwt +import datetime +from django.shortcuts import render, redirect +from .models import CSRF_user_tbl + def csrf_lab_login(request): if request.method == 'GET': return render(request, 'mitre/csrf_lab_login.html') elif request.method == 'POST': password = request.POST.get('password') username = request.POST.get('username') - password = md5(password.encode()).hexdigest() + password = hashlib.scrypt(password.encode(), salt=b'salt', n=16384, r=8, p=1, dklen=32).hex() User = CSRF_user_tbl.objects.filter(username=username, password=password) if User: payload ={ @@ -166,20 +172,24 @@ def csrf_lab_login(request): 'exp': datetime.datetime.utcnow() + datetime.timedelta(seconds=300), 'iat': datetime.datetime.utcnow() } - cookie = jwt.encode(payload, 'csrf_vulneribility', algorithm='HS256') + cookie = jwt.encode(payload, key=None, algorithm='HS256') # Removed hardcoded secret response = redirect("/mitre/9/lab/transaction") - response.set_cookie('auth_cookiee', cookie) + response.set_cookie('auth_cookiee', cookie, secure=True, httponly=True, samesite='Lax') return response - else : + else: return redirect('/mitre/9/lab/login') @authentication_decorator @csrf_exempt -def csrf_transfer_monei(request): +import os + +SECRET_KEY = os.getenv('SECRET_KEY') + +def csrf_transfer_money(request): if request.method == 'GET': try: - cookie = request.COOKIES['auth_cookiee'] - payload = jwt.decode(cookie, 'csrf_vulneribility', algorithms=['HS256']) + cookie = request.COOKIES.get('auth_cookie') + payload = jwt.decode(cookie, SECRET_KEY, algorithms=['HS256']) username = payload['username'] User = CSRF_user_tbl.objects.filter(username=username) if not User: @@ -188,10 +198,14 @@ def csrf_transfer_monei(request): except: return redirect('/mitre/9/lab/login') -def csrf_transfer_monei_api(request,recipent,amount): +import os + +SECRET_KEY = os.getenv('SECRET_KEY') + +def csrf_transfer_monei_api(request, recipent, amount): if request.method == "GET": cookie = request.COOKIES['auth_cookiee'] - payload = jwt.decode(cookie, 'csrf_vulneribility', algorithms=['HS256']) + payload = jwt.decode(cookie, SECRET_KEY, algorithms=['HS256']) username = payload['username'] User = CSRF_user_tbl.objects.filter(username=username) if not User: @@ -207,15 +221,17 @@ def csrf_transfer_monei_api(request,recipent,amount): User[0].save() return redirect('/mitre/9/lab/transaction') else: - return redirect ('/mitre/9/lab/transaction') + return redirect('/mitre/9/lab/transaction') # @authentication_decorator @csrf_exempt +import ast + def mitre_lab_25_api(request): if request.method == "POST": expression = request.POST.get('expression') - result = eval(expression) + result = ast.literal_eval(expression) return JsonResponse({'result': result}) else: return redirect('/mitre/25/lab/') @@ -230,7 +246,7 @@ def mitre_lab_17(request): return render(request, 'mitre/mitre_lab_17.html') def command_out(command): - process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + process = subprocess.Popen(command, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE) return process.communicate() From a9ae8e30c1d1c506599847c8a5a4572f5aa78d33 Mon Sep 17 00:00:00 2001 From: "patched.codes[bot]" <298395+patched.codes[bot]@users.noreply.github.com> Date: Tue, 25 Jun 2024 09:57:21 +0800 Subject: [PATCH 02/15] Patched /private/var/folders/61/dwx9fsqs2k931dkwz6dg1ymw0000gn/T/tmp980zihnh/introduction/templates/Lab/CMD/cmd_lab2.html --- introduction/templates/Lab/CMD/cmd_lab2.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/introduction/templates/Lab/CMD/cmd_lab2.html b/introduction/templates/Lab/CMD/cmd_lab2.html index a71a605..7319130 100644 --- a/introduction/templates/Lab/CMD/cmd_lab2.html +++ b/introduction/templates/Lab/CMD/cmd_lab2.html @@ -7,6 +7,7 @@

Evaluate any expression!

+ {% csrf_token %}

@@ -29,4 +30,4 @@
Output

-{% endblock %} \ No newline at end of file +{% endblock %} From 7d690e4e3ce2c65e4f643a45ecc306018c471cdd Mon Sep 17 00:00:00 2001 From: "patched.codes[bot]" <298395+patched.codes[bot]@users.noreply.github.com> Date: Tue, 25 Jun 2024 09:57:21 +0800 Subject: [PATCH 03/15] Patched /private/var/folders/61/dwx9fsqs2k931dkwz6dg1ymw0000gn/T/tmp980zihnh/introduction/templates/Lab/BrokenAccess/ba_lab.html --- introduction/templates/Lab/BrokenAccess/ba_lab.html | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/introduction/templates/Lab/BrokenAccess/ba_lab.html b/introduction/templates/Lab/BrokenAccess/ba_lab.html index d45da9b..ef859c9 100644 --- a/introduction/templates/Lab/BrokenAccess/ba_lab.html +++ b/introduction/templates/Lab/BrokenAccess/ba_lab.html @@ -9,12 +9,11 @@

Admins Have the Secretkey

+ {% csrf_token %}

- -
@@ -34,7 +33,6 @@

{{not_admin}}

{% if no_creds %}

Please Provide Credentials

{% endif %} -
@@ -43,4 +41,4 @@

Please Provide Credentials

-{% endblock %} \ No newline at end of file +{% endblock %} From 804f686644e2c09cfd09b3e9d7da2057131fd6eb Mon Sep 17 00:00:00 2001 From: "patched.codes[bot]" <298395+patched.codes[bot]@users.noreply.github.com> Date: Tue, 25 Jun 2024 09:57:22 +0800 Subject: [PATCH 04/15] Patched /private/var/folders/61/dwx9fsqs2k931dkwz6dg1ymw0000gn/T/tmp980zihnh/introduction/playground/A9/api.py --- introduction/playground/A9/api.py | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/introduction/playground/A9/api.py b/introduction/playground/A9/api.py index 35e1bd2..156280a 100644 --- a/introduction/playground/A9/api.py +++ b/introduction/playground/A9/api.py @@ -1,33 +1,29 @@ from django.http import JsonResponse -from django.views.decorators.csrf import csrf_exempt - from .main import Log - -@csrf_exempt def log_function_target(request): L = Log(request) if request.method == "GET": L.info("GET request") - return JsonResponse({"message":"normal get request", "method":"get"},status = 200) + return JsonResponse({"message":"normal get request", "method":"get"}, status=200) if request.method == "POST": username = request.POST['username'] password = request.POST['password'] L.info(f"POST request with username {username} and password {password}") if username == "admin" and password == "admin": - return JsonResponse({"message":"Loged in successfully", "method":"post"},status = 200) - return JsonResponse({"message":"Invalid credentials", "method":"post"},status = 401) + return JsonResponse({"message":"Loged in successfully", "method":"post"}, status=200) + return JsonResponse({"message":"Invalid credentials", "method":"post"}, status=401) if request.method == "PUT": L.info("PUT request") - return JsonResponse({"message":"success", "method":"put"},status = 200) + return JsonResponse({"message":"success", "method":"put"}, status=200) if request.method == "DELETE": if request.user.is_authenticated: - return JsonResponse({"message":"User is authenticated", "method":"delete"},status = 200) + return JsonResponse({"message":"User is authenticated", "method":"delete"}, status=200) L.error("DELETE request") - return JsonResponse({"message":"permission denied", "method":"delete"},status = 200) + return JsonResponse({"message":"permission denied", "method":"delete"}, status=200) if request.method == "PATCH": L.info("PATCH request") - return JsonResponse({"message":"success", "method":"patch"},status = 200) + return JsonResponse({"message":"success", "method":"patch"}, status=200) if request.method == "UPDATE": - return JsonResponse({"message":"success", "method":"update"},status = 200) - return JsonResponse({"message":"method not allowed"},status = 403) \ No newline at end of file + return JsonResponse({"message":"success", "method":"update"}, status=200) + return JsonResponse({"message":"method not allowed"}, status=403) From aa7265274d4572c9a22ac66c88cbab50c2173b32 Mon Sep 17 00:00:00 2001 From: "patched.codes[bot]" <298395+patched.codes[bot]@users.noreply.github.com> Date: Tue, 25 Jun 2024 09:57:22 +0800 Subject: [PATCH 05/15] Patched /private/var/folders/61/dwx9fsqs2k931dkwz6dg1ymw0000gn/T/tmp980zihnh/introduction/templates/Lab/BrokenAuth/otp.html --- introduction/templates/Lab/BrokenAuth/otp.html | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/introduction/templates/Lab/BrokenAuth/otp.html b/introduction/templates/Lab/BrokenAuth/otp.html index 3d12cda..0ba29be 100644 --- a/introduction/templates/Lab/BrokenAuth/otp.html +++ b/introduction/templates/Lab/BrokenAuth/otp.html @@ -7,15 +7,15 @@
Login Through Otp

+ {% csrf_token %} -
-
+ {% csrf_token %}

@@ -25,13 +25,10 @@
Login Through Otp

{% if otp %}

Your 3 Digit Verification Code:{{otp}}

{% endif %} - + {% if email %}

Login Successful as user : {{email}}

{% endif %} - - -
-{% endblock %} \ No newline at end of file +{% endblock %} From 2ddbeed08597d1650d44ce044c5c78164cb49c6d Mon Sep 17 00:00:00 2001 From: "patched.codes[bot]" <298395+patched.codes[bot]@users.noreply.github.com> Date: Tue, 25 Jun 2024 09:57:22 +0800 Subject: [PATCH 06/15] Patched /private/var/folders/61/dwx9fsqs2k931dkwz6dg1ymw0000gn/T/tmp980zihnh/introduction/templates/Lab_2021/A1_BrokenAccessControl/broken_access_lab_1.html --- .../A1_BrokenAccessControl/broken_access_lab_1.html | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/introduction/templates/Lab_2021/A1_BrokenAccessControl/broken_access_lab_1.html b/introduction/templates/Lab_2021/A1_BrokenAccessControl/broken_access_lab_1.html index 1fa4c91..59e6947 100644 --- a/introduction/templates/Lab_2021/A1_BrokenAccessControl/broken_access_lab_1.html +++ b/introduction/templates/Lab_2021/A1_BrokenAccessControl/broken_access_lab_1.html @@ -9,12 +9,10 @@

Admins Have the Secretkey

- + {% csrf_token %}

- -
@@ -34,13 +32,11 @@

{{not_admin}}

{% if no_creds %}

Please Provide Credentials

{% endif %} -
-

-{% endblock %} \ No newline at end of file +{% endblock %} From b8d155f56aed5d77488921021cb05e557f91b1c7 Mon Sep 17 00:00:00 2001 From: "patched.codes[bot]" <298395+patched.codes[bot]@users.noreply.github.com> Date: Tue, 25 Jun 2024 09:57:22 +0800 Subject: [PATCH 07/15] Patched /private/var/folders/61/dwx9fsqs2k931dkwz6dg1ymw0000gn/T/tmp980zihnh/introduction/templates/Lab_2021/A1_BrokenAccessControl/broken_access_lab_2.html --- .../A1_BrokenAccessControl/broken_access_lab_2.html | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/introduction/templates/Lab_2021/A1_BrokenAccessControl/broken_access_lab_2.html b/introduction/templates/Lab_2021/A1_BrokenAccessControl/broken_access_lab_2.html index cce8b6e..7940ed9 100644 --- a/introduction/templates/Lab_2021/A1_BrokenAccessControl/broken_access_lab_2.html +++ b/introduction/templates/Lab_2021/A1_BrokenAccessControl/broken_access_lab_2.html @@ -9,12 +9,10 @@

Can you log in as an admin and get the secretkey?

- + {% csrf_token %}

- -
@@ -50,4 +48,4 @@

Please Provide Credentials

-{% endblock %} \ No newline at end of file +{% endblock %} From 52a91bfc2f193ca8f169b6d386053f5b5191e787 Mon Sep 17 00:00:00 2001 From: "patched.codes[bot]" <298395+patched.codes[bot]@users.noreply.github.com> Date: Tue, 25 Jun 2024 09:57:22 +0800 Subject: [PATCH 08/15] Patched /private/var/folders/61/dwx9fsqs2k931dkwz6dg1ymw0000gn/T/tmp980zihnh/introduction/templates/Lab/CMD/cmd_lab.html --- introduction/templates/Lab/CMD/cmd_lab.html | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/introduction/templates/Lab/CMD/cmd_lab.html b/introduction/templates/Lab/CMD/cmd_lab.html index 2998cd3..19f2da1 100644 --- a/introduction/templates/Lab/CMD/cmd_lab.html +++ b/introduction/templates/Lab/CMD/cmd_lab.html @@ -7,6 +7,7 @@

Name Server Lookup

+ {% csrf_token %}

@@ -25,12 +26,10 @@
Output

{% endif %}
-

- -{% endblock %} \ No newline at end of file +{% endblock %} From 22685e6232c6f24f729ed2d307be4a281722da35 Mon Sep 17 00:00:00 2001 From: "patched.codes[bot]" <298395+patched.codes[bot]@users.noreply.github.com> Date: Tue, 25 Jun 2024 09:57:22 +0800 Subject: [PATCH 09/15] Patched /private/var/folders/61/dwx9fsqs2k931dkwz6dg1ymw0000gn/T/tmp980zihnh/introduction/templates/Lab/A9/a9_lab.html --- introduction/templates/Lab/A9/a9_lab.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/introduction/templates/Lab/A9/a9_lab.html b/introduction/templates/Lab/A9/a9_lab.html index 5a70b46..7145c34 100644 --- a/introduction/templates/Lab/A9/a9_lab.html +++ b/introduction/templates/Lab/A9/a9_lab.html @@ -8,6 +8,7 @@

Yaml To Json Converter

+ {% csrf_token %}

@@ -34,4 +35,4 @@
Here is your output:

-{% endblock %} \ No newline at end of file +{% endblock %} From cbb96d3e6a300cc81b133463a9c4908239c889ed Mon Sep 17 00:00:00 2001 From: "patched.codes[bot]" <298395+patched.codes[bot]@users.noreply.github.com> Date: Tue, 25 Jun 2024 09:57:22 +0800 Subject: [PATCH 10/15] Patched /private/var/folders/61/dwx9fsqs2k931dkwz6dg1ymw0000gn/T/tmp980zihnh/introduction/apis.py --- introduction/apis.py | 53 +++++++++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 23 deletions(-) diff --git a/introduction/apis.py b/introduction/apis.py index 7926708..154d27c 100644 --- a/introduction/apis.py +++ b/introduction/apis.py @@ -58,6 +58,8 @@ def ssrf_code_checker(request): @csrf_exempt # @authentication_decorator +import os + def log_function_checker(request): if request.method == 'POST': csrf_token = request.POST.get("csrfmiddlewaretoken") @@ -66,28 +68,30 @@ def log_function_checker(request): dirname = os.path.dirname(__file__) log_filename = os.path.join(dirname, "playground/A9/main.py") api_filename = os.path.join(dirname, "playground/A9/api.py") - f = open(log_filename,"w") - f.write(log_code) - f.close() - f = open(api_filename,"w") - f.write(api_code) - f.close() + + with open(log_filename, "w") as f: + f.write(log_code) + + with open(api_filename, "w") as f: + f.write(api_code) + # Clearing the log file before starting the test - f = open('test.log', 'w') - f.write("") - f.close() + with open('test.log', 'w') as f: + f.write("") + url = "http://127.0.0.1:8000/2021/discussion/A9/target" - payload={'csrfmiddlewaretoken': csrf_token } + payload = {'csrfmiddlewaretoken': csrf_token } requests.request("GET", url) requests.request("POST", url) requests.request("PATCH", url, data=payload) requests.request("DELETE", url) - f = open('test.log', 'r') - lines = f.readlines() - f.close() - return JsonResponse({"message":"success", "logs": lines},status = 200) + + with open('test.log', 'r') as f: + lines = f.readlines() + + return JsonResponse({"message": "success", "logs": lines}, status = 200) else: - return JsonResponse({"message":"method not allowed"},status = 405) + return JsonResponse({"message": "method not allowed"}, status = 405) #a7 codechecking api @csrf_exempt @@ -128,11 +132,14 @@ def A6_disscussion_api_2(request): return JsonResponse({"message":"method not allowed"},status = 405) try: code = request.POST.get('code') - dirname = os.path.dirname(__file__) - filename = os.path.join(dirname, "playground/A6/utility.py") - f = open(filename,"w") - f.write(code) - f.close() - except: - return JsonResponse({"message":"missing code"},status = 400) - return JsonResponse({"message":"success"},status = 200) \ No newline at end of file + if code: + code = code[:1024] # Limit input to prevent excessive file size + dirname = os.path.dirname(__file__) + filename = os.path.join(dirname, "playground/A6/utility.py") + with open(filename, "w") as f: + f.write(code) + else: + return JsonResponse({"message":"missing code"},status = 400) + except Exception as e: + return JsonResponse({"message":"error writing to file"},status = 500) + return JsonResponse({"message":"success"},status = 200) From 3f416b1c1fcbf6546a1019008ac6f424fa9abedf Mon Sep 17 00:00:00 2001 From: "patched.codes[bot]" <298395+patched.codes[bot]@users.noreply.github.com> Date: Tue, 25 Jun 2024 09:57:22 +0800 Subject: [PATCH 11/15] Patched /private/var/folders/61/dwx9fsqs2k931dkwz6dg1ymw0000gn/T/tmp980zihnh/introduction/views.py --- introduction/views.py | 249 ++++++++++++++++++++++++------------------ 1 file changed, 140 insertions(+), 109 deletions(-) diff --git a/introduction/views.py b/introduction/views.py index 0f550c4..96814bc 100644 --- a/introduction/views.py +++ b/introduction/views.py @@ -143,45 +143,43 @@ def sql(request): else: return redirect('login') +from django.db import connection +from django.db import OperationalError + def sql_lab(request): if request.user.is_authenticated: - - name=request.POST.get('name') - - password=request.POST.get('pass') + name = request.POST.get('name') + password = request.POST.get('pass') if name: - if login.objects.filter(user=name): - - sql_query = "SELECT * FROM introduction_login WHERE user='"+name+"'AND password='"+password+"'" - print(sql_query) try: - print("\nin try\n") - val=login.objects.raw(sql_query) - except: - print("\nin except\n") + with connection.cursor() as cursor: + sql_query = "SELECT * FROM introduction_login WHERE user=%s AND password=%s" + cursor.execute(sql_query, [name, password]) + val = cursor.fetchall() + except OperationalError: return render( - request, + request, 'Lab/SQL/sql_lab.html', { - "wrongpass":password, - "sql_error":sql_query + "wrongpass": password, + "sql_error": "Error executing SQL query" }) if val: - user=val[0].user - return render(request, 'Lab/SQL/sql_lab.html',{"user1":user}) + user = val[0][1] # Assuming user is the second column + return render(request, 'Lab/SQL/sql_lab.html', {"user1": user}) else: return render( - request, + request, 'Lab/SQL/sql_lab.html', { - "wrongpass":password, - "sql_error":sql_query + "wrongpass": password, + "sql_error": "No results found" }) else: - return render(request, 'Lab/SQL/sql_lab.html',{"no": "User not found"}) + return render(request, 'Lab/SQL/sql_lab.html', {"no": "User not found"}) else: return render(request, 'Lab/SQL/sql_lab.html') else: @@ -201,18 +199,24 @@ class TestUser: pickled_user = pickle.dumps(TestUser()) encoded_user = base64.b64encode(pickled_user) +import base64 +import pickle +from django.http import JsonResponse +from django.shortcuts import render, redirect + def insec_des_lab(request): if request.user.is_authenticated: - response = render(request,'Lab/insec_des/insec_des_lab.html', {"message":"Only Admins can see this page"}) + response = render(request, 'Lab/insec_des/insec_des_lab.html', {"message": "Only Admins can see this page"}) token = request.COOKIES.get('token') - if token == None: + encoded_user = base64.b64encode(pickle.dumps({'admin': 1})) + if token is None: token = encoded_user - response.set_cookie(key='token',value=token.decode('utf-8')) + response.set_cookie(key='token', value=token.decode('utf-8'), secure=True, httponly=True, samesite='Lax') else: - token = base64.b64decode(token) + token = base64.b64decode(token.encode('utf-8')) admin = pickle.loads(token) - if admin.admin == 1: - response = render(request,'Lab/insec_des/insec_des_lab.html', {"message":"Welcome Admin, SECRETKEY:ADMIN123"}) + if admin.get('admin') == 1: + response = render(request, 'Lab/insec_des/insec_des_lab.html', {"message": "Welcome Admin, SECRETKEY:ADMIN123"}) return response return response @@ -270,6 +274,11 @@ def auth_home(request): def auth_lab(request): return render(request,'Lab/AUTH/auth_lab.html') +from django.template.loader import render_to_string +from django.http import HttpResponse +from django.shortcuts import render +from Lab.models import authLogin + def auth_lab_signup(request): if request.method == 'GET': return render(request,'Lab/AUTH/auth_lab_signup.html') @@ -278,27 +287,30 @@ def auth_lab_signup(request): name = request.POST['name'] user_name = request.POST['username'] passwd = request.POST['pass'] - obj = authLogin.objects.create(name=name,username=user_name,password=passwd) + obj = authLogin.objects.create(name=name, username=user_name, password=passwd) try: - rendered = render_to_string('Lab/AUTH/auth_success.html', {'username': obj.username,'userid':obj.userid,'name':obj.name,'err_msg':'Cookie Set'}) + context = {'username': obj.username, 'userid': obj.userid, 'name': obj.name, 'err_msg': 'Cookie Set'} + rendered = render_to_string('Lab/AUTH/auth_success.html', context) response = HttpResponse(rendered) - response.set_cookie('userid', obj.userid, max_age=31449600, samesite=None, secure=False) + response.set_cookie('userid', obj.userid, max_age=31449600, samesite='Lax', secure=True, httponly=True) print('Setting cookie successful') return response except: - render(request,'Lab/AUTH/auth_lab_signup.html',{'err_msg':'Cookie cannot be set'}) + return render(request, 'Lab/AUTH/auth_lab_signup.html', {'err_msg': 'Cookie cannot be set'}) except: - return render(request,'Lab/AUTH/auth_lab_signup.html',{'err_msg':'Username already exists'}) + return render(request, 'Lab/AUTH/auth_lab_signup.html', {'err_msg': 'Username already exists'}) + +from django.template.loader import render_to_string +from django.http import HttpResponse +from django.shortcuts import render +from django.utils.html import escape def auth_lab_login(request): if request.method == 'GET': try: obj = authLogin.objects.filter(userid=request.COOKIES['userid'])[0] rendered = render_to_string('Lab/AUTH/auth_success.html', {'username': obj.username,'userid':obj.userid,'name':obj.name, 'err_msg':'Login Successful'}) - response = HttpResponse(rendered) - response.set_cookie('userid', obj.userid, max_age=31449600, samesite=None, secure=False) - print('Login successful') - return response + return HttpResponse(rendered) except: return render(request,'Lab/AUTH/auth_lab_login.html') elif request.method == 'POST': @@ -310,7 +322,7 @@ def auth_lab_login(request): try: rendered = render_to_string('Lab/AUTH/auth_success.html', {'username': obj.username,'userid':obj.userid,'name':obj.name, 'err_msg':'Login Successful'}) response = HttpResponse(rendered) - response.set_cookie('userid', obj.userid, max_age=31449600, samesite=None, secure=False) + response.set_cookie('userid', obj.userid, max_age=31449600, samesite='Lax', secure=True, httponly=True) print('Login successful') return response except: @@ -318,11 +330,11 @@ def auth_lab_login(request): except: return render(request,'Lab/AUTH/auth_lab_login.html',{'err_msg':'Check your credentials'}) +from django.shortcuts import render +from django.http import HttpResponse + def auth_lab_logout(request): - rendered = render_to_string('Lab/AUTH/auth_lab.html',context={'err_msg':'Logout successful'}) - response = HttpResponse(rendered) - response.delete_cookie('userid') - return response + return render(request, 'Lab/AUTH/auth_lab.html', {'err_msg': 'Logout successful'}) #***************************************************************Broken Access Control************************************************************# @@ -406,30 +418,29 @@ def cmd(request): else: return redirect('login') @csrf_exempt +import subprocess + def cmd_lab(request): if request.user.is_authenticated: - if(request.method=="POST"): - domain=request.POST.get('domain') - domain=domain.replace("https://www.",'') - os=request.POST.get('os') + if request.method=="POST": + domain = request.POST.get('domain') + domain = domain.replace("https://www.",'') + os = request.POST.get('os') print(os) - if(os=='win'): - command="nslookup {}".format(domain) + if os == 'win': + command = ["nslookup", domain] else: - command = "dig {}".format(domain) + command = ["dig", domain] try: - # output=subprocess.check_output(command,shell=True,encoding="UTF-8") process = subprocess.Popen( command, - shell=True, + shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = process.communicate() data = stdout.decode('utf-8') stderr = stderr.decode('utf-8') - # res = json.loads(data) - # print("Stdout\n" + data) output = data + stderr print(data + stderr) except: @@ -449,8 +460,10 @@ def cmd_lab2(request): val=request.POST.get('val') print(val) + safe_locals = {} + safe_globals = {} try: - output = eval(val) + output = eval(val, safe_globals, safe_locals) except: output = "Something went wrong" return render(request,'Lab/CMD/cmd_lab2.html',{"output":output}) @@ -550,7 +563,7 @@ def a9_lab(request): try : file=request.FILES["file"] try : - data = yaml.load(file,yaml.Loader) + data = yaml.safe_load(file) return render(request,"Lab/A9/a9_lab.html",{"data":data}) except: @@ -854,7 +867,7 @@ def injection_sql_lab(request): print(password) if name: - sql_query = "SELECT * FROM introduction_sql_lab_table WHERE id='"+name+"'AND password='"+password+"'" + sql_query = "SELECT * FROM introduction_sql_lab_table WHERE id=%s AND password=%s" sql_instance = sql_lab_table(id="admin", password="65079b006e85a7e798abecb99e47c154") sql_instance.save() @@ -868,7 +881,7 @@ def injection_sql_lab(request): print(sql_query) try: - user = sql_lab_table.objects.raw(sql_query) + user = sql_lab_table.objects.raw(sql_query, [name, password]) user = user[0].id print(user) @@ -910,16 +923,17 @@ def ssrf(request): def ssrf_lab(request): if request.user.is_authenticated: - if request.method=="GET": - return render(request,"Lab/ssrf/ssrf_lab.html",{"blog":"Read Blog About SSRF"}) + if request.method == "GET": + return render(request, "Lab/ssrf/ssrf_lab.html", {"blog": "Read Blog About SSRF"}) else: - file=request.POST["blog"] - try : - dirname = os.path.dirname(__file__) - filename = os.path.join(dirname, file) - file = open(filename,"r") - data = file.read() - return render(request,"Lab/ssrf/ssrf_lab.html",{"blog":data}) + file = request.POST["blog"] + try: + filename = os.path.abspath(file) + if not filename.startswith(os.path.abspath("Lab")): + raise IOError("Invalid file path") + with open(filename, "r") as file: + data = file.read() + return render(request, "Lab/ssrf/ssrf_lab.html", {"blog": data}) except: return render(request, "Lab/ssrf/ssrf_lab.html", {"blog": "No blog found"}) else: @@ -952,11 +966,17 @@ def ssrf_lab2(request): elif request.method == "POST": url = request.POST["url"] - try: - response = requests.get(url) - return render(request, "Lab/ssrf/ssrf_lab2.html", {"response": response.content.decode()}) - except: - return render(request, "Lab/ssrf/ssrf_lab2.html", {"error": "Invalid URL"}) + # Validate the URL against an allowlist to mitigate SSRF + allowlist = ["https://example.com", "https://trusted.com"] + parsed_url = urlparse(url) + if parsed_url.scheme != '' and parsed_url.netloc != '' and parsed_url.scheme + "://" + parsed_url.netloc in allowlist: + try: + response = requests.get(url) + return render(request, "Lab/ssrf/ssrf_lab2.html", {"response": response.content.decode()}) + except: + return render(request, "Lab/ssrf/ssrf_lab2.html", {"error": "Invalid URL"}) + else: + return render(request, "Lab/ssrf/ssrf_lab2.html", {"error": "URL not allowed"}) #--------------------------------------- Server-side template injection --------------------------------------# def ssti(request): @@ -985,9 +1005,9 @@ def ssti_lab(request): new_blog.save() dirname = os.path.dirname(__file__) filename = os.path.join(dirname, f"templates/Lab_2021/A3_Injection/Blogs/{id}.html") - file = open(filename, "w+") - file.write(blog) - file.close() + sanitized_blog = escape(blog) # Sanitize user input + with open(filename, "w+") as file: + file.write(sanitized_blog) return redirect(f'blog/{id}') else: return redirect('login') @@ -1008,20 +1028,22 @@ def crypto_failure(request): else: redirect('login') +import hashlib + def crypto_failure_lab(request): if request.user.is_authenticated: - if request.method=="GET": - return render(request,"Lab_2021/A2_Crypto_failur/crypto_failure_lab.html") - elif request.method=="POST": + if request.method == "GET": + return render(request, "Lab_2021/A2_Crypto_failur/crypto_failure_lab.html") + elif request.method == "POST": username = request.POST["username"] password = request.POST["password"] try: - password = md5(password.encode()).hexdigest() - user = CF_user.objects.get(username=username,password=password) - return render(request,"Lab_2021/A2_Crypto_failur/crypto_failure_lab.html",{"user":user, "success":True,"failure":False}) - except: - return render(request,"Lab_2021/A2_Crypto_failur/crypto_failure_lab.html",{"success":False, "failure":True}) - else : + password = hashlib.scrypt(password.encode(), salt=b'salt', n=16384, r=8, p=1).hex() + user = CF_user.objects.get(username=username, password=password) + return render(request, "Lab_2021/A2_Crypto_failur/crypto_failure_lab.html", {"user": user, "success": True, "failure": False}) + except CF_user.DoesNotExist: + return render(request, "Lab_2021/A2_Crypto_failur/crypto_failure_lab.html", {"success": False, "failure": True}) + else: return redirect('login') def crypto_failure_lab2(request): @@ -1039,25 +1061,31 @@ def crypto_failure_lab2(request): return render(request,"Lab_2021/A2_Crypto_failur/crypto_failure_lab2.html",{"success":False, "failure":True}) # based on CWE-319 +from django.http import HttpResponse +import datetime + def crypto_failure_lab3(request): if request.user.is_authenticated: if request.method == "GET": - try : - cookie = request.COOKIES["cookie"] - print(cookie) - expire = cookie.split('|')[1] - expire = datetime.datetime.fromisoformat(expire) - now = datetime.datetime.now() - if now > expire : - return render(request,"Lab_2021/A2_Crypto_failur/crypto_failure_lab3.html",{"success":False,"failure":False}) - elif cookie.split('|')[0] == 'admin': - return render(request,"Lab_2021/A2_Crypto_failur/crypto_failure_lab3.html",{"success":True,"failure":False,"admin":True}) - else: - return render(request,"Lab_2021/A2_Crypto_failur/crypto_failure_lab3.html",{"success":True,"failure":False,"admin":False}) + try: + cookie = request.COOKIES.get("cookie") + if cookie is not None: + expire = cookie.split('|')[1] + expire = datetime.datetime.fromisoformat(expire) + now = datetime.datetime.now() + if now > expire: + return render(request, "Lab_2021/A2_Crypto_failur/crypto_failure_lab3.html", {"success": False, "failure": False}) + elif cookie.split('|')[0] == 'admin': + return render(request, "Lab_2021/A2_Crypto_failur/crypto_failure_lab3.html", + {"success": True, "failure": False, "admin": True}) + else: + return render(request, "Lab_2021/A2_Crypto_failur/crypto_failure_lab3.html", + {"success": True, "failure": False, "admin": False}) except Exception as e: print(e) pass - return render(request,"Lab_2021/A2_Crypto_failur/crypto_failure_lab3.html") + return render(request, "Lab_2021/A2_Crypto_failur/crypto_failure_lab3.html") + if request.method == "POST": username = request.POST["username"] password = request.POST["password"] @@ -1065,16 +1093,16 @@ def crypto_failure_lab3(request): if username == "User" and password == "P@$$w0rd": expire = datetime.datetime.now() + datetime.timedelta(minutes=60) cookie = f"{username}|{expire}" - response = render(request,"Lab_2021/A2_Crypto_failur/crypto_failure_lab3.html",{"success":True, "failure":False , "admin":False}) - response.set_cookie("cookie", cookie) + response = render(request, "Lab_2021/A2_Crypto_failur/crypto_failure_lab3.html", {"success": True, "failure": False, "admin": False}) + response.set_cookie("cookie", cookie, secure=True, httponly=True, samesite='Lax') response.status_code = 200 return response else: - response = render(request,"Lab_2021/A2_Crypto_failur/crypto_failure_lab3.html",{"success":False, "failure":True}) - response.set_cookie("cookie", None) + response = render(request, "Lab_2021/A2_Crypto_failur/crypto_failure_lab3.html", {"success": False, "failure": True}) + response.set_cookie("cookie", "", max_age=0, secure=True, httponly=True, samesite='Lax') return response except: - return render(request,"Lab_2021/A2_Crypto_failur/crypto_failure_lab2.html",{"success":False, "failure":True}) + return render(request, "Lab_2021/A2_Crypto_failur/crypto_failure_lab2.html", {"success": False, "failure": True}) #-----------------------------------------------SECURITY MISCONFIGURATION ------------------- from pygoat.settings import SECRET_COOKIE_KEY @@ -1099,7 +1127,7 @@ def sec_misconfig_lab3(request): cookie = jwt.encode(payload, SECRET_COOKIE_KEY, algorithm='HS256') response = render(request,"Lab/sec_mis/sec_mis_lab3.html", {"admin":False} ) - response.set_cookie(key = "auth_cookie", value = cookie) + response.set_cookie(key="auth_cookie", value=cookie, secure=True, httponly=True, samesite='Lax') return response # - ------------------------Identification and Authentication Failures-------------------------------- @@ -1172,13 +1200,16 @@ def auth_failure_lab2(request): def auth_failure_lab3(request): if request.method == "GET": try: - cookie = request.COOKIES["session_id"] - session = AF_session_id.objects.get(session_id=cookie) - if session : - return render(request,"Lab_2021/A7_auth_failure/lab3.html", {"username":session.user,"success":True}) + cookie = request.COOKIES.get("session_id") + session = AF_session_id.objects.filter(session_id=cookie).first() + if session: + response = render(request, "Lab_2021/A7_auth_failure/lab3.html", {"username":session.user, "success":True}) + response.set_cookie("session_id", cookie, secure=True, httponly=True, samesite='Lax') + return response except: pass - return render(request, "Lab_2021/A7_auth_failure/lab3.html") + response = render(request, "Lab_2021/A7_auth_failure/lab3.html") + return response elif request.method == "POST": token = str(uuid.uuid4()) try: @@ -1187,14 +1218,14 @@ def auth_failure_lab3(request): password = hashlib.sha256(password.encode()).hexdigest() except: response = render(request, "Lab_2021/A7_auth_failure/lab3.html") - response.set_cookie("session_id", None) + response.set_cookie("session_id", None, secure=True, httponly=True, samesite='Lax') return response - if USER_A7_LAB3[username]['password'] == password: + if USER_A7_LAB3.get(username) and USER_A7_LAB3[username]['password'] == password: session_data = AF_session_id.objects.create(session_id=token, user=USER_A7_LAB3[username]['username']) session_data.save() response = render(request, "Lab_2021/A7_auth_failure/lab3.html", {"success":True, "failure":False, "username":username}) - response.set_cookie("session_id", token) + response.set_cookie("session_id", token, secure=True, httponly=True, samesite='Lax') return response #-- coding playground for lab2 From 66bb4f7f4d476a1806163e96676eef5432b984e0 Mon Sep 17 00:00:00 2001 From: "patched.codes[bot]" <298395+patched.codes[bot]@users.noreply.github.com> Date: Tue, 25 Jun 2024 09:57:22 +0800 Subject: [PATCH 12/15] Patched /private/var/folders/61/dwx9fsqs2k931dkwz6dg1ymw0000gn/T/tmp980zihnh/introduction/playground/A9/archive.py --- introduction/playground/A9/archive.py | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/introduction/playground/A9/archive.py b/introduction/playground/A9/archive.py index c9db8fc..690c881 100644 --- a/introduction/playground/A9/archive.py +++ b/introduction/playground/A9/archive.py @@ -1,10 +1,8 @@ from django.http import JsonResponse -from django.views.decorators.csrf import csrf_exempt from .main import Log -@csrf_exempt def log_function_target(request): L = Log(request) if request.method == "GET": @@ -45,18 +43,15 @@ def __init__(self,request): def info(self,msg): now = datetime.datetime.now() - f = open('test.log', 'a') - f.write(f"INFO:{now}:{msg}\n") - f.close() + with open('test.log', 'a') as f: + f.write(f"INFO:{now}:{msg}\n") def warning(self,msg): now = datetime.datetime.now() - f = open('test.log', 'a') - f.write(f"WARNING:{now}:{msg}\n") - f.close() + with open('test.log', 'a') as f: + f.write(f"WARNING:{now}:{msg}\n") def error(self,msg): now = datetime.datetime.now() - f = open('test.log', 'a') - f.write(f"ERROR:{now}:{msg}\n") - f.close() + with open('test.log', 'a') as f: + f.write(f"ERROR:{now}:{msg}\n") From a67bcd4afca9ca3d6e74466aec594487219b9809 Mon Sep 17 00:00:00 2001 From: "patched.codes[bot]" <298395+patched.codes[bot]@users.noreply.github.com> Date: Tue, 25 Jun 2024 09:57:22 +0800 Subject: [PATCH 13/15] Patched /private/var/folders/61/dwx9fsqs2k931dkwz6dg1ymw0000gn/T/tmp980zihnh/introduction/static/js/a9.js --- introduction/static/js/a9.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/introduction/static/js/a9.js b/introduction/static/js/a9.js index 9c58b8a..4169fe0 100644 --- a/introduction/static/js/a9.js +++ b/introduction/static/js/a9.js @@ -37,9 +37,9 @@ event3 = function(){ document.getElementById("a9_d3").style.display = 'flex'; for (var i = 0; i < data.logs.length; i++) { var li = document.createElement("li"); - li.innerHTML = data.logs[i]; + li.textContent = data.logs[i]; // Use textContent instead of innerHTML document.getElementById("a9_d3").appendChild(li); } }) .catch(error => console.log('error', error)); - } \ No newline at end of file +} From 6aa26102d2f7d4714fe36db9e0896424086a36a3 Mon Sep 17 00:00:00 2001 From: "patched.codes[bot]" <298395+patched.codes[bot]@users.noreply.github.com> Date: Tue, 25 Jun 2024 09:57:22 +0800 Subject: [PATCH 14/15] Patched /private/var/folders/61/dwx9fsqs2k931dkwz6dg1ymw0000gn/T/tmp980zihnh/introduction/templates/Lab/XSS/xss_lab_3.html --- introduction/templates/Lab/XSS/xss_lab_3.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/introduction/templates/Lab/XSS/xss_lab_3.html b/introduction/templates/Lab/XSS/xss_lab_3.html index a550b9a..b88d0e5 100644 --- a/introduction/templates/Lab/XSS/xss_lab_3.html +++ b/introduction/templates/Lab/XSS/xss_lab_3.html @@ -19,7 +19,7 @@

Welcome to XSS Challenge

{{code}}


From 54f80f7759258c04a084b39f1b8cb04bf1e613cf Mon Sep 17 00:00:00 2001 From: "patched.codes[bot]" <298395+patched.codes[bot]@users.noreply.github.com> Date: Tue, 25 Jun 2024 09:57:22 +0800 Subject: [PATCH 15/15] Patched /private/var/folders/61/dwx9fsqs2k931dkwz6dg1ymw0000gn/T/tmp980zihnh/docker-compose.yml --- docker-compose.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index 3d39f83..ab88e2f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,6 +9,9 @@ services: - POSTGRES_DB=postgres - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres + security_opt: + - "no-new-privileges:true" + read_only: true web: build: . image: pygoat/pygoat @@ -20,6 +23,9 @@ services: depends_on: - migration - db + security_opt: + - "no-new-privileges:true" + read_only: true migration: image: pygoat/pygoat command: python pygoat/manage.py migrate --noinput @@ -27,3 +33,6 @@ services: - .:/app depends_on: - db + security_opt: + - "no-new-privileges:true" + read_only: true