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..e7dc04e 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,7 +9,7 @@
Admins Have the Secretkey
@@ -50,4 +48,4 @@
Please Provide Credentials
-{% endblock %}
\ No newline at end of file
+{% endblock %}
diff --git a/introduction/views.py b/introduction/views.py
index 0f550c4..4b77ec0 100644
--- a/introduction/views.py
+++ b/introduction/views.py
@@ -142,46 +142,33 @@ def sql(request):
return render(request,'Lab/SQL/sql.html')
else:
return redirect('login')
-
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)
+ val = login.objects.raw("SELECT * FROM introduction_login WHERE user=%s AND password=%s", [name, password])
except:
print("\nin except\n")
- return render(
- request,
- 'Lab/SQL/sql_lab.html',
- {
- "wrongpass":password,
- "sql_error":sql_query
- })
-
+ return render(request, 'Lab/SQL/sql_lab.html',
+ {
+ "wrongpass": password
+ })
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,
+ request,
'Lab/SQL/sql_lab.html',
{
- "wrongpass":password,
- "sql_error":sql_query
+ "wrongpass": password
})
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:
@@ -200,21 +187,22 @@ class TestUser:
admin: int = 0
pickled_user = pickle.dumps(TestUser())
encoded_user = base64.b64encode(pickled_user)
+import json
+import base64
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'))
+ if token is None:
+ token = base64.b64encode(json.dumps(encoded_user).encode('utf-8')).decode('utf-8')
+ response.set_cookie(key='token', value=token, 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"})
- return response
-
+ token = base64.b64decode(token).decode('utf-8')
+ admin = json.loads(token)
+ if admin['admin'] == 1:
+ response = render(request, 'Lab/insec_des/insec_des_lab.html', {"message": "Welcome Admin, SECRETKEY:ADMIN123"})
+ return response
return response
else:
return redirect('login')
@@ -234,8 +222,6 @@ 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:
@@ -245,8 +231,6 @@ def xxe_see(request):
else:
return redirect('login')
-
-@csrf_exempt
def xxe_parse(request):
parser = make_parser()
@@ -269,7 +253,6 @@ def auth_home(request):
def auth_lab(request):
return render(request,'Lab/AUTH/auth_lab.html')
-
def auth_lab_signup(request):
if request.method == 'GET':
return render(request,'Lab/AUTH/auth_lab_signup.html')
@@ -280,23 +263,26 @@ def auth_lab_signup(request):
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'})
- response = HttpResponse(rendered)
- response.set_cookie('userid', obj.userid, max_age=31449600, samesite=None, secure=False)
+ response = render(request, 'Lab/AUTH/auth_success.html', {
+ 'username': obj.username,
+ 'userid': obj.userid,
+ 'name':obj.name,
+ 'err_msg':'Cookie Set'
+ })
+ 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'})
-
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)
+ context = {'username': obj.username,'userid':obj.userid,'name':obj.name, 'err_msg':'Login Successful'}
+ response = render(request, 'Lab/AUTH/auth_success.html', context)
+ response.set_cookie('userid', obj.userid, max_age=31449600, samesite='Lax', secure=True, httponly=True)
print('Login successful')
return response
except:
@@ -308,9 +294,9 @@ def auth_lab_login(request):
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)
+ context = {'username': obj.username,'userid':obj.userid,'name':obj.name, 'err_msg':'Login Successful'}
+ response = render(request, 'Lab/AUTH/auth_success.html', context)
+ response.set_cookie('userid', obj.userid, max_age=31449600, samesite='Lax', secure=True, httponly=True)
print('Login successful')
return response
except:
@@ -318,21 +304,18 @@ 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
+
def auth_lab_logout(request):
- rendered = render_to_string('Lab/AUTH/auth_lab.html',context={'err_msg':'Logout successful'})
- response = HttpResponse(rendered)
+ response = render(request, 'Lab/AUTH/auth_lab.html', context={'err_msg':'Logout successful'})
response.delete_cookie('userid')
return response
-
-#***************************************************************Broken Access Control************************************************************#
-
-@csrf_exempt
def ba(request):
- if request.user.is_authenticated:
- return render(request,"Lab/BrokenAccess/ba.html")
- else:
- return redirect('login')
-@csrf_exempt
+ if request.method == 'POST':
+ if request.user.is_authenticated:
+ return render(request, "Lab/BrokenAccess/ba.html")
+ else:
+ return redirect('login')
def ba_lab(request):
if request.user.is_authenticated:
name = request.POST.get('name')
@@ -405,31 +388,31 @@ def cmd(request):
return render(request,'Lab/CMD/cmd.html')
else:
return redirect('login')
-@csrf_exempt
+from django.views.decorators.csrf import csrf_protect
+import shlex
+
+@csrf_protect
def cmd_lab(request):
if request.user.is_authenticated:
if(request.method=="POST"):
domain=request.POST.get('domain')
- domain=domain.replace("https://www.",'')
+ domain=shlex.quote(domain.replace("https://www.",''))
os=request.POST.get('os')
print(os)
if(os=='win'):
- command="nslookup {}".format(domain)
+ command=[shlex.split("nslookup {}".format(domain))]
else:
- command = "dig {}".format(domain)
+ command = [shlex.split("dig {}".format(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:
@@ -441,21 +424,23 @@ def cmd_lab(request):
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')
-
- print(val)
+ if request.method == "POST":
+ val = request.POST.get('val')
+
+ output = None
try:
- output = eval(val)
+ if val.isdigit():
+ # Assuming 'val' is used for mathematical computations
+ # Only permitting integer operations in this secured implementation
+ output = int(val)
+ else:
+ output = "Invalid input"
except:
output = "Something went wrong"
- 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,11 +466,12 @@ 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')
+ if request.method=="POST":
+ csrf_token = request.POST.get('csrfmiddlewaretoken')
+ if not csrf_token:
+ return render(request,"Lab/BrokenAuth/otp.html",{"otp":"Invalid CSRF Token"})
+ email=request.POST.get('email')
otpN=randint(100,999)
if email and otpN:
if email=="admin@pygoat.com":
@@ -540,17 +526,19 @@ def a9(request):
return render(request,"Lab/A9/a9.html")
else:
return redirect('login')
-@csrf_exempt
+from django.views.decorators.csrf import csrf_protect
+
+@csrf_protect
def a9_lab(request):
if request.user.is_authenticated:
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)
+ # using safe_load to prevent insecure deserialization attack
+ data = yaml.safe_load(file)
return render(request,"Lab/A9/a9_lab.html",{"data":data})
except:
@@ -562,8 +550,6 @@ def a9_lab(request):
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')
@@ -577,10 +563,8 @@ def a9_lab2(request):
img = Image.open(file)
img = img.convert("RGB")
r,g,b = img.split()
- # function_str = "convert(r+g, '1')"
output = ImageMath.eval(function_str,img = img, b=b, r=r, g=g)
- # saving the image
buffered = BytesIO()
output.save(buffered, format="JPEG")
img_str = base64.b64encode(buffered.getvalue()).decode("utf-8")
@@ -721,22 +705,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 +749,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
@@ -783,8 +759,6 @@ def a1_broken_access_lab_2(request):
password = request.POST.get('pass')
user_agent = request.META['HTTP_USER_AGENT']
- # print(name)
- # print(password)
print(user_agent)
if name :
if (user_agent == "pygoat_admin"):
@@ -832,19 +806,15 @@ 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")
+from django.shortcuts import render, redirect
+from django.views.decorator.csrf import uses_csrf_token
-
-@csrf_exempt
+@uses_csrf_token
def injection_sql_lab(request):
if request.user.is_authenticated:
@@ -854,8 +824,6 @@ def injection_sql_lab(request):
print(password)
if name:
- sql_query = "SELECT * FROM introduction_sql_lab_table WHERE id='"+name+"'AND password='"+password+"'"
-
sql_instance = sql_lab_table(id="admin", password="65079b006e85a7e798abecb99e47c154")
sql_instance.save()
sql_instance = sql_lab_table(id="jack", password="jack")
@@ -865,12 +833,9 @@ def injection_sql_lab(request):
sql_instance = sql_lab_table(id="bloke", password="f8d1ce191319ea8f4d1d26e65e130dd5")
sql_instance.save()
- print(sql_query)
-
try:
- user = sql_lab_table.objects.raw(sql_query)
- user = user[0].id
- print(user)
+ user = sql_lab_table.objects.get(id=name, password=password)
+ print(user.id)
except:
return render(
@@ -878,18 +843,16 @@ def injection_sql_lab(request):
'Lab_2021/A3_Injection/sql_lab.html',
{
"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.id})
else:
return render(
request,
'Lab_2021/A3_Injection/sql_lab.html',
{
"wrongpass":password,
- "sql_error":sql_query
})
else:
return render(request, 'Lab_2021/A3_Injection/sql_lab.html')
@@ -916,6 +879,9 @@ def ssrf_lab(request):
file=request.POST["blog"]
try :
dirname = os.path.dirname(__file__)
+ abs_path = os.path.abspath(file)
+ if not abs_path.startswith(dirname):
+ raise ValueError("Invalid path")
filename = os.path.join(dirname, file)
file = open(filename,"r")
data = file.read()
@@ -925,6 +891,7 @@ def ssrf_lab(request):
else:
return redirect('login')
+
def ssrf_discussion(request):
if request.user.is_authenticated:
return render(request,"Lab/ssrf/ssrf_discussion.html")
@@ -944,19 +911,27 @@ def ssrf_target(request):
return render(request,"Lab/ssrf/ssrf_target.html")
else:
return render(request,"Lab/ssrf/ssrf_target.html",{"access_denied":True})
+ALLOWED_HOSTS = ['www.example.com']
+ALLOWED_SCHEMES = ['http', 'https']
@authentication_decorator
def ssrf_lab2(request):
if request.method == "GET":
return render(request, "Lab/ssrf/ssrf_lab2.html")
-
+
elif request.method == "POST":
url = request.POST["url"]
+ parsed_url = urlparse(url)
+
+ if not parsed_url.scheme in ALLOWED_SCHEMES or not parsed_url.netloc in ALLOWED_HOSTS:
+ return render(request, "Lab/ssrf/ssrf_lab2.html", {"error": "URL not allowed"})
+
try:
response = requests.get(url)
- return render(request, "Lab/ssrf/ssrf_lab2.html", {"response": response.content.decode()})
- except:
+ except Exception:
return render(request, "Lab/ssrf/ssrf_lab2.html", {"error": "Invalid URL"})
+
+ return render(request, "Lab/ssrf/ssrf_lab2.html")
#--------------------------------------- Server-side template injection --------------------------------------#
def ssti(request):
@@ -964,6 +939,7 @@ def ssti(request):
return render(request,"Lab_2021/A3_Injection/ssti.html")
else:
return redirect('login')
+from django.utils.html import escape
def ssti_lab(request):
if request.user.is_authenticated:
@@ -974,20 +950,19 @@ def ssti_lab(request):
blog = request.POST["blog"]
id = str(uuid.uuid4()).split('-')[-1]
- blog = filter_blog(blog)
- prepend_code = "{% extends 'introduction/base.html' %}\
- {% block content %}{% block title %}\
-
SSTI-Blogs\
- {% endblock %}"
-
- blog = prepend_code + blog + "{% endblock %}"
+ blog = filter_blog(escape(blog)) # sanitizing the blog string
+
new_blog = Blogs.objects.create(author = request.user, blog_id = id)
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()
+
+ context = {'blog': blog}
+
+ # Removed the manual generation of HTML string
+ filename = os.path.join("Lab_2021", "A3_Injection", "Blogs", f'{id}.html')
+ with open(filename, "w+") as file:
+ content = render(request, filename, context)
+ file.write(str(content.content))
+
return redirect(f'blog/{id}')
else:
return redirect('login')
@@ -1007,6 +982,8 @@ def crypto_failure(request):
return render(request,"Lab_2021/A2_Crypto_failur/crypto_failure.html",{"success":False,"failure":False})
else:
redirect('login')
+import hashlib
+import binascii
def crypto_failure_lab(request):
if request.user.is_authenticated:
@@ -1016,7 +993,8 @@ def crypto_failure_lab(request):
username = request.POST["username"]
password = request.POST["password"]
try:
- password = md5(password.encode()).hexdigest()
+ password = hashlib.scrypt(password.encode(), salt=b'salt', n=16384, r=8, p=1)
+ password = binascii.hexlify(password).decode()
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:
@@ -1037,8 +1015,6 @@ 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":
@@ -1066,20 +1042,18 @@ def crypto_failure_lab3(request):
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.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.delete_cookie("cookie")
return response
except:
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')
@@ -1098,8 +1072,8 @@ 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 = 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 +1133,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,7 +1141,6 @@ def auth_failure_lab2(request):
# }
@authentication_decorator
-@csrf_exempt
def auth_failure_lab3(request):
if request.method == "GET":
try:
@@ -1187,14 +1159,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.set_cookie("session_id", token, secure=True, httponly=True, samesite='Lax')
return response
#-- coding playground for lab2