From c14601e1275b22faf6fee231cc7c9b486536571c Mon Sep 17 00:00:00 2001 From: "patched.codes[bot]" <298395+patched.codes[bot]@users.noreply.github.com> Date: Wed, 8 May 2024 12:11:55 +0800 Subject: [PATCH 01/17] Patched introduction/playground/A9/api.py --- introduction/playground/A9/api.py | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/introduction/playground/A9/api.py b/introduction/playground/A9/api.py index 35e1bd2..f6ad731 100644 --- a/introduction/playground/A9/api.py +++ b/introduction/playground/A9/api.py @@ -1,33 +1,30 @@ 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 c1ae8162af59b26437757d8a3da08852090acb40 Mon Sep 17 00:00:00 2001 From: "patched.codes[bot]" <298395+patched.codes[bot]@users.noreply.github.com> Date: Wed, 8 May 2024 12:11:55 +0800 Subject: [PATCH 02/17] Patched introduction/templates/Lab/CMD/cmd_lab.html --- introduction/templates/Lab/CMD/cmd_lab.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/introduction/templates/Lab/CMD/cmd_lab.html b/introduction/templates/Lab/CMD/cmd_lab.html index 2998cd3..6175ff5 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 %}

@@ -33,4 +34,4 @@
Output

-{% endblock %} \ No newline at end of file +{% endblock %} From 18ec2ec5ecb029b080e7f35296b101f10eccf2dd Mon Sep 17 00:00:00 2001 From: "patched.codes[bot]" <298395+patched.codes[bot]@users.noreply.github.com> Date: Wed, 8 May 2024 12:11:55 +0800 Subject: [PATCH 03/17] Patched introduction/playground/A9/archive.py --- introduction/playground/A9/archive.py | 53 ++++++--------------------- 1 file changed, 11 insertions(+), 42 deletions(-) diff --git a/introduction/playground/A9/archive.py b/introduction/playground/A9/archive.py index c9db8fc..b804e9c 100644 --- a/introduction/playground/A9/archive.py +++ b/introduction/playground/A9/archive.py @@ -1,62 +1,31 @@ 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'] + username = request.POST.get('username') + password = request.POST.get('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) - - -# ====================================== - -import datetime - - -# f = open('test.log', 'a') --> use this file to log -class Log: - def __init__(self,request): - self.request = request - - def info(self,msg): - now = datetime.datetime.now() - f = open('test.log', 'a') - f.write(f"INFO:{now}:{msg}\n") - f.close() - - def warning(self,msg): - now = datetime.datetime.now() - f = open('test.log', 'a') - f.write(f"WARNING:{now}:{msg}\n") - f.close() - - def error(self,msg): - now = datetime.datetime.now() - f = open('test.log', 'a') - f.write(f"ERROR:{now}:{msg}\n") - f.close() + return JsonResponse({"message": "success", "method": "update"}, status=200) + return JsonResponse({"message": "method not allowed"}, status=403) From 6bcf48bf927af83d4dffa74342cd22da4a6ef680 Mon Sep 17 00:00:00 2001 From: "patched.codes[bot]" <298395+patched.codes[bot]@users.noreply.github.com> Date: Wed, 8 May 2024 12:11:55 +0800 Subject: [PATCH 04/17] Patched introduction/views.py --- introduction/views.py | 366 +++++++++++++++++++----------------------- 1 file changed, 167 insertions(+), 199 deletions(-) diff --git a/introduction/views.py b/introduction/views.py index 0f550c4..165a415 100644 --- a/introduction/views.py +++ b/introduction/views.py @@ -142,43 +142,40 @@ def sql(request): return render(request,'Lab/SQL/sql.html') else: return redirect('login') +from django.db import connection 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+"'" + sql_query = "SELECT * FROM introduction_login WHERE user=%s AND password=%s" print(sql_query) try: print("\nin try\n") - val=login.objects.raw(sql_query) + val = login.objects.raw(sql_query, [name, password]) except: print("\nin except\n") return render( request, 'Lab/SQL/sql_lab.html', { - "wrongpass":password, - "sql_error":sql_query + "wrongpass": password, + "sql_error": sql_query }) - + if val: - user=val[0].user - return render(request, 'Lab/SQL/sql_lab.html',{"user1":user}) + user = val[0].user + return render(request, 'Lab/SQL/sql_lab.html',{"user1": user}) else: return render( request, 'Lab/SQL/sql_lab.html', { - "wrongpass":password, - "sql_error":sql_query + "wrongpass": password, + "sql_error": sql_query }) else: return render(request, 'Lab/SQL/sql_lab.html',{"no": "User not found"}) @@ -200,19 +197,21 @@ class TestUser: admin: int = 0 pickled_user = pickle.dumps(TestUser()) encoded_user = base64.b64encode(pickled_user) +import base64 +import json 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: 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) - admin = pickle.loads(token) - if admin.admin == 1: - response = render(request,'Lab/insec_des/insec_des_lab.html', {"message":"Welcome Admin, SECRETKEY:ADMIN123"}) + token_data = json.loads(token) + if token_data.get('admin') == 1: + response = render(request, 'Lab/insec_des/insec_des_lab.html', {"message": "Welcome Admin, SECRETKEY:ADMIN123"}) return response return response @@ -234,19 +233,13 @@ def xxe_lab(request): return render(request,'Lab/XXE/xxe_lab.html') else: return redirect('login') - -@csrf_exempt def xxe_see(request): if request.user.is_authenticated: - - data=comments.objects.all() - com=data[0].comment - return render(request,'Lab/XXE/xxe_lab.html',{"com":com}) + data = comments.objects.all() + com = data[0].comment + return render(request, 'Lab/XXE/xxe_lab.html', {"com": com}) else: return redirect('login') - - -@csrf_exempt def xxe_parse(request): parser = make_parser() @@ -259,7 +252,7 @@ def xxe_parse(request): startInd = text.find('>') endInd = text.find('<', startInd) text = text[startInd + 1:endInd:] - p=comments.objects.filter(id=1).update(comment=text) + p = comments.objects.filter(id=1).update(comment=text) return render(request, 'Lab/XXE/xxe_lab.html') @@ -269,70 +262,67 @@ 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 django.utils.safestring import mark_safe def auth_lab_signup(request): if request.method == 'GET': - return render(request,'Lab/AUTH/auth_lab_signup.html') + return render(request, 'Lab/AUTH/auth_lab_signup.html') elif request.method == 'POST': try: name = request.POST['name'] user_name = request.POST['username'] - passwd = request.POST['pass'] - obj = authLogin.objects.create(name=name,username=user_name,password=passwd) + passwd = request.POST['pass'] + 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': mark_safe(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.shortcuts import render +from django.http import HttpResponse +from django.template.loader import render_to_string +from django.utils.html import escape +from Lab.models import authLogin def auth_lab_login(request): if request.method == 'GET': try: - obj = authLogin.objects.filter(userid=request.COOKIES['userid'])[0] + obj = authLogin.objects.filter(userid=request.COOKIES.get('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': try: user_name = request.POST['username'] passwd = request.POST['pass'] - print(user_name,passwd) obj = authLogin.objects.filter(username=user_name,password=passwd)[0] 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: - render(request,'Lab/AUTH/auth_lab_login.html',{'err_msg':'Cookie cannot be set'}) + return render(request,'Lab/AUTH/auth_lab_login.html',{'err_msg':'Cookie cannot be set'}) except: return render(request,'Lab/AUTH/auth_lab_login.html',{'err_msg':'Check your credentials'}) - 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 - -#***************************************************************Broken Access Control************************************************************# - -@csrf_exempt + return render(request, 'Lab/AUTH/auth_lab.html', context={'err_msg': 'Logout successful'}) def ba(request): if request.user.is_authenticated: - return render(request,"Lab/BrokenAccess/ba.html") + return render(request, "Lab/BrokenAccess/ba.html") else: return redirect('login') -@csrf_exempt def ba_lab(request): if request.user.is_authenticated: name = request.POST.get('name') @@ -405,57 +395,56 @@ def cmd(request): return render(request,'Lab/CMD/cmd.html') else: return redirect('login') -@csrf_exempt +import shlex +from django.http import HttpResponse +from django.shortcuts import render, redirect +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, - stdout=subprocess.PIPE, + 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: output = "Something went wrong" - return render(request,'Lab/CMD/cmd_lab.html',{"output":output}) + return render(request, 'Lab/CMD/cmd_lab.html', {"output": output}) print(output) - return render(request,'Lab/CMD/cmd_lab.html',{"output":output}) + return render(request, 'Lab/CMD/cmd_lab.html', {"output": output}) else: return render(request, 'Lab/CMD/cmd_lab.html') else: return redirect('login') - -@csrf_exempt def cmd_lab2(request): if request.user.is_authenticated: - if (request.method=="POST"): - val=request.POST.get('val') + if request.method == "POST": + val = request.POST.get('val') print(val) try: output = eval(val) except: output = "Something went wrong" - return render(request,'Lab/CMD/cmd_lab2.html',{"output":output}) + return render(request, 'Lab/CMD/cmd_lab2.html', {"output": output}) print("Output = ", output) - return render(request,'Lab/CMD/cmd_lab2.html',{"output":output}) + return render(request, 'Lab/CMD/cmd_lab2.html', {"output": output}) else: return render(request, 'Lab/CMD/cmd_lab2.html') else: @@ -481,34 +470,30 @@ def bau_lab(request): def login_otp(request): return render(request,"Lab/BrokenAuth/otp.html") - -@csrf_exempt def Otp(request): - if request.method=="GET": - email=request.GET.get('email') - otpN=randint(100,999) + if request.method == "GET": + email = request.GET.get('email') + otpN = randint(100,999) if email and otpN: - if email=="admin@pygoat.com": + if email == "admin@pygoat.com": otp.objects.filter(id=2).update(otp=otpN) - html = render(request, "Lab/BrokenAuth/otp.html", {"otp":"Sent To Admin Mail ID"}) + html = render(request, "Lab/BrokenAuth/otp.html", {"otp": "Sent To Admin Mail ID"}) html.set_cookie("email", email) return html - else: otp.objects.filter(id=1).update(email=email, otp=otpN) - html=render (request,"Lab/BrokenAuth/otp.html",{"otp":otpN}) - html.set_cookie("email",email) + html = render(request, "Lab/BrokenAuth/otp.html", {"otp": otpN}) + html.set_cookie("email", email) return html else: - return render(request,"Lab/BrokenAuth/otp.html") + return render(request, "Lab/BrokenAuth/otp.html") else: - otpR=request.POST.get("otp") - email=request.COOKIES.get("email") - if otp.objects.filter(email=email,otp=otpR) or otp.objects.filter(id=2,otp=otpR): - # return HttpResponse("

