-
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/grpc): 添加 README、源码、构建文件以及工作流文件 (#5)
* docs(web/grpc): 添加 README * feat(web/grpc): 添加源码及构建文件 * ci(web/grpc): 添加工作流文件
- Loading branch information
Showing
8 changed files
with
285 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 gRPC | ||
|
||
on: | ||
push: | ||
branches: ["main"] | ||
paths: | ||
- "!**/README.md" | ||
- "challenges/web/grpc/build/**" | ||
workflow_dispatch: | ||
|
||
env: | ||
TYPE: web | ||
NAME: grpc | ||
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 @@ | ||
# gRPC | ||
|
||
- 作者:13m0n4de | ||
- 参考:- | ||
- 难度:- | ||
- 分类:Web | ||
- 镜像:- | ||
- 端口:- | ||
|
||
## 题目描述 | ||
|
||
<description> | ||
|
||
## 题目解析 | ||
|
||
<analysis> |
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,11 @@ | ||
FROM python:3.12-alpine | ||
|
||
WORKDIR /app | ||
|
||
COPY app/ . | ||
|
||
RUN pip install --no-cache-dir -r requirements.txt | ||
|
||
RUN python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. *.proto | ||
|
||
CMD ["python", "server.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,16 @@ | ||
syntax = "proto3"; | ||
|
||
package flagservice; | ||
|
||
service FlagService { | ||
rpc GetFlag (FlagRequest) returns (FlagResponse) {} | ||
} | ||
|
||
message FlagRequest { | ||
string token = 1; | ||
} | ||
|
||
message FlagResponse { | ||
string flag = 1; | ||
} | ||
|
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 @@ | ||
grpcio==1.66.1 | ||
grpcio_reflection==1.66.1 | ||
grpcio_tools==1.66.1 | ||
protobuf==5.27.2 |
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,151 @@ | ||
import os | ||
import uuid | ||
from concurrent import futures | ||
|
||
import grpc | ||
from grpc_reflection.v1alpha import reflection | ||
|
||
import user_info_v2_pb2 | ||
import user_info_v2_pb2_grpc | ||
import user_info_v1_pb2 | ||
import user_info_v1_pb2_grpc | ||
import flag_pb2 | ||
import flag_pb2_grpc | ||
|
||
FLAG = os.environ.get("GZCTF_FLAG", "SVUCTF{test_flag}") | ||
|
||
|
||
class UserInfoServiceV2(user_info_v2_pb2_grpc.UserInfoServiceV2Servicer): | ||
def __init__(self, users): | ||
self.users = users | ||
|
||
def GetUserInfo(self, request, context): | ||
user = self.users.get(request.user_id) | ||
if user: | ||
response = user_info_v2_pb2.UserInfoResponseV2( | ||
user_id=user["user_id"], | ||
username=user["username"], | ||
email=user["email"], | ||
role=user["role"], | ||
) | ||
context.set_trailing_metadata( | ||
( | ||
( | ||
"note", | ||
"This version has been updated for security reasons and no longer returns sensitive information like auth tokens.", | ||
), | ||
) | ||
) | ||
return response | ||
|
||
context.abort(grpc.StatusCode.NOT_FOUND, "User not found") | ||
|
||
|
||
class UserInfoServiceV1(user_info_v1_pb2_grpc.UserInfoServiceV1Servicer): | ||
def __init__(self, users): | ||
self.users = users | ||
|
||
def GetUserInfo(self, request, context): | ||
user = self.users.get(request.user_id) | ||
if user: | ||
return user_info_v1_pb2.UserInfoResponseV1( | ||
user_id=user["user_id"], | ||
username=user["username"], | ||
email=user["email"], | ||
role=user["role"], | ||
auth_token=user["auth_token"], | ||
) | ||
|
||
context.abort(grpc.StatusCode.NOT_FOUND, "User not found") | ||
|
||
|
||
class FlagService(flag_pb2_grpc.FlagServiceServicer): | ||
def __init__(self, users): | ||
self.users = users | ||
|
||
def GetFlag(self, request, context): | ||
token = request.token | ||
user = next((u for u in self.users.values() if u["auth_token"] == token), None) | ||
|
||
if user and user["role"] == "admin": | ||
return flag_pb2.FlagResponse(flag=FLAG) | ||
|
||
context.abort( | ||
grpc.StatusCode.PERMISSION_DENIED, | ||
"Access denied. Invalid token or insufficient permissions.", | ||
) | ||
|
||
|
||
def serve(): | ||
users = { | ||
0: { | ||
"user_id": 0, | ||
"username": "admin", | ||
"email": "admin@company.internal", | ||
"role": "admin", | ||
"auth_token": str(uuid.uuid4()), | ||
}, | ||
1: { | ||
"user_id": 1, | ||
"username": "13m0n4de", | ||
"email": "13m0n4de@svuctf.com", | ||
"role": "user", | ||
"auth_token": str(uuid.uuid4()), | ||
}, | ||
2: { | ||
"user_id": 2, | ||
"username": "johndoe", | ||
"email": "johndoe@example.com", | ||
"role": "user", | ||
"auth_token": str(uuid.uuid4()), | ||
}, | ||
3: { | ||
"user_id": 3, | ||
"username": "alice", | ||
"email": "alice@example.com", | ||
"role": "user", | ||
"auth_token": str(uuid.uuid4()), | ||
}, | ||
4: { | ||
"user_id": 4, | ||
"username": "bob", | ||
"email": "bob@example.com", | ||
"role": "user", | ||
"auth_token": str(uuid.uuid4()), | ||
}, | ||
5: { | ||
"user_id": 5, | ||
"username": "guest", | ||
"email": "guest@example.com", | ||
"role": "guest", | ||
"auth_token": str(uuid.uuid4()), | ||
}, | ||
} | ||
|
||
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) | ||
|
||
# Add services to server | ||
user_info_v2_pb2_grpc.add_UserInfoServiceV2Servicer_to_server( | ||
UserInfoServiceV2(users), server | ||
) | ||
user_info_v1_pb2_grpc.add_UserInfoServiceV1Servicer_to_server( | ||
UserInfoServiceV1(users), server | ||
) | ||
flag_pb2_grpc.add_FlagServiceServicer_to_server(FlagService(users), server) | ||
|
||
# Only add V2 and FlagService to reflection | ||
service_names = ( | ||
user_info_v2_pb2.DESCRIPTOR.services_by_name["UserInfoServiceV2"].full_name, | ||
flag_pb2.DESCRIPTOR.services_by_name["FlagService"].full_name, | ||
reflection.SERVICE_NAME, | ||
) | ||
reflection.enable_server_reflection(service_names, server) | ||
|
||
server.add_insecure_port("[::]:50051") | ||
server.start() | ||
print("Server started on port 50051") | ||
server.wait_for_termination() | ||
|
||
|
||
if __name__ == "__main__": | ||
serve() |
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,19 @@ | ||
syntax = "proto3"; | ||
|
||
package userinfo; | ||
|
||
service UserInfoServiceV1 { | ||
rpc GetUserInfo (UserRequestV1) returns (UserInfoResponseV1) {} | ||
} | ||
|
||
message UserRequestV1 { | ||
int32 user_id = 1; | ||
} | ||
|
||
message UserInfoResponseV1 { | ||
int32 user_id = 1; | ||
string username = 2; | ||
string email = 3; | ||
string role = 4; | ||
string auth_token = 5; | ||
} |
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,18 @@ | ||
syntax = "proto3"; | ||
|
||
package userinfo; | ||
|
||
service UserInfoServiceV2 { | ||
rpc GetUserInfo (UserRequestV2) returns (UserInfoResponseV2) {} | ||
} | ||
|
||
message UserRequestV2 { | ||
int32 user_id = 1; | ||
} | ||
|
||
message UserInfoResponseV2 { | ||
int32 user_id = 1; | ||
string username = 2; | ||
string email = 3; | ||
string role = 4; | ||
} |