-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(web/python-prototype-pollution): 添加 README、源码、工作流文件 (#2)
* feat(web/python-prototype-pollution): 添加 README * feat(web/python-prototype-pollution): 添加源码及构建文件 * ci(web/python-prototype-pollution): 添加工作流文件
- Loading branch information
Showing
9 changed files
with
694 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
name: Challenge 拼尽全力也无法越权 | ||
|
||
on: | ||
push: | ||
branches: ["main"] | ||
paths: | ||
- "!**/README.md" | ||
- "challenges/web/python_prototype_pollution/build/**" | ||
workflow_dispatch: | ||
|
||
env: | ||
TYPE: web | ||
NAME: python_prototype_pollution | ||
REGISTRY: ghcr.io | ||
|
||
jobs: | ||
challenge-build: | ||
runs-on: ubuntu-latest | ||
permissions: | ||
contents: read | ||
packages: write | ||
steps: | ||
- name: Checkout repository | ||
uses: actions/checkout@v4 | ||
|
||
- name: Set up Docker Buildx | ||
uses: docker/setup-buildx-action@v3 | ||
|
||
- name: Log in to the Container registry | ||
uses: docker/login-action@v3 | ||
with: | ||
registry: ${{ env.REGISTRY }} | ||
username: ${{ github.actor }} | ||
password: ${{ secrets.GITHUB_TOKEN }} | ||
|
||
- name: Extract metadata (tags, labels) for Docker | ||
id: meta | ||
uses: docker/metadata-action@v5 | ||
with: | ||
images: ${{ env.REGISTRY }}/${{ github.repository }}/${{ env.NAME }} | ||
tags: | | ||
latest | ||
- name: Build and push Docker image | ||
uses: docker/build-push-action@v4 | ||
with: | ||
context: challenges/${{ env.TYPE }}/${{ env.NAME }}/build | ||
tags: ${{ steps.meta.outputs.tags }} | ||
labels: ${{ steps.meta.outputs.labels }} | ||
push: true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# 拼尽全力也无法越权 | ||
|
||
- 作者:13m0n4de | ||
- 参考:- | ||
- 难度:- | ||
- 分类:Web | ||
- 镜像:- | ||
- 端口:- | ||
|
||
## 题目描述 | ||
|
||
<description> | ||
|
||
## 题目解析 | ||
|
||
<analysis> |
15 changes: 15 additions & 0 deletions
15
challenges/web/python_prototype_pollution/build/Dockerfile
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
FROM python:3.12-alpine | ||
|
||
WORKDIR /app | ||
|
||
COPY app/requirements.txt /app/requirements.txt | ||
RUN pip install --no-cache-dir -r requirements.txt | ||
|
||
COPY app/main.py /app/main.py | ||
COPY app/static/index.html /app/static/index.html | ||
COPY app/static/index-compiled.js /app/static/index-compiled.js | ||
|
||
ENV PYTHONDONTWRITEBYTECODE=1 \ | ||
PYTHONUNBUFFERED=1 | ||
|
||
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"] |
121 changes: 121 additions & 0 deletions
121
challenges/web/python_prototype_pollution/build/app/main.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
import os | ||
from typing import Dict, List, Optional | ||
|
||
import jwt | ||
from pydantic import BaseModel | ||
from fastapi import FastAPI, Depends, HTTPException | ||
from fastapi.security import OAuth2PasswordBearer | ||
from fastapi.staticfiles import StaticFiles | ||
from fastapi.responses import FileResponse | ||
|
||
|
||
app = FastAPI(openapi_url=None) | ||
SECRET_KEY: str = os.urandom(32).hex() | ||
FLAG = os.environ.get("GZCTF_FLAG", "SVUCTF{test_flag}") | ||
|
||
|
||
class User(BaseModel): | ||
username: str | ||
password: str | ||
|
||
def get_info(self): | ||
return f"User: {self.username}" | ||
|
||
|
||
class LoginRequest(BaseModel): | ||
username: str | ||
password: str | ||
|
||
|
||
users_db: List[User] = [ | ||
User(username="admin", password=os.urandom(32).hex()), | ||
User(username="user", password="123456"), | ||
] | ||
|
||
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") | ||
|
||
|
||
def merge(src, dst) -> None: | ||
for k, v in src.items(): | ||
if isinstance(dst, dict): | ||
if dst.get(k) and isinstance(v, dict): | ||
merge(v, dst.get(k)) | ||
else: | ||
dst[k] = v | ||
elif hasattr(dst, k) and isinstance(v, dict): | ||
merge(v, getattr(dst, k)) | ||
else: | ||
setattr(dst, k, v) | ||
|
||
|
||
def get_user(username: str) -> Optional[User]: | ||
return next((user for user in users_db if user.username == username), None) | ||
|
||
|
||
def decode_token(token: str) -> dict: | ||
try: | ||
payload = jwt.decode(token, SECRET_KEY, algorithms=["HS256"]) | ||
return payload | ||
except jwt.PyJWTError as e: | ||
raise HTTPException(status_code=401, detail="Invalid token") from e | ||
|
||
|
||
app.mount("/static", StaticFiles(directory="static"), name="static") | ||
|
||
|
||
@app.get("/") | ||
async def read_index(): | ||
return FileResponse("static/index.html") | ||
|
||
|
||
@app.post("/api/login") | ||
async def login(login_data: LoginRequest): | ||
user = get_user(login_data.username) | ||
if not user or user.password != login_data.password: | ||
raise HTTPException(status_code=401, detail="Incorrect username or password") | ||
token = jwt.encode( | ||
{"sub": user.username, "role": "user"}, SECRET_KEY, algorithm="HS256" | ||
) | ||
return {"access_token": token, "token_type": "bearer"} | ||
|
||
|
||
@app.post("/api/update_user") | ||
async def update_user(user_update: Dict, token: str = Depends(oauth2_scheme)): | ||
payload = decode_token(token) | ||
|
||
username = payload.get("sub") | ||
if not username: | ||
raise HTTPException(status_code=404, detail="User not found") | ||
|
||
user = get_user(username) | ||
if not user: | ||
raise HTTPException(status_code=404, detail="User not found") | ||
|
||
merge(user_update, user) | ||
|
||
new_token = jwt.encode( | ||
{"sub": user.username, "role": payload.get("role", "user")}, | ||
SECRET_KEY, | ||
algorithm="HS256", | ||
) | ||
|
||
return {"message": "User updated successfully", "new_token": new_token} | ||
|
||
|
||
@app.get("/api/get_flag") | ||
async def get_flag(token: str = Depends(oauth2_scheme)): | ||
payload = decode_token(token) | ||
role = payload.get("role") | ||
|
||
if not role or role != "admin": | ||
raise HTTPException(status_code=403, detail="Admin access required") | ||
|
||
return {"flag": FLAG} | ||
|
||
|
||
# @app.get("/debug") | ||
# async def debug(): | ||
# return { | ||
# "secret_key": SECRET_KEY, | ||
# "users_db": [user.model_dump() for user in users_db], | ||
# } |
4 changes: 4 additions & 0 deletions
4
challenges/web/python_prototype_pollution/build/app/requirements.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
fastapi==0.114.2 | ||
pydantic==2.9.1 | ||
PyJWT==2.9.0 | ||
uvicorn==0.30.6 |
4 changes: 4 additions & 0 deletions
4
challenges/web/python_prototype_pollution/build/app/static/.gitignore
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
node_modules/ | ||
package.json | ||
yarn.lock | ||
.babelrc |
Oops, something went wrong.