Login Success for email:::"+email+"

") - return render (request,"Lab/BrokenAuth/otp.html",{"email":email}) + otpR = request.POST.get("otp") + email = request.COOKIES.get("email") + if otp.objects.filter(email=email, otp=otpR) or otp.objects.filter(id=2, otp=otpR): + return render(request, "Lab/BrokenAuth/otp.html", {"email": email}) else: - return render (request,"Lab/BrokenAuth/otp.html",{"otp":"Invalid OTP Please Try Again"}) + return render(request, "Lab/BrokenAuth/otp.html", {"otp": "Invalid OTP Please Try Again"}) #*****************************************Security Misconfiguration**********************************************# @@ -540,45 +525,39 @@ def a9(request): return render(request,"Lab/A9/a9.html") else: return redirect('login') -@csrf_exempt def a9_lab(request): if request.user.is_authenticated: - if request.method=="GET": - return render(request,"Lab/A9/a9_lab.html") + if request.method == "GET": + return render(request, "Lab/A9/a9_lab.html") else: - - try : - file=request.FILES["file"] - try : - data = yaml.load(file,yaml.Loader) - - return render(request,"Lab/A9/a9_lab.html",{"data":data}) + try: + file = request.FILES["file"] + try: + data = yaml.safe_load(file) + return render(request, "Lab/A9/a9_lab.html", {"data": data}) except: return render(request, "Lab/A9/a9_lab.html", {"data": "Error"}) - except: - return render(request, "Lab/A9/a9_lab.html", {"data":"Please Upload a Yaml file."}) + return render(request, "Lab/A9/a9_lab.html", {"data": "Please Upload a Yaml file."}) else: return redirect('login') def get_version(request): return render(request,"Lab/A9/a9_lab.html",{"version":"pyyaml v5.1"}) - -@csrf_exempt def a9_lab2(request): if not request.user.is_authenticated: return redirect('login') if request.method == "GET": - return render (request,"Lab/A9/a9_lab2.html") + return render(request, "Lab/A9/a9_lab2.html") elif request.method == "POST": - try : - file=request.FILES["file"] + try: + file = request.FILES["file"] function_str = request.POST.get("function") - img = Image.open(file) + img = Image.open(file) img = img.convert("RGB") - r,g,b = img.split() + r, g, b = img.split() # function_str = "convert(r+g, '1')" - output = ImageMath.eval(function_str,img = img, b=b, r=r, g=g) + output = ImageMath.eval(function_str, img=img, b=b, r=r, g=g) # saving the image buffered = BytesIO() @@ -588,14 +567,14 @@ def a9_lab2(request): bufferd_ref = BytesIO() img.save(bufferd_ref, format="JPEG") img_str_ref = base64.b64encode(bufferd_ref.getvalue()).decode("utf-8") - try : - return render(request,"Lab/A9/a9_lab2.html",{"img_str": img_str,"img_str_ref":img_str_ref, "success": True}) + try: + return render(request, "Lab/A9/a9_lab2.html", {"img_str": img_str, "img_str_ref": img_str_ref, "success": True}) except Exception as e: print(e) return render(request, "Lab/A9/a9_lab2.html", {"data": "Error", "error": True}) except Exception as e: print(e) - return render(request, "Lab/A9/a9_lab2.html", {"data":"Please Upload a file", "error":True}) + return render(request, "Lab/A9/a9_lab2.html", {"data": "Please Upload a file", "error": True}) @authentication_decorator @@ -721,22 +700,16 @@ def insec_desgine_lab(request): pass else: return redirect('login') - - #------------------------------------------------------------------------------------------------------------------------- #------------------------------------------------------------------------------------------------------------------------- ###################################################### 2021 A1: Broken Access -@csrf_exempt def a1_broken_access(request): if not request.user.is_authenticated: return redirect('login') return render(request,"Lab_2021/A1_BrokenAccessControl/broken_access.html") - - -@csrf_exempt def a1_broken_access_lab_1(request): if request.user.is_authenticated: pass @@ -771,8 +744,6 @@ def a1_broken_access_lab_1(request): else: return render(request,'Lab_2021/A1_BrokenAccessControl/broken_access_lab_1.html',{"no_creds":True}) - -@csrf_exempt def a1_broken_access_lab_2(request): if request.user.is_authenticated: pass @@ -798,13 +769,13 @@ def a1_broken_access_lab_2(request): }) elif ( name=='jack' and password=='jacktheripper'): # Will implement hashing here html = render( - request, - 'Lab_2021/A1_BrokenAccessControl/broken_access_lab_2.html', - { - "not_admin":"No Secret key for this User", - "username": name, - "status": "not admin" - }) + request, + 'Lab_2021/A1_BrokenAccessControl/broken_access_lab_2.html', + { + "not_admin":"No Secret key for this User", + "username": name, + "status": "not admin" + }) return html else: return render(request, 'Lab_2021/A1_BrokenAccessControl/broken_access_lab_2.html', {"data": "User Not Found"}) @@ -832,29 +803,21 @@ def a1_broken_access_lab3_secret(request): return redirect('login') # no checking applied here return render(request, 'Lab_2021/A1_BrokenAccessControl/secret.html') - - -###################################################### 2021 A3: Injection - -@csrf_exempt def injection(request): if not request.user.is_authenticated: return redirect('login') return render(request,"Lab_2021/A3_Injection/injection.html") - - -@csrf_exempt def injection_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') print(name) 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_params = [name, password] sql_instance = sql_lab_table(id="admin", password="65079b006e85a7e798abecb99e47c154") sql_instance.save() @@ -868,7 +831,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, sql_params) user = user[0].id print(user) @@ -877,19 +840,19 @@ def injection_sql_lab(request): request, 'Lab_2021/A3_Injection/sql_lab.html', { - "wrongpass":password, - "sql_error":sql_query + "wrongpass": password, + "sql_error": sql_query }) if user: - return render(request, 'Lab_2021/A3_Injection/sql_lab.html',{"user1":user}) + return render(request, 'Lab_2021/A3_Injection/sql_lab.html', {"user1": user}) else: return render( request, 'Lab_2021/A3_Injection/sql_lab.html', { - "wrongpass":password, - "sql_error":sql_query + "wrongpass": password, + "sql_error": sql_query }) else: return render(request, 'Lab_2021/A3_Injection/sql_lab.html') @@ -907,18 +870,17 @@ def ssrf(request): return render(request,"Lab/ssrf/ssrf.html") else: return redirect('login') - def ssrf_lab(request): if request.user.is_authenticated: - if request.method=="GET": + if request.method == "GET": return render(request,"Lab/ssrf/ssrf_lab.html",{"blog":"Read Blog About SSRF"}) else: - file=request.POST["blog"] - try : + file = request.POST["blog"] + try: dirname = os.path.dirname(__file__) - filename = os.path.join(dirname, file) - file = open(filename,"r") - data = file.read() + filename = os.path.abspath(os.path.join(dirname, file)) + 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"}) @@ -944,6 +906,14 @@ def ssrf_target(request): return render(request,"Lab/ssrf/ssrf_target.html") else: return render(request,"Lab/ssrf/ssrf_target.html",{"access_denied":True}) +from urllib.parse import urlparse +from django.http import Http404 + +ALLOWED_HOSTS = ["example.com", "api.example.com"] # Add your allowed hosts here + +def is_valid_url(url): + parsed_url = urlparse(url) + return parsed_url.hostname in ALLOWED_HOSTS @authentication_decorator def ssrf_lab2(request): @@ -952,11 +922,14 @@ def ssrf_lab2(request): elif request.method == "POST": url = request.POST["url"] + if not is_valid_url(url): + raise Http404("Invalid 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"}) + return render(request, "Lab/ssrf/ssrf_lab2.html", {"error": "Failed to fetch URL"}) #--------------------------------------- Server-side template injection --------------------------------------# def ssti(request): @@ -964,7 +937,6 @@ def ssti(request): return render(request,"Lab_2021/A3_Injection/ssti.html") else: return redirect('login') - def ssti_lab(request): if request.user.is_authenticated: if request.method=="GET": @@ -985,9 +957,8 @@ 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() + with open(filename, "w+") as file: + file.write(escape(blog)) return redirect(f'blog/{id}') else: return redirect('login') @@ -1007,21 +978,23 @@ def crypto_failure(request): return render(request,"Lab_2021/A2_Crypto_failur/crypto_failure.html",{"success":False,"failure":False}) 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}) + password_hash = hashlib.scrypt(password.encode(), salt=b'salt', n=16384, r=8, p=1) + password = password_hash.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: - return render(request,"Lab_2021/A2_Crypto_failur/crypto_failure_lab.html",{"success":False, "failure":True}) - else : + 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): @@ -1037,27 +1010,26 @@ def crypto_failure_lab2(request): return render(request,"Lab_2021/A2_Crypto_failur/crypto_failure_lab2.html",{"user":user, "success":True,"failure":False}) except: return render(request,"Lab_2021/A2_Crypto_failur/crypto_failure_lab2.html",{"success":False, "failure":True}) - # based on CWE-319 def crypto_failure_lab3(request): if request.user.is_authenticated: if request.method == "GET": - try : - cookie = request.COOKIES["cookie"] + try: + cookie = request.COOKIES.get("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}) + 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}) + 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}) + 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,21 +1037,19 @@ 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", None, 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 - - def sec_misconfig_lab3(request): if not request.user.is_authenticated: return redirect('login') @@ -1087,19 +1057,19 @@ def sec_misconfig_lab3(request): cookie = request.COOKIES["auth_cookie"] payload = jwt.decode(cookie, SECRET_COOKIE_KEY, algorithms=['HS256']) if payload['user'] == 'admin': - return render(request,"Lab/sec_mis/sec_mis_lab3.html", {"admin":True} ) + return render(request, "Lab/sec_mis/sec_mis_lab3.html", {"admin": True}) else: - return render(request,"Lab/sec_mis/sec_mis_lab3.html", {"admin":False} ) + return render(request, "Lab/sec_mis/sec_mis_lab3.html", {"admin": False}) except: payload = { - 'user':'not_admin', + 'user': 'not_admin', 'exp': datetime.datetime.utcnow() + datetime.timedelta(minutes=60), 'iat': datetime.datetime.utcnow(), } 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 = render(request, "Lab/sec_mis/sec_mis_lab3.html", {"admin": False}) + response.set_cookie(key="auth_cookie", value=cookie, secure=True, httponly=True, samesite='Lax') return response # - ------------------------Identification and Authentication Failures-------------------------------- @@ -1159,7 +1129,6 @@ def auth_failure_lab2(request): "User3":{"userid":"3", "username":"User3", "password": "5a91a66f0c86b5435fe748706b99c17e6e54a17e03c2a3ef8d0dfa918db41cf6"}, "User4":{"userid":"4", "username":"User4", "password": "6046bc3337728a60967a151ee584e4fd7c53740a49485ebdc38cac42a255f266"} } - # USER_A7_LAB3 = { # "User1":{"userid":"1", "username":"User1", "password": "Hash1"}, # "User2":{"userid":"2", "username":"User2", "password": "Hash2"}, @@ -1168,14 +1137,13 @@ def auth_failure_lab2(request): # } @authentication_decorator -@csrf_exempt 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}) + if session: + return render(request, "Lab_2021/A7_auth_failure/lab3.html", {"username": session.user, "success": True}) except: pass return render(request, "Lab_2021/A7_auth_failure/lab3.html") @@ -1187,14 +1155,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: 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 = render(request, "Lab_2021/A7_auth_failure/lab3.html", {"success": True, "failure": False, "username": username}) + response.set_cookie("session_id", token, secure=True, httponly=True, samesite='Lax') return response #-- coding playground for lab2 From f4b0047394060a5c89bdf2f2a3fc83762e41f00b Mon Sep 17 00:00:00 2001 From: "patched.codes[bot]" <298395+patched.codes[bot]@users.noreply.github.com> Date: Wed, 8 May 2024 12:11:55 +0800 Subject: [PATCH 05/17] Patched 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 From ee26d4abb432f79de2a12a35093339909e776f2b Mon Sep 17 00:00:00 2001 From: "patched.codes[bot]" <298395+patched.codes[bot]@users.noreply.github.com> Date: Wed, 8 May 2024 12:11:55 +0800 Subject: [PATCH 06/17] Patched introduction/static/js/a9.js --- introduction/static/js/a9.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/introduction/static/js/a9.js b/introduction/static/js/a9.js index 9c58b8a..c6bc051 100644 --- a/introduction/static/js/a9.js +++ b/introduction/static/js/a9.js @@ -35,11 +35,14 @@ event3 = function(){ let data = JSON.parse(result); // parse JSON string into object console.log(data.logs); document.getElementById("a9_d3").style.display = 'flex'; - for (var i = 0; i < data.logs.length; i++) { + var ul = document.getElementById("a9_d3"); + ul.innerHTML = ''; // Clear existing list items + data.logs.forEach(log => { var li = document.createElement("li"); - li.innerHTML = data.logs[i]; + var text = document.createTextNode(log); + li.appendChild(text); document.getElementById("a9_d3").appendChild(li); - } + }); }) .catch(error => console.log('error', error)); - } \ No newline at end of file +} From 56d714c3fdcedbb7c5124ea4d7c92f048b8e843e Mon Sep 17 00:00:00 2001 From: "patched.codes[bot]" <298395+patched.codes[bot]@users.noreply.github.com> Date: Wed, 8 May 2024 12:11:55 +0800 Subject: [PATCH 07/17] Patched introduction/templates/Lab/ssrf/ssrf_discussion.html --- introduction/templates/Lab/ssrf/ssrf_discussion.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/introduction/templates/Lab/ssrf/ssrf_discussion.html b/introduction/templates/Lab/ssrf/ssrf_discussion.html index 7dc6678..2eb5868 100644 --- a/introduction/templates/Lab/ssrf/ssrf_discussion.html +++ b/introduction/templates/Lab/ssrf/ssrf_discussion.html @@ -123,22 +123,22 @@
ssrf_lab.